@ethlete/core 5.0.0-next.27 → 5.0.0-next.28

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @ethlete/core
2
2
 
3
+ ## 5.0.0-next.28
4
+
5
+ ### Minor Changes
6
+
7
+ - [#3022](https://github.com/ethlete-io/ethdk/pull/3022) [`9431073`](https://github.com/ethlete-io/ethdk/commit/9431073bb693aa10bbb84d5196597cb2c4b7463f) Thanks [@github-actions](https://github.com/apps/github-actions)! - Overlays and menus now open on insecure origins (plain-HTTP pages on a LAN IP, not just `localhost`/HTTPS). Id generation used `crypto.randomUUID()`, which is `undefined` outside a secure context, so opening any dialog, sheet, anchored overlay or menu threw and only the backdrop appeared. A new `randomId()` helper in `@ethlete/core` uses `crypto.randomUUID()` when available and falls back to `getRandomValues` otherwise.
8
+
9
+ - [#3022](https://github.com/ethlete-io/ethdk/pull/3022) [`9431073`](https://github.com/ethlete-io/ethdk/commit/9431073bb693aa10bbb84d5196597cb2c4b7463f) Thanks [@github-actions](https://github.com/apps/github-actions)! - Rich text editor: the link flow is now a responsive popover (arrow-anchored on wider screens, a keyboard-pinned top sheet on touch) to edit a link's text and URL, with an open-in-new-tab toggle — replacing the browser `prompt()`. New-tab links persist through the Markdown value as raw HTML (`<a target="_blank" rel="noopener noreferrer">`); ordinary links stay `[text](url)`. `htmlToMarkdown` / `markdownToHtml` in `@ethlete/core` now round-trip `target="_blank"` anchors (sanitized href + forced `rel`). After applying a link the caret moves just past it, with a trailing space added when the link ends the line.
10
+
11
+ ### Patch Changes
12
+
13
+ - [#3022](https://github.com/ethlete-io/ethdk/pull/3022) [`49591f4`](https://github.com/ethlete-io/ethdk/commit/49591f4e529552fde07ef88b9754bf7c0cd91a3b) Thanks [@github-actions](https://github.com/apps/github-actions)! - `injectAnimatedBlockSize`: growing panels (menu, select) no longer flash at their final size for one frame before the resize animation plays — the animation now starts inside the `ResizeObserver` callback, before the browser paints the new layout.
14
+
15
+ - [#3022](https://github.com/ethlete-io/ethdk/pull/3022) [`d262f59`](https://github.com/ethlete-io/ethdk/commit/d262f596a4f0e3dda315447d0173cba301237c01) Thanks [@github-actions](https://github.com/apps/github-actions)! - `htmlToMarkdown`: boundary whitespace inside bold/italic/strikethrough now serializes outside the delimiters (`<strong> x</strong>` → ` **x**` instead of the invalid `** x**`).
16
+
17
+ - [#3022](https://github.com/ethlete-io/ethdk/pull/3022) [`00b7c33`](https://github.com/ethlete-io/ethdk/commit/00b7c337e5ae0ac1bfc7186237b1ac2879eb018d) Thanks [@github-actions](https://github.com/apps/github-actions)! - Theming: overlay panes (menu, select) now resolve their color context through passive providers and apply it before the first painted frame.
18
+ - `ProvideColorDirective` gains `resolvedColor` — the color that actually applies at the provider's location, falling through passive providers like the CSS cascade does. `syncWithProvider` uses it, so a passive in-between provider (e.g. a form field's) no longer erases the theme inside a detached overlay pane.
19
+ - The menu and select panels install the context sync during construction instead of in an effect, eliminating a wrong-theme flash during the enter animation.
20
+
3
21
  ## 5.0.0-next.27
4
22
 
5
23
  ### Minor Changes
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, inject, ElementRef, Directive, assertInInjectionContext, DestroyRef, TemplateRef, QueryList, RendererFactory2, RendererStyleFlags2, isSignal, DOCUMENT, signal, linkedSignal, isDevMode, computed, afterNextRender, effect, NgZone, untracked, EnvironmentInjector, runInInjectionContext, Injector, booleanAttribute, numberAttribute, PLATFORM_ID, ApplicationRef, createComponent, model, ViewContainerRef, input, output, Pipe, ViewEncapsulation, Component } from '@angular/core';
3
3
  import { takeUntilDestroyed, toSignal, toObservable, outputFromObservable } from '@angular/core/rxjs-interop';
4
- import { Subject, BehaviorSubject, debounceTime, combineLatest, map, merge, fromEvent, filter, tap, switchMap, startWith, of, timer, takeUntil, pairwise, distinctUntilChanged, take, Observable, concatMap, EMPTY, concat, defer, exhaustMap, share } from 'rxjs';
4
+ import { Subject, BehaviorSubject, debounceTime, combineLatest, map, merge, fromEvent, filter, tap, switchMap, startWith, of, defer, from, catchError, timer, takeUntil, pairwise, distinctUntilChanged, take, Observable, concatMap, EMPTY, concat, exhaustMap, share } from 'rxjs';
5
5
  import { FormGroup, FormArray, FormControl } from '@angular/forms';
6
6
  import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
7
7
  import { coerceElement } from '@angular/cdk/coercion';
@@ -132,6 +132,29 @@ const createComponentId = (prefix) => {
132
132
  componentIds.set(prefix, id + 1);
133
133
  return `${prefix}-${id}`;
134
134
  };
135
+ let randomIdFallbackCounter = 0;
136
+ /**
137
+ * A unique id string. Uses `crypto.randomUUID()` when available, but falls back gracefully when it is
138
+ * not — crucially in **insecure contexts** (a plain-HTTP page served from a LAN IP, not `localhost`),
139
+ * where `crypto.randomUUID` is `undefined`. Calling it there throws, so anything using it during e.g.
140
+ * an overlay/menu open would break on such hosts. Prefer this over `crypto.randomUUID()` directly.
141
+ */
142
+ const randomId = () => {
143
+ const cryptoObj = typeof globalThis !== 'undefined' ? globalThis.crypto : undefined;
144
+ if (typeof cryptoObj?.randomUUID === 'function') {
145
+ return cryptoObj.randomUUID();
146
+ }
147
+ // `getRandomValues` is available even in insecure contexts — build an RFC-4122-ish v4 id from it.
148
+ if (typeof cryptoObj?.getRandomValues === 'function') {
149
+ const bytes = Array.from(cryptoObj.getRandomValues(new Uint8Array(16)));
150
+ bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;
151
+ bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;
152
+ const hex = bytes.map((byte) => (byte ?? 0).toString(16).padStart(2, '0'));
153
+ return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex.slice(6, 8).join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10, 16).join('')}`;
154
+ }
155
+ // last resort: no Web Crypto at all — a session-unique (not cryptographic) id is enough for DOM ids
156
+ return `et-id-${(randomIdFallbackCounter++).toString(36)}-${Date.now().toString(36)}`;
157
+ };
135
158
 
136
159
  const createDestroy = () => {
137
160
  assertInInjectionContext(createDestroy);
@@ -360,32 +383,23 @@ const Validators = {
360
383
  ValidateAtLeastOneRequired,
361
384
  };
362
385
 
363
- const copyToClipboard = async (text) => {
386
+ const copyToClipboard = (text) => defer(() => {
364
387
  if (typeof navigator === 'undefined' || typeof document === 'undefined') {
365
- return false;
388
+ return of(false);
366
389
  }
367
390
  if (navigator.clipboard) {
368
- try {
369
- await navigator.clipboard.writeText(text);
370
- return true;
371
- }
372
- catch {
373
- // The async Clipboard API can be blocked (missing permission, insecure context) — try the legacy path.
374
- }
391
+ return from(navigator.clipboard.writeText(text)).pipe(map(() => true),
392
+ // The async Clipboard API can be blocked (missing permission, insecure context) — try the legacy path.
393
+ catchError(() => of(copyToClipboardViaExecCommand(text))));
375
394
  }
376
- return copyToClipboardViaExecCommand(text);
377
- };
378
- const readFromClipboard = async () => {
395
+ return of(copyToClipboardViaExecCommand(text));
396
+ });
397
+ const readFromClipboard = () => defer(() => {
379
398
  if (typeof navigator === 'undefined' || !navigator.clipboard) {
380
- return null;
381
- }
382
- try {
383
- return await navigator.clipboard.readText();
384
- }
385
- catch {
386
- return null;
399
+ return of(null);
387
400
  }
388
- };
401
+ return from(navigator.clipboard.readText()).pipe(catchError(() => of(null)));
402
+ });
389
403
  const copyToClipboardViaExecCommand = (text) => {
390
404
  const previouslyFocusedElement = document.activeElement;
391
405
  const textarea = document.createElement('textarea');
@@ -1323,9 +1337,15 @@ const injectScrollbarDimensions = memoizeSignal(() => {
1323
1337
  * element(s) and animates the host from its previous height to its new natural height.
1324
1338
  *
1325
1339
  * Robustness notes: the baseline height is captured on the first render (via `afterNextRender`) and
1326
- * the effect only animates after that, so the initial layout settling never plays as a grow-from-0.
1340
+ * only later changes animate, so the initial layout settling never plays as a grow-from-0.
1327
1341
  * A change that interrupts an in-flight animation continues from the current animated height, and
1328
1342
  * zero/pre-layout measurements are ignored. Respects `prefers-reduced-motion`.
1343
+ *
1344
+ * The animation starts synchronously inside the `ResizeObserver` callback — it runs after layout
1345
+ * but **before paint**, so the host never paints a frame at its new natural size. Routing the
1346
+ * resize through a signal + effect instead would apply the animation one change-detection cycle
1347
+ * (= one painted frame) late: a growing panel would flash at its final size, snap back, and only
1348
+ * then animate.
1329
1349
  */
1330
1350
  const injectAnimatedBlockSize = (config) => {
1331
1351
  const hostBinding = config.host ?? inject(ElementRef);
@@ -1334,7 +1354,7 @@ const injectAnimatedBlockSize = (config) => {
1334
1354
  const destroyRef = inject(DestroyRef);
1335
1355
  const hostSignal = firstElementSignal(buildElementSignal(hostBinding));
1336
1356
  const observeTargets = Array.isArray(config.observe) ? config.observe : [config.observe];
1337
- const dimensionSignals = observeTargets.map((target) => signalElementDimensions(target));
1357
+ const observedElements = observeTargets.map((target) => firstElementSignal(buildElementSignal(target)));
1338
1358
  const duration = config.duration ?? 160;
1339
1359
  const easing = config.easing ?? 'ease';
1340
1360
  let lastBlockSize = null;
@@ -1372,20 +1392,33 @@ const injectAnimatedBlockSize = (config) => {
1372
1392
  nextAnimation.finished.then(cleanup).catch(cleanup);
1373
1393
  animation = nextAnimation;
1374
1394
  };
1395
+ // no zone/signal indirection — see the pre-paint timing note in the doc comment above
1396
+ const observer = new ResizeObserver(() => {
1397
+ if (!ready)
1398
+ return;
1399
+ run();
1400
+ });
1401
+ effect(() => {
1402
+ const elements = observedElements.map((element) => element().currentElement);
1403
+ untracked(() => {
1404
+ observer.disconnect();
1405
+ for (const element of elements) {
1406
+ if (element) {
1407
+ observer.observe(element);
1408
+ }
1409
+ }
1410
+ });
1411
+ });
1375
1412
  // Capture the settled height of the first render as the baseline, then only animate later changes.
1376
1413
  afterNextRender(() => {
1377
1414
  const host = hostElement();
1378
1415
  lastBlockSize = host ? host.getBoundingClientRect().height || null : null;
1379
1416
  ready = true;
1380
1417
  });
1381
- effect(() => {
1382
- // track every observed element's size
1383
- dimensionSignals.forEach((dimensions) => dimensions());
1384
- if (!ready)
1385
- return;
1386
- untracked(() => run());
1418
+ destroyRef.onDestroy(() => {
1419
+ observer.disconnect();
1420
+ animation?.cancel();
1387
1421
  });
1388
- destroyRef.onDestroy(() => animation?.cancel());
1389
1422
  };
1390
1423
 
1391
1424
  /**
@@ -2986,6 +3019,16 @@ const parseSeparatorAligns = (line) => parseTableRow(line).map((cell) => {
2986
3019
  /** The GFM separator token for a column alignment. */
2987
3020
  const separatorFor = (align) => align === 'center' ? ':---:' : align === 'right' ? '---:' : align === 'left' ? ':---' : '---';
2988
3021
  const alignStyle = (align) => (align ? ` style="text-align: ${align}"` : '');
3022
+ /** Wraps `content` in an emphasis `marker`, hoisting boundary whitespace outside the delimiters —
3023
+ * CommonMark emphasis must not face whitespace on the inside (`** fett**` doesn't parse), and
3024
+ * `&nbsp;` counts as whitespace there too. Whitespace-only content stays unwrapped. */
3025
+ const emphasize = (marker, content) => {
3026
+ const lead = /^(?:\s|&nbsp;)+/i.exec(content)?.[0] ?? '';
3027
+ const rest = content.slice(lead.length);
3028
+ const trail = /(?:\s|&nbsp;)+$/i.exec(rest)?.[0] ?? '';
3029
+ const core = rest.slice(0, rest.length - trail.length);
3030
+ return core ? `${lead}${marker}${core}${marker}${trail}` : content;
3031
+ };
2989
3032
  const makePlaceholder = (kind, idx) => `\u{E000}${kind}${idx}\u{E001}`;
2990
3033
  const placeholderRe = (kind) => new RegExp(`\u{E000}${kind}(\\d+)\u{E001}`, 'gu');
2991
3034
  const isPlaceholder = (kind, str) => new RegExp(`^\u{E000}${kind}\\d+\u{E001}$`, 'u').test(str);
@@ -3015,6 +3058,19 @@ const processInline = (text) => {
3015
3058
  const idx = inlineCodes.push(`<code>${escapeHtml(code)}</code>`) - 1;
3016
3059
  return makePlaceholder('IC', idx);
3017
3060
  });
3061
+ // "Open in new tab" links round-trip as raw HTML because Markdown has no `target` syntax. Extract
3062
+ // them before the raw-HTML escape below, keeping only a safe href, `target="_blank"` and a forced
3063
+ // `rel="noopener noreferrer"` (any other attribute — including event handlers — is dropped); their
3064
+ // inner markup is processed recursively. Anything else that looks like raw HTML is still escaped.
3065
+ const newTabLinks = [];
3066
+ text = text.replace(/<a\b([^>]*)>([\s\S]*?)<\/a>/gi, (full, attrs, inner) => {
3067
+ const href = /\bhref\s*=\s*"([^"]*)"/i.exec(attrs)?.[1];
3068
+ const newTab = /\btarget\s*=\s*"_blank"/i.test(attrs);
3069
+ if (!newTab || !href || !isSafeUrl(href))
3070
+ return full;
3071
+ const anchor = `<a href="${href}" target="_blank" rel="noopener noreferrer">${processInline(inner)}</a>`;
3072
+ return makePlaceholder('NTLINK', newTabLinks.push(anchor) - 1);
3073
+ });
3018
3074
  // Raw HTML in Markdown text is escaped, not rendered — the editor writes this HTML straight
3019
3075
  // into the DOM via innerHTML, so anything else would let a crafted value inject markup. `<u>`
3020
3076
  // is the one deliberate exception: underline has no Markdown form and round-trips as raw <u>.
@@ -3031,7 +3087,9 @@ const processInline = (text) => {
3031
3087
  // Images before links (order matters); URLs with script-running schemes stay literal text
3032
3088
  text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (match, alt, src) => isSafeUrl(src) ? `<img src="${src}" alt="${alt}">` : match);
3033
3089
  text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (match, label, href) => isSafeUrl(href) ? `<a href="${href}">${label}</a>` : match);
3034
- return text.replace(placeholderRe('IC'), (_, i) => inlineCodes[+i] ?? '');
3090
+ return text
3091
+ .replace(placeholderRe('IC'), (_, i) => inlineCodes[+i] ?? '')
3092
+ .replace(placeholderRe('NTLINK'), (_, i) => newTabLinks[+i] ?? '');
3035
3093
  };
3036
3094
  // --- Nested list helpers (regex can't match balanced nesting, so these scan by tag depth) ---
3037
3095
  /** The first top-level `<ul>`/`<ol>` in `html`, matched with balanced nesting. */
@@ -3239,16 +3297,27 @@ const htmlToMarkdown = (html) => {
3239
3297
  for (let i = 6; i >= 1; i--) {
3240
3298
  md = md.replace(new RegExp(`<h${i}[^>]*>([\\s\\S]*?)<\\/h${i}>`, 'gi'), (_, content) => `\n${'#'.repeat(i)} ${content.trim()}\n`);
3241
3299
  }
3242
- // Bold + italic (combined before individual)
3243
- md = md.replace(/<strong[^>]*><em[^>]*>([\s\S]*?)<\/em><\/strong>/gi, '***$1***');
3244
- md = md.replace(/<em[^>]*><strong[^>]*>([\s\S]*?)<\/strong><\/em>/gi, '***$1***');
3245
- md = md.replace(/<(strong|b)[^>]*>([\s\S]*?)<\/\1>/gi, '**$2**');
3246
- md = md.replace(/<(em|i)[^>]*>([\s\S]*?)<\/\1>/gi, '*$2*');
3247
- md = md.replace(/<(del|s|strike)[^>]*>([\s\S]*?)<\/\1>/gi, '~~$2~~');
3300
+ // Bold + italic (combined before individual). Boundary whitespace is hoisted out of the
3301
+ // delimiters (emphasize) — `<strong> x</strong>` must become ` **x**`, not the invalid `** x**`.
3302
+ md = md.replace(/<strong[^>]*><em[^>]*>([\s\S]*?)<\/em><\/strong>/gi, (_, c) => emphasize('***', c));
3303
+ md = md.replace(/<em[^>]*><strong[^>]*>([\s\S]*?)<\/strong><\/em>/gi, (_, c) => emphasize('***', c));
3304
+ md = md.replace(/<(strong|b)[^>]*>([\s\S]*?)<\/\1>/gi, (_, _tag, c) => emphasize('**', c));
3305
+ md = md.replace(/<(em|i)[^>]*>([\s\S]*?)<\/\1>/gi, (_, _tag, c) => emphasize('*', c));
3306
+ md = md.replace(/<(del|s|strike)[^>]*>([\s\S]*?)<\/\1>/gi, (_, _tag, c) => emphasize('~~', c));
3248
3307
  // Inline code
3249
3308
  md = md.replace(/<code[^>]*>([\s\S]*?)<\/code>/gi, (_, code) => `\`${unescapeHtml(code)}\``);
3250
- // Links and images
3251
- md = md.replace(/<a[^>]+href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/gi, '[$2]($1)');
3309
+ // Links and images. A link with `target="_blank"` has no Markdown form, so it round-trips as raw
3310
+ // HTML (keeping only href + target + rel) via a placeholder — like underline below; ordinary links
3311
+ // become `[text](url)`.
3312
+ const newTabLinks = [];
3313
+ md = md.replace(/<a\b([^>]*)>([\s\S]*?)<\/a>/gi, (_, attrs, inner) => {
3314
+ const href = /\bhref\s*=\s*"([^"]*)"/i.exec(attrs)?.[1] ?? '';
3315
+ if (/\btarget\s*=\s*"_blank"/i.test(attrs) && href) {
3316
+ const anchor = `<a href="${href}" target="_blank" rel="noopener noreferrer">${inner}</a>`;
3317
+ return makePlaceholder('NTLINK', newTabLinks.push(anchor) - 1);
3318
+ }
3319
+ return href ? `[${inner}](${href})` : inner;
3320
+ });
3252
3321
  md = md.replace(/<img[^>]+src="([^"]*)"[^>]*alt="([^"]*)"[^>]*\/?>/gi, '![$2]($1)');
3253
3322
  md = md.replace(/<img[^>]+alt="([^"]*)"[^>]*src="([^"]*)"[^>]*\/?>/gi, '![$1]($2)');
3254
3323
  md = md.replace(/<img[^>]+src="([^"]*)"[^>]*\/?>/gi, '![]($1)');
@@ -3302,6 +3371,8 @@ const htmlToMarkdown = (html) => {
3302
3371
  md = md.replace(/<br\s*\/?>/gi, '\n');
3303
3372
  md = md.replace(/<hr\s*\/?>/gi, '\n---\n');
3304
3373
  md = unescapeHtml(stripTags(md)).replace(placeholderRe('U'), (_, i) => `<u>${underlines[+i] ?? ''}</u>`);
3374
+ // new-tab links survive the tag-strip as raw HTML (restored after it, like underline)
3375
+ md = md.replace(placeholderRe('NTLINK'), (_, i) => newTabLinks[+i] ?? '');
3305
3376
  // aligned blocks are block-level, so pad with blank lines before collapsing so they survive as
3306
3377
  // their own Markdown block
3307
3378
  md = md.replace(placeholderRe('ALIGN'), (_, i) => `\n\n${alignedBlocks[+i] ?? ''}\n\n`);
@@ -7700,6 +7771,7 @@ class ProvideColorDirective {
7700
7771
  this.themes = injectColorThemes({ optional: true });
7701
7772
  this.prefix = injectColorThemesPrefix({ optional: true });
7702
7773
  this.injector = inject(Injector);
7774
+ this.parentProvider = inject(COLOR_PROVIDER, { optional: true, skipSelf: true });
7703
7775
  this.currentProviderSync = null;
7704
7776
  this.forcedColor = signal(FORCED_COLOR_UNSET, /* @ts-ignore */
7705
7777
  ...(ngDevMode ? [{ debugName: "forcedColor" }] : /* istanbul ignore next */ []));
@@ -7712,6 +7784,22 @@ class ProvideColorDirective {
7712
7784
  return this.color();
7713
7785
  }, /* @ts-ignore */
7714
7786
  ...(ngDevMode ? [{ debugName: "effectiveColor" }] : /* istanbul ignore next */ []));
7787
+ /**
7788
+ * The color that actually applies at this provider's location: its own effective color, or —
7789
+ * when this provider is passive (no input, nothing forced) — the nearest ancestor provider's.
7790
+ * Mirrors the CSS cascade, which falls through a provider's `-color--inherited` scope class;
7791
+ * consumers that re-apply context across detached DOM (overlay panes) must use this instead
7792
+ * of `effectiveColor` or a passive in-between provider (e.g. a form field's) erases the theme.
7793
+ */
7794
+ this.resolvedColor = computed(() => {
7795
+ const own = this.effectiveColor();
7796
+ const ownName = typeof own === 'object' && own !== null ? own.name : own;
7797
+ if (ownName) {
7798
+ return own;
7799
+ }
7800
+ return this.parentProvider?.resolvedColor();
7801
+ }, /* @ts-ignore */
7802
+ ...(ngDevMode ? [{ debugName: "resolvedColor" }] : /* istanbul ignore next */ []));
7715
7803
  this.colorName = computed(() => {
7716
7804
  const raw = this.effectiveColor();
7717
7805
  const value = typeof raw === 'object' && raw !== null ? raw.name : raw;
@@ -7736,7 +7824,7 @@ class ProvideColorDirective {
7736
7824
  this.currentProviderSync?.destroy();
7737
7825
  runInInjectionContext(this.injector, () => {
7738
7826
  this.currentProviderSync = effect(() => {
7739
- const provideColor = provider.effectiveColor();
7827
+ const provideColor = provider.resolvedColor();
7740
7828
  untracked(() => {
7741
7829
  if (provideColor === undefined) {
7742
7830
  this.clearForcedColor();
@@ -7847,5 +7935,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
7847
7935
  * Generated bundle index. Do not edit.
7848
7936
  */
7849
7937
 
7850
- export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PROVIDER, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MustMatch, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RuntimeError, SEO_DIRECTIVE_TOKEN, SURFACE_PROVIDER, SURFACE_TYPE, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SeoDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, ValidateAtLeastOneRequired, Validators, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boolBreakpointTransform, booleanBreakpointAttribute, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createProvider, createRootProvider, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createStaticProvider, createStaticRootProvider, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUserConsentProvider, deferredSignal, deleteCookie, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, equal, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideViewportConfig, readFromClipboard, resetPositioningStyles, resolveSurfaceByElevation, round, routerDisableScrollTop, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toStringBinding, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
7938
+ export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PROVIDER, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MustMatch, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RuntimeError, SEO_DIRECTIVE_TOKEN, SURFACE_PROVIDER, SURFACE_TYPE, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SeoDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, ValidateAtLeastOneRequired, Validators, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boolBreakpointTransform, booleanBreakpointAttribute, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createProvider, createRootProvider, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createStaticProvider, createStaticRootProvider, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUserConsentProvider, deferredSignal, deleteCookie, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, equal, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideViewportConfig, randomId, readFromClipboard, resetPositioningStyles, resolveSurfaceByElevation, round, routerDisableScrollTop, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toStringBinding, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
7851
7939
  //# sourceMappingURL=ethlete-core.mjs.map