valtech-components 2.0.302 → 2.0.305

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 (32) hide show
  1. package/esm2022/lib/components/atoms/button/button.component.mjs +103 -23
  2. package/esm2022/lib/components/types.mjs +1 -1
  3. package/esm2022/lib/services/lang-provider/content.mjs +1 -72
  4. package/esm2022/lib/services/lang-provider/lang-provider.service.mjs +4 -9
  5. package/esm2022/lib/shared/utils/content.mjs +2 -8
  6. package/esm2022/public-api.mjs +1 -12
  7. package/fesm2022/valtech-components.mjs +124 -2824
  8. package/fesm2022/valtech-components.mjs.map +1 -1
  9. package/lib/components/atoms/button/button.component.d.ts +33 -2
  10. package/lib/components/types.d.ts +19 -7
  11. package/package.json +1 -1
  12. package/public-api.d.ts +0 -10
  13. package/esm2022/lib/examples/comprehensive-link-test.component.mjs +0 -208
  14. package/esm2022/lib/examples/custom-content-demo.component.mjs +0 -291
  15. package/esm2022/lib/examples/display-demo.component.mjs +0 -518
  16. package/esm2022/lib/examples/display-simple-example.component.mjs +0 -202
  17. package/esm2022/lib/examples/link-processing-example.component.mjs +0 -233
  18. package/esm2022/lib/examples/multi-language-demo.component.mjs +0 -304
  19. package/esm2022/lib/examples/reactive-components-demo.component.mjs +0 -303
  20. package/esm2022/lib/examples/reactivity-test.component.mjs +0 -200
  21. package/esm2022/lib/examples/selector-examples.component.mjs +0 -234
  22. package/esm2022/lib/examples/user-issue-test.component.mjs +0 -267
  23. package/lib/examples/comprehensive-link-test.component.d.ts +0 -23
  24. package/lib/examples/custom-content-demo.component.d.ts +0 -26
  25. package/lib/examples/display-demo.component.d.ts +0 -62
  26. package/lib/examples/display-simple-example.component.d.ts +0 -23
  27. package/lib/examples/link-processing-example.component.d.ts +0 -26
  28. package/lib/examples/multi-language-demo.component.d.ts +0 -34
  29. package/lib/examples/reactive-components-demo.component.d.ts +0 -45
  30. package/lib/examples/reactivity-test.component.d.ts +0 -27
  31. package/lib/examples/selector-examples.component.d.ts +0 -21
  32. package/lib/examples/user-issue-test.component.d.ts +0 -31
@@ -1,291 +0,0 @@
1
- import { CommonModule } from '@angular/common';
2
- import { Component, inject } from '@angular/core';
3
- import { IonButton, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonItem, IonLabel, } from '@ionic/angular/standalone';
4
- import { ContentService } from '../services/content.service';
5
- import { LANGUAGES } from '../services/lang-provider/types';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "@angular/common";
8
- export class CustomContentDemoComponent {
9
- constructor() {
10
- this.content = inject(ContentService);
11
- this.currentLang = 'es';
12
- // Contenido global predefinido (sin className)
13
- this.saveText$ = this.content.fromContent({ key: 'save' });
14
- this.cancelText$ = this.content.fromContent({ key: 'cancel' });
15
- this.deleteText$ = this.content.fromContent({ key: 'delete' });
16
- this.loadingText$ = this.content.fromContent({ key: 'loading' });
17
- // Tu contenido global personalizado (sin className)
18
- this.dashboardText$ = this.content.fromContent({ key: 'dashboard' });
19
- this.profileText$ = this.content.fromContent({ key: 'profile' });
20
- this.settingsText$ = this.content.fromContent({ key: 'settings' });
21
- this.welcomeText$ = this.content.fromContent({
22
- key: 'welcome',
23
- interpolation: { appName: 'Mi Aplicación' },
24
- });
25
- // Contenido específico del componente Language (con className)
26
- this.spanishText$ = this.content.fromContent({
27
- className: 'Language',
28
- key: 'spanish',
29
- });
30
- this.englishText$ = this.content.fromContent({
31
- className: 'Language',
32
- key: 'english',
33
- });
34
- this.descriptionText$ = this.content.fromContent({
35
- className: 'Language',
36
- key: 'description',
37
- });
38
- // Para debug - texto síncrono
39
- this.saveTextSync = '';
40
- this.dashboardTextSync = '';
41
- this.languageDescSync = '';
42
- }
43
- ngOnInit() {
44
- // Obtener idioma actual
45
- this.content.currentLang$.subscribe(lang => {
46
- this.currentLang = lang;
47
- });
48
- // Obtener textos síncronos para debug
49
- this.updateSyncTexts();
50
- // 🔍 DIAGNÓSTICO: Verificar configuración
51
- this.diagnoseConfiguration();
52
- }
53
- switchLanguage() {
54
- const newLang = this.currentLang === 'es' ? LANGUAGES.EN : LANGUAGES.ES;
55
- this.content.setLang(newLang);
56
- // Actualizar textos síncronos después del cambio
57
- setTimeout(() => {
58
- this.updateSyncTexts();
59
- }, 100);
60
- }
61
- updateSyncTexts() {
62
- // Contenido global predefinido
63
- this.saveTextSync = this.content.getText('save');
64
- // Tu contenido global personalizado
65
- this.dashboardTextSync = this.content.getText('dashboard');
66
- // Contenido específico del componente - SOLUCIÓN TEMPORAL
67
- // En lugar de usar getText, acceder directamente
68
- try {
69
- const langService = this.content.langService;
70
- const languageContent = langService.content['Language'];
71
- const currentLang = langService.selectedLang?.value || 'es';
72
- const classContent = languageContent?.Content?.[currentLang];
73
- this.languageDescSync = classContent?.['description'] || 'No encontrado';
74
- }
75
- catch (error) {
76
- this.languageDescSync = `Error: ${error}`;
77
- }
78
- }
79
- diagnoseConfiguration() {
80
- console.log('=== DIAGNÓSTICO DE CONFIGURACIÓN ===');
81
- // Verificar acceso directo al servicio
82
- console.log('ContentService available:', !!this.content);
83
- console.log('Current language:', this.content.currentLang);
84
- // 🔍 Diagnóstico detallado del contenido Language
85
- console.log('\n--- DIAGNÓSTICO DETALLADO LANGUAGE ---');
86
- try {
87
- // Acceder directamente al LangService
88
- const langService = this.content.langService;
89
- console.log('LangService available:', !!langService);
90
- // Verificar si existe el contenido Language
91
- const languageContent = langService.content['Language'];
92
- console.log('Language content exists:', !!languageContent);
93
- if (languageContent) {
94
- console.log('Language content structure:', languageContent);
95
- console.log('Language content.Content:', languageContent.Content);
96
- // Verificar contenido en español
97
- const esContent = languageContent.Content?.es;
98
- console.log('ES content:', esContent);
99
- console.log('ES description:', esContent?.description);
100
- // Verificar contenido en inglés
101
- const enContent = languageContent.Content?.en;
102
- console.log('EN content:', enContent);
103
- console.log('EN description:', enContent?.description);
104
- }
105
- // Verificar current lang
106
- const currentLang = langService.selectedLang?.value;
107
- console.log('Current selected language:', currentLang);
108
- }
109
- catch (error) {
110
- console.log('❌ Error accessing LangService:', error);
111
- }
112
- // Intentar acceso síncrono a contenido global predefinido
113
- try {
114
- const saveText = this.content.getText('save');
115
- console.log('✅ Global predefinido (save):', saveText);
116
- }
117
- catch (error) {
118
- console.log('❌ Error global predefinido (save):', error);
119
- }
120
- // Intentar acceso síncrono a contenido global personalizado
121
- try {
122
- const dashboardText = this.content.getText('dashboard');
123
- console.log('✅ Global personalizado (dashboard):', dashboardText);
124
- }
125
- catch (error) {
126
- console.log('❌ Error global personalizado (dashboard):', error);
127
- }
128
- // Intentar acceso síncrono a contenido de componente
129
- try {
130
- const spanishText = this.content.getText('Language', 'spanish');
131
- console.log('✅ Componente Language (spanish):', spanishText);
132
- // 🔍 Debug paso a paso para spanish
133
- const langService = this.content.langService;
134
- const languageContent = langService.content['Language'];
135
- const currentLang = langService.selectedLang?.value;
136
- const classContent = languageContent?.Content[currentLang];
137
- console.log('🔍 Debug spanish - currentLang:', currentLang);
138
- console.log('🔍 Debug spanish - classContent:', classContent);
139
- console.log('🔍 Debug spanish - classContent["spanish"]:', classContent?.['spanish']);
140
- }
141
- catch (error) {
142
- console.log('❌ Error componente Language (spanish):', error);
143
- }
144
- // Intentar acceso síncrono a contenido de componente
145
- try {
146
- const descriptionText = this.content.getText('Language', 'description');
147
- console.log('✅ Componente Language (description):', descriptionText);
148
- // 🔍 Debug paso a paso para description
149
- const langService = this.content.langService;
150
- const languageContent = langService.content['Language'];
151
- const currentLang = langService.selectedLang?.value;
152
- const classContent = languageContent?.Content[currentLang];
153
- console.log('🔍 Debug description - currentLang:', currentLang);
154
- console.log('🔍 Debug description - classContent:', classContent);
155
- console.log('🔍 Debug description - classContent["description"]:', classContent?.['description']);
156
- }
157
- catch (error) {
158
- console.log('❌ Error componente Language (description):', error);
159
- }
160
- }
161
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomContentDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
162
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CustomContentDemoComponent, isStandalone: true, selector: "app-custom-content-demo", ngImport: i0, template: `
163
- <ion-card>
164
- <ion-card-header>
165
- <ion-card-title>Demo de Contenido Personalizado</ion-card-title>
166
- </ion-card-header>
167
-
168
- <ion-card-content>
169
- <!-- Contenido global predefinido -->
170
- <div style="margin-bottom: 20px;">
171
- <h3>Contenido Global Predefinido:</h3>
172
- <ion-button>{{ saveText$ | async }}</ion-button>
173
- <ion-button color="medium">{{ cancelText$ | async }}</ion-button>
174
- <ion-button color="danger">{{ deleteText$ | async }}</ion-button>
175
- <p><strong>Estado:</strong> {{ loadingText$ | async }}</p>
176
- </div>
177
-
178
- <!-- Tu contenido global personalizado -->
179
- <div style="margin-bottom: 20px;">
180
- <h3>Tu Contenido Global Personalizado:</h3>
181
- <p><strong>Sección:</strong> {{ dashboardText$ | async }}</p>
182
- <p><strong>Usuario:</strong> {{ profileText$ | async }}</p>
183
- <p><strong>Config:</strong> {{ settingsText$ | async }}</p>
184
- <p>{{ welcomeText$ | async }}</p>
185
- </div>
186
-
187
- <!-- Contenido específico del componente Language -->
188
- <div style="margin-bottom: 20px;">
189
- <h3>Contenido del Componente Language:</h3>
190
- <ion-item>
191
- <ion-label> <strong>Español:</strong> {{ spanishText$ | async }} </ion-label>
192
- </ion-item>
193
- <ion-item>
194
- <ion-label> <strong>Inglés:</strong> {{ englishText$ | async }} </ion-label>
195
- </ion-item>
196
- <p>
197
- <em>{{ descriptionText$ | async }}</em>
198
- </p>
199
- </div>
200
-
201
- <!-- Botón para cambiar idioma -->
202
- <div>
203
- <h3>Control de Idioma:</h3>
204
- <ion-button (click)="switchLanguage()" color="secondary">
205
- Cambiar a {{ currentLang === 'es' ? 'English' : 'Español' }}
206
- </ion-button>
207
- <p>
208
- <small>Idioma actual: {{ currentLang }}</small>
209
- </p>
210
- </div>
211
-
212
- <!-- Debug info -->
213
- <div style="margin-top: 20px; padding: 10px; background: #f5f5f5; border-radius: 4px;">
214
- <h4>Debug Info:</h4>
215
- <p><strong>Save (sync):</strong> {{ saveTextSync }}</p>
216
- <p><strong>Dashboard (sync):</strong> {{ dashboardTextSync }}</p>
217
- <p><strong>Language Description (sync):</strong> {{ languageDescSync }}</p>
218
- </div>
219
- </ion-card-content>
220
- </ion-card>
221
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }] }); }
222
- }
223
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomContentDemoComponent, decorators: [{
224
- type: Component,
225
- args: [{
226
- selector: 'app-custom-content-demo',
227
- standalone: true,
228
- imports: [CommonModule, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonButton, IonItem, IonLabel],
229
- template: `
230
- <ion-card>
231
- <ion-card-header>
232
- <ion-card-title>Demo de Contenido Personalizado</ion-card-title>
233
- </ion-card-header>
234
-
235
- <ion-card-content>
236
- <!-- Contenido global predefinido -->
237
- <div style="margin-bottom: 20px;">
238
- <h3>Contenido Global Predefinido:</h3>
239
- <ion-button>{{ saveText$ | async }}</ion-button>
240
- <ion-button color="medium">{{ cancelText$ | async }}</ion-button>
241
- <ion-button color="danger">{{ deleteText$ | async }}</ion-button>
242
- <p><strong>Estado:</strong> {{ loadingText$ | async }}</p>
243
- </div>
244
-
245
- <!-- Tu contenido global personalizado -->
246
- <div style="margin-bottom: 20px;">
247
- <h3>Tu Contenido Global Personalizado:</h3>
248
- <p><strong>Sección:</strong> {{ dashboardText$ | async }}</p>
249
- <p><strong>Usuario:</strong> {{ profileText$ | async }}</p>
250
- <p><strong>Config:</strong> {{ settingsText$ | async }}</p>
251
- <p>{{ welcomeText$ | async }}</p>
252
- </div>
253
-
254
- <!-- Contenido específico del componente Language -->
255
- <div style="margin-bottom: 20px;">
256
- <h3>Contenido del Componente Language:</h3>
257
- <ion-item>
258
- <ion-label> <strong>Español:</strong> {{ spanishText$ | async }} </ion-label>
259
- </ion-item>
260
- <ion-item>
261
- <ion-label> <strong>Inglés:</strong> {{ englishText$ | async }} </ion-label>
262
- </ion-item>
263
- <p>
264
- <em>{{ descriptionText$ | async }}</em>
265
- </p>
266
- </div>
267
-
268
- <!-- Botón para cambiar idioma -->
269
- <div>
270
- <h3>Control de Idioma:</h3>
271
- <ion-button (click)="switchLanguage()" color="secondary">
272
- Cambiar a {{ currentLang === 'es' ? 'English' : 'Español' }}
273
- </ion-button>
274
- <p>
275
- <small>Idioma actual: {{ currentLang }}</small>
276
- </p>
277
- </div>
278
-
279
- <!-- Debug info -->
280
- <div style="margin-top: 20px; padding: 10px; background: #f5f5f5; border-radius: 4px;">
281
- <h4>Debug Info:</h4>
282
- <p><strong>Save (sync):</strong> {{ saveTextSync }}</p>
283
- <p><strong>Dashboard (sync):</strong> {{ dashboardTextSync }}</p>
284
- <p><strong>Language Description (sync):</strong> {{ languageDescSync }}</p>
285
- </div>
286
- </ion-card-content>
287
- </ion-card>
288
- `,
289
- }]
290
- }] });
291
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLWNvbnRlbnQtZGVtby5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy92YWx0ZWNoLWNvbXBvbmVudHMvc3JjL2xpYi9leGFtcGxlcy9jdXN0b20tY29udGVudC1kZW1vLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxFQUNMLFNBQVMsRUFDVCxPQUFPLEVBQ1AsY0FBYyxFQUNkLGFBQWEsRUFDYixZQUFZLEVBQ1osT0FBTyxFQUNQLFFBQVEsR0FDVCxNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7OztBQW1FNUQsTUFBTSxPQUFPLDBCQUEwQjtJQWpFdkM7UUFrRVUsWUFBTyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUV6QyxnQkFBVyxHQUFHLElBQUksQ0FBQztRQUVuQiwrQ0FBK0M7UUFDL0MsY0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsZ0JBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQzFELGdCQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUMxRCxpQkFBWSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsR0FBRyxF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QWEsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUM7b0JBQzNHLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyRFQ7aUJBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBpbmplY3QsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgSW9uQnV0dG9uLFxuICBJb25DYXJkLFxuICBJb25DYXJkQ29udGVudCxcbiAgSW9uQ2FyZEhlYWRlcixcbiAgSW9uQ2FyZFRpdGxlLFxuICBJb25JdGVtLFxuICBJb25MYWJlbCxcbn0gZnJvbSAnQGlvbmljL2FuZ3VsYXIvc3RhbmRhbG9uZSc7XG5pbXBvcnQgeyBDb250ZW50U2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2NvbnRlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBMQU5HVUFHRVMgfSBmcm9tICcuLi9zZXJ2aWNlcy9sYW5nLXByb3ZpZGVyL3R5cGVzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWN1c3RvbS1jb250ZW50LWRlbW8nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBJb25DYXJkLCBJb25DYXJkQ29udGVudCwgSW9uQ2FyZEhlYWRlciwgSW9uQ2FyZFRpdGxlLCBJb25CdXR0b24sIElvbkl0ZW0sIElvbkxhYmVsXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8aW9uLWNhcmQ+XG4gICAgICA8aW9uLWNhcmQtaGVhZGVyPlxuICAgICAgICA8aW9uLWNhcmQtdGl0bGU+RGVtbyBkZSBDb250ZW5pZG8gUGVyc29uYWxpemFkbzwvaW9uLWNhcmQtdGl0bGU+XG4gICAgICA8L2lvbi1jYXJkLWhlYWRlcj5cblxuICAgICAgPGlvbi1jYXJkLWNvbnRlbnQ+XG4gICAgICAgIDwhLS0gQ29udGVuaWRvIGdsb2JhbCBwcmVkZWZpbmlkbyAtLT5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDIwcHg7XCI+XG4gICAgICAgICAgPGgzPkNvbnRlbmlkbyBHbG9iYWwgUHJlZGVmaW5pZG86PC9oMz5cbiAgICAgICAgICA8aW9uLWJ1dHRvbj57eyBzYXZlVGV4dCQgfCBhc3luYyB9fTwvaW9uLWJ1dHRvbj5cbiAgICAgICAgICA8aW9uLWJ1dHRvbiBjb2xvcj1cIm1lZGl1bVwiPnt7IGNhbmNlbFRleHQkIHwgYXN5bmMgfX08L2lvbi1idXR0b24+XG4gICAgICAgICAgPGlvbi1idXR0b24gY29sb3I9XCJkYW5nZXJcIj57eyBkZWxldGVUZXh0JCB8IGFzeW5jIH19PC9pb24tYnV0dG9uPlxuICAgICAgICAgIDxwPjxzdHJvbmc+RXN0YWRvOjwvc3Ryb25nPiB7eyBsb2FkaW5nVGV4dCQgfCBhc3luYyB9fTwvcD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBUdSBjb250ZW5pZG8gZ2xvYmFsIHBlcnNvbmFsaXphZG8gLS0+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAyMHB4O1wiPlxuICAgICAgICAgIDxoMz5UdSBDb250ZW5pZG8gR2xvYmFsIFBlcnNvbmFsaXphZG86PC9oMz5cbiAgICAgICAgICA8cD48c3Ryb25nPlNlY2Npw7NuOjwvc3Ryb25nPiB7eyBkYXNoYm9hcmRUZXh0JCB8IGFzeW5jIH19PC9wPlxuICAgICAgICAgIDxwPjxzdHJvbmc+VXN1YXJpbzo8L3N0cm9uZz4ge3sgcHJvZmlsZVRleHQkIHwgYXN5bmMgfX08L3A+XG4gICAgICAgICAgPHA+PHN0cm9uZz5Db25maWc6PC9zdHJvbmc+IHt7IHNldHRpbmdzVGV4dCQgfCBhc3luYyB9fTwvcD5cbiAgICAgICAgICA8cD57eyB3ZWxjb21lVGV4dCQgfCBhc3luYyB9fTwvcD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBDb250ZW5pZG8gZXNwZWPDrWZpY28gZGVsIGNvbXBvbmVudGUgTGFuZ3VhZ2UgLS0+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAyMHB4O1wiPlxuICAgICAgICAgIDxoMz5Db250ZW5pZG8gZGVsIENvbXBvbmVudGUgTGFuZ3VhZ2U6PC9oMz5cbiAgICAgICAgICA8aW9uLWl0ZW0+XG4gICAgICAgICAgICA8aW9uLWxhYmVsPiA8c3Ryb25nPkVzcGHDsW9sOjwvc3Ryb25nPiB7eyBzcGFuaXNoVGV4dCQgfCBhc3luYyB9fSA8L2lvbi1sYWJlbD5cbiAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICAgIDxpb24taXRlbT5cbiAgICAgICAgICAgIDxpb24tbGFiZWw+IDxzdHJvbmc+SW5nbMOpczo8L3N0cm9uZz4ge3sgZW5nbGlzaFRleHQkIHwgYXN5bmMgfX0gPC9pb24tbGFiZWw+XG4gICAgICAgICAgPC9pb24taXRlbT5cbiAgICAgICAgICA8cD5cbiAgICAgICAgICAgIDxlbT57eyBkZXNjcmlwdGlvblRleHQkIHwgYXN5bmMgfX08L2VtPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBCb3TDs24gcGFyYSBjYW1iaWFyIGlkaW9tYSAtLT5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8aDM+Q29udHJvbCBkZSBJZGlvbWE6PC9oMz5cbiAgICAgICAgICA8aW9uLWJ1dHRvbiAoY2xpY2spPVwic3dpdGNoTGFuZ3VhZ2UoKVwiIGNvbG9yPVwic2Vjb25kYXJ5XCI+XG4gICAgICAgICAgICBDYW1iaWFyIGEge3sgY3VycmVudExhbmcgPT09ICdlcycgPyAnRW5nbGlzaCcgOiAnRXNwYcOxb2wnIH19XG4gICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICAgIDxwPlxuICAgICAgICAgICAgPHNtYWxsPklkaW9tYSBhY3R1YWw6IHt7IGN1cnJlbnRMYW5nIH19PC9zbWFsbD5cbiAgICAgICAgICA8L3A+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gRGVidWcgaW5mbyAtLT5cbiAgICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDIwcHg7IHBhZGRpbmc6IDEwcHg7IGJhY2tncm91bmQ6ICNmNWY1ZjU7IGJvcmRlci1yYWRpdXM6IDRweDtcIj5cbiAgICAgICAgICA8aDQ+RGVidWcgSW5mbzo8L2g0PlxuICAgICAgICAgIDxwPjxzdHJvbmc+U2F2ZSAoc3luYyk6PC9zdHJvbmc+IHt7IHNhdmVUZXh0U3luYyB9fTwvcD5cbiAgICAgICAgICA8cD48c3Ryb25nPkRhc2hib2FyZCAoc3luYyk6PC9zdHJvbmc+IHt7IGRhc2hib2FyZFRleHRTeW5jIH19PC9wPlxuICAgICAgICAgIDxwPjxzdHJvbmc+TGFuZ3VhZ2UgRGVzY3JpcHRpb24gKHN5bmMpOjwvc3Ryb25nPiB7eyBsYW5ndWFnZURlc2NTeW5jIH19PC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvaW9uLWNhcmQtY29udGVudD5cbiAgICA8L2lvbi1jYXJkPlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBDdXN0b21Db250ZW50RGVtb0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByaXZhdGUgY29udGVudCA9IGluamVjdChDb250ZW50U2VydmljZSk7XG5cbiAgY3VycmVudExhbmcgPSAnZXMnO1xuXG4gIC8vIENvbnRlbmlkbyBnbG9iYWwgcHJlZGVmaW5pZG8gKHNpbiBjbGFzc05hbWUpXG4gIHNhdmVUZXh0JCA9IHRoaXMuY29udGVudC5mcm9tQ29udGVudCh7IGtleTogJ3NhdmUnIH0pO1xuICBjYW5jZWxUZXh0JCA9IHRoaXMuY29udGVudC5mcm9tQ29udGVudCh7IGtleTogJ2NhbmNlbCcgfSk7XG4gIGRlbGV0ZVRleHQkID0gdGhpcy5jb250ZW50LmZyb21Db250ZW50KHsga2V5OiAnZGVsZXRlJyB9KTtcbiAgbG9hZGluZ1RleHQkID0gdGhpcy5jb250ZW50LmZyb21Db250ZW50KHsga2V5OiAnbG9hZGluZycgfSk7XG5cbiAgLy8gVHUgY29udGVuaWRvIGdsb2JhbCBwZXJzb25hbGl6YWRvIChzaW4gY2xhc3NOYW1lKVxuICBkYXNoYm9hcmRUZXh0JCA9IHRoaXMuY29udGVudC5mcm9tQ29udGVudCh7IGtleTogJ2Rhc2hib2FyZCcgfSk7XG4gIHByb2ZpbGVUZXh0JCA9IHRoaXMuY29udGVudC5mcm9tQ29udGVudCh7IGtleTogJ3Byb2ZpbGUnIH0pO1xuICBzZXR0aW5nc1RleHQkID0gdGhpcy5jb250ZW50LmZyb21Db250ZW50KHsga2V5OiAnc2V0dGluZ3MnIH0pO1xuICB3ZWxjb21lVGV4dCQgPSB0aGlzLmNvbnRlbnQuZnJvbUNvbnRlbnQoe1xuICAgIGtleTogJ3dlbGNvbWUnLFxuICAgIGludGVycG9sYXRpb246IHsgYXBwTmFtZTogJ01pIEFwbGljYWNpw7NuJyB9LFxuICB9KTtcblxuICAvLyBDb250ZW5pZG8gZXNwZWPDrWZpY28gZGVsIGNvbXBvbmVudGUgTGFuZ3VhZ2UgKGNvbiBjbGFzc05hbWUpXG4gIHNwYW5pc2hUZXh0JCA9IHRoaXMuY29udGVudC5mcm9tQ29udGVudCh7XG4gICAgY2xhc3NOYW1lOiAnTGFuZ3VhZ2UnLFxuICAgIGtleTogJ3NwYW5pc2gnLFxuICB9KTtcbiAgZW5nbGlzaFRleHQkID0gdGhpcy5jb250ZW50LmZyb21Db250ZW50KHtcbiAgICBjbGFzc05hbWU6ICdMYW5ndWFnZScsXG4gICAga2V5OiAnZW5nbGlzaCcsXG4gIH0pO1xuICBkZXNjcmlwdGlvblRleHQkID0gdGhpcy5jb250ZW50LmZyb21Db250ZW50KHtcbiAgICBjbGFzc05hbWU6ICdMYW5ndWFnZScsXG4gICAga2V5OiAnZGVzY3JpcHRpb24nLFxuICB9KTtcblxuICAvLyBQYXJhIGRlYnVnIC0gdGV4dG8gc8OtbmNyb25vXG4gIHNhdmVUZXh0U3luYyA9ICcnO1xuICBkYXNoYm9hcmRUZXh0U3luYyA9ICcnO1xuICBsYW5ndWFnZURlc2NTeW5jID0gJyc7XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgLy8gT2J0ZW5lciBpZGlvbWEgYWN0dWFsXG4gICAgdGhpcy5jb250ZW50LmN1cnJlbnRMYW5nJC5zdWJzY3JpYmUobGFuZyA9PiB7XG4gICAgICB0aGlzLmN1cnJlbnRMYW5nID0gbGFuZztcbiAgICB9KTtcblxuICAgIC8vIE9idGVuZXIgdGV4dG9zIHPDrW5jcm9ub3MgcGFyYSBkZWJ1Z1xuICAgIHRoaXMudXBkYXRlU3luY1RleHRzKCk7XG5cbiAgICAvLyDwn5SNIERJQUdOw5NTVElDTzogVmVyaWZpY2FyIGNvbmZpZ3VyYWNpw7NuXG4gICAgdGhpcy5kaWFnbm9zZUNvbmZpZ3VyYXRpb24oKTtcbiAgfVxuXG4gIHN3aXRjaExhbmd1YWdlKCkge1xuICAgIGNvbnN0IG5ld0xhbmcgPSB0aGlzLmN1cnJlbnRMYW5nID09PSAnZXMnID8gTEFOR1VBR0VTLkVOIDogTEFOR1VBR0VTLkVTO1xuICAgIHRoaXMuY29udGVudC5zZXRMYW5nKG5ld0xhbmcpO1xuXG4gICAgLy8gQWN0dWFsaXphciB0ZXh0b3Mgc8OtbmNyb25vcyBkZXNwdcOpcyBkZWwgY2FtYmlvXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZVN5bmNUZXh0cygpO1xuICAgIH0sIDEwMCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVN5bmNUZXh0cygpIHtcbiAgICAvLyBDb250ZW5pZG8gZ2xvYmFsIHByZWRlZmluaWRvXG4gICAgdGhpcy5zYXZlVGV4dFN5bmMgPSB0aGlzLmNvbnRlbnQuZ2V0VGV4dCgnc2F2ZScpO1xuXG4gICAgLy8gVHUgY29udGVuaWRvIGdsb2JhbCBwZXJzb25hbGl6YWRvXG4gICAgdGhpcy5kYXNoYm9hcmRUZXh0U3luYyA9IHRoaXMuY29udGVudC5nZXRUZXh0KCdkYXNoYm9hcmQnKTtcblxuICAgIC8vIENvbnRlbmlkbyBlc3BlY8OtZmljbyBkZWwgY29tcG9uZW50ZSAtIFNPTFVDScOTTiBURU1QT1JBTFxuICAgIC8vIEVuIGx1Z2FyIGRlIHVzYXIgZ2V0VGV4dCwgYWNjZWRlciBkaXJlY3RhbWVudGVcbiAgICB0cnkge1xuICAgICAgY29uc3QgbGFuZ1NlcnZpY2UgPSAodGhpcy5jb250ZW50IGFzIGFueSkubGFuZ1NlcnZpY2U7XG4gICAgICBjb25zdCBsYW5ndWFnZUNvbnRlbnQgPSBsYW5nU2VydmljZS5jb250ZW50WydMYW5ndWFnZSddO1xuICAgICAgY29uc3QgY3VycmVudExhbmcgPSBsYW5nU2VydmljZS5zZWxlY3RlZExhbmc/LnZhbHVlIHx8ICdlcyc7XG4gICAgICBjb25zdCBjbGFzc0NvbnRlbnQgPSBsYW5ndWFnZUNvbnRlbnQ/LkNvbnRlbnQ/LltjdXJyZW50TGFuZ107XG4gICAgICB0aGlzLmxhbmd1YWdlRGVzY1N5bmMgPSBjbGFzc0NvbnRlbnQ/LlsnZGVzY3JpcHRpb24nXSB8fCAnTm8gZW5jb250cmFkbyc7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMubGFuZ3VhZ2VEZXNjU3luYyA9IGBFcnJvcjogJHtlcnJvcn1gO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGlhZ25vc2VDb25maWd1cmF0aW9uKCkge1xuICAgIGNvbnNvbGUubG9nKCc9PT0gRElBR07Dk1NUSUNPIERFIENPTkZJR1VSQUNJw5NOID09PScpO1xuXG4gICAgLy8gVmVyaWZpY2FyIGFjY2VzbyBkaXJlY3RvIGFsIHNlcnZpY2lvXG4gICAgY29uc29sZS5sb2coJ0NvbnRlbnRTZXJ2aWNlIGF2YWlsYWJsZTonLCAhIXRoaXMuY29udGVudCk7XG4gICAgY29uc29sZS5sb2coJ0N1cnJlbnQgbGFuZ3VhZ2U6JywgdGhpcy5jb250ZW50LmN1cnJlbnRMYW5nKTtcblxuICAgIC8vIPCflI0gRGlhZ27Ds3N0aWNvIGRldGFsbGFkbyBkZWwgY29udGVuaWRvIExhbmd1YWdlXG4gICAgY29uc29sZS5sb2coJ1xcbi0tLSBESUFHTsOTU1RJQ08gREVUQUxMQURPIExBTkdVQUdFIC0tLScpO1xuICAgIHRyeSB7XG4gICAgICAvLyBBY2NlZGVyIGRpcmVjdGFtZW50ZSBhbCBMYW5nU2VydmljZVxuICAgICAgY29uc3QgbGFuZ1NlcnZpY2UgPSAodGhpcy5jb250ZW50IGFzIGFueSkubGFuZ1NlcnZpY2U7XG4gICAgICBjb25zb2xlLmxvZygnTGFuZ1NlcnZpY2UgYXZhaWxhYmxlOicsICEhbGFuZ1NlcnZpY2UpO1xuXG4gICAgICAvLyBWZXJpZmljYXIgc2kgZXhpc3RlIGVsIGNvbnRlbmlkbyBMYW5ndWFnZVxuICAgICAgY29uc3QgbGFuZ3VhZ2VDb250ZW50ID0gbGFuZ1NlcnZpY2UuY29udGVudFsnTGFuZ3VhZ2UnXTtcbiAgICAgIGNvbnNvbGUubG9nKCdMYW5ndWFnZSBjb250ZW50IGV4aXN0czonLCAhIWxhbmd1YWdlQ29udGVudCk7XG5cbiAgICAgIGlmIChsYW5ndWFnZUNvbnRlbnQpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ0xhbmd1YWdlIGNvbnRlbnQgc3RydWN0dXJlOicsIGxhbmd1YWdlQ29udGVudCk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdMYW5ndWFnZSBjb250ZW50LkNvbnRlbnQ6JywgbGFuZ3VhZ2VDb250ZW50LkNvbnRlbnQpO1xuXG4gICAgICAgIC8vIFZlcmlmaWNhciBjb250ZW5pZG8gZW4gZXNwYcOxb2xcbiAgICAgICAgY29uc3QgZXNDb250ZW50ID0gbGFuZ3VhZ2VDb250ZW50LkNvbnRlbnQ/LmVzO1xuICAgICAgICBjb25zb2xlLmxvZygnRVMgY29udGVudDonLCBlc0NvbnRlbnQpO1xuICAgICAgICBjb25zb2xlLmxvZygnRVMgZGVzY3JpcHRpb246JywgZXNDb250ZW50Py5kZXNjcmlwdGlvbik7XG5cbiAgICAgICAgLy8gVmVyaWZpY2FyIGNvbnRlbmlkbyBlbiBpbmdsw6lzXG4gICAgICAgIGNvbnN0IGVuQ29udGVudCA9IGxhbmd1YWdlQ29udGVudC5Db250ZW50Py5lbjtcbiAgICAgICAgY29uc29sZS5sb2coJ0VOIGNvbnRlbnQ6JywgZW5Db250ZW50KTtcbiAgICAgICAgY29uc29sZS5sb2coJ0VOIGRlc2NyaXB0aW9uOicsIGVuQ29udGVudD8uZGVzY3JpcHRpb24pO1xuICAgICAgfVxuXG4gICAgICAvLyBWZXJpZmljYXIgY3VycmVudCBsYW5nXG4gICAgICBjb25zdCBjdXJyZW50TGFuZyA9IGxhbmdTZXJ2aWNlLnNlbGVjdGVkTGFuZz8udmFsdWU7XG4gICAgICBjb25zb2xlLmxvZygnQ3VycmVudCBzZWxlY3RlZCBsYW5ndWFnZTonLCBjdXJyZW50TGFuZyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUubG9nKCfinYwgRXJyb3IgYWNjZXNzaW5nIExhbmdTZXJ2aWNlOicsIGVycm9yKTtcbiAgICB9XG5cbiAgICAvLyBJbnRlbnRhciBhY2Nlc28gc8OtbmNyb25vIGEgY29udGVuaWRvIGdsb2JhbCBwcmVkZWZpbmlkb1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzYXZlVGV4dCA9IHRoaXMuY29udGVudC5nZXRUZXh0KCdzYXZlJyk7XG4gICAgICBjb25zb2xlLmxvZygn4pyFIEdsb2JhbCBwcmVkZWZpbmlkbyAoc2F2ZSk6Jywgc2F2ZVRleHQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmxvZygn4p2MIEVycm9yIGdsb2JhbCBwcmVkZWZpbmlkbyAoc2F2ZSk6JywgZXJyb3IpO1xuICAgIH1cblxuICAgIC8vIEludGVudGFyIGFjY2VzbyBzw61uY3Jvbm8gYSBjb250ZW5pZG8gZ2xvYmFsIHBlcnNvbmFsaXphZG9cbiAgICB0cnkge1xuICAgICAgY29uc3QgZGFzaGJvYXJkVGV4dCA9IHRoaXMuY29udGVudC5nZXRUZXh0KCdkYXNoYm9hcmQnKTtcbiAgICAgIGNvbnNvbGUubG9nKCfinIUgR2xvYmFsIHBlcnNvbmFsaXphZG8gKGRhc2hib2FyZCk6JywgZGFzaGJvYXJkVGV4dCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUubG9nKCfinYwgRXJyb3IgZ2xvYmFsIHBlcnNvbmFsaXphZG8gKGRhc2hib2FyZCk6JywgZXJyb3IpO1xuICAgIH1cblxuICAgIC8vIEludGVudGFyIGFjY2VzbyBzw61uY3Jvbm8gYSBjb250ZW5pZG8gZGUgY29tcG9uZW50ZVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBzcGFuaXNoVGV4dCA9IHRoaXMuY29udGVudC5nZXRUZXh0KCdMYW5ndWFnZScsICdzcGFuaXNoJyk7XG4gICAgICBjb25zb2xlLmxvZygn4pyFIENvbXBvbmVudGUgTGFuZ3VhZ2UgKHNwYW5pc2gpOicsIHNwYW5pc2hUZXh0KTtcblxuICAgICAgLy8g8J+UjSBEZWJ1ZyBwYXNvIGEgcGFzbyBwYXJhIHNwYW5pc2hcbiAgICAgIGNvbnN0IGxhbmdTZXJ2aWNlID0gKHRoaXMuY29udGVudCBhcyBhbnkpLmxhbmdTZXJ2aWNlO1xuICAgICAgY29uc3QgbGFuZ3VhZ2VDb250ZW50ID0gbGFuZ1NlcnZpY2UuY29udGVudFsnTGFuZ3VhZ2UnXTtcbiAgICAgIGNvbnN0IGN1cnJlbnRMYW5nID0gbGFuZ1NlcnZpY2Uuc2VsZWN0ZWRMYW5nPy52YWx1ZTtcbiAgICAgIGNvbnN0IGNsYXNzQ29udGVudCA9IGxhbmd1YWdlQ29udGVudD8uQ29udGVudFtjdXJyZW50TGFuZ107XG4gICAgICBjb25zb2xlLmxvZygn8J+UjSBEZWJ1ZyBzcGFuaXNoIC0gY3VycmVudExhbmc6JywgY3VycmVudExhbmcpO1xuICAgICAgY29uc29sZS5sb2coJ/CflI0gRGVidWcgc3BhbmlzaCAtIGNsYXNzQ29udGVudDonLCBjbGFzc0NvbnRlbnQpO1xuICAgICAgY29uc29sZS5sb2coJ/CflI0gRGVidWcgc3BhbmlzaCAtIGNsYXNzQ29udGVudFtcInNwYW5pc2hcIl06JywgY2xhc3NDb250ZW50Py5bJ3NwYW5pc2gnXSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUubG9nKCfinYwgRXJyb3IgY29tcG9uZW50ZSBMYW5ndWFnZSAoc3BhbmlzaCk6JywgZXJyb3IpO1xuICAgIH1cblxuICAgIC8vIEludGVudGFyIGFjY2VzbyBzw61uY3Jvbm8gYSBjb250ZW5pZG8gZGUgY29tcG9uZW50ZVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZXNjcmlwdGlvblRleHQgPSB0aGlzLmNvbnRlbnQuZ2V0VGV4dCgnTGFuZ3VhZ2UnLCAnZGVzY3JpcHRpb24nKTtcbiAgICAgIGNvbnNvbGUubG9nKCfinIUgQ29tcG9uZW50ZSBMYW5ndWFnZSAoZGVzY3JpcHRpb24pOicsIGRlc2NyaXB0aW9uVGV4dCk7XG5cbiAgICAgIC8vIPCflI0gRGVidWcgcGFzbyBhIHBhc28gcGFyYSBkZXNjcmlwdGlvblxuICAgICAgY29uc3QgbGFuZ1NlcnZpY2UgPSAodGhpcy5jb250ZW50IGFzIGFueSkubGFuZ1NlcnZpY2U7XG4gICAgICBjb25zdCBsYW5ndWFnZUNvbnRlbnQgPSBsYW5nU2VydmljZS5jb250ZW50WydMYW5ndWFnZSddO1xuICAgICAgY29uc3QgY3VycmVudExhbmcgPSBsYW5nU2VydmljZS5zZWxlY3RlZExhbmc/LnZhbHVlO1xuICAgICAgY29uc3QgY2xhc3NDb250ZW50ID0gbGFuZ3VhZ2VDb250ZW50Py5Db250ZW50W2N1cnJlbnRMYW5nXTtcbiAgICAgIGNvbnNvbGUubG9nKCfwn5SNIERlYnVnIGRlc2NyaXB0aW9uIC0gY3VycmVudExhbmc6JywgY3VycmVudExhbmcpO1xuICAgICAgY29uc29sZS5sb2coJ/CflI0gRGVidWcgZGVzY3JpcHRpb24gLSBjbGFzc0NvbnRlbnQ6JywgY2xhc3NDb250ZW50KTtcbiAgICAgIGNvbnNvbGUubG9nKCfwn5SNIERlYnVnIGRlc2NyaXB0aW9uIC0gY2xhc3NDb250ZW50W1wiZGVzY3JpcHRpb25cIl06JywgY2xhc3NDb250ZW50Py5bJ2Rlc2NyaXB0aW9uJ10pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmxvZygn4p2MIEVycm9yIGNvbXBvbmVudGUgTGFuZ3VhZ2UgKGRlc2NyaXB0aW9uKTonLCBlcnJvcik7XG4gICAgfVxuICB9XG59XG4iXX0=