valtech-components 2.0.621 → 2.0.623

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.
Files changed (31) hide show
  1. package/esm2022/lib/components/molecules/docs-code-example/docs-code-example.component.mjs +3 -3
  2. package/esm2022/lib/components/molecules/footer-links/footer-links.component.mjs +5 -5
  3. package/esm2022/lib/components/molecules/update-banner/update-banner.component.mjs +112 -0
  4. package/esm2022/lib/components/organisms/menu/menu.component.mjs +3 -3
  5. package/esm2022/lib/components/templates/maintenance-page/maintenance-page.component.mjs +153 -0
  6. package/esm2022/lib/components/templates/maintenance-page/types.mjs +2 -0
  7. package/esm2022/lib/components/templates/page-content/page-content.component.mjs +21 -5
  8. package/esm2022/lib/components/templates/page-content/types.mjs +1 -1
  9. package/esm2022/lib/services/app-config/app-config.service.mjs +209 -0
  10. package/esm2022/lib/services/app-config/config.mjs +47 -0
  11. package/esm2022/lib/services/app-config/index.mjs +39 -0
  12. package/esm2022/lib/services/app-config/types.mjs +13 -0
  13. package/esm2022/lib/services/i18n/default-content.mjs +21 -1
  14. package/esm2022/public-api.mjs +8 -1
  15. package/fesm2022/valtech-components.mjs +8180 -7595
  16. package/fesm2022/valtech-components.mjs.map +1 -1
  17. package/lib/components/atoms/rights-footer/rights-footer.component.d.ts +1 -1
  18. package/lib/components/molecules/features-list/features-list.component.d.ts +2 -2
  19. package/lib/components/molecules/update-banner/update-banner.component.d.ts +42 -0
  20. package/lib/components/organisms/article/article.component.d.ts +2 -2
  21. package/lib/components/organisms/toolbar/toolbar.component.d.ts +1 -1
  22. package/lib/components/templates/maintenance-page/maintenance-page.component.d.ts +57 -0
  23. package/lib/components/templates/maintenance-page/types.d.ts +12 -0
  24. package/lib/components/templates/page-content/page-content.component.d.ts +6 -0
  25. package/lib/components/templates/page-content/types.d.ts +6 -0
  26. package/lib/services/app-config/app-config.service.d.ts +115 -0
  27. package/lib/services/app-config/config.d.ts +31 -0
  28. package/lib/services/app-config/index.d.ts +38 -0
  29. package/lib/services/app-config/types.d.ts +54 -0
  30. package/package.json +1 -1
  31. package/public-api.d.ts +4 -0
@@ -0,0 +1,153 @@
1
+ /**
2
+ * MaintenancePageComponent
3
+ *
4
+ * Página de mantenimiento que se muestra cuando la aplicación está en modo mantenimiento.
5
+ */
6
+ import { CommonModule } from '@angular/common';
7
+ import { Component, computed, inject, Input } from '@angular/core';
8
+ import { IonContent } from '@ionic/angular/standalone';
9
+ import { ImageComponent } from '../../atoms/image/image.component';
10
+ import { I18nService } from '../../../services/i18n';
11
+ import * as i0 from "@angular/core";
12
+ /**
13
+ * val-maintenance-page
14
+ *
15
+ * Página completa de mantenimiento con imagen, título y mensaje personalizables.
16
+ * Se integra con i18n para textos por defecto en múltiples idiomas.
17
+ *
18
+ * @example
19
+ * ```html
20
+ * <!-- Uso básico (usa textos por defecto) -->
21
+ * <val-maintenance-page />
22
+ *
23
+ * <!-- Personalizado -->
24
+ * <val-maintenance-page
25
+ * [props]="{
26
+ * title: 'En mantenimiento',
27
+ * message: 'Volvemos pronto',
28
+ * image: 'assets/maintenance.svg'
29
+ * }"
30
+ * />
31
+ * ```
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // En app.component.ts
36
+ * @Component({
37
+ * template: \`
38
+ * @if (appConfig.isMaintenanceMode()) {
39
+ * <val-maintenance-page />
40
+ * } @else {
41
+ * <ion-router-outlet />
42
+ * }
43
+ * \`
44
+ * })
45
+ * export class AppComponent {
46
+ * appConfig = inject(AppConfigService);
47
+ * }
48
+ * ```
49
+ */
50
+ export class MaintenancePageComponent {
51
+ constructor() {
52
+ /**
53
+ * Configuración de la página de mantenimiento.
54
+ */
55
+ this.props = {};
56
+ this.i18n = inject(I18nService);
57
+ /**
58
+ * Título de la página (reactivo a cambios de idioma).
59
+ */
60
+ this.title = computed(() => this.props.title || this.i18n.t('maintenanceMode', 'AppConfig'));
61
+ /**
62
+ * Mensaje de la página (reactivo a cambios de idioma).
63
+ */
64
+ this.message = computed(() => this.props.message || this.i18n.t('maintenanceMessage', 'AppConfig'));
65
+ }
66
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MaintenancePageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
67
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MaintenancePageComponent, isStandalone: true, selector: "val-maintenance-page", inputs: { props: "props" }, ngImport: i0, template: `
68
+ <ion-content class="maintenance-content">
69
+ <div class="maintenance-container">
70
+ <div class="maintenance-icon">
71
+ @if (props.image) {
72
+ <val-image
73
+ [props]="{
74
+ src: props.image,
75
+ alt: 'Maintenance',
76
+ mode: 'box',
77
+ size: 'large',
78
+ shaded: false,
79
+ bordered: false
80
+ }"
81
+ />
82
+ } @else {
83
+ <div class="default-icon">
84
+ <svg
85
+ xmlns="http://www.w3.org/2000/svg"
86
+ viewBox="0 0 24 24"
87
+ fill="currentColor"
88
+ >
89
+ <path
90
+ d="M12 6v6l4 2m6-2a10 10 0 11-20 0 10 10 0 0120 0z"
91
+ stroke="currentColor"
92
+ stroke-width="2"
93
+ fill="none"
94
+ stroke-linecap="round"
95
+ stroke-linejoin="round"
96
+ />
97
+ </svg>
98
+ </div>
99
+ }
100
+ </div>
101
+
102
+ <h1 class="maintenance-title">{{ title() }}</h1>
103
+ <p class="maintenance-message">{{ message() }}</p>
104
+ </div>
105
+ </ion-content>
106
+ `, isInline: true, styles: [".maintenance-content{--background: var(--ion-background-color, #f5f5f5)}.maintenance-container{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100%;padding:2rem;text-align:center}.maintenance-icon{margin-bottom:2rem}.maintenance-icon .default-icon{width:120px;height:120px;color:var(--ion-color-primary, #4a1d96);opacity:.8}.maintenance-icon .default-icon svg{width:100%;height:100%}.maintenance-title{font-size:2rem;font-weight:700;color:var(--ion-text-color, #1a1a1a);margin:0 0 1rem}.maintenance-message{font-size:1.125rem;color:var(--ion-color-medium, #666);margin:0;max-width:400px;line-height:1.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: ImageComponent, selector: "val-image", inputs: ["props"] }] }); }
107
+ }
108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MaintenancePageComponent, decorators: [{
109
+ type: Component,
110
+ args: [{ selector: 'val-maintenance-page', standalone: true, imports: [CommonModule, IonContent, ImageComponent], template: `
111
+ <ion-content class="maintenance-content">
112
+ <div class="maintenance-container">
113
+ <div class="maintenance-icon">
114
+ @if (props.image) {
115
+ <val-image
116
+ [props]="{
117
+ src: props.image,
118
+ alt: 'Maintenance',
119
+ mode: 'box',
120
+ size: 'large',
121
+ shaded: false,
122
+ bordered: false
123
+ }"
124
+ />
125
+ } @else {
126
+ <div class="default-icon">
127
+ <svg
128
+ xmlns="http://www.w3.org/2000/svg"
129
+ viewBox="0 0 24 24"
130
+ fill="currentColor"
131
+ >
132
+ <path
133
+ d="M12 6v6l4 2m6-2a10 10 0 11-20 0 10 10 0 0120 0z"
134
+ stroke="currentColor"
135
+ stroke-width="2"
136
+ fill="none"
137
+ stroke-linecap="round"
138
+ stroke-linejoin="round"
139
+ />
140
+ </svg>
141
+ </div>
142
+ }
143
+ </div>
144
+
145
+ <h1 class="maintenance-title">{{ title() }}</h1>
146
+ <p class="maintenance-message">{{ message() }}</p>
147
+ </div>
148
+ </ion-content>
149
+ `, styles: [".maintenance-content{--background: var(--ion-background-color, #f5f5f5)}.maintenance-container{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100%;padding:2rem;text-align:center}.maintenance-icon{margin-bottom:2rem}.maintenance-icon .default-icon{width:120px;height:120px;color:var(--ion-color-primary, #4a1d96);opacity:.8}.maintenance-icon .default-icon svg{width:100%;height:100%}.maintenance-title{font-size:2rem;font-weight:700;color:var(--ion-text-color, #1a1a1a);margin:0 0 1rem}.maintenance-message{font-size:1.125rem;color:var(--ion-color-medium, #666);margin:0;max-width:400px;line-height:1.6}\n"] }]
150
+ }], propDecorators: { props: [{
151
+ type: Input
152
+ }] } });
153
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbnRlbmFuY2UtcGFnZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvdGVtcGxhdGVzL21haW50ZW5hbmNlLXBhZ2UvbWFpbnRlbmFuY2UtcGFnZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25FLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV2RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbkUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDOztBQUdyRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFDRztBQStDSCxNQUFNLE9BQU8sd0JBQXdCO0lBOUNyQztRQStDRTs7V0FFRztRQUNNLFVBQUssR0FBNEIsRUFBRSxDQUFDO1FBRXJDLFNBQUksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFbkM7O1dBRUc7UUFDSCxVQUFLLEdBQUcsUUFBUSxDQUNkLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixFQUFFLFdBQVcsQ0FBQyxDQUN0RSxDQUFDO1FBRUY7O1dBRUc7UUFDSCxZQUFPLEdBQUcsUUFBUSxDQUNoQixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsRUFBRSxXQUFXLENBQUMsQ0FDM0UsQ0FBQztLQUNIOytHQXJCWSx3QkFBd0I7bUdBQXhCLHdCQUF3Qiw0R0ExQ3pCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Q1QsOHNCQXhDUyxZQUFZLCtCQUFFLFVBQVUsd0tBQUUsY0FBYzs7NEZBMkN2Qyx3QkFBd0I7a0JBOUNwQyxTQUFTOytCQUNFLHNCQUFzQixjQUNwQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLGNBQWMsQ0FBQyxZQUN6Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUNUOzhCQU9RLEtBQUs7c0JBQWIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTWFpbnRlbmFuY2VQYWdlQ29tcG9uZW50XG4gKlxuICogUMOhZ2luYSBkZSBtYW50ZW5pbWllbnRvIHF1ZSBzZSBtdWVzdHJhIGN1YW5kbyBsYSBhcGxpY2FjacOzbiBlc3TDoSBlbiBtb2RvIG1hbnRlbmltaWVudG8uXG4gKi9cblxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbXBvbmVudCwgY29tcHV0ZWQsIGluamVjdCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElvbkNvbnRlbnQgfSBmcm9tICdAaW9uaWMvYW5ndWxhci9zdGFuZGFsb25lJztcblxuaW1wb3J0IHsgSW1hZ2VDb21wb25lbnQgfSBmcm9tICcuLi8uLi9hdG9tcy9pbWFnZS9pbWFnZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgSTE4blNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9pMThuJztcbmltcG9ydCB7IE1haW50ZW5hbmNlUGFnZU1ldGFkYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogdmFsLW1haW50ZW5hbmNlLXBhZ2VcbiAqXG4gKiBQw6FnaW5hIGNvbXBsZXRhIGRlIG1hbnRlbmltaWVudG8gY29uIGltYWdlbiwgdMOtdHVsbyB5IG1lbnNhamUgcGVyc29uYWxpemFibGVzLlxuICogU2UgaW50ZWdyYSBjb24gaTE4biBwYXJhIHRleHRvcyBwb3IgZGVmZWN0byBlbiBtw7psdGlwbGVzIGlkaW9tYXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGh0bWxcbiAqIDwhLS0gVXNvIGLDoXNpY28gKHVzYSB0ZXh0b3MgcG9yIGRlZmVjdG8pIC0tPlxuICogPHZhbC1tYWludGVuYW5jZS1wYWdlIC8+XG4gKlxuICogPCEtLSBQZXJzb25hbGl6YWRvIC0tPlxuICogPHZhbC1tYWludGVuYW5jZS1wYWdlXG4gKiAgIFtwcm9wc109XCJ7XG4gKiAgICAgdGl0bGU6ICdFbiBtYW50ZW5pbWllbnRvJyxcbiAqICAgICBtZXNzYWdlOiAnVm9sdmVtb3MgcHJvbnRvJyxcbiAqICAgICBpbWFnZTogJ2Fzc2V0cy9tYWludGVuYW5jZS5zdmcnXG4gKiAgIH1cIlxuICogLz5cbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBFbiBhcHAuY29tcG9uZW50LnRzXG4gKiBAQ29tcG9uZW50KHtcbiAqICAgdGVtcGxhdGU6IFxcYFxuICogICAgIEBpZiAoYXBwQ29uZmlnLmlzTWFpbnRlbmFuY2VNb2RlKCkpIHtcbiAqICAgICAgIDx2YWwtbWFpbnRlbmFuY2UtcGFnZSAvPlxuICogICAgIH0gQGVsc2Uge1xuICogICAgICAgPGlvbi1yb3V0ZXItb3V0bGV0IC8+XG4gKiAgICAgfVxuICogICBcXGBcbiAqIH0pXG4gKiBleHBvcnQgY2xhc3MgQXBwQ29tcG9uZW50IHtcbiAqICAgYXBwQ29uZmlnID0gaW5qZWN0KEFwcENvbmZpZ1NlcnZpY2UpO1xuICogfVxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZhbC1tYWludGVuYW5jZS1wYWdlJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgSW9uQ29udGVudCwgSW1hZ2VDb21wb25lbnRdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxpb24tY29udGVudCBjbGFzcz1cIm1haW50ZW5hbmNlLWNvbnRlbnRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJtYWludGVuYW5jZS1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1haW50ZW5hbmNlLWljb25cIj5cbiAgICAgICAgICBAaWYgKHByb3BzLmltYWdlKSB7XG4gICAgICAgICAgICA8dmFsLWltYWdlXG4gICAgICAgICAgICAgIFtwcm9wc109XCJ7XG4gICAgICAgICAgICAgICAgc3JjOiBwcm9wcy5pbWFnZSxcbiAgICAgICAgICAgICAgICBhbHQ6ICdNYWludGVuYW5jZScsXG4gICAgICAgICAgICAgICAgbW9kZTogJ2JveCcsXG4gICAgICAgICAgICAgICAgc2l6ZTogJ2xhcmdlJyxcbiAgICAgICAgICAgICAgICBzaGFkZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGJvcmRlcmVkOiBmYWxzZVxuICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVmYXVsdC1pY29uXCI+XG4gICAgICAgICAgICAgIDxzdmdcbiAgICAgICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcbiAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDI0IDI0XCJcbiAgICAgICAgICAgICAgICBmaWxsPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICBkPVwiTTEyIDZ2Nmw0IDJtNi0yYTEwIDEwIDAgMTEtMjAgMCAxMCAxMCAwIDAxMjAgMHpcIlxuICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiY3VycmVudENvbG9yXCJcbiAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjJcIlxuICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxoMSBjbGFzcz1cIm1haW50ZW5hbmNlLXRpdGxlXCI+e3sgdGl0bGUoKSB9fTwvaDE+XG4gICAgICAgIDxwIGNsYXNzPVwibWFpbnRlbmFuY2UtbWVzc2FnZVwiPnt7IG1lc3NhZ2UoKSB9fTwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvaW9uLWNvbnRlbnQ+XG4gIGAsXG4gIHN0eWxlVXJsczogWycuL21haW50ZW5hbmNlLXBhZ2UuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgTWFpbnRlbmFuY2VQYWdlQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIENvbmZpZ3VyYWNpw7NuIGRlIGxhIHDDoWdpbmEgZGUgbWFudGVuaW1pZW50by5cbiAgICovXG4gIEBJbnB1dCgpIHByb3BzOiBNYWludGVuYW5jZVBhZ2VNZXRhZGF0YSA9IHt9O1xuXG4gIHByaXZhdGUgaTE4biA9IGluamVjdChJMThuU2VydmljZSk7XG5cbiAgLyoqXG4gICAqIFTDrXR1bG8gZGUgbGEgcMOhZ2luYSAocmVhY3Rpdm8gYSBjYW1iaW9zIGRlIGlkaW9tYSkuXG4gICAqL1xuICB0aXRsZSA9IGNvbXB1dGVkKFxuICAgICgpID0+IHRoaXMucHJvcHMudGl0bGUgfHwgdGhpcy5pMThuLnQoJ21haW50ZW5hbmNlTW9kZScsICdBcHBDb25maWcnKVxuICApO1xuXG4gIC8qKlxuICAgKiBNZW5zYWplIGRlIGxhIHDDoWdpbmEgKHJlYWN0aXZvIGEgY2FtYmlvcyBkZSBpZGlvbWEpLlxuICAgKi9cbiAgbWVzc2FnZSA9IGNvbXB1dGVkKFxuICAgICgpID0+IHRoaXMucHJvcHMubWVzc2FnZSB8fCB0aGlzLmkxOG4udCgnbWFpbnRlbmFuY2VNZXNzYWdlJywgJ0FwcENvbmZpZycpXG4gICk7XG59XG4iXX0=
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvdGVtcGxhdGVzL21haW50ZW5hbmNlLXBhZ2UvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUHJvcHMgcGFyYSB2YWwtbWFpbnRlbmFuY2UtcGFnZSBjb21wb25lbnQuXG4gKlxuICogQHByb3BlcnR5IHRpdGxlIC0gVMOtdHVsbyBwZXJzb25hbGl6YWRvIChvcGNpb25hbCwgdXNhIGkxOG4gcG9yIGRlZmVjdG8pXG4gKiBAcHJvcGVydHkgbWVzc2FnZSAtIE1lbnNhamUgcGVyc29uYWxpemFkbyAob3BjaW9uYWwsIHVzYSBpMThuIHBvciBkZWZlY3RvKVxuICogQHByb3BlcnR5IGltYWdlIC0gUnV0YSBhIGltYWdlbiBwZXJzb25hbGl6YWRhIChvcGNpb25hbClcbiAqL1xuZXhwb3J0IHR5cGUgTWFpbnRlbmFuY2VQYWdlTWV0YWRhdGEgPSB7XG4gIHRpdGxlPzogc3RyaW5nO1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICBpbWFnZT86IHN0cmluZztcbn07XG4iXX0=
@@ -1,7 +1,9 @@
1
1
  import { CommonModule } from '@angular/common';
2
- import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
3
3
  import { IonContent } from '@ionic/angular/standalone';
4
4
  import { HeaderComponent } from '../../organisms/header/header.component';
5
+ import { UpdateBannerComponent } from '../../molecules/update-banner/update-banner.component';
6
+ import { VALTECH_APP_CONFIG } from '../../../services/app-config/config';
5
7
  import { resolveColor } from '../../../shared/utils/styles';
6
8
  import * as i0 from "@angular/core";
7
9
  import * as i1 from "../../../services/theme.service";
@@ -41,6 +43,7 @@ export class PageContentComponent {
41
43
  * Page content configuration.
42
44
  */
43
45
  this.props = {};
46
+ this.appConfigEnabled = inject(VALTECH_APP_CONFIG, { optional: true });
44
47
  /**
45
48
  * Emits when a header action is clicked.
46
49
  */
@@ -80,6 +83,13 @@ export class PageContentComponent {
80
83
  },
81
84
  };
82
85
  }
86
+ /**
87
+ * Whether to show the update banner.
88
+ * Only shows if AppConfigService is configured and not disabled via props.
89
+ */
90
+ get showUpdateBanner() {
91
+ return this.appConfigEnabled !== null && this.props.showUpdateBanner !== false;
92
+ }
83
93
  /**
84
94
  * Gets header props, using cached default if not provided.
85
95
  * Injects languageSelector into toolbar when provided at page level.
@@ -122,7 +132,7 @@ export class PageContentComponent {
122
132
  }
123
133
  }
124
134
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PageContentComponent, deps: [{ token: i1.ThemeService }, { token: i2.NavigationService }], target: i0.ɵɵFactoryTarget.Component }); }
125
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PageContentComponent, isStandalone: true, selector: "val-page-content", inputs: { props: "props" }, outputs: { onHeaderClick: "onHeaderClick" }, ngImport: i0, template: `
135
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PageContentComponent, isStandalone: true, selector: "val-page-content", inputs: { props: "props" }, outputs: { onHeaderClick: "onHeaderClick" }, ngImport: i0, template: `
126
136
  <div class="ion-page">
127
137
  <val-header
128
138
  [props]="headerProps"
@@ -134,6 +144,9 @@ export class PageContentComponent {
134
144
  '--background': getBackground()
135
145
  }"
136
146
  >
147
+ @if (showUpdateBanner) {
148
+ <val-update-banner />
149
+ }
137
150
  <div class="page-wrapper">
138
151
  <main>
139
152
  <ng-content select="[content]"></ng-content>
@@ -143,11 +156,11 @@ export class PageContentComponent {
143
156
  </ion-content>
144
157
  <ng-content select="[extra-footer]"></ng-content>
145
158
  </div>
146
- `, isInline: true, styles: [".page-wrapper{display:flex;flex-direction:column;min-height:100%}main{flex:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: HeaderComponent, selector: "val-header", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }] }); }
159
+ `, isInline: true, styles: [".page-wrapper{display:flex;flex-direction:column;min-height:100%}main{flex:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: HeaderComponent, selector: "val-header", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: UpdateBannerComponent, selector: "val-update-banner" }] }); }
147
160
  }
148
161
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PageContentComponent, decorators: [{
149
162
  type: Component,
150
- args: [{ selector: 'val-page-content', standalone: true, imports: [CommonModule, HeaderComponent, IonContent], template: `
163
+ args: [{ selector: 'val-page-content', standalone: true, imports: [CommonModule, HeaderComponent, IonContent, UpdateBannerComponent], template: `
151
164
  <div class="ion-page">
152
165
  <val-header
153
166
  [props]="headerProps"
@@ -159,6 +172,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
159
172
  '--background': getBackground()
160
173
  }"
161
174
  >
175
+ @if (showUpdateBanner) {
176
+ <val-update-banner />
177
+ }
162
178
  <div class="page-wrapper">
163
179
  <main>
164
180
  <ng-content select="[content]"></ng-content>
@@ -174,4 +190,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
174
190
  }], onHeaderClick: [{
175
191
  type: Output
176
192
  }] } });
177
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZS1jb250ZW50LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy90ZW1wbGF0ZXMvcGFnZS1jb250ZW50L3BhZ2UtY29udGVudC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUkxRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sOEJBQThCLENBQUM7Ozs7O0FBRTVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBdUNILE1BQU0sT0FBTyxvQkFBb0I7SUFNL0IsWUFDVSxLQUFtQixFQUNuQixHQUFzQjtRQUR0QixVQUFLLEdBQUwsS0FBSyxDQUFjO1FBQ25CLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBUGhDOztXQUVHO1FBQ00sVUFBSyxHQUF3QixFQUFFLENBQUM7UUFPekM7O1dBRUc7UUFDTyxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFFckQ7O1dBRUc7UUFDYyxrQkFBYSxHQUFHO1lBQy9CLFFBQVEsRUFBRSxJQUFJO1lBQ2QsV0FBVyxFQUFFLElBQUk7WUFDakIsT0FBTyxFQUFFO2dCQUNQLFFBQVEsRUFBRSxLQUFLO2dCQUNmLFdBQVcsRUFBRSxJQUFJO2dCQUNqQixTQUFTLEVBQUUsTUFBZTtnQkFDMUIsUUFBUSxFQUFFLElBQUk7Z0JBQ2QsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsZ0JBQWdCLEVBQUUsU0FBc0I7Z0JBQ3hDLE9BQU8sRUFBRTtvQkFDUDt3QkFDRSxLQUFLLEVBQUUsYUFBYTt3QkFDcEIsV0FBVyxFQUFFLEVBQUU7d0JBQ2YsUUFBUSxFQUFFLE1BQWU7d0JBQ3pCLElBQUksRUFBRSxPQUFnQjt3QkFDdEIsS0FBSyxFQUFFOzRCQUNMLEtBQUssRUFBRSxFQUFFOzRCQUNULEdBQUcsRUFBRSxhQUFhOzRCQUNsQixHQUFHLEVBQUUsYUFBYTs0QkFDbEIsSUFBSSxFQUFFLEtBQWM7NEJBQ3BCLE1BQU0sRUFBRSxLQUFLOzRCQUNiLFFBQVEsRUFBRSxLQUFLOzRCQUNmLElBQUksRUFBRSxPQUFnQjs0QkFDdEIsT0FBTyxFQUFFLEtBQUs7NEJBQ2QsSUFBSSxFQUFFLElBQUk7eUJBQ1g7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUM7SUF4Q0MsQ0FBQztJQTBDSjs7O09BR0c7SUFDSCxJQUFJLFdBQVc7UUFDYixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDO1FBRXZELGlFQUFpRTtRQUNqRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDcEUsT0FBTztnQkFDTCxHQUFHLE1BQU07Z0JBQ1QsT0FBTyxFQUFFO29CQUNQLEdBQUcsTUFBTSxDQUFDLE9BQU87b0JBQ2pCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCO2lCQUM5QzthQUNGLENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYTtRQUNYLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN0QixPQUFPLDZCQUE2QixDQUFDO1FBQ3ZDLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUNqQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDUixPQUFPLDZCQUE2QixDQUFDO1FBQ3ZDLENBQUM7UUFFRCxPQUFPLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxvQkFBb0IsQ0FBQyxLQUFhO1FBQ2hDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRS9CLDREQUE0RDtRQUM1RCxJQUFJLEtBQUssS0FBSyxhQUFhLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNwRCxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9DLENBQUM7SUFDSCxDQUFDOytHQWxHVSxvQkFBb0I7bUdBQXBCLG9CQUFvQixxSkFsQ3JCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQlQsd0pBdEJTLFlBQVksb0hBQUUsZUFBZSxnR0FBRSxVQUFVOzs0RkFtQ3hDLG9CQUFvQjtrQkF0Q2hDLFNBQVM7K0JBQ0Usa0JBQWtCLGNBQ2hCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxlQUFlLEVBQUUsVUFBVSxDQUFDLFlBQzFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQlQ7aUhBaUJRLEtBQUs7c0JBQWIsS0FBSztnQkFVSSxhQUFhO3NCQUF0QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJb25Db250ZW50IH0gZnJvbSAnQGlvbmljL2FuZ3VsYXIvc3RhbmRhbG9uZSc7XG5pbXBvcnQgeyBIZWFkZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9vcmdhbmlzbXMvaGVhZGVyL2hlYWRlci5jb21wb25lbnQnO1xuaW1wb3J0IHsgVGhlbWVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvdGhlbWUuc2VydmljZSc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL25hdmlnYXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBQYWdlQ29udGVudE1ldGFkYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyByZXNvbHZlQ29sb3IgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvdXRpbHMvc3R5bGVzJztcblxuLyoqXG4gKiB2YWwtcGFnZS1jb250ZW50XG4gKlxuICogQSBwYWdlIGNvbnRlbnQgdGVtcGxhdGUgd2l0aCBjb3Jwb3JhdGUgaGVhZGVyLCBtYWluIGNvbnRlbnQgYXJlYSxcbiAqIGFuZCBmb290ZXIgc2xvdHMuIFN1cHBvcnRzIGRhcmsgbW9kZSBhbmQgY3VzdG9taXphYmxlIGJhY2tncm91bmRzLlxuICpcbiAqIEBleGFtcGxlXG4gKiA8dmFsLXBhZ2UtY29udGVudFxuICogICBbcHJvcHNdPVwie1xuICogICAgIGhlYWRlcjogeyAuLi4gfSxcbiAqICAgICBiYWNrZ3JvdW5kOiAnLS1tYWluLWJhY2tncm91bmQnLFxuICogICAgIGhvbWVSb3V0ZTogJy8nXG4gKiAgIH1cIlxuICogICAob25IZWFkZXJDbGljayk9XCJoYW5kbGVIZWFkZXJBY3Rpb24oJGV2ZW50KVwiXG4gKiA+XG4gKiAgIDxkaXYgY29udGVudD5cbiAqICAgICA8IS0tIE1haW4gcGFnZSBjb250ZW50IC0tPlxuICogICA8L2Rpdj5cbiAqICAgPGRpdiBmb290ZXI+XG4gKiAgICAgPHZhbC1jb21wYW55LWZvb3RlciBbcHJvcHNdPVwiZm9vdGVyUHJvcHNcIj48L3ZhbC1jb21wYW55LWZvb3Rlcj5cbiAqICAgPC9kaXY+XG4gKiA8L3ZhbC1wYWdlLWNvbnRlbnQ+XG4gKlxuICogQGlucHV0IHByb3BzIC0gUGFnZSBjb250ZW50IGNvbmZpZ3VyYXRpb25cbiAqIEBvdXRwdXQgb25IZWFkZXJDbGljayAtIEVtaXRzIHdoZW4gYSBoZWFkZXIgYWN0aW9uIGlzIGNsaWNrZWRcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndmFsLXBhZ2UtY29udGVudCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEhlYWRlckNvbXBvbmVudCwgSW9uQ29udGVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImlvbi1wYWdlXCI+XG4gICAgICA8dmFsLWhlYWRlclxuICAgICAgICBbcHJvcHNdPVwiaGVhZGVyUHJvcHNcIlxuICAgICAgICAob25DbGljayk9XCJvbkhlYWRlckNsaWNrSGFuZGxlcigkZXZlbnQpXCJcbiAgICAgIC8+XG4gICAgICA8aW9uLWNvbnRlbnRcbiAgICAgICAgW2Z1bGxzY3JlZW5dPVwidHJ1ZVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAnLS1iYWNrZ3JvdW5kJzogZ2V0QmFja2dyb3VuZCgpXG4gICAgICAgIH1cIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicGFnZS13cmFwcGVyXCI+XG4gICAgICAgICAgPG1haW4+XG4gICAgICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbY29udGVudF1cIj48L25nLWNvbnRlbnQ+XG4gICAgICAgICAgPC9tYWluPlxuICAgICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltmb290ZXJdXCI+PC9uZy1jb250ZW50PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvaW9uLWNvbnRlbnQ+XG4gICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbZXh0cmEtZm9vdGVyXVwiPjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBgXG4gICAgLnBhZ2Utd3JhcHBlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIG1pbi1oZWlnaHQ6IDEwMCU7XG4gICAgfVxuXG4gICAgbWFpbiB7XG4gICAgICBmbGV4OiAxO1xuICAgIH1cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgUGFnZUNvbnRlbnRDb21wb25lbnQge1xuICAvKipcbiAgICogUGFnZSBjb250ZW50IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBASW5wdXQoKSBwcm9wczogUGFnZUNvbnRlbnRNZXRhZGF0YSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdGhlbWU6IFRoZW1lU2VydmljZSxcbiAgICBwcml2YXRlIG5hdjogTmF2aWdhdGlvblNlcnZpY2VcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBFbWl0cyB3aGVuIGEgaGVhZGVyIGFjdGlvbiBpcyBjbGlja2VkLlxuICAgKi9cbiAgQE91dHB1dCgpIG9uSGVhZGVyQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAvKipcbiAgICogRGVmYXVsdCBoZWFkZXIgY29uZmlndXJhdGlvbiAoY2FjaGVkIHRvIGF2b2lkIGluZmluaXRlIGNoYW5nZSBkZXRlY3Rpb24pLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0SGVhZGVyID0ge1xuICAgIGJvcmRlcmVkOiB0cnVlLFxuICAgIHRyYW5zbHVjZW50OiB0cnVlLFxuICAgIHRvb2xiYXI6IHtcbiAgICAgIHdpdGhCYWNrOiBmYWxzZSxcbiAgICAgIHdpdGhBY3Rpb25zOiB0cnVlLFxuICAgICAgdGV4dENvbG9yOiAnZGFyaycgYXMgY29uc3QsXG4gICAgICB3aXRoTWVudTogdHJ1ZSxcbiAgICAgIHRpdGxlOiAnJyxcbiAgICAgIGxhbmd1YWdlU2VsZWN0b3I6IHVuZGVmaW5lZCBhcyB1bmRlZmluZWQsXG4gICAgICBhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0b2tlbjogJ2hlYWRlci1sb2dvJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJycsXG4gICAgICAgICAgcG9zaXRpb246ICdsZWZ0JyBhcyBjb25zdCxcbiAgICAgICAgICB0eXBlOiAnSU1BR0UnIGFzIGNvbnN0LFxuICAgICAgICAgIGltYWdlOiB7XG4gICAgICAgICAgICB3aWR0aDogMTAsXG4gICAgICAgICAgICBzcmM6ICctLW1haW4tbG9nbycsXG4gICAgICAgICAgICBhbHQ6ICdoZWFkZXIgbG9nbycsXG4gICAgICAgICAgICBtb2RlOiAnYm94JyBhcyBjb25zdCxcbiAgICAgICAgICAgIHNoYWRlZDogZmFsc2UsXG4gICAgICAgICAgICBib3JkZXJlZDogZmFsc2UsXG4gICAgICAgICAgICBzaXplOiAnc21hbGwnIGFzIGNvbnN0LFxuICAgICAgICAgICAgbGltaXRlZDogZmFsc2UsXG4gICAgICAgICAgICBmbGV4OiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0sXG4gIH07XG5cbiAgLyoqXG4gICAqIEdldHMgaGVhZGVyIHByb3BzLCB1c2luZyBjYWNoZWQgZGVmYXVsdCBpZiBub3QgcHJvdmlkZWQuXG4gICAqIEluamVjdHMgbGFuZ3VhZ2VTZWxlY3RvciBpbnRvIHRvb2xiYXIgd2hlbiBwcm92aWRlZCBhdCBwYWdlIGxldmVsLlxuICAgKi9cbiAgZ2V0IGhlYWRlclByb3BzKCkge1xuICAgIGNvbnN0IGhlYWRlciA9IHRoaXMucHJvcHMuaGVhZGVyIHx8IHRoaXMuZGVmYXVsdEhlYWRlcjtcblxuICAgIC8vIEluamVjdCBsYW5ndWFnZVNlbGVjdG9yIGludG8gdG9vbGJhciBpZiBwcm92aWRlZCBhdCBwYWdlIGxldmVsXG4gICAgaWYgKHRoaXMucHJvcHMubGFuZ3VhZ2VTZWxlY3RvciAmJiAhaGVhZGVyLnRvb2xiYXIubGFuZ3VhZ2VTZWxlY3Rvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uaGVhZGVyLFxuICAgICAgICB0b29sYmFyOiB7XG4gICAgICAgICAgLi4uaGVhZGVyLnRvb2xiYXIsXG4gICAgICAgICAgbGFuZ3VhZ2VTZWxlY3RvcjogdGhpcy5wcm9wcy5sYW5ndWFnZVNlbGVjdG9yLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gaGVhZGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGJhY2tncm91bmQgY29sb3IgYmFzZWQgb24gdGhlbWUuXG4gICAqL1xuICBnZXRCYWNrZ3JvdW5kKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMudGhlbWUuSXNEYXJrKSB7XG4gICAgICByZXR1cm4gJ3ZhcigtLWlvbi1iYWNrZ3JvdW5kLWNvbG9yKSc7XG4gICAgfVxuXG4gICAgY29uc3QgYmcgPSB0aGlzLnByb3BzLmJhY2tncm91bmQ7XG4gICAgaWYgKCFiZykge1xuICAgICAgcmV0dXJuICd2YXIoLS1pb24tYmFja2dyb3VuZC1jb2xvciknO1xuICAgIH1cblxuICAgIHJldHVybiByZXNvbHZlQ29sb3IoYmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZXMgaGVhZGVyIGFjdGlvbiBjbGlja3MuXG4gICAqL1xuICBvbkhlYWRlckNsaWNrSGFuZGxlcih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5vbkhlYWRlckNsaWNrLmVtaXQodG9rZW4pO1xuXG4gICAgLy8gTmF2aWdhdGUgdG8gaG9tZSByb3V0ZSBpZiBjb25maWd1cmVkIGFuZCBsb2dvIHdhcyBjbGlja2VkXG4gICAgaWYgKHRva2VuID09PSAnaGVhZGVyLWxvZ28nICYmIHRoaXMucHJvcHMuaG9tZVJvdXRlKSB7XG4gICAgICB0aGlzLm5hdi5uYXZpZ2F0ZUJ5VXJsKHRoaXMucHJvcHMuaG9tZVJvdXRlKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
193
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZS1jb250ZW50LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy90ZW1wbGF0ZXMvcGFnZS1jb250ZW50L3BhZ2UtY29udGVudC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdURBQXVELENBQUM7QUFHOUYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFFekUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7OztBQUU1RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQTBDSCxNQUFNLE9BQU8sb0JBQW9CO0lBUS9CLFlBQ1UsS0FBbUIsRUFDbkIsR0FBc0I7UUFEdEIsVUFBSyxHQUFMLEtBQUssQ0FBYztRQUNuQixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQVRoQzs7V0FFRztRQUNNLFVBQUssR0FBd0IsRUFBRSxDQUFDO1FBRWpDLHFCQUFnQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBZTFFOztXQUVHO1FBQ08sa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRXJEOztXQUVHO1FBQ2Msa0JBQWEsR0FBRztZQUMvQixRQUFRLEVBQUUsSUFBSTtZQUNkLFdBQVcsRUFB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QUs7Z0JBb0JJLGFBQWE7c0JBQXRCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIGluamVjdCwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSW9uQ29udGVudCB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyL3N0YW5kYWxvbmUnO1xuaW1wb3J0IHsgSGVhZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vb3JnYW5pc21zL2hlYWRlci9oZWFkZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFVwZGF0ZUJhbm5lckNvbXBvbmVudCB9IGZyb20gJy4uLy4uL21vbGVjdWxlcy91cGRhdGUtYmFubmVyL3VwZGF0ZS1iYW5uZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFRoZW1lU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3RoZW1lLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmF2aWdhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9uYXZpZ2F0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgVkFMVEVDSF9BUFBfQ09ORklHIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvYXBwLWNvbmZpZy9jb25maWcnO1xuaW1wb3J0IHsgUGFnZUNvbnRlbnRNZXRhZGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgcmVzb2x2ZUNvbG9yIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL3V0aWxzL3N0eWxlcyc7XG5cbi8qKlxuICogdmFsLXBhZ2UtY29udGVudFxuICpcbiAqIEEgcGFnZSBjb250ZW50IHRlbXBsYXRlIHdpdGggY29ycG9yYXRlIGhlYWRlciwgbWFpbiBjb250ZW50IGFyZWEsXG4gKiBhbmQgZm9vdGVyIHNsb3RzLiBTdXBwb3J0cyBkYXJrIG1vZGUgYW5kIGN1c3RvbWl6YWJsZSBiYWNrZ3JvdW5kcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogPHZhbC1wYWdlLWNvbnRlbnRcbiAqICAgW3Byb3BzXT1cIntcbiAqICAgICBoZWFkZXI6IHsgLi4uIH0sXG4gKiAgICAgYmFja2dyb3VuZDogJy0tbWFpbi1iYWNrZ3JvdW5kJyxcbiAqICAgICBob21lUm91dGU6ICcvJ1xuICogICB9XCJcbiAqICAgKG9uSGVhZGVyQ2xpY2spPVwiaGFuZGxlSGVhZGVyQWN0aW9uKCRldmVudClcIlxuICogPlxuICogICA8ZGl2IGNvbnRlbnQ+XG4gKiAgICAgPCEtLSBNYWluIHBhZ2UgY29udGVudCAtLT5cbiAqICAgPC9kaXY+XG4gKiAgIDxkaXYgZm9vdGVyPlxuICogICAgIDx2YWwtY29tcGFueS1mb290ZXIgW3Byb3BzXT1cImZvb3RlclByb3BzXCI+PC92YWwtY29tcGFueS1mb290ZXI+XG4gKiAgIDwvZGl2PlxuICogPC92YWwtcGFnZS1jb250ZW50PlxuICpcbiAqIEBpbnB1dCBwcm9wcyAtIFBhZ2UgY29udGVudCBjb25maWd1cmF0aW9uXG4gKiBAb3V0cHV0IG9uSGVhZGVyQ2xpY2sgLSBFbWl0cyB3aGVuIGEgaGVhZGVyIGFjdGlvbiBpcyBjbGlja2VkXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZhbC1wYWdlLWNvbnRlbnQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBIZWFkZXJDb21wb25lbnQsIElvbkNvbnRlbnQsIFVwZGF0ZUJhbm5lckNvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImlvbi1wYWdlXCI+XG4gICAgICA8dmFsLWhlYWRlclxuICAgICAgICBbcHJvcHNdPVwiaGVhZGVyUHJvcHNcIlxuICAgICAgICAob25DbGljayk9XCJvbkhlYWRlckNsaWNrSGFuZGxlcigkZXZlbnQpXCJcbiAgICAgIC8+XG4gICAgICA8aW9uLWNvbnRlbnRcbiAgICAgICAgW2Z1bGxzY3JlZW5dPVwidHJ1ZVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAnLS1iYWNrZ3JvdW5kJzogZ2V0QmFja2dyb3VuZCgpXG4gICAgICAgIH1cIlxuICAgICAgPlxuICAgICAgICBAaWYgKHNob3dVcGRhdGVCYW5uZXIpIHtcbiAgICAgICAgICA8dmFsLXVwZGF0ZS1iYW5uZXIgLz5cbiAgICAgICAgfVxuICAgICAgICA8ZGl2IGNsYXNzPVwicGFnZS13cmFwcGVyXCI+XG4gICAgICAgICAgPG1haW4+XG4gICAgICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbY29udGVudF1cIj48L25nLWNvbnRlbnQ+XG4gICAgICAgICAgPC9tYWluPlxuICAgICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltmb290ZXJdXCI+PC9uZy1jb250ZW50PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvaW9uLWNvbnRlbnQ+XG4gICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbZXh0cmEtZm9vdGVyXVwiPjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBgXG4gICAgLnBhZ2Utd3JhcHBlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIG1pbi1oZWlnaHQ6IDEwMCU7XG4gICAgfVxuXG4gICAgbWFpbiB7XG4gICAgICBmbGV4OiAxO1xuICAgIH1cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgUGFnZUNvbnRlbnRDb21wb25lbnQge1xuICAvKipcbiAgICogUGFnZSBjb250ZW50IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBASW5wdXQoKSBwcm9wczogUGFnZUNvbnRlbnRNZXRhZGF0YSA9IHt9O1xuXG4gIHByaXZhdGUgYXBwQ29uZmlnRW5hYmxlZCA9IGluamVjdChWQUxURUNIX0FQUF9DT05GSUcsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB0aGVtZTogVGhlbWVTZXJ2aWNlLFxuICAgIHByaXZhdGUgbmF2OiBOYXZpZ2F0aW9uU2VydmljZVxuICApIHt9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc2hvdyB0aGUgdXBkYXRlIGJhbm5lci5cbiAgICogT25seSBzaG93cyBpZiBBcHBDb25maWdTZXJ2aWNlIGlzIGNvbmZpZ3VyZWQgYW5kIG5vdCBkaXNhYmxlZCB2aWEgcHJvcHMuXG4gICAqL1xuICBnZXQgc2hvd1VwZGF0ZUJhbm5lcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5hcHBDb25maWdFbmFibGVkICE9PSBudWxsICYmIHRoaXMucHJvcHMuc2hvd1VwZGF0ZUJhbm5lciAhPT0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgd2hlbiBhIGhlYWRlciBhY3Rpb24gaXMgY2xpY2tlZC5cbiAgICovXG4gIEBPdXRwdXQoKSBvbkhlYWRlckNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgaGVhZGVyIGNvbmZpZ3VyYXRpb24gKGNhY2hlZCB0byBhdm9pZCBpbmZpbml0ZSBjaGFuZ2UgZGV0ZWN0aW9uKS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdEhlYWRlciA9IHtcbiAgICBib3JkZXJlZDogdHJ1ZSxcbiAgICB0cmFuc2x1Y2VudDogdHJ1ZSxcbiAgICB0b29sYmFyOiB7XG4gICAgICB3aXRoQmFjazogZmFsc2UsXG4gICAgICB3aXRoQWN0aW9uczogdHJ1ZSxcbiAgICAgIHRleHRDb2xvcjogJ2RhcmsnIGFzIGNvbnN0LFxuICAgICAgd2l0aE1lbnU6IHRydWUsXG4gICAgICB0aXRsZTogJycsXG4gICAgICBsYW5ndWFnZVNlbGVjdG9yOiB1bmRlZmluZWQgYXMgdW5kZWZpbmVkLFxuICAgICAgYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgdG9rZW46ICdoZWFkZXItbG9nbycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICcnLFxuICAgICAgICAgIHBvc2l0aW9uOiAnbGVmdCcgYXMgY29uc3QsXG4gICAgICAgICAgdHlwZTogJ0lNQUdFJyBhcyBjb25zdCxcbiAgICAgICAgICBpbWFnZToge1xuICAgICAgICAgICAgd2lkdGg6IDEwLFxuICAgICAgICAgICAgc3JjOiAnLS1tYWluLWxvZ28nLFxuICAgICAgICAgICAgYWx0OiAnaGVhZGVyIGxvZ28nLFxuICAgICAgICAgICAgbW9kZTogJ2JveCcgYXMgY29uc3QsXG4gICAgICAgICAgICBzaGFkZWQ6IGZhbHNlLFxuICAgICAgICAgICAgYm9yZGVyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgc2l6ZTogJ3NtYWxsJyBhcyBjb25zdCxcbiAgICAgICAgICAgIGxpbWl0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgZmxleDogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9LFxuICB9O1xuXG4gIC8qKlxuICAgKiBHZXRzIGhlYWRlciBwcm9wcywgdXNpbmcgY2FjaGVkIGRlZmF1bHQgaWYgbm90IHByb3ZpZGVkLlxuICAgKiBJbmplY3RzIGxhbmd1YWdlU2VsZWN0b3IgaW50byB0b29sYmFyIHdoZW4gcHJvdmlkZWQgYXQgcGFnZSBsZXZlbC5cbiAgICovXG4gIGdldCBoZWFkZXJQcm9wcygpIHtcbiAgICBjb25zdCBoZWFkZXIgPSB0aGlzLnByb3BzLmhlYWRlciB8fCB0aGlzLmRlZmF1bHRIZWFkZXI7XG5cbiAgICAvLyBJbmplY3QgbGFuZ3VhZ2VTZWxlY3RvciBpbnRvIHRvb2xiYXIgaWYgcHJvdmlkZWQgYXQgcGFnZSBsZXZlbFxuICAgIGlmICh0aGlzLnByb3BzLmxhbmd1YWdlU2VsZWN0b3IgJiYgIWhlYWRlci50b29sYmFyLmxhbmd1YWdlU2VsZWN0b3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmhlYWRlcixcbiAgICAgICAgdG9vbGJhcjoge1xuICAgICAgICAgIC4uLmhlYWRlci50b29sYmFyLFxuICAgICAgICAgIGxhbmd1YWdlU2VsZWN0b3I6IHRoaXMucHJvcHMubGFuZ3VhZ2VTZWxlY3RvcixcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGhlYWRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBiYWNrZ3JvdW5kIGNvbG9yIGJhc2VkIG9uIHRoZW1lLlxuICAgKi9cbiAgZ2V0QmFja2dyb3VuZCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnRoZW1lLklzRGFyaykge1xuICAgICAgcmV0dXJuICd2YXIoLS1pb24tYmFja2dyb3VuZC1jb2xvciknO1xuICAgIH1cblxuICAgIGNvbnN0IGJnID0gdGhpcy5wcm9wcy5iYWNrZ3JvdW5kO1xuICAgIGlmICghYmcpIHtcbiAgICAgIHJldHVybiAndmFyKC0taW9uLWJhY2tncm91bmQtY29sb3IpJztcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZUNvbG9yKGJnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIGhlYWRlciBhY3Rpb24gY2xpY2tzLlxuICAgKi9cbiAgb25IZWFkZXJDbGlja0hhbmRsZXIodG9rZW46IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMub25IZWFkZXJDbGljay5lbWl0KHRva2VuKTtcblxuICAgIC8vIE5hdmlnYXRlIHRvIGhvbWUgcm91dGUgaWYgY29uZmlndXJlZCBhbmQgbG9nbyB3YXMgY2xpY2tlZFxuICAgIGlmICh0b2tlbiA9PT0gJ2hlYWRlci1sb2dvJyAmJiB0aGlzLnByb3BzLmhvbWVSb3V0ZSkge1xuICAgICAgdGhpcy5uYXYubmF2aWdhdGVCeVVybCh0aGlzLnByb3BzLmhvbWVSb3V0ZSk7XG4gICAgfVxuICB9XG59XG4iXX0=
@@ -1,2 +1,2 @@
1
1
  export {};
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvdGVtcGxhdGVzL3BhZ2UtY29udGVudC90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSGVhZGVyTWV0YWRhdGEgfSBmcm9tICcuLi8uLi9vcmdhbmlzbXMvaGVhZGVyL3R5cGVzJztcbmltcG9ydCB7IExhbmd1YWdlU2VsZWN0b3JNZXRhZGF0YSB9IGZyb20gJy4uLy4uL21vbGVjdWxlcy9sYW5ndWFnZS1zZWxlY3Rvci90eXBlcyc7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIHBhZ2UgY29udGVudCBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZUNvbnRlbnRNZXRhZGF0YSB7XG4gIC8qKiBIZWFkZXIgY29uZmlndXJhdGlvbiAqL1xuICBoZWFkZXI/OiBIZWFkZXJNZXRhZGF0YTtcbiAgLyoqIEJhY2tncm91bmQgY29sb3Igb3IgQ1NTIHZhcmlhYmxlICovXG4gIGJhY2tncm91bmQ/OiBzdHJpbmc7XG4gIC8qKiBCYWNrZ3JvdW5kIGNvbG9yIGZvciBkYXJrIG1vZGUgKi9cbiAgYmFja2dyb3VuZERhcms/OiBzdHJpbmc7XG4gIC8qKiBSb3V0ZSB0byBuYXZpZ2F0ZSB0byB3aGVuIGhlYWRlciBsb2dvIGlzIGNsaWNrZWQgKi9cbiAgaG9tZVJvdXRlPzogc3RyaW5nO1xuICAvKipcbiAgICogTGFuZ3VhZ2Ugc2VsZWN0b3IgY29uZmlndXJhdGlvbi5cbiAgICogV2hlbiBwcm92aWRlZCwgZGlzcGxheXMgYSBsYW5ndWFnZSBzZWxlY3RvciBpY29uIGluIHRoZSBoZWFkZXIgKGxlZnQgb2YgbWVudSBidXR0b24pLlxuICAgKiBVc2VzICdpY29uJyBtb2RlIGJ5IGRlZmF1bHQgZm9yIGNvbXBhY3QgZGlzcGxheS5cbiAgICovXG4gIGxhbmd1YWdlU2VsZWN0b3I/OiBMYW5ndWFnZVNlbGVjdG9yTWV0YWRhdGE7XG59XG4iXX0=
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvdGVtcGxhdGVzL3BhZ2UtY29udGVudC90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSGVhZGVyTWV0YWRhdGEgfSBmcm9tICcuLi8uLi9vcmdhbmlzbXMvaGVhZGVyL3R5cGVzJztcbmltcG9ydCB7IExhbmd1YWdlU2VsZWN0b3JNZXRhZGF0YSB9IGZyb20gJy4uLy4uL21vbGVjdWxlcy9sYW5ndWFnZS1zZWxlY3Rvci90eXBlcyc7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIHBhZ2UgY29udGVudCBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZUNvbnRlbnRNZXRhZGF0YSB7XG4gIC8qKiBIZWFkZXIgY29uZmlndXJhdGlvbiAqL1xuICBoZWFkZXI/OiBIZWFkZXJNZXRhZGF0YTtcbiAgLyoqIEJhY2tncm91bmQgY29sb3Igb3IgQ1NTIHZhcmlhYmxlICovXG4gIGJhY2tncm91bmQ/OiBzdHJpbmc7XG4gIC8qKiBCYWNrZ3JvdW5kIGNvbG9yIGZvciBkYXJrIG1vZGUgKi9cbiAgYmFja2dyb3VuZERhcms/OiBzdHJpbmc7XG4gIC8qKiBSb3V0ZSB0byBuYXZpZ2F0ZSB0byB3aGVuIGhlYWRlciBsb2dvIGlzIGNsaWNrZWQgKi9cbiAgaG9tZVJvdXRlPzogc3RyaW5nO1xuICAvKipcbiAgICogTGFuZ3VhZ2Ugc2VsZWN0b3IgY29uZmlndXJhdGlvbi5cbiAgICogV2hlbiBwcm92aWRlZCwgZGlzcGxheXMgYSBsYW5ndWFnZSBzZWxlY3RvciBpY29uIGluIHRoZSBoZWFkZXIgKGxlZnQgb2YgbWVudSBidXR0b24pLlxuICAgKiBVc2VzICdpY29uJyBtb2RlIGJ5IGRlZmF1bHQgZm9yIGNvbXBhY3QgZGlzcGxheS5cbiAgICovXG4gIGxhbmd1YWdlU2VsZWN0b3I/OiBMYW5ndWFnZVNlbGVjdG9yTWV0YWRhdGE7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHNob3cgdGhlIHVwZGF0ZSBiYW5uZXIgd2hlbiBhIG5ldyB2ZXJzaW9uIGlzIGF2YWlsYWJsZS5cbiAgICogUmVxdWlyZXMgQXBwQ29uZmlnU2VydmljZSB0byBiZSBjb25maWd1cmVkIHdpdGggcHJvdmlkZVZhbHRlY2hBcHBDb25maWcoKS5cbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgc2hvd1VwZGF0ZUJhbm5lcj86IGJvb2xlYW47XG59XG4iXX0=
@@ -0,0 +1,209 @@
1
+ /**
2
+ * AppConfigService
3
+ *
4
+ * Servicio para gestionar configuración remota de la aplicación desde Firestore.
5
+ * Soporta feature flags, variables dinámicas, y detección de actualizaciones.
6
+ */
7
+ import { computed, inject, Injectable, signal } from '@angular/core';
8
+ import { FirestoreService } from '../firebase/firestore.service';
9
+ import { VALTECH_APP_CONFIG } from './config';
10
+ import * as i0 from "@angular/core";
11
+ /**
12
+ * Servicio de configuración remota de la aplicación.
13
+ *
14
+ * Lee la configuración desde Firestore (apps/{appId}/config/app) y provee:
15
+ * - Feature flags reactivos
16
+ * - Variables dinámicas de configuración
17
+ * - Detección de nuevas versiones
18
+ * - Modo mantenimiento
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * @Component({...})
23
+ * export class MyComponent {
24
+ * private appConfig = inject(AppConfigService);
25
+ *
26
+ * // Verificar feature flag
27
+ * showNewFeature = computed(() =>
28
+ * this.appConfig.isFeatureEnabled('newDashboard')
29
+ * );
30
+ *
31
+ * // Obtener variable
32
+ * maxSize = this.appConfig.getVariable('maxUploadSize', 5242880);
33
+ * }
34
+ * ```
35
+ */
36
+ export class AppConfigService {
37
+ constructor() {
38
+ this.firestore = inject(FirestoreService);
39
+ this.serviceConfig = inject(VALTECH_APP_CONFIG, { optional: true });
40
+ this.subscription = null;
41
+ // =========================================================================
42
+ // SIGNALS REACTIVOS
43
+ // =========================================================================
44
+ /**
45
+ * Configuración actual de la aplicación.
46
+ * null si no se ha cargado o no está configurado.
47
+ */
48
+ this.appConfig = signal(null);
49
+ /**
50
+ * Indica si la configuración está cargando.
51
+ */
52
+ this.loading = signal(true);
53
+ /**
54
+ * Error de carga, si existe.
55
+ */
56
+ this.error = signal(null);
57
+ /**
58
+ * Indica si hay una nueva versión disponible.
59
+ */
60
+ this.hasUpdate = computed(() => {
61
+ const config = this.appConfig();
62
+ const currentVersion = this.serviceConfig?.currentVersion;
63
+ if (!config || !currentVersion)
64
+ return false;
65
+ return this.isNewerVersion(config.version, currentVersion);
66
+ });
67
+ /**
68
+ * Indica si la aplicación está en modo mantenimiento.
69
+ */
70
+ this.isMaintenanceMode = computed(() => this.appConfig()?.maintenance ?? false);
71
+ /**
72
+ * Versión remota de la aplicación.
73
+ */
74
+ this.remoteVersion = computed(() => this.appConfig()?.version ?? null);
75
+ /**
76
+ * Versión actual de la aplicación (local).
77
+ */
78
+ this.currentVersion = computed(() => this.serviceConfig?.currentVersion ?? '0.0.0');
79
+ }
80
+ // =========================================================================
81
+ // MÉTODOS PÚBLICOS
82
+ // =========================================================================
83
+ /**
84
+ * Inicializa el servicio y comienza a escuchar cambios en la configuración.
85
+ * Se llama automáticamente via APP_INITIALIZER si se usa provideValtechAppConfig().
86
+ */
87
+ initialize() {
88
+ if (!this.serviceConfig) {
89
+ console.warn('[AppConfigService] No configuration provided. Use provideValtechAppConfig() in main.ts');
90
+ this.loading.set(false);
91
+ return Promise.resolve();
92
+ }
93
+ return new Promise((resolve) => {
94
+ this.subscription = this.firestore
95
+ .docChanges('config', 'app')
96
+ .subscribe({
97
+ next: (config) => {
98
+ this.appConfig.set(config);
99
+ this.loading.set(false);
100
+ this.error.set(null);
101
+ resolve();
102
+ },
103
+ error: (err) => {
104
+ console.error('[AppConfigService] Error loading config:', err);
105
+ this.error.set(err.message || 'Error al cargar configuración');
106
+ this.loading.set(false);
107
+ resolve(); // Resolve anyway to not block app startup
108
+ },
109
+ });
110
+ });
111
+ }
112
+ /**
113
+ * Verifica si un feature flag está habilitado.
114
+ *
115
+ * @param feature - Nombre del feature flag
116
+ * @param defaultValue - Valor por defecto si no existe (default: false)
117
+ * @returns true si el feature está habilitado
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * if (appConfig.isFeatureEnabled('darkMode')) {
122
+ * // Mostrar toggle de dark mode
123
+ * }
124
+ * ```
125
+ */
126
+ isFeatureEnabled(feature, defaultValue = false) {
127
+ const config = this.appConfig();
128
+ if (!config?.features)
129
+ return defaultValue;
130
+ return config.features[feature] ?? defaultValue;
131
+ }
132
+ /**
133
+ * Obtiene una variable de configuración.
134
+ *
135
+ * @param key - Clave de la variable
136
+ * @param defaultValue - Valor por defecto si no existe
137
+ * @returns Valor de la variable o el valor por defecto
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const maxSize = appConfig.getVariable('maxUploadSize', 5242880);
142
+ * const supportEmail = appConfig.getVariable('supportEmail', 'support@example.com');
143
+ * ```
144
+ */
145
+ getVariable(key, defaultValue) {
146
+ const config = this.appConfig();
147
+ if (!config?.variables)
148
+ return defaultValue;
149
+ return config.variables[key] ?? defaultValue;
150
+ }
151
+ /**
152
+ * Recarga la configuración manualmente (one-time read).
153
+ * Útil si necesitas forzar una actualización.
154
+ */
155
+ async refresh() {
156
+ this.loading.set(true);
157
+ try {
158
+ const config = await this.firestore.getDoc('config', 'app');
159
+ this.appConfig.set(config);
160
+ this.error.set(null);
161
+ }
162
+ catch (err) {
163
+ const error = err;
164
+ console.error('[AppConfigService] Error refreshing config:', error);
165
+ this.error.set(error.message || 'Error al refrescar configuración');
166
+ }
167
+ finally {
168
+ this.loading.set(false);
169
+ }
170
+ }
171
+ /**
172
+ * Desuscribe del listener de Firestore.
173
+ * Se llama automáticamente cuando el servicio se destruye.
174
+ */
175
+ destroy() {
176
+ this.subscription?.unsubscribe();
177
+ this.subscription = null;
178
+ }
179
+ // =========================================================================
180
+ // MÉTODOS PRIVADOS
181
+ // =========================================================================
182
+ /**
183
+ * Compara dos versiones semver y retorna true si remote > current.
184
+ *
185
+ * @param remote - Versión remota (ej: "1.2.3")
186
+ * @param current - Versión actual (ej: "1.2.0")
187
+ * @returns true si remote es mayor que current
188
+ */
189
+ isNewerVersion(remote, current) {
190
+ const remoteParts = remote.split('.').map(Number);
191
+ const currentParts = current.split('.').map(Number);
192
+ for (let i = 0; i < Math.max(remoteParts.length, currentParts.length); i++) {
193
+ const remotePart = remoteParts[i] || 0;
194
+ const currentPart = currentParts[i] || 0;
195
+ if (remotePart > currentPart)
196
+ return true;
197
+ if (remotePart < currentPart)
198
+ return false;
199
+ }
200
+ return false;
201
+ }
202
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AppConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
203
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AppConfigService, providedIn: 'root' }); }
204
+ }
205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AppConfigService, decorators: [{
206
+ type: Injectable,
207
+ args: [{ providedIn: 'root' }]
208
+ }] });
209
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLWNvbmZpZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hcHAtY29uZmlnL2FwcC1jb25maWcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sVUFBVSxDQUFDOztBQUc5Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBRUgsTUFBTSxPQUFPLGdCQUFnQjtJQUQ3QjtRQUVVLGNBQVMsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNyQyxrQkFBYSxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRS9ELGlCQUFZLEdBQXdCLElBQUksQ0FBQztRQUVqRCw0RUFBNEU7UUFDNUUsb0JBQW9CO1FBQ3BCLDRFQUE0RTtRQUU1RTs7O1dBR0c7UUFDTSxjQUFTLEdBQUcsTUFBTSxDQUFtQixJQUFJLENBQUMsQ0FBQztRQUVwRDs7V0FFRztRQUNNLFlBQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFaEM7O1dBRUc7UUFDTSxVQUFLLEdBQUcsTUFBTSxDQUFnQixJQUFJLENBQUMsQ0FBQztRQUU3Qzs7V0FFRztRQUNNLGNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ2pDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNoQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLGNBQWMsQ0FBQztZQUUxRCxJQUFJLENB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Q0FBQyxNQUFNLENBQUMsQ0FBQztRQUVwRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzNFLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV6QyxJQUFJLFVBQVUsR0FBRyxXQUFXO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQzFDLElBQUksVUFBVSxHQUFHLFdBQVc7Z0JBQUUsT0FBTyxLQUFLLENBQUM7UUFDN0MsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQzsrR0ExTFUsZ0JBQWdCO21IQUFoQixnQkFBZ0IsY0FESCxNQUFNOzs0RkFDbkIsZ0JBQWdCO2tCQUQ1QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXBwQ29uZmlnU2VydmljZVxuICpcbiAqIFNlcnZpY2lvIHBhcmEgZ2VzdGlvbmFyIGNvbmZpZ3VyYWNpw7NuIHJlbW90YSBkZSBsYSBhcGxpY2FjacOzbiBkZXNkZSBGaXJlc3RvcmUuXG4gKiBTb3BvcnRhIGZlYXR1cmUgZmxhZ3MsIHZhcmlhYmxlcyBkaW7DoW1pY2FzLCB5IGRldGVjY2nDs24gZGUgYWN0dWFsaXphY2lvbmVzLlxuICovXG5cbmltcG9ydCB7IGNvbXB1dGVkLCBpbmplY3QsIEluamVjdGFibGUsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZpcmVzdG9yZVNlcnZpY2UgfSBmcm9tICcuLi9maXJlYmFzZS9maXJlc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBWQUxURUNIX0FQUF9DT05GSUcgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyBBcHBDb25maWcsIEFwcENvbmZpZ1NlcnZpY2VDb25maWcgfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiBTZXJ2aWNpbyBkZSBjb25maWd1cmFjacOzbiByZW1vdGEgZGUgbGEgYXBsaWNhY2nDs24uXG4gKlxuICogTGVlIGxhIGNvbmZpZ3VyYWNpw7NuIGRlc2RlIEZpcmVzdG9yZSAoYXBwcy97YXBwSWR9L2NvbmZpZy9hcHApIHkgcHJvdmVlOlxuICogLSBGZWF0dXJlIGZsYWdzIHJlYWN0aXZvc1xuICogLSBWYXJpYWJsZXMgZGluw6FtaWNhcyBkZSBjb25maWd1cmFjacOzblxuICogLSBEZXRlY2Npw7NuIGRlIG51ZXZhcyB2ZXJzaW9uZXNcbiAqIC0gTW9kbyBtYW50ZW5pbWllbnRvXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIEBDb21wb25lbnQoey4uLn0pXG4gKiBleHBvcnQgY2xhc3MgTXlDb21wb25lbnQge1xuICogICBwcml2YXRlIGFwcENvbmZpZyA9IGluamVjdChBcHBDb25maWdTZXJ2aWNlKTtcbiAqXG4gKiAgIC8vIFZlcmlmaWNhciBmZWF0dXJlIGZsYWdcbiAqICAgc2hvd05ld0ZlYXR1cmUgPSBjb21wdXRlZCgoKSA9PlxuICogICAgIHRoaXMuYXBwQ29uZmlnLmlzRmVhdHVyZUVuYWJsZWQoJ25ld0Rhc2hib2FyZCcpXG4gKiAgICk7XG4gKlxuICogICAvLyBPYnRlbmVyIHZhcmlhYmxlXG4gKiAgIG1heFNpemUgPSB0aGlzLmFwcENvbmZpZy5nZXRWYXJpYWJsZSgnbWF4VXBsb2FkU2l6ZScsIDUyNDI4ODApO1xuICogfVxuICogYGBgXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQXBwQ29uZmlnU2VydmljZSB7XG4gIHByaXZhdGUgZmlyZXN0b3JlID0gaW5qZWN0KEZpcmVzdG9yZVNlcnZpY2UpO1xuICBwcml2YXRlIHNlcnZpY2VDb25maWcgPSBpbmplY3QoVkFMVEVDSF9BUFBfQ09ORklHLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbDtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFNJR05BTFMgUkVBQ1RJVk9TXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogQ29uZmlndXJhY2nDs24gYWN0dWFsIGRlIGxhIGFwbGljYWNpw7NuLlxuICAgKiBudWxsIHNpIG5vIHNlIGhhIGNhcmdhZG8gbyBubyBlc3TDoSBjb25maWd1cmFkby5cbiAgICovXG4gIHJlYWRvbmx5IGFwcENvbmZpZyA9IHNpZ25hbDxBcHBDb25maWcgfCBudWxsPihudWxsKTtcblxuICAvKipcbiAgICogSW5kaWNhIHNpIGxhIGNvbmZpZ3VyYWNpw7NuIGVzdMOhIGNhcmdhbmRvLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9hZGluZyA9IHNpZ25hbCh0cnVlKTtcblxuICAvKipcbiAgICogRXJyb3IgZGUgY2FyZ2EsIHNpIGV4aXN0ZS5cbiAgICovXG4gIHJlYWRvbmx5IGVycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gIC8qKlxuICAgKiBJbmRpY2Egc2kgaGF5IHVuYSBudWV2YSB2ZXJzacOzbiBkaXNwb25pYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgaGFzVXBkYXRlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuYXBwQ29uZmlnKCk7XG4gICAgY29uc3QgY3VycmVudFZlcnNpb24gPSB0aGlzLnNlcnZpY2VDb25maWc/LmN1cnJlbnRWZXJzaW9uO1xuXG4gICAgaWYgKCFjb25maWcgfHwgIWN1cnJlbnRWZXJzaW9uKSByZXR1cm4gZmFsc2U7XG5cbiAgICByZXR1cm4gdGhpcy5pc05ld2VyVmVyc2lvbihjb25maWcudmVyc2lvbiwgY3VycmVudFZlcnNpb24pO1xuICB9KTtcblxuICAvKipcbiAgICogSW5kaWNhIHNpIGxhIGFwbGljYWNpw7NuIGVzdMOhIGVuIG1vZG8gbWFudGVuaW1pZW50by5cbiAgICovXG4gIHJlYWRvbmx5IGlzTWFpbnRlbmFuY2VNb2RlID0gY29tcHV0ZWQoXG4gICAgKCkgPT4gdGhpcy5hcHBDb25maWcoKT8ubWFpbnRlbmFuY2UgPz8gZmFsc2VcbiAgKTtcblxuICAvKipcbiAgICogVmVyc2nDs24gcmVtb3RhIGRlIGxhIGFwbGljYWNpw7NuLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVtb3RlVmVyc2lvbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMuYXBwQ29uZmlnKCk/LnZlcnNpb24gPz8gbnVsbCk7XG5cbiAgLyoqXG4gICAqIFZlcnNpw7NuIGFjdHVhbCBkZSBsYSBhcGxpY2FjacOzbiAobG9jYWwpLlxuICAgKi9cbiAgcmVhZG9ubHkgY3VycmVudFZlcnNpb24gPSBjb21wdXRlZChcbiAgICAoKSA9PiB0aGlzLnNlcnZpY2VDb25maWc/LmN1cnJlbnRWZXJzaW9uID8/ICcwLjAuMCdcbiAgKTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIE3DiVRPRE9TIFDDmkJMSUNPU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLyoqXG4gICAqIEluaWNpYWxpemEgZWwgc2VydmljaW8geSBjb21pZW56YSBhIGVzY3VjaGFyIGNhbWJpb3MgZW4gbGEgY29uZmlndXJhY2nDs24uXG4gICAqIFNlIGxsYW1hIGF1dG9tw6F0aWNhbWVudGUgdmlhIEFQUF9JTklUSUFMSVpFUiBzaSBzZSB1c2EgcHJvdmlkZVZhbHRlY2hBcHBDb25maWcoKS5cbiAgICovXG4gIGluaXRpYWxpemUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLnNlcnZpY2VDb25maWcpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ1tBcHBDb25maWdTZXJ2aWNlXSBObyBjb25maWd1cmF0aW9uIHByb3ZpZGVkLiBVc2UgcHJvdmlkZVZhbHRlY2hBcHBDb25maWcoKSBpbiBtYWluLnRzJ1xuICAgICAgKTtcbiAgICAgIHRoaXMubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb24gPSB0aGlzLmZpcmVzdG9yZVxuICAgICAgICAuZG9jQ2hhbmdlczxBcHBDb25maWc+KCdjb25maWcnLCAnYXBwJylcbiAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgbmV4dDogKGNvbmZpZykgPT4ge1xuICAgICAgICAgICAgdGhpcy5hcHBDb25maWcuc2V0KGNvbmZpZyk7XG4gICAgICAgICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgIHRoaXMuZXJyb3Iuc2V0KG51bGwpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tBcHBDb25maWdTZXJ2aWNlXSBFcnJvciBsb2FkaW5nIGNvbmZpZzonLCBlcnIpO1xuICAgICAgICAgICAgdGhpcy5lcnJvci5zZXQoZXJyLm1lc3NhZ2UgfHwgJ0Vycm9yIGFsIGNhcmdhciBjb25maWd1cmFjacOzbicpO1xuICAgICAgICAgICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgICByZXNvbHZlKCk7IC8vIFJlc29sdmUgYW55d2F5IHRvIG5vdCBibG9jayBhcHAgc3RhcnR1cFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWNhIHNpIHVuIGZlYXR1cmUgZmxhZyBlc3TDoSBoYWJpbGl0YWRvLlxuICAgKlxuICAgKiBAcGFyYW0gZmVhdHVyZSAtIE5vbWJyZSBkZWwgZmVhdHVyZSBmbGFnXG4gICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgLSBWYWxvciBwb3IgZGVmZWN0byBzaSBubyBleGlzdGUgKGRlZmF1bHQ6IGZhbHNlKVxuICAgKiBAcmV0dXJucyB0cnVlIHNpIGVsIGZlYXR1cmUgZXN0w6EgaGFiaWxpdGFkb1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGlmIChhcHBDb25maWcuaXNGZWF0dXJlRW5hYmxlZCgnZGFya01vZGUnKSkge1xuICAgKiAgIC8vIE1vc3RyYXIgdG9nZ2xlIGRlIGRhcmsgbW9kZVxuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgaXNGZWF0dXJlRW5hYmxlZChmZWF0dXJlOiBzdHJpbmcsIGRlZmF1bHRWYWx1ZSA9IGZhbHNlKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5hcHBDb25maWcoKTtcbiAgICBpZiAoIWNvbmZpZz8uZmVhdHVyZXMpIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgcmV0dXJuIGNvbmZpZy5mZWF0dXJlc1tmZWF0dXJlXSA/PyBkZWZhdWx0VmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogT2J0aWVuZSB1bmEgdmFyaWFibGUgZGUgY29uZmlndXJhY2nDs24uXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBDbGF2ZSBkZSBsYSB2YXJpYWJsZVxuICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIC0gVmFsb3IgcG9yIGRlZmVjdG8gc2kgbm8gZXhpc3RlXG4gICAqIEByZXR1cm5zIFZhbG9yIGRlIGxhIHZhcmlhYmxlIG8gZWwgdmFsb3IgcG9yIGRlZmVjdG9cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBtYXhTaXplID0gYXBwQ29uZmlnLmdldFZhcmlhYmxlKCdtYXhVcGxvYWRTaXplJywgNTI0Mjg4MCk7XG4gICAqIGNvbnN0IHN1cHBvcnRFbWFpbCA9IGFwcENvbmZpZy5nZXRWYXJpYWJsZSgnc3VwcG9ydEVtYWlsJywgJ3N1cHBvcnRAZXhhbXBsZS5jb20nKTtcbiAgICogYGBgXG4gICAqL1xuICBnZXRWYXJpYWJsZTxUPihrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlOiBUKTogVCB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5hcHBDb25maWcoKTtcbiAgICBpZiAoIWNvbmZpZz8udmFyaWFibGVzKSByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgIHJldHVybiAoY29uZmlnLnZhcmlhYmxlc1trZXldIGFzIFQpID8/IGRlZmF1bHRWYWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNhcmdhIGxhIGNvbmZpZ3VyYWNpw7NuIG1hbnVhbG1lbnRlIChvbmUtdGltZSByZWFkKS5cbiAgICogw5p0aWwgc2kgbmVjZXNpdGFzIGZvcnphciB1bmEgYWN0dWFsaXphY2nDs24uXG4gICAqL1xuICBhc3luYyByZWZyZXNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9hZGluZy5zZXQodHJ1ZSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5maXJlc3RvcmUuZ2V0RG9jPEFwcENvbmZpZz4oJ2NvbmZpZycsICdhcHAnKTtcbiAgICAgIHRoaXMuYXBwQ29uZmlnLnNldChjb25maWcpO1xuICAgICAgdGhpcy5lcnJvci5zZXQobnVsbCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zdCBlcnJvciA9IGVyciBhcyBFcnJvcjtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tBcHBDb25maWdTZXJ2aWNlXSBFcnJvciByZWZyZXNoaW5nIGNvbmZpZzonLCBlcnJvcik7XG4gICAgICB0aGlzLmVycm9yLnNldChlcnJvci5tZXNzYWdlIHx8ICdFcnJvciBhbCByZWZyZXNjYXIgY29uZmlndXJhY2nDs24nKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlc3VzY3JpYmUgZGVsIGxpc3RlbmVyIGRlIEZpcmVzdG9yZS5cbiAgICogU2UgbGxhbWEgYXV0b23DoXRpY2FtZW50ZSBjdWFuZG8gZWwgc2VydmljaW8gc2UgZGVzdHJ1eWUuXG4gICAqL1xuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gTcOJVE9ET1MgUFJJVkFET1NcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBDb21wYXJhIGRvcyB2ZXJzaW9uZXMgc2VtdmVyIHkgcmV0b3JuYSB0cnVlIHNpIHJlbW90ZSA+IGN1cnJlbnQuXG4gICAqXG4gICAqIEBwYXJhbSByZW1vdGUgLSBWZXJzacOzbiByZW1vdGEgKGVqOiBcIjEuMi4zXCIpXG4gICAqIEBwYXJhbSBjdXJyZW50IC0gVmVyc2nDs24gYWN0dWFsIChlajogXCIxLjIuMFwiKVxuICAgKiBAcmV0dXJucyB0cnVlIHNpIHJlbW90ZSBlcyBtYXlvciBxdWUgY3VycmVudFxuICAgKi9cbiAgcHJpdmF0ZSBpc05ld2VyVmVyc2lvbihyZW1vdGU6IHN0cmluZywgY3VycmVudDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgcmVtb3RlUGFydHMgPSByZW1vdGUuc3BsaXQoJy4nKS5tYXAoTnVtYmVyKTtcbiAgICBjb25zdCBjdXJyZW50UGFydHMgPSBjdXJyZW50LnNwbGl0KCcuJykubWFwKE51bWJlcik7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IE1hdGgubWF4KHJlbW90ZVBhcnRzLmxlbmd0aCwgY3VycmVudFBhcnRzLmxlbmd0aCk7IGkrKykge1xuICAgICAgY29uc3QgcmVtb3RlUGFydCA9IHJlbW90ZVBhcnRzW2ldIHx8IDA7XG4gICAgICBjb25zdCBjdXJyZW50UGFydCA9IGN1cnJlbnRQYXJ0c1tpXSB8fCAwO1xuXG4gICAgICBpZiAocmVtb3RlUGFydCA+IGN1cnJlbnRQYXJ0KSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmIChyZW1vdGVQYXJ0IDwgY3VycmVudFBhcnQpIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,47 @@
1
+ import { APP_INITIALIZER, InjectionToken, makeEnvironmentProviders, } from '@angular/core';
2
+ import { DEFAULT_APP_CONFIG_SERVICE_CONFIG, } from './types';
3
+ import { AppConfigService } from './app-config.service';
4
+ /**
5
+ * Token de inyección para la configuración de AppConfig.
6
+ */
7
+ export const VALTECH_APP_CONFIG = new InjectionToken('ValtechAppConfig');
8
+ /**
9
+ * Provee el servicio de configuración remota a la aplicación Angular.
10
+ *
11
+ * @param config - Configuración del servicio
12
+ * @returns EnvironmentProviders para usar en bootstrapApplication
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // main.ts
17
+ * import { bootstrapApplication } from '@angular/platform-browser';
18
+ * import { provideValtechAppConfig } from 'valtech-components';
19
+ * import { version } from '../package.json';
20
+ *
21
+ * bootstrapApplication(AppComponent, {
22
+ * providers: [
23
+ * provideValtechFirebase(environment.valtechFirebase),
24
+ * provideValtechAppConfig({
25
+ * currentVersion: version,
26
+ * showUpdateBanner: true,
27
+ * }),
28
+ * ],
29
+ * });
30
+ * ```
31
+ */
32
+ export function provideValtechAppConfig(config) {
33
+ const mergedConfig = {
34
+ ...DEFAULT_APP_CONFIG_SERVICE_CONFIG,
35
+ ...config,
36
+ };
37
+ return makeEnvironmentProviders([
38
+ { provide: VALTECH_APP_CONFIG, useValue: mergedConfig },
39
+ {
40
+ provide: APP_INITIALIZER,
41
+ useFactory: (appConfigService) => () => appConfigService.initialize(),
42
+ deps: [AppConfigService],
43
+ multi: true,
44
+ },
45
+ ]);
46
+ }
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hcHAtY29uZmlnL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsZUFBZSxFQUVmLGNBQWMsRUFDZCx3QkFBd0IsR0FDekIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUVMLGlDQUFpQyxHQUNsQyxNQUFNLFNBQVMsQ0FBQztBQUNqQixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLElBQUksY0FBYyxDQUNsRCxrQkFBa0IsQ0FDbkIsQ0FBQztBQUVGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRztBQUNILE1BQU0sVUFBVSx1QkFBdUIsQ0FDckMsTUFBOEI7SUFFOUIsTUFBTSxZQUFZLEdBQTJCO1FBQzNDLEdBQUcsaUNBQWlDO1FBQ3BDLEdBQUcsTUFBTTtLQUNWLENBQUM7SUFFRixPQUFPLHdCQUF3QixDQUFDO1FBQzlCLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUU7UUFDdkQ7WUFDRSxPQUFPLEVBQUUsZUFBZTtZQUN4QixVQUFVLEVBQUUsQ0FBQyxnQkFBa0MsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQ3ZELGdCQUFnQixDQUFDLFVBQVUsRUFBRTtZQUMvQixJQUFJLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztZQUN4QixLQUFLLEVBQUUsSUFBSTtTQUNaO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFQUF9JTklUSUFMSVpFUixcbiAgRW52aXJvbm1lbnRQcm92aWRlcnMsXG4gIEluamVjdGlvblRva2VuLFxuICBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQXBwQ29uZmlnU2VydmljZUNvbmZpZyxcbiAgREVGQVVMVF9BUFBfQ09ORklHX1NFUlZJQ0VfQ09ORklHLFxufSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IEFwcENvbmZpZ1NlcnZpY2UgfSBmcm9tICcuL2FwcC1jb25maWcuc2VydmljZSc7XG5cbi8qKlxuICogVG9rZW4gZGUgaW55ZWNjacOzbiBwYXJhIGxhIGNvbmZpZ3VyYWNpw7NuIGRlIEFwcENvbmZpZy5cbiAqL1xuZXhwb3J0IGNvbnN0IFZBTFRFQ0hfQVBQX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxBcHBDb25maWdTZXJ2aWNlQ29uZmlnPihcbiAgJ1ZhbHRlY2hBcHBDb25maWcnXG4pO1xuXG4vKipcbiAqIFByb3ZlZSBlbCBzZXJ2aWNpbyBkZSBjb25maWd1cmFjacOzbiByZW1vdGEgYSBsYSBhcGxpY2FjacOzbiBBbmd1bGFyLlxuICpcbiAqIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmFjacOzbiBkZWwgc2VydmljaW9cbiAqIEByZXR1cm5zIEVudmlyb25tZW50UHJvdmlkZXJzIHBhcmEgdXNhciBlbiBib290c3RyYXBBcHBsaWNhdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBtYWluLnRzXG4gKiBpbXBvcnQgeyBib290c3RyYXBBcHBsaWNhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuICogaW1wb3J0IHsgcHJvdmlkZVZhbHRlY2hBcHBDb25maWcgfSBmcm9tICd2YWx0ZWNoLWNvbXBvbmVudHMnO1xuICogaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uL3BhY2thZ2UuanNvbic7XG4gKlxuICogYm9vdHN0cmFwQXBwbGljYXRpb24oQXBwQ29tcG9uZW50LCB7XG4gKiAgIHByb3ZpZGVyczogW1xuICogICAgIHByb3ZpZGVWYWx0ZWNoRmlyZWJhc2UoZW52aXJvbm1lbnQudmFsdGVjaEZpcmViYXNlKSxcbiAqICAgICBwcm92aWRlVmFsdGVjaEFwcENvbmZpZyh7XG4gKiAgICAgICBjdXJyZW50VmVyc2lvbjogdmVyc2lvbixcbiAqICAgICAgIHNob3dVcGRhdGVCYW5uZXI6IHRydWUsXG4gKiAgICAgfSksXG4gKiAgIF0sXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZVZhbHRlY2hBcHBDb25maWcoXG4gIGNvbmZpZzogQXBwQ29uZmlnU2VydmljZUNvbmZpZ1xuKTogRW52aXJvbm1lbnRQcm92aWRlcnMge1xuICBjb25zdCBtZXJnZWRDb25maWc6IEFwcENvbmZpZ1NlcnZpY2VDb25maWcgPSB7XG4gICAgLi4uREVGQVVMVF9BUFBfQ09ORklHX1NFUlZJQ0VfQ09ORklHLFxuICAgIC4uLmNvbmZpZyxcbiAgfTtcblxuICByZXR1cm4gbWFrZUVudmlyb25tZW50UHJvdmlkZXJzKFtcbiAgICB7IHByb3ZpZGU6IFZBTFRFQ0hfQVBQX0NPTkZJRywgdXNlVmFsdWU6IG1lcmdlZENvbmZpZyB9LFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IEFQUF9JTklUSUFMSVpFUixcbiAgICAgIHVzZUZhY3Rvcnk6IChhcHBDb25maWdTZXJ2aWNlOiBBcHBDb25maWdTZXJ2aWNlKSA9PiAoKSA9PlxuICAgICAgICBhcHBDb25maWdTZXJ2aWNlLmluaXRpYWxpemUoKSxcbiAgICAgIGRlcHM6IFtBcHBDb25maWdTZXJ2aWNlXSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gIF0pO1xufVxuIl19
@@ -0,0 +1,39 @@
1
+ /**
2
+ * AppConfig Service Module
3
+ *
4
+ * Servicio de configuración remota para aplicaciones Angular.
5
+ * Lee configuración desde Firestore y provee feature flags, variables dinámicas,
6
+ * y detección de actualizaciones.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // main.ts
11
+ * import { provideValtechAppConfig } from 'valtech-components';
12
+ *
13
+ * bootstrapApplication(AppComponent, {
14
+ * providers: [
15
+ * provideValtechFirebase(environment.valtechFirebase),
16
+ * provideValtechAppConfig({
17
+ * currentVersion: '1.0.0',
18
+ * showUpdateBanner: true,
19
+ * }),
20
+ * ],
21
+ * });
22
+ *
23
+ * // component.ts
24
+ * import { AppConfigService } from 'valtech-components';
25
+ *
26
+ * @Component({...})
27
+ * export class MyComponent {
28
+ * private appConfig = inject(AppConfigService);
29
+ *
30
+ * showFeature = computed(() =>
31
+ * this.appConfig.isFeatureEnabled('newDashboard')
32
+ * );
33
+ * }
34
+ * ```
35
+ */
36
+ export * from './types';
37
+ export { VALTECH_APP_CONFIG, provideValtechAppConfig } from './config';
38
+ export { AppConfigService } from './app-config.service';
39
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2FwcC1jb25maWcvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQ0c7QUFFSCxjQUFjLFNBQVMsQ0FBQztBQUN4QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFwcENvbmZpZyBTZXJ2aWNlIE1vZHVsZVxuICpcbiAqIFNlcnZpY2lvIGRlIGNvbmZpZ3VyYWNpw7NuIHJlbW90YSBwYXJhIGFwbGljYWNpb25lcyBBbmd1bGFyLlxuICogTGVlIGNvbmZpZ3VyYWNpw7NuIGRlc2RlIEZpcmVzdG9yZSB5IHByb3ZlZSBmZWF0dXJlIGZsYWdzLCB2YXJpYWJsZXMgZGluw6FtaWNhcyxcbiAqIHkgZGV0ZWNjacOzbiBkZSBhY3R1YWxpemFjaW9uZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIG1haW4udHNcbiAqIGltcG9ydCB7IHByb3ZpZGVWYWx0ZWNoQXBwQ29uZmlnIH0gZnJvbSAndmFsdGVjaC1jb21wb25lbnRzJztcbiAqXG4gKiBib290c3RyYXBBcHBsaWNhdGlvbihBcHBDb21wb25lbnQsIHtcbiAqICAgcHJvdmlkZXJzOiBbXG4gKiAgICAgcHJvdmlkZVZhbHRlY2hGaXJlYmFzZShlbnZpcm9ubWVudC52YWx0ZWNoRmlyZWJhc2UpLFxuICogICAgIHByb3ZpZGVWYWx0ZWNoQXBwQ29uZmlnKHtcbiAqICAgICAgIGN1cnJlbnRWZXJzaW9uOiAnMS4wLjAnLFxuICogICAgICAgc2hvd1VwZGF0ZUJhbm5lcjogdHJ1ZSxcbiAqICAgICB9KSxcbiAqICAgXSxcbiAqIH0pO1xuICpcbiAqIC8vIGNvbXBvbmVudC50c1xuICogaW1wb3J0IHsgQXBwQ29uZmlnU2VydmljZSB9IGZyb20gJ3ZhbHRlY2gtY29tcG9uZW50cyc7XG4gKlxuICogQENvbXBvbmVudCh7Li4ufSlcbiAqIGV4cG9ydCBjbGFzcyBNeUNvbXBvbmVudCB7XG4gKiAgIHByaXZhdGUgYXBwQ29uZmlnID0gaW5qZWN0KEFwcENvbmZpZ1NlcnZpY2UpO1xuICpcbiAqICAgc2hvd0ZlYXR1cmUgPSBjb21wdXRlZCgoKSA9PlxuICogICAgIHRoaXMuYXBwQ29uZmlnLmlzRmVhdHVyZUVuYWJsZWQoJ25ld0Rhc2hib2FyZCcpXG4gKiAgICk7XG4gKiB9XG4gKiBgYGBcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcbmV4cG9ydCB7IFZBTFRFQ0hfQVBQX0NPTkZJRywgcHJvdmlkZVZhbHRlY2hBcHBDb25maWcgfSBmcm9tICcuL2NvbmZpZyc7XG5leHBvcnQgeyBBcHBDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi9hcHAtY29uZmlnLnNlcnZpY2UnO1xuIl19