valtech-components 2.0.325 → 2.0.328
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/atoms/button/button.component.mjs +18 -18
- package/esm2022/lib/components/atoms/display/display.component.mjs +13 -16
- package/esm2022/lib/components/atoms/text/text.component.mjs +19 -19
- package/esm2022/lib/components/atoms/title/title.component.mjs +7 -7
- package/esm2022/lib/components/atoms/title/types.mjs +6 -2
- package/esm2022/lib/components/molecules/alert-box/alert-box.component.mjs +6 -6
- package/esm2022/lib/components/molecules/language-selector/language-selector.component.mjs +6 -17
- package/esm2022/lib/components/organisms/form/form.component.mjs +1 -1
- package/esm2022/lib/services/lang-provider/lang-provider.service.mjs +198 -2
- package/esm2022/lib/shared/utils/simple-content.mjs +119 -0
- package/esm2022/public-api.mjs +3 -4
- package/fesm2022/valtech-components.mjs +520 -837
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/atoms/button/button.component.d.ts +3 -3
- package/lib/components/atoms/display/display.component.d.ts +2 -3
- package/lib/components/atoms/text/text.component.d.ts +3 -3
- package/lib/components/atoms/title/title.component.d.ts +1 -2
- package/lib/components/atoms/title/types.d.ts +10 -4
- package/lib/components/molecules/alert-box/alert-box.component.d.ts +3 -3
- package/lib/components/molecules/language-selector/language-selector.component.d.ts +1 -3
- package/lib/services/lang-provider/lang-provider.service.d.ts +108 -1
- package/lib/shared/utils/simple-content.d.ts +120 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -3
- package/esm2022/lib/services/content-loader.service.mjs +0 -185
- package/esm2022/lib/services/content.service.mjs +0 -327
- package/esm2022/lib/shared/utils/reactive-content.mjs +0 -117
- package/lib/services/content-loader.service.d.ts +0 -98
- package/lib/services/content.service.d.ts +0 -296
- package/lib/shared/utils/reactive-content.d.ts +0 -109
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
|
-
import { ContentService } from '../../../services/content.service';
|
|
4
3
|
import { DownloadService } from '../../../services/download.service';
|
|
5
4
|
import { IconService } from '../../../services/icons.service';
|
|
5
|
+
import { LangService } from '../../../services/lang-provider/lang-provider.service';
|
|
6
6
|
import { NavigationService } from '../../../services/navigation.service';
|
|
7
7
|
import { ButtonContentConfig, ButtonMetadata } from '../../types';
|
|
8
8
|
import * as i0 from "@angular/core";
|
|
9
9
|
export declare class ButtonComponent implements OnInit, OnDestroy {
|
|
10
10
|
private download;
|
|
11
11
|
private navigation;
|
|
12
|
-
private
|
|
12
|
+
private langService;
|
|
13
13
|
states: {
|
|
14
14
|
ENABLED: "ENABLED";
|
|
15
15
|
DISABLED: "DISABLED";
|
|
@@ -27,7 +27,7 @@ export declare class ButtonComponent implements OnInit, OnDestroy {
|
|
|
27
27
|
* Event emitted when the button is clicked.
|
|
28
28
|
*/
|
|
29
29
|
onClick: EventEmitter<string>;
|
|
30
|
-
constructor(download: DownloadService, icon: IconService, navigation: NavigationService,
|
|
30
|
+
constructor(download: DownloadService, icon: IconService, navigation: NavigationService, langService: LangService);
|
|
31
31
|
ngOnInit(): void;
|
|
32
32
|
ngOnDestroy(): void;
|
|
33
33
|
/**
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { OnDestroy, OnInit } from '@angular/core';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
|
-
import { ContentService } from '../../../services/content.service';
|
|
4
3
|
import { DisplayContentConfig, DisplayMetadata } from './types';
|
|
5
4
|
import * as i0 from "@angular/core";
|
|
6
5
|
export declare class DisplayComponent implements OnInit, OnDestroy {
|
|
7
|
-
private contentService;
|
|
8
6
|
displayContent$: Observable<string>;
|
|
9
7
|
private subscriptions;
|
|
10
8
|
/**
|
|
@@ -16,7 +14,8 @@ export declare class DisplayComponent implements OnInit, OnDestroy {
|
|
|
16
14
|
* @property size - The text size ('small' | 'medium' | 'large' | 'xlarge').
|
|
17
15
|
*/
|
|
18
16
|
props: DisplayMetadata;
|
|
19
|
-
|
|
17
|
+
private langService;
|
|
18
|
+
constructor();
|
|
20
19
|
ngOnInit(): void;
|
|
21
20
|
ngOnDestroy(): void;
|
|
22
21
|
private initializeDisplayContent;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { OnDestroy, OnInit } from '@angular/core';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
|
-
import {
|
|
3
|
+
import { LangService } from '../../../services/lang-provider/lang-provider.service';
|
|
4
4
|
import { LinkProcessorService } from '../../../services/link-processor.service';
|
|
5
5
|
import { TextContentConfig, TextMetadata } from './types';
|
|
6
6
|
import * as i0 from "@angular/core";
|
|
7
7
|
export declare class TextComponent implements OnInit, OnDestroy {
|
|
8
|
-
private
|
|
8
|
+
private langService;
|
|
9
9
|
private linkProcessor;
|
|
10
10
|
/**
|
|
11
11
|
* Text configuration object.
|
|
@@ -35,7 +35,7 @@ export declare class TextComponent implements OnInit, OnDestroy {
|
|
|
35
35
|
*/
|
|
36
36
|
displayContent$: Observable<string>;
|
|
37
37
|
private subscription;
|
|
38
|
-
constructor(
|
|
38
|
+
constructor(langService: LangService, linkProcessor: LinkProcessorService);
|
|
39
39
|
ngOnInit(): void;
|
|
40
40
|
ngOnDestroy(): void;
|
|
41
41
|
/**
|
|
@@ -14,8 +14,7 @@ export declare class TitleComponent implements OnInit {
|
|
|
14
14
|
* @property thin - Whether the title is thin (optional).
|
|
15
15
|
*/
|
|
16
16
|
props: TitleMetadata;
|
|
17
|
-
private
|
|
18
|
-
private contentHelper;
|
|
17
|
+
private langService;
|
|
19
18
|
displayContent$: Observable<string>;
|
|
20
19
|
constructor();
|
|
21
20
|
ngOnInit(): void;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Color } from '@ionic/core';
|
|
2
|
-
import { ReactiveTextMetadata } from '../../../shared/utils/
|
|
2
|
+
import { ReactiveTextMetadata } from '../../../shared/utils/simple-content';
|
|
3
3
|
/**
|
|
4
4
|
* Props for val-title component.
|
|
5
5
|
* Supports both static content and reactive content from the language service.
|
|
6
6
|
*
|
|
7
7
|
* @property content - Static title text to display (takes precedence over reactive content).
|
|
8
|
-
* @property
|
|
8
|
+
* @property contentKey - Content key for reactive content lookup.
|
|
9
|
+
* @property contentClass - Component class name for content lookup.
|
|
10
|
+
* @property contentFallback - Fallback text if content is not found.
|
|
9
11
|
* @property color - The title color (Ionic color string).
|
|
10
12
|
* @property size - The title size ('small' | 'medium' | 'large' | 'xlarge').
|
|
11
13
|
* @property bold - Whether the title is bold.
|
|
@@ -36,8 +38,12 @@ export interface TitleMetadata extends ReactiveTextMetadata {
|
|
|
36
38
|
* ```typescript
|
|
37
39
|
* const props = createTitleProps(
|
|
38
40
|
* { size: 'large', color: 'primary', bold: true },
|
|
39
|
-
* {
|
|
41
|
+
* {
|
|
42
|
+
* contentKey: 'pageTitle',
|
|
43
|
+
* contentClass: 'MyComponent',
|
|
44
|
+
* contentFallback: 'Default Title'
|
|
45
|
+
* }
|
|
40
46
|
* );
|
|
41
47
|
* ```
|
|
42
48
|
*/
|
|
43
|
-
export declare function createTitleProps(styleConfig: Pick<TitleMetadata, 'size' | 'color' | 'bold' | 'thin'>, contentConfig: Pick<TitleMetadata, 'content' | '
|
|
49
|
+
export declare function createTitleProps(styleConfig: Pick<TitleMetadata, 'size' | 'color' | 'bold' | 'thin'>, contentConfig: Pick<TitleMetadata, 'content' | 'contentKey' | 'contentClass' | 'contentFallback'>): TitleMetadata;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { OnDestroy, OnInit } from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { LangService } from '../../../services/lang-provider/lang-provider.service';
|
|
3
3
|
import { AlertBoxMetadata, ReactiveAlertBoxMetadata } from './types';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
export declare class AlertBoxComponent implements OnInit, OnDestroy {
|
|
6
|
-
private
|
|
6
|
+
private langService;
|
|
7
7
|
private subscriptions;
|
|
8
8
|
/**
|
|
9
9
|
* Alert box configuration object.
|
|
@@ -16,7 +16,7 @@ export declare class AlertBoxComponent implements OnInit, OnDestroy {
|
|
|
16
16
|
get isLegacyProps(): boolean;
|
|
17
17
|
/** Get text props for legacy pattern */
|
|
18
18
|
getLegacyTextProps(): any;
|
|
19
|
-
constructor(
|
|
19
|
+
constructor(langService: LangService);
|
|
20
20
|
ngOnInit(): void;
|
|
21
21
|
ngOnDestroy(): void;
|
|
22
22
|
private initializeReactiveTextProps;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
|
-
import { ContentService } from '../../../services/content.service';
|
|
4
3
|
import { LangService } from '../../../services/lang-provider/lang-provider.service';
|
|
5
4
|
import { LangOption } from '../../../services/lang-provider/types';
|
|
6
5
|
import { PopoverSelectorMetadata } from '../popover-selector/types';
|
|
@@ -8,7 +7,6 @@ import { LanguageSelectorMetadata } from './types';
|
|
|
8
7
|
import * as i0 from "@angular/core";
|
|
9
8
|
export declare class LanguageSelectorComponent implements OnInit, OnDestroy {
|
|
10
9
|
private langService;
|
|
11
|
-
private contentService;
|
|
12
10
|
/**
|
|
13
11
|
* Language selector configuration object.
|
|
14
12
|
* @type {LanguageSelectorMetadata}
|
|
@@ -32,7 +30,7 @@ export declare class LanguageSelectorComponent implements OnInit, OnDestroy {
|
|
|
32
30
|
private readonly defaultLanguageNames;
|
|
33
31
|
/** Default flag icons for languages */
|
|
34
32
|
private readonly defaultLanguageFlags;
|
|
35
|
-
constructor(langService: LangService
|
|
33
|
+
constructor(langService: LangService);
|
|
36
34
|
ngOnInit(): void;
|
|
37
35
|
ngOnDestroy(): void;
|
|
38
36
|
private initializeLanguageState;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
2
|
import { ValtechConfig } from '../types';
|
|
3
|
-
import {
|
|
3
|
+
import { Provider } from './content';
|
|
4
|
+
import { LangOption, LanguageText, LanguagesContent } from './types';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
/**
|
|
6
7
|
* LangService - Reactive language and content management service.
|
|
@@ -150,6 +151,112 @@ export declare class LangService {
|
|
|
150
151
|
* @returns Array of missing keys
|
|
151
152
|
*/
|
|
152
153
|
getMissingContentKeys(className: string, lang: LangOption, referenceLang?: LangOption): string[];
|
|
154
|
+
/**
|
|
155
|
+
* Register or update content for a component dynamically.
|
|
156
|
+
* This allows registering content at runtime without APP_INITIALIZER.
|
|
157
|
+
*
|
|
158
|
+
* @param className - The component class name
|
|
159
|
+
* @param content - The multilingual content object
|
|
160
|
+
* @param merge - Whether to merge with existing content (default: true)
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* this.langService.registerContent('MyComponent', {
|
|
165
|
+
* [LANGUAGES.ES]: { title: 'Título', description: 'Descripción' },
|
|
166
|
+
* [LANGUAGES.EN]: { title: 'Title', description: 'Description' }
|
|
167
|
+
* });
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
registerContent(className: string, content: LanguagesContent, merge?: boolean): void;
|
|
171
|
+
/**
|
|
172
|
+
* Update multiple content registrations at once.
|
|
173
|
+
*
|
|
174
|
+
* @param contentMap - Map of className to content
|
|
175
|
+
* @param merge - Whether to merge with existing content (default: true)
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* this.langService.registerMultipleContent({
|
|
180
|
+
* 'Component1': { [LANGUAGES.ES]: { key1: 'valor1' } },
|
|
181
|
+
* 'Component2': { [LANGUAGES.EN]: { key2: 'value2' } }
|
|
182
|
+
* });
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
registerMultipleContent(contentMap: Record<string, LanguagesContent>, merge?: boolean): void;
|
|
186
|
+
/**
|
|
187
|
+
* Remove content for a specific component.
|
|
188
|
+
*
|
|
189
|
+
* @param className - The component class name to remove
|
|
190
|
+
*/
|
|
191
|
+
removeContent(className: string): void;
|
|
192
|
+
/**
|
|
193
|
+
* Get a list of all registered component classes.
|
|
194
|
+
*
|
|
195
|
+
* @returns Array of registered class names
|
|
196
|
+
*/
|
|
197
|
+
getRegisteredClasses(): string[];
|
|
198
|
+
/**
|
|
199
|
+
* Get the complete content configuration (for debugging purposes).
|
|
200
|
+
* Returns a deep copy to prevent accidental mutations.
|
|
201
|
+
*
|
|
202
|
+
* @returns Complete content configuration
|
|
203
|
+
*/
|
|
204
|
+
getContentConfiguration(): Provider;
|
|
205
|
+
/**
|
|
206
|
+
* Clear all content and reset to initial state.
|
|
207
|
+
* Useful for testing or complete reinitialization.
|
|
208
|
+
*/
|
|
209
|
+
clearAllContent(): void;
|
|
210
|
+
/**
|
|
211
|
+
* Get content with interpolation support.
|
|
212
|
+
* Retrieves content and replaces placeholders with provided values.
|
|
213
|
+
*
|
|
214
|
+
* @param className - The component class name
|
|
215
|
+
* @param key - The text key
|
|
216
|
+
* @param interpolationData - Object with values to interpolate
|
|
217
|
+
* @param fallback - Optional fallback text if key is not found
|
|
218
|
+
* @returns Text with interpolated values
|
|
219
|
+
*/
|
|
220
|
+
getTextWithInterpolation(className: string, key: string, interpolationData?: Record<string, string | number>, fallback?: string): string;
|
|
221
|
+
/**
|
|
222
|
+
* Get reactive content with interpolation support.
|
|
223
|
+
* Returns an Observable that emits interpolated content when language changes.
|
|
224
|
+
*
|
|
225
|
+
* @param className - The component class name
|
|
226
|
+
* @param key - The text key
|
|
227
|
+
* @param interpolationData - Object with values to interpolate
|
|
228
|
+
* @param fallback - Optional fallback text if key is not found
|
|
229
|
+
* @returns Observable that emits interpolated text
|
|
230
|
+
*/
|
|
231
|
+
getContentWithInterpolation(className: string, key: string, interpolationData?: Record<string, string | number>, fallback?: string): Observable<string>;
|
|
232
|
+
/**
|
|
233
|
+
* Interpolate a string with provided values.
|
|
234
|
+
* Replaces placeholders like {{key}} or {key} with actual values.
|
|
235
|
+
*
|
|
236
|
+
* @param content - Content string with placeholders
|
|
237
|
+
* @param values - Values to interpolate
|
|
238
|
+
* @returns Interpolated string
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* interpolateString('Hello {{name}}!', { name: 'World' })
|
|
243
|
+
* // Returns: 'Hello World!'
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
private interpolateString;
|
|
247
|
+
/**
|
|
248
|
+
* Legacy function equivalent to the old fromContentWithInterpolation.
|
|
249
|
+
* Provides reactive content with interpolation support for backward compatibility.
|
|
250
|
+
*
|
|
251
|
+
* @param className - The component class name
|
|
252
|
+
* @param key - The text key
|
|
253
|
+
* @param interpolationData - Object with values to interpolate
|
|
254
|
+
* @param fallback - Optional fallback text if key is not found
|
|
255
|
+
* @returns Observable that emits interpolated text
|
|
256
|
+
*
|
|
257
|
+
* @deprecated Use getContentWithInterpolation instead
|
|
258
|
+
*/
|
|
259
|
+
fromContentWithInterpolation(className: string, key: string, interpolationData?: Record<string, string | number>, fallback?: string): Observable<string>;
|
|
153
260
|
get Lang(): LangOption;
|
|
154
261
|
set Lang(lang: LangOption);
|
|
155
262
|
static ɵfac: i0.ɵɵFactoryDeclaration<LangService, never>;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simplified content utilities for the new LangService-only system.
|
|
3
|
+
* This replaces the old reactive-content.ts with a much simpler approach.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Base metadata for components that support reactive content.
|
|
7
|
+
* Simplified version that works directly with LangService.
|
|
8
|
+
*/
|
|
9
|
+
export interface ReactiveContentMetadata {
|
|
10
|
+
/** Static content text (takes precedence over reactive content) */
|
|
11
|
+
content?: string;
|
|
12
|
+
/** Content key for reactive content from LangService */
|
|
13
|
+
contentKey?: string;
|
|
14
|
+
/** Component class name for content lookup */
|
|
15
|
+
contentClass?: string;
|
|
16
|
+
/** Fallback text if content is not found */
|
|
17
|
+
contentFallback?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Extended metadata for text-based components with reactive content support.
|
|
21
|
+
*/
|
|
22
|
+
export interface ReactiveTextMetadata extends ReactiveContentMetadata {
|
|
23
|
+
/** Static content text */
|
|
24
|
+
content?: string;
|
|
25
|
+
/** Content key for reactive lookup */
|
|
26
|
+
contentKey?: string;
|
|
27
|
+
/** Component class name */
|
|
28
|
+
contentClass?: string;
|
|
29
|
+
/** Fallback text */
|
|
30
|
+
contentFallback?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Extended metadata for components that support content interpolation.
|
|
34
|
+
*/
|
|
35
|
+
export interface ReactiveContentWithInterpolation extends ReactiveContentMetadata {
|
|
36
|
+
/** Interpolation data for parameterized content */
|
|
37
|
+
contentInterpolation?: Record<string, string | number>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Helper function to determine if component should use reactive content.
|
|
41
|
+
* @param metadata Component metadata
|
|
42
|
+
* @returns True if component should use reactive content
|
|
43
|
+
*/
|
|
44
|
+
export declare function shouldUseReactiveContent(metadata: ReactiveContentMetadata): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Extract content configuration from metadata.
|
|
47
|
+
* @param metadata Component metadata
|
|
48
|
+
* @returns Content configuration for LangService
|
|
49
|
+
*/
|
|
50
|
+
export declare function extractContentConfig(metadata: ReactiveContentMetadata): {
|
|
51
|
+
className: string;
|
|
52
|
+
key: string;
|
|
53
|
+
fallback: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Create reactive content metadata with defaults.
|
|
57
|
+
* @param config Partial content configuration
|
|
58
|
+
* @returns Complete reactive content metadata
|
|
59
|
+
*/
|
|
60
|
+
export declare function createReactiveContentMetadata(config: Partial<ReactiveContentMetadata>): ReactiveContentMetadata;
|
|
61
|
+
/**
|
|
62
|
+
* Interpolate content string with values.
|
|
63
|
+
* Replaces placeholders like {{key}} or {key} with actual values.
|
|
64
|
+
*
|
|
65
|
+
* @param content - Content string with placeholders
|
|
66
|
+
* @param values - Values to interpolate
|
|
67
|
+
* @returns Interpolated string
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* interpolateContent('Hello {{name}}!', { name: 'World' })
|
|
72
|
+
* // Returns: 'Hello World!'
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function interpolateContent(content: string, values?: Record<string, string | number>): string;
|
|
76
|
+
/**
|
|
77
|
+
* Check if component should use reactive content with interpolation.
|
|
78
|
+
* @param metadata Component metadata with interpolation
|
|
79
|
+
* @returns True if component should use reactive content with interpolation
|
|
80
|
+
*/
|
|
81
|
+
export declare function shouldUseReactiveContentWithInterpolation(metadata: ReactiveContentWithInterpolation): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Extract content configuration with interpolation from metadata.
|
|
84
|
+
* @param metadata Component metadata with interpolation
|
|
85
|
+
* @returns Content configuration for LangService with interpolation data
|
|
86
|
+
*/
|
|
87
|
+
export declare function extractContentConfigWithInterpolation(metadata: ReactiveContentWithInterpolation): {
|
|
88
|
+
className: string;
|
|
89
|
+
key: string;
|
|
90
|
+
fallback: string;
|
|
91
|
+
interpolation: Record<string, string | number>;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Helper function to get reactive content with interpolation using LangService.
|
|
95
|
+
* This provides a unified way to get reactive, interpolated content.
|
|
96
|
+
*
|
|
97
|
+
* @param langService - The LangService instance
|
|
98
|
+
* @param metadata - Component metadata with interpolation
|
|
99
|
+
* @returns Observable that emits interpolated content
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const content$ = fromContentWithInterpolation(this.langService, {
|
|
104
|
+
* contentClass: 'MyComponent',
|
|
105
|
+
* contentKey: 'greeting',
|
|
106
|
+
* contentInterpolation: { name: 'World' }
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function fromContentWithInterpolation(langService: any, // LangService type would cause circular dependency
|
|
111
|
+
metadata: ReactiveContentWithInterpolation): any;
|
|
112
|
+
/**
|
|
113
|
+
* Helper function to get static content with interpolation.
|
|
114
|
+
* This provides interpolation for static content strings.
|
|
115
|
+
*
|
|
116
|
+
* @param content - Static content string
|
|
117
|
+
* @param interpolationData - Values to interpolate
|
|
118
|
+
* @returns Interpolated string
|
|
119
|
+
*/
|
|
120
|
+
export declare function interpolateStaticContent(content: string, interpolationData?: Record<string, string | number>): string;
|
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -87,8 +87,6 @@ export * from './lib/components/organisms/article/types';
|
|
|
87
87
|
export * from './lib/components/templates/layout/layout.component';
|
|
88
88
|
export * from './lib/components/templates/simple/simple.component';
|
|
89
89
|
export * from './lib/components/templates/simple/types';
|
|
90
|
-
export * from './lib/services/content-loader.service';
|
|
91
|
-
export * from './lib/services/content.service';
|
|
92
90
|
export * from './lib/services/download.service';
|
|
93
91
|
export * from './lib/services/icons.service';
|
|
94
92
|
export * from './lib/services/in-app-browser.service';
|
|
@@ -106,6 +104,6 @@ export * from './lib/shared/pipes/process-links.pipe';
|
|
|
106
104
|
export * from './lib/shared/utils/content';
|
|
107
105
|
export * from './lib/shared/utils/dom';
|
|
108
106
|
export * from './lib/shared/utils/form-defaults';
|
|
109
|
-
export
|
|
107
|
+
export { createReactiveContentMetadata, extractContentConfig, extractContentConfigWithInterpolation, interpolateStaticContent, ReactiveContentMetadata, ReactiveContentWithInterpolation, ReactiveTextMetadata, shouldUseReactiveContent, shouldUseReactiveContentWithInterpolation, } from './lib/shared/utils/simple-content';
|
|
110
108
|
export * from './lib/shared/utils/styles';
|
|
111
109
|
export * from './lib/shared/utils/text';
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { Injectable, inject } from '@angular/core';
|
|
2
|
-
import { TextContent } from './lang-provider/types';
|
|
3
|
-
import { ValtechConfigService } from './types';
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
/**
|
|
6
|
-
* ContentLoader Service - Dynamic content loading system.
|
|
7
|
-
*
|
|
8
|
-
* REFACTORED: Now uses ValtechConfigService properly instead of hacking LangService.
|
|
9
|
-
* This provides a clean, maintainable way to register content dynamically.
|
|
10
|
-
*
|
|
11
|
-
* @example Basic usage:
|
|
12
|
-
* ```typescript
|
|
13
|
-
* // user-page.content.ts
|
|
14
|
-
* export const UserPageContent = {
|
|
15
|
-
* es: { title: 'Mi Página de Usuario', welcome: 'Bienvenido {{name}}' },
|
|
16
|
-
* en: { title: 'My User Page', welcome: 'Welcome {{name}}' }
|
|
17
|
-
* };
|
|
18
|
-
*
|
|
19
|
-
* // In component
|
|
20
|
-
* import { UserPageContent } from './user-page.content';
|
|
21
|
-
* registerContent('UserPage', UserPageContent);
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export class ContentLoaderService {
|
|
25
|
-
constructor() {
|
|
26
|
-
this.valtechConfig = inject(ValtechConfigService);
|
|
27
|
-
this.registeredContent = new Map();
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Register content for a specific component/page class.
|
|
31
|
-
* ✅ CLEAN: Uses proper ValtechConfigService API instead of hacking LangService
|
|
32
|
-
*/
|
|
33
|
-
registerContent(className, content) {
|
|
34
|
-
// Store locally for tracking
|
|
35
|
-
this.registeredContent.set(className, content);
|
|
36
|
-
// Update the configuration properly
|
|
37
|
-
this.addContentToProvider(className, content);
|
|
38
|
-
console.log(`✅ ContentLoader: Registered content for "${className}"`);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Register multiple content modules at once.
|
|
42
|
-
*/
|
|
43
|
-
loadContent(contentModules) {
|
|
44
|
-
console.log(`🔄 ContentLoader: Loading ${contentModules.length} content modules...`);
|
|
45
|
-
contentModules.forEach(module => {
|
|
46
|
-
this.registerContent(module.className, module.content);
|
|
47
|
-
});
|
|
48
|
-
console.log('✅ ContentLoader: All content modules loaded successfully');
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Check if content is registered for a class.
|
|
52
|
-
*/
|
|
53
|
-
hasContentFor(className) {
|
|
54
|
-
return this.registeredContent.has(className);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Get all registered class names.
|
|
58
|
-
*/
|
|
59
|
-
getRegisteredClasses() {
|
|
60
|
-
return Array.from(this.registeredContent.keys());
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Get registered content for a specific class.
|
|
64
|
-
*/
|
|
65
|
-
getContentFor(className) {
|
|
66
|
-
return this.registeredContent.get(className);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Remove content registration for a class.
|
|
70
|
-
*/
|
|
71
|
-
unregisterContent(className) {
|
|
72
|
-
const existed = this.registeredContent.has(className);
|
|
73
|
-
this.registeredContent.delete(className);
|
|
74
|
-
// Also remove from the provider
|
|
75
|
-
if (existed && this.valtechConfig.content) {
|
|
76
|
-
const updatedContent = { ...this.valtechConfig.content };
|
|
77
|
-
delete updatedContent[className];
|
|
78
|
-
this.valtechConfig.content = updatedContent;
|
|
79
|
-
console.log(`🗑️ ContentLoader: Unregistered content for "${className}"`);
|
|
80
|
-
}
|
|
81
|
-
return existed;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Clear all registered content.
|
|
85
|
-
*/
|
|
86
|
-
clearAllContent() {
|
|
87
|
-
this.registeredContent.clear();
|
|
88
|
-
console.log('🧹 ContentLoader: Cleared all registered content');
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Get current content provider state.
|
|
92
|
-
* Useful for debugging.
|
|
93
|
-
*/
|
|
94
|
-
getContentProvider() {
|
|
95
|
-
return this.valtechConfig.content;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* ✅ CLEAN: Add content to provider using proper API
|
|
99
|
-
* @private
|
|
100
|
-
*/
|
|
101
|
-
addContentToProvider(className, content) {
|
|
102
|
-
try {
|
|
103
|
-
// Get current content provider
|
|
104
|
-
const currentContent = this.valtechConfig.content || {};
|
|
105
|
-
// Create TextContent instance
|
|
106
|
-
const textContent = new TextContent(content);
|
|
107
|
-
// Update the content provider properly
|
|
108
|
-
const updatedContent = {
|
|
109
|
-
...currentContent,
|
|
110
|
-
[className]: textContent,
|
|
111
|
-
};
|
|
112
|
-
// Set the updated content - this is the clean way
|
|
113
|
-
this.valtechConfig.content = updatedContent;
|
|
114
|
-
console.log(`📝 ContentLoader: Added "${className}" to content provider`);
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
console.error(`❌ ContentLoader: Error adding content for "${className}":`, error);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ContentLoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
121
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ContentLoaderService, providedIn: 'root' }); }
|
|
122
|
-
}
|
|
123
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ContentLoaderService, decorators: [{
|
|
124
|
-
type: Injectable,
|
|
125
|
-
args: [{
|
|
126
|
-
providedIn: 'root',
|
|
127
|
-
}]
|
|
128
|
-
}] });
|
|
129
|
-
/**
|
|
130
|
-
* Helper function to create a content module.
|
|
131
|
-
*/
|
|
132
|
-
export function createContentModule(className, content) {
|
|
133
|
-
return { className, content };
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* ✅ CLEAN: Global registry using proper array instead of globalThis hack
|
|
137
|
-
*/
|
|
138
|
-
const globalContentRegistry = [];
|
|
139
|
-
/**
|
|
140
|
-
* Simple function to register content directly.
|
|
141
|
-
* ✅ IMPROVED: Cleaner global registry management
|
|
142
|
-
*/
|
|
143
|
-
export function registerContent(className, content) {
|
|
144
|
-
// Add to global registry
|
|
145
|
-
globalContentRegistry.push({ className, content });
|
|
146
|
-
console.log(`📝 registerContent: Queued "${className}" for registration`);
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Load all content from the global registry.
|
|
150
|
-
* ✅ IMPROVED: Better error handling and logging
|
|
151
|
-
*/
|
|
152
|
-
export function loadRegisteredContent(contentLoader) {
|
|
153
|
-
if (globalContentRegistry.length === 0) {
|
|
154
|
-
console.log('ℹ️ ContentLoader: No content registered to load');
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
console.log(`🚀 ContentLoader: Loading ${globalContentRegistry.length} registered content modules...`);
|
|
158
|
-
try {
|
|
159
|
-
// Load all content
|
|
160
|
-
contentLoader.loadContent([...globalContentRegistry]);
|
|
161
|
-
// Clear the registry after loading
|
|
162
|
-
globalContentRegistry.length = 0;
|
|
163
|
-
console.log('🎉 ContentLoader: All registered content loaded and registry cleared');
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
console.error('❌ ContentLoader: Error loading registered content:', error);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* ✅ NEW: Debugging helper
|
|
171
|
-
* Get current global registry state
|
|
172
|
-
*/
|
|
173
|
-
export function getRegisteredContentQueue() {
|
|
174
|
-
return [...globalContentRegistry];
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* ✅ NEW: Debugging helper
|
|
178
|
-
* Clear the global registry without loading
|
|
179
|
-
*/
|
|
180
|
-
export function clearRegisteredContentQueue() {
|
|
181
|
-
const count = globalContentRegistry.length;
|
|
182
|
-
globalContentRegistry.length = 0;
|
|
183
|
-
console.log(`🧹 ContentLoader: Cleared ${count} items from registration queue`);
|
|
184
|
-
}
|
|
185
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGVudC1sb2FkZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3ZhbHRlY2gtY29tcG9uZW50cy9zcmMvbGliL3NlcnZpY2VzL2NvbnRlbnQtbG9hZGVyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkQsT0FBTyxFQUFvQixXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxTQUFTLENBQUM7O0FBQy9DOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFJSCxNQUFNLE9BQU8sb0JBQW9CO0lBSGpDO1FBSVUsa0JBQWEsR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUM3QyxzQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBNEIsQ0FBQztLQThHakU7SUE1R0M7OztPQUdHO0lBQ0gsZUFBZSxDQUFDLFNBQWlCLEVBQUUsT0FBeUI7UUFDMUQsNkJBQTZCO1FBQzdCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRS9DLG9DQUFvQztRQUNwQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTlDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNENBQTRDLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsV0FBVyxDQUFDLGNBQStCO1FBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLGNBQWMsQ0FBQyxNQUFNLHFCQUFxQixDQUFDLENBQUM7UUFFckYsY0FBYyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUM5QixJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxTQUFT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QUFxQixDQUFDLE1BQU0sQ0FBQztJQUMzQyxxQkFBcUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLEtBQUssZ0NBQWdDLENBQUMsQ0FBQztBQUNsRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gJy4vbGFuZy1wcm92aWRlci9jb250ZW50JztcbmltcG9ydCB7IExhbmd1YWdlc0NvbnRlbnQsIFRleHRDb250ZW50IH0gZnJvbSAnLi9sYW5nLXByb3ZpZGVyL3R5cGVzJztcbmltcG9ydCB7IFZhbHRlY2hDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi90eXBlcyc7XG4vKipcbiAqIENvbnRlbnRMb2FkZXIgU2VydmljZSAtIER5bmFtaWMgY29udGVudCBsb2FkaW5nIHN5c3RlbS5cbiAqXG4gKiBSRUZBQ1RPUkVEOiBOb3cgdXNlcyBWYWx0ZWNoQ29uZmlnU2VydmljZSBwcm9wZXJseSBpbnN0ZWFkIG9mIGhhY2tpbmcgTGFuZ1NlcnZpY2UuXG4gKiBUaGlzIHByb3ZpZGVzIGEgY2xlYW4sIG1haW50YWluYWJsZSB3YXkgdG8gcmVnaXN0ZXIgY29udGVudCBkeW5hbWljYWxseS5cbiAqXG4gKiBAZXhhbXBsZSBCYXNpYyB1c2FnZTpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHVzZXItcGFnZS5jb250ZW50LnRzXG4gKiBleHBvcnQgY29uc3QgVXNlclBhZ2VDb250ZW50ID0ge1xuICogICBlczogeyB0aXRsZTogJ01pIFDDoWdpbmEgZGUgVXN1YXJpbycsIHdlbGNvbWU6ICdCaWVudmVuaWRvIHt7bmFtZX19JyB9LFxuICogICBlbjogeyB0aXRsZTogJ015IFVzZXIgUGFnZScsIHdlbGNvbWU6ICdXZWxjb21lIHt7bmFtZX19JyB9XG4gKiB9O1xuICpcbiAqIC8vIEluIGNvbXBvbmVudFxuICogaW1wb3J0IHsgVXNlclBhZ2VDb250ZW50IH0gZnJvbSAnLi91c2VyLXBhZ2UuY29udGVudCc7XG4gKiByZWdpc3RlckNvbnRlbnQoJ1VzZXJQYWdlJywgVXNlclBhZ2VDb250ZW50KTtcbiAqIGBgYFxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgQ29udGVudExvYWRlclNlcnZpY2Uge1xuICBwcml2YXRlIHZhbHRlY2hDb25maWcgPSBpbmplY3QoVmFsdGVjaENvbmZpZ1NlcnZpY2UpO1xuICBwcml2YXRlIHJlZ2lzdGVyZWRDb250ZW50ID0gbmV3IE1hcDxzdHJpbmcsIExhbmd1YWdlc0NvbnRlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGNvbnRlbnQgZm9yIGEgc3BlY2lmaWMgY29tcG9uZW50L3BhZ2UgY2xhc3MuXG4gICAqIOKchSBDTEVBTjogVXNlcyBwcm9wZXIgVmFsdGVjaENvbmZpZ1NlcnZpY2UgQVBJIGluc3RlYWQgb2YgaGFja2luZyBMYW5nU2VydmljZVxuICAgKi9cbiAgcmVnaXN0ZXJDb250ZW50KGNsYXNzTmFtZTogc3RyaW5nLCBjb250ZW50OiBMYW5ndWFnZXNDb250ZW50KTogdm9pZCB7XG4gICAgLy8gU3RvcmUgbG9jYWxseSBmb3IgdHJhY2tpbmdcbiAgICB0aGlzLnJlZ2lzdGVyZWRDb250ZW50LnNldChjbGFzc05hbWUsIGNvbnRlbnQpO1xuXG4gICAgLy8gVXBkYXRlIHRoZSBjb25maWd1cmF0aW9uIHByb3Blcmx5XG4gICAgdGhpcy5hZGRDb250ZW50VG9Qcm92aWRlcihjbGFzc05hbWUsIGNvbnRlbnQpO1xuXG4gICAgY29uc29sZS5sb2coYOKchSBDb250ZW50TG9hZGVyOiBSZWdpc3RlcmVkIGNvbnRlbnQgZm9yIFwiJHtjbGFzc05hbWV9XCJgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBtdWx0aXBsZSBjb250ZW50IG1vZHVsZXMgYXQgb25jZS5cbiAgICovXG4gIGxvYWRDb250ZW50KGNvbnRlbnRNb2R1bGVzOiBDb250ZW50TW9kdWxlW10pOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyhg8J+UhCBDb250ZW50TG9hZGVyOiBMb2FkaW5nICR7Y29udGVudE1vZHVsZXMubGVuZ3RofSBjb250ZW50IG1vZHVsZXMuLi5gKTtcblxuICAgIGNvbnRlbnRNb2R1bGVzLmZvckVhY2gobW9kdWxlID0+IHtcbiAgICAgIHRoaXMucmVnaXN0ZXJDb250ZW50KG1vZHVsZS5jbGFzc05hbWUsIG1vZHVsZS5jb250ZW50KTtcbiAgICB9KTtcblxuICAgIGNvbnNvbGUubG9nKCfinIUgQ29udGVudExvYWRlcjogQWxsIGNvbnRlbnQgbW9kdWxlcyBsb2FkZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgY29udGVudCBpcyByZWdpc3RlcmVkIGZvciBhIGNsYXNzLlxuICAgKi9cbiAgaGFzQ29udGVudEZvcihjbGFzc05hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lzdGVyZWRDb250ZW50LmhhcyhjbGFzc05hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgcmVnaXN0ZXJlZCBjbGFzcyBuYW1lcy5cbiAgICovXG4gIGdldFJlZ2lzdGVyZWRDbGFzc2VzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLnJlZ2lzdGVyZWRDb250ZW50LmtleXMoKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHJlZ2lzdGVyZWQgY29udGVudCBmb3IgYSBzcGVjaWZpYyBjbGFzcy5cbiAgICovXG4gIGdldENvbnRlbnRGb3IoY2xhc3NOYW1lOiBzdHJpbmcpOiBMYW5ndWFnZXNDb250ZW50IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpc3RlcmVkQ29udGVudC5nZXQoY2xhc3NOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgY29udGVudCByZWdpc3RyYXRpb24gZm9yIGEgY2xhc3MuXG4gICAqL1xuICB1bnJlZ2lzdGVyQ29udGVudChjbGFzc05hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGV4aXN0ZWQgPSB0aGlzLnJlZ2lzdGVyZWRDb250ZW50LmhhcyhjbGFzc05hbWUpO1xuICAgIHRoaXMucmVnaXN0ZXJlZENvbnRlbnQuZGVsZXRlKGNsYXNzTmFtZSk7XG5cbiAgICAvLyBBbHNvIHJlbW92ZSBmcm9tIHRoZSBwcm92aWRlclxuICAgIGlmIChleGlzdGVkICYmIHRoaXMudmFsdGVjaENvbmZpZy5jb250ZW50KSB7XG4gICAgICBjb25zdCB1cGRhdGVkQ29udGVudCA9IHsgLi4udGhpcy52YWx0ZWNoQ29uZmlnLmNvbnRlbnQgfTtcbiAgICAgIGRlbGV0ZSB1cGRhdGVkQ29udGVudFtjbGFzc05hbWVdO1xuICAgICAgdGhpcy52YWx0ZWNoQ29uZmlnLmNvbnRlbnQgPSB1cGRhdGVkQ29udGVudDtcbiAgICAgIGNvbnNvbGUubG9nKGDwn5eR77iPIENvbnRlbnRMb2FkZXI6IFVucmVnaXN0ZXJlZCBjb250ZW50IGZvciBcIiR7Y2xhc3NOYW1lfVwiYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGV4aXN0ZWQ7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgYWxsIHJlZ2lzdGVyZWQgY29udGVudC5cbiAgICovXG4gIGNsZWFyQWxsQ29udGVudCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lzdGVyZWRDb250ZW50LmNsZWFyKCk7XG4gICAgY29uc29sZS5sb2coJ/Cfp7kgQ29udGVudExvYWRlcjogQ2xlYXJlZCBhbGwgcmVnaXN0ZXJlZCBjb250ZW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgY29udGVudCBwcm92aWRlciBzdGF0ZS5cbiAgICogVXNlZnVsIGZvciBkZWJ1Z2dpbmcuXG4gICAqL1xuICBnZXRDb250ZW50UHJvdmlkZXIoKTogUHJvdmlkZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnZhbHRlY2hDb25maWcuY29udGVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiDinIUgQ0xFQU46IEFkZCBjb250ZW50IHRvIHByb3ZpZGVyIHVzaW5nIHByb3BlciBBUElcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgYWRkQ29udGVudFRvUHJvdmlkZXIoY2xhc3NOYW1lOiBzdHJpbmcsIGNvbnRlbnQ6IExhbmd1YWdlc0NvbnRlbnQpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgLy8gR2V0IGN1cnJlbnQgY29udGVudCBwcm92aWRlclxuICAgICAgY29uc3QgY3VycmVudENvbnRlbnQgPSB0aGlzLnZhbHRlY2hDb25maWcuY29udGVudCB8fCB7fTtcblxuICAgICAgLy8gQ3JlYXRlIFRleHRDb250ZW50IGluc3RhbmNlXG4gICAgICBjb25zdCB0ZXh0Q29udGVudCA9IG5ldyBUZXh0Q29udGVudChjb250ZW50KTtcblxuICAgICAgLy8gVXBkYXRlIHRoZSBjb250ZW50IHByb3ZpZGVyIHByb3Blcmx5XG4gICAgICBjb25zdCB1cGRhdGVkQ29udGVudDogUHJvdmlkZXIgPSB7XG4gICAgICAgIC4uLmN1cnJlbnRDb250ZW50LFxuICAgICAgICBbY2xhc3NOYW1lXTogdGV4dENvbnRlbnQsXG4gICAgICB9O1xuXG4gICAgICAvLyBTZXQgdGhlIHVwZGF0ZWQgY29udGVudCAtIHRoaXMgaXMgdGhlIGNsZWFuIHdheVxuICAgICAgdGhpcy52YWx0ZWNoQ29uZmlnLmNvbnRlbnQgPSB1cGRhdGVkQ29udGVudDtcblxuICAgICAgY29uc29sZS5sb2coYPCfk50gQ29udGVudExvYWRlcjogQWRkZWQgXCIke2NsYXNzTmFtZX1cIiB0byBjb250ZW50IHByb3ZpZGVyYCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYOKdjCBDb250ZW50TG9hZGVyOiBFcnJvciBhZGRpbmcgY29udGVudCBmb3IgXCIke2NsYXNzTmFtZX1cIjpgLCBlcnJvcik7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBjb250ZW50IG1vZHVsZSByZWdpc3RyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udGVudE1vZHVsZSB7XG4gIGNsYXNzTmFtZTogc3RyaW5nO1xuICBjb250ZW50OiBMYW5ndWFnZXNDb250ZW50O1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSBjb250ZW50IG1vZHVsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbnRlbnRNb2R1bGUoY2xhc3NOYW1lOiBzdHJpbmcsIGNvbnRlbnQ6IExhbmd1YWdlc0NvbnRlbnQpOiBDb250ZW50TW9kdWxlIHtcbiAgcmV0dXJuIHsgY2xhc3NOYW1lLCBjb250ZW50IH07XG59XG5cbi8qKlxuICog4pyFIENMRUFOOiBHbG9iYWwgcmVnaXN0cnkgdXNpbmcgcHJvcGVyIGFycmF5IGluc3RlYWQgb2YgZ2xvYmFsVGhpcyBoYWNrXG4gKi9cbmNvbnN0IGdsb2JhbENvbnRlbnRSZWdpc3RyeTogQ29udGVudE1vZHVsZVtdID0gW107XG5cbi8qKlxuICogU2ltcGxlIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIGNvbnRlbnQgZGlyZWN0bHkuXG4gKiDinIUgSU1QUk9WRUQ6IENsZWFuZXIgZ2xvYmFsIHJlZ2lzdHJ5IG1hbmFnZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyQ29udGVudChjbGFzc05hbWU6IHN0cmluZywgY29udGVudDogTGFuZ3VhZ2VzQ29udGVudCk6IHZvaWQge1xuICAvLyBBZGQgdG8gZ2xvYmFsIHJlZ2lzdHJ5XG4gIGdsb2JhbENvbnRlbnRSZWdpc3RyeS5wdXNoKHsgY2xhc3NOYW1lLCBjb250ZW50IH0pO1xuICBjb25zb2xlLmxvZyhg8J+TnSByZWdpc3RlckNvbnRlbnQ6IFF1ZXVlZCBcIiR7Y2xhc3NOYW1lfVwiIGZvciByZWdpc3RyYXRpb25gKTtcbn1cblxuLyoqXG4gKiBMb2FkIGFsbCBjb250ZW50IGZyb20gdGhlIGdsb2JhbCByZWdpc3RyeS5cbiAqIOKchSBJTVBST1ZFRDogQmV0dGVyIGVycm9yIGhhbmRsaW5nIGFuZCBsb2dnaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkUmVnaXN0ZXJlZENvbnRlbnQoY29udGVudExvYWRlcjogQ29udGVudExvYWRlclNlcnZpY2UpOiB2b2lkIHtcbiAgaWYgKGdsb2JhbENvbnRlbnRSZWdpc3RyeS5sZW5ndGggPT09IDApIHtcbiAgICBjb25zb2xlLmxvZygn4oS577iPIENvbnRlbnRMb2FkZXI6IE5vIGNvbnRlbnQgcmVnaXN0ZXJlZCB0byBsb2FkJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc29sZS5sb2coXG4gICAgYPCfmoAgQ29udGVudExvYWRlcjogTG9hZGluZyAke2dsb2JhbENvbnRlbnRSZWdpc3RyeS5sZW5ndGh9IHJlZ2lzdGVyZWQgY29udGVudCBtb2R1bGVzLi4uYFxuICApO1xuXG4gIHRyeSB7XG4gICAgLy8gTG9hZCBhbGwgY29udGVudFxuICAgIGNvbnRlbnRMb2FkZXIubG9hZENvbnRlbnQoWy4uLmdsb2JhbENvbnRlbnRSZWdpc3RyeV0pO1xuXG4gICAgLy8gQ2xlYXIgdGhlIHJlZ2lzdHJ5IGFmdGVyIGxvYWRpbmdcbiAgICBnbG9iYWxDb250ZW50UmVnaXN0cnkubGVuZ3RoID0gMDtcblxuICAgIGNvbnNvbGUubG9nKCfwn46JIENvbnRlbnRMb2FkZXI6IEFsbCByZWdpc3RlcmVkIGNvbnRlbnQgbG9hZGVkIGFuZCByZWdpc3RyeSBjbGVhcmVkJyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc29sZS5lcnJvcign4p2MIENvbnRlbnRMb2FkZXI6IEVycm9yIGxvYWRpbmcgcmVnaXN0ZXJlZCBjb250ZW50OicsIGVycm9yKTtcbiAgfVxufVxuXG4vKipcbiAqIOKchSBORVc6IERlYnVnZ2luZyBoZWxwZXJcbiAqIEdldCBjdXJyZW50IGdsb2JhbCByZWdpc3RyeSBzdGF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVnaXN0ZXJlZENvbnRlbnRRdWV1ZSgpOiBDb250ZW50TW9kdWxlW10ge1xuICByZXR1cm4gWy4uLmdsb2JhbENvbnRlbnRSZWdpc3RyeV07XG59XG5cbi8qKlxuICog4pyFIE5FVzogRGVidWdnaW5nIGhlbHBlclxuICogQ2xlYXIgdGhlIGdsb2JhbCByZWdpc3RyeSB3aXRob3V0IGxvYWRpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyUmVnaXN0ZXJlZENvbnRlbnRRdWV1ZSgpOiB2b2lkIHtcbiAgY29uc3QgY291bnQgPSBnbG9iYWxDb250ZW50UmVnaXN0cnkubGVuZ3RoO1xuICBnbG9iYWxDb250ZW50UmVnaXN0cnkubGVuZ3RoID0gMDtcbiAgY29uc29sZS5sb2coYPCfp7kgQ29udGVudExvYWRlcjogQ2xlYXJlZCAke2NvdW50fSBpdGVtcyBmcm9tIHJlZ2lzdHJhdGlvbiBxdWV1ZWApO1xufVxuIl19
|