valtech-components 2.0.728 → 2.0.730
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/esm2022/lib/components/organisms/bottom-nav/bottom-nav.component.mjs +36 -21
- package/esm2022/lib/components/organisms/bottom-nav/types.mjs +2 -1
- package/esm2022/lib/services/auth/handoff.service.mjs +1 -1
- package/esm2022/lib/services/auth/notification-action.service.mjs +10 -6
- package/esm2022/lib/services/markdown-article/legal-content.service.mjs +65 -14
- package/esm2022/lib/services/markdown-article/markdown-article-parser.mjs +266 -0
- package/esm2022/lib/services/markdown-article/markdown-article-parser.service.mjs +6 -275
- package/esm2022/lib/services/preferences/index.mjs +3 -0
- package/esm2022/lib/services/preferences/preferences.service.mjs +164 -0
- package/esm2022/lib/services/preferences/preferences.types.mjs +7 -0
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +7 -1
- package/fesm2022/valtech-components.mjs +495 -267
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/bottom-nav/bottom-nav.component.d.ts +3 -0
- package/lib/components/organisms/bottom-nav/types.d.ts +3 -1
- package/lib/services/auth/handoff.service.d.ts +10 -0
- package/lib/services/markdown-article/legal-content.service.d.ts +49 -7
- package/lib/services/markdown-article/markdown-article-parser.d.ts +16 -0
- package/lib/services/markdown-article/markdown-article-parser.service.d.ts +3 -22
- package/lib/services/preferences/index.d.ts +2 -0
- package/lib/services/preferences/preferences.service.d.ts +51 -0
- package/lib/services/preferences/preferences.types.d.ts +35 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
|
@@ -50,7 +50,7 @@ import 'prismjs/components/prism-json';
|
|
|
50
50
|
* Current version of valtech-components.
|
|
51
51
|
* This is automatically updated during the publish process.
|
|
52
52
|
*/
|
|
53
|
-
const VERSION = '2.0.
|
|
53
|
+
const VERSION = '2.0.730';
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Servicio para gestionar presets de componentes.
|
|
@@ -31164,14 +31164,18 @@ class NotificationActionService {
|
|
|
31164
31164
|
const currentApp = this.config.appId;
|
|
31165
31165
|
const targetApp = notif.appId;
|
|
31166
31166
|
// 2) Cross-app: handoff + full redirect
|
|
31167
|
+
//
|
|
31168
|
+
// baseUrl resolution priority:
|
|
31169
|
+
// (1) response.targetBaseUrl — backend lookup en app-config (preferred, single source of truth)
|
|
31170
|
+
// (2) config.appUrls[targetApp] — fallback frontend mientras backend agrega el campo
|
|
31167
31171
|
if (targetApp && currentApp && targetApp !== currentApp) {
|
|
31168
|
-
const baseUrl = this.config.appUrls?.[targetApp];
|
|
31169
|
-
if (!baseUrl) {
|
|
31170
|
-
console.warn(`[NotificationAction] Missing appUrls['${targetApp}'] — configure ValtechAuthConfig.appUrls`);
|
|
31171
|
-
return 'cross-app-unconfigured';
|
|
31172
|
-
}
|
|
31173
31172
|
try {
|
|
31174
31173
|
const resp = await firstValueFrom(this.handoff.createHandoff({ targetAppId: targetApp, route }));
|
|
31174
|
+
const baseUrl = resp.targetBaseUrl ?? this.config.appUrls?.[targetApp];
|
|
31175
|
+
if (!baseUrl) {
|
|
31176
|
+
console.warn(`[NotificationAction] No baseUrl for app '${targetApp}' — backend did not return targetBaseUrl and no appUrls fallback configured`);
|
|
31177
|
+
return 'cross-app-unconfigured';
|
|
31178
|
+
}
|
|
31175
31179
|
const url = this.buildHandoffUrl(baseUrl, resp.token, route);
|
|
31176
31180
|
if (typeof window !== 'undefined') {
|
|
31177
31181
|
window.location.href = url;
|
|
@@ -32468,6 +32472,7 @@ const BOTTOM_NAV_DEFAULTS = {
|
|
|
32468
32472
|
hideLabels: false,
|
|
32469
32473
|
safeArea: true,
|
|
32470
32474
|
animation: 'scale',
|
|
32475
|
+
maxWidth: 'xl',
|
|
32471
32476
|
theme: {
|
|
32472
32477
|
background: 'var(--ion-background-color)',
|
|
32473
32478
|
activeColor: 'primary',
|
|
@@ -32594,7 +32599,7 @@ class BottomNavComponent {
|
|
|
32594
32599
|
return true;
|
|
32595
32600
|
// Check additional active routes
|
|
32596
32601
|
if (tab.activeRoutes) {
|
|
32597
|
-
return tab.activeRoutes.some(
|
|
32602
|
+
return tab.activeRoutes.some(r => route.startsWith(r));
|
|
32598
32603
|
}
|
|
32599
32604
|
return false;
|
|
32600
32605
|
}
|
|
@@ -32624,15 +32629,36 @@ class BottomNavComponent {
|
|
|
32624
32629
|
'--bottom-nav-active': this.resolveColor(theme.activeColor),
|
|
32625
32630
|
'--bottom-nav-inactive': this.resolveColor(theme.inactiveColor),
|
|
32626
32631
|
'--bottom-nav-radius': theme.borderRadius || '',
|
|
32632
|
+
'--bottom-nav-max-width': this.resolveMaxWidth(this.config().maxWidth),
|
|
32627
32633
|
};
|
|
32628
32634
|
}
|
|
32635
|
+
/** Resolve maxWidth token (sm|md|lg|xl|full) to CSS var or raw value */
|
|
32636
|
+
resolveMaxWidth(v) {
|
|
32637
|
+
switch (v) {
|
|
32638
|
+
case 'sm':
|
|
32639
|
+
return 'var(--val-container-sm, 540px)';
|
|
32640
|
+
case 'md':
|
|
32641
|
+
return 'var(--val-container-md, 720px)';
|
|
32642
|
+
case 'lg':
|
|
32643
|
+
return 'var(--val-container-lg, 880px)';
|
|
32644
|
+
case 'xl':
|
|
32645
|
+
return 'var(--val-container-xl, 1100px)';
|
|
32646
|
+
case 'full':
|
|
32647
|
+
return 'none';
|
|
32648
|
+
case undefined:
|
|
32649
|
+
case '':
|
|
32650
|
+
return 'var(--val-container-xl, 1100px)';
|
|
32651
|
+
default:
|
|
32652
|
+
return v;
|
|
32653
|
+
}
|
|
32654
|
+
}
|
|
32629
32655
|
ngOnInit() {
|
|
32630
32656
|
// Set initial route
|
|
32631
32657
|
this.currentRoute.set(this.router.url);
|
|
32632
32658
|
// Subscribe to route changes
|
|
32633
32659
|
this.routerSubscription = this.router.events
|
|
32634
|
-
.pipe(filter$1(
|
|
32635
|
-
.subscribe(
|
|
32660
|
+
.pipe(filter$1(event => event instanceof NavigationEnd))
|
|
32661
|
+
.subscribe(event => {
|
|
32636
32662
|
this.currentRoute.set(event.urlAfterRedirects);
|
|
32637
32663
|
});
|
|
32638
32664
|
}
|
|
@@ -32670,17 +32696,7 @@ class BottomNavComponent {
|
|
|
32670
32696
|
resolveColor(color) {
|
|
32671
32697
|
if (!color)
|
|
32672
32698
|
return '';
|
|
32673
|
-
const ionicColors = [
|
|
32674
|
-
'primary',
|
|
32675
|
-
'secondary',
|
|
32676
|
-
'tertiary',
|
|
32677
|
-
'success',
|
|
32678
|
-
'warning',
|
|
32679
|
-
'danger',
|
|
32680
|
-
'light',
|
|
32681
|
-
'medium',
|
|
32682
|
-
'dark',
|
|
32683
|
-
];
|
|
32699
|
+
const ionicColors = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
|
|
32684
32700
|
if (ionicColors.includes(color)) {
|
|
32685
32701
|
return `var(--ion-color-${color})`;
|
|
32686
32702
|
}
|
|
@@ -32738,7 +32754,9 @@ class BottomNavComponent {
|
|
|
32738
32754
|
class="bottom-nav__badge"
|
|
32739
32755
|
[class.bottom-nav__badge--dot]="item.badge.dot"
|
|
32740
32756
|
[style.color]="item.badge.color ? resolveColor(item.badge.color) : null"
|
|
32741
|
-
[style.background-color]="
|
|
32757
|
+
[style.background-color]="
|
|
32758
|
+
item.badge.backgroundColor ? resolveColor(item.badge.backgroundColor) : null
|
|
32759
|
+
"
|
|
32742
32760
|
>
|
|
32743
32761
|
@if (!item.badge.dot && item.badge.text) {
|
|
32744
32762
|
{{ item.badge.text }}
|
|
@@ -32755,7 +32773,7 @@ class BottomNavComponent {
|
|
|
32755
32773
|
}
|
|
32756
32774
|
</div>
|
|
32757
32775
|
</nav>
|
|
32758
|
-
`, isInline: true, styles: [":host{display:block;position:fixed;bottom:0;left:0;right:0;z-index:100;pointer-events:none}.bottom-nav{--bottom-nav-bg: var(--ion-background-color);--bottom-nav-active: var(--ion-color-primary);--bottom-nav-inactive: var(--ion-color-medium);--bottom-nav-radius: 16px 16px 0 0;--bottom-nav-height: 64px;--bottom-nav-fab-size: 56px;--fab-color: var(--ion-color-primary);pointer-events:auto;background:var(--bottom-nav-bg);border-radius:var(--bottom-nav-radius);height:var(--bottom-nav-height);padding:0 8px}.bottom-nav--elevated{box-shadow:0 -4px 20px #00000014}.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 255, 255, 255),.75);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border-top:1px solid rgba(var(--ion-text-color-rgb, 0, 0, 0),.06)}.bottom-nav--floating{margin:0
|
|
32776
|
+
`, isInline: true, styles: [":host{display:block;position:fixed;bottom:0;left:0;right:0;z-index:100;pointer-events:none}.bottom-nav{--bottom-nav-bg: var(--ion-background-color);--bottom-nav-active: var(--ion-color-primary);--bottom-nav-inactive: var(--ion-color-medium);--bottom-nav-radius: 16px 16px 0 0;--bottom-nav-height: 64px;--bottom-nav-fab-size: 56px;--bottom-nav-max-width: var(--val-container-xl, 1100px);--fab-color: var(--ion-color-primary);pointer-events:auto;background:var(--bottom-nav-bg);border-radius:var(--bottom-nav-radius);height:var(--bottom-nav-height);padding:0 8px;max-width:var(--bottom-nav-max-width);margin:0 auto}.bottom-nav--elevated{box-shadow:0 -4px 20px #00000014}.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 255, 255, 255),.75);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border-top:1px solid rgba(var(--ion-text-color-rgb, 0, 0, 0),.06)}.bottom-nav--floating{margin:0 auto 8px;width:calc(100% - 32px);border-radius:32px;border:1px solid rgba(var(--ion-text-color-rgb, 0, 0, 0),.08);box-shadow:0 4px 24px #00000014,0 8px 32px #0000000a;--bottom-nav-radius: 32px}.bottom-nav--floating.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 255, 255, 255),.82);backdrop-filter:blur(28px) saturate(200%);-webkit-backdrop-filter:blur(28px) saturate(200%);border:1px solid rgba(var(--ion-text-color-rgb, 0, 0, 0),.08)}.bottom-nav--floating.bottom-nav--elevated{box-shadow:0 4px 24px #0000001a,0 12px 48px #00000014}.bottom-nav--floating.bottom-nav--safe-area{margin-bottom:calc(8px + env(safe-area-inset-bottom,0))}.bottom-nav--safe-area{padding-bottom:env(safe-area-inset-bottom,0);height:calc(var(--bottom-nav-height) + env(safe-area-inset-bottom,0))}.bottom-nav__container{display:flex;align-items:center;justify-content:space-around;height:var(--bottom-nav-height);max-width:500px;margin:0 auto}.bottom-nav__tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;height:100%;padding:8px 4px;background:transparent;border:none;cursor:pointer;position:relative;overflow:hidden;color:var(--bottom-nav-inactive);transition:color .2s ease;max-width:80px;--ripple-color: var(--bottom-nav-active)}.bottom-nav__tab:focus-visible{outline:2px solid var(--bottom-nav-active);outline-offset:-2px;border-radius:8px}.bottom-nav__tab--active{color:var(--bottom-nav-active)}.bottom-nav__tab--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.bottom-nav__tab[data-animation=scale] .bottom-nav__tab-icon{transition:transform .2s cubic-bezier(.4,0,.2,1)}.bottom-nav__tab[data-animation=scale].bottom-nav__tab--active .bottom-nav__tab-icon{transform:scale(1.15)}.bottom-nav__tab[data-animation=fade]{transition:opacity .2s ease,color .2s ease}.bottom-nav__tab[data-animation=fade]:not(.bottom-nav__tab--active){opacity:.6}.bottom-nav__tab[data-animation=slide] .bottom-nav__tab-label{transition:transform .2s ease,opacity .2s ease;transform:translateY(6px);opacity:0}.bottom-nav__tab[data-animation=slide].bottom-nav__tab--active .bottom-nav__tab-label{transform:translateY(0);opacity:1}.bottom-nav__tab-icon{position:relative;font-size:24px;line-height:1}.bottom-nav__tab-icon ion-icon{display:block}.bottom-nav__tab-label{font-size:11px;font-weight:500;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;letter-spacing:.01em}.bottom-nav__badge{position:absolute;top:-4px;right:-10px;min-width:18px;height:18px;padding:0 5px;font-size:10px;font-weight:600;line-height:18px;text-align:center;color:#fff;background-color:var(--ion-color-danger);border-radius:9px;box-shadow:0 1px 3px #0003}.bottom-nav__badge--dot{min-width:10px;width:10px;height:10px;padding:0;top:-2px;right:-4px;border-radius:50%}.bottom-nav__fab{position:relative;flex-shrink:0;width:var(--bottom-nav-fab-size);height:var(--bottom-nav-fab-size);margin:0 12px;margin-top:calc(var(--bottom-nav-fab-size) * -.35);background:var(--fab-color);border:none;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#fff;font-size:28px;box-shadow:0 4px 14px rgba(var(--ion-color-primary-rgb, 56, 128, 255),.4);transition:transform .2s cubic-bezier(.4,0,.2,1),box-shadow .2s ease;overflow:hidden;--ripple-color: rgba(255, 255, 255, .3)}.bottom-nav__fab:hover{transform:scale(1.08);box-shadow:0 6px 20px rgba(var(--ion-color-primary-rgb, 56, 128, 255),.5)}.bottom-nav__fab:active{transform:scale(.95)}.bottom-nav__fab:focus-visible{outline:3px solid white;outline-offset:2px}.bottom-nav__fab--small{--bottom-nav-fab-size: 48px;font-size:24px;margin-top:-14.4px}.bottom-nav__fab ion-icon{display:block}.bottom-nav--hide-labels{--bottom-nav-height: 56px}.bottom-nav--hide-labels .bottom-nav__tab-label{display:none}.bottom-nav--hide-labels .bottom-nav__tab-icon{font-size:26px}@media (prefers-color-scheme: dark){.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 0, 0, 0),.8);border-top-color:#ffffff14}.bottom-nav--elevated{box-shadow:0 -4px 20px #00000040}.bottom-nav--floating{border-color:#ffffff1a;box-shadow:0 4px 24px #0003,0 8px 32px #00000026}.bottom-nav--floating.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 18, 18, 18),.88);border-color:#ffffff1a}.bottom-nav__fab{box-shadow:0 4px 14px #0006}.bottom-nav__fab:hover{box-shadow:0 6px 20px #00000080}}:host-context(.dark) .bottom-nav--translucent,:host-context(body.dark) .bottom-nav--translucent,:host-context([data-theme=dark]) .bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 18, 18, 18),.85);border-top-color:#ffffff14}:host-context(.dark) .bottom-nav--elevated,:host-context(body.dark) .bottom-nav--elevated,:host-context([data-theme=dark]) .bottom-nav--elevated{box-shadow:0 -4px 20px #0000004d}:host-context(.dark) .bottom-nav--floating,:host-context(body.dark) .bottom-nav--floating,:host-context([data-theme=dark]) .bottom-nav--floating{border-color:#ffffff1a;box-shadow:0 4px 24px #0003,0 8px 32px #00000026}:host-context(.dark) .bottom-nav--floating.bottom-nav--translucent,:host-context(body.dark) .bottom-nav--floating.bottom-nav--translucent,:host-context([data-theme=dark]) .bottom-nav--floating.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 18, 18, 18),.88);border-color:#ffffff1a}:host-context(.dark) .bottom-nav__fab,:host-context(body.dark) .bottom-nav__fab,:host-context([data-theme=dark]) .bottom-nav__fab{box-shadow:0 4px 14px #00000080}:host-context(.dark) .bottom-nav__fab:hover,:host-context(body.dark) .bottom-nav__fab:hover,:host-context([data-theme=dark]) .bottom-nav__fab:hover{box-shadow:0 6px 20px #0009}@supports (padding-bottom: env(safe-area-inset-bottom)){.bottom-nav--safe-area .bottom-nav__container{height:var(--bottom-nav-height)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonRippleEffect, selector: "ion-ripple-effect", inputs: ["type"] }] }); }
|
|
32759
32777
|
}
|
|
32760
32778
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BottomNavComponent, decorators: [{
|
|
32761
32779
|
type: Component,
|
|
@@ -32810,7 +32828,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
32810
32828
|
class="bottom-nav__badge"
|
|
32811
32829
|
[class.bottom-nav__badge--dot]="item.badge.dot"
|
|
32812
32830
|
[style.color]="item.badge.color ? resolveColor(item.badge.color) : null"
|
|
32813
|
-
[style.background-color]="
|
|
32831
|
+
[style.background-color]="
|
|
32832
|
+
item.badge.backgroundColor ? resolveColor(item.badge.backgroundColor) : null
|
|
32833
|
+
"
|
|
32814
32834
|
>
|
|
32815
32835
|
@if (!item.badge.dot && item.badge.text) {
|
|
32816
32836
|
{{ item.badge.text }}
|
|
@@ -32827,7 +32847,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
32827
32847
|
}
|
|
32828
32848
|
</div>
|
|
32829
32849
|
</nav>
|
|
32830
|
-
`, styles: [":host{display:block;position:fixed;bottom:0;left:0;right:0;z-index:100;pointer-events:none}.bottom-nav{--bottom-nav-bg: var(--ion-background-color);--bottom-nav-active: var(--ion-color-primary);--bottom-nav-inactive: var(--ion-color-medium);--bottom-nav-radius: 16px 16px 0 0;--bottom-nav-height: 64px;--bottom-nav-fab-size: 56px;--fab-color: var(--ion-color-primary);pointer-events:auto;background:var(--bottom-nav-bg);border-radius:var(--bottom-nav-radius);height:var(--bottom-nav-height);padding:0 8px}.bottom-nav--elevated{box-shadow:0 -4px 20px #00000014}.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 255, 255, 255),.75);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border-top:1px solid rgba(var(--ion-text-color-rgb, 0, 0, 0),.06)}.bottom-nav--floating{margin:0
|
|
32850
|
+
`, styles: [":host{display:block;position:fixed;bottom:0;left:0;right:0;z-index:100;pointer-events:none}.bottom-nav{--bottom-nav-bg: var(--ion-background-color);--bottom-nav-active: var(--ion-color-primary);--bottom-nav-inactive: var(--ion-color-medium);--bottom-nav-radius: 16px 16px 0 0;--bottom-nav-height: 64px;--bottom-nav-fab-size: 56px;--bottom-nav-max-width: var(--val-container-xl, 1100px);--fab-color: var(--ion-color-primary);pointer-events:auto;background:var(--bottom-nav-bg);border-radius:var(--bottom-nav-radius);height:var(--bottom-nav-height);padding:0 8px;max-width:var(--bottom-nav-max-width);margin:0 auto}.bottom-nav--elevated{box-shadow:0 -4px 20px #00000014}.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 255, 255, 255),.75);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);border-top:1px solid rgba(var(--ion-text-color-rgb, 0, 0, 0),.06)}.bottom-nav--floating{margin:0 auto 8px;width:calc(100% - 32px);border-radius:32px;border:1px solid rgba(var(--ion-text-color-rgb, 0, 0, 0),.08);box-shadow:0 4px 24px #00000014,0 8px 32px #0000000a;--bottom-nav-radius: 32px}.bottom-nav--floating.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 255, 255, 255),.82);backdrop-filter:blur(28px) saturate(200%);-webkit-backdrop-filter:blur(28px) saturate(200%);border:1px solid rgba(var(--ion-text-color-rgb, 0, 0, 0),.08)}.bottom-nav--floating.bottom-nav--elevated{box-shadow:0 4px 24px #0000001a,0 12px 48px #00000014}.bottom-nav--floating.bottom-nav--safe-area{margin-bottom:calc(8px + env(safe-area-inset-bottom,0))}.bottom-nav--safe-area{padding-bottom:env(safe-area-inset-bottom,0);height:calc(var(--bottom-nav-height) + env(safe-area-inset-bottom,0))}.bottom-nav__container{display:flex;align-items:center;justify-content:space-around;height:var(--bottom-nav-height);max-width:500px;margin:0 auto}.bottom-nav__tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;height:100%;padding:8px 4px;background:transparent;border:none;cursor:pointer;position:relative;overflow:hidden;color:var(--bottom-nav-inactive);transition:color .2s ease;max-width:80px;--ripple-color: var(--bottom-nav-active)}.bottom-nav__tab:focus-visible{outline:2px solid var(--bottom-nav-active);outline-offset:-2px;border-radius:8px}.bottom-nav__tab--active{color:var(--bottom-nav-active)}.bottom-nav__tab--disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.bottom-nav__tab[data-animation=scale] .bottom-nav__tab-icon{transition:transform .2s cubic-bezier(.4,0,.2,1)}.bottom-nav__tab[data-animation=scale].bottom-nav__tab--active .bottom-nav__tab-icon{transform:scale(1.15)}.bottom-nav__tab[data-animation=fade]{transition:opacity .2s ease,color .2s ease}.bottom-nav__tab[data-animation=fade]:not(.bottom-nav__tab--active){opacity:.6}.bottom-nav__tab[data-animation=slide] .bottom-nav__tab-label{transition:transform .2s ease,opacity .2s ease;transform:translateY(6px);opacity:0}.bottom-nav__tab[data-animation=slide].bottom-nav__tab--active .bottom-nav__tab-label{transform:translateY(0);opacity:1}.bottom-nav__tab-icon{position:relative;font-size:24px;line-height:1}.bottom-nav__tab-icon ion-icon{display:block}.bottom-nav__tab-label{font-size:11px;font-weight:500;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;letter-spacing:.01em}.bottom-nav__badge{position:absolute;top:-4px;right:-10px;min-width:18px;height:18px;padding:0 5px;font-size:10px;font-weight:600;line-height:18px;text-align:center;color:#fff;background-color:var(--ion-color-danger);border-radius:9px;box-shadow:0 1px 3px #0003}.bottom-nav__badge--dot{min-width:10px;width:10px;height:10px;padding:0;top:-2px;right:-4px;border-radius:50%}.bottom-nav__fab{position:relative;flex-shrink:0;width:var(--bottom-nav-fab-size);height:var(--bottom-nav-fab-size);margin:0 12px;margin-top:calc(var(--bottom-nav-fab-size) * -.35);background:var(--fab-color);border:none;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#fff;font-size:28px;box-shadow:0 4px 14px rgba(var(--ion-color-primary-rgb, 56, 128, 255),.4);transition:transform .2s cubic-bezier(.4,0,.2,1),box-shadow .2s ease;overflow:hidden;--ripple-color: rgba(255, 255, 255, .3)}.bottom-nav__fab:hover{transform:scale(1.08);box-shadow:0 6px 20px rgba(var(--ion-color-primary-rgb, 56, 128, 255),.5)}.bottom-nav__fab:active{transform:scale(.95)}.bottom-nav__fab:focus-visible{outline:3px solid white;outline-offset:2px}.bottom-nav__fab--small{--bottom-nav-fab-size: 48px;font-size:24px;margin-top:-14.4px}.bottom-nav__fab ion-icon{display:block}.bottom-nav--hide-labels{--bottom-nav-height: 56px}.bottom-nav--hide-labels .bottom-nav__tab-label{display:none}.bottom-nav--hide-labels .bottom-nav__tab-icon{font-size:26px}@media (prefers-color-scheme: dark){.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 0, 0, 0),.8);border-top-color:#ffffff14}.bottom-nav--elevated{box-shadow:0 -4px 20px #00000040}.bottom-nav--floating{border-color:#ffffff1a;box-shadow:0 4px 24px #0003,0 8px 32px #00000026}.bottom-nav--floating.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 18, 18, 18),.88);border-color:#ffffff1a}.bottom-nav__fab{box-shadow:0 4px 14px #0006}.bottom-nav__fab:hover{box-shadow:0 6px 20px #00000080}}:host-context(.dark) .bottom-nav--translucent,:host-context(body.dark) .bottom-nav--translucent,:host-context([data-theme=dark]) .bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 18, 18, 18),.85);border-top-color:#ffffff14}:host-context(.dark) .bottom-nav--elevated,:host-context(body.dark) .bottom-nav--elevated,:host-context([data-theme=dark]) .bottom-nav--elevated{box-shadow:0 -4px 20px #0000004d}:host-context(.dark) .bottom-nav--floating,:host-context(body.dark) .bottom-nav--floating,:host-context([data-theme=dark]) .bottom-nav--floating{border-color:#ffffff1a;box-shadow:0 4px 24px #0003,0 8px 32px #00000026}:host-context(.dark) .bottom-nav--floating.bottom-nav--translucent,:host-context(body.dark) .bottom-nav--floating.bottom-nav--translucent,:host-context([data-theme=dark]) .bottom-nav--floating.bottom-nav--translucent{background:rgba(var(--ion-background-color-rgb, 18, 18, 18),.88);border-color:#ffffff1a}:host-context(.dark) .bottom-nav__fab,:host-context(body.dark) .bottom-nav__fab,:host-context([data-theme=dark]) .bottom-nav__fab{box-shadow:0 4px 14px #00000080}:host-context(.dark) .bottom-nav__fab:hover,:host-context(body.dark) .bottom-nav__fab:hover,:host-context([data-theme=dark]) .bottom-nav__fab:hover{box-shadow:0 6px 20px #0009}@supports (padding-bottom: env(safe-area-inset-bottom)){.bottom-nav--safe-area .bottom-nav__container{height:var(--bottom-nav-height)}}\n"] }]
|
|
32831
32851
|
}], propDecorators: { tabClick: [{
|
|
32832
32852
|
type: Output
|
|
32833
32853
|
}], fabClick: [{
|
|
@@ -34933,7 +34953,8 @@ const ORDERED_RE = /^\s*\d+\.\s+(.+)$/;
|
|
|
34933
34953
|
const TABLE_DIVIDER_RE = /^\s*\|?[\s:|-]+\|?\s*$/;
|
|
34934
34954
|
const TABLE_ROW_RE = /^\s*\|(.+)\|\s*$/;
|
|
34935
34955
|
/**
|
|
34936
|
-
*
|
|
34956
|
+
* Pure Markdown → ArticleMetadata parser. No Angular deps — usable from Node scripts
|
|
34957
|
+
* (build-time generation) and from the Angular `MarkdownArticleParserService` wrapper.
|
|
34937
34958
|
*
|
|
34938
34959
|
* Supported syntax:
|
|
34939
34960
|
* - Headings (#, ##, ### …) → title / subtitle
|
|
@@ -34945,261 +34966,256 @@ const TABLE_ROW_RE = /^\s*\|(.+)\|\s*$/;
|
|
|
34945
34966
|
* - Tables → flattened into paragraphs with bold keys
|
|
34946
34967
|
* - Horizontal rules (---, ***, ___) → separator
|
|
34947
34968
|
*/
|
|
34948
|
-
|
|
34949
|
-
|
|
34950
|
-
|
|
34951
|
-
|
|
34952
|
-
|
|
34953
|
-
|
|
34954
|
-
|
|
34955
|
-
|
|
34969
|
+
function parseMarkdownArticle(markdown, config) {
|
|
34970
|
+
const lines = normalize(markdown).split('\n');
|
|
34971
|
+
const elements = [];
|
|
34972
|
+
let i = 0;
|
|
34973
|
+
while (i < lines.length) {
|
|
34974
|
+
const line = lines[i];
|
|
34975
|
+
if (line.trim() === '') {
|
|
34976
|
+
i++;
|
|
34977
|
+
continue;
|
|
34978
|
+
}
|
|
34979
|
+
const fence = line.match(FENCE_RE);
|
|
34980
|
+
if (fence) {
|
|
34981
|
+
const lang = fence[1] || undefined;
|
|
34982
|
+
const body = [];
|
|
34983
|
+
i++;
|
|
34984
|
+
while (i < lines.length && !FENCE_RE.test(lines[i])) {
|
|
34985
|
+
body.push(lines[i]);
|
|
34956
34986
|
i++;
|
|
34957
|
-
continue;
|
|
34958
34987
|
}
|
|
34959
|
-
|
|
34960
|
-
|
|
34961
|
-
|
|
34962
|
-
|
|
34963
|
-
|
|
34988
|
+
i++;
|
|
34989
|
+
elements.push({
|
|
34990
|
+
type: 'code',
|
|
34991
|
+
props: { code: body.join('\n'), language: lang, theme: 'dark' },
|
|
34992
|
+
});
|
|
34993
|
+
continue;
|
|
34994
|
+
}
|
|
34995
|
+
if (BOX_DRAWING.test(line)) {
|
|
34996
|
+
const body = [];
|
|
34997
|
+
while (i < lines.length && (lines[i].trim() === '' || BOX_DRAWING.test(lines[i]))) {
|
|
34998
|
+
body.push(lines[i]);
|
|
34964
34999
|
i++;
|
|
34965
|
-
while (i < lines.length && !FENCE_RE.test(lines[i])) {
|
|
34966
|
-
body.push(lines[i]);
|
|
34967
|
-
i++;
|
|
34968
|
-
}
|
|
34969
|
-
i++; // skip closing fence
|
|
34970
|
-
elements.push({
|
|
34971
|
-
type: 'code',
|
|
34972
|
-
props: { code: body.join('\n'), language: lang, theme: 'dark' },
|
|
34973
|
-
});
|
|
34974
|
-
continue;
|
|
34975
35000
|
}
|
|
34976
|
-
|
|
34977
|
-
|
|
34978
|
-
|
|
34979
|
-
|
|
34980
|
-
|
|
34981
|
-
|
|
34982
|
-
|
|
34983
|
-
|
|
34984
|
-
|
|
34985
|
-
|
|
34986
|
-
|
|
34987
|
-
|
|
34988
|
-
|
|
34989
|
-
|
|
34990
|
-
|
|
34991
|
-
|
|
34992
|
-
|
|
34993
|
-
|
|
34994
|
-
|
|
35001
|
+
while (body.length && body[body.length - 1].trim() === '')
|
|
35002
|
+
body.pop();
|
|
35003
|
+
elements.push({
|
|
35004
|
+
type: 'code',
|
|
35005
|
+
props: { code: body.join('\n'), language: 'text', theme: 'dark' },
|
|
35006
|
+
});
|
|
35007
|
+
continue;
|
|
35008
|
+
}
|
|
35009
|
+
if (SEPARATOR_RE.test(line)) {
|
|
35010
|
+
elements.push({ type: 'separator', props: { style: 'line' } });
|
|
35011
|
+
i++;
|
|
35012
|
+
continue;
|
|
35013
|
+
}
|
|
35014
|
+
const heading = line.match(HEADING_RE);
|
|
35015
|
+
if (heading) {
|
|
35016
|
+
elements.push(makeHeading(heading[1].length, heading[2].trim()));
|
|
35017
|
+
i++;
|
|
35018
|
+
continue;
|
|
35019
|
+
}
|
|
35020
|
+
if (line.startsWith('>')) {
|
|
35021
|
+
const block = [];
|
|
35022
|
+
while (i < lines.length && lines[i].startsWith('>')) {
|
|
35023
|
+
block.push(lines[i]);
|
|
34995
35024
|
i++;
|
|
34996
|
-
continue;
|
|
34997
35025
|
}
|
|
34998
|
-
|
|
34999
|
-
|
|
35000
|
-
|
|
35001
|
-
|
|
35026
|
+
elements.push(makeQuoteOrCallout(block));
|
|
35027
|
+
continue;
|
|
35028
|
+
}
|
|
35029
|
+
if (TABLE_ROW_RE.test(line)) {
|
|
35030
|
+
const rows = [];
|
|
35031
|
+
while (i < lines.length && TABLE_ROW_RE.test(lines[i])) {
|
|
35032
|
+
rows.push(lines[i]);
|
|
35002
35033
|
i++;
|
|
35003
|
-
continue;
|
|
35004
|
-
}
|
|
35005
|
-
// Callout / blockquote (consume contiguous `>` lines)
|
|
35006
|
-
if (line.startsWith('>')) {
|
|
35007
|
-
const block = [];
|
|
35008
|
-
while (i < lines.length && lines[i].startsWith('>')) {
|
|
35009
|
-
block.push(lines[i]);
|
|
35010
|
-
i++;
|
|
35011
|
-
}
|
|
35012
|
-
elements.push(this.makeQuoteOrCallout(block));
|
|
35013
|
-
continue;
|
|
35014
35034
|
}
|
|
35015
|
-
|
|
35016
|
-
|
|
35017
|
-
|
|
35018
|
-
|
|
35019
|
-
|
|
35020
|
-
|
|
35021
|
-
|
|
35022
|
-
|
|
35023
|
-
|
|
35024
|
-
|
|
35025
|
-
|
|
35026
|
-
|
|
35027
|
-
const
|
|
35028
|
-
|
|
35029
|
-
|
|
35030
|
-
|
|
35031
|
-
|
|
35032
|
-
|
|
35033
|
-
|
|
35034
|
-
|
|
35035
|
-
|
|
35036
|
-
|
|
35037
|
-
|
|
35038
|
-
if (check)
|
|
35039
|
-
items.push({ text: check[2].trim() });
|
|
35040
|
-
else if (ord && listType === 'ordered')
|
|
35041
|
-
items.push({ text: ord[1].trim() });
|
|
35042
|
-
else if (unord && listType !== 'ordered')
|
|
35043
|
-
items.push({ text: unord[1].trim() });
|
|
35044
|
-
else
|
|
35045
|
-
break;
|
|
35046
|
-
i++;
|
|
35047
|
-
}
|
|
35048
|
-
elements.push({ type: 'list', props: { items, listType } });
|
|
35049
|
-
continue;
|
|
35050
|
-
}
|
|
35051
|
-
// Paragraph — consume contiguous non-empty lines that aren't a special block
|
|
35052
|
-
const paragraph = [];
|
|
35053
|
-
while (i < lines.length && lines[i].trim() !== '' && !this.startsNewBlock(lines[i])) {
|
|
35054
|
-
paragraph.push(lines[i]);
|
|
35035
|
+
elements.push(...makeTable(rows));
|
|
35036
|
+
continue;
|
|
35037
|
+
}
|
|
35038
|
+
if (CHECKLIST_RE.test(line) || UNORDERED_RE.test(line) || ORDERED_RE.test(line)) {
|
|
35039
|
+
const listType = CHECKLIST_RE.test(line)
|
|
35040
|
+
? 'checklist'
|
|
35041
|
+
: ORDERED_RE.test(line)
|
|
35042
|
+
? 'ordered'
|
|
35043
|
+
: 'unordered';
|
|
35044
|
+
const items = [];
|
|
35045
|
+
while (i < lines.length && lines[i].trim() !== '') {
|
|
35046
|
+
const cur = lines[i];
|
|
35047
|
+
const check = cur.match(CHECKLIST_RE);
|
|
35048
|
+
const unord = cur.match(UNORDERED_RE);
|
|
35049
|
+
const ord = cur.match(ORDERED_RE);
|
|
35050
|
+
if (check)
|
|
35051
|
+
items.push({ text: check[2].trim() });
|
|
35052
|
+
else if (ord && listType === 'ordered')
|
|
35053
|
+
items.push({ text: ord[1].trim() });
|
|
35054
|
+
else if (unord && listType !== 'ordered')
|
|
35055
|
+
items.push({ text: unord[1].trim() });
|
|
35056
|
+
else
|
|
35057
|
+
break;
|
|
35055
35058
|
i++;
|
|
35056
35059
|
}
|
|
35057
|
-
|
|
35058
|
-
|
|
35059
|
-
elements.push({
|
|
35060
|
-
type: 'paragraph',
|
|
35061
|
-
props: {
|
|
35062
|
-
content: text,
|
|
35063
|
-
size: 'medium',
|
|
35064
|
-
color: 'dark',
|
|
35065
|
-
bold: false,
|
|
35066
|
-
processLinks: true,
|
|
35067
|
-
allowPartialBold: true,
|
|
35068
|
-
},
|
|
35069
|
-
});
|
|
35070
|
-
}
|
|
35060
|
+
elements.push({ type: 'list', props: { items, listType } });
|
|
35061
|
+
continue;
|
|
35071
35062
|
}
|
|
35072
|
-
|
|
35073
|
-
|
|
35074
|
-
|
|
35075
|
-
|
|
35076
|
-
|
|
35077
|
-
|
|
35078
|
-
|
|
35079
|
-
|
|
35080
|
-
|
|
35081
|
-
|
|
35082
|
-
|
|
35083
|
-
|
|
35084
|
-
|
|
35085
|
-
|
|
35086
|
-
|
|
35087
|
-
|
|
35088
|
-
|
|
35089
|
-
|
|
35090
|
-
CHECKLIST_RE.test(line) ||
|
|
35091
|
-
line.startsWith('>') ||
|
|
35092
|
-
BOX_DRAWING.test(line));
|
|
35093
|
-
}
|
|
35094
|
-
makeHeading(level, content) {
|
|
35095
|
-
if (level === 1) {
|
|
35096
|
-
return {
|
|
35097
|
-
type: 'title',
|
|
35098
|
-
props: { content, size: 'xlarge', color: 'dark', bold: true },
|
|
35099
|
-
};
|
|
35063
|
+
const paragraph = [];
|
|
35064
|
+
while (i < lines.length && lines[i].trim() !== '' && !startsNewBlock(lines[i])) {
|
|
35065
|
+
paragraph.push(lines[i]);
|
|
35066
|
+
i++;
|
|
35067
|
+
}
|
|
35068
|
+
const text = paragraph.join(' ').trim();
|
|
35069
|
+
if (text) {
|
|
35070
|
+
elements.push({
|
|
35071
|
+
type: 'paragraph',
|
|
35072
|
+
props: {
|
|
35073
|
+
content: text,
|
|
35074
|
+
size: 'medium',
|
|
35075
|
+
color: 'dark',
|
|
35076
|
+
bold: false,
|
|
35077
|
+
processLinks: true,
|
|
35078
|
+
allowPartialBold: true,
|
|
35079
|
+
},
|
|
35080
|
+
});
|
|
35100
35081
|
}
|
|
35101
|
-
const size = level === 2 ? 'large' : level === 3 ? 'medium' : 'small';
|
|
35102
|
-
return {
|
|
35103
|
-
type: 'subtitle',
|
|
35104
|
-
props: { content, size, color: 'dark', bold: true },
|
|
35105
|
-
};
|
|
35106
|
-
}
|
|
35107
|
-
makeQuoteOrCallout(block) {
|
|
35108
|
-
const first = block[0];
|
|
35109
|
-
const callout = first.match(CALLOUT_RE);
|
|
35110
|
-
const lines = block.map(l => l.replace(/^>\s?/, ''));
|
|
35111
|
-
if (callout) {
|
|
35112
|
-
const type = callout[1].toUpperCase();
|
|
35113
|
-
const firstLineRest = callout[2] || '';
|
|
35114
|
-
const rest = lines.slice(1).join(' ').trim();
|
|
35115
|
-
const text = [firstLineRest, rest].filter(Boolean).join(' ').trim();
|
|
35116
|
-
return this.makeNote(type, text);
|
|
35117
|
-
}
|
|
35118
|
-
const text = lines.join(' ').trim();
|
|
35119
|
-
return {
|
|
35120
|
-
type: 'quote',
|
|
35121
|
-
props: {
|
|
35122
|
-
content: text,
|
|
35123
|
-
size: 'medium',
|
|
35124
|
-
color: 'medium',
|
|
35125
|
-
bold: false,
|
|
35126
|
-
showQuoteMark: true,
|
|
35127
|
-
alignment: 'left',
|
|
35128
|
-
},
|
|
35129
|
-
};
|
|
35130
35082
|
}
|
|
35131
|
-
|
|
35132
|
-
|
|
35133
|
-
|
|
35134
|
-
|
|
35135
|
-
|
|
35136
|
-
|
|
35137
|
-
|
|
35138
|
-
|
|
35139
|
-
|
|
35140
|
-
|
|
35083
|
+
return {
|
|
35084
|
+
elements,
|
|
35085
|
+
maxWidth: '900px',
|
|
35086
|
+
centered: true,
|
|
35087
|
+
theme: 'auto',
|
|
35088
|
+
...config,
|
|
35089
|
+
};
|
|
35090
|
+
}
|
|
35091
|
+
function normalize(md) {
|
|
35092
|
+
return md.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
35093
|
+
}
|
|
35094
|
+
function startsNewBlock(line) {
|
|
35095
|
+
return (HEADING_RE.test(line) ||
|
|
35096
|
+
FENCE_RE.test(line) ||
|
|
35097
|
+
SEPARATOR_RE.test(line) ||
|
|
35098
|
+
TABLE_ROW_RE.test(line) ||
|
|
35099
|
+
UNORDERED_RE.test(line) ||
|
|
35100
|
+
ORDERED_RE.test(line) ||
|
|
35101
|
+
CHECKLIST_RE.test(line) ||
|
|
35102
|
+
line.startsWith('>') ||
|
|
35103
|
+
BOX_DRAWING.test(line));
|
|
35104
|
+
}
|
|
35105
|
+
function makeHeading(level, content) {
|
|
35106
|
+
if (level === 1) {
|
|
35141
35107
|
return {
|
|
35142
|
-
type: '
|
|
35143
|
-
props: {
|
|
35144
|
-
text,
|
|
35145
|
-
prefix: `${cfg.prefix}:`,
|
|
35146
|
-
color: cfg.color,
|
|
35147
|
-
textColor: 'dark',
|
|
35148
|
-
size: 'medium',
|
|
35149
|
-
rounded: true,
|
|
35150
|
-
},
|
|
35108
|
+
type: 'title',
|
|
35109
|
+
props: { content, size: 'xlarge', color: 'dark', bold: true },
|
|
35151
35110
|
};
|
|
35152
35111
|
}
|
|
35153
|
-
|
|
35154
|
-
|
|
35155
|
-
|
|
35156
|
-
|
|
35157
|
-
|
|
35158
|
-
|
|
35159
|
-
|
|
35160
|
-
|
|
35161
|
-
|
|
35162
|
-
|
|
35163
|
-
|
|
35164
|
-
|
|
35165
|
-
|
|
35166
|
-
|
|
35167
|
-
|
|
35168
|
-
|
|
35169
|
-
|
|
35170
|
-
|
|
35171
|
-
|
|
35172
|
-
|
|
35173
|
-
|
|
35174
|
-
|
|
35175
|
-
|
|
35176
|
-
|
|
35177
|
-
|
|
35178
|
-
|
|
35179
|
-
|
|
35180
|
-
|
|
35181
|
-
|
|
35182
|
-
|
|
35183
|
-
|
|
35184
|
-
|
|
35185
|
-
}
|
|
35186
|
-
|
|
35187
|
-
|
|
35188
|
-
|
|
35189
|
-
|
|
35190
|
-
|
|
35191
|
-
|
|
35112
|
+
const size = level === 2 ? 'large' : level === 3 ? 'medium' : 'small';
|
|
35113
|
+
return {
|
|
35114
|
+
type: 'subtitle',
|
|
35115
|
+
props: { content, size, color: 'dark', bold: true },
|
|
35116
|
+
};
|
|
35117
|
+
}
|
|
35118
|
+
function makeQuoteOrCallout(block) {
|
|
35119
|
+
const first = block[0];
|
|
35120
|
+
const callout = first.match(CALLOUT_RE);
|
|
35121
|
+
const lines = block.map(l => l.replace(/^>\s?/, ''));
|
|
35122
|
+
if (callout) {
|
|
35123
|
+
const type = callout[1].toUpperCase();
|
|
35124
|
+
const firstLineRest = callout[2] || '';
|
|
35125
|
+
const rest = lines.slice(1).join(' ').trim();
|
|
35126
|
+
const text = [firstLineRest, rest].filter(Boolean).join(' ').trim();
|
|
35127
|
+
return makeNote(type, text);
|
|
35128
|
+
}
|
|
35129
|
+
const text = lines.join(' ').trim();
|
|
35130
|
+
return {
|
|
35131
|
+
type: 'quote',
|
|
35132
|
+
props: {
|
|
35133
|
+
content: text,
|
|
35134
|
+
size: 'medium',
|
|
35135
|
+
color: 'medium',
|
|
35136
|
+
bold: false,
|
|
35137
|
+
showQuoteMark: true,
|
|
35138
|
+
alignment: 'left',
|
|
35139
|
+
},
|
|
35140
|
+
};
|
|
35141
|
+
}
|
|
35142
|
+
function makeNote(kind, text) {
|
|
35143
|
+
const map = {
|
|
35144
|
+
NOTE: { color: 'primary', prefix: 'Nota' },
|
|
35145
|
+
TIP: { color: 'success', prefix: 'Tip' },
|
|
35146
|
+
INFO: { color: 'tertiary', prefix: 'Info' },
|
|
35147
|
+
IMPORTANT: { color: 'warning', prefix: 'Importante' },
|
|
35148
|
+
WARNING: { color: 'warning', prefix: 'Atención' },
|
|
35149
|
+
CAUTION: { color: 'danger', prefix: 'Precaución' },
|
|
35150
|
+
};
|
|
35151
|
+
const cfg = map[kind];
|
|
35152
|
+
return {
|
|
35153
|
+
type: 'note',
|
|
35154
|
+
props: {
|
|
35155
|
+
text,
|
|
35156
|
+
prefix: `${cfg.prefix}:`,
|
|
35157
|
+
color: cfg.color,
|
|
35158
|
+
textColor: 'dark',
|
|
35159
|
+
size: 'medium',
|
|
35160
|
+
rounded: true,
|
|
35161
|
+
},
|
|
35162
|
+
};
|
|
35163
|
+
}
|
|
35164
|
+
function makeTable(rows) {
|
|
35165
|
+
const parsed = rows
|
|
35166
|
+
.filter(r => !TABLE_DIVIDER_RE.test(r))
|
|
35167
|
+
.map(r => r
|
|
35168
|
+
.trim()
|
|
35169
|
+
.replace(/^\|/, '')
|
|
35170
|
+
.replace(/\|$/, '')
|
|
35171
|
+
.split('|')
|
|
35172
|
+
.map(c => c.trim()));
|
|
35173
|
+
if (parsed.length === 0)
|
|
35174
|
+
return [];
|
|
35175
|
+
const header = parsed[0];
|
|
35176
|
+
const dataRows = parsed.slice(1);
|
|
35177
|
+
if (dataRows.length === 0) {
|
|
35178
|
+
return [
|
|
35179
|
+
{
|
|
35192
35180
|
type: 'paragraph',
|
|
35193
35181
|
props: {
|
|
35194
|
-
content:
|
|
35182
|
+
content: header.join(' · '),
|
|
35195
35183
|
size: 'medium',
|
|
35196
35184
|
color: 'dark',
|
|
35197
35185
|
bold: false,
|
|
35198
35186
|
processLinks: true,
|
|
35199
35187
|
allowPartialBold: true,
|
|
35200
35188
|
},
|
|
35201
|
-
}
|
|
35189
|
+
},
|
|
35190
|
+
];
|
|
35191
|
+
}
|
|
35192
|
+
return dataRows.map(row => {
|
|
35193
|
+
const pairs = row.map((cell, idx) => {
|
|
35194
|
+
const key = header[idx] ?? '';
|
|
35195
|
+
return key ? `**${key}:** ${cell}` : cell;
|
|
35202
35196
|
});
|
|
35197
|
+
return {
|
|
35198
|
+
type: 'paragraph',
|
|
35199
|
+
props: {
|
|
35200
|
+
content: pairs.join(' · '),
|
|
35201
|
+
size: 'medium',
|
|
35202
|
+
color: 'dark',
|
|
35203
|
+
bold: false,
|
|
35204
|
+
processLinks: true,
|
|
35205
|
+
allowPartialBold: true,
|
|
35206
|
+
},
|
|
35207
|
+
};
|
|
35208
|
+
});
|
|
35209
|
+
}
|
|
35210
|
+
|
|
35211
|
+
/**
|
|
35212
|
+
* Angular service wrapper for the pure {@link parseMarkdownArticle} function.
|
|
35213
|
+
* Provided in root so it can be injected anywhere. The actual parsing logic lives in
|
|
35214
|
+
* `markdown-article-parser.ts` and is also usable from Node scripts (build-time generation).
|
|
35215
|
+
*/
|
|
35216
|
+
class MarkdownArticleParserService {
|
|
35217
|
+
parse(markdown, config) {
|
|
35218
|
+
return parseMarkdownArticle(markdown, config);
|
|
35203
35219
|
}
|
|
35204
35220
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MarkdownArticleParserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
35205
35221
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MarkdownArticleParserService, providedIn: 'root' }); }
|
|
@@ -35209,43 +35225,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
35209
35225
|
args: [{ providedIn: 'root' }]
|
|
35210
35226
|
}] });
|
|
35211
35227
|
|
|
35228
|
+
const LEGAL_CONTENT_CONFIG = new InjectionToken('LEGAL_CONTENT_CONFIG');
|
|
35212
35229
|
/**
|
|
35213
|
-
* Loads
|
|
35214
|
-
*
|
|
35215
|
-
*
|
|
35230
|
+
* Loads legal articles via one of two modes:
|
|
35231
|
+
*
|
|
35232
|
+
* 1. **Build-time** (preferred): when the app provides `LEGAL_CONTENT_CONFIG.factories`
|
|
35233
|
+
* via `provideLegalContent()`, the service dynamically imports the matching
|
|
35234
|
+
* locale module and returns the pre-parsed `ArticleMetadata` synchronously
|
|
35235
|
+
* (wrapped in an Observable). Each locale is code-split.
|
|
35236
|
+
*
|
|
35237
|
+
* 2. **Runtime**: when no factory matches, falls back to fetching
|
|
35238
|
+
* `/assets/legal/{locale}/{slug}.md` and parsing on the fly.
|
|
35239
|
+
*
|
|
35240
|
+
* Both modes cache by `locale:slug` so concurrent loads share one promise/HTTP request.
|
|
35216
35241
|
*/
|
|
35217
35242
|
class LegalContentService {
|
|
35218
35243
|
constructor() {
|
|
35219
35244
|
this.http = inject(HttpClient);
|
|
35220
35245
|
this.parser = inject(MarkdownArticleParserService);
|
|
35246
|
+
this.config = inject(LEGAL_CONTENT_CONFIG, { optional: true }) ?? {};
|
|
35221
35247
|
this.DEFAULT_BASE = '/assets/legal';
|
|
35222
35248
|
this.cache = new Map();
|
|
35249
|
+
this.factoryCache = new Map();
|
|
35223
35250
|
}
|
|
35224
35251
|
load(slug, options = {}) {
|
|
35225
35252
|
const locale = (options.locale ?? 'es').toLowerCase();
|
|
35226
|
-
const
|
|
35227
|
-
|
|
35228
|
-
|
|
35253
|
+
const fallback = options.fallbackLocale === undefined
|
|
35254
|
+
? (this.config.fallbackLocale ?? 'es')
|
|
35255
|
+
: options.fallbackLocale;
|
|
35256
|
+
const key = `${locale}|${slug}`;
|
|
35229
35257
|
const cached = this.cache.get(key);
|
|
35230
35258
|
if (cached)
|
|
35231
35259
|
return cached;
|
|
35232
|
-
const primary = this.
|
|
35260
|
+
const primary = this.loadOne(slug, locale, options.basePath);
|
|
35233
35261
|
const stream = fallback && fallback !== locale
|
|
35234
|
-
? primary.pipe(catchError(() => this.
|
|
35262
|
+
? primary.pipe(catchError(() => this.loadOne(slug, fallback, options.basePath)))
|
|
35235
35263
|
: primary;
|
|
35236
35264
|
const shared = stream.pipe(shareReplay({ bufferSize: 1, refCount: false }));
|
|
35237
35265
|
this.cache.set(key, shared);
|
|
35238
35266
|
return shared;
|
|
35239
35267
|
}
|
|
35240
|
-
/**
|
|
35268
|
+
/** Raw Markdown — only available in runtime mode (HTTP). */
|
|
35241
35269
|
raw(slug, options = {}) {
|
|
35242
35270
|
const locale = (options.locale ?? 'es').toLowerCase();
|
|
35243
|
-
const base = options.basePath ?? this.DEFAULT_BASE;
|
|
35271
|
+
const base = options.basePath ?? this.config.basePath ?? this.DEFAULT_BASE;
|
|
35244
35272
|
return this.http.get(`${base}/${locale}/${slug}.md`, { responseType: 'text' });
|
|
35245
35273
|
}
|
|
35246
|
-
/** Clears
|
|
35274
|
+
/** Clears in-memory caches. Call on runtime locale change. */
|
|
35247
35275
|
invalidate() {
|
|
35248
35276
|
this.cache.clear();
|
|
35277
|
+
this.factoryCache.clear();
|
|
35278
|
+
}
|
|
35279
|
+
loadOne(slug, locale, basePathOverride) {
|
|
35280
|
+
const factory = this.config.factories?.[locale];
|
|
35281
|
+
if (factory) {
|
|
35282
|
+
return from(this.runFactory(locale, factory)).pipe(switchMap(content => {
|
|
35283
|
+
const article = content[slug];
|
|
35284
|
+
return article
|
|
35285
|
+
? of(article)
|
|
35286
|
+
: throwError(() => new Error(`Legal doc not found: ${locale}/${slug}`));
|
|
35287
|
+
}));
|
|
35288
|
+
}
|
|
35289
|
+
const base = basePathOverride ?? this.config.basePath ?? this.DEFAULT_BASE;
|
|
35290
|
+
return this.fetchAndParse(`${base}/${locale}/${slug}.md`);
|
|
35291
|
+
}
|
|
35292
|
+
runFactory(locale, factory) {
|
|
35293
|
+
const cached = this.factoryCache.get(locale);
|
|
35294
|
+
if (cached)
|
|
35295
|
+
return cached;
|
|
35296
|
+
const promise = factory();
|
|
35297
|
+
this.factoryCache.set(locale, promise);
|
|
35298
|
+
return promise;
|
|
35249
35299
|
}
|
|
35250
35300
|
fetchAndParse(url) {
|
|
35251
35301
|
return this.http.get(url, { responseType: 'text' }).pipe(switchMap(md => md && md.trim().length > 0
|
|
@@ -35259,6 +35309,184 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
35259
35309
|
type: Injectable,
|
|
35260
35310
|
args: [{ providedIn: 'root' }]
|
|
35261
35311
|
}] });
|
|
35312
|
+
/**
|
|
35313
|
+
* Wires pre-generated legal content into `LegalContentService`. Call from `main.ts`
|
|
35314
|
+
* (or any `providers: []` array). The factories use dynamic `import()` so each
|
|
35315
|
+
* locale is code-split — only the active locale's bundle is loaded.
|
|
35316
|
+
*
|
|
35317
|
+
* @example
|
|
35318
|
+
* provideLegalContent({
|
|
35319
|
+
* factories: {
|
|
35320
|
+
* es: () => import('./app/generated/legal-content.es').then((m) => m.LEGAL_CONTENT_ES),
|
|
35321
|
+
* en: () => import('./app/generated/legal-content.en').then((m) => m.LEGAL_CONTENT_EN),
|
|
35322
|
+
* pt: () => import('./app/generated/legal-content.pt').then((m) => m.LEGAL_CONTENT_PT),
|
|
35323
|
+
* },
|
|
35324
|
+
* })
|
|
35325
|
+
*/
|
|
35326
|
+
function provideLegalContent(config) {
|
|
35327
|
+
return { provide: LEGAL_CONTENT_CONFIG, useValue: config };
|
|
35328
|
+
}
|
|
35329
|
+
|
|
35330
|
+
/**
|
|
35331
|
+
* PreferencesService — preferencias del user en el doc canónico Firestore
|
|
35332
|
+
* `/apps/{appId}/users/{uid}/preferences/main`.
|
|
35333
|
+
*
|
|
35334
|
+
* Read reactivo (signals) via listener Firestore.
|
|
35335
|
+
* Write via `PUT /v2/auth/preferences` (cliente NUNCA escribe Firestore directo —
|
|
35336
|
+
* ver memoria `feedback_no_direct_firestore_writes`).
|
|
35337
|
+
*
|
|
35338
|
+
* Side-effects automáticos:
|
|
35339
|
+
* - Cuando `theme()` cambia → `ThemeService.Theme = ...`
|
|
35340
|
+
* - Cuando `language()` cambia → `I18nService.setLanguage(...)`
|
|
35341
|
+
*
|
|
35342
|
+
* Auto-bind al user actual via `AuthService.user()`. Sin user (logout) → unbind.
|
|
35343
|
+
*/
|
|
35344
|
+
class PreferencesService {
|
|
35345
|
+
constructor(config, firestore, auth, http, themeService, i18n) {
|
|
35346
|
+
this.config = config;
|
|
35347
|
+
this.firestore = firestore;
|
|
35348
|
+
this.auth = auth;
|
|
35349
|
+
this.http = http;
|
|
35350
|
+
this.themeService = themeService;
|
|
35351
|
+
this.i18n = i18n;
|
|
35352
|
+
this._theme = signal('auto');
|
|
35353
|
+
this._language = signal('es');
|
|
35354
|
+
this._notificationsMaster = signal(true);
|
|
35355
|
+
/** `true` después del primer snapshot Firestore. Antes, defaults sin side-effects. */
|
|
35356
|
+
this._synced = signal(false);
|
|
35357
|
+
this.theme = this._theme.asReadonly();
|
|
35358
|
+
this.language = this._language.asReadonly();
|
|
35359
|
+
this.notificationsMaster = this._notificationsMaster.asReadonly();
|
|
35360
|
+
this.synced = this._synced.asReadonly();
|
|
35361
|
+
const destroyRef = inject(DestroyRef);
|
|
35362
|
+
destroyRef.onDestroy(() => this.unbind());
|
|
35363
|
+
// Auto-bind al user actual. effect() corre en injection context (constructor OK).
|
|
35364
|
+
effect(() => {
|
|
35365
|
+
const user = this.auth.user();
|
|
35366
|
+
if (user?.userId) {
|
|
35367
|
+
this.bindToUser(user.userId);
|
|
35368
|
+
}
|
|
35369
|
+
else {
|
|
35370
|
+
this.unbind();
|
|
35371
|
+
}
|
|
35372
|
+
});
|
|
35373
|
+
// Side-effect: aplicar theme local cuando llega snapshot real.
|
|
35374
|
+
effect(() => {
|
|
35375
|
+
if (!this._synced())
|
|
35376
|
+
return;
|
|
35377
|
+
const t = this._theme();
|
|
35378
|
+
if (this.themeService) {
|
|
35379
|
+
this.themeService.Theme = t;
|
|
35380
|
+
}
|
|
35381
|
+
});
|
|
35382
|
+
// Side-effect: aplicar language local cuando llega snapshot real.
|
|
35383
|
+
effect(() => {
|
|
35384
|
+
if (!this._synced())
|
|
35385
|
+
return;
|
|
35386
|
+
const l = this._language();
|
|
35387
|
+
if (this.i18n && this.i18n.lang() !== l) {
|
|
35388
|
+
this.i18n.setLanguage(l);
|
|
35389
|
+
}
|
|
35390
|
+
});
|
|
35391
|
+
}
|
|
35392
|
+
/** Actualiza preferencias via backend. Optimistic UI: aplica local, revierte si falla. */
|
|
35393
|
+
async update(partial) {
|
|
35394
|
+
const url = `${this.config.apiUrl}/v2/auth/preferences`;
|
|
35395
|
+
const prev = {
|
|
35396
|
+
theme: this._theme(),
|
|
35397
|
+
language: this._language(),
|
|
35398
|
+
master: this._notificationsMaster(),
|
|
35399
|
+
};
|
|
35400
|
+
if (partial.theme)
|
|
35401
|
+
this._theme.set(partial.theme);
|
|
35402
|
+
if (partial.language)
|
|
35403
|
+
this._language.set(partial.language);
|
|
35404
|
+
if (partial.notifications && typeof partial.notifications.master === 'boolean') {
|
|
35405
|
+
this._notificationsMaster.set(partial.notifications.master);
|
|
35406
|
+
}
|
|
35407
|
+
try {
|
|
35408
|
+
const res = await firstValueFrom(this.http.put(url, partial));
|
|
35409
|
+
// El listener Firestore es la fuente final, pero alinear ya con la
|
|
35410
|
+
// respuesta del backend acelera UX (especialmente si el listener
|
|
35411
|
+
// tarda en propagar).
|
|
35412
|
+
if (res.theme)
|
|
35413
|
+
this._theme.set(res.theme);
|
|
35414
|
+
if (res.language)
|
|
35415
|
+
this._language.set(res.language);
|
|
35416
|
+
if (typeof res.notifications?.master === 'boolean') {
|
|
35417
|
+
this._notificationsMaster.set(res.notifications.master);
|
|
35418
|
+
}
|
|
35419
|
+
return res;
|
|
35420
|
+
}
|
|
35421
|
+
catch (err) {
|
|
35422
|
+
// Revert optimistic.
|
|
35423
|
+
this._theme.set(prev.theme);
|
|
35424
|
+
this._language.set(prev.language);
|
|
35425
|
+
this._notificationsMaster.set(prev.master);
|
|
35426
|
+
throw err;
|
|
35427
|
+
}
|
|
35428
|
+
}
|
|
35429
|
+
setTheme(theme) {
|
|
35430
|
+
return this.update({ theme });
|
|
35431
|
+
}
|
|
35432
|
+
setLanguage(language) {
|
|
35433
|
+
return this.update({ language });
|
|
35434
|
+
}
|
|
35435
|
+
setNotificationsMaster(enabled) {
|
|
35436
|
+
return this.update({ notifications: { master: enabled } });
|
|
35437
|
+
}
|
|
35438
|
+
bindToUser(userId) {
|
|
35439
|
+
if (this.currentUserId === userId && this.subscription)
|
|
35440
|
+
return;
|
|
35441
|
+
this.unbind();
|
|
35442
|
+
this.currentUserId = userId;
|
|
35443
|
+
// FirestoreService.docChanges prefija automáticamente `apps/{appId}/`
|
|
35444
|
+
// cuando `config.appId` está seteado en ValtechAuthConfig.
|
|
35445
|
+
this.subscription = this.firestore
|
|
35446
|
+
.docChanges(`users/${userId}/preferences`, 'main')
|
|
35447
|
+
.subscribe(doc => {
|
|
35448
|
+
if (!doc) {
|
|
35449
|
+
// Doc no existe aún (user nuevo, sin primer sync). Mantenemos
|
|
35450
|
+
// defaults locales pero NO marcamos synced — los side-effects no
|
|
35451
|
+
// pisan el theme/lang locales con valores arbitrarios.
|
|
35452
|
+
return;
|
|
35453
|
+
}
|
|
35454
|
+
if (doc.theme)
|
|
35455
|
+
this._theme.set(doc.theme);
|
|
35456
|
+
if (doc.language)
|
|
35457
|
+
this._language.set(doc.language);
|
|
35458
|
+
if (doc.notifications && typeof doc.notifications.master === 'boolean') {
|
|
35459
|
+
this._notificationsMaster.set(doc.notifications.master);
|
|
35460
|
+
}
|
|
35461
|
+
this._synced.set(true);
|
|
35462
|
+
});
|
|
35463
|
+
}
|
|
35464
|
+
unbind() {
|
|
35465
|
+
this.subscription?.unsubscribe();
|
|
35466
|
+
this.subscription = undefined;
|
|
35467
|
+
this.currentUserId = undefined;
|
|
35468
|
+
this._synced.set(false);
|
|
35469
|
+
}
|
|
35470
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PreferencesService, deps: [{ token: VALTECH_AUTH_CONFIG }, { token: FirestoreService }, { token: AuthService }, { token: i1$8.HttpClient }, { token: ThemeService, optional: true }, { token: I18nService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
35471
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PreferencesService, providedIn: 'root' }); }
|
|
35472
|
+
}
|
|
35473
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PreferencesService, decorators: [{
|
|
35474
|
+
type: Injectable,
|
|
35475
|
+
args: [{ providedIn: 'root' }]
|
|
35476
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
35477
|
+
type: Inject,
|
|
35478
|
+
args: [VALTECH_AUTH_CONFIG]
|
|
35479
|
+
}] }, { type: FirestoreService }, { type: AuthService }, { type: i1$8.HttpClient }, { type: ThemeService, decorators: [{
|
|
35480
|
+
type: Optional
|
|
35481
|
+
}] }, { type: I18nService, decorators: [{
|
|
35482
|
+
type: Optional
|
|
35483
|
+
}] }] });
|
|
35484
|
+
|
|
35485
|
+
/**
|
|
35486
|
+
* Preferences types — Fase 1 schema simple (theme + language + notifications.master).
|
|
35487
|
+
* Doc canónico: /apps/{appId}/users/{uid}/preferences/main
|
|
35488
|
+
* Cliente NUNCA escribe directo — todas las mutaciones via PUT /v2/auth/preferences.
|
|
35489
|
+
*/
|
|
35262
35490
|
|
|
35263
35491
|
/**
|
|
35264
35492
|
* Cross-Platform Version Helpers
|
|
@@ -42407,5 +42635,5 @@ function buildFooterLinks(links, t) {
|
|
|
42407
42635
|
* Generated bundle index. Do not edit.
|
|
42408
42636
|
*/
|
|
42409
42637
|
|
|
42410
|
-
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, 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, 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, GlowCardComponent, 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, LOGIN_DEFAULTS, LanguageSelectorComponent, LayeredCardComponent, LegalContentService, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MODAL_SIZES, 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, PLATFORM_CONFIGS, PageContentComponent, PageTemplateComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, PhoneInputComponent, PillComponent, PinInputComponent, PlainCodeBoxComponent, PopoverSelectorComponent, 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, SKELETON_PRESETS, 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, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UpdateBannerComponent, 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_SOCIAL_LINKS, VERSION, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, blogPost, buildFooterLinks, buildPath, collections, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createTitleProps, docs, extractPathParams, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, news, permissionGuard, permissionGuardFromRoute, provideValtechAds, provideValtechAppConfig, provideValtechAuth, provideValtechAuthInterceptor, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechPresets, provideValtechSkeleton, query, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard, toArticle };
|
|
42638
|
+
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, 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, 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, GlowCardComponent, 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, LinkComponent, LinkProcessorService, LinkedProvidersComponent, LinksAccordionComponent, LinksCakeComponent, ListSkeletonComponent, LoadingDirective, LocalStorageService, LocaleService, LoginComponent, MODAL_SIZES, 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, PLATFORM_CONFIGS, PageContentComponent, PageTemplateComponent, PageWrapperComponent, PaginationComponent, PaginationService, PasswordInputComponent, 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, SKELETON_PRESETS, 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, SkeletonService, SolidBlockButton, SolidDefault, SolidDefaultBlock, SolidDefaultButton, SolidDefaultFull, SolidDefaultRound, SolidDefaultRoundBlock, SolidDefaultRoundButton, SolidDefaultRoundFull, SolidFullButton, SolidLargeButton, SolidLargeRoundButton, SolidSmallButton, SolidSmallRoundButton, StatsCardComponent, StepperComponent, StorageService, SwipeCarouselComponent, TabbedContentComponent, TableSkeletonComponent, TabsComponent, Terminal404Component, TestimonialCardComponent, TestimonialCarouselComponent, TextComponent, TextInputComponent, TextareaInputComponent, ThemeOption, ThemeService, TimelineComponent, TitleBlockComponent, TitleComponent, ToastService, ToggleInputComponent, TokenService, ToolbarActionType, ToolbarComponent, TranslatePipe, TypedCollection, UpdateBannerComponent, 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_SOCIAL_LINKS, VERSION, WizardComponent, WizardFooterComponent, applyDefaultValueToControl, authGuard, authInterceptor, blogPost, buildFooterLinks, buildPath, collections, createFirebaseConfig, createGlowCardProps, createInitialPaginationState, createNumberFromToField, createTitleProps, docs, extractPathParams, getAppInfo, getAppVersion, getCollectionPath, getDocumentId, getTimeOfDayKey, goToTop, guestGuard, hasEmulators, isAtEnd, isCollectionPath, isDocumentPath, isEmulatorMode, isValidPath, joinPath, maxLength, news, parseMarkdownArticle, permissionGuard, permissionGuardFromRoute, provideLegalContent, provideValtechAds, provideValtechAppConfig, provideValtechAuth, provideValtechAuthInterceptor, provideValtechFeedback, provideValtechFirebase, provideValtechI18n, provideValtechPresets, provideValtechSkeleton, query, replaceSpecialChars, resolveColor, resolveInputDefaultValue, roleGuard, storagePaths, superAdminGuard, toArticle };
|
|
42411
42639
|
//# sourceMappingURL=valtech-components.mjs.map
|