@ethlete/components 1.0.0-next.28 → 1.0.0-next.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/fesm2022/ethlete-components.mjs +1089 -51
- package/fesm2022/ethlete-components.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ethlete-components.d.ts +273 -2
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { ViewEncapsulation, Component, Directive, input, booleanAttribute, signal, effect, numberAttribute, computed, inject, ElementRef, afterNextRender, DestroyRef, InjectionToken, model, linkedSignal, output, Injector, runInInjectionContext, untracked, ApplicationRef, viewChild, ViewContainerRef, createEnvironmentInjector, DOCUMENT, EnvironmentInjector, inputBinding, createComponent, TemplateRef, afterRenderEffect, contentChild, viewChildren, outputBinding, afterEveryRender, isSignal, assertInInjectionContext, isDevMode, provideEnvironmentInitializer, PLATFORM_ID, contentChildren } from '@angular/core';
|
|
3
3
|
import * as i1 from '@ethlete/core';
|
|
4
|
-
import { injectStyleManager, SurfaceInteractiveDirective, RuntimeError, createCanAnimateSignal, ColorInteractiveDirective, ProvideColorDirective, injectErrorTheme, signalElementDimensions, createProvider, ProvideSurfaceDirective, COLOR_PROVIDER, SURFACE_PROVIDER, injectSurfaceThemes, injectSurfaceContextTracker, injectRenderer, injectBoundaryElement, ANIMATED_LIFECYCLE_TOKEN, resolveAppRootColorProvider, resolveSurfaceByElevation, provideBoundaryElement, AnimatedLifecycleDirective, injectBreakpointObserver, isHTMLElement, equal, animationDebugLog, createRootProvider, injectOverlayRuntime, injectAnimatedBlockSize, randomId, createStaticRootProvider, forceReflow, nextFrame, elementCanScroll, createSwipeTracker, createComponentId, injectObserveBreakpoint, AutoSurfaceDirective, AnimatableDirective, ColorInteractiveContainerDirective, ColorInteractiveExcludeDirective, createFlipAnimation, injectPrefersReducedMotion, createFlipAnimationGroup, ColorInteractiveHasFocusDirective, htmlToMarkdown, markdownToHtml, injectHasTouchInput, injectLocale, clamp, signalHostElementDimensions, DragHandleDirective, ResizeHandlesComponent, copyToClipboard, ScrollObserverDirective, signalElementScrollState, ScrollObserverStartDirective, ScrollObserverEndDirective, applyHostListener, injectQueryParam, createUnsavedChangesTracker, createDocumentElementSignal, fromNextFrame, injectRoute, AnimatedIfDirective, applyInitialFocus, syncSignal, typedBreakpointTransform, signalElementChildren, signalElementIntersection, signalHostAttributes, signalHostClasses, signalHostStyles, getScrollContainerTarget, getScrollItemTarget, getElementScrollCoordinates, provideBreakpointInstance, signalClasses, useCursorDragScroll, signalStyles, getScrollSnapTarget, injectViewportSize, signalHostElementIntersection, setInputSignal, injectHostElement, injectRouterEvent, canUseSessionMemory, createAutoSessionMemoryKey, createSessionMemory, injectFocusVisibleTracker } from '@ethlete/core';
|
|
4
|
+
import { injectStyleManager, SurfaceInteractiveDirective, RuntimeError, createCanAnimateSignal, ColorInteractiveDirective, ProvideColorDirective, injectErrorTheme, signalElementDimensions, createProvider, ProvideSurfaceDirective, COLOR_PROVIDER, SURFACE_PROVIDER, injectSurfaceThemes, injectSurfaceThemesPrefix, injectSurfaceContextTracker, injectRenderer, injectBoundaryElement, ANIMATED_LIFECYCLE_TOKEN, resolveAppRootColorProvider, resolveSurfaceByElevation, createCssSurfaceName, provideBoundaryElement, AnimatedLifecycleDirective, injectBreakpointObserver, isHTMLElement, equal, animationDebugLog, createRootProvider, injectOverlayRuntime, injectAnimatedBlockSize, randomId, createStaticRootProvider, forceReflow, nextFrame, elementCanScroll, createSwipeTracker, createComponentId, injectObserveBreakpoint, AutoSurfaceDirective, AnimatableDirective, ColorInteractiveContainerDirective, ColorInteractiveExcludeDirective, createFlipAnimation, injectPrefersReducedMotion, createFlipAnimationGroup, ColorInteractiveHasFocusDirective, htmlToMarkdown, markdownToHtml, injectHasTouchInput, injectLocale, clamp, signalHostElementDimensions, DragHandleDirective, ResizeHandlesComponent, copyToClipboard, ScrollObserverDirective, signalElementScrollState, ScrollObserverStartDirective, ScrollObserverEndDirective, applyHostListener, injectQueryParam, createUnsavedChangesTracker, createDocumentElementSignal, fromNextFrame, injectRoute, AnimatedIfDirective, applyInitialFocus, syncSignal, typedBreakpointTransform, signalElementChildren, signalElementIntersection, signalHostAttributes, signalHostClasses, signalHostStyles, getScrollContainerTarget, getScrollItemTarget, getElementScrollCoordinates, provideBreakpointInstance, signalClasses, useCursorDragScroll, signalStyles, getScrollSnapTarget, injectViewportSize, signalHostElementIntersection, setInputSignal, injectHostElement, injectRouterEvent, canUseSessionMemory, createAutoSessionMemoryKey, createSessionMemory, injectFocusVisibleTracker } from '@ethlete/core';
|
|
5
5
|
import { NgTemplateOutlet, DOCUMENT as DOCUMENT$1, NgComponentOutlet, Location, isPlatformBrowser } from '@angular/common';
|
|
6
6
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
7
7
|
import { endOfMonth, startOfWeek, startOfMonth, addDays, addYears, addMonths, startOfDay, isSameMonth, getDate, setDate, lastDayOfMonth, isBefore, format, isSameDay, isAfter, parse, isValid, setMilliseconds, setSeconds, setMinutes, setHours } from 'date-fns';
|
|
8
|
-
import { withArgs, queryStateSignal, isQueryStateSuccess, isQueryStateFailure, isQueryStateLoading, queryComputed } from '@ethlete/query';
|
|
9
|
-
import { defer, filter, take, map, finalize, timer, switchMap, EMPTY, tap, Subject, fromEvent, merge, takeUntil, of, isObservable, from, catchError, distinctUntilChanged, concat, scan, combineLatest, debounceTime, animationFrameScheduler, exhaustMap, Observable, shareReplay
|
|
8
|
+
import { withArgs, queryStateSignal, isQueryStateSuccess, isQueryStateFailure, isQueryStateLoading, queryComputed, queryDevtoolsEntries, createQueryErrorResponse } from '@ethlete/query';
|
|
9
|
+
import { defer, filter, take, map, finalize, timer, switchMap, EMPTY, tap, Subject, fromEvent, merge, takeUntil, of, isObservable, from, catchError, distinctUntilChanged, concat, scan, combineLatest, debounceTime, animationFrameScheduler, interval, exhaustMap, Observable, shareReplay } from 'rxjs';
|
|
10
10
|
import { toObservable, takeUntilDestroyed, toSignal, outputToObservable, outputFromObservable, rxResource } from '@angular/core/rxjs-interop';
|
|
11
11
|
import { createManagedMetadataKey, metadata, validate, FORM_FIELD } from '@angular/forms/signals';
|
|
12
12
|
import { tap as tap$1 } from 'rxjs/operators';
|
|
13
13
|
import * as i1$1 from '@angular/router';
|
|
14
14
|
import { Router, RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
|
|
15
|
+
import { HttpErrorResponse } from '@angular/common/http';
|
|
15
16
|
|
|
16
17
|
class ButtonPropertiesStylesComponent {
|
|
17
18
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ButtonPropertiesStylesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
@@ -2912,6 +2913,7 @@ const OVERLAY_ERROR_CODES = {
|
|
|
2912
2913
|
NO_CLOSEST_OVERLAY: 1205,
|
|
2913
2914
|
NESTED_OVERLAY_MAIN: 1206,
|
|
2914
2915
|
REF_OUTSIDE_OVERLAY: 1207,
|
|
2916
|
+
MISSING_OVERLAY_MAIN: 1208,
|
|
2915
2917
|
};
|
|
2916
2918
|
|
|
2917
2919
|
const getClosestOverlay = (element, openOverlays) => {
|
|
@@ -3110,6 +3112,7 @@ class OverlayContainerComponent {
|
|
|
3110
3112
|
this.appRef = inject(ApplicationRef);
|
|
3111
3113
|
this.overlayRef = inject(OVERLAY_REF);
|
|
3112
3114
|
this.surfaceThemes = injectSurfaceThemes({ optional: true });
|
|
3115
|
+
this.surfacePrefix = injectSurfaceThemesPrefix({ optional: true });
|
|
3113
3116
|
this.surfaceContextTracker = injectSurfaceContextTracker();
|
|
3114
3117
|
this.renderer = injectRenderer();
|
|
3115
3118
|
this.rootBoundary = injectBoundaryElement();
|
|
@@ -3133,9 +3136,18 @@ class OverlayContainerComponent {
|
|
|
3133
3136
|
this.ownColorProvider.syncWithProvider(contextColorProvider);
|
|
3134
3137
|
}
|
|
3135
3138
|
if (this.surfaceThemes) {
|
|
3136
|
-
|
|
3139
|
+
// Resolve the surface the overlay's trigger visually sits on, so the overlay elevates one
|
|
3140
|
+
// level above it. The trigger keeps its *declaration* injector even when projected/portaled
|
|
3141
|
+
// into another overlay, so DI (`parentSurfaceProvider`) reports the wrong surface for a
|
|
3142
|
+
// trigger rendered inside a dialog/menu pane, and reports nothing for the anchored panel
|
|
3143
|
+
// overlays (select/menu/date) which mount with no DI link to the trigger at all. The
|
|
3144
|
+
// trigger's nearest painted surface ancestor *in the DOM* is authoritative in every case —
|
|
3145
|
+
// an overlay pane and a plain elevated card both carry the surface class — so read that,
|
|
3146
|
+
// and fall back to DI (openers that pass a viewContainerRef but no origin).
|
|
3147
|
+
const parentSurface = this.resolveOriginSurface() ?? this.parentDiSurface();
|
|
3148
|
+
const parentType = parentSurface?.type ?? 'dark';
|
|
3137
3149
|
const hasBackdrop = this.overlayRef.config.hasBackdrop ?? this.overlayRef.config.mode !== 'non-modal';
|
|
3138
|
-
const elevation = hasBackdrop || !
|
|
3150
|
+
const elevation = hasBackdrop || !parentSurface ? 1 : parentSurface.elevation + 1;
|
|
3139
3151
|
const resolved = resolveSurfaceByElevation(this.surfaceThemes, parentType, elevation);
|
|
3140
3152
|
if (resolved) {
|
|
3141
3153
|
this.ownSurfaceProvider.forceSurface(resolved.name);
|
|
@@ -3216,6 +3228,49 @@ class OverlayContainerComponent {
|
|
|
3216
3228
|
* dialog), otherwise the first painted element in the rendered content (menu/tooltip/date-picker
|
|
3217
3229
|
* paint a nested element, potentially at a higher elevation than the host's forced surface).
|
|
3218
3230
|
*/
|
|
3231
|
+
parentDiSurface() {
|
|
3232
|
+
const provider = this.parentSurfaceProvider;
|
|
3233
|
+
if (!provider)
|
|
3234
|
+
return null;
|
|
3235
|
+
return { elevation: provider.elevation(), type: provider.surfaceType() ?? 'dark' };
|
|
3236
|
+
}
|
|
3237
|
+
/**
|
|
3238
|
+
* The surface of the nearest ancestor of the overlay's origin (trigger) that paints a resolved
|
|
3239
|
+
* surface — walking the real DOM so it sees *through* the portal/projection boundary that hides
|
|
3240
|
+
* the true parent surface from DI. Returns null when there is no origin element or no surfaced
|
|
3241
|
+
* ancestor (the overlay then falls back to DI, and ultimately to elevation 1).
|
|
3242
|
+
*/
|
|
3243
|
+
resolveOriginSurface() {
|
|
3244
|
+
const themes = this.surfaceThemes;
|
|
3245
|
+
if (!themes)
|
|
3246
|
+
return null;
|
|
3247
|
+
const origin = this.resolveOriginElement();
|
|
3248
|
+
if (!origin)
|
|
3249
|
+
return null;
|
|
3250
|
+
const prefix = this.surfacePrefix || 'et';
|
|
3251
|
+
const themeByClass = new Map();
|
|
3252
|
+
for (const theme of themes) {
|
|
3253
|
+
themeByClass.set(`${prefix}-surface--${createCssSurfaceName(theme.name)}`, theme);
|
|
3254
|
+
}
|
|
3255
|
+
for (let el = origin; el; el = el.parentElement) {
|
|
3256
|
+
for (const cls of Array.from(el.classList)) {
|
|
3257
|
+
const theme = themeByClass.get(cls);
|
|
3258
|
+
if (theme)
|
|
3259
|
+
return { elevation: theme.elevation, type: theme.type };
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
return null;
|
|
3263
|
+
}
|
|
3264
|
+
resolveOriginElement() {
|
|
3265
|
+
const origin = this.overlayRef.config.origin;
|
|
3266
|
+
if (origin instanceof HTMLElement)
|
|
3267
|
+
return origin;
|
|
3268
|
+
if (origin instanceof Event) {
|
|
3269
|
+
const target = origin.target ?? origin.currentTarget;
|
|
3270
|
+
return target instanceof HTMLElement ? target : null;
|
|
3271
|
+
}
|
|
3272
|
+
return null;
|
|
3273
|
+
}
|
|
3219
3274
|
isSheetHost(host) {
|
|
3220
3275
|
return (host.classList.contains('et-overlay--bottom-sheet') ||
|
|
3221
3276
|
host.classList.contains('et-overlay--top-sheet') ||
|
|
@@ -28364,6 +28419,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
28364
28419
|
}]
|
|
28365
28420
|
}], ctorParameters: () => [] });
|
|
28366
28421
|
|
|
28422
|
+
const OVERLAY_MAIN_TOKEN = new InjectionToken('OVERLAY_MAIN_TOKEN');
|
|
28423
|
+
class OverlayMainDirective {
|
|
28424
|
+
constructor() {
|
|
28425
|
+
this.parent = inject(OVERLAY_MAIN_TOKEN, { optional: true, skipSelf: true });
|
|
28426
|
+
this.elementRef = inject(ElementRef);
|
|
28427
|
+
this.overlayRef = inject(OVERLAY_REF, { optional: true });
|
|
28428
|
+
this.overlayManager = injectOverlayManager();
|
|
28429
|
+
this.enabled = input(true, { ...(ngDevMode ? { debugName: "enabled" } : /* istanbul ignore next */ {}), alias: 'etOverlayMain', transform: booleanAttribute });
|
|
28430
|
+
}
|
|
28431
|
+
ngOnInit() {
|
|
28432
|
+
this.overlayRef = resolveClosestOverlay({
|
|
28433
|
+
overlayRef: this.overlayRef,
|
|
28434
|
+
element: this.elementRef,
|
|
28435
|
+
openOverlays: this.overlayManager.openOverlays(),
|
|
28436
|
+
});
|
|
28437
|
+
if (this.parent) {
|
|
28438
|
+
if (this.overlayRef.id === this.parent.overlayRef?.id && this.parent.enabled() && this.enabled()) {
|
|
28439
|
+
throw new RuntimeError(OVERLAY_ERROR_CODES.NESTED_OVERLAY_MAIN, '[OverlayMainDirective] An overlay must not contain nested <et-overlay-main> elements or etOverlayMain directives.');
|
|
28440
|
+
}
|
|
28441
|
+
}
|
|
28442
|
+
}
|
|
28443
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OverlayMainDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
28444
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: OverlayMainDirective, isStandalone: true, selector: "[etOverlayMain], et-overlay-main", inputs: { enabled: { classPropertyName: "enabled", publicName: "etOverlayMain", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.et-overlay-main": "enabled()" } }, providers: [
|
|
28445
|
+
{
|
|
28446
|
+
provide: OVERLAY_MAIN_TOKEN,
|
|
28447
|
+
useExisting: OverlayMainDirective,
|
|
28448
|
+
},
|
|
28449
|
+
], ngImport: i0 }); }
|
|
28450
|
+
}
|
|
28451
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OverlayMainDirective, decorators: [{
|
|
28452
|
+
type: Directive,
|
|
28453
|
+
args: [{
|
|
28454
|
+
selector: '[etOverlayMain], et-overlay-main',
|
|
28455
|
+
providers: [
|
|
28456
|
+
{
|
|
28457
|
+
provide: OVERLAY_MAIN_TOKEN,
|
|
28458
|
+
useExisting: OverlayMainDirective,
|
|
28459
|
+
},
|
|
28460
|
+
],
|
|
28461
|
+
host: {
|
|
28462
|
+
'[class.et-overlay-main]': 'enabled()',
|
|
28463
|
+
},
|
|
28464
|
+
}]
|
|
28465
|
+
}], propDecorators: { enabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "etOverlayMain", required: false }] }] } });
|
|
28466
|
+
|
|
28367
28467
|
const OVERLAY_BODY_TOKEN = new InjectionToken('OVERLAY_BODY_TOKEN');
|
|
28368
28468
|
class OverlayBodyComponent {
|
|
28369
28469
|
constructor() {
|
|
@@ -28371,6 +28471,7 @@ class OverlayBodyComponent {
|
|
|
28371
28471
|
this.elementRef = inject(ElementRef);
|
|
28372
28472
|
this.scrollObserver = inject(ScrollObserverDirective);
|
|
28373
28473
|
this.overlayManager = injectOverlayManager();
|
|
28474
|
+
this.overlayMain = inject(OVERLAY_MAIN_TOKEN, { optional: true });
|
|
28374
28475
|
this.dividers = input(false, /* @ts-ignore */
|
|
28375
28476
|
...(ngDevMode ? [{ debugName: "dividers" }] : /* istanbul ignore next */ []));
|
|
28376
28477
|
this.dividersEnabled = computed(() => this.dividers() === 'dynamic' || this.dividers() === 'static', /* @ts-ignore */
|
|
@@ -28398,6 +28499,9 @@ class OverlayBodyComponent {
|
|
|
28398
28499
|
nextFrame(() => this.enableDividerAnimations.set(true));
|
|
28399
28500
|
}
|
|
28400
28501
|
ngOnInit() {
|
|
28502
|
+
if (!this.overlayMain) {
|
|
28503
|
+
throw new RuntimeError(OVERLAY_ERROR_CODES.MISSING_OVERLAY_MAIN, '[OverlayBodyComponent] An overlay body must be used inside an <et-overlay-main> element or a host with the etOverlayMain directive.');
|
|
28504
|
+
}
|
|
28401
28505
|
this.overlayRef = resolveClosestOverlay({
|
|
28402
28506
|
overlayRef: this.overlayRef,
|
|
28403
28507
|
element: this.elementRef,
|
|
@@ -28610,8 +28714,12 @@ class OverlayFooterDirective {
|
|
|
28610
28714
|
this.overlayRef = inject(OVERLAY_REF, { optional: true });
|
|
28611
28715
|
this.elementRef = inject(ElementRef);
|
|
28612
28716
|
this.overlayManager = injectOverlayManager();
|
|
28717
|
+
this.overlayMain = inject(OVERLAY_MAIN_TOKEN, { optional: true });
|
|
28613
28718
|
}
|
|
28614
28719
|
ngOnInit() {
|
|
28720
|
+
if (!this.overlayMain) {
|
|
28721
|
+
throw new RuntimeError(OVERLAY_ERROR_CODES.MISSING_OVERLAY_MAIN, '[OverlayFooterDirective] An overlay footer must be used inside an <et-overlay-main> element or a host with the etOverlayMain directive.');
|
|
28722
|
+
}
|
|
28615
28723
|
this.overlayRef = resolveClosestOverlay({
|
|
28616
28724
|
overlayRef: this.overlayRef,
|
|
28617
28725
|
element: this.elementRef,
|
|
@@ -28648,8 +28756,12 @@ class OverlayHeaderDirective {
|
|
|
28648
28756
|
this.overlayRef = inject(OVERLAY_REF, { optional: true });
|
|
28649
28757
|
this.elementRef = inject(ElementRef);
|
|
28650
28758
|
this.overlayManager = injectOverlayManager();
|
|
28759
|
+
this.overlayMain = inject(OVERLAY_MAIN_TOKEN, { optional: true });
|
|
28651
28760
|
}
|
|
28652
28761
|
ngOnInit() {
|
|
28762
|
+
if (!this.overlayMain) {
|
|
28763
|
+
throw new RuntimeError(OVERLAY_ERROR_CODES.MISSING_OVERLAY_MAIN, '[OverlayHeaderDirective] An overlay header must be used inside an <et-overlay-main> element or a host with the etOverlayMain directive.');
|
|
28764
|
+
}
|
|
28653
28765
|
this.overlayRef = resolveClosestOverlay({
|
|
28654
28766
|
overlayRef: this.overlayRef,
|
|
28655
28767
|
element: this.elementRef,
|
|
@@ -28723,51 +28835,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
28723
28835
|
}]
|
|
28724
28836
|
}], ctorParameters: () => [] });
|
|
28725
28837
|
|
|
28726
|
-
const OVERLAY_MAIN_TOKEN = new InjectionToken('OVERLAY_MAIN_TOKEN');
|
|
28727
|
-
class OverlayMainDirective {
|
|
28728
|
-
constructor() {
|
|
28729
|
-
this.parent = inject(OVERLAY_MAIN_TOKEN, { optional: true, skipSelf: true });
|
|
28730
|
-
this.elementRef = inject(ElementRef);
|
|
28731
|
-
this.overlayRef = inject(OVERLAY_REF, { optional: true });
|
|
28732
|
-
this.overlayManager = injectOverlayManager();
|
|
28733
|
-
this.enabled = input(true, { ...(ngDevMode ? { debugName: "enabled" } : /* istanbul ignore next */ {}), alias: 'etOverlayMain', transform: booleanAttribute });
|
|
28734
|
-
}
|
|
28735
|
-
ngOnInit() {
|
|
28736
|
-
this.overlayRef = resolveClosestOverlay({
|
|
28737
|
-
overlayRef: this.overlayRef,
|
|
28738
|
-
element: this.elementRef,
|
|
28739
|
-
openOverlays: this.overlayManager.openOverlays(),
|
|
28740
|
-
});
|
|
28741
|
-
if (this.parent) {
|
|
28742
|
-
if (this.overlayRef.id === this.parent.overlayRef?.id && this.parent.enabled() && this.enabled()) {
|
|
28743
|
-
throw new RuntimeError(OVERLAY_ERROR_CODES.NESTED_OVERLAY_MAIN, '[OverlayMainDirective] An overlay must not contain nested <et-overlay-main> elements or etOverlayMain directives.');
|
|
28744
|
-
}
|
|
28745
|
-
}
|
|
28746
|
-
}
|
|
28747
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OverlayMainDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
28748
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: OverlayMainDirective, isStandalone: true, selector: "[etOverlayMain], et-overlay-main", inputs: { enabled: { classPropertyName: "enabled", publicName: "etOverlayMain", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.et-overlay-main": "enabled()" } }, providers: [
|
|
28749
|
-
{
|
|
28750
|
-
provide: OVERLAY_MAIN_TOKEN,
|
|
28751
|
-
useExisting: OverlayMainDirective,
|
|
28752
|
-
},
|
|
28753
|
-
], ngImport: i0 }); }
|
|
28754
|
-
}
|
|
28755
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: OverlayMainDirective, decorators: [{
|
|
28756
|
-
type: Directive,
|
|
28757
|
-
args: [{
|
|
28758
|
-
selector: '[etOverlayMain], et-overlay-main',
|
|
28759
|
-
providers: [
|
|
28760
|
-
{
|
|
28761
|
-
provide: OVERLAY_MAIN_TOKEN,
|
|
28762
|
-
useExisting: OverlayMainDirective,
|
|
28763
|
-
},
|
|
28764
|
-
],
|
|
28765
|
-
host: {
|
|
28766
|
-
'[class.et-overlay-main]': 'enabled()',
|
|
28767
|
-
},
|
|
28768
|
-
}]
|
|
28769
|
-
}], propDecorators: { enabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "etOverlayMain", required: false }] }] } });
|
|
28770
|
-
|
|
28771
28838
|
const isWritableSignal = (value) => isSignal(value) && typeof value.set === 'function';
|
|
28772
28839
|
const splitOpenerConfig = (config) => {
|
|
28773
28840
|
const { afterClosed, beforeClosed, afterOpened, ...overlayConfig } = config ?? {};
|
|
@@ -29884,6 +29951,977 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
29884
29951
|
}]
|
|
29885
29952
|
}], ctorParameters: () => [], propDecorators: { pageDividers: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageDividers", required: false }] }], sidebarContent: [{ type: i0.ViewChild, args: ['sidebarContentTpl', { isSignal: true }] }], sidebarHeaderContent: [{ type: i0.ContentChild, args: [i0.forwardRef(() => OVERLAY_HEADER_TEMPLATE_TOKEN), { isSignal: true }] }] } });
|
|
29886
29953
|
|
|
29954
|
+
const kindOf = (value) => {
|
|
29955
|
+
if (value === null)
|
|
29956
|
+
return 'null';
|
|
29957
|
+
if (value === undefined)
|
|
29958
|
+
return 'undefined';
|
|
29959
|
+
if (Array.isArray(value))
|
|
29960
|
+
return 'array';
|
|
29961
|
+
return typeof value;
|
|
29962
|
+
};
|
|
29963
|
+
/**
|
|
29964
|
+
* A recursive, collapsible, searchable JSON tree used by the query devtools value explorer. Renders
|
|
29965
|
+
* the *transformed* value the app actually sees (post `transformResponse`). Self-recurses via its
|
|
29966
|
+
* own selector.
|
|
29967
|
+
*/
|
|
29968
|
+
class QueryDevtoolsJsonComponent {
|
|
29969
|
+
constructor() {
|
|
29970
|
+
this.value = input(/* @ts-ignore */
|
|
29971
|
+
...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
29972
|
+
this.nodeKey = input(null, /* @ts-ignore */
|
|
29973
|
+
...(ngDevMode ? [{ debugName: "nodeKey" }] : /* istanbul ignore next */ []));
|
|
29974
|
+
this.depth = input(0, /* @ts-ignore */
|
|
29975
|
+
...(ngDevMode ? [{ debugName: "depth" }] : /* istanbul ignore next */ []));
|
|
29976
|
+
/** Lowercased search term; when set, the tree auto-expands and matches are highlighted. */
|
|
29977
|
+
this.search = input('', /* @ts-ignore */
|
|
29978
|
+
...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
|
|
29979
|
+
/** Full path of this node from the explorer root, used as the key for persisted expansion. */
|
|
29980
|
+
this.path = input('', /* @ts-ignore */
|
|
29981
|
+
...(ngDevMode ? [{ debugName: "path" }] : /* istanbul ignore next */ []));
|
|
29982
|
+
/** Persisted paths explicitly expanded (overrides the depth default). */
|
|
29983
|
+
this.expandedPaths = input(null, /* @ts-ignore */
|
|
29984
|
+
...(ngDevMode ? [{ debugName: "expandedPaths" }] : /* istanbul ignore next */ []));
|
|
29985
|
+
/** Persisted paths explicitly collapsed (overrides the depth default). */
|
|
29986
|
+
this.collapsedPaths = input(null, /* @ts-ignore */
|
|
29987
|
+
...(ngDevMode ? [{ debugName: "collapsedPaths" }] : /* istanbul ignore next */ []));
|
|
29988
|
+
/** When provided, expansion is externally persisted via this callback instead of local state. */
|
|
29989
|
+
this.toggleFn = input(null, /* @ts-ignore */
|
|
29990
|
+
...(ngDevMode ? [{ debugName: "toggleFn" }] : /* istanbul ignore next */ []));
|
|
29991
|
+
this.kind = computed(() => kindOf(this.value()), /* @ts-ignore */
|
|
29992
|
+
...(ngDevMode ? [{ debugName: "kind" }] : /* istanbul ignore next */ []));
|
|
29993
|
+
this.isContainer = computed(() => this.kind() === 'array' || this.kind() === 'object', /* @ts-ignore */
|
|
29994
|
+
...(ngDevMode ? [{ debugName: "isContainer" }] : /* istanbul ignore next */ []));
|
|
29995
|
+
this.entries = computed(() => {
|
|
29996
|
+
const value = this.value();
|
|
29997
|
+
if (Array.isArray(value))
|
|
29998
|
+
return value.map((v, i) => ({ k: String(i), v }));
|
|
29999
|
+
if (value && typeof value === 'object') {
|
|
30000
|
+
return Object.entries(value).map(([k, v]) => ({ k, v }));
|
|
30001
|
+
}
|
|
30002
|
+
return [];
|
|
30003
|
+
}, /* @ts-ignore */
|
|
30004
|
+
...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
|
|
30005
|
+
this.localExpanded = linkedSignal(() => this.depth() < 1, /* @ts-ignore */
|
|
30006
|
+
...(ngDevMode ? [{ debugName: "localExpanded" }] : /* istanbul ignore next */ []));
|
|
30007
|
+
this.expanded = computed(() => {
|
|
30008
|
+
// Externally-persisted mode: resolve from the expanded/collapsed path sets, else the depth default.
|
|
30009
|
+
if (this.toggleFn()) {
|
|
30010
|
+
const path = this.path();
|
|
30011
|
+
if (this.collapsedPaths()?.has(path))
|
|
30012
|
+
return false;
|
|
30013
|
+
if (this.expandedPaths()?.has(path))
|
|
30014
|
+
return true;
|
|
30015
|
+
return this.depth() < 1;
|
|
30016
|
+
}
|
|
30017
|
+
return this.localExpanded();
|
|
30018
|
+
}, /* @ts-ignore */
|
|
30019
|
+
...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
30020
|
+
this.effectiveExpanded = computed(() => (this.search() ? true : this.expanded()), /* @ts-ignore */
|
|
30021
|
+
...(ngDevMode ? [{ debugName: "effectiveExpanded" }] : /* istanbul ignore next */ []));
|
|
30022
|
+
this.preview = computed(() => {
|
|
30023
|
+
const value = this.value();
|
|
30024
|
+
if (Array.isArray(value))
|
|
30025
|
+
return value.length ? `[…] ${value.length}` : '[]';
|
|
30026
|
+
const count = value ? Object.keys(value).length : 0;
|
|
30027
|
+
return count ? `{…} ${count}` : '{}';
|
|
30028
|
+
}, /* @ts-ignore */
|
|
30029
|
+
...(ngDevMode ? [{ debugName: "preview" }] : /* istanbul ignore next */ []));
|
|
30030
|
+
this.display = computed(() => {
|
|
30031
|
+
const value = this.value();
|
|
30032
|
+
const kind = this.kind();
|
|
30033
|
+
if (kind === 'string')
|
|
30034
|
+
return `"${value}"`;
|
|
30035
|
+
if (kind === 'null')
|
|
30036
|
+
return 'null';
|
|
30037
|
+
if (kind === 'undefined')
|
|
30038
|
+
return 'undefined';
|
|
30039
|
+
return String(value);
|
|
30040
|
+
}, /* @ts-ignore */
|
|
30041
|
+
...(ngDevMode ? [{ debugName: "display" }] : /* istanbul ignore next */ []));
|
|
30042
|
+
this.keyHit = computed(() => {
|
|
30043
|
+
const term = this.search();
|
|
30044
|
+
const key = this.nodeKey();
|
|
30045
|
+
return !!term && !!key && key.toLowerCase().includes(term);
|
|
30046
|
+
}, /* @ts-ignore */
|
|
30047
|
+
...(ngDevMode ? [{ debugName: "keyHit" }] : /* istanbul ignore next */ []));
|
|
30048
|
+
this.valueHit = computed(() => {
|
|
30049
|
+
const term = this.search();
|
|
30050
|
+
return !!term && this.display().toLowerCase().includes(term);
|
|
30051
|
+
}, /* @ts-ignore */
|
|
30052
|
+
...(ngDevMode ? [{ debugName: "valueHit" }] : /* istanbul ignore next */ []));
|
|
30053
|
+
}
|
|
30054
|
+
childPath(key) {
|
|
30055
|
+
const path = this.path();
|
|
30056
|
+
return path ? `${path}.${key}` : key;
|
|
30057
|
+
}
|
|
30058
|
+
toggle() {
|
|
30059
|
+
const toggleFn = this.toggleFn();
|
|
30060
|
+
if (toggleFn) {
|
|
30061
|
+
toggleFn(this.path(), !this.expanded());
|
|
30062
|
+
return;
|
|
30063
|
+
}
|
|
30064
|
+
this.localExpanded.set(!this.localExpanded());
|
|
30065
|
+
}
|
|
30066
|
+
copyValue() {
|
|
30067
|
+
try {
|
|
30068
|
+
navigator.clipboard?.writeText(JSON.stringify(this.value(), null, 2));
|
|
30069
|
+
}
|
|
30070
|
+
catch {
|
|
30071
|
+
// clipboard unavailable
|
|
30072
|
+
}
|
|
30073
|
+
}
|
|
30074
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsJsonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
30075
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsJsonComponent, isStandalone: true, selector: "et-query-devtools-json", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, nodeKey: { classPropertyName: "nodeKey", publicName: "nodeKey", isSignal: true, isRequired: false, transformFunction: null }, depth: { classPropertyName: "depth", publicName: "depth", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: false, transformFunction: null }, expandedPaths: { classPropertyName: "expandedPaths", publicName: "expandedPaths", isSignal: true, isRequired: false, transformFunction: null }, collapsedPaths: { classPropertyName: "collapsedPaths", publicName: "collapsedPaths", isSignal: true, isRequired: false, transformFunction: null }, toggleFn: { classPropertyName: "toggleFn", publicName: "toggleFn", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
30076
|
+
@if (isContainer()) {
|
|
30077
|
+
<div class="et-query-devtools-json-node">
|
|
30078
|
+
<button
|
|
30079
|
+
[attr.aria-expanded]="effectiveExpanded()"
|
|
30080
|
+
(click)="toggle()"
|
|
30081
|
+
class="et-query-devtools-json-row et-query-devtools-json-toggle"
|
|
30082
|
+
type="button"
|
|
30083
|
+
>
|
|
30084
|
+
<span class="et-query-devtools-json-caret">{{ effectiveExpanded() ? '▾' : '▸' }}</span>
|
|
30085
|
+
@if (nodeKey() !== null) {
|
|
30086
|
+
<span [class.et-query-devtools-json-hit]="keyHit()" class="et-query-devtools-json-key">{{
|
|
30087
|
+
nodeKey()
|
|
30088
|
+
}}</span>
|
|
30089
|
+
<span class="et-query-devtools-json-colon">:</span>
|
|
30090
|
+
}
|
|
30091
|
+
<span class="et-query-devtools-json-preview">{{ preview() }}</span>
|
|
30092
|
+
</button>
|
|
30093
|
+
|
|
30094
|
+
@if (effectiveExpanded()) {
|
|
30095
|
+
<div class="et-query-devtools-json-children">
|
|
30096
|
+
@for (entry of entries(); track entry.k) {
|
|
30097
|
+
<et-query-devtools-json
|
|
30098
|
+
[value]="entry.v"
|
|
30099
|
+
[nodeKey]="entry.k"
|
|
30100
|
+
[depth]="depth() + 1"
|
|
30101
|
+
[path]="childPath(entry.k)"
|
|
30102
|
+
[search]="search()"
|
|
30103
|
+
[expandedPaths]="expandedPaths()"
|
|
30104
|
+
[collapsedPaths]="collapsedPaths()"
|
|
30105
|
+
[toggleFn]="toggleFn()"
|
|
30106
|
+
/>
|
|
30107
|
+
}
|
|
30108
|
+
</div>
|
|
30109
|
+
}
|
|
30110
|
+
</div>
|
|
30111
|
+
} @else {
|
|
30112
|
+
<div [attr.data-kind]="kind()" class="et-query-devtools-json-row et-query-devtools-json-leaf">
|
|
30113
|
+
@if (nodeKey() !== null) {
|
|
30114
|
+
<span [class.et-query-devtools-json-hit]="keyHit()" class="et-query-devtools-json-key">{{ nodeKey() }}</span>
|
|
30115
|
+
<span class="et-query-devtools-json-colon">:</span>
|
|
30116
|
+
}
|
|
30117
|
+
<span [class.et-query-devtools-json-hit]="valueHit()" class="et-query-devtools-json-value">{{
|
|
30118
|
+
display()
|
|
30119
|
+
}}</span>
|
|
30120
|
+
<button (click)="copyValue()" class="et-query-devtools-json-copy" type="button" title="Copy value">⧉</button>
|
|
30121
|
+
</div>
|
|
30122
|
+
}
|
|
30123
|
+
`, isInline: true, dependencies: [{ kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "path", "expandedPaths", "collapsedPaths", "toggleFn"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
30124
|
+
}
|
|
30125
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsJsonComponent, decorators: [{
|
|
30126
|
+
type: Component,
|
|
30127
|
+
args: [{
|
|
30128
|
+
selector: 'et-query-devtools-json',
|
|
30129
|
+
template: `
|
|
30130
|
+
@if (isContainer()) {
|
|
30131
|
+
<div class="et-query-devtools-json-node">
|
|
30132
|
+
<button
|
|
30133
|
+
[attr.aria-expanded]="effectiveExpanded()"
|
|
30134
|
+
(click)="toggle()"
|
|
30135
|
+
class="et-query-devtools-json-row et-query-devtools-json-toggle"
|
|
30136
|
+
type="button"
|
|
30137
|
+
>
|
|
30138
|
+
<span class="et-query-devtools-json-caret">{{ effectiveExpanded() ? '▾' : '▸' }}</span>
|
|
30139
|
+
@if (nodeKey() !== null) {
|
|
30140
|
+
<span [class.et-query-devtools-json-hit]="keyHit()" class="et-query-devtools-json-key">{{
|
|
30141
|
+
nodeKey()
|
|
30142
|
+
}}</span>
|
|
30143
|
+
<span class="et-query-devtools-json-colon">:</span>
|
|
30144
|
+
}
|
|
30145
|
+
<span class="et-query-devtools-json-preview">{{ preview() }}</span>
|
|
30146
|
+
</button>
|
|
30147
|
+
|
|
30148
|
+
@if (effectiveExpanded()) {
|
|
30149
|
+
<div class="et-query-devtools-json-children">
|
|
30150
|
+
@for (entry of entries(); track entry.k) {
|
|
30151
|
+
<et-query-devtools-json
|
|
30152
|
+
[value]="entry.v"
|
|
30153
|
+
[nodeKey]="entry.k"
|
|
30154
|
+
[depth]="depth() + 1"
|
|
30155
|
+
[path]="childPath(entry.k)"
|
|
30156
|
+
[search]="search()"
|
|
30157
|
+
[expandedPaths]="expandedPaths()"
|
|
30158
|
+
[collapsedPaths]="collapsedPaths()"
|
|
30159
|
+
[toggleFn]="toggleFn()"
|
|
30160
|
+
/>
|
|
30161
|
+
}
|
|
30162
|
+
</div>
|
|
30163
|
+
}
|
|
30164
|
+
</div>
|
|
30165
|
+
} @else {
|
|
30166
|
+
<div [attr.data-kind]="kind()" class="et-query-devtools-json-row et-query-devtools-json-leaf">
|
|
30167
|
+
@if (nodeKey() !== null) {
|
|
30168
|
+
<span [class.et-query-devtools-json-hit]="keyHit()" class="et-query-devtools-json-key">{{ nodeKey() }}</span>
|
|
30169
|
+
<span class="et-query-devtools-json-colon">:</span>
|
|
30170
|
+
}
|
|
30171
|
+
<span [class.et-query-devtools-json-hit]="valueHit()" class="et-query-devtools-json-value">{{
|
|
30172
|
+
display()
|
|
30173
|
+
}}</span>
|
|
30174
|
+
<button (click)="copyValue()" class="et-query-devtools-json-copy" type="button" title="Copy value">⧉</button>
|
|
30175
|
+
</div>
|
|
30176
|
+
}
|
|
30177
|
+
`,
|
|
30178
|
+
encapsulation: ViewEncapsulation.None,
|
|
30179
|
+
imports: [QueryDevtoolsJsonComponent],
|
|
30180
|
+
}]
|
|
30181
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], nodeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeKey", required: false }] }], depth: [{ type: i0.Input, args: [{ isSignal: true, alias: "depth", required: false }] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: false }] }], path: [{ type: i0.Input, args: [{ isSignal: true, alias: "path", required: false }] }], expandedPaths: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedPaths", required: false }] }], collapsedPaths: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedPaths", required: false }] }], toggleFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleFn", required: false }] }] } });
|
|
30182
|
+
|
|
30183
|
+
/**
|
|
30184
|
+
* The floating toggle button for the query devtools. Rendered with `ShadowDom` encapsulation so the
|
|
30185
|
+
* host application's global CSS (Tailwind resets, button styles, …) can never touch it and its own
|
|
30186
|
+
* styles can never leak out. Uses px (not rem) internally so it doesn't depend on the host's root
|
|
30187
|
+
* font-size; theme accent colour is read from an inherited custom property with a fallback.
|
|
30188
|
+
*/
|
|
30189
|
+
class QueryDevtoolsToggleComponent {
|
|
30190
|
+
constructor() {
|
|
30191
|
+
this.openChange = output();
|
|
30192
|
+
}
|
|
30193
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
30194
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: QueryDevtoolsToggleComponent, isStandalone: true, selector: "et-query-devtools-toggle", outputs: { openChange: "openChange" }, ngImport: i0, template: `
|
|
30195
|
+
<button (click)="openChange.emit()" type="button" title="Toggle query devtools (Ctrl/Cmd + Alt + Q)">
|
|
30196
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
30197
|
+
<ellipse cx="12" cy="6" rx="7.5" ry="3" />
|
|
30198
|
+
<path d="M4.5 6v6c0 1.66 3.36 3 7.5 3s7.5-1.34 7.5-3V6" />
|
|
30199
|
+
<path d="M4.5 12v6c0 1.66 3.36 3 7.5 3s7.5-1.34 7.5-3v-6" />
|
|
30200
|
+
</svg>
|
|
30201
|
+
<span class="label">Query</span>
|
|
30202
|
+
</button>
|
|
30203
|
+
`, isInline: true, styles: [":host{position:fixed;inset-block-end:16px;inset-inline-end:16px;z-index:2147483001}button{--_accent: var(--et-theme-color-primary-solid, #60a5fa);position:relative;display:inline-flex;align-items:center;gap:8px;padding:10px 16px 10px 14px;border:none;border-radius:999px;background:linear-gradient(135deg,#1f1f23,#2a2a30);color:#fafafa;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;font-weight:600;letter-spacing:.02em;cursor:pointer;box-shadow:0 6px 20px #00000059,inset 0 0 0 1px #ffffff14;transition:transform .15s ease,box-shadow .2s ease}button:before{content:\"\";position:absolute;inset:0;border-radius:inherit;padding:1px;background:linear-gradient(135deg,var(--_accent),transparent 60%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.7;transition:opacity .2s ease}button:hover{transform:translateY(-2px);box-shadow:0 10px 28px #0006,0 0 0 4px color-mix(in srgb,var(--_accent) 22%,transparent),inset 0 0 0 1px #ffffff1a}button:hover:before{opacity:1}svg{inline-size:16px;block-size:16px;fill:none;stroke:var(--_accent);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}.label{line-height:1}\n"], encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
30204
|
+
}
|
|
30205
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsToggleComponent, decorators: [{
|
|
30206
|
+
type: Component,
|
|
30207
|
+
args: [{ selector: 'et-query-devtools-toggle', template: `
|
|
30208
|
+
<button (click)="openChange.emit()" type="button" title="Toggle query devtools (Ctrl/Cmd + Alt + Q)">
|
|
30209
|
+
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
30210
|
+
<ellipse cx="12" cy="6" rx="7.5" ry="3" />
|
|
30211
|
+
<path d="M4.5 6v6c0 1.66 3.36 3 7.5 3s7.5-1.34 7.5-3V6" />
|
|
30212
|
+
<path d="M4.5 12v6c0 1.66 3.36 3 7.5 3s7.5-1.34 7.5-3v-6" />
|
|
30213
|
+
</svg>
|
|
30214
|
+
<span class="label">Query</span>
|
|
30215
|
+
</button>
|
|
30216
|
+
`, encapsulation: ViewEncapsulation.ShadowDom, styles: [":host{position:fixed;inset-block-end:16px;inset-inline-end:16px;z-index:2147483001}button{--_accent: var(--et-theme-color-primary-solid, #60a5fa);position:relative;display:inline-flex;align-items:center;gap:8px;padding:10px 16px 10px 14px;border:none;border-radius:999px;background:linear-gradient(135deg,#1f1f23,#2a2a30);color:#fafafa;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;font-weight:600;letter-spacing:.02em;cursor:pointer;box-shadow:0 6px 20px #00000059,inset 0 0 0 1px #ffffff14;transition:transform .15s ease,box-shadow .2s ease}button:before{content:\"\";position:absolute;inset:0;border-radius:inherit;padding:1px;background:linear-gradient(135deg,var(--_accent),transparent 60%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.7;transition:opacity .2s ease}button:hover{transform:translateY(-2px);box-shadow:0 10px 28px #0006,0 0 0 4px color-mix(in srgb,var(--_accent) 22%,transparent),inset 0 0 0 1px #ffffff1a}button:hover:before{opacity:1}svg{inline-size:16px;block-size:16px;fill:none;stroke:var(--_accent);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}.label{line-height:1}\n"] }]
|
|
30217
|
+
}], propDecorators: { openChange: [{ type: i0.Output, args: ["openChange"] }] } });
|
|
30218
|
+
|
|
30219
|
+
const STORAGE_KEY = 'ethlete:query:devtools:v4';
|
|
30220
|
+
const MAX_EVENTS = 100;
|
|
30221
|
+
const DEFAULT_HEIGHT = 360;
|
|
30222
|
+
const MIN_HEIGHT = 200;
|
|
30223
|
+
const readPersistedState = () => {
|
|
30224
|
+
try {
|
|
30225
|
+
const raw = sessionStorage.getItem(STORAGE_KEY);
|
|
30226
|
+
return raw ? JSON.parse(raw) : {};
|
|
30227
|
+
}
|
|
30228
|
+
catch {
|
|
30229
|
+
return {};
|
|
30230
|
+
}
|
|
30231
|
+
};
|
|
30232
|
+
/**
|
|
30233
|
+
* Slims a value for a shareable report: long strings are truncated and long arrays keep only the
|
|
30234
|
+
* first couple of entries, replacing the repetitive tail with a `… (N more)` marker, so a big
|
|
30235
|
+
* response collapses to a representative sample.
|
|
30236
|
+
*/
|
|
30237
|
+
const slimForReport = (value, depth = 0) => {
|
|
30238
|
+
if (typeof value === 'string')
|
|
30239
|
+
return value.length > 200 ? `${value.slice(0, 200)}…` : value;
|
|
30240
|
+
if (depth > 6)
|
|
30241
|
+
return '…';
|
|
30242
|
+
if (Array.isArray(value)) {
|
|
30243
|
+
if (value.length > 3) {
|
|
30244
|
+
return [...value.slice(0, 2).map((v) => slimForReport(v, depth + 1)), `… (${value.length - 2} more)`];
|
|
30245
|
+
}
|
|
30246
|
+
return value.map((v) => slimForReport(v, depth + 1));
|
|
30247
|
+
}
|
|
30248
|
+
if (value && typeof value === 'object') {
|
|
30249
|
+
const out = {};
|
|
30250
|
+
for (const [key, val] of Object.entries(value))
|
|
30251
|
+
out[key] = slimForReport(val, depth + 1);
|
|
30252
|
+
return out;
|
|
30253
|
+
}
|
|
30254
|
+
return value;
|
|
30255
|
+
};
|
|
30256
|
+
/** Best-effort decode of a JWT payload for the auth tab. Returns `null` for anything non-decodable. */
|
|
30257
|
+
const decodeJwtPayload = (token) => {
|
|
30258
|
+
if (!token)
|
|
30259
|
+
return null;
|
|
30260
|
+
try {
|
|
30261
|
+
const payload = token.split('.')[1];
|
|
30262
|
+
if (!payload)
|
|
30263
|
+
return null;
|
|
30264
|
+
const normalized = payload.replace(/-/g, '+').replace(/_/g, '/');
|
|
30265
|
+
const decoded = atob(normalized);
|
|
30266
|
+
const json = decodeURIComponent(decoded
|
|
30267
|
+
.split('')
|
|
30268
|
+
.map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
|
|
30269
|
+
.join(''));
|
|
30270
|
+
return JSON.parse(json);
|
|
30271
|
+
}
|
|
30272
|
+
catch {
|
|
30273
|
+
return null;
|
|
30274
|
+
}
|
|
30275
|
+
};
|
|
30276
|
+
/**
|
|
30277
|
+
* A floating, dockable panel that inspects the live state of the signals-first `@ethlete/query`
|
|
30278
|
+
* system: queries, stacks, sequences, bearer auth providers, the repository cache and a rolling
|
|
30279
|
+
* event log.
|
|
30280
|
+
*
|
|
30281
|
+
* Requires `provideQueryDevtools()` in the application providers — without it the registry stays
|
|
30282
|
+
* empty and the panel shows nothing.
|
|
30283
|
+
*/
|
|
30284
|
+
class QueryDevtoolsComponent {
|
|
30285
|
+
constructor() {
|
|
30286
|
+
this.hostEl = inject(ElementRef);
|
|
30287
|
+
this.document = inject(DOCUMENT$1);
|
|
30288
|
+
this.eventIdCounter = 0;
|
|
30289
|
+
this.lastSelectionKey = '';
|
|
30290
|
+
this.persisted = readPersistedState();
|
|
30291
|
+
this.tabs = [
|
|
30292
|
+
{ id: 'queries', label: 'Queries' },
|
|
30293
|
+
{ id: 'stacks', label: 'Stacks' },
|
|
30294
|
+
{ id: 'sequences', label: 'Sequences' },
|
|
30295
|
+
{ id: 'auth', label: 'Auth' },
|
|
30296
|
+
{ id: 'ws', label: 'Sockets' },
|
|
30297
|
+
{ id: 'cache', label: 'Cache' },
|
|
30298
|
+
{ id: 'events', label: 'Events' },
|
|
30299
|
+
];
|
|
30300
|
+
this.open = signal(this.persisted.open ?? false, /* @ts-ignore */
|
|
30301
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
30302
|
+
this.panelHeight = signal(this.persisted.height ?? DEFAULT_HEIGHT, /* @ts-ignore */
|
|
30303
|
+
...(ngDevMode ? [{ debugName: "panelHeight" }] : /* istanbul ignore next */ []));
|
|
30304
|
+
this.resizing = signal(false, /* @ts-ignore */
|
|
30305
|
+
...(ngDevMode ? [{ debugName: "resizing" }] : /* istanbul ignore next */ []));
|
|
30306
|
+
this.activeTab = signal(this.persisted.activeTab ?? 'queries', /* @ts-ignore */
|
|
30307
|
+
...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
|
|
30308
|
+
this.selectedClientName = signal(this.persisted.selectedClientName ?? null, /* @ts-ignore */
|
|
30309
|
+
...(ngDevMode ? [{ debugName: "selectedClientName" }] : /* istanbul ignore next */ []));
|
|
30310
|
+
this.selectedQueryId = signal(this.persisted.selectedQueryId ?? null, /* @ts-ignore */
|
|
30311
|
+
...(ngDevMode ? [{ debugName: "selectedQueryId" }] : /* istanbul ignore next */ []));
|
|
30312
|
+
// Independent per-drawer selection so the Stacks / Sequences drawers don't share the Queries tab's.
|
|
30313
|
+
this.stackSelectedQueryId = signal(null, /* @ts-ignore */
|
|
30314
|
+
...(ngDevMode ? [{ debugName: "stackSelectedQueryId" }] : /* istanbul ignore next */ []));
|
|
30315
|
+
this.sequenceSelectedQueryId = signal(null, /* @ts-ignore */
|
|
30316
|
+
...(ngDevMode ? [{ debugName: "sequenceSelectedQueryId" }] : /* istanbul ignore next */ []));
|
|
30317
|
+
this.eventLog = signal([], /* @ts-ignore */
|
|
30318
|
+
...(ngDevMode ? [{ debugName: "eventLog" }] : /* istanbul ignore next */ []));
|
|
30319
|
+
/** Keys (`<entryId>:<stepIndex>`) of the sequence steps whose in/out detail is expanded. */
|
|
30320
|
+
this.expandedSteps = signal(new Set(this.persisted.expandedSteps ?? []), /* @ts-ignore */
|
|
30321
|
+
...(ngDevMode ? [{ debugName: "expandedSteps" }] : /* istanbul ignore next */ []));
|
|
30322
|
+
/** Shared value-explorer search term. */
|
|
30323
|
+
this.jsonSearch = signal(this.persisted.jsonSearch ?? '', /* @ts-ignore */
|
|
30324
|
+
...(ngDevMode ? [{ debugName: "jsonSearch" }] : /* istanbul ignore next */ []));
|
|
30325
|
+
this.jsonSearchTerm = computed(() => this.jsonSearch().trim().toLowerCase(), /* @ts-ignore */
|
|
30326
|
+
...(ngDevMode ? [{ debugName: "jsonSearchTerm" }] : /* istanbul ignore next */ []));
|
|
30327
|
+
/** Path-keyed value-explorer expansion overrides (persisted so open trees survive a reload). */
|
|
30328
|
+
this.jsonExpandedPaths = signal(new Set(this.persisted.jsonExpanded ?? []), /* @ts-ignore */
|
|
30329
|
+
...(ngDevMode ? [{ debugName: "jsonExpandedPaths" }] : /* istanbul ignore next */ []));
|
|
30330
|
+
this.jsonCollapsedPaths = signal(new Set(this.persisted.jsonCollapsed ?? []), /* @ts-ignore */
|
|
30331
|
+
...(ngDevMode ? [{ debugName: "jsonCollapsedPaths" }] : /* istanbul ignore next */ []));
|
|
30332
|
+
/** JIT editor state (response / args editing on the selected query). */
|
|
30333
|
+
this.editorMode = signal('none', /* @ts-ignore */
|
|
30334
|
+
...(ngDevMode ? [{ debugName: "editorMode" }] : /* istanbul ignore next */ []));
|
|
30335
|
+
this.responseDraft = signal('', /* @ts-ignore */
|
|
30336
|
+
...(ngDevMode ? [{ debugName: "responseDraft" }] : /* istanbul ignore next */ []));
|
|
30337
|
+
this.argsDraft = signal('', /* @ts-ignore */
|
|
30338
|
+
...(ngDevMode ? [{ debugName: "argsDraft" }] : /* istanbul ignore next */ []));
|
|
30339
|
+
this.editError = signal(null, /* @ts-ignore */
|
|
30340
|
+
...(ngDevMode ? [{ debugName: "editError" }] : /* istanbul ignore next */ []));
|
|
30341
|
+
/** Transient "Copied!" feedback for the copy-report action. */
|
|
30342
|
+
this.copiedReport = signal(false, /* @ts-ignore */
|
|
30343
|
+
...(ngDevMode ? [{ debugName: "copiedReport" }] : /* istanbul ignore next */ []));
|
|
30344
|
+
/** 1-second tick driving the cache freshness countdowns. */
|
|
30345
|
+
this.clock = toSignal(interval(1000), { initialValue: 0 });
|
|
30346
|
+
/** "Inspect" mode: hover the live UI to find the query that a component created. */
|
|
30347
|
+
this.inspectActive = signal(false, /* @ts-ignore */
|
|
30348
|
+
...(ngDevMode ? [{ debugName: "inspectActive" }] : /* istanbul ignore next */ []));
|
|
30349
|
+
this.inspectHover = signal(null, /* @ts-ignore */
|
|
30350
|
+
...(ngDevMode ? [{ debugName: "inspectHover" }] : /* istanbul ignore next */ []));
|
|
30351
|
+
/** When set (via inspect), the Queries list is filtered to exactly these entry ids. */
|
|
30352
|
+
this.inspectFilterIds = signal(this.persisted.inspectFilterIds ?? null, /* @ts-ignore */
|
|
30353
|
+
...(ngDevMode ? [{ debugName: "inspectFilterIds" }] : /* istanbul ignore next */ []));
|
|
30354
|
+
this.queryEntries = computed(() => queryDevtoolsEntries().filter((e) => e.kind === 'query'), /* @ts-ignore */
|
|
30355
|
+
...(ngDevMode ? [{ debugName: "queryEntries" }] : /* istanbul ignore next */ []));
|
|
30356
|
+
this.stackEntries = computed(() => queryDevtoolsEntries().filter((e) => e.kind === 'query-stack' || e.kind === 'paged-query-stack'), /* @ts-ignore */
|
|
30357
|
+
...(ngDevMode ? [{ debugName: "stackEntries" }] : /* istanbul ignore next */ []));
|
|
30358
|
+
this.sequenceEntries = computed(() => queryDevtoolsEntries().filter((e) => e.kind === 'query-sequence'), /* @ts-ignore */
|
|
30359
|
+
...(ngDevMode ? [{ debugName: "sequenceEntries" }] : /* istanbul ignore next */ []));
|
|
30360
|
+
this.authEntries = computed(() => queryDevtoolsEntries().filter((e) => e.kind === 'auth-provider'), /* @ts-ignore */
|
|
30361
|
+
...(ngDevMode ? [{ debugName: "authEntries" }] : /* istanbul ignore next */ []));
|
|
30362
|
+
this.wsEntries = computed(() => queryDevtoolsEntries().filter((e) => e.kind === 'ws-client'), /* @ts-ignore */
|
|
30363
|
+
...(ngDevMode ? [{ debugName: "wsEntries" }] : /* istanbul ignore next */ []));
|
|
30364
|
+
/** Unique client names present across queries and auth providers, for the Queries-tab picker. */
|
|
30365
|
+
this.clientNames = computed(() => {
|
|
30366
|
+
const names = new Set();
|
|
30367
|
+
for (const entry of queryDevtoolsEntries()) {
|
|
30368
|
+
if (entry.meta.clientName)
|
|
30369
|
+
names.add(entry.meta.clientName);
|
|
30370
|
+
}
|
|
30371
|
+
return Array.from(names).sort();
|
|
30372
|
+
}, /* @ts-ignore */
|
|
30373
|
+
...(ngDevMode ? [{ debugName: "clientNames" }] : /* istanbul ignore next */ []));
|
|
30374
|
+
/** Unique repositories (with their client name + base URL) used by the Cache and Events tabs. */
|
|
30375
|
+
this.repositories = computed(() => {
|
|
30376
|
+
const map = new Map();
|
|
30377
|
+
for (const entry of queryDevtoolsEntries()) {
|
|
30378
|
+
const repo = entry.meta.repository;
|
|
30379
|
+
if (repo && !map.has(repo)) {
|
|
30380
|
+
map.set(repo, { name: entry.meta.clientName ?? 'unknown', baseUrl: entry.meta.clientBaseUrl ?? '' });
|
|
30381
|
+
}
|
|
30382
|
+
}
|
|
30383
|
+
return Array.from(map, ([repository, info]) => ({ repository, name: info.name, baseUrl: info.baseUrl }));
|
|
30384
|
+
}, /* @ts-ignore */
|
|
30385
|
+
...(ngDevMode ? [{ debugName: "repositories" }] : /* istanbul ignore next */ []));
|
|
30386
|
+
this.filteredQueries = computed(() => {
|
|
30387
|
+
const entries = this.queryEntries();
|
|
30388
|
+
const inspectIds = this.inspectFilterIds();
|
|
30389
|
+
let filtered;
|
|
30390
|
+
if (inspectIds) {
|
|
30391
|
+
filtered = entries.filter((e) => inspectIds.includes(e.id));
|
|
30392
|
+
}
|
|
30393
|
+
else {
|
|
30394
|
+
const client = this.selectedClientName();
|
|
30395
|
+
filtered = client ? entries.filter((e) => e.meta.clientName === client) : entries;
|
|
30396
|
+
}
|
|
30397
|
+
return filtered.map((entry) => ({ entry, query: entry.handle }));
|
|
30398
|
+
}, /* @ts-ignore */
|
|
30399
|
+
...(ngDevMode ? [{ debugName: "filteredQueries" }] : /* istanbul ignore next */ []));
|
|
30400
|
+
this.selectedQuery = computed(() => this.findQuery(this.selectedQueryId()), /* @ts-ignore */
|
|
30401
|
+
...(ngDevMode ? [{ debugName: "selectedQuery" }] : /* istanbul ignore next */ []));
|
|
30402
|
+
this.stackSelectedQuery = computed(() => this.findQuery(this.stackSelectedQueryId()), /* @ts-ignore */
|
|
30403
|
+
...(ngDevMode ? [{ debugName: "stackSelectedQuery" }] : /* istanbul ignore next */ []));
|
|
30404
|
+
this.sequenceSelectedQuery = computed(() => this.findQuery(this.sequenceSelectedQueryId()), /* @ts-ignore */
|
|
30405
|
+
...(ngDevMode ? [{ debugName: "sequenceSelectedQuery" }] : /* istanbul ignore next */ []));
|
|
30406
|
+
this.cacheView = computed(() => this.repositories().map(({ repository, name, baseUrl }) => {
|
|
30407
|
+
// Read the version signal so this recomputes on every cache mutation.
|
|
30408
|
+
repository.subtle.cacheVersion();
|
|
30409
|
+
return { name, baseUrl, repository, entries: repository.subtle.cacheEntries() };
|
|
30410
|
+
}), /* @ts-ignore */
|
|
30411
|
+
...(ngDevMode ? [{ debugName: "cacheView" }] : /* istanbul ignore next */ []));
|
|
30412
|
+
/** Map of a component's host element to the query entries it created (for the inspect tool). */
|
|
30413
|
+
this.elementQueryMap = computed(() => {
|
|
30414
|
+
const map = new Map();
|
|
30415
|
+
for (const entry of this.queryEntries()) {
|
|
30416
|
+
const el = entry.meta.element;
|
|
30417
|
+
if (!el)
|
|
30418
|
+
continue;
|
|
30419
|
+
const list = map.get(el);
|
|
30420
|
+
if (list)
|
|
30421
|
+
list.push(entry);
|
|
30422
|
+
else
|
|
30423
|
+
map.set(el, [entry]);
|
|
30424
|
+
}
|
|
30425
|
+
return map;
|
|
30426
|
+
}, /* @ts-ignore */
|
|
30427
|
+
...(ngDevMode ? [{ debugName: "elementQueryMap" }] : /* istanbul ignore next */ []));
|
|
30428
|
+
// Assigned here (not as an arrow property) so `this` is bound for the value-explorer callback.
|
|
30429
|
+
this.toggleJsonPath = (path, expand) => {
|
|
30430
|
+
const expanded = new Set(this.jsonExpandedPaths());
|
|
30431
|
+
const collapsed = new Set(this.jsonCollapsedPaths());
|
|
30432
|
+
if (expand) {
|
|
30433
|
+
expanded.add(path);
|
|
30434
|
+
collapsed.delete(path);
|
|
30435
|
+
}
|
|
30436
|
+
else {
|
|
30437
|
+
collapsed.add(path);
|
|
30438
|
+
expanded.delete(path);
|
|
30439
|
+
}
|
|
30440
|
+
this.jsonExpandedPaths.set(expanded);
|
|
30441
|
+
this.jsonCollapsedPaths.set(collapsed);
|
|
30442
|
+
};
|
|
30443
|
+
// Merge every live repository's event stream into the rolling log, re-subscribing as the set of
|
|
30444
|
+
// repositories changes. Composed with RxJS (not a subscribe-in-effect) per the styleguide.
|
|
30445
|
+
toObservable(this.repositories)
|
|
30446
|
+
.pipe(switchMap((repos) => merge(...repos.map(({ repository, name, baseUrl }) => repository.events$.pipe(map((event) => ({ event, client: baseUrl || name })))))), tap(({ event, client }) => this.pushEvent(event, client)), takeUntilDestroyed())
|
|
30447
|
+
.subscribe();
|
|
30448
|
+
effect(() => {
|
|
30449
|
+
const state = {
|
|
30450
|
+
open: this.open(),
|
|
30451
|
+
height: this.panelHeight(),
|
|
30452
|
+
activeTab: this.activeTab(),
|
|
30453
|
+
selectedClientName: this.selectedClientName(),
|
|
30454
|
+
selectedQueryId: this.selectedQueryId(),
|
|
30455
|
+
inspectFilterIds: this.inspectFilterIds(),
|
|
30456
|
+
jsonSearch: this.jsonSearch(),
|
|
30457
|
+
expandedSteps: [...this.expandedSteps()],
|
|
30458
|
+
jsonExpanded: [...this.jsonExpandedPaths()],
|
|
30459
|
+
jsonCollapsed: [...this.jsonCollapsedPaths()],
|
|
30460
|
+
};
|
|
30461
|
+
try {
|
|
30462
|
+
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state));
|
|
30463
|
+
}
|
|
30464
|
+
catch {
|
|
30465
|
+
// ignore (private mode / disabled storage)
|
|
30466
|
+
}
|
|
30467
|
+
});
|
|
30468
|
+
// Close any open JIT editor on any selection / tab change, and reset the value-explorer search
|
|
30469
|
+
// when the *selected query* actually changes (but not on the initial restore, so a persisted
|
|
30470
|
+
// search survives a reload).
|
|
30471
|
+
this.lastSelectionKey = this.selectionKey();
|
|
30472
|
+
effect(() => {
|
|
30473
|
+
const key = this.selectionKey();
|
|
30474
|
+
this.activeTab();
|
|
30475
|
+
this.editorMode.set('none');
|
|
30476
|
+
this.editError.set(null);
|
|
30477
|
+
this.copiedReport.set(false);
|
|
30478
|
+
if (key !== this.lastSelectionKey) {
|
|
30479
|
+
this.lastSelectionKey = key;
|
|
30480
|
+
this.jsonSearch.set('');
|
|
30481
|
+
}
|
|
30482
|
+
});
|
|
30483
|
+
const doc = this.document;
|
|
30484
|
+
// Global toggle shortcut: Ctrl/Cmd + Alt + Q ("Q" for Query) — uncommon, no browser/OS conflict.
|
|
30485
|
+
fromEvent(doc, 'keydown')
|
|
30486
|
+
.pipe(filter((e) => (e.ctrlKey || e.metaKey) && e.altKey && e.key.toLowerCase() === 'q'), tap((e) => {
|
|
30487
|
+
e.preventDefault();
|
|
30488
|
+
this.open.update((v) => !v);
|
|
30489
|
+
}), takeUntilDestroyed())
|
|
30490
|
+
.subscribe();
|
|
30491
|
+
// Drag-to-resize: while a resize is in progress, track pointer movement on the document.
|
|
30492
|
+
toObservable(this.resizing)
|
|
30493
|
+
.pipe(switchMap((active) => active
|
|
30494
|
+
? merge(fromEvent(doc, 'pointermove').pipe(tap((e) => this.applyResize(e))), fromEvent(doc, 'pointerup').pipe(tap(() => this.resizing.set(false))))
|
|
30495
|
+
: EMPTY), takeUntilDestroyed())
|
|
30496
|
+
.subscribe();
|
|
30497
|
+
// Inspect mode: while active, listen on the document to map the hovered element to a query.
|
|
30498
|
+
const capture = { capture: true };
|
|
30499
|
+
toObservable(this.inspectActive)
|
|
30500
|
+
.pipe(tap((active) => {
|
|
30501
|
+
if (!active)
|
|
30502
|
+
this.inspectHover.set(null);
|
|
30503
|
+
}), switchMap((active) => active
|
|
30504
|
+
? merge(fromEvent(doc, 'mousemove', capture).pipe(tap((e) => this.updateInspectHover(e))), fromEvent(doc, 'click', capture).pipe(tap((e) => this.selectInspectedQuery(e))), fromEvent(doc, 'keydown', capture).pipe(tap((e) => {
|
|
30505
|
+
if (e.key === 'Escape')
|
|
30506
|
+
this.inspectActive.set(false);
|
|
30507
|
+
})))
|
|
30508
|
+
: EMPTY), takeUntilDestroyed())
|
|
30509
|
+
.subscribe();
|
|
30510
|
+
}
|
|
30511
|
+
toggleOpen() {
|
|
30512
|
+
this.open.update((v) => !v);
|
|
30513
|
+
}
|
|
30514
|
+
clearEvents() {
|
|
30515
|
+
this.eventLog.set([]);
|
|
30516
|
+
}
|
|
30517
|
+
selectClient(name) {
|
|
30518
|
+
this.selectedClientName.set(name);
|
|
30519
|
+
this.inspectFilterIds.set(null);
|
|
30520
|
+
}
|
|
30521
|
+
clearInspectFilter() {
|
|
30522
|
+
this.inspectFilterIds.set(null);
|
|
30523
|
+
}
|
|
30524
|
+
toggleInspect() {
|
|
30525
|
+
this.inspectActive.update((v) => !v);
|
|
30526
|
+
}
|
|
30527
|
+
startResize(event) {
|
|
30528
|
+
event.preventDefault();
|
|
30529
|
+
this.resizing.set(true);
|
|
30530
|
+
}
|
|
30531
|
+
inspectLabel(entries) {
|
|
30532
|
+
const first = entries[0];
|
|
30533
|
+
if (entries.length === 1 && first)
|
|
30534
|
+
return `${first.meta.method ?? ''} ${first.meta.route ?? ''}`.trim();
|
|
30535
|
+
return `${entries.length} queries`;
|
|
30536
|
+
}
|
|
30537
|
+
queryStatus(query) {
|
|
30538
|
+
const state = query.executionState();
|
|
30539
|
+
if (!state)
|
|
30540
|
+
return 'idle';
|
|
30541
|
+
if (state.type === 'loading')
|
|
30542
|
+
return 'loading';
|
|
30543
|
+
if (state.type === 'failure')
|
|
30544
|
+
return 'error';
|
|
30545
|
+
return 'success';
|
|
30546
|
+
}
|
|
30547
|
+
isStale(query) {
|
|
30548
|
+
try {
|
|
30549
|
+
return query.subtle.request()?.isStale() ?? false;
|
|
30550
|
+
}
|
|
30551
|
+
catch {
|
|
30552
|
+
return false;
|
|
30553
|
+
}
|
|
30554
|
+
}
|
|
30555
|
+
executeQuery(query, allowCache) {
|
|
30556
|
+
query.execute(allowCache ? { options: { allowCache: true } } : undefined);
|
|
30557
|
+
}
|
|
30558
|
+
resetQuery(query) {
|
|
30559
|
+
query.reset();
|
|
30560
|
+
}
|
|
30561
|
+
/**
|
|
30562
|
+
* Copies a shareable report (path, args, status, slimmed response) for handing to an API dev.
|
|
30563
|
+
* Writes both rich `text/html` (Slack applies formatting on paste — it does not parse markdown) and
|
|
30564
|
+
* a plain-text fallback.
|
|
30565
|
+
*/
|
|
30566
|
+
copyReport(entry, query) {
|
|
30567
|
+
const error = query.error();
|
|
30568
|
+
const httpStatus = error ? error.raw.status : this.responseStatus(query);
|
|
30569
|
+
const method = entry.meta.method ?? '';
|
|
30570
|
+
const route = entry.meta.route || '—';
|
|
30571
|
+
const client = entry.meta.clientBaseUrl ?? entry.meta.clientName ?? '';
|
|
30572
|
+
const statusLine = `status: ${this.queryStatus(query)}${httpStatus !== null ? ` (${httpStatus})` : ''} · ${this.formatTime(query.lastTimeExecutedAt())}`;
|
|
30573
|
+
const gqlDoc = entry.meta.gqlQuery ? this.gqlDocument(entry.meta.gqlQuery) : null;
|
|
30574
|
+
const args = query.args();
|
|
30575
|
+
const argsLabel = gqlDoc ? 'Variables' : 'Args';
|
|
30576
|
+
const argsJson = args !== null && args !== undefined ? JSON.stringify(args, null, 2) : null;
|
|
30577
|
+
const bodyLabel = error ? `Error (${error.raw.status})` : 'Response';
|
|
30578
|
+
const bodyContent = error
|
|
30579
|
+
? error.isList
|
|
30580
|
+
? error.errors.map((e) => e.message).join('\n')
|
|
30581
|
+
: error.error.message
|
|
30582
|
+
: JSON.stringify(slimForReport(query.response()), null, 2);
|
|
30583
|
+
const textParts = [`${method} ${route}${client ? ` — ${client}` : ''}`, statusLine];
|
|
30584
|
+
if (gqlDoc)
|
|
30585
|
+
textParts.push('', 'GraphQL document', gqlDoc);
|
|
30586
|
+
if (argsJson)
|
|
30587
|
+
textParts.push('', argsLabel, argsJson);
|
|
30588
|
+
textParts.push('', bodyLabel, bodyContent);
|
|
30589
|
+
const text = textParts.join('\n');
|
|
30590
|
+
const esc = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
30591
|
+
const htmlParts = [
|
|
30592
|
+
`<b>${esc(method)}</b> <code>${esc(route)}</code>${client ? ` — <code>${esc(client)}</code>` : ''}`,
|
|
30593
|
+
esc(statusLine),
|
|
30594
|
+
];
|
|
30595
|
+
if (gqlDoc)
|
|
30596
|
+
htmlParts.push('<b>GraphQL document</b>', `<pre><code>${esc(gqlDoc)}</code></pre>`);
|
|
30597
|
+
if (argsJson)
|
|
30598
|
+
htmlParts.push(`<b>${argsLabel}</b>`, `<pre><code>${esc(argsJson)}</code></pre>`);
|
|
30599
|
+
htmlParts.push(`<b>${esc(bodyLabel)}</b>`, `<pre><code>${esc(bodyContent)}</code></pre>`);
|
|
30600
|
+
const html = htmlParts.join('<br>');
|
|
30601
|
+
this.writeToClipboard(html, text);
|
|
30602
|
+
}
|
|
30603
|
+
// --- JIT editing ---
|
|
30604
|
+
openResponseEditor(query) {
|
|
30605
|
+
this.responseDraft.set(JSON.stringify(query.response() ?? null, null, 2));
|
|
30606
|
+
this.editError.set(null);
|
|
30607
|
+
this.editorMode.set('response');
|
|
30608
|
+
}
|
|
30609
|
+
openArgsEditor(query) {
|
|
30610
|
+
this.argsDraft.set(JSON.stringify(query.args() ?? {}, null, 2));
|
|
30611
|
+
this.editError.set(null);
|
|
30612
|
+
this.editorMode.set('args');
|
|
30613
|
+
}
|
|
30614
|
+
applyResponse(query) {
|
|
30615
|
+
try {
|
|
30616
|
+
query.subtle.setResponse(JSON.parse(this.responseDraft()));
|
|
30617
|
+
this.editorMode.set('none');
|
|
30618
|
+
this.editError.set(null);
|
|
30619
|
+
}
|
|
30620
|
+
catch {
|
|
30621
|
+
this.editError.set('Invalid JSON');
|
|
30622
|
+
}
|
|
30623
|
+
}
|
|
30624
|
+
applyArgs(query) {
|
|
30625
|
+
try {
|
|
30626
|
+
query.execute({ args: JSON.parse(this.argsDraft()) });
|
|
30627
|
+
this.editorMode.set('none');
|
|
30628
|
+
this.editError.set(null);
|
|
30629
|
+
}
|
|
30630
|
+
catch {
|
|
30631
|
+
this.editError.set('Invalid JSON');
|
|
30632
|
+
}
|
|
30633
|
+
}
|
|
30634
|
+
cancelEditor() {
|
|
30635
|
+
this.editorMode.set('none');
|
|
30636
|
+
this.editError.set(null);
|
|
30637
|
+
}
|
|
30638
|
+
// --- Force states ---
|
|
30639
|
+
forceLoading(query) {
|
|
30640
|
+
// `executionState` prioritises loading > error > response, so clear the others to switch cleanly.
|
|
30641
|
+
query.subtle.setError(null);
|
|
30642
|
+
query.subtle.setLoading({ executeTime: Date.now(), progress: null });
|
|
30643
|
+
}
|
|
30644
|
+
forceError(query) {
|
|
30645
|
+
query.subtle.setLoading(null);
|
|
30646
|
+
// A real failed execution also drops the response, so mirror that for consumers bound to it.
|
|
30647
|
+
query.subtle.setResponse(null);
|
|
30648
|
+
query.subtle.setError(createQueryErrorResponse(new HttpErrorResponse({
|
|
30649
|
+
status: 500,
|
|
30650
|
+
statusText: 'Forced',
|
|
30651
|
+
error: { message: 'Forced error (devtools)' },
|
|
30652
|
+
})));
|
|
30653
|
+
}
|
|
30654
|
+
forceEmpty(query) {
|
|
30655
|
+
query.subtle.setLoading(null);
|
|
30656
|
+
query.subtle.setError(null);
|
|
30657
|
+
query.subtle.setResponse(null);
|
|
30658
|
+
}
|
|
30659
|
+
clearForced(query) {
|
|
30660
|
+
query.subtle.setLoading(null);
|
|
30661
|
+
query.subtle.setError(null);
|
|
30662
|
+
}
|
|
30663
|
+
// --- Cache actions ---
|
|
30664
|
+
refetchCacheEntry(entry) {
|
|
30665
|
+
entry.request.execute();
|
|
30666
|
+
}
|
|
30667
|
+
evictCacheEntry(repository, key) {
|
|
30668
|
+
repository.subtle.evict(key);
|
|
30669
|
+
}
|
|
30670
|
+
cacheFreshness(entry) {
|
|
30671
|
+
this.clock();
|
|
30672
|
+
if (entry.request.loading())
|
|
30673
|
+
return 'refreshing…';
|
|
30674
|
+
const expiresAt = entry.request.expiresAt();
|
|
30675
|
+
if (expiresAt === null)
|
|
30676
|
+
return 'uncacheable';
|
|
30677
|
+
const ms = expiresAt - Date.now();
|
|
30678
|
+
return ms <= 0 ? 'stale' : `${Math.ceil(ms / 1000)}s`;
|
|
30679
|
+
}
|
|
30680
|
+
/** The path + query of a request URL (origin stripped), for readable cache/event identifiers. */
|
|
30681
|
+
requestPath(url) {
|
|
30682
|
+
try {
|
|
30683
|
+
const parsed = new URL(url);
|
|
30684
|
+
return parsed.pathname + parsed.search;
|
|
30685
|
+
}
|
|
30686
|
+
catch {
|
|
30687
|
+
return url;
|
|
30688
|
+
}
|
|
30689
|
+
}
|
|
30690
|
+
// --- Typed template accessors (entry.handle is `unknown`) ---
|
|
30691
|
+
asStack(entry) {
|
|
30692
|
+
return entry.handle;
|
|
30693
|
+
}
|
|
30694
|
+
asPagedStack(entry) {
|
|
30695
|
+
return entry.handle;
|
|
30696
|
+
}
|
|
30697
|
+
asSequence(entry) {
|
|
30698
|
+
return entry.handle.current;
|
|
30699
|
+
}
|
|
30700
|
+
asAuth(entry) {
|
|
30701
|
+
return entry.handle;
|
|
30702
|
+
}
|
|
30703
|
+
asWs(entry) {
|
|
30704
|
+
return entry.handle;
|
|
30705
|
+
}
|
|
30706
|
+
/** Derives the per-step status of a sequence step from its live progress signals. */
|
|
30707
|
+
sequenceStepStatus(sequence, index) {
|
|
30708
|
+
const failedAt = sequence.failedAt();
|
|
30709
|
+
if (failedAt !== null && index === failedAt)
|
|
30710
|
+
return 'error';
|
|
30711
|
+
const current = sequence.currentStep();
|
|
30712
|
+
const running = sequence.running();
|
|
30713
|
+
if (index < current - 1)
|
|
30714
|
+
return 'success';
|
|
30715
|
+
if (index === current - 1 && running)
|
|
30716
|
+
return 'running';
|
|
30717
|
+
if (sequence.status() === 'success')
|
|
30718
|
+
return 'success';
|
|
30719
|
+
return 'idle';
|
|
30720
|
+
}
|
|
30721
|
+
authTokenPayload(auth) {
|
|
30722
|
+
return decodeJwtPayload(auth.accessToken());
|
|
30723
|
+
}
|
|
30724
|
+
queriesForStack(stack) {
|
|
30725
|
+
const inner = stack.queries();
|
|
30726
|
+
const queryEntries = this.queryEntries();
|
|
30727
|
+
return inner.map((query) => {
|
|
30728
|
+
const entry = queryEntries.find((e) => e.handle === query);
|
|
30729
|
+
return {
|
|
30730
|
+
id: entry?.id ?? '',
|
|
30731
|
+
query: query,
|
|
30732
|
+
method: entry?.meta.method ?? '',
|
|
30733
|
+
route: entry?.meta.route ?? '',
|
|
30734
|
+
clientName: entry?.meta.clientName ?? '',
|
|
30735
|
+
clientBaseUrl: entry?.meta.clientBaseUrl ?? '',
|
|
30736
|
+
};
|
|
30737
|
+
});
|
|
30738
|
+
}
|
|
30739
|
+
/** Identifying info for a stack, derived from its (uniform) inner queries. */
|
|
30740
|
+
stackIdentity(stack) {
|
|
30741
|
+
const first = this.queriesForStack(stack)[0];
|
|
30742
|
+
return { method: first?.method ?? '', route: first?.route ?? '', baseUrl: first?.clientBaseUrl ?? '' };
|
|
30743
|
+
}
|
|
30744
|
+
authFeatures(auth) {
|
|
30745
|
+
return Object.keys(auth.features ?? {});
|
|
30746
|
+
}
|
|
30747
|
+
authQueryKeys(auth) {
|
|
30748
|
+
return Object.keys(auth.queries ?? {});
|
|
30749
|
+
}
|
|
30750
|
+
/** Countdown to the access-token's `exp` (the point a refresh becomes due), or `null` if unknown. */
|
|
30751
|
+
authTokenExpiry(auth) {
|
|
30752
|
+
this.clock();
|
|
30753
|
+
const payload = decodeJwtPayload(auth.accessToken());
|
|
30754
|
+
const exp = typeof payload?.['exp'] === 'number' ? payload['exp'] : null;
|
|
30755
|
+
if (exp === null)
|
|
30756
|
+
return null;
|
|
30757
|
+
const seconds = Math.round((exp * 1000 - Date.now()) / 1000);
|
|
30758
|
+
if (seconds <= 0)
|
|
30759
|
+
return 'expired';
|
|
30760
|
+
if (seconds < 120)
|
|
30761
|
+
return `${seconds}s`;
|
|
30762
|
+
if (seconds > 86400)
|
|
30763
|
+
return `${Math.floor(seconds / 86400)}d`;
|
|
30764
|
+
return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
|
|
30765
|
+
}
|
|
30766
|
+
queriesForSequence(sequence) {
|
|
30767
|
+
const queryEntries = this.queryEntries();
|
|
30768
|
+
return sequence.queries.map((query) => {
|
|
30769
|
+
const entry = queryEntries.find((e) => e.handle === query);
|
|
30770
|
+
return {
|
|
30771
|
+
id: entry?.id ?? '',
|
|
30772
|
+
query: query,
|
|
30773
|
+
method: entry?.meta.method ?? '',
|
|
30774
|
+
route: entry?.meta.route ?? '',
|
|
30775
|
+
};
|
|
30776
|
+
});
|
|
30777
|
+
}
|
|
30778
|
+
/** The snapshot of a sequence step, once it has run (holds the args in and the response/error out). */
|
|
30779
|
+
stepSnapshot(sequence, index) {
|
|
30780
|
+
return sequence.snapshots()[index] ?? null;
|
|
30781
|
+
}
|
|
30782
|
+
isStepExpanded(entryId, index) {
|
|
30783
|
+
return this.expandedSteps().has(this.stepKey(entryId, index));
|
|
30784
|
+
}
|
|
30785
|
+
toggleStep(entryId, index) {
|
|
30786
|
+
const key = this.stepKey(entryId, index);
|
|
30787
|
+
const next = new Set(this.expandedSteps());
|
|
30788
|
+
if (next.has(key)) {
|
|
30789
|
+
next.delete(key);
|
|
30790
|
+
}
|
|
30791
|
+
else {
|
|
30792
|
+
next.add(key);
|
|
30793
|
+
}
|
|
30794
|
+
this.expandedSteps.set(next);
|
|
30795
|
+
}
|
|
30796
|
+
/** Dedents a GraphQL document (template-literal indentation) for readable display. */
|
|
30797
|
+
gqlDocument(doc) {
|
|
30798
|
+
const lines = doc.replace(/\t/g, ' ').split('\n');
|
|
30799
|
+
while (lines.length && !lines[0]?.trim())
|
|
30800
|
+
lines.shift();
|
|
30801
|
+
while (lines.length && !lines[lines.length - 1]?.trim())
|
|
30802
|
+
lines.pop();
|
|
30803
|
+
const indents = lines.filter((l) => l.trim()).map((l) => l.match(/^ */)?.[0].length ?? 0);
|
|
30804
|
+
const min = indents.length ? Math.min(...indents) : 0;
|
|
30805
|
+
return lines.map((l) => l.slice(min)).join('\n');
|
|
30806
|
+
}
|
|
30807
|
+
featureLabel(type) {
|
|
30808
|
+
return type
|
|
30809
|
+
.replace(/^WITH_/, '')
|
|
30810
|
+
.replace(/_/g, ' ')
|
|
30811
|
+
.toLowerCase();
|
|
30812
|
+
}
|
|
30813
|
+
formatTime(timestamp) {
|
|
30814
|
+
if (!timestamp)
|
|
30815
|
+
return '—';
|
|
30816
|
+
return new Date(timestamp).toLocaleTimeString(undefined, { hour12: false });
|
|
30817
|
+
}
|
|
30818
|
+
stepKey(entryId, index) {
|
|
30819
|
+
return `${entryId}:${index}`;
|
|
30820
|
+
}
|
|
30821
|
+
applyResize(event) {
|
|
30822
|
+
// The panel is docked to the bottom, so its height is the distance from the pointer to the viewport bottom.
|
|
30823
|
+
const viewport = this.document.documentElement.clientHeight;
|
|
30824
|
+
const next = viewport - event.clientY;
|
|
30825
|
+
const max = Math.round(viewport * 0.9);
|
|
30826
|
+
this.panelHeight.set(Math.min(Math.max(next, MIN_HEIGHT), max));
|
|
30827
|
+
}
|
|
30828
|
+
updateInspectHover(event) {
|
|
30829
|
+
const host = this.hostEl.nativeElement;
|
|
30830
|
+
const map = this.elementQueryMap();
|
|
30831
|
+
let node = event.target;
|
|
30832
|
+
// Ignore the devtools UI itself.
|
|
30833
|
+
if (node && host.contains(node)) {
|
|
30834
|
+
this.inspectHover.set(null);
|
|
30835
|
+
return;
|
|
30836
|
+
}
|
|
30837
|
+
while (node) {
|
|
30838
|
+
const entries = map.get(node);
|
|
30839
|
+
if (entries) {
|
|
30840
|
+
this.inspectHover.set({ rect: node.getBoundingClientRect(), entries });
|
|
30841
|
+
return;
|
|
30842
|
+
}
|
|
30843
|
+
node = node.parentElement;
|
|
30844
|
+
}
|
|
30845
|
+
this.inspectHover.set(null);
|
|
30846
|
+
}
|
|
30847
|
+
selectInspectedQuery(event) {
|
|
30848
|
+
const hover = this.inspectHover();
|
|
30849
|
+
const first = hover?.entries[0];
|
|
30850
|
+
if (!hover || !first)
|
|
30851
|
+
return;
|
|
30852
|
+
event.preventDefault();
|
|
30853
|
+
event.stopPropagation();
|
|
30854
|
+
const ids = hover.entries.map((e) => e.id);
|
|
30855
|
+
this.open.set(true);
|
|
30856
|
+
this.activeTab.set('queries');
|
|
30857
|
+
this.selectedClientName.set(null);
|
|
30858
|
+
this.inspectFilterIds.set(ids);
|
|
30859
|
+
// Auto-select when the element owns a single query, otherwise let the user pick from the filtered list.
|
|
30860
|
+
this.selectedQueryId.set(ids.length === 1 ? first.id : null);
|
|
30861
|
+
this.inspectActive.set(false);
|
|
30862
|
+
}
|
|
30863
|
+
selectionKey() {
|
|
30864
|
+
return `${this.selectedQueryId()}|${this.stackSelectedQueryId()}|${this.sequenceSelectedQueryId()}`;
|
|
30865
|
+
}
|
|
30866
|
+
writeToClipboard(html, text) {
|
|
30867
|
+
const clipboard = navigator.clipboard;
|
|
30868
|
+
if (!clipboard)
|
|
30869
|
+
return;
|
|
30870
|
+
// Prefer rich HTML (Slack keeps the formatting on paste); fall back to plain text.
|
|
30871
|
+
if ('write' in clipboard && typeof ClipboardItem !== 'undefined') {
|
|
30872
|
+
const item = new ClipboardItem({
|
|
30873
|
+
'text/html': new Blob([html], { type: 'text/html' }),
|
|
30874
|
+
'text/plain': new Blob([text], { type: 'text/plain' }),
|
|
30875
|
+
});
|
|
30876
|
+
clipboard
|
|
30877
|
+
.write([item])
|
|
30878
|
+
.then(() => this.copiedReport.set(true))
|
|
30879
|
+
.catch(() => clipboard
|
|
30880
|
+
.writeText(text)
|
|
30881
|
+
.then(() => this.copiedReport.set(true))
|
|
30882
|
+
.catch(() => undefined));
|
|
30883
|
+
return;
|
|
30884
|
+
}
|
|
30885
|
+
clipboard
|
|
30886
|
+
.writeText(text)
|
|
30887
|
+
.then(() => this.copiedReport.set(true))
|
|
30888
|
+
.catch(() => undefined);
|
|
30889
|
+
}
|
|
30890
|
+
responseStatus(query) {
|
|
30891
|
+
const event = query.latestHttpEvent();
|
|
30892
|
+
return typeof event?.status === 'number' ? event.status : null;
|
|
30893
|
+
}
|
|
30894
|
+
findQuery(id) {
|
|
30895
|
+
if (!id)
|
|
30896
|
+
return null;
|
|
30897
|
+
const entry = this.queryEntries().find((e) => e.id === id);
|
|
30898
|
+
return entry ? { entry, query: entry.handle } : null;
|
|
30899
|
+
}
|
|
30900
|
+
pushEvent(event, client) {
|
|
30901
|
+
const item = {
|
|
30902
|
+
id: this.eventIdCounter++,
|
|
30903
|
+
timestamp: Date.now(),
|
|
30904
|
+
client,
|
|
30905
|
+
type: event.type,
|
|
30906
|
+
method: event.request.method,
|
|
30907
|
+
url: event.request.url,
|
|
30908
|
+
isSecure: event.isSecure,
|
|
30909
|
+
status: event.type === 'request-error' ? event.error.status : null,
|
|
30910
|
+
};
|
|
30911
|
+
this.eventLog.update((log) => [item, ...log].slice(0, MAX_EVENTS));
|
|
30912
|
+
}
|
|
30913
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
30914
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools-host" }, ngImport: i0, template: "@if (open()) {\n <section\n [class.et-query-devtools-panel--resizing]=\"resizing()\"\n [style.height.px]=\"panelHeight()\"\n class=\"et-query-devtools-panel\"\n >\n <div\n (pointerdown)=\"startResize($event)\"\n class=\"et-query-devtools-resize\"\n title=\"Drag to resize\"\n aria-hidden=\"true\"\n ></div>\n <header class=\"et-query-devtools-header\">\n <nav class=\"et-query-devtools-tabs\" role=\"tablist\">\n @for (tab of tabs; track tab.id) {\n <button\n [class.et-query-devtools-tab--active]=\"activeTab() === tab.id\"\n [attr.aria-selected]=\"activeTab() === tab.id\"\n (click)=\"activeTab.set(tab.id)\"\n class=\"et-query-devtools-tab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n </button>\n }\n </nav>\n\n <div class=\"et-query-devtools-header-actions\">\n <button\n [class.et-query-devtools-inspect-btn--active]=\"inspectActive()\"\n (click)=\"toggleInspect()\"\n class=\"et-query-devtools-inspect-btn\"\n type=\"button\"\n title=\"Inspect: hover the UI to find its query\"\n >\n \u2316 Inspect\n </button>\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-close\" type=\"button\" title=\"Close devtools\">\u2715</button>\n </div>\n </header>\n\n <div class=\"et-query-devtools-body\">\n @switch (activeTab()) {\n <!-- QUERIES -->\n @case ('queries') {\n <div class=\"et-query-devtools-master-detail\">\n <div class=\"et-query-devtools-list\">\n <div class=\"et-query-devtools-toolbar\">\n @if (inspectFilterIds(); as ids) {\n <span class=\"et-query-devtools-filter-chip\">\u2316 inspected \u00B7 {{ ids.length }}</span>\n <button (click)=\"clearInspectFilter()\" class=\"et-query-devtools-btn\" type=\"button\">Reset</button>\n } @else {\n <label class=\"et-query-devtools-field\">\n <span>Client</span>\n <select\n #clientSelect\n [value]=\"selectedClientName() ?? ''\"\n (change)=\"selectClient(clientSelect.value || null)\"\n class=\"et-query-devtools-select\"\n >\n <option value=\"\">All clients</option>\n @for (name of clientNames(); track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n </label>\n }\n <span class=\"et-query-devtools-count\">{{ filteredQueries().length }}</span>\n </div>\n\n @for (item of filteredQueries(); track item.entry.id) {\n <button\n [class.et-query-devtools-row--active]=\"selectedQueryId() === item.entry.id\"\n (click)=\"selectedQueryId.set(item.entry.id)\"\n class=\"et-query-devtools-row\"\n type=\"button\"\n >\n <span\n [attr.data-status]=\"queryStatus(item.query)\"\n [title]=\"queryStatus(item.query)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ item.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">{{ item.entry.meta.route || '\u2014' }}</span>\n @if (isStale(item.query)) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">stale</span>\n }\n </button>\n } @empty {\n @if (inspectFilterIds()) {\n <p class=\"et-query-devtools-empty\">\n The inspected element's queries are no longer registered. Reset the filter.\n </p>\n } @else {\n <p class=\"et-query-devtools-empty\">No queries registered.</p>\n }\n }\n </div>\n\n <div class=\"et-query-devtools-detail\">\n @if (selectedQuery(); as sel) {\n <ng-container *ngTemplateOutlet=\"queryDetailTpl; context: { sel }\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Select a query to inspect it.</p>\n }\n </div>\n </div>\n }\n\n <!-- STACKS -->\n @case ('stacks') {\n <div class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of stackEntries(); track entry.id) {\n @if (entry.kind === 'paged-query-stack') {\n @let paged = asPagedStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">paged stack</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ paged.direction() }}</span>\n @if (paged.loading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n </div>\n\n @let pagedId = stackIdentity(paged);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ pagedId.method }}</span>\n <span class=\"et-query-devtools-route\">{{ pagedId.route }}</span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ pagedId.baseUrl }}</div>\n @if (entry.meta.featureTypes?.length) {\n <div class=\"et-query-devtools-chips\">\n @for (feature of entry.meta.featureTypes; track feature) {\n <span class=\"et-query-devtools-chip\">{{ featureLabel(feature) }}</span>\n }\n </div>\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Pages loaded</dt>\n <dd>{{ paged.queries().length }}</dd>\n <dt>Items</dt>\n <dd>{{ paged.items().length }}</dd>\n <dt>First page loaded</dt>\n <dd>{{ paged.isFirstPageLoaded() }}</dd>\n <dt>Last page loaded</dt>\n <dd>{{ paged.isLastPageLoaded() }}</dd>\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueriesTpl; context: { links: queriesForStack(paged) }\" />\n </div>\n } @else {\n @let stack = asStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">stack</span>\n @if (stack.anyLoading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n @if (stack.anyError()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">error</span>\n }\n </div>\n\n @let stackId = stackIdentity(stack);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ stackId.method }}</span>\n <span class=\"et-query-devtools-route\">{{ stackId.route }}</span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ stackId.baseUrl }}</div>\n @if (entry.meta.featureTypes?.length) {\n <div class=\"et-query-devtools-chips\">\n @for (feature of entry.meta.featureTypes; track feature) {\n <span class=\"et-query-devtools-chip\">{{ featureLabel(feature) }}</span>\n }\n </div>\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Queries</dt>\n <dd>{{ stack.queries().length }}</dd>\n <dt>Loading</dt>\n <dd>{{ stack.loadingProgress().loaded }} / {{ stack.loadingProgress().total }}</dd>\n <dt>Errors</dt>\n <dd>{{ stack.errors().length }}</dd>\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueriesTpl; context: { links: queriesForStack(stack) }\" />\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No stacks registered.</p>\n }\n </div>\n\n @if (stackSelectedQuery(); as sel) {\n <aside class=\"et-query-devtools-drawer\">\n <div class=\"et-query-devtools-drawer-head\">\n <span>Query detail</span>\n <button\n (click)=\"stackSelectedQueryId.set(null)\"\n class=\"et-query-devtools-close\"\n type=\"button\"\n title=\"Close detail\"\n >\n \u2715\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"queryDetailTpl; context: { sel }\" />\n </aside>\n }\n </div>\n }\n\n <!-- SEQUENCES -->\n @case ('sequences') {\n <div class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of sequenceEntries(); track entry.id) {\n @let sequence = asSequence(entry);\n @if (sequence) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">sequence</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ sequence.status() }}</span>\n <span class=\"et-query-devtools-count\"\n >step {{ sequence.currentStep() }} / {{ sequence.total }}</span\n >\n </div>\n\n <ol class=\"et-query-devtools-step-list\">\n @for (link of queriesForSequence(sequence); track $index; let i = $index) {\n <li [attr.data-status]=\"sequenceStepStatus(sequence, i)\" class=\"et-query-devtools-step-item\">\n <div class=\"et-query-devtools-step-head\">\n <button\n [class.et-query-devtools-inner-row--active]=\"sequenceSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"sequenceSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span\n [attr.data-status]=\"sequenceStepStatus(sequence, i)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ i + 1 }}. {{ link.method }}</span>\n <span class=\"et-query-devtools-route\">{{ link.route || 'step ' + (i + 1) }}</span>\n </button>\n <button\n [attr.aria-expanded]=\"isStepExpanded(entry.id, i)\"\n (click)=\"toggleStep(entry.id, i)\"\n class=\"et-query-devtools-step-caret-btn\"\n type=\"button\"\n title=\"Toggle in / out\"\n >\n {{ isStepExpanded(entry.id, i) ? '\u25BE' : '\u25B8' }}\n </button>\n </div>\n\n @if (isStepExpanded(entry.id, i)) {\n @let snap = stepSnapshot(sequence, i);\n <div class=\"et-query-devtools-step-io\">\n <h5 class=\"et-query-devtools-section\">In \u00B7 args</h5>\n @if (sequence.stepArgs().length > i) {\n <et-query-devtools-json [value]=\"sequence.stepArgs()[i]\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n\n @if (snap?.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 error ({{ error.raw.status }})</h5>\n <et-query-devtools-json [value]=\"error.isList ? error.errors : error.error\" />\n } @else {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 response</h5>\n @if (snap) {\n <et-query-devtools-json [value]=\"snap.response()\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n }\n </div>\n }\n </li>\n }\n </ol>\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No sequences registered.</p>\n }\n </div>\n\n @if (sequenceSelectedQuery(); as sel) {\n <aside class=\"et-query-devtools-drawer\">\n <div class=\"et-query-devtools-drawer-head\">\n <span>Query detail</span>\n <button\n (click)=\"sequenceSelectedQueryId.set(null)\"\n class=\"et-query-devtools-close\"\n type=\"button\"\n title=\"Close detail\"\n >\n \u2715\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"queryDetailTpl; context: { sel }\" />\n </aside>\n }\n </div>\n }\n\n <!-- AUTH -->\n @case ('auth') {\n <div class=\"et-query-devtools-scroll\">\n @for (entry of authEntries(); track entry.id) {\n @let auth = asAuth(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'auth provider' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"auth.isAuthenticated()\"\n [class.et-query-devtools-chip--muted]=\"!auth.isAuthenticated()\"\n class=\"et-query-devtools-chip\"\n >\n {{ auth.isAuthenticated() ? 'authenticated' : 'anonymous' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.clientBaseUrl || entry.meta.clientName || '\u2014' }}</dd>\n <dt>Access token</dt>\n <dd>{{ auth.accessToken() ? 'present' : 'none' }}</dd>\n <dt>Refresh token</dt>\n <dd>{{ auth.refreshToken() ? 'present' : 'none' }}</dd>\n @if (authTokenExpiry(auth); as expiry) {\n <dt>Token expires in</dt>\n <dd>{{ expiry }}</dd>\n }\n @if (auth.executionState(); as state) {\n <dt>Execution state</dt>\n <dd>{{ state.type }} \u00B7 {{ state.state }}</dd>\n }\n @if (authQueryKeys(auth).length) {\n <dt>Queries</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (key of authQueryKeys(auth); track key) {\n <span class=\"et-query-devtools-chip\">{{ key }}</span>\n }\n </div>\n </dd>\n }\n @if (authFeatures(auth).length) {\n <dt>Features</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (feature of authFeatures(auth); track feature) {\n <span class=\"et-query-devtools-chip\">{{ feature }}</span>\n }\n </div>\n </dd>\n }\n </dl>\n\n @if (authTokenPayload(auth); as payload) {\n <h4 class=\"et-query-devtools-section\">Access token payload</h4>\n <et-query-devtools-json [value]=\"payload\" />\n }\n\n @if (auth.latestNonInternalQuery(); as latest) {\n <h4 class=\"et-query-devtools-section\">Latest auth query \u00B7 {{ latest.key }}</h4>\n <et-query-devtools-json [value]=\"latest.snapshot.response()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No auth providers registered.</p>\n }\n </div>\n }\n\n <!-- SOCKETS -->\n @case ('ws') {\n <div class=\"et-query-devtools-scroll\">\n @for (entry of wsEntries(); track entry.id) {\n @let ws = asWs(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'socket' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"ws.connected()\"\n [class.et-query-devtools-chip--muted]=\"!ws.connected()\"\n class=\"et-query-devtools-chip\"\n >\n {{ ws.connected() ? 'connected' : 'disconnected' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.url }}</dd>\n <dt>Rooms</dt>\n <dd>\n @if (ws.rooms().length) {\n <div class=\"et-query-devtools-chips\">\n @for (room of ws.rooms(); track room) {\n <span class=\"et-query-devtools-chip\">{{ room }}</span>\n }\n </div>\n } @else {\n none\n }\n </dd>\n </dl>\n\n <h5 class=\"et-query-devtools-section\">Messages ({{ ws.messages().length }})</h5>\n @for (message of ws.messages(); track message.id) {\n <div class=\"et-query-devtools-ws-message\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-count\">{{ formatTime(message.timestamp) }}</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ message.room }}</span>\n <span class=\"et-query-devtools-method\">{{ message.event }}</span>\n </div>\n <et-query-devtools-json [value]=\"message.data\" />\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No messages received yet.</p>\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No web socket clients registered.</p>\n }\n </div>\n }\n\n <!-- CACHE -->\n @case ('cache') {\n <div class=\"et-query-devtools-scroll\">\n @for (client of cacheView(); track client.name) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.baseUrl || client.name }}</strong>\n <span class=\"et-query-devtools-count\">{{ client.entries.length }} entries</span>\n </div>\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Request</th>\n <th>Consumers</th>\n <th>Secure</th>\n <th>Freshness</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (cacheEntry of client.entries; track cacheEntry.key) {\n <tr>\n <td [title]=\"cacheEntry.request.method + ' ' + cacheEntry.request.url\">\n <span class=\"et-query-devtools-method\">{{ cacheEntry.request.method }}</span>\n <span class=\"et-query-devtools-url\">{{ requestPath(cacheEntry.request.url) }}</span>\n </td>\n <td>{{ cacheEntry.consumerCount }}</td>\n <td>{{ cacheEntry.isSecure ? 'yes' : 'no' }}</td>\n <td>{{ cacheFreshness(cacheEntry) }}</td>\n <td class=\"et-query-devtools-cell-actions\">\n <button (click)=\"refetchCacheEntry(cacheEntry)\" class=\"et-query-devtools-btn\" type=\"button\">\n Refetch\n </button>\n <button\n (click)=\"evictCacheEntry(client.repository, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Evict\n </button>\n </td>\n </tr>\n } @empty {\n <tr>\n <td class=\"et-query-devtools-empty\" colspan=\"5\">Cache empty.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No clients with a cache yet.</p>\n }\n </div>\n }\n\n <!-- EVENTS -->\n @case ('events') {\n <div class=\"et-query-devtools-scroll\">\n <div class=\"et-query-devtools-toolbar\">\n <span class=\"et-query-devtools-count\">{{ eventLog().length }} events</span>\n <button (click)=\"clearEvents()\" class=\"et-query-devtools-btn\" type=\"button\">Clear</button>\n </div>\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Time</th>\n <th>Base URL</th>\n <th>Type</th>\n <th>Request</th>\n </tr>\n </thead>\n <tbody>\n @for (event of eventLog(); track event.id) {\n <tr [attr.data-status]=\"event.type === 'request-error' ? 'error' : 'success'\">\n <td>{{ formatTime(event.timestamp) }}</td>\n <td class=\"et-query-devtools-mono\">{{ event.client }}</td>\n <td>\n {{ event.type === 'request-error' ? 'error ' + event.status : 'success' }}\n @if (event.isSecure) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">secure</span>\n }\n </td>\n <td [title]=\"event.method + ' ' + event.url\">\n <span class=\"et-query-devtools-method\">{{ event.method }}</span>\n <span class=\"et-query-devtools-url\">{{ requestPath(event.url) }}</span>\n </td>\n </tr>\n } @empty {\n <tr>\n <td class=\"et-query-devtools-empty\" colspan=\"4\">No events captured yet.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n </div>\n\n <!-- Reusable inner-query list (stacks) \u2014 clicking opens the split-view drawer, not a tab switch. -->\n <ng-template #innerQueriesTpl let-links=\"links\">\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of links; track $index) {\n <button\n [class.et-query-devtools-inner-row--active]=\"stackSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"stackSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">{{ link.route || link.query.id() || 'query ' + ($index + 1) }}</span>\n </button>\n }\n </div>\n </ng-template>\n\n <!-- Reusable query detail \u2014 used by the Queries tab and the stacks split-view drawer. -->\n <ng-template #queryDetailTpl let-sel=\"sel\">\n <div class=\"et-query-devtools-detail-head\">\n <span class=\"et-query-devtools-method\">{{ sel.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">{{ sel.entry.meta.route || '\u2014' }}</span>\n </div>\n\n <div class=\"et-query-devtools-actions\">\n <span class=\"et-query-devtools-actions-label\">Run</span>\n <button (click)=\"executeQuery(sel.query, false)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"executeQuery(sel.query, true)\" class=\"et-query-devtools-btn\" type=\"button\">Cached</button>\n <button (click)=\"resetQuery(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Reset</button>\n <button (click)=\"copyReport(sel.entry, sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">\n {{ copiedReport() ? '\u2713 Copied' : 'Copy report' }}\n </button>\n <span class=\"et-query-devtools-actions-label\">Edit</span>\n <button (click)=\"openResponseEditor(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Response</button>\n <button (click)=\"openArgsEditor(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Replay args</button>\n <span class=\"et-query-devtools-actions-label\">Force</span>\n <button (click)=\"forceLoading(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Loading</button>\n <button (click)=\"forceError(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Error</button>\n <button (click)=\"forceEmpty(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Empty</button>\n <button (click)=\"clearForced(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Clear</button>\n </div>\n\n @if (editorMode() !== 'none') {\n <div class=\"et-query-devtools-editor\">\n @if (editorMode() === 'response') {\n <h4 class=\"et-query-devtools-section\">Edit response \u2192 setResponse()</h4>\n <textarea\n #respArea\n [value]=\"responseDraft()\"\n (input)=\"responseDraft.set(respArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"applyResponse(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Apply</button>\n <button (click)=\"cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n } @else {\n <h4 class=\"et-query-devtools-section\">Replay with edited args \u2192 execute()</h4>\n <textarea\n #argsArea\n [value]=\"argsDraft()\"\n (input)=\"argsDraft.set(argsArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"applyArgs(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n }\n @if (editError(); as err) {\n <p class=\"et-query-devtools-editor-error\">{{ err }}</p>\n }\n </div>\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ sel.entry.meta.clientBaseUrl || sel.entry.meta.clientName || '\u2014' }}</dd>\n <dt>Status</dt>\n <dd>{{ queryStatus(sel.query) }}</dd>\n <dt>Cache key</dt>\n <dd class=\"et-query-devtools-mono\">{{ sel.query.id() || '\u2014' }}</dd>\n <dt>Last executed</dt>\n <dd>{{ formatTime(sel.query.lastTimeExecutedAt()) }}</dd>\n <dt>Triggered by</dt>\n <dd>{{ sel.query.triggeredBy() || 'user' }}</dd>\n @if (sel.entry.meta.featureTypes?.length) {\n <dt>Features</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (feature of sel.entry.meta.featureTypes; track feature) {\n <span class=\"et-query-devtools-chip\">{{ featureLabel(feature) }}</span>\n }\n </div>\n </dd>\n }\n </dl>\n\n @if (sel.entry.meta.gqlQuery; as gqlQuery) {\n <h5 class=\"et-query-devtools-section\">GraphQL document</h5>\n <pre class=\"et-query-devtools-code\">{{ gqlDocument(gqlQuery) }}</pre>\n }\n\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Value explorer</h4>\n <input\n #jsonSearchInput\n [value]=\"jsonSearch()\"\n (input)=\"jsonSearch.set(jsonSearchInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter keys / values\u2026\"\n />\n </div>\n\n <h5 class=\"et-query-devtools-section\">Args</h5>\n <et-query-devtools-json\n [value]=\"sel.query.args()\"\n [search]=\"jsonSearchTerm()\"\n [expandedPaths]=\"jsonExpandedPaths()\"\n [collapsedPaths]=\"jsonCollapsedPaths()\"\n [toggleFn]=\"toggleJsonPath\"\n path=\"args\"\n />\n\n @if (sel.query.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Error ({{ error.raw.status }})</h5>\n <et-query-devtools-json\n [value]=\"error.isList ? error.errors : error.error\"\n [search]=\"jsonSearchTerm()\"\n [expandedPaths]=\"jsonExpandedPaths()\"\n [collapsedPaths]=\"jsonCollapsedPaths()\"\n [toggleFn]=\"toggleJsonPath\"\n path=\"error\"\n />\n } @else {\n <h5 class=\"et-query-devtools-section\">Response</h5>\n <et-query-devtools-json\n [value]=\"sel.query.response()\"\n [search]=\"jsonSearchTerm()\"\n [expandedPaths]=\"jsonExpandedPaths()\"\n [collapsedPaths]=\"jsonCollapsedPaths()\"\n [toggleFn]=\"toggleJsonPath\"\n path=\"response\"\n />\n }\n </ng-template>\n </section>\n}\n\n@if (!open()) {\n <et-query-devtools-toggle (openChange)=\"toggleOpen()\" />\n}\n\n@if (inspectActive() && inspectHover(); as hover) {\n <div\n [style.left.px]=\"hover.rect.left\"\n [style.top.px]=\"hover.rect.top\"\n [style.width.px]=\"hover.rect.width\"\n [style.height.px]=\"hover.rect.height\"\n class=\"et-query-devtools-inspect-box\"\n >\n <span class=\"et-query-devtools-inspect-tag\">{{ inspectLabel(hover.entries) }}</span>\n </div>\n}\n", styles: ["@layer components{.et-query-devtools-host{--_et-qdt-bg: var(--et-surface-background-solid, rgb(24 24 27));--_et-qdt-fg: var(--et-surface-color-solid, rgb(244 244 245));--_et-qdt-muted: var(--et-surface-color-muted-solid, rgb(161 161 170));--_et-qdt-subtle: var(--et-surface-color-subtle-solid, rgb(113 113 122));--_et-qdt-border: var(--et-surface-border-solid, rgb(255 255 255 / .12));--_et-qdt-interaction: var(--et-surface-interaction-solid, rgb(255 255 255));--_et-qdt-accent: var(--et-theme-color-primary-solid, rgb(96 165 250));--_et-qdt-hover: color-mix(in srgb, var(--_et-qdt-interaction) 10%, transparent);--_et-qdt-active: color-mix(in srgb, var(--_et-qdt-interaction) 18%, transparent);--_et-qdt-success: rgb(34 197 94);--_et-qdt-error: rgb(239 68 68);--_et-qdt-loading: rgb(234 179 8);position:fixed;inset-inline:0;inset-block-end:0;z-index:2147483000;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,Liberation Mono,monospace;font-size:1.2rem;line-height:1.4;pointer-events:none}.et-query-devtools-host>*{pointer-events:auto}.et-query-devtools-panel{position:relative;display:flex;flex-direction:column;inline-size:100%;min-block-size:20rem;max-block-size:90vh;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border-block-start:1px solid var(--_et-qdt-border);box-shadow:0 -.4rem 2rem #00000059}.et-query-devtools-panel--resizing{-webkit-user-select:none;user-select:none}.et-query-devtools-resize{position:absolute;inset-inline:0;inset-block-start:0;block-size:.6rem;cursor:ns-resize;z-index:1}.et-query-devtools-resize:after{content:\"\";position:absolute;inset-inline:50%;inset-block-start:.2rem;inline-size:4rem;margin-inline-start:-2rem;block-size:.2rem;border-radius:999px;background:var(--_et-qdt-border)}.et-query-devtools-resize:hover:after{background:var(--_et-qdt-accent)}.et-query-devtools-header{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding-inline:.8rem;border-block-end:1px solid var(--_et-qdt-border);flex:0 0 auto}.et-query-devtools-tabs{display:flex;flex-wrap:wrap;gap:.2rem}.et-query-devtools-tab{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);padding:.9rem 1rem;cursor:pointer;border-block-end:2px solid transparent;font:inherit}.et-query-devtools-tab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-tab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-header-actions{display:flex;align-items:center;gap:.4rem;flex:0 0 auto}.et-query-devtools-inspect-btn{appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.4rem .8rem;font:inherit}.et-query-devtools-inspect-btn:hover{color:var(--_et-qdt-fg)}.et-query-devtools-inspect-btn--active{color:#09090b;background:var(--_et-qdt-accent);border-color:var(--_et-qdt-accent)}.et-query-devtools-close{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.6rem;font:inherit}.et-query-devtools-inspect-box{position:fixed;z-index:2147483002;pointer-events:none;border:2px solid var(--_et-qdt-accent);background:color-mix(in srgb,var(--_et-qdt-accent) 15%,transparent);border-radius:.2rem}.et-query-devtools-inspect-tag{position:absolute;inset-block-start:100%;inset-inline-start:0;margin-block-start:.2rem;padding:.2rem .5rem;border-radius:.3rem;background:var(--_et-qdt-accent);color:#09090b;font-family:ui-monospace,monospace;font-size:1.1rem;font-weight:600;white-space:nowrap}.et-query-devtools-close:hover{color:var(--_et-qdt-fg)}.et-query-devtools-body{flex:1 1 auto;min-block-size:0;overflow:hidden}.et-query-devtools-master-detail{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-list{flex:0 0 34%;min-inline-size:22rem;max-inline-size:40rem;overflow-y:auto;border-inline-end:1px solid var(--_et-qdt-border)}.et-query-devtools-detail{flex:1 1 auto;min-inline-size:0;overflow-y:auto;padding:1rem}.et-query-devtools-detail .et-query-devtools-detail-head,.et-query-devtools-drawer .et-query-devtools-detail-head{padding-block-end:.8rem;border-block-end:1px solid var(--_et-qdt-border)}.et-query-devtools-detail .et-query-devtools-meta,.et-query-devtools-drawer .et-query-devtools-meta{padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-detail .et-query-devtools-section-row,.et-query-devtools-drawer .et-query-devtools-section-row{padding-block-start:.8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-filter-chip{display:inline-flex;align-items:center;padding:.3rem .7rem;border-radius:999px;background:var(--_et-qdt-accent);color:#09090b;font-size:1.1rem;font-weight:600}.et-query-devtools-scroll{block-size:100%;overflow:auto;padding:1rem;display:flex;flex-direction:column;gap:1rem}.et-query-devtools-split{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-split .et-query-devtools-scroll{flex:1 1 auto;min-inline-size:0}.et-query-devtools-drawer{flex:0 0 42%;min-inline-size:26rem;max-inline-size:48rem;overflow-y:auto;padding:0 1rem 1rem;border-inline-start:1px solid var(--_et-qdt-border)}.et-query-devtools-drawer-head{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.8rem 0;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg);color:var(--_et-qdt-muted);border-block-end:1px solid var(--_et-qdt-border);margin-block-end:.8rem}.et-query-devtools-toolbar{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.8rem;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-field{display:inline-flex;align-items:center;gap:.6rem;color:var(--_et-qdt-muted)}.et-query-devtools-select{background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-count{color:var(--_et-qdt-subtle)}.et-query-devtools-row{display:flex;align-items:center;gap:.8rem;inline-size:100%;text-align:start;appearance:none;border:none;border-block-end:1px solid var(--_et-qdt-border);background:transparent;color:var(--_et-qdt-fg);padding:.8rem;cursor:pointer;font:inherit}.et-query-devtools-row:hover{background:var(--_et-qdt-hover)}.et-query-devtools-row--active{background:var(--_et-qdt-active)}.et-query-devtools-method{font-weight:700;font-size:1.1rem;color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-route{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto;min-inline-size:0}.et-query-devtools-status{inline-size:.8rem;block-size:.8rem;border-radius:999px;flex:0 0 auto;background:var(--_et-qdt-subtle)}.et-query-devtools-status[data-status=success]{background:var(--_et-qdt-success)}.et-query-devtools-status[data-status=error]{background:var(--_et-qdt-error)}.et-query-devtools-status[data-status=loading],.et-query-devtools-status[data-status=running]{background:var(--_et-qdt-loading)}.et-query-devtools-detail-head{display:flex;align-items:center;gap:.8rem;margin-block-end:.8rem}.et-query-devtools-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;margin-block-end:.8rem}.et-query-devtools-btn{appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.3rem;background:transparent;color:var(--_et-qdt-fg);padding:.25rem .55rem;font-size:1.15rem;line-height:1.4;cursor:pointer}.et-query-devtools-btn:hover{background:var(--_et-qdt-hover)}.et-query-devtools-meta{display:grid;grid-template-columns:auto 1fr;gap:.3rem 1rem;margin:0 0 1rem}.et-query-devtools-meta dt{color:var(--_et-qdt-muted)}.et-query-devtools-meta dd{margin:0;overflow-wrap:anywhere}.et-query-devtools-section{margin:1rem 0 .4rem;font-size:1.1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-json{margin:0;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow-x:auto;white-space:pre-wrap;overflow-wrap:anywhere;max-block-size:24rem;overflow-y:auto}.et-query-devtools-json--error{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-mono{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.et-query-devtools-code{margin:0 0 .8rem;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:1.15rem;max-block-size:20rem}.et-query-devtools-ws-message{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;margin-block-end:.4rem}.et-query-devtools-url{display:inline-block;max-inline-size:32rem;margin-inline-start:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.et-query-devtools-chips,.et-query-devtools-chip-row{display:flex;flex-wrap:wrap;gap:.4rem;margin-block-end:.8rem}.et-query-devtools-chip{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem .6rem;border-radius:999px;border:1px solid var(--_et-qdt-border);font-size:1.1rem;color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-interaction) 6%,transparent)}.et-query-devtools-chip--muted{color:var(--_et-qdt-muted)}.et-query-devtools-chip--loading{color:var(--_et-qdt-loading);border-color:color-mix(in srgb,var(--_et-qdt-loading) 50%,transparent)}.et-query-devtools-chip--error{color:var(--_et-qdt-error);border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-chip--success{color:var(--_et-qdt-success);border-color:color-mix(in srgb,var(--_et-qdt-success) 50%,transparent)}.et-query-devtools-card{border:1px solid var(--_et-qdt-border);border-radius:.6rem;padding:1rem}.et-query-devtools-card-head{display:flex;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-card-title{display:flex;align-items:baseline;gap:.5rem;margin-block-end:.2rem}.et-query-devtools-card-sub{color:var(--_et-qdt-subtle);font-size:1.1rem;margin-block-end:.6rem;overflow-wrap:anywhere}.et-query-devtools-inner-queries{display:flex;flex-direction:column;gap:.3rem}.et-query-devtools-inner-row{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-fg);padding:.4rem .6rem;cursor:pointer;font:inherit}.et-query-devtools-inner-row:hover:not([disabled]){background:var(--_et-qdt-hover)}.et-query-devtools-inner-row--active{background:var(--_et-qdt-active);border-color:var(--_et-qdt-accent)}.et-query-devtools-inner-row[disabled]{cursor:default;opacity:.6}.et-query-devtools-step-list{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none}.et-query-devtools-step-item{border:1px solid var(--_et-qdt-border);border-radius:.4rem;overflow:hidden}.et-query-devtools-step-item[data-status=error]{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-step-head{display:flex;align-items:stretch}.et-query-devtools-step-head .et-query-devtools-inner-row{border:none;border-radius:0;flex:1 1 auto}.et-query-devtools-step-caret-btn{appearance:none;border:none;border-inline-start:1px solid var(--_et-qdt-border);background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:0 .7rem;font:inherit}.et-query-devtools-step-caret-btn:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-step-toggle{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:none;background:transparent;color:var(--_et-qdt-fg);padding:.6rem;cursor:pointer;font:inherit}.et-query-devtools-step-toggle:hover{background:var(--_et-qdt-hover)}.et-query-devtools-step-index{flex:1 1 auto;min-inline-size:0}.et-query-devtools-step-caret{color:var(--_et-qdt-muted)}.et-query-devtools-step-io{padding:0 .8rem .8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-table{inline-size:100%;border-collapse:collapse}.et-query-devtools-table th,.et-query-devtools-table td{text-align:start;padding:.5rem .6rem;border-block-end:1px solid var(--_et-qdt-border);vertical-align:top}.et-query-devtools-table th{color:var(--_et-qdt-muted);font-weight:600;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-table tr[data-status=error] td{color:var(--_et-qdt-error)}.et-query-devtools-empty{color:var(--_et-qdt-subtle);padding:1.2rem;text-align:center}.et-query-devtools-actions-label{color:var(--_et-qdt-subtle);align-self:center;text-transform:uppercase;font-size:1rem;letter-spacing:.05em}.et-query-devtools-actions-label:not(:first-child){margin-inline-start:.7rem}.et-query-devtools-cell-actions{display:flex;gap:.4rem;white-space:nowrap}.et-query-devtools-section-row{display:flex;align-items:center;justify-content:space-between;gap:.8rem;margin-block-start:1rem}.et-query-devtools-search{flex:0 1 20rem;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-editor{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.8rem;margin-block-end:1rem}.et-query-devtools-textarea{inline-size:100%;min-block-size:12rem;resize:vertical;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;font-family:inherit;font-size:1.2rem}.et-query-devtools-editor-error{color:var(--_et-qdt-error);margin:.4rem 0 0}.et-query-devtools-json-node,.et-query-devtools-json-children{display:flex;flex-direction:column}.et-query-devtools-json-children{padding-inline-start:1.4rem;border-inline-start:1px solid var(--_et-qdt-border);margin-inline-start:.4rem}.et-query-devtools-json-row{display:flex;align-items:baseline;gap:.4rem;padding:.1rem 0;font-family:inherit;line-height:1.5}.et-query-devtools-json-toggle{appearance:none;border:none;background:transparent;color:var(--_et-qdt-fg);cursor:pointer;text-align:start;font:inherit;padding:.1rem 0}.et-query-devtools-json-toggle:hover{background:var(--_et-qdt-hover)}.et-query-devtools-json-caret{color:var(--_et-qdt-subtle);inline-size:1rem;flex:0 0 auto}.et-query-devtools-json-key{color:var(--_et-qdt-accent)}.et-query-devtools-json-colon,.et-query-devtools-json-preview{color:var(--_et-qdt-subtle)}.et-query-devtools-json-value{overflow-wrap:anywhere}.et-query-devtools-json-leaf[data-kind=string] .et-query-devtools-json-value{color:var(--_et-qdt-success)}.et-query-devtools-json-leaf[data-kind=number] .et-query-devtools-json-value,.et-query-devtools-json-leaf[data-kind=boolean] .et-query-devtools-json-value{color:var(--_et-qdt-loading)}.et-query-devtools-json-leaf[data-kind=null] .et-query-devtools-json-value,.et-query-devtools-json-leaf[data-kind=undefined] .et-query-devtools-json-value{color:var(--_et-qdt-subtle)}.et-query-devtools-json-hit{background:color-mix(in srgb,var(--_et-qdt-loading) 40%,transparent);border-radius:.2rem}.et-query-devtools-json-copy{appearance:none;border:none;background:transparent;color:var(--_et-qdt-subtle);cursor:pointer;opacity:0;font:inherit}.et-query-devtools-json-row:hover .et-query-devtools-json-copy{opacity:1}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "path", "expandedPaths", "collapsedPaths", "toggleFn"] }, { kind: "component", type: QueryDevtoolsToggleComponent, selector: "et-query-devtools-toggle", outputs: ["openChange"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
30915
|
+
}
|
|
30916
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
|
|
30917
|
+
type: Component,
|
|
30918
|
+
args: [{ selector: 'et-query-devtools', encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet, QueryDevtoolsJsonComponent, QueryDevtoolsToggleComponent], host: {
|
|
30919
|
+
class: 'et-query-devtools-host',
|
|
30920
|
+
}, template: "@if (open()) {\n <section\n [class.et-query-devtools-panel--resizing]=\"resizing()\"\n [style.height.px]=\"panelHeight()\"\n class=\"et-query-devtools-panel\"\n >\n <div\n (pointerdown)=\"startResize($event)\"\n class=\"et-query-devtools-resize\"\n title=\"Drag to resize\"\n aria-hidden=\"true\"\n ></div>\n <header class=\"et-query-devtools-header\">\n <nav class=\"et-query-devtools-tabs\" role=\"tablist\">\n @for (tab of tabs; track tab.id) {\n <button\n [class.et-query-devtools-tab--active]=\"activeTab() === tab.id\"\n [attr.aria-selected]=\"activeTab() === tab.id\"\n (click)=\"activeTab.set(tab.id)\"\n class=\"et-query-devtools-tab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n </button>\n }\n </nav>\n\n <div class=\"et-query-devtools-header-actions\">\n <button\n [class.et-query-devtools-inspect-btn--active]=\"inspectActive()\"\n (click)=\"toggleInspect()\"\n class=\"et-query-devtools-inspect-btn\"\n type=\"button\"\n title=\"Inspect: hover the UI to find its query\"\n >\n \u2316 Inspect\n </button>\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-close\" type=\"button\" title=\"Close devtools\">\u2715</button>\n </div>\n </header>\n\n <div class=\"et-query-devtools-body\">\n @switch (activeTab()) {\n <!-- QUERIES -->\n @case ('queries') {\n <div class=\"et-query-devtools-master-detail\">\n <div class=\"et-query-devtools-list\">\n <div class=\"et-query-devtools-toolbar\">\n @if (inspectFilterIds(); as ids) {\n <span class=\"et-query-devtools-filter-chip\">\u2316 inspected \u00B7 {{ ids.length }}</span>\n <button (click)=\"clearInspectFilter()\" class=\"et-query-devtools-btn\" type=\"button\">Reset</button>\n } @else {\n <label class=\"et-query-devtools-field\">\n <span>Client</span>\n <select\n #clientSelect\n [value]=\"selectedClientName() ?? ''\"\n (change)=\"selectClient(clientSelect.value || null)\"\n class=\"et-query-devtools-select\"\n >\n <option value=\"\">All clients</option>\n @for (name of clientNames(); track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n </label>\n }\n <span class=\"et-query-devtools-count\">{{ filteredQueries().length }}</span>\n </div>\n\n @for (item of filteredQueries(); track item.entry.id) {\n <button\n [class.et-query-devtools-row--active]=\"selectedQueryId() === item.entry.id\"\n (click)=\"selectedQueryId.set(item.entry.id)\"\n class=\"et-query-devtools-row\"\n type=\"button\"\n >\n <span\n [attr.data-status]=\"queryStatus(item.query)\"\n [title]=\"queryStatus(item.query)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ item.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">{{ item.entry.meta.route || '\u2014' }}</span>\n @if (isStale(item.query)) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">stale</span>\n }\n </button>\n } @empty {\n @if (inspectFilterIds()) {\n <p class=\"et-query-devtools-empty\">\n The inspected element's queries are no longer registered. Reset the filter.\n </p>\n } @else {\n <p class=\"et-query-devtools-empty\">No queries registered.</p>\n }\n }\n </div>\n\n <div class=\"et-query-devtools-detail\">\n @if (selectedQuery(); as sel) {\n <ng-container *ngTemplateOutlet=\"queryDetailTpl; context: { sel }\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Select a query to inspect it.</p>\n }\n </div>\n </div>\n }\n\n <!-- STACKS -->\n @case ('stacks') {\n <div class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of stackEntries(); track entry.id) {\n @if (entry.kind === 'paged-query-stack') {\n @let paged = asPagedStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">paged stack</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ paged.direction() }}</span>\n @if (paged.loading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n </div>\n\n @let pagedId = stackIdentity(paged);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ pagedId.method }}</span>\n <span class=\"et-query-devtools-route\">{{ pagedId.route }}</span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ pagedId.baseUrl }}</div>\n @if (entry.meta.featureTypes?.length) {\n <div class=\"et-query-devtools-chips\">\n @for (feature of entry.meta.featureTypes; track feature) {\n <span class=\"et-query-devtools-chip\">{{ featureLabel(feature) }}</span>\n }\n </div>\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Pages loaded</dt>\n <dd>{{ paged.queries().length }}</dd>\n <dt>Items</dt>\n <dd>{{ paged.items().length }}</dd>\n <dt>First page loaded</dt>\n <dd>{{ paged.isFirstPageLoaded() }}</dd>\n <dt>Last page loaded</dt>\n <dd>{{ paged.isLastPageLoaded() }}</dd>\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueriesTpl; context: { links: queriesForStack(paged) }\" />\n </div>\n } @else {\n @let stack = asStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">stack</span>\n @if (stack.anyLoading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n @if (stack.anyError()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">error</span>\n }\n </div>\n\n @let stackId = stackIdentity(stack);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ stackId.method }}</span>\n <span class=\"et-query-devtools-route\">{{ stackId.route }}</span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ stackId.baseUrl }}</div>\n @if (entry.meta.featureTypes?.length) {\n <div class=\"et-query-devtools-chips\">\n @for (feature of entry.meta.featureTypes; track feature) {\n <span class=\"et-query-devtools-chip\">{{ featureLabel(feature) }}</span>\n }\n </div>\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Queries</dt>\n <dd>{{ stack.queries().length }}</dd>\n <dt>Loading</dt>\n <dd>{{ stack.loadingProgress().loaded }} / {{ stack.loadingProgress().total }}</dd>\n <dt>Errors</dt>\n <dd>{{ stack.errors().length }}</dd>\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueriesTpl; context: { links: queriesForStack(stack) }\" />\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No stacks registered.</p>\n }\n </div>\n\n @if (stackSelectedQuery(); as sel) {\n <aside class=\"et-query-devtools-drawer\">\n <div class=\"et-query-devtools-drawer-head\">\n <span>Query detail</span>\n <button\n (click)=\"stackSelectedQueryId.set(null)\"\n class=\"et-query-devtools-close\"\n type=\"button\"\n title=\"Close detail\"\n >\n \u2715\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"queryDetailTpl; context: { sel }\" />\n </aside>\n }\n </div>\n }\n\n <!-- SEQUENCES -->\n @case ('sequences') {\n <div class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of sequenceEntries(); track entry.id) {\n @let sequence = asSequence(entry);\n @if (sequence) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">sequence</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ sequence.status() }}</span>\n <span class=\"et-query-devtools-count\"\n >step {{ sequence.currentStep() }} / {{ sequence.total }}</span\n >\n </div>\n\n <ol class=\"et-query-devtools-step-list\">\n @for (link of queriesForSequence(sequence); track $index; let i = $index) {\n <li [attr.data-status]=\"sequenceStepStatus(sequence, i)\" class=\"et-query-devtools-step-item\">\n <div class=\"et-query-devtools-step-head\">\n <button\n [class.et-query-devtools-inner-row--active]=\"sequenceSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"sequenceSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span\n [attr.data-status]=\"sequenceStepStatus(sequence, i)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ i + 1 }}. {{ link.method }}</span>\n <span class=\"et-query-devtools-route\">{{ link.route || 'step ' + (i + 1) }}</span>\n </button>\n <button\n [attr.aria-expanded]=\"isStepExpanded(entry.id, i)\"\n (click)=\"toggleStep(entry.id, i)\"\n class=\"et-query-devtools-step-caret-btn\"\n type=\"button\"\n title=\"Toggle in / out\"\n >\n {{ isStepExpanded(entry.id, i) ? '\u25BE' : '\u25B8' }}\n </button>\n </div>\n\n @if (isStepExpanded(entry.id, i)) {\n @let snap = stepSnapshot(sequence, i);\n <div class=\"et-query-devtools-step-io\">\n <h5 class=\"et-query-devtools-section\">In \u00B7 args</h5>\n @if (sequence.stepArgs().length > i) {\n <et-query-devtools-json [value]=\"sequence.stepArgs()[i]\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n\n @if (snap?.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 error ({{ error.raw.status }})</h5>\n <et-query-devtools-json [value]=\"error.isList ? error.errors : error.error\" />\n } @else {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 response</h5>\n @if (snap) {\n <et-query-devtools-json [value]=\"snap.response()\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n }\n </div>\n }\n </li>\n }\n </ol>\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No sequences registered.</p>\n }\n </div>\n\n @if (sequenceSelectedQuery(); as sel) {\n <aside class=\"et-query-devtools-drawer\">\n <div class=\"et-query-devtools-drawer-head\">\n <span>Query detail</span>\n <button\n (click)=\"sequenceSelectedQueryId.set(null)\"\n class=\"et-query-devtools-close\"\n type=\"button\"\n title=\"Close detail\"\n >\n \u2715\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"queryDetailTpl; context: { sel }\" />\n </aside>\n }\n </div>\n }\n\n <!-- AUTH -->\n @case ('auth') {\n <div class=\"et-query-devtools-scroll\">\n @for (entry of authEntries(); track entry.id) {\n @let auth = asAuth(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'auth provider' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"auth.isAuthenticated()\"\n [class.et-query-devtools-chip--muted]=\"!auth.isAuthenticated()\"\n class=\"et-query-devtools-chip\"\n >\n {{ auth.isAuthenticated() ? 'authenticated' : 'anonymous' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.clientBaseUrl || entry.meta.clientName || '\u2014' }}</dd>\n <dt>Access token</dt>\n <dd>{{ auth.accessToken() ? 'present' : 'none' }}</dd>\n <dt>Refresh token</dt>\n <dd>{{ auth.refreshToken() ? 'present' : 'none' }}</dd>\n @if (authTokenExpiry(auth); as expiry) {\n <dt>Token expires in</dt>\n <dd>{{ expiry }}</dd>\n }\n @if (auth.executionState(); as state) {\n <dt>Execution state</dt>\n <dd>{{ state.type }} \u00B7 {{ state.state }}</dd>\n }\n @if (authQueryKeys(auth).length) {\n <dt>Queries</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (key of authQueryKeys(auth); track key) {\n <span class=\"et-query-devtools-chip\">{{ key }}</span>\n }\n </div>\n </dd>\n }\n @if (authFeatures(auth).length) {\n <dt>Features</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (feature of authFeatures(auth); track feature) {\n <span class=\"et-query-devtools-chip\">{{ feature }}</span>\n }\n </div>\n </dd>\n }\n </dl>\n\n @if (authTokenPayload(auth); as payload) {\n <h4 class=\"et-query-devtools-section\">Access token payload</h4>\n <et-query-devtools-json [value]=\"payload\" />\n }\n\n @if (auth.latestNonInternalQuery(); as latest) {\n <h4 class=\"et-query-devtools-section\">Latest auth query \u00B7 {{ latest.key }}</h4>\n <et-query-devtools-json [value]=\"latest.snapshot.response()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No auth providers registered.</p>\n }\n </div>\n }\n\n <!-- SOCKETS -->\n @case ('ws') {\n <div class=\"et-query-devtools-scroll\">\n @for (entry of wsEntries(); track entry.id) {\n @let ws = asWs(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'socket' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"ws.connected()\"\n [class.et-query-devtools-chip--muted]=\"!ws.connected()\"\n class=\"et-query-devtools-chip\"\n >\n {{ ws.connected() ? 'connected' : 'disconnected' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.url }}</dd>\n <dt>Rooms</dt>\n <dd>\n @if (ws.rooms().length) {\n <div class=\"et-query-devtools-chips\">\n @for (room of ws.rooms(); track room) {\n <span class=\"et-query-devtools-chip\">{{ room }}</span>\n }\n </div>\n } @else {\n none\n }\n </dd>\n </dl>\n\n <h5 class=\"et-query-devtools-section\">Messages ({{ ws.messages().length }})</h5>\n @for (message of ws.messages(); track message.id) {\n <div class=\"et-query-devtools-ws-message\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-count\">{{ formatTime(message.timestamp) }}</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ message.room }}</span>\n <span class=\"et-query-devtools-method\">{{ message.event }}</span>\n </div>\n <et-query-devtools-json [value]=\"message.data\" />\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No messages received yet.</p>\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No web socket clients registered.</p>\n }\n </div>\n }\n\n <!-- CACHE -->\n @case ('cache') {\n <div class=\"et-query-devtools-scroll\">\n @for (client of cacheView(); track client.name) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.baseUrl || client.name }}</strong>\n <span class=\"et-query-devtools-count\">{{ client.entries.length }} entries</span>\n </div>\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Request</th>\n <th>Consumers</th>\n <th>Secure</th>\n <th>Freshness</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (cacheEntry of client.entries; track cacheEntry.key) {\n <tr>\n <td [title]=\"cacheEntry.request.method + ' ' + cacheEntry.request.url\">\n <span class=\"et-query-devtools-method\">{{ cacheEntry.request.method }}</span>\n <span class=\"et-query-devtools-url\">{{ requestPath(cacheEntry.request.url) }}</span>\n </td>\n <td>{{ cacheEntry.consumerCount }}</td>\n <td>{{ cacheEntry.isSecure ? 'yes' : 'no' }}</td>\n <td>{{ cacheFreshness(cacheEntry) }}</td>\n <td class=\"et-query-devtools-cell-actions\">\n <button (click)=\"refetchCacheEntry(cacheEntry)\" class=\"et-query-devtools-btn\" type=\"button\">\n Refetch\n </button>\n <button\n (click)=\"evictCacheEntry(client.repository, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Evict\n </button>\n </td>\n </tr>\n } @empty {\n <tr>\n <td class=\"et-query-devtools-empty\" colspan=\"5\">Cache empty.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No clients with a cache yet.</p>\n }\n </div>\n }\n\n <!-- EVENTS -->\n @case ('events') {\n <div class=\"et-query-devtools-scroll\">\n <div class=\"et-query-devtools-toolbar\">\n <span class=\"et-query-devtools-count\">{{ eventLog().length }} events</span>\n <button (click)=\"clearEvents()\" class=\"et-query-devtools-btn\" type=\"button\">Clear</button>\n </div>\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Time</th>\n <th>Base URL</th>\n <th>Type</th>\n <th>Request</th>\n </tr>\n </thead>\n <tbody>\n @for (event of eventLog(); track event.id) {\n <tr [attr.data-status]=\"event.type === 'request-error' ? 'error' : 'success'\">\n <td>{{ formatTime(event.timestamp) }}</td>\n <td class=\"et-query-devtools-mono\">{{ event.client }}</td>\n <td>\n {{ event.type === 'request-error' ? 'error ' + event.status : 'success' }}\n @if (event.isSecure) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">secure</span>\n }\n </td>\n <td [title]=\"event.method + ' ' + event.url\">\n <span class=\"et-query-devtools-method\">{{ event.method }}</span>\n <span class=\"et-query-devtools-url\">{{ requestPath(event.url) }}</span>\n </td>\n </tr>\n } @empty {\n <tr>\n <td class=\"et-query-devtools-empty\" colspan=\"4\">No events captured yet.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n </div>\n\n <!-- Reusable inner-query list (stacks) \u2014 clicking opens the split-view drawer, not a tab switch. -->\n <ng-template #innerQueriesTpl let-links=\"links\">\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of links; track $index) {\n <button\n [class.et-query-devtools-inner-row--active]=\"stackSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"stackSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">{{ link.route || link.query.id() || 'query ' + ($index + 1) }}</span>\n </button>\n }\n </div>\n </ng-template>\n\n <!-- Reusable query detail \u2014 used by the Queries tab and the stacks split-view drawer. -->\n <ng-template #queryDetailTpl let-sel=\"sel\">\n <div class=\"et-query-devtools-detail-head\">\n <span class=\"et-query-devtools-method\">{{ sel.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">{{ sel.entry.meta.route || '\u2014' }}</span>\n </div>\n\n <div class=\"et-query-devtools-actions\">\n <span class=\"et-query-devtools-actions-label\">Run</span>\n <button (click)=\"executeQuery(sel.query, false)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"executeQuery(sel.query, true)\" class=\"et-query-devtools-btn\" type=\"button\">Cached</button>\n <button (click)=\"resetQuery(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Reset</button>\n <button (click)=\"copyReport(sel.entry, sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">\n {{ copiedReport() ? '\u2713 Copied' : 'Copy report' }}\n </button>\n <span class=\"et-query-devtools-actions-label\">Edit</span>\n <button (click)=\"openResponseEditor(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Response</button>\n <button (click)=\"openArgsEditor(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Replay args</button>\n <span class=\"et-query-devtools-actions-label\">Force</span>\n <button (click)=\"forceLoading(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Loading</button>\n <button (click)=\"forceError(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Error</button>\n <button (click)=\"forceEmpty(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Empty</button>\n <button (click)=\"clearForced(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Clear</button>\n </div>\n\n @if (editorMode() !== 'none') {\n <div class=\"et-query-devtools-editor\">\n @if (editorMode() === 'response') {\n <h4 class=\"et-query-devtools-section\">Edit response \u2192 setResponse()</h4>\n <textarea\n #respArea\n [value]=\"responseDraft()\"\n (input)=\"responseDraft.set(respArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"applyResponse(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Apply</button>\n <button (click)=\"cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n } @else {\n <h4 class=\"et-query-devtools-section\">Replay with edited args \u2192 execute()</h4>\n <textarea\n #argsArea\n [value]=\"argsDraft()\"\n (input)=\"argsDraft.set(argsArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"applyArgs(sel.query)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n }\n @if (editError(); as err) {\n <p class=\"et-query-devtools-editor-error\">{{ err }}</p>\n }\n </div>\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ sel.entry.meta.clientBaseUrl || sel.entry.meta.clientName || '\u2014' }}</dd>\n <dt>Status</dt>\n <dd>{{ queryStatus(sel.query) }}</dd>\n <dt>Cache key</dt>\n <dd class=\"et-query-devtools-mono\">{{ sel.query.id() || '\u2014' }}</dd>\n <dt>Last executed</dt>\n <dd>{{ formatTime(sel.query.lastTimeExecutedAt()) }}</dd>\n <dt>Triggered by</dt>\n <dd>{{ sel.query.triggeredBy() || 'user' }}</dd>\n @if (sel.entry.meta.featureTypes?.length) {\n <dt>Features</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (feature of sel.entry.meta.featureTypes; track feature) {\n <span class=\"et-query-devtools-chip\">{{ featureLabel(feature) }}</span>\n }\n </div>\n </dd>\n }\n </dl>\n\n @if (sel.entry.meta.gqlQuery; as gqlQuery) {\n <h5 class=\"et-query-devtools-section\">GraphQL document</h5>\n <pre class=\"et-query-devtools-code\">{{ gqlDocument(gqlQuery) }}</pre>\n }\n\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Value explorer</h4>\n <input\n #jsonSearchInput\n [value]=\"jsonSearch()\"\n (input)=\"jsonSearch.set(jsonSearchInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter keys / values\u2026\"\n />\n </div>\n\n <h5 class=\"et-query-devtools-section\">Args</h5>\n <et-query-devtools-json\n [value]=\"sel.query.args()\"\n [search]=\"jsonSearchTerm()\"\n [expandedPaths]=\"jsonExpandedPaths()\"\n [collapsedPaths]=\"jsonCollapsedPaths()\"\n [toggleFn]=\"toggleJsonPath\"\n path=\"args\"\n />\n\n @if (sel.query.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Error ({{ error.raw.status }})</h5>\n <et-query-devtools-json\n [value]=\"error.isList ? error.errors : error.error\"\n [search]=\"jsonSearchTerm()\"\n [expandedPaths]=\"jsonExpandedPaths()\"\n [collapsedPaths]=\"jsonCollapsedPaths()\"\n [toggleFn]=\"toggleJsonPath\"\n path=\"error\"\n />\n } @else {\n <h5 class=\"et-query-devtools-section\">Response</h5>\n <et-query-devtools-json\n [value]=\"sel.query.response()\"\n [search]=\"jsonSearchTerm()\"\n [expandedPaths]=\"jsonExpandedPaths()\"\n [collapsedPaths]=\"jsonCollapsedPaths()\"\n [toggleFn]=\"toggleJsonPath\"\n path=\"response\"\n />\n }\n </ng-template>\n </section>\n}\n\n@if (!open()) {\n <et-query-devtools-toggle (openChange)=\"toggleOpen()\" />\n}\n\n@if (inspectActive() && inspectHover(); as hover) {\n <div\n [style.left.px]=\"hover.rect.left\"\n [style.top.px]=\"hover.rect.top\"\n [style.width.px]=\"hover.rect.width\"\n [style.height.px]=\"hover.rect.height\"\n class=\"et-query-devtools-inspect-box\"\n >\n <span class=\"et-query-devtools-inspect-tag\">{{ inspectLabel(hover.entries) }}</span>\n </div>\n}\n", styles: ["@layer components{.et-query-devtools-host{--_et-qdt-bg: var(--et-surface-background-solid, rgb(24 24 27));--_et-qdt-fg: var(--et-surface-color-solid, rgb(244 244 245));--_et-qdt-muted: var(--et-surface-color-muted-solid, rgb(161 161 170));--_et-qdt-subtle: var(--et-surface-color-subtle-solid, rgb(113 113 122));--_et-qdt-border: var(--et-surface-border-solid, rgb(255 255 255 / .12));--_et-qdt-interaction: var(--et-surface-interaction-solid, rgb(255 255 255));--_et-qdt-accent: var(--et-theme-color-primary-solid, rgb(96 165 250));--_et-qdt-hover: color-mix(in srgb, var(--_et-qdt-interaction) 10%, transparent);--_et-qdt-active: color-mix(in srgb, var(--_et-qdt-interaction) 18%, transparent);--_et-qdt-success: rgb(34 197 94);--_et-qdt-error: rgb(239 68 68);--_et-qdt-loading: rgb(234 179 8);position:fixed;inset-inline:0;inset-block-end:0;z-index:2147483000;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,Liberation Mono,monospace;font-size:1.2rem;line-height:1.4;pointer-events:none}.et-query-devtools-host>*{pointer-events:auto}.et-query-devtools-panel{position:relative;display:flex;flex-direction:column;inline-size:100%;min-block-size:20rem;max-block-size:90vh;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border-block-start:1px solid var(--_et-qdt-border);box-shadow:0 -.4rem 2rem #00000059}.et-query-devtools-panel--resizing{-webkit-user-select:none;user-select:none}.et-query-devtools-resize{position:absolute;inset-inline:0;inset-block-start:0;block-size:.6rem;cursor:ns-resize;z-index:1}.et-query-devtools-resize:after{content:\"\";position:absolute;inset-inline:50%;inset-block-start:.2rem;inline-size:4rem;margin-inline-start:-2rem;block-size:.2rem;border-radius:999px;background:var(--_et-qdt-border)}.et-query-devtools-resize:hover:after{background:var(--_et-qdt-accent)}.et-query-devtools-header{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding-inline:.8rem;border-block-end:1px solid var(--_et-qdt-border);flex:0 0 auto}.et-query-devtools-tabs{display:flex;flex-wrap:wrap;gap:.2rem}.et-query-devtools-tab{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);padding:.9rem 1rem;cursor:pointer;border-block-end:2px solid transparent;font:inherit}.et-query-devtools-tab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-tab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-header-actions{display:flex;align-items:center;gap:.4rem;flex:0 0 auto}.et-query-devtools-inspect-btn{appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.4rem .8rem;font:inherit}.et-query-devtools-inspect-btn:hover{color:var(--_et-qdt-fg)}.et-query-devtools-inspect-btn--active{color:#09090b;background:var(--_et-qdt-accent);border-color:var(--_et-qdt-accent)}.et-query-devtools-close{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.6rem;font:inherit}.et-query-devtools-inspect-box{position:fixed;z-index:2147483002;pointer-events:none;border:2px solid var(--_et-qdt-accent);background:color-mix(in srgb,var(--_et-qdt-accent) 15%,transparent);border-radius:.2rem}.et-query-devtools-inspect-tag{position:absolute;inset-block-start:100%;inset-inline-start:0;margin-block-start:.2rem;padding:.2rem .5rem;border-radius:.3rem;background:var(--_et-qdt-accent);color:#09090b;font-family:ui-monospace,monospace;font-size:1.1rem;font-weight:600;white-space:nowrap}.et-query-devtools-close:hover{color:var(--_et-qdt-fg)}.et-query-devtools-body{flex:1 1 auto;min-block-size:0;overflow:hidden}.et-query-devtools-master-detail{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-list{flex:0 0 34%;min-inline-size:22rem;max-inline-size:40rem;overflow-y:auto;border-inline-end:1px solid var(--_et-qdt-border)}.et-query-devtools-detail{flex:1 1 auto;min-inline-size:0;overflow-y:auto;padding:1rem}.et-query-devtools-detail .et-query-devtools-detail-head,.et-query-devtools-drawer .et-query-devtools-detail-head{padding-block-end:.8rem;border-block-end:1px solid var(--_et-qdt-border)}.et-query-devtools-detail .et-query-devtools-meta,.et-query-devtools-drawer .et-query-devtools-meta{padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-detail .et-query-devtools-section-row,.et-query-devtools-drawer .et-query-devtools-section-row{padding-block-start:.8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-filter-chip{display:inline-flex;align-items:center;padding:.3rem .7rem;border-radius:999px;background:var(--_et-qdt-accent);color:#09090b;font-size:1.1rem;font-weight:600}.et-query-devtools-scroll{block-size:100%;overflow:auto;padding:1rem;display:flex;flex-direction:column;gap:1rem}.et-query-devtools-split{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-split .et-query-devtools-scroll{flex:1 1 auto;min-inline-size:0}.et-query-devtools-drawer{flex:0 0 42%;min-inline-size:26rem;max-inline-size:48rem;overflow-y:auto;padding:0 1rem 1rem;border-inline-start:1px solid var(--_et-qdt-border)}.et-query-devtools-drawer-head{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.8rem 0;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg);color:var(--_et-qdt-muted);border-block-end:1px solid var(--_et-qdt-border);margin-block-end:.8rem}.et-query-devtools-toolbar{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.8rem;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-field{display:inline-flex;align-items:center;gap:.6rem;color:var(--_et-qdt-muted)}.et-query-devtools-select{background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-count{color:var(--_et-qdt-subtle)}.et-query-devtools-row{display:flex;align-items:center;gap:.8rem;inline-size:100%;text-align:start;appearance:none;border:none;border-block-end:1px solid var(--_et-qdt-border);background:transparent;color:var(--_et-qdt-fg);padding:.8rem;cursor:pointer;font:inherit}.et-query-devtools-row:hover{background:var(--_et-qdt-hover)}.et-query-devtools-row--active{background:var(--_et-qdt-active)}.et-query-devtools-method{font-weight:700;font-size:1.1rem;color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-route{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto;min-inline-size:0}.et-query-devtools-status{inline-size:.8rem;block-size:.8rem;border-radius:999px;flex:0 0 auto;background:var(--_et-qdt-subtle)}.et-query-devtools-status[data-status=success]{background:var(--_et-qdt-success)}.et-query-devtools-status[data-status=error]{background:var(--_et-qdt-error)}.et-query-devtools-status[data-status=loading],.et-query-devtools-status[data-status=running]{background:var(--_et-qdt-loading)}.et-query-devtools-detail-head{display:flex;align-items:center;gap:.8rem;margin-block-end:.8rem}.et-query-devtools-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;margin-block-end:.8rem}.et-query-devtools-btn{appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.3rem;background:transparent;color:var(--_et-qdt-fg);padding:.25rem .55rem;font-size:1.15rem;line-height:1.4;cursor:pointer}.et-query-devtools-btn:hover{background:var(--_et-qdt-hover)}.et-query-devtools-meta{display:grid;grid-template-columns:auto 1fr;gap:.3rem 1rem;margin:0 0 1rem}.et-query-devtools-meta dt{color:var(--_et-qdt-muted)}.et-query-devtools-meta dd{margin:0;overflow-wrap:anywhere}.et-query-devtools-section{margin:1rem 0 .4rem;font-size:1.1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-json{margin:0;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow-x:auto;white-space:pre-wrap;overflow-wrap:anywhere;max-block-size:24rem;overflow-y:auto}.et-query-devtools-json--error{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-mono{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.et-query-devtools-code{margin:0 0 .8rem;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:1.15rem;max-block-size:20rem}.et-query-devtools-ws-message{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;margin-block-end:.4rem}.et-query-devtools-url{display:inline-block;max-inline-size:32rem;margin-inline-start:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.et-query-devtools-chips,.et-query-devtools-chip-row{display:flex;flex-wrap:wrap;gap:.4rem;margin-block-end:.8rem}.et-query-devtools-chip{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem .6rem;border-radius:999px;border:1px solid var(--_et-qdt-border);font-size:1.1rem;color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-interaction) 6%,transparent)}.et-query-devtools-chip--muted{color:var(--_et-qdt-muted)}.et-query-devtools-chip--loading{color:var(--_et-qdt-loading);border-color:color-mix(in srgb,var(--_et-qdt-loading) 50%,transparent)}.et-query-devtools-chip--error{color:var(--_et-qdt-error);border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-chip--success{color:var(--_et-qdt-success);border-color:color-mix(in srgb,var(--_et-qdt-success) 50%,transparent)}.et-query-devtools-card{border:1px solid var(--_et-qdt-border);border-radius:.6rem;padding:1rem}.et-query-devtools-card-head{display:flex;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-card-title{display:flex;align-items:baseline;gap:.5rem;margin-block-end:.2rem}.et-query-devtools-card-sub{color:var(--_et-qdt-subtle);font-size:1.1rem;margin-block-end:.6rem;overflow-wrap:anywhere}.et-query-devtools-inner-queries{display:flex;flex-direction:column;gap:.3rem}.et-query-devtools-inner-row{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-fg);padding:.4rem .6rem;cursor:pointer;font:inherit}.et-query-devtools-inner-row:hover:not([disabled]){background:var(--_et-qdt-hover)}.et-query-devtools-inner-row--active{background:var(--_et-qdt-active);border-color:var(--_et-qdt-accent)}.et-query-devtools-inner-row[disabled]{cursor:default;opacity:.6}.et-query-devtools-step-list{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none}.et-query-devtools-step-item{border:1px solid var(--_et-qdt-border);border-radius:.4rem;overflow:hidden}.et-query-devtools-step-item[data-status=error]{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-step-head{display:flex;align-items:stretch}.et-query-devtools-step-head .et-query-devtools-inner-row{border:none;border-radius:0;flex:1 1 auto}.et-query-devtools-step-caret-btn{appearance:none;border:none;border-inline-start:1px solid var(--_et-qdt-border);background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:0 .7rem;font:inherit}.et-query-devtools-step-caret-btn:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-step-toggle{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:none;background:transparent;color:var(--_et-qdt-fg);padding:.6rem;cursor:pointer;font:inherit}.et-query-devtools-step-toggle:hover{background:var(--_et-qdt-hover)}.et-query-devtools-step-index{flex:1 1 auto;min-inline-size:0}.et-query-devtools-step-caret{color:var(--_et-qdt-muted)}.et-query-devtools-step-io{padding:0 .8rem .8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-table{inline-size:100%;border-collapse:collapse}.et-query-devtools-table th,.et-query-devtools-table td{text-align:start;padding:.5rem .6rem;border-block-end:1px solid var(--_et-qdt-border);vertical-align:top}.et-query-devtools-table th{color:var(--_et-qdt-muted);font-weight:600;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-table tr[data-status=error] td{color:var(--_et-qdt-error)}.et-query-devtools-empty{color:var(--_et-qdt-subtle);padding:1.2rem;text-align:center}.et-query-devtools-actions-label{color:var(--_et-qdt-subtle);align-self:center;text-transform:uppercase;font-size:1rem;letter-spacing:.05em}.et-query-devtools-actions-label:not(:first-child){margin-inline-start:.7rem}.et-query-devtools-cell-actions{display:flex;gap:.4rem;white-space:nowrap}.et-query-devtools-section-row{display:flex;align-items:center;justify-content:space-between;gap:.8rem;margin-block-start:1rem}.et-query-devtools-search{flex:0 1 20rem;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-editor{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.8rem;margin-block-end:1rem}.et-query-devtools-textarea{inline-size:100%;min-block-size:12rem;resize:vertical;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;font-family:inherit;font-size:1.2rem}.et-query-devtools-editor-error{color:var(--_et-qdt-error);margin:.4rem 0 0}.et-query-devtools-json-node,.et-query-devtools-json-children{display:flex;flex-direction:column}.et-query-devtools-json-children{padding-inline-start:1.4rem;border-inline-start:1px solid var(--_et-qdt-border);margin-inline-start:.4rem}.et-query-devtools-json-row{display:flex;align-items:baseline;gap:.4rem;padding:.1rem 0;font-family:inherit;line-height:1.5}.et-query-devtools-json-toggle{appearance:none;border:none;background:transparent;color:var(--_et-qdt-fg);cursor:pointer;text-align:start;font:inherit;padding:.1rem 0}.et-query-devtools-json-toggle:hover{background:var(--_et-qdt-hover)}.et-query-devtools-json-caret{color:var(--_et-qdt-subtle);inline-size:1rem;flex:0 0 auto}.et-query-devtools-json-key{color:var(--_et-qdt-accent)}.et-query-devtools-json-colon,.et-query-devtools-json-preview{color:var(--_et-qdt-subtle)}.et-query-devtools-json-value{overflow-wrap:anywhere}.et-query-devtools-json-leaf[data-kind=string] .et-query-devtools-json-value{color:var(--_et-qdt-success)}.et-query-devtools-json-leaf[data-kind=number] .et-query-devtools-json-value,.et-query-devtools-json-leaf[data-kind=boolean] .et-query-devtools-json-value{color:var(--_et-qdt-loading)}.et-query-devtools-json-leaf[data-kind=null] .et-query-devtools-json-value,.et-query-devtools-json-leaf[data-kind=undefined] .et-query-devtools-json-value{color:var(--_et-qdt-subtle)}.et-query-devtools-json-hit{background:color-mix(in srgb,var(--_et-qdt-loading) 40%,transparent);border-radius:.2rem}.et-query-devtools-json-copy{appearance:none;border:none;background:transparent;color:var(--_et-qdt-subtle);cursor:pointer;opacity:0;font:inherit}.et-query-devtools-json-row:hover .et-query-devtools-json-copy{opacity:1}}\n"] }]
|
|
30921
|
+
}], ctorParameters: () => [] });
|
|
30922
|
+
|
|
30923
|
+
const QUERY_DEVTOOLS_IMPORTS = [QueryDevtoolsComponent];
|
|
30924
|
+
|
|
29887
30925
|
// codes 2100-2199
|
|
29888
30926
|
const SCROLLABLE_ERROR_CODES = {
|
|
29889
30927
|
MISSING_SCROLL_CONTAINER: 2100,
|
|
@@ -36704,5 +37742,5 @@ const TOOLTIP_IMPORTS = [TooltipDirective, TooltipComponent];
|
|
|
36704
37742
|
* Generated bundle index. Do not edit.
|
|
36705
37743
|
*/
|
|
36706
37744
|
|
|
36707
|
-
export { ALIGN_CENTER_ICON, ALIGN_JUSTIFY_ICON, ALIGN_LEFT_ICON, ALIGN_RIGHT_ICON, ARROW_OUT_UP_RIGHT_ICON, ARROW_RIGHT_ICON, BOLD_ICON, BUTTON_ICON_ALIGNMENTS, BUTTON_IMPORTS, BUTTON_SIZES, BUTTON_SPINNER_CONFIG, BUTTON_TYPES, BUTTON_VARIANTS, BrandLoaderComponent, ButtonComponent, ButtonDirective, ButtonStylesDirective, CALENDAR_ERROR_CODES, CALENDAR_ICON, CALENDAR_IMPORTS, CASCADER_ERROR_CODES, CASCADER_IMPORTS, CASCADER_SELECTABLE_LEVELS, CHECKBOX_IMPORTS, CHECK_ICON, CHEVRON_ICON, CHIP_ERROR_CODES, CHIP_IMPORTS, CHOICE_FIELD_IMPORTS, CLIPBOARD_CHECK_ICON, CLOCK_ICON, CODE_ICON, COLOR_INPUT_IMPORTS, CalendarCellDirective, CalendarComponent, CalendarDirective, CalendarGridDirective, CascaderColumnDirective, CascaderComponent, CascaderDirective, CascaderNodeDirective, CascaderPanelComponent, CascaderSearchDirective, CascaderSearchOptionDirective, CascaderSurfaceDirective, CascaderTriggerDirective, CheckboxComponent, CheckboxDirective, CheckboxGroupComponent, CheckboxOptionComponent, ChipComponent, ChipDirective, ChipRemoveDirective, ChoiceFieldComponent, ColorInputComponent, ColorInputDirective, DAILYMOTION_PLAYER_TOKEN, DATE_FORMAT, DATE_INPUT_ERROR_CODES, DATE_INPUT_IMPORTS, DATE_LOCALE, DATE_PICKER_HOST, DATE_RANGE_INPUT_ERROR_CODES, DATE_RANGE_INPUT_IMPORTS, DATE_TIME_INPUT_ERROR_CODES, DATE_TIME_INPUT_IMPORTS, DEFAULT_BREAKPOINTS, DEFAULT_ICON_VARIANT, DEFAULT_NOTIFICATION_MANAGER_CONFIG, DEFAULT_PIP_WINDOW_CONFIG, DEFAULT_RICH_TEXT_EDITOR_TOOLS, DEFAULT_STREAM_PLAYER_STATE, DROPZONE_ENTRY_STATUSES, DROPZONE_ERROR_CODES, DROPZONE_FILES_ERROR_KIND, DROPZONE_FILE_CONSTRAINTS, DROPZONE_FILE_REJECTION_REASONS, DROPZONE_IMPORTS, DURATION_INPUT_ERROR_CODES, DURATION_INPUT_IMPORTS, DailymotionPlayerComponent, DailymotionPlayerDirective, DailymotionPlayerParamsDirective, DailymotionPlayerSlotComponent, DateInputComponent, DateInputDirective, DateInputFieldDirective, DatePickerPanelComponent, DatePickerSurfaceDirective, DatePickerTriggerDirective, DateRangeInputComponent, DateRangeInputDirective, DateRangeInputFieldDirective, DateTimeInputComponent, DateTimeInputDirective, DateTimeInputFieldDirective, DescriptionComponent, DropzoneComponent, DropzoneDirective, DurationInputComponent, DurationInputDirective, DurationInputFieldDirective, ET_BUILT_IN_ICON_NAMES, EYE_ICON, EYE_SLASH_ICON, FACEBOOK_PLAYER_TOKEN, FILE_ICON, FLOPPY_DISK_ICON, FOCUS_FRAME_ICON, FORM_ERROR_MESSAGE_RESOLVER, FORM_FIELD_APPEARANCES, FORM_FIELD_CONTROL_TYPES, FORM_FIELD_ERROR_CODES, FORM_FIELD_FILLS, FORM_FIELD_IMPORTS, FORM_FIELD_LABEL_MODES, FORM_FIELD_SIZES, FORM_FIELD_TOKEN, FabComponent, FacebookPlayerComponent, FacebookPlayerDirective, FacebookPlayerParamsDirective, FacebookPlayerSlotComponent, FocusRingDirective, FormErrorComponent, FormFieldComponent, FormFieldDirective, GRID_2X2_ICON, GRID_ERROR_CODES, GRID_IMPORTS, GRID_TOKEN, GridComponent, GridDebugComponent, GridDirective, GridDragDirective, GridItemComponent, GridItemDefaultActionsComponent, GridItemDirective, GridItemRef, GridItemToolbarComponent, GridResizeDirective, HEADING_1_ICON, HEADING_2_ICON, HEADING_3_ICON, HintComponent, ICONS_TOKEN, ICON_DIRECTIVE_TOKEN, ICON_ERROR_CODES, ICON_IMPORTS, ICON_OVERRIDES_TOKEN, INITIAL_SUPPORT_PRESENTATION_STATE, INPUT_IMPORTS, INPUT_MASK_HOST, INPUT_TEXT_ALIGNMENTS, INPUT_TYPES, INTERACTIVE_TAGS, ITALIC_ICON, IconButtonComponent, IconDirective, InputComponent, InputDirective, InputMaskDirective, InputPrefixDirective, InputSuffixDirective, KICK_PLAYER_TOKEN, KickPlayerComponent, KickPlayerDirective, KickPlayerParamsDirective, KickPlayerSlotComponent, LINK_ICON, LIST_BULLETED_ICON, LIST_NUMBERED_ICON, LOCK_ICON, LabelDirective, MASKED_INPUT_ERROR_CODES, MASKED_INPUT_IMPORTS, MASK_VALUE_MODES, MENU_ERROR_CODES, MENU_IMPORTS, MENU_ITEM_VARIANTS, MENU_SELECTION_GROUP_MULTIPLE, MENU_SELECTION_GROUP_TOKEN, MENU_SELECTION_ITEM_KIND, MINUS_ICON, MULTI_LANGUAGE_RICH_TEXT_EDITOR_ERROR_CODES, MULTI_LANGUAGE_RICH_TEXT_EDITOR_IMPORTS, MenuCheckboxGroupComponent, MenuCheckboxItemComponent, MenuComponent, MenuContextTriggerDirective, MenuDirective, MenuGroupLabelComponent, MenuItemComponent, MenuItemDirective, MenuItemShortcutComponent, MenuPanelDirective, MenuRadioGroupComponent, MenuRadioItemComponent, MenuSearchDirective, MenuSelectionGroupDirective, MenuSelectionItemDirective, MenuSeparatorComponent, MenuSurfaceDirective, MenuTriggerDirective, MultiLanguageRichTextEditorComponent, MultiLanguageRichTextEditorDirective, MultiLanguageRichTextEditorLanguageToolComponent, NAV_TABS_TOKEN, NAV_TAB_IMPORTS, NOTIFICATION_ERROR_CODES, NOTIFICATION_IMPORTS, NOTIFICATION_STACK_CONTEXT_TOKEN, NOTIFICATION_STATUS, NUMBER_INPUT_IMPORTS, NavTabLinkComponent, NavTabLinkDirective, NavTabsComponent, NavTabsDirective, NavTabsOutletComponent, NavTabsOutletDirective, NotificationActionDirective, NotificationComponent, NotificationDirective, NotificationDismissDirective, NotificationItemDirective, NotificationStackDirective, NumberInputComponent, NumberInputDirective, OTP_INPUT_IMPORTS, OVERLAY_BACK_OR_CLOSE_TOKEN, OVERLAY_BODY_TOKEN, OVERLAY_CONFIG_CLASS_KEYS, OVERLAY_CONTENT_IMPORTS, OVERLAY_ERROR_CODES, OVERLAY_FOOTER_TOKEN, OVERLAY_HEADER_TEMPLATE_TOKEN, OVERLAY_HEADER_TOKEN, OVERLAY_IMPORTS, OVERLAY_MAIN_TOKEN, OVERLAY_QUERY_PARAM_INPUT_NAME, OVERLAY_REF, OVERLAY_ROUTER_CONFIG_TOKEN, OVERLAY_ROUTER_LINK_TOKEN, OVERLAY_ROUTER_OUTLET_DISABLED_TEMPLATE_TOKEN, OVERLAY_ROUTER_OUTLET_TOKEN, OVERLAY_ROUTER_TOKEN, OVERLAY_SHARED_ROUTE_TEMPLATE_TOKEN, OtpInputComponent, OtpInputDirective, OverlayAnchorDirective, OverlayBackOrCloseDirective, OverlayBodyComponent, OverlayCloseDirective, OverlayContainerComponent, OverlayDirective, OverlayFooterDirective, OverlayHeaderDirective, OverlayHeaderTemplateDirective, OverlayMainDirective, OverlayOriginCloneComponent, OverlayRouteHeaderTemplateOutletComponent, OverlayRouterLinkDirective, OverlayRouterOutletComponent, OverlayRouterOutletDisabledTemplateDirective, OverlaySharedRouteTemplateDirective, OverlaySharedRouteTemplateOutletComponent, OverlaySidebarComponent, OverlaySidebarPageComponent, OverlaySurfaceDirective, OverlayTitleDirective, OverlayTriggerDirective, PARAGRAPH_ICON, PASSWORD_INPUT_IMPORTS, PENCIL_ICON, PHONE_COUNTRIES, PHONE_INPUT_ERROR_CODES, PHONE_INPUT_IMPORTS, PIP_CHROME_REF_TOKEN, PIP_ENTRY_TOKEN, PIP_WINDOW_ASPECT_RATIO_TOKEN, PLUS_ICON, PasswordInputComponent, PasswordInputDirective, PhoneInputComponent, PhoneInputDirective, PhoneInputFieldDirective, PhoneInputFlagDirective, PipBackDirective, PipBringBackDirective, PipCellDirective, PipCloseDirective, PipCollapseOverlayDirective, PipGridToggleDirective, PipPlayerComponent, PipSlotPlaceholderComponent, PipStageDirective, PipTitleBarDirective, PipTitleBarTemplateDirective, PipWindowComponent, PipWindowParamsDirective, ProgressBarComponent, QueryParamOverlayLinkDirective, RATING_IMPORTS, RICH_TEXT_EDITOR_HEADING_OPTIONS, RICH_TEXT_EDITOR_IMPORTS, RICH_TEXT_EDITOR_INLINE_TOOLS, RICH_TEXT_EDITOR_LANGUAGE_TOOL, RICH_TEXT_EDITOR_TOKEN_CODEC, RICH_TEXT_EDITOR_TOKEN_PALETTE_IMPORTS, RICH_TEXT_EDITOR_TOOL, RICH_TEXT_EDITOR_TOOLS, RICH_TEXT_EDITOR_TOOL_BUTTONS, RICH_TEXT_EDITOR_TRIGGERS_IMPORTS, ROTATE_RIGHT_ICON, RadioComponent, RadioGroupComponent, RangeSliderComponent, RangeSliderDirective, RatingComponent, RatingDirective, RatingIconDirective, RichTextEditorAlignToolComponent, RichTextEditorComponent, RichTextEditorDirective, RichTextEditorFloatingToolbarComponent, RichTextEditorFloatingToolbarDirective, RichTextEditorLinkEditorComponent, RichTextEditorLinkEditorDirective, RichTextEditorTableToolComponent, RichTextEditorTokenPaletteComponent, RichTextEditorTokenPopupComponent, RichTextEditorTriggersDirective, SCROLLABLE_ERROR_CODES, SCROLLABLE_IMPORTS, SELECTION_LIST_MULTIPLE, SELECTION_LIST_TOKEN, SELECT_ERROR_CODES, SELECT_FILTER_MODES, SELECT_IMPORTS, SIDEBAR_OVERLAY_CONFIG, SIDEBAR_OVERLAY_TOKEN, SLIDER_ERROR_CODES, SLIDER_IMPORTS, SLIDER_TOKEN, SNAP_HYSTERESIS, SOOP_PLAYER_TOKEN, SPLIT_BUTTON_ERROR_CODES, STAR_ICON, STREAM_CONSENT_TOKEN, STREAM_IMPORTS, STREAM_PLAYER_COMPONENT_TOKEN, STREAM_PLAYER_ERROR_CONTEXT_TOKEN, STREAM_PLAYER_ERROR_TOKEN, STREAM_PLAYER_PARAMS_TOKEN, STREAM_PLAYER_SLOT_TOKEN, STREAM_PLAYER_TOKEN, STREAM_SLOT_PLAYER_ID_TOKEN, STREAM_USER_CONSENT_PROVIDER_TOKEN, STRIKETHROUGH_ICON, SUPPORT_CONTENT_STATE, SUPPORT_TRANSITION_DIRECTION, SWITCH_IMPORTS, ScrollableActiveChildDirective, ScrollableButtonsDirective, ScrollableComponent, ScrollableDarkenDirective, ScrollableDirective, ScrollableDragDirective, ScrollableIgnoreChildDirective, ScrollableLoadingTemplateDirective, ScrollableMasksDirective, ScrollableNavigationDirective, ScrollableSnapDirective, SegmentedButtonComponent, SegmentedButtonGroupComponent, SelectComponent, SelectDirective, SelectEmptyDirective, SelectErrorDirective, SelectListboxDirective, SelectLoadingDirective, SelectOptionComponent, SelectOptionDirective, SelectOptionGroupComponent, SelectOptionGroupDirective, SelectOptionTemplateDirective, SelectOptionsDirective, SelectPanelComponent, SelectSearchDirective, SelectSurfaceDirective, SelectTriggerDirective, SelectValueDirective, SelectViewportDirective, SelectVirtualOptionComponent, SelectVirtualOptionDirective, SelectionListControlDirective, SelectionListDirective, SelectionOptionDirective, SliderComponent, SliderDirective, SliderThumbDirective, SliderThumbLabelDirective, SliderTrackDirective, SoopPlayerComponent, SoopPlayerDirective, SoopPlayerParamsDirective, SoopPlayerSlotComponent, SpinnerComponent, SplitButtonActionDirective, SplitButtonComponent, SplitButtonDirective, SplitButtonTriggerDirective, StreamConsentAcceptDirective, StreamConsentComponent, StreamConsentDirective, StreamPipChromeComponent, StreamPlayerErrorComponent, StreamPlayerErrorDirective, StreamPlayerLoadingComponent, StreamPlayerSlotDirective, SwitchComponent, SwitchDirective, TABLE_ICON, TAB_BAR_FITS, TAB_BAR_ORIENTATIONS, TAB_BAR_TOKEN, TAB_BAR_TRIGGER_TOKEN, TAB_BAR_VARIANTS, TAB_ERROR_CODES, TAB_GROUP_TOKEN, TAB_IMPORTS, TAB_PANEL_TOKEN, TAB_SIZES, TAG_INPUT_ERROR_CODES, TAG_INPUT_IMPORTS, TEXTAREA_IMPORTS, TEXTAREA_RESIZE_MODES, TEXT_ALIGNS, TIKTOK_PLAYER_TOKEN, TIMES_ICON, TIME_FORMAT, TIME_INPUT_ERROR_CODES, TIME_INPUT_IMPORTS, TIME_PICKER_ERROR_CODES, TIME_PICKER_IMPORTS, TOGGLETIP_ERROR_CODES, TOGGLETIP_IMPORTS, TOOLTIP_ERROR_CODES, TOOLTIP_IMPORTS, TRIANGLE_EXCLAMATION_ICON, TWITCH_PLAYER_TOKEN, TabBarDirective, TabBarTriggerDirective, TabBarUnderlineDirective, TabComponent, TabGroupComponent, TabGroupDirective, TabLabelDirective, TabPanelDirective, TabTriggerDirective, TagInputComponent, TagInputDirective, TagInputFieldDirective, TextButtonComponent, TextFieldControlDirective, TextareaComponent, TextareaDirective, TikTokPlayerComponent, TikTokPlayerDirective, TikTokPlayerParamsDirective, TikTokPlayerSlotComponent, TimeInputComponent, TimeInputDirective, TimeInputFieldDirective, TimePickerColumnDirective, TimePickerComponent, TimePickerDirective, TimePickerOptionDirective, ToggletipCloseDirective, ToggletipComponent, ToggletipDirective, ToggletipTriggerDirective, TooltipComponent, TooltipDirective, TwitchPlayerComponent, TwitchPlayerDirective, TwitchPlayerParamsDirective, TwitchPlayerSlotComponent, UNDERLINE_ICON, UNIT_MS, UPLOAD_ICON, VIMEO_PLAYER_TOKEN, VimeoPlayerComponent, VimeoPlayerDirective, VimeoPlayerParamsDirective, VimeoPlayerSlotComponent, WINDOW_CONTROL_BUTTON_KINDS, WINDOW_CONTROL_BUTTON_SIZES, WindowControlButtonComponent, YOUTUBE_PLAYER_SLOT_TOKEN, YOUTUBE_PLAYER_TOKEN, YoutubePlayerComponent, YoutubePlayerDirective, YoutubePlayerParamsDirective, YoutubePlayerSlotComponent, YoutubePlayerSlotDirective, abortFullscreenAnimation, anchoredDialogOverlayStrategy, anchoredOverlayStrategy, autoPlace, bottomSheetOverlayStrategy, buildAnchoredRuntimePositionStrategy, canHaveChildren, cascaderFromQuery, centeredOverlayStrategy, clampPosition, clampResizeRect, cleanupFullscreenAnimation, cleanupFullscreenAnimationStyles, compactLayout, computeGeometry, computeGridHeight, createAnchoredPanelController, createAutoScroller, createCardMask, createCurrencyMask, createDefaultDropzoneArgs, createDropzoneUpload, createExistingDropzoneEntry, createFileDropzoneEntry, createGridAdapter, createIbanMask, createNotificationRef, createOverlayOpener, createOverlayRef, createOverlayStrategyController, createOverlayUnsavedChangesGuard, createPipChromeAnimations, createPipChromeState, createRichTextEditorTrigger, createRichTextEditorTriggerWithQuery, createStreamConfig, createStreamPlayerSlot, createV2DropzoneUpload, defaultCompareWith, defaultDropzoneRejectionMessage, defineOverlay, defineQueryParamOverlay, deriveDurationFormatSpec, deserializeGridLayout, dialogOverlayStrategy, disposeDropzoneEntry, dropzoneFiles, enableDragToDismiss, findCollision, findNextRelevantHtmlElement, findScrollableAncestor, formatDuration, formatFileSize, fromGridPosition, fullScreenDialogOverlayStrategy, getClosestOverlay, getOriginCoordinatesAndDimensions, hysteresisRound, iconRegistryKey, indexOfNode, injectAnchoredDialogStrategy, injectAnchoredDialogStrategyDefaults, injectBottomSheetStrategy, injectBottomSheetStrategyDefaults, injectDateFormat, injectDateLocale, injectDialogStrategy, injectDialogStrategyDefaults, injectFormSupport, injectFullscreenDialogStrategy, injectFullscreenDialogStrategyDefaults, injectGridConfig, injectLeftSheetStrategy, injectLeftSheetStrategyDefaults, injectNotificationManager, injectNotificationManagerConfig, injectOverlayManager, injectOverlayRouter, injectOverlayScrollBlocker, injectOverlaySurfaceContext, injectPipChromeManager, injectPipManager, injectPipSlotPlaceholderConfig, injectRichTextEditorTools, injectRightSheetStrategy, injectRightSheetStrategyDefaults, injectSidebarOverlay, injectStreamConfig, injectStreamConsentConfig, injectStreamManager, injectStreamPlayerErrorConfig, injectStreamPlayerLoadingConfig, injectStreamScriptLoader, injectStreamUserConsentProvider, injectTimeFormat, injectTopSheetStrategy, injectTopSheetStrategyDefaults, isFileAccepted, isHtmlElement, isInteractiveElement, isPointerEvent, isTargetInsideOverlayTree, isTouchEvent, itemsCollide, leftSheetOverlayStrategy, mapLayoutToBreakpoint, matchCountryByDialCode, mergeOverlayBreakpointConfigs, mergeOverlayConfigs, nodesEqual, parseDuration, phoneCountryFlag, phoneCountryName, pixelRectsEqual, positionToPixelRect, positionsEqual, projectDragCell, provideAnchoredDialogStrategy, provideAnchoredDialogStrategyDefaults, provideBottomSheetStrategy, provideBottomSheetStrategyDefaults, provideDateFormat, provideDateLocale, provideDialogStrategy, provideDialogStrategyDefaults, provideFormErrorMessageResolver, provideFormSupport, provideFullscreenDialogStrategy, provideFullscreenDialogStrategyDefaults, provideGridConfig, provideIconOverrides, provideIcons, provideLeftSheetStrategy, provideLeftSheetStrategyDefaults, provideNotificationManager, provideNotificationManagerConfig, provideNotificationManagerInstance, provideOverlay, provideOverlayManager, provideOverlayRouter, provideOverlayRouterConfig, provideOverlayRouterService, provideOverlayScrollBlocker, providePipChromeManager, providePipManager, providePipSlotPlaceholderConfig, provideRichTextEditorAlignmentTool, provideRichTextEditorLanguageTool, provideRichTextEditorTableTool, provideRichTextEditorTokenRendering, provideRichTextEditorTools, provideRightSheetStrategy, provideRightSheetStrategyDefaults, provideSidebarOverlay, provideSidebarOverlayConfig, provideSidebarOverlayService, provideStreamConfig, provideStreamConsentConfig, provideStreamManager, provideStreamPlayerErrorConfig, provideStreamPlayerLoadingConfig, provideTimeFormat, provideTopSheetStrategy, provideTopSheetStrategyDefaults, reduceSupportPresentation, registerSingleton, requiredLanguages, resizeSpanBounds, resolveBreakpoint, resolveClosestOverlay, resolveCollisions, rightSheetOverlayStrategy, rowsToPixelHeight, selectOptionsFromQuery, selectOptionsFromV2Query, serializeGridLayout, snapResizeSpan, spanHeight, spanWidth, startFullscreenEnterAnimation, startFullscreenLeaveAnimation, stripTrunkZero, supportPresentationIncludesState, toChildrenObservable, toGridPosition, toPathObservable, toSearchObservable, topSheetOverlayStrategy, transformingBottomSheetToDialogOverlayStrategy, transformingFullScreenDialogToDialogOverlayStrategy, transformingFullScreenDialogToRightSheetOverlayStrategy, wireFormSupport };
|
|
37745
|
+
export { ALIGN_CENTER_ICON, ALIGN_JUSTIFY_ICON, ALIGN_LEFT_ICON, ALIGN_RIGHT_ICON, ARROW_OUT_UP_RIGHT_ICON, ARROW_RIGHT_ICON, BOLD_ICON, BUTTON_ICON_ALIGNMENTS, BUTTON_IMPORTS, BUTTON_SIZES, BUTTON_SPINNER_CONFIG, BUTTON_TYPES, BUTTON_VARIANTS, BrandLoaderComponent, ButtonComponent, ButtonDirective, ButtonStylesDirective, CALENDAR_ERROR_CODES, CALENDAR_ICON, CALENDAR_IMPORTS, CASCADER_ERROR_CODES, CASCADER_IMPORTS, CASCADER_SELECTABLE_LEVELS, CHECKBOX_IMPORTS, CHECK_ICON, CHEVRON_ICON, CHIP_ERROR_CODES, CHIP_IMPORTS, CHOICE_FIELD_IMPORTS, CLIPBOARD_CHECK_ICON, CLOCK_ICON, CODE_ICON, COLOR_INPUT_IMPORTS, CalendarCellDirective, CalendarComponent, CalendarDirective, CalendarGridDirective, CascaderColumnDirective, CascaderComponent, CascaderDirective, CascaderNodeDirective, CascaderPanelComponent, CascaderSearchDirective, CascaderSearchOptionDirective, CascaderSurfaceDirective, CascaderTriggerDirective, CheckboxComponent, CheckboxDirective, CheckboxGroupComponent, CheckboxOptionComponent, ChipComponent, ChipDirective, ChipRemoveDirective, ChoiceFieldComponent, ColorInputComponent, ColorInputDirective, DAILYMOTION_PLAYER_TOKEN, DATE_FORMAT, DATE_INPUT_ERROR_CODES, DATE_INPUT_IMPORTS, DATE_LOCALE, DATE_PICKER_HOST, DATE_RANGE_INPUT_ERROR_CODES, DATE_RANGE_INPUT_IMPORTS, DATE_TIME_INPUT_ERROR_CODES, DATE_TIME_INPUT_IMPORTS, DEFAULT_BREAKPOINTS, DEFAULT_ICON_VARIANT, DEFAULT_NOTIFICATION_MANAGER_CONFIG, DEFAULT_PIP_WINDOW_CONFIG, DEFAULT_RICH_TEXT_EDITOR_TOOLS, DEFAULT_STREAM_PLAYER_STATE, DROPZONE_ENTRY_STATUSES, DROPZONE_ERROR_CODES, DROPZONE_FILES_ERROR_KIND, DROPZONE_FILE_CONSTRAINTS, DROPZONE_FILE_REJECTION_REASONS, DROPZONE_IMPORTS, DURATION_INPUT_ERROR_CODES, DURATION_INPUT_IMPORTS, DailymotionPlayerComponent, DailymotionPlayerDirective, DailymotionPlayerParamsDirective, DailymotionPlayerSlotComponent, DateInputComponent, DateInputDirective, DateInputFieldDirective, DatePickerPanelComponent, DatePickerSurfaceDirective, DatePickerTriggerDirective, DateRangeInputComponent, DateRangeInputDirective, DateRangeInputFieldDirective, DateTimeInputComponent, DateTimeInputDirective, DateTimeInputFieldDirective, DescriptionComponent, DropzoneComponent, DropzoneDirective, DurationInputComponent, DurationInputDirective, DurationInputFieldDirective, ET_BUILT_IN_ICON_NAMES, EYE_ICON, EYE_SLASH_ICON, FACEBOOK_PLAYER_TOKEN, FILE_ICON, FLOPPY_DISK_ICON, FOCUS_FRAME_ICON, FORM_ERROR_MESSAGE_RESOLVER, FORM_FIELD_APPEARANCES, FORM_FIELD_CONTROL_TYPES, FORM_FIELD_ERROR_CODES, FORM_FIELD_FILLS, FORM_FIELD_IMPORTS, FORM_FIELD_LABEL_MODES, FORM_FIELD_SIZES, FORM_FIELD_TOKEN, FabComponent, FacebookPlayerComponent, FacebookPlayerDirective, FacebookPlayerParamsDirective, FacebookPlayerSlotComponent, FocusRingDirective, FormErrorComponent, FormFieldComponent, FormFieldDirective, GRID_2X2_ICON, GRID_ERROR_CODES, GRID_IMPORTS, GRID_TOKEN, GridComponent, GridDebugComponent, GridDirective, GridDragDirective, GridItemComponent, GridItemDefaultActionsComponent, GridItemDirective, GridItemRef, GridItemToolbarComponent, GridResizeDirective, HEADING_1_ICON, HEADING_2_ICON, HEADING_3_ICON, HintComponent, ICONS_TOKEN, ICON_DIRECTIVE_TOKEN, ICON_ERROR_CODES, ICON_IMPORTS, ICON_OVERRIDES_TOKEN, INITIAL_SUPPORT_PRESENTATION_STATE, INPUT_IMPORTS, INPUT_MASK_HOST, INPUT_TEXT_ALIGNMENTS, INPUT_TYPES, INTERACTIVE_TAGS, ITALIC_ICON, IconButtonComponent, IconDirective, InputComponent, InputDirective, InputMaskDirective, InputPrefixDirective, InputSuffixDirective, KICK_PLAYER_TOKEN, KickPlayerComponent, KickPlayerDirective, KickPlayerParamsDirective, KickPlayerSlotComponent, LINK_ICON, LIST_BULLETED_ICON, LIST_NUMBERED_ICON, LOCK_ICON, LabelDirective, MASKED_INPUT_ERROR_CODES, MASKED_INPUT_IMPORTS, MASK_VALUE_MODES, MENU_ERROR_CODES, MENU_IMPORTS, MENU_ITEM_VARIANTS, MENU_SELECTION_GROUP_MULTIPLE, MENU_SELECTION_GROUP_TOKEN, MENU_SELECTION_ITEM_KIND, MINUS_ICON, MULTI_LANGUAGE_RICH_TEXT_EDITOR_ERROR_CODES, MULTI_LANGUAGE_RICH_TEXT_EDITOR_IMPORTS, MenuCheckboxGroupComponent, MenuCheckboxItemComponent, MenuComponent, MenuContextTriggerDirective, MenuDirective, MenuGroupLabelComponent, MenuItemComponent, MenuItemDirective, MenuItemShortcutComponent, MenuPanelDirective, MenuRadioGroupComponent, MenuRadioItemComponent, MenuSearchDirective, MenuSelectionGroupDirective, MenuSelectionItemDirective, MenuSeparatorComponent, MenuSurfaceDirective, MenuTriggerDirective, MultiLanguageRichTextEditorComponent, MultiLanguageRichTextEditorDirective, MultiLanguageRichTextEditorLanguageToolComponent, NAV_TABS_TOKEN, NAV_TAB_IMPORTS, NOTIFICATION_ERROR_CODES, NOTIFICATION_IMPORTS, NOTIFICATION_STACK_CONTEXT_TOKEN, NOTIFICATION_STATUS, NUMBER_INPUT_IMPORTS, NavTabLinkComponent, NavTabLinkDirective, NavTabsComponent, NavTabsDirective, NavTabsOutletComponent, NavTabsOutletDirective, NotificationActionDirective, NotificationComponent, NotificationDirective, NotificationDismissDirective, NotificationItemDirective, NotificationStackDirective, NumberInputComponent, NumberInputDirective, OTP_INPUT_IMPORTS, OVERLAY_BACK_OR_CLOSE_TOKEN, OVERLAY_BODY_TOKEN, OVERLAY_CONFIG_CLASS_KEYS, OVERLAY_CONTENT_IMPORTS, OVERLAY_ERROR_CODES, OVERLAY_FOOTER_TOKEN, OVERLAY_HEADER_TEMPLATE_TOKEN, OVERLAY_HEADER_TOKEN, OVERLAY_IMPORTS, OVERLAY_MAIN_TOKEN, OVERLAY_QUERY_PARAM_INPUT_NAME, OVERLAY_REF, OVERLAY_ROUTER_CONFIG_TOKEN, OVERLAY_ROUTER_LINK_TOKEN, OVERLAY_ROUTER_OUTLET_DISABLED_TEMPLATE_TOKEN, OVERLAY_ROUTER_OUTLET_TOKEN, OVERLAY_ROUTER_TOKEN, OVERLAY_SHARED_ROUTE_TEMPLATE_TOKEN, OtpInputComponent, OtpInputDirective, OverlayAnchorDirective, OverlayBackOrCloseDirective, OverlayBodyComponent, OverlayCloseDirective, OverlayContainerComponent, OverlayDirective, OverlayFooterDirective, OverlayHeaderDirective, OverlayHeaderTemplateDirective, OverlayMainDirective, OverlayOriginCloneComponent, OverlayRouteHeaderTemplateOutletComponent, OverlayRouterLinkDirective, OverlayRouterOutletComponent, OverlayRouterOutletDisabledTemplateDirective, OverlaySharedRouteTemplateDirective, OverlaySharedRouteTemplateOutletComponent, OverlaySidebarComponent, OverlaySidebarPageComponent, OverlaySurfaceDirective, OverlayTitleDirective, OverlayTriggerDirective, PARAGRAPH_ICON, PASSWORD_INPUT_IMPORTS, PENCIL_ICON, PHONE_COUNTRIES, PHONE_INPUT_ERROR_CODES, PHONE_INPUT_IMPORTS, PIP_CHROME_REF_TOKEN, PIP_ENTRY_TOKEN, PIP_WINDOW_ASPECT_RATIO_TOKEN, PLUS_ICON, PasswordInputComponent, PasswordInputDirective, PhoneInputComponent, PhoneInputDirective, PhoneInputFieldDirective, PhoneInputFlagDirective, PipBackDirective, PipBringBackDirective, PipCellDirective, PipCloseDirective, PipCollapseOverlayDirective, PipGridToggleDirective, PipPlayerComponent, PipSlotPlaceholderComponent, PipStageDirective, PipTitleBarDirective, PipTitleBarTemplateDirective, PipWindowComponent, PipWindowParamsDirective, ProgressBarComponent, QUERY_DEVTOOLS_IMPORTS, QueryDevtoolsComponent, QueryDevtoolsJsonComponent, QueryDevtoolsToggleComponent, QueryParamOverlayLinkDirective, RATING_IMPORTS, RICH_TEXT_EDITOR_HEADING_OPTIONS, RICH_TEXT_EDITOR_IMPORTS, RICH_TEXT_EDITOR_INLINE_TOOLS, RICH_TEXT_EDITOR_LANGUAGE_TOOL, RICH_TEXT_EDITOR_TOKEN_CODEC, RICH_TEXT_EDITOR_TOKEN_PALETTE_IMPORTS, RICH_TEXT_EDITOR_TOOL, RICH_TEXT_EDITOR_TOOLS, RICH_TEXT_EDITOR_TOOL_BUTTONS, RICH_TEXT_EDITOR_TRIGGERS_IMPORTS, ROTATE_RIGHT_ICON, RadioComponent, RadioGroupComponent, RangeSliderComponent, RangeSliderDirective, RatingComponent, RatingDirective, RatingIconDirective, RichTextEditorAlignToolComponent, RichTextEditorComponent, RichTextEditorDirective, RichTextEditorFloatingToolbarComponent, RichTextEditorFloatingToolbarDirective, RichTextEditorLinkEditorComponent, RichTextEditorLinkEditorDirective, RichTextEditorTableToolComponent, RichTextEditorTokenPaletteComponent, RichTextEditorTokenPopupComponent, RichTextEditorTriggersDirective, SCROLLABLE_ERROR_CODES, SCROLLABLE_IMPORTS, SELECTION_LIST_MULTIPLE, SELECTION_LIST_TOKEN, SELECT_ERROR_CODES, SELECT_FILTER_MODES, SELECT_IMPORTS, SIDEBAR_OVERLAY_CONFIG, SIDEBAR_OVERLAY_TOKEN, SLIDER_ERROR_CODES, SLIDER_IMPORTS, SLIDER_TOKEN, SNAP_HYSTERESIS, SOOP_PLAYER_TOKEN, SPLIT_BUTTON_ERROR_CODES, STAR_ICON, STREAM_CONSENT_TOKEN, STREAM_IMPORTS, STREAM_PLAYER_COMPONENT_TOKEN, STREAM_PLAYER_ERROR_CONTEXT_TOKEN, STREAM_PLAYER_ERROR_TOKEN, STREAM_PLAYER_PARAMS_TOKEN, STREAM_PLAYER_SLOT_TOKEN, STREAM_PLAYER_TOKEN, STREAM_SLOT_PLAYER_ID_TOKEN, STREAM_USER_CONSENT_PROVIDER_TOKEN, STRIKETHROUGH_ICON, SUPPORT_CONTENT_STATE, SUPPORT_TRANSITION_DIRECTION, SWITCH_IMPORTS, ScrollableActiveChildDirective, ScrollableButtonsDirective, ScrollableComponent, ScrollableDarkenDirective, ScrollableDirective, ScrollableDragDirective, ScrollableIgnoreChildDirective, ScrollableLoadingTemplateDirective, ScrollableMasksDirective, ScrollableNavigationDirective, ScrollableSnapDirective, SegmentedButtonComponent, SegmentedButtonGroupComponent, SelectComponent, SelectDirective, SelectEmptyDirective, SelectErrorDirective, SelectListboxDirective, SelectLoadingDirective, SelectOptionComponent, SelectOptionDirective, SelectOptionGroupComponent, SelectOptionGroupDirective, SelectOptionTemplateDirective, SelectOptionsDirective, SelectPanelComponent, SelectSearchDirective, SelectSurfaceDirective, SelectTriggerDirective, SelectValueDirective, SelectViewportDirective, SelectVirtualOptionComponent, SelectVirtualOptionDirective, SelectionListControlDirective, SelectionListDirective, SelectionOptionDirective, SliderComponent, SliderDirective, SliderThumbDirective, SliderThumbLabelDirective, SliderTrackDirective, SoopPlayerComponent, SoopPlayerDirective, SoopPlayerParamsDirective, SoopPlayerSlotComponent, SpinnerComponent, SplitButtonActionDirective, SplitButtonComponent, SplitButtonDirective, SplitButtonTriggerDirective, StreamConsentAcceptDirective, StreamConsentComponent, StreamConsentDirective, StreamPipChromeComponent, StreamPlayerErrorComponent, StreamPlayerErrorDirective, StreamPlayerLoadingComponent, StreamPlayerSlotDirective, SwitchComponent, SwitchDirective, TABLE_ICON, TAB_BAR_FITS, TAB_BAR_ORIENTATIONS, TAB_BAR_TOKEN, TAB_BAR_TRIGGER_TOKEN, TAB_BAR_VARIANTS, TAB_ERROR_CODES, TAB_GROUP_TOKEN, TAB_IMPORTS, TAB_PANEL_TOKEN, TAB_SIZES, TAG_INPUT_ERROR_CODES, TAG_INPUT_IMPORTS, TEXTAREA_IMPORTS, TEXTAREA_RESIZE_MODES, TEXT_ALIGNS, TIKTOK_PLAYER_TOKEN, TIMES_ICON, TIME_FORMAT, TIME_INPUT_ERROR_CODES, TIME_INPUT_IMPORTS, TIME_PICKER_ERROR_CODES, TIME_PICKER_IMPORTS, TOGGLETIP_ERROR_CODES, TOGGLETIP_IMPORTS, TOOLTIP_ERROR_CODES, TOOLTIP_IMPORTS, TRIANGLE_EXCLAMATION_ICON, TWITCH_PLAYER_TOKEN, TabBarDirective, TabBarTriggerDirective, TabBarUnderlineDirective, TabComponent, TabGroupComponent, TabGroupDirective, TabLabelDirective, TabPanelDirective, TabTriggerDirective, TagInputComponent, TagInputDirective, TagInputFieldDirective, TextButtonComponent, TextFieldControlDirective, TextareaComponent, TextareaDirective, TikTokPlayerComponent, TikTokPlayerDirective, TikTokPlayerParamsDirective, TikTokPlayerSlotComponent, TimeInputComponent, TimeInputDirective, TimeInputFieldDirective, TimePickerColumnDirective, TimePickerComponent, TimePickerDirective, TimePickerOptionDirective, ToggletipCloseDirective, ToggletipComponent, ToggletipDirective, ToggletipTriggerDirective, TooltipComponent, TooltipDirective, TwitchPlayerComponent, TwitchPlayerDirective, TwitchPlayerParamsDirective, TwitchPlayerSlotComponent, UNDERLINE_ICON, UNIT_MS, UPLOAD_ICON, VIMEO_PLAYER_TOKEN, VimeoPlayerComponent, VimeoPlayerDirective, VimeoPlayerParamsDirective, VimeoPlayerSlotComponent, WINDOW_CONTROL_BUTTON_KINDS, WINDOW_CONTROL_BUTTON_SIZES, WindowControlButtonComponent, YOUTUBE_PLAYER_SLOT_TOKEN, YOUTUBE_PLAYER_TOKEN, YoutubePlayerComponent, YoutubePlayerDirective, YoutubePlayerParamsDirective, YoutubePlayerSlotComponent, YoutubePlayerSlotDirective, abortFullscreenAnimation, anchoredDialogOverlayStrategy, anchoredOverlayStrategy, autoPlace, bottomSheetOverlayStrategy, buildAnchoredRuntimePositionStrategy, canHaveChildren, cascaderFromQuery, centeredOverlayStrategy, clampPosition, clampResizeRect, cleanupFullscreenAnimation, cleanupFullscreenAnimationStyles, compactLayout, computeGeometry, computeGridHeight, createAnchoredPanelController, createAutoScroller, createCardMask, createCurrencyMask, createDefaultDropzoneArgs, createDropzoneUpload, createExistingDropzoneEntry, createFileDropzoneEntry, createGridAdapter, createIbanMask, createNotificationRef, createOverlayOpener, createOverlayRef, createOverlayStrategyController, createOverlayUnsavedChangesGuard, createPipChromeAnimations, createPipChromeState, createRichTextEditorTrigger, createRichTextEditorTriggerWithQuery, createStreamConfig, createStreamPlayerSlot, createV2DropzoneUpload, defaultCompareWith, defaultDropzoneRejectionMessage, defineOverlay, defineQueryParamOverlay, deriveDurationFormatSpec, deserializeGridLayout, dialogOverlayStrategy, disposeDropzoneEntry, dropzoneFiles, enableDragToDismiss, findCollision, findNextRelevantHtmlElement, findScrollableAncestor, formatDuration, formatFileSize, fromGridPosition, fullScreenDialogOverlayStrategy, getClosestOverlay, getOriginCoordinatesAndDimensions, hysteresisRound, iconRegistryKey, indexOfNode, injectAnchoredDialogStrategy, injectAnchoredDialogStrategyDefaults, injectBottomSheetStrategy, injectBottomSheetStrategyDefaults, injectDateFormat, injectDateLocale, injectDialogStrategy, injectDialogStrategyDefaults, injectFormSupport, injectFullscreenDialogStrategy, injectFullscreenDialogStrategyDefaults, injectGridConfig, injectLeftSheetStrategy, injectLeftSheetStrategyDefaults, injectNotificationManager, injectNotificationManagerConfig, injectOverlayManager, injectOverlayRouter, injectOverlayScrollBlocker, injectOverlaySurfaceContext, injectPipChromeManager, injectPipManager, injectPipSlotPlaceholderConfig, injectRichTextEditorTools, injectRightSheetStrategy, injectRightSheetStrategyDefaults, injectSidebarOverlay, injectStreamConfig, injectStreamConsentConfig, injectStreamManager, injectStreamPlayerErrorConfig, injectStreamPlayerLoadingConfig, injectStreamScriptLoader, injectStreamUserConsentProvider, injectTimeFormat, injectTopSheetStrategy, injectTopSheetStrategyDefaults, isFileAccepted, isHtmlElement, isInteractiveElement, isPointerEvent, isTargetInsideOverlayTree, isTouchEvent, itemsCollide, leftSheetOverlayStrategy, mapLayoutToBreakpoint, matchCountryByDialCode, mergeOverlayBreakpointConfigs, mergeOverlayConfigs, nodesEqual, parseDuration, phoneCountryFlag, phoneCountryName, pixelRectsEqual, positionToPixelRect, positionsEqual, projectDragCell, provideAnchoredDialogStrategy, provideAnchoredDialogStrategyDefaults, provideBottomSheetStrategy, provideBottomSheetStrategyDefaults, provideDateFormat, provideDateLocale, provideDialogStrategy, provideDialogStrategyDefaults, provideFormErrorMessageResolver, provideFormSupport, provideFullscreenDialogStrategy, provideFullscreenDialogStrategyDefaults, provideGridConfig, provideIconOverrides, provideIcons, provideLeftSheetStrategy, provideLeftSheetStrategyDefaults, provideNotificationManager, provideNotificationManagerConfig, provideNotificationManagerInstance, provideOverlay, provideOverlayManager, provideOverlayRouter, provideOverlayRouterConfig, provideOverlayRouterService, provideOverlayScrollBlocker, providePipChromeManager, providePipManager, providePipSlotPlaceholderConfig, provideRichTextEditorAlignmentTool, provideRichTextEditorLanguageTool, provideRichTextEditorTableTool, provideRichTextEditorTokenRendering, provideRichTextEditorTools, provideRightSheetStrategy, provideRightSheetStrategyDefaults, provideSidebarOverlay, provideSidebarOverlayConfig, provideSidebarOverlayService, provideStreamConfig, provideStreamConsentConfig, provideStreamManager, provideStreamPlayerErrorConfig, provideStreamPlayerLoadingConfig, provideTimeFormat, provideTopSheetStrategy, provideTopSheetStrategyDefaults, reduceSupportPresentation, registerSingleton, requiredLanguages, resizeSpanBounds, resolveBreakpoint, resolveClosestOverlay, resolveCollisions, rightSheetOverlayStrategy, rowsToPixelHeight, selectOptionsFromQuery, selectOptionsFromV2Query, serializeGridLayout, snapResizeSpan, spanHeight, spanWidth, startFullscreenEnterAnimation, startFullscreenLeaveAnimation, stripTrunkZero, supportPresentationIncludesState, toChildrenObservable, toGridPosition, toPathObservable, toSearchObservable, topSheetOverlayStrategy, transformingBottomSheetToDialogOverlayStrategy, transformingFullScreenDialogToDialogOverlayStrategy, transformingFullScreenDialogToRightSheetOverlayStrategy, wireFormSupport };
|
|
36708
37746
|
//# sourceMappingURL=ethlete-components.mjs.map
|