valtech-components 2.0.803 → 2.0.805

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, Injectable, makeEnvironmentProviders, APP_INITIALIZER, inject, EventEmitter, Component, Input, Output, input, computed, ChangeDetectionStrategy, HostBinding, HostListener, Pipe, effect, ViewChild, ChangeDetectorRef, ContentChild, PLATFORM_ID, Inject, ErrorHandler, DestroyRef, InjectionToken, runInInjectionContext, Optional, TemplateRef, ViewContainerRef, isSignal, Directive, ElementRef, ViewEncapsulation } from '@angular/core';
2
+ import { signal, Injectable, makeEnvironmentProviders, APP_INITIALIZER, inject, EventEmitter, Component, Input, Output, input, computed, ChangeDetectionStrategy, HostBinding, HostListener, Pipe, effect, ViewChild, ChangeDetectorRef, ContentChild, PLATFORM_ID, Inject, ErrorHandler, DestroyRef, InjectionToken, runInInjectionContext, Optional, Injector, TemplateRef, ViewContainerRef, isSignal, Directive, ElementRef, ViewEncapsulation } from '@angular/core';
3
3
  import * as i2$1 from '@ionic/angular/standalone';
4
4
  import { IonAvatar, IonCard, IonIcon, IonButton, IonSpinner, IonText, IonModal, IonHeader, IonToolbar, IonContent, IonButtons, IonTitle, IonProgressBar, IonSkeletonText, IonFab, IonFabButton, IonFabList, IonLabel, IonCardContent, IonCardHeader, IonCardTitle, IonCardSubtitle, IonCheckbox, IonTextarea, IonDatetime, IonDatetimeButton, IonInput, IonSelect, IonSelectOption, IonPopover, IonList, IonItem, IonRadioGroup, IonRadio, IonRange, IonSearchbar, IonSegment, IonSegmentButton, IonToggle, IonAccordion, IonAccordionGroup, IonTabBar, IonTabButton, IonBadge, IonBreadcrumb, IonBreadcrumbs, IonChip, IonNote, ToastController as ToastController$1, IonCol, IonRow, IonRefresher, IonRefresherContent, IonRippleEffect, AlertController, IonMenuButton, IonFooter, IonListHeader, IonInfiniteScroll, IonInfiniteScrollContent, IonGrid, MenuController, IonMenu, IonMenuToggle, IonSplitPane } from '@ionic/angular/standalone';
5
5
  import * as i1 from '@angular/common';
@@ -14,7 +14,7 @@ import { DomSanitizer, Meta, Title } from '@angular/platform-browser';
14
14
  import QRCodeStyling from 'qr-code-styling';
15
15
  import * as i1$3 from '@angular/forms';
16
16
  import { ReactiveFormsModule, FormsModule, FormControl, Validators, FormBuilder } from '@angular/forms';
17
- import { BehaviorSubject, map, throwError, Subject, distinctUntilChanged, EMPTY, of, from, Observable, firstValueFrom, debounceTime, switchMap as switchMap$1, catchError as catchError$1, takeUntil, isObservable, filter as filter$1, shareReplay } from 'rxjs';
17
+ import { BehaviorSubject, map, throwError, Subject, distinctUntilChanged, filter as filter$1, take as take$1, firstValueFrom, of, from, EMPTY, Observable, debounceTime, switchMap as switchMap$1, catchError as catchError$1, takeUntil, isObservable, shareReplay, timer } from 'rxjs';
18
18
  import * as i1$4 from 'ng-otp-input';
19
19
  import { NgOtpInputComponent, NgOtpInputModule } from 'ng-otp-input';
20
20
  import * as i2 from '@ionic/angular';
@@ -37,8 +37,8 @@ import { provideAuth, getAuth, connectAuthEmulator, authState, signInWithCustomT
37
37
  import { provideMessaging, getMessaging, getToken, deleteToken, onMessage } from '@angular/fire/messaging';
38
38
  import * as i1$7 from '@angular/fire/storage';
39
39
  import { provideStorage, getStorage, connectStorageEmulator, ref, uploadBytesResumable, getDownloadURL, getMetadata, deleteObject, listAll } from '@angular/fire/storage';
40
- import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
41
- import { filter, catchError, switchMap, finalize, take, tap, map as map$1, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs/operators';
40
+ import { takeUntilDestroyed, toSignal, toObservable } from '@angular/core/rxjs-interop';
41
+ import { filter, catchError, switchMap, finalize, take, map as map$1, tap, retry, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs/operators';
42
42
  import * as i1$8 from '@angular/common/http';
43
43
  import { provideHttpClient, withInterceptors, HttpErrorResponse, HttpClient } from '@angular/common/http';
44
44
  import { isSupported, getMessaging as getMessaging$1 } from 'firebase/messaging';
@@ -52,7 +52,7 @@ import 'prismjs/components/prism-json';
52
52
  * Current version of valtech-components.
53
53
  * This is automatically updated during the publish process.
54
54
  */
55
- const VERSION = '2.0.803';
55
+ const VERSION = '2.0.805';
56
56
 
57
57
  /**
58
58
  * Servicio para gestionar presets de componentes.
@@ -21072,12 +21072,46 @@ class FirebaseService {
21072
21072
  });
21073
21073
  /** Estado actual de la sesión como Observable */
21074
21074
  this.state$ = this.sessionState.asObservable();
21075
+ /**
21076
+ * Signal interna que respalda `firebaseAuthReady`.
21077
+ * `true` cuando hay un `firebase.User` activo y por tanto las reglas de
21078
+ * Firestore evaluarán `request.auth != null` correctamente.
21079
+ */
21080
+ this._firebaseAuthReady = signal(false);
21081
+ /**
21082
+ * Indica si la sesión de **Firebase Auth** está establecida y lista para
21083
+ * leer Firestore.
21084
+ *
21085
+ * IMPORTANTE: esto es distinto del JWT del backend. La sesión de Firebase
21086
+ * Auth es una sesión separada que se establece vía `signInWithCustomToken`
21087
+ * (ver `AuthService.signInWithFirebase`). En cold start de PWA, el JWT del
21088
+ * backend puede estar listo varios cientos de ms antes de que Firebase Auth
21089
+ * confirme su `User` — adjuntar un listener de Firestore en esa ventana
21090
+ * produce `permission-denied`.
21091
+ *
21092
+ * Usar este signal (o `whenFirebaseAuthReady()`) como gate antes de
21093
+ * suscribirse a cualquier query/listener de Firestore.
21094
+ *
21095
+ * @example
21096
+ * ```typescript
21097
+ * if (this.firebase.firebaseAuthReady()) {
21098
+ * // seguro leer Firestore
21099
+ * }
21100
+ * ```
21101
+ */
21102
+ this.firebaseAuthReady = this._firebaseAuthReady.asReadonly();
21075
21103
  // Inicializar observables que dependen de auth
21076
- this.user$ = authState(this.auth).pipe(map((user) => (user ? this.mapUser(user) : null)), distinctUntilChanged((a, b) => a?.uid === b?.uid));
21077
- this.isAuthenticated$ = this.user$.pipe(map((user) => !!user), distinctUntilChanged());
21104
+ this.user$ = authState(this.auth).pipe(map(user => (user ? this.mapUser(user) : null)), distinctUntilChanged((a, b) => a?.uid === b?.uid));
21105
+ this.isAuthenticated$ = this.user$.pipe(map(user => !!user), distinctUntilChanged());
21106
+ // Gate compartido: emite true en cuanto haya un firebase.User y completa.
21107
+ this.firebaseAuthReady$ = authState(this.auth).pipe(filter$1((user) => !!user), map(() => true), take$1(1));
21078
21108
  // Escuchar cambios en el estado de autenticación
21079
21109
  authState(this.auth).subscribe({
21080
- next: (user) => {
21110
+ next: user => {
21111
+ // Mantener `firebaseAuthReady` sincronizado con la sesión real:
21112
+ // true al haber User, false en signout. Permite que los gates
21113
+ // re-evalúen tras un logout/login dentro de la misma sesión de página.
21114
+ this._firebaseAuthReady.set(!!user);
21081
21115
  this.sessionState.next({
21082
21116
  user: user ? this.mapUser(user) : null,
21083
21117
  isAuthenticated: !!user,
@@ -21085,7 +21119,8 @@ class FirebaseService {
21085
21119
  error: null,
21086
21120
  });
21087
21121
  },
21088
- error: (error) => {
21122
+ error: error => {
21123
+ this._firebaseAuthReady.set(false);
21089
21124
  this.sessionState.next({
21090
21125
  user: null,
21091
21126
  isAuthenticated: false,
@@ -21095,6 +21130,19 @@ class FirebaseService {
21095
21130
  },
21096
21131
  });
21097
21132
  }
21133
+ /**
21134
+ * Resuelve en cuanto la sesión de Firebase Auth está lista para leer
21135
+ * Firestore. Si ya está lista, resuelve inmediatamente.
21136
+ *
21137
+ * Útil para gatear la primera suscripción a un listener de Firestore y así
21138
+ * cerrar la ventana de `permission-denied` en cold start.
21139
+ */
21140
+ whenFirebaseAuthReady() {
21141
+ if (this._firebaseAuthReady()) {
21142
+ return Promise.resolve(true);
21143
+ }
21144
+ return firstValueFrom(this.firebaseAuthReady$);
21145
+ }
21098
21146
  // ===========================================================================
21099
21147
  // AUTENTICACIÓN
21100
21148
  // ===========================================================================
@@ -21221,7 +21269,7 @@ class FirebaseService {
21221
21269
  */
21222
21270
  async hasRole(role) {
21223
21271
  const claims = await this.getClaims();
21224
- return claims['role'] === role || (Array.isArray(claims['roles']) && claims['roles'].includes(role));
21272
+ return (claims['role'] === role || (Array.isArray(claims['roles']) && claims['roles'].includes(role)));
21225
21273
  }
21226
21274
  // ===========================================================================
21227
21275
  // RBAC - PERMISOS Y ORGANIZACIONES
@@ -21395,8 +21443,8 @@ class FirebaseService {
21395
21443
  * @returns Usuario actual o null
21396
21444
  */
21397
21445
  waitForAuth() {
21398
- return new Promise((resolve) => {
21399
- const subscription = this.state$.subscribe((state) => {
21446
+ return new Promise(resolve => {
21447
+ const subscription = this.state$.subscribe(state => {
21400
21448
  if (!state.isLoading) {
21401
21449
  subscription.unsubscribe();
21402
21450
  resolve(state.user);
@@ -21414,7 +21462,9 @@ class FirebaseService {
21414
21462
  * Indica si los emuladores están habilitados.
21415
21463
  */
21416
21464
  isUsingEmulators() {
21417
- return !!(this.config.emulator?.firestore || this.config.emulator?.auth || this.config.emulator?.storage);
21465
+ return !!(this.config.emulator?.firestore ||
21466
+ this.config.emulator?.auth ||
21467
+ this.config.emulator?.storage);
21418
21468
  }
21419
21469
  // ===========================================================================
21420
21470
  // MÉTODOS PRIVADOS
@@ -23298,9 +23348,32 @@ class NotificationsService {
23298
23348
  this.collectionReady$ = new BehaviorSubject(null);
23299
23349
  // Inyección opcional - AuthService puede no estar configurado
23300
23350
  this.authService = null;
23351
+ // Inyección opcional - FirebaseService gatea los listeners hasta que la
23352
+ // sesión de Firebase Auth esté lista (cierra la ventana de permission-denied
23353
+ // en cold start de PWA).
23354
+ this.firebaseService = null;
23355
+ this.firebaseService = this.injector.get(FirebaseService, null);
23301
23356
  // Intentar obtener AuthService de forma lazy (puede no estar configurado)
23302
23357
  this.setupAutoInitialization();
23303
23358
  }
23359
+ /**
23360
+ * Gate de Firebase Auth: emite la colección lista SOLO cuando la sesión de
23361
+ * Firebase Auth está confirmada. Sin FirebaseService disponible, no gatea
23362
+ * (degrada al comportamiento previo). Espera a que `firebaseAuthReady$`
23363
+ * emita antes de propagar la colección — así el listener Firestore nunca se
23364
+ * adjunta antes de que `request.auth` esté disponible.
23365
+ */
23366
+ collectionWhenAuthReady$() {
23367
+ const fb = this.firebaseService;
23368
+ if (!fb) {
23369
+ return this.collectionReady$.asObservable();
23370
+ }
23371
+ return this.collectionReady$.pipe(switchMap(collection => {
23372
+ if (!collection)
23373
+ return of(null);
23374
+ return from(fb.whenFirebaseAuthReady()).pipe(map$1(() => collection));
23375
+ }));
23376
+ }
23304
23377
  /**
23305
23378
  * Configura auto-inicialización observando el estado de AuthService.
23306
23379
  * Se ejecuta en el contexto del injector para poder usar effect().
@@ -23374,10 +23447,15 @@ class NotificationsService {
23374
23447
  * Obtiene notificaciones ordenadas por fecha descendente (real-time).
23375
23448
  * Se actualiza automáticamente cuando cambian los datos.
23376
23449
  *
23450
+ * El listener Firestore NO se adjunta hasta que la sesión de Firebase Auth
23451
+ * esté confirmada (`FirebaseService.firebaseAuthReady`). Esto cierra la
23452
+ * ventana de `permission-denied` en cold start de PWA, donde el JWT del
23453
+ * backend puede estar listo antes que la sesión de Firebase Auth.
23454
+ *
23377
23455
  * @param limit - Máximo de notificaciones a cargar (default: 50)
23378
23456
  */
23379
23457
  getAll(limit = DEFAULT_LIMIT) {
23380
- return this.collectionReady$.pipe(switchMap(collection => {
23458
+ return this.collectionWhenAuthReady$().pipe(switchMap(collection => {
23381
23459
  if (!collection)
23382
23460
  return EMPTY;
23383
23461
  return collection.watchAll({
@@ -23417,9 +23495,12 @@ class NotificationsService {
23417
23495
  /**
23418
23496
  * Cuenta notificaciones no leídas usando server-side aggregation query.
23419
23497
  * No descarga documentos — eficiente para badges en UI.
23498
+ *
23499
+ * Gateado por `firebaseAuthReady` — la aggregation query no se ejecuta hasta
23500
+ * que la sesión de Firebase Auth esté lista.
23420
23501
  */
23421
23502
  getUnreadCount() {
23422
- return this.collectionReady$.pipe(switchMap(collection => {
23503
+ return this.collectionWhenAuthReady$().pipe(switchMap(collection => {
23423
23504
  if (!collection)
23424
23505
  return of(0);
23425
23506
  return from(collection.count({
@@ -37628,6 +37709,106 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
37628
37709
  * Cliente NUNCA escribe directo — todas las mutaciones via PUT /v2/auth/preferences.
37629
37710
  */
37630
37711
 
37712
+ /**
37713
+ * Refreshable Stream
37714
+ *
37715
+ * Helper estándar para vistas que consumen datos de Firestore. Soporta DOS
37716
+ * modos — el caller decide cuál vía la `factory`:
37717
+ *
37718
+ * - **one-shot** (recomendado por defecto): `() => from(svc.getAllOnce())`.
37719
+ * Carga una vez y completa. Más barato — sin listener vivo.
37720
+ * - **real-time**: `() => svc.getAll()`. Listener Firestore que auto-actualiza.
37721
+ * Solo donde importa (inbox de notificaciones, badges).
37722
+ *
37723
+ * En ambos modos la primera suscripción se gatea por `firebaseAuthReady`
37724
+ * (sesión de Firebase Auth lista) — así el listener/lectura nunca se adjunta
37725
+ * antes de que `request.auth` esté disponible en las reglas de Firestore, lo
37726
+ * que cierra la ventana de `permission-denied` en cold start de PWA.
37727
+ *
37728
+ * El `retry` con backoff corto es solo red de seguridad para reconexiones
37729
+ * transitorias (no para cubrir cold start — eso lo cubre el gate de auth).
37730
+ */
37731
+ /**
37732
+ * Crea un stream refrescable a partir de una factory de Observable.
37733
+ *
37734
+ * DEBE llamarse en un injection context (field initializer o constructor) —
37735
+ * usa `toSignal`/`toObservable`/`inject` internamente.
37736
+ *
37737
+ * @param factory - Función que produce el Observable a consumir. El caller
37738
+ * decide el modo: `() => from(svc.getAllOnce())` (one-shot) o
37739
+ * `() => svc.getAll()` (real-time).
37740
+ * @param options - Configuración opcional (fallback, retry, gate).
37741
+ *
37742
+ * @example
37743
+ * ```typescript
37744
+ * // one-shot (recomendado por defecto)
37745
+ * private readonly stream = createRefreshableStream(
37746
+ * () => from(this.svc.getAllOnce()),
37747
+ * );
37748
+ *
37749
+ * // real-time (inbox)
37750
+ * private readonly stream = createRefreshableStream(
37751
+ * () => this.notifs.getAll(50),
37752
+ * );
37753
+ *
37754
+ * readonly items = this.stream.data;
37755
+ * readonly loading = this.stream.loading;
37756
+ *
37757
+ * ionViewWillEnter() {
37758
+ * this.pageRefresh.register(() => this.stream.reload());
37759
+ * }
37760
+ * ```
37761
+ */
37762
+ function createRefreshableStream(factory, options) {
37763
+ const injector = options?.injector ?? inject(Injector);
37764
+ const fallback = (options?.fallback ?? null);
37765
+ const retryCount = options?.retryCount ?? 4;
37766
+ const retryBaseDelayMs = options?.retryBaseDelayMs ?? 500;
37767
+ const gateOnFirebaseAuth = options?.gateOnFirebaseAuth ?? true;
37768
+ // FirebaseService es opcional — sin él (apps sin Firebase) no se gatea.
37769
+ const firebase = gateOnFirebaseAuth ? injector.get(FirebaseService, null) : null;
37770
+ const _reload = signal(0);
37771
+ const _loading = signal(true);
37772
+ const _error = signal(false);
37773
+ // Gate compartido de Firebase Auth: el stream no abre la primera
37774
+ // suscripción hasta que la sesión de Firebase Auth esté confirmada.
37775
+ const authGate$ = firebase ? firebase.firebaseAuthReady$ : of(true);
37776
+ const data = toSignal(toObservable(_reload, { injector }).pipe(tap(() => {
37777
+ _loading.set(true);
37778
+ _error.set(false);
37779
+ }),
37780
+ // Esperar a Firebase Auth listo antes de cada (re)suscripción. Como
37781
+ // `firebaseAuthReady$` completa tras la primera emisión, las reloads
37782
+ // posteriores resuelven el gate de inmediato (auth ya está listo).
37783
+ switchMap(() => authGate$.pipe(switchMap(() => factory().pipe(tap(() => {
37784
+ _loading.set(false);
37785
+ _error.set(false);
37786
+ }),
37787
+ // Backoff corto exponencial acotado — solo red de seguridad para
37788
+ // reconexiones transitorias, NO para cubrir cold start.
37789
+ retry({
37790
+ count: retryCount,
37791
+ delay: (_err, attempt) => timer(Math.min(retryBaseDelayMs * 2 ** (attempt - 1), 4000)),
37792
+ }), catchError(() => {
37793
+ _loading.set(false);
37794
+ _error.set(true);
37795
+ return of(fallback);
37796
+ })))))), { initialValue: null, injector });
37797
+ return {
37798
+ data,
37799
+ loading: _loading.asReadonly(),
37800
+ error: _error.asReadonly(),
37801
+ reload: () => _reload.update(n => n + 1),
37802
+ };
37803
+ }
37804
+
37805
+ /**
37806
+ * Refreshable Stream
37807
+ *
37808
+ * Helper `createRefreshableStream` para vistas con datos Firestore.
37809
+ * Soporta modo one-shot y real-time, con gate de `firebaseAuthReady`.
37810
+ */
37811
+
37631
37812
  /**
37632
37813
  * Cross-Platform Version Helpers
37633
37814
  *
@@ -41469,6 +41650,158 @@ const DEFAULT_FEEDBACK_TYPE_OPTIONS = [
41469
41650
  */
41470
41651
  // Configuration
41471
41652
 
41653
+ /**
41654
+ * Token de inyección para la configuración de Donation/Support.
41655
+ */
41656
+ const VALTECH_DONATION_CONFIG = new InjectionToken('ValtechDonationConfig');
41657
+ /** Configuración por defecto — sin métodos habilitados. */
41658
+ const DEFAULT_DONATION_CONFIG = {
41659
+ methods: [],
41660
+ };
41661
+ /**
41662
+ * Provee el feature de aportes (Support) a la aplicación Angular.
41663
+ *
41664
+ * Cada app del factory declara qué métodos habilita. La vista de Support
41665
+ * (heredada o local) renderiza solo los métodos configurados.
41666
+ *
41667
+ * @example
41668
+ * ```typescript
41669
+ * // main.ts
41670
+ * provideValtechDonations({
41671
+ * appId: 'showcase',
41672
+ * methods: ['coffee', 'bank', 'ads'],
41673
+ * coffee: { provider: 'buymeacoffee', url: 'https://buymeacoffee.com/valtech' },
41674
+ * bank: {
41675
+ * accounts: [{
41676
+ * country: 'CL', bank: 'Banco X', accountType: 'Cuenta Corriente',
41677
+ * number: '000000000', taxId: '11.111.111-1', holder: 'Valtech SpA',
41678
+ * email: 'aportes@valtech.com', currency: 'CLP',
41679
+ * }],
41680
+ * },
41681
+ * ads: { provider: 'admob', rewardedUnitId: 'ca-app-pub-xxx' },
41682
+ * }),
41683
+ * ```
41684
+ */
41685
+ function provideValtechDonations(config) {
41686
+ const merged = {
41687
+ ...DEFAULT_DONATION_CONFIG,
41688
+ ...config,
41689
+ };
41690
+ return makeEnvironmentProviders([{ provide: VALTECH_DONATION_CONFIG, useValue: merged }]);
41691
+ }
41692
+
41693
+ /**
41694
+ * `DonationService`
41695
+ *
41696
+ * Servicio cross-app para el feature de aportes voluntarios (Support).
41697
+ * Patrón factory: cada app llama `provideValtechDonations(...)` y este
41698
+ * servicio expone solo los métodos habilitados.
41699
+ *
41700
+ * **Fase 0 (placeholder)** — abre links externos + expone datos de config.
41701
+ * Sin backend. Fases futuras: rewarded ads reales, webhook de café,
41702
+ * registro de intents para una página de transparencia.
41703
+ *
41704
+ * @example
41705
+ * ```typescript
41706
+ * private donations = inject(DonationService);
41707
+ *
41708
+ * methods = this.donations.enabledMethods(); // ['coffee', 'bank']
41709
+ * onCoffee() { this.donations.openCoffee(); }
41710
+ * accounts = this.donations.bankAccounts();
41711
+ * ```
41712
+ */
41713
+ class DonationService {
41714
+ constructor() {
41715
+ this.config = inject(VALTECH_DONATION_CONFIG, {
41716
+ optional: true,
41717
+ }) ?? { methods: [] };
41718
+ /** Último intent registrado — útil para tests / debugging / UI feedback. */
41719
+ this._lastIntent = signal(null);
41720
+ this.lastIntent = this._lastIntent.asReadonly();
41721
+ /** Métodos habilitados por la app, en orden de config. */
41722
+ this.enabledMethods = computed(() => this.config.methods ?? []);
41723
+ }
41724
+ /** `true` si el método está habilitado en la config de la app. */
41725
+ isEnabled(method) {
41726
+ return this.enabledMethods().includes(method);
41727
+ }
41728
+ /** Cuentas bancarias configuradas (vacío si `bank` no está habilitado). */
41729
+ bankAccounts() {
41730
+ if (!this.isEnabled('bank'))
41731
+ return [];
41732
+ return this.config.bank?.accounts ?? [];
41733
+ }
41734
+ /** Cuentas filtradas por país ISO — para apps multi-mercado. */
41735
+ bankAccountsByCountry(country) {
41736
+ return this.bankAccounts().filter(a => a.country.toUpperCase() === country.toUpperCase());
41737
+ }
41738
+ /**
41739
+ * Abre el checkout de "café" (Buy Me a Coffee / Ko-fi) en una pestaña nueva.
41740
+ * El proveedor es el merchant of record — Valtech no procesa el pago.
41741
+ */
41742
+ openCoffee() {
41743
+ if (!this.isEnabled('coffee')) {
41744
+ return { method: 'coffee', ok: false, reason: 'not-enabled' };
41745
+ }
41746
+ const url = this.config.coffee?.url;
41747
+ if (!url) {
41748
+ return { method: 'coffee', ok: false, reason: 'not-configured' };
41749
+ }
41750
+ this.recordIntent('coffee');
41751
+ window.open(url, '_blank', 'noopener,noreferrer');
41752
+ return { method: 'coffee', ok: true };
41753
+ }
41754
+ /**
41755
+ * Muestra un anuncio rewarded (opt-in). **Fase 0: no implementado** —
41756
+ * placeholder hasta integrar el plugin de ads (AdMob/AdSense) + la
41757
+ * categoría de consentimiento. Retorna `not-supported`.
41758
+ */
41759
+ async showRewardedAd() {
41760
+ if (!this.isEnabled('ads')) {
41761
+ return { method: 'ads', ok: false, reason: 'not-enabled' };
41762
+ }
41763
+ // TODO Fase 3 — integrar Capacitor AdMob (mobile) / AdSense (web)
41764
+ // + gate en una nueva categoría de consentimiento.
41765
+ return { method: 'ads', ok: false, reason: 'not-supported' };
41766
+ }
41767
+ /**
41768
+ * Registra la intención de aporte. **Fase 0: solo estado local.**
41769
+ * Fase 4 — POST a un endpoint para una página de transparencia.
41770
+ */
41771
+ recordIntent(method) {
41772
+ this._lastIntent.set(method);
41773
+ }
41774
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DonationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
41775
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DonationService, providedIn: 'root' }); }
41776
+ }
41777
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DonationService, decorators: [{
41778
+ type: Injectable,
41779
+ args: [{ providedIn: 'root' }]
41780
+ }] });
41781
+
41782
+ /**
41783
+ * Valtech Donation / Support Service
41784
+ *
41785
+ * Feature cross-app de aportes voluntarios. Patrón factory: cada app llama
41786
+ * `provideValtechDonations(...)` y habilita los métodos que quiera
41787
+ * (`ads` · `coffee` · `bank`).
41788
+ *
41789
+ * Importante (legal): el dinero recibido por una entidad con fines de lucro
41790
+ * es ingreso afecto a impuesto, NO una donación deducible. La UI debe usar
41791
+ * lenguaje de "aporte voluntario / apoyo", nunca "donación".
41792
+ *
41793
+ * @example
41794
+ * ```typescript
41795
+ * // main.ts
41796
+ * provideValtechDonations({
41797
+ * appId: 'showcase',
41798
+ * methods: ['coffee', 'bank'],
41799
+ * coffee: { provider: 'buymeacoffee', url: 'https://buymeacoffee.com/valtech' },
41800
+ * bank: { accounts: [ ... ] },
41801
+ * }),
41802
+ * ```
41803
+ */
41804
+
41472
41805
  /**
41473
41806
  * val-feedback-form
41474
41807
  *
@@ -44775,5 +45108,5 @@ function buildFooterLinks(links, t, resolver) {
44775
45108
  * Generated bundle index. Do not edit.
44776
45109
  */
44777
45110
 
44778
- export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_SPACING, AVATAR_UPLOAD_DEFAULTS, AccordionComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AppConfigService, ArticleBuilder, ArticleComponent, AuthBackgroundComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BaseDefault, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentTransformer, CookieBannerComponent, CountdownComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_CANCEL_BUTTON, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DataTableComponent, DateInputComponent, DateRangeInputComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DownloadService, EmailInputComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FabComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FormSkeletonComponent, FunHeaderComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGIN_DEFAULTS, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MenuComponent, MessagingService, MetaService, ModalService, MultiSelectSearchComponent, NavigationService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OrgSwitchService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PATTERN_MOTIFS, PATTERN_PALETTES, PLATFORM_CONFIGS, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProfileSkeletonComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RightsFooterComponent, RotatingTextComponent, SHAPE_KEYS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UpdateBannerComponent, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_DEFAULT_CONTENT, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_SOCIAL_LINKS, VERSION, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, blogPost, buildFooterLinks, buildPath, collections, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createTitleProps, docs, extractPathParams, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideValtechAds, provideValtechAppConfig, provideValtechAuth, provideValtechAuthInterceptor, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechPresets, provideValtechSkeleton, query, renderPatternSvgInner, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard, toArticle };
45111
+ export { ACTION_CARD_DEFAULTS, AD_SIZE_MAP, API_TABLE_COLUMN_LABELS, ARTICLE_SPACING, AVATAR_UPLOAD_DEFAULTS, AccordionComponent, ActionCardComponent, ActionHeaderComponent, ActionType, AdSlotComponent, AdsLoaderService, AdsService, AlertBoxComponent, AnalyticsErrorHandler, AnalyticsRouterTracker, AnalyticsService, AppConfigService, ArticleBuilder, ArticleComponent, AuthBackgroundComponent, AuthService, AuthStateService, AuthStorageService, AuthSyncService, AvatarComponent, AvatarUploadComponent, BOTTOM_NAV_DEFAULTS, BannerComponent, BaseDefault, BlogPostBuilder, BottomNavComponent, BoxComponent, BreadcrumbComponent, ButtonComponent, ButtonGroupComponent, CALLOUT_LABELS, CHEV_KEYS, COMMON_COUNTRY_CODES, COMMON_CURRENCIES, CURRENCY_INFO, CardComponent, CardSection, CardType, CardsCarouselComponent, CheckInputComponent, CheckboxRadioInputComponent, ChipGroupComponent, ClearDefault, ClearDefaultBlock, ClearDefaultFull, ClearDefaultRound, ClearDefaultRoundBlock, ClearDefaultRoundFull, CodeDisplayComponent, CommandDisplayComponent, CommentComponent, CommentInputComponent, CommentSectionComponent, CompanyFooterComponent, ComponentStates, ConfirmationDialogService, ContainerComponent, ContentLoaderComponent, ContentReactionComponent, ContentTransformer, CookieBannerComponent, CountdownComponent, CurrencyInputComponent, DEFAULT_ADS_CONFIG, DEFAULT_APP_CONFIG_SERVICE_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_BACK_HEADER, DEFAULT_CANCEL_BUTTON, DEFAULT_CONFIRM_BUTTON, DEFAULT_COUNTDOWN_LABELS, DEFAULT_COUNTDOWN_LABELS_EN, DEFAULT_DONATION_CONFIG, DEFAULT_EMPTY_STATE, DEFAULT_EMULATOR_CONFIG, DEFAULT_FEEDBACK_CONFIG, DEFAULT_FEEDBACK_TYPE_OPTIONS, DEFAULT_HOME_HEADER, DEFAULT_INFINITE_LIST_METADATA, DEFAULT_MODAL_CANCEL_BUTTON, DEFAULT_MODAL_CONFIRM_BUTTON, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLATFORMS, DEFAULT_REFRESHER_METADATA, DEFAULT_SKELETON_CONFIG, DataTableComponent, DateInputComponent, DateRangeInputComponent, DetailSkeletonComponent, DeviceService, DisplayComponent, DividerComponent, DocsApiTableComponent, DocsBreadcrumbComponent, DocsBuilder, DocsCalloutComponent, DocsCodeExampleComponent, DocsLayoutComponent, DocsNavLinksComponent, DocsNavigationService, DocsPageComponent, DocsSearchComponent, DocsSectionComponent, DocsShellComponent, DocsSidebarComponent, DocsTocComponent, DonationService, DownloadService, EmailInputComponent, ExpandableTextComponent, FEATURES_LIST_DEFAULTS, FabComponent, FeaturesListComponent, FeedbackFormComponent, FeedbackService, FileInputComponent, FirebaseService, FirestoreCollectionFactory, FirestoreService, FooterComponent, FooterLinksComponent, FormComponent, FormFooterComponent, FormSkeletonComponent, FunHeaderComponent, GlassComponent, GlowCardComponent, GlowComponent, GridSkeletonComponent, HANDOFF_ROUTE_PARAM, HANDOFF_TOKEN_PARAM, HandoffService, HeaderComponent, HintComponent, HorizontalScrollComponent, HourInputComponent, HrefComponent, I18nService, IMAGE_DEFAULTS, INITIAL_AUTH_STATE, INITIAL_MFA_STATE, Icon, IconComponent, IconService, ImageComponent, ImageCropComponent, ImageService, InAppBrowserService, InfiniteListComponent, InfoComponent, InputI18nHelper, InputType, ItemListComponent, LANG_STORAGE_KEY$1 as LANG_STORAGE_KEY, LEGAL_CONTENT_CONFIG, LOGIN_DEFAULTS, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LegalLinkService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MODAL_SIZES, MOTIF_KEYS, MOTION, MaintenancePageComponent, MarkdownArticleParserService, MenuComponent, MessagingService, MetaService, ModalService, MultiSelectSearchComponent, NavigationService, NewsBuilder, NoContentComponent, NotesBoxComponent, NotificationActionService, NotificationsService, NumberFromToComponent, NumberInputComponent, NumberStepperComponent, OAUTH_PROVIDERS_INFO, OAuthCallbackComponent, OAuthService, OrgSwitchService, OutlineDefault, OutlineDefaultBlock, OutlineDefaultFull, OutlineDefaultRound, OutlineDefaultRoundBlock, OutlineDefaultRoundFull, PATTERN_MOTIFS, PATTERN_PALETTES, PLATFORM_CONFIGS, PageContentComponent, PageLinksComponent, PageRefreshService, PageTemplateComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PatternComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, PreferencesService, PresetService, PriceTagComponent, PrimarySolidBlockButton, PrimarySolidBlockHrefButton, PrimarySolidBlockIconButton, PrimarySolidBlockIconHrefButton, PrimarySolidDefaultRoundButton, PrimarySolidDefaultRoundHrefButton, PrimarySolidDefaultRoundIconButton, PrimarySolidDefaultRoundIconHrefButton, PrimarySolidFullButton, PrimarySolidFullHrefButton, PrimarySolidFullIconButton, PrimarySolidFullIconHrefButton, PrimarySolidLargeRoundButton, PrimarySolidLargeRoundHrefButton, PrimarySolidLargeRoundIconButton, PrimarySolidLargeRoundIconHrefButton, PrimarySolidSmallRoundButton, PrimarySolidSmallRoundHrefButton, PrimarySolidSmallRoundIconButton, PrimarySolidSmallRoundIconHrefButton, ProcessLinksPipe, ProfileSkeletonComponent, ProgressBarComponent, ProgressRingComponent, ProgressStatusComponent, PrompterComponent, QR_PRESETS, QrCodeComponent, QrGeneratorService, QueryBuilder, QuoteBoxComponent, RadioInputComponent, RangeInputComponent, RatingComponent, RefresherComponent, RightsFooterComponent, RotatingTextComponent, SHAPE_KEYS, SKELETON_LAYOUT_DEFAULT_ROWS, SKELETON_PRESETS, SOLID_KEYS, SearchSelectorComponent, SearchbarComponent, SecondarySolidBlockButton, SecondarySolidBlockHrefButton, SecondarySolidBlockIconButton, SecondarySolidBlockIconHrefButton, SecondarySolidDefaultRoundButton, SecondarySolidDefaultRoundHrefButton, SecondarySolidDefaultRoundIconButton, SecondarySolidDefaultRoundIconHrefButton, SecondarySolidFullButton, SecondarySolidFullHrefButton, SecondarySolidFullIconButton, SecondarySolidFullIconHrefButton, SecondarySolidLargeRoundButton, SecondarySolidLargeRoundHrefButton, SecondarySolidLargeRoundIconButton, SecondarySolidLargeRoundIconHrefButton, SecondarySolidSmallRoundButton, SecondarySolidSmallRoundHrefButton, SecondarySolidSmallRoundIconButton, SecondarySolidSmallRoundIconHrefButton, SegmentControlComponent, SelectSearchComponent, SessionService, ShareButtonsComponent, SimpleComponent, SkeletonComponent, SkeletonLayoutComponent, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TRI_KEYS, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UpdateBannerComponent, UserAvatarComponent, UsernameInputComponent, VALTECH_ADS_CONFIG, VALTECH_APP_CONFIG, VALTECH_AUTH_CONFIG, VALTECH_COMPANY_LINKS, VALTECH_DEFAULT_CONTENT, VALTECH_DONATION_CONFIG, VALTECH_FEEDBACK_CONFIG, VALTECH_FIREBASE_CONFIG, VALTECH_FOOTER_I18N, VALTECH_FOOTER_LOGO, VALTECH_LANGUAGE_SELECTOR, VALTECH_LEGAL_CONFIG, VALTECH_SOCIAL_LINKS, VERSION, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, blogPost, buildFooterLinks, buildPath, collections, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createRefreshableStream, createTitleProps, docs, extractPathParams, generatePatternTiles, generateRandomTile, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, mulberry32, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideValtechAds, provideValtechAppConfig, provideValtechAuth, provideValtechAuthInterceptor, provideValtechDonations, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechLegal, provideValtechPresets, provideValtechSkeleton, query, renderPatternSvgInner, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard, toArticle };
44779
45112
  //# sourceMappingURL=valtech-components.mjs.map