@seniorsistemas/components-ai 0.0.0-master-d4a804fe

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 (76) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/CONTRIBUTING.md +317 -0
  3. package/README.md +161 -0
  4. package/docs/API.md +486 -0
  5. package/docs/COMPONENTS.md +272 -0
  6. package/docs/EXAMPLES.md +559 -0
  7. package/docs/MIGRATION.md +367 -0
  8. package/esm2022/lib/angular-components.module.mjs +25 -0
  9. package/esm2022/lib/components/breadcrumb/breadcrumb.component.mjs +121 -0
  10. package/esm2022/lib/components/bulk-delete-dialog/bulk-delete-dialog.component.mjs +176 -0
  11. package/esm2022/lib/components/dynamic-form/dynamic-form.component.mjs +625 -0
  12. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-date.component.mjs +86 -0
  13. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-dropdown.component.mjs +103 -0
  14. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-lookup.component.mjs +599 -0
  15. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-number.component.mjs +92 -0
  16. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-text.component.mjs +163 -0
  17. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-textarea.component.mjs +81 -0
  18. package/esm2022/lib/components/dynamic-form/fields/dynamic-field-wrapper.component.mjs +93 -0
  19. package/esm2022/lib/components/dynamic-form/fields/index.mjs +8 -0
  20. package/esm2022/lib/components/dynamic-form/models/dynamic-form.models.mjs +2 -0
  21. package/esm2022/lib/components/export-dialog/export-dialog.component.mjs +219 -0
  22. package/esm2022/lib/config/translation.config.mjs +70 -0
  23. package/esm2022/lib/directives/cep-mask.directive.mjs +79 -0
  24. package/esm2022/lib/directives/document-mask.directive.mjs +62 -0
  25. package/esm2022/lib/directives/phone-mask.directive.mjs +59 -0
  26. package/esm2022/lib/interceptors/api.interceptor.mjs +55 -0
  27. package/esm2022/lib/models/base-entity.interface.mjs +2 -0
  28. package/esm2022/lib/models/entity-list.config.mjs +2 -0
  29. package/esm2022/lib/pipes/translate.pipe.mjs +74 -0
  30. package/esm2022/lib/services/auth.service.mjs +169 -0
  31. package/esm2022/lib/services/cookie.service.mjs +90 -0
  32. package/esm2022/lib/services/entity.service.mjs +208 -0
  33. package/esm2022/lib/services/mask.service.mjs +121 -0
  34. package/esm2022/lib/services/permission.service.mjs +180 -0
  35. package/esm2022/lib/services/senior-token.service.mjs +209 -0
  36. package/esm2022/lib/services/theme.service.mjs +85 -0
  37. package/esm2022/lib/services/translation.service.mjs +232 -0
  38. package/esm2022/public-api.mjs +90 -0
  39. package/esm2022/seniorsistemas-components-ai.mjs +5 -0
  40. package/fesm2022/seniorsistemas-components-ai.mjs +4006 -0
  41. package/fesm2022/seniorsistemas-components-ai.mjs.map +1 -0
  42. package/index.d.ts +5 -0
  43. package/lib/angular-components.module.d.ts +13 -0
  44. package/lib/components/breadcrumb/breadcrumb.component.d.ts +23 -0
  45. package/lib/components/bulk-delete-dialog/bulk-delete-dialog.component.d.ts +46 -0
  46. package/lib/components/dynamic-form/dynamic-form.component.d.ts +97 -0
  47. package/lib/components/dynamic-form/fields/dynamic-field-date.component.d.ts +16 -0
  48. package/lib/components/dynamic-form/fields/dynamic-field-dropdown.component.d.ts +17 -0
  49. package/lib/components/dynamic-form/fields/dynamic-field-lookup.component.d.ts +52 -0
  50. package/lib/components/dynamic-form/fields/dynamic-field-number.component.d.ts +16 -0
  51. package/lib/components/dynamic-form/fields/dynamic-field-text.component.d.ts +17 -0
  52. package/lib/components/dynamic-form/fields/dynamic-field-textarea.component.d.ts +16 -0
  53. package/lib/components/dynamic-form/fields/dynamic-field-wrapper.component.d.ts +20 -0
  54. package/lib/components/dynamic-form/fields/index.d.ts +7 -0
  55. package/lib/components/dynamic-form/models/dynamic-form.models.d.ts +178 -0
  56. package/lib/components/export-dialog/export-dialog.component.d.ts +56 -0
  57. package/lib/config/translation.config.d.ts +24 -0
  58. package/lib/directives/cep-mask.directive.d.ts +13 -0
  59. package/lib/directives/document-mask.directive.d.ts +19 -0
  60. package/lib/directives/phone-mask.directive.d.ts +11 -0
  61. package/lib/interceptors/api.interceptor.d.ts +2 -0
  62. package/lib/models/base-entity.interface.d.ts +7 -0
  63. package/lib/models/entity-list.config.d.ts +161 -0
  64. package/lib/pipes/translate.pipe.d.ts +21 -0
  65. package/lib/services/auth.service.d.ts +82 -0
  66. package/lib/services/cookie.service.d.ts +31 -0
  67. package/lib/services/entity.service.d.ts +99 -0
  68. package/lib/services/mask.service.d.ts +36 -0
  69. package/lib/services/permission.service.d.ts +91 -0
  70. package/lib/services/senior-token.service.d.ts +70 -0
  71. package/lib/services/theme.service.d.ts +16 -0
  72. package/lib/services/translation.service.d.ts +54 -0
  73. package/package.json +53 -0
  74. package/public-api.d.ts +17 -0
  75. package/src/lib/styles/entity-list.shared.scss +383 -0
  76. package/src/lib/styles/index.scss +10 -0
@@ -0,0 +1,209 @@
1
+ import { Injectable } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "./cookie.service";
4
+ /**
5
+ * Serviço para gerenciar o token Senior e extrair informações específicas
6
+ * para o sistema de traduções.
7
+ *
8
+ * Nota: Este serviço foca especificamente na extração do locale e informações
9
+ * básicas do usuário. Para funcionalidades completas de autenticação,
10
+ * use o AuthService que tem uma interface mais robusta.
11
+ */
12
+ export class SeniorTokenService {
13
+ cookieService;
14
+ SENIOR_TOKEN_COOKIE = 'com.senior.token';
15
+ constructor(cookieService) {
16
+ this.cookieService = cookieService;
17
+ }
18
+ /**
19
+ * Obtém o token Senior completo do cookie
20
+ */
21
+ getSeniorToken() {
22
+ // Tentar o nome padrão primeiro
23
+ let token = this.cookieService.getCookie(this.SENIOR_TOKEN_COOKIE);
24
+ if (!token) {
25
+ // Tentar nomes alternativos comuns
26
+ const alternativeNames = [
27
+ 'com.senior.token',
28
+ 'senior.token',
29
+ 'senior_token',
30
+ 'seniorToken',
31
+ 'token',
32
+ 'authToken',
33
+ 'auth_token'
34
+ ];
35
+ for (const name of alternativeNames) {
36
+ token = this.cookieService.getCookie(name);
37
+ if (token) {
38
+ break;
39
+ }
40
+ }
41
+ }
42
+ return token;
43
+ }
44
+ /**
45
+ * Decodifica e obtém os dados do token Senior
46
+ */
47
+ getSeniorTokenData() {
48
+ const token = this.getSeniorToken();
49
+ if (!token) {
50
+ return null;
51
+ }
52
+ try {
53
+ let tokenData;
54
+ // Primeiro, tentar como JSON direto (mais provável baseado na informação fornecida)
55
+ try {
56
+ tokenData = JSON.parse(token);
57
+ }
58
+ catch (jsonError) {
59
+ // Se falhar, tentar como JWT
60
+ if (token.includes('.')) {
61
+ const parts = token.split('.');
62
+ if (parts.length >= 2) {
63
+ const payload = parts[1];
64
+ // Adicionar padding se necessário
65
+ const paddedPayload = payload + '='.repeat((4 - payload.length % 4) % 4);
66
+ const decodedPayload = atob(paddedPayload);
67
+ tokenData = JSON.parse(decodedPayload);
68
+ }
69
+ else {
70
+ throw new Error('Invalid JWT format');
71
+ }
72
+ }
73
+ else {
74
+ throw jsonError; // Re-throw original JSON error
75
+ }
76
+ }
77
+ return tokenData;
78
+ }
79
+ catch (error) {
80
+ console.error('[SeniorTokenService] Error parsing Senior token:', error);
81
+ return null;
82
+ }
83
+ }
84
+ /**
85
+ * Obtém o locale do usuário do token Senior
86
+ */
87
+ getUserLocale() {
88
+ const tokenData = this.getSeniorTokenData();
89
+ if (!tokenData) {
90
+ return null;
91
+ }
92
+ // O locale deve estar no mesmo nível do access_token
93
+ if (tokenData.locale) {
94
+ return tokenData.locale;
95
+ }
96
+ // Fallback: tentar outros campos comuns
97
+ const possibleLocaleFields = [
98
+ 'language',
99
+ 'lang',
100
+ 'user_locale',
101
+ 'userLocale',
102
+ 'preferred_language',
103
+ 'preferredLanguage'
104
+ ];
105
+ for (const field of possibleLocaleFields) {
106
+ if (tokenData[field]) {
107
+ return tokenData[field];
108
+ }
109
+ }
110
+ return null;
111
+ }
112
+ /**
113
+ * Obtém informações do usuário do token Senior
114
+ */
115
+ getUserInfo() {
116
+ const tokenData = this.getSeniorTokenData();
117
+ if (!tokenData) {
118
+ return null;
119
+ }
120
+ // Baseado na estrutura do AuthService, os campos devem estar no nível raiz
121
+ return {
122
+ userId: tokenData.userId || tokenData['sub'] || tokenData['user_id'] || tokenData.username,
123
+ userName: tokenData.userName || tokenData['name'] || tokenData['user_name'] || tokenData.username || tokenData.fullName,
124
+ locale: tokenData.locale,
125
+ email: tokenData.email,
126
+ fullName: tokenData.fullName
127
+ };
128
+ }
129
+ /**
130
+ * Verifica se o usuário está logado (token existe e é válido)
131
+ */
132
+ isUserLoggedIn() {
133
+ const tokenData = this.getSeniorTokenData();
134
+ if (!tokenData) {
135
+ return false;
136
+ }
137
+ // Verificar expiração se existir
138
+ if (tokenData['exp']) {
139
+ const now = Math.floor(Date.now() / 1000);
140
+ if (tokenData['exp'] < now) {
141
+ console.warn('Senior token has expired');
142
+ return false;
143
+ }
144
+ }
145
+ return true;
146
+ }
147
+ /**
148
+ * Monitora mudanças no cookie do token (para detectar login/logout)
149
+ */
150
+ watchTokenChanges(callback) {
151
+ let lastToken = this.getSeniorToken();
152
+ const checkToken = () => {
153
+ const currentToken = this.getSeniorToken();
154
+ if (currentToken !== lastToken) {
155
+ lastToken = currentToken;
156
+ const tokenData = this.getSeniorTokenData();
157
+ callback(tokenData);
158
+ }
159
+ };
160
+ // Verificar a cada 5 segundos
161
+ setInterval(checkToken, 5000);
162
+ }
163
+ /**
164
+ * Valida se o token tem a estrutura esperada do Senior
165
+ */
166
+ validateTokenStructure() {
167
+ const tokenData = this.getSeniorTokenData();
168
+ const issues = [];
169
+ if (!tokenData) {
170
+ issues.push('Token not found or could not be parsed');
171
+ return { isValid: false, issues };
172
+ }
173
+ // Verificar campos obrigatórios esperados
174
+ const requiredFields = ['access_token'];
175
+ const recommendedFields = ['locale', 'username', 'email'];
176
+ for (const field of requiredFields) {
177
+ if (!tokenData[field]) {
178
+ issues.push(`Missing required field: ${field}`);
179
+ }
180
+ }
181
+ for (const field of recommendedFields) {
182
+ if (!tokenData[field]) {
183
+ issues.push(`Missing recommended field: ${field}`);
184
+ }
185
+ }
186
+ // Verificar se locale está presente e é válido
187
+ if (tokenData.locale) {
188
+ // Importar a função de mapeamento seria circular, então fazer verificação básica
189
+ const supportedLocales = ['pt-BR', 'en-US', 'es-ES', 'pt', 'en', 'es'];
190
+ const locale = tokenData.locale;
191
+ const isSupported = supportedLocales.some(supportedLocale => locale.toLowerCase().includes(supportedLocale.toLowerCase()));
192
+ if (!isSupported) {
193
+ issues.push(`Locale '${locale}' might not be supported`);
194
+ }
195
+ }
196
+ const isValid = issues.filter(issue => issue.includes('required')).length === 0;
197
+ console.log('[SeniorTokenService] Token validation result:', { isValid, issues });
198
+ return { isValid, issues };
199
+ }
200
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SeniorTokenService, deps: [{ token: i1.CookieService }], target: i0.ɵɵFactoryTarget.Injectable });
201
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SeniorTokenService, providedIn: 'root' });
202
+ }
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SeniorTokenService, decorators: [{
204
+ type: Injectable,
205
+ args: [{
206
+ providedIn: 'root'
207
+ }]
208
+ }], ctorParameters: () => [{ type: i1.CookieService }] });
209
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuaW9yLXRva2VuLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzLWFpL3NyYy9saWIvc2VydmljZXMvc2VuaW9yLXRva2VuLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7O0FBb0IzQzs7Ozs7OztHQU9HO0FBSUgsTUFBTSxPQUFPLGtCQUFrQjtJQUdUO0lBRkgsbUJBQW1CLEdBQUcsa0JBQWtCLENBQUM7SUFFMUQsWUFBb0IsYUFBNEI7UUFBNUIsa0JBQWEsR0FBYixhQUFhLENBQWU7SUFBRyxDQUFDO0lBRXBEOztPQUVHO0lBQ0gsY0FBYztRQUNaLGdDQUFnQztRQUNoQyxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUVuRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxtQ0FBbUM7WUFDbkMsTUFBTSxnQkFBZ0IsR0FBRztnQkFDdkIsa0JBQWtCO2dCQUNsQixjQUFjO2dCQUNkLGNBQWM7Z0JBQ2QsYUFBYTtnQkFDYixPQUFPO2dCQUNQLFdBQVc7Z0JBQ1gsWUFBWTthQUNiLENBQUM7WUFFRixLQUFLLE1BQU0sSUFBSSxJQUFJLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3BDLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDM0MsSUFBSSxLQUFLLEVBQUUsQ0FBQztvQkFDVixNQUFNO2dCQUNSLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0gsa0JBQWtCO1FBQ2hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUVwQyxJQUFJLENB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QUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1lBQ2hDLE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUMxRCxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUM3RCxDQUFDO1lBRUYsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsTUFBTSwwQkFBMEIsQ0FBQyxDQUFDO1lBQzNELENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO1FBRWhGLE9BQU8sQ0FBQyxHQUFHLENBQUMsK0NBQStDLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUVsRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQzdCLENBQUM7d0dBM05VLGtCQUFrQjs0R0FBbEIsa0JBQWtCLGNBRmpCLE1BQU07OzRGQUVQLGtCQUFrQjtrQkFIOUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb29raWVTZXJ2aWNlIH0gZnJvbSAnLi9jb29raWUuc2VydmljZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VuaW9yVG9rZW5EYXRhIHtcbiAgbG9jYWxlPzogc3RyaW5nO1xuICB1c2VySWQ/OiBzdHJpbmc7XG4gIHVzZXJOYW1lPzogc3RyaW5nO1xuICBhY2Nlc3NfdG9rZW4/OiBzdHJpbmc7XG4gIGV4cGlyZXNfaW4/OiBudW1iZXI7XG4gIHJlZnJlc2hfdG9rZW4/OiBzdHJpbmc7XG4gIHRva2VuX3R5cGU/OiBzdHJpbmc7XG4gIHJlZnJlc2hfZXhwaXJlc19pbj86IG51bWJlcjtcbiAgdXNlcm5hbWU/OiBzdHJpbmc7XG4gIGVtYWlsPzogc3RyaW5nO1xuICBmdWxsTmFtZT86IHN0cmluZztcbiAgdGVuYW50TmFtZT86IHN0cmluZztcbiAgdHlwZT86IHN0cmluZztcbiAgW2tleTogc3RyaW5nXTogYW55O1xufVxuXG4vKipcbiAqIFNlcnZpw6dvIHBhcmEgZ2VyZW5jaWFyIG8gdG9rZW4gU2VuaW9yIGUgZXh0cmFpciBpbmZvcm1hw6fDtWVzIGVzcGVjw61maWNhc1xuICogcGFyYSBvIHNpc3RlbWEgZGUgdHJhZHXDp8O1ZXMuXG4gKiBcbiAqIE5vdGE6IEVzdGUgc2VydmnDp28gZm9jYSBlc3BlY2lmaWNhbWVudGUgbmEgZXh0cmHDp8OjbyBkbyBsb2NhbGUgZSBpbmZvcm1hw6fDtWVzXG4gKiBiw6FzaWNhcyBkbyB1c3XDoXJpby4gUGFyYSBmdW5jaW9uYWxpZGFkZXMgY29tcGxldGFzIGRlIGF1dGVudGljYcOnw6NvLFxuICogdXNlIG8gQXV0aFNlcnZpY2UgcXVlIHRlbSB1bWEgaW50ZXJmYWNlIG1haXMgcm9idXN0YS5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgU2VuaW9yVG9rZW5TZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBTRU5JT1JfVE9LRU5fQ09PS0lFID0gJ2NvbS5zZW5pb3IudG9rZW4nO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY29va2llU2VydmljZTogQ29va2llU2VydmljZSkge31cblxuICAvKipcbiAgICogT2J0w6ltIG8gdG9rZW4gU2VuaW9yIGNvbXBsZXRvIGRvIGNvb2tpZVxuICAgKi9cbiAgZ2V0U2VuaW9yVG9rZW4oKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgLy8gVGVudGFyIG8gbm9tZSBwYWRyw6NvIHByaW1laXJvXG4gICAgbGV0IHRva2VuID0gdGhpcy5jb29raWVTZXJ2aWNlLmdldENvb2tpZSh0aGlzLlNFTklPUl9UT0tFTl9DT09LSUUpO1xuICAgIFxuICAgIGlmICghdG9rZW4pIHtcbiAgICAgIC8vIFRlbnRhciBub21lcyBhbHRlcm5hdGl2b3MgY29tdW5zXG4gICAgICBjb25zdCBhbHRlcm5hdGl2ZU5hbWVzID0gW1xuICAgICAgICAnY29tLnNlbmlvci50b2tlbicsXG4gICAgICAgICdzZW5pb3IudG9rZW4nLFxuICAgICAgICAnc2VuaW9yX3Rva2VuJyxcbiAgICAgICAgJ3NlbmlvclRva2VuJyxcbiAgICAgICAgJ3Rva2VuJyxcbiAgICAgICAgJ2F1dGhUb2tlbicsXG4gICAgICAgICdhdXRoX3Rva2VuJ1xuICAgICAgXTtcbiAgICAgIFxuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIGFsdGVybmF0aXZlTmFtZXMpIHtcbiAgICAgICAgdG9rZW4gPSB0aGlzLmNvb2tpZVNlcnZpY2UuZ2V0Q29va2llKG5hbWUpO1xuICAgICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICByZXR1cm4gdG9rZW47XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RpZmljYSBlIG9idMOpbSBvcyBkYWRvcyBkbyB0b2tlbiBTZW5pb3JcbiAgICovXG4gIGdldFNlbmlvclRva2VuRGF0YSgpOiBTZW5pb3JUb2tlbkRhdGEgfCBudWxsIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuZ2V0U2VuaW9yVG9rZW4oKTtcbiAgICBcbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgbGV0IHRva2VuRGF0YTogYW55O1xuICAgICAgXG4gICAgICAvLyBQcmltZWlybywgdGVudGFyIGNvbW8gSlNPTiBkaXJldG8gKG1haXMgcHJvdsOhdmVsIGJhc2VhZG8gbmEgaW5mb3JtYcOnw6NvIGZvcm5lY2lkYSlcbiAgICAgIHRyeSB7XG4gICAgICAgIHRva2VuRGF0YSA9IEpTT04ucGFyc2UodG9rZW4pO1xuICAgICAgfSBjYXRjaCAoanNvbkVycm9yKSB7XG4gICAgICAgIC8vIFNlIGZhbGhhciwgdGVudGFyIGNvbW8gSldUXG4gICAgICAgIGlmICh0b2tlbi5pbmNsdWRlcygnLicpKSB7XG4gICAgICAgICAgY29uc3QgcGFydHMgPSB0b2tlbi5zcGxpdCgnLicpO1xuICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHBhcnRzWzFdO1xuICAgICAgICAgICAgLy8gQWRpY2lvbmFyIHBhZGRpbmcgc2UgbmVjZXNzw6FyaW9cbiAgICAgICAgICAgIGNvbnN0IHBhZGRlZFBheWxvYWQgPSBwYXlsb2FkICsgJz0nLnJlcGVhdCgoNCAtIHBheWxvYWQubGVuZ3RoICUgNCkgJSA0KTtcbiAgICAgICAgICAgIGNvbnN0IGRlY29kZWRQYXlsb2FkID0gYXRvYihwYWRkZWRQYXlsb2FkKTtcbiAgICAgICAgICAgIHRva2VuRGF0YSA9IEpTT04ucGFyc2UoZGVjb2RlZFBheWxvYWQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSldUIGZvcm1hdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBqc29uRXJyb3I7IC8vIFJlLXRocm93IG9yaWdpbmFsIEpTT04gZXJyb3JcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdG9rZW5EYXRhIGFzIFNlbmlvclRva2VuRGF0YTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignW1NlbmlvclRva2VuU2VydmljZV0gRXJyb3IgcGFyc2luZyBTZW5pb3IgdG9rZW46JywgZXJyb3IpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE9idMOpbSBvIGxvY2FsZSBkbyB1c3XDoXJpbyBkbyB0b2tlbiBTZW5pb3JcbiAgICovXG4gIGdldFVzZXJMb2NhbGUoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3QgdG9rZW5EYXRhID0gdGhpcy5nZXRTZW5pb3JUb2tlbkRhdGEoKTtcbiAgICBcbiAgICBpZiAoIXRva2VuRGF0YSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gTyBsb2NhbGUgZGV2ZSBlc3RhciBubyBtZXNtbyBuw612ZWwgZG8gYWNjZXNzX3Rva2VuXG4gICAgaWYgKHRva2VuRGF0YS5sb2NhbGUpIHtcbiAgICAgIHJldHVybiB0b2tlbkRhdGEubG9jYWxlO1xuICAgIH1cblxuICAgIC8vIEZhbGxiYWNrOiB0ZW50YXIgb3V0cm9zIGNhbXBvcyBjb211bnNcbiAgICBjb25zdCBwb3NzaWJsZUxvY2FsZUZpZWxkcyA9IFtcbiAgICAgICdsYW5ndWFnZScsIFxuICAgICAgJ2xhbmcnLFxuICAgICAgJ3VzZXJfbG9jYWxlJyxcbiAgICAgICd1c2VyTG9jYWxlJyxcbiAgICAgICdwcmVmZXJyZWRfbGFuZ3VhZ2UnLFxuICAgICAgJ3ByZWZlcnJlZExhbmd1YWdlJ1xuICAgIF07XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHBvc3NpYmxlTG9jYWxlRmllbGRzKSB7XG4gICAgICBpZiAodG9rZW5EYXRhW2ZpZWxkXSkge1xuICAgICAgICByZXR1cm4gdG9rZW5EYXRhW2ZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogT2J0w6ltIGluZm9ybWHDp8O1ZXMgZG8gdXN1w6FyaW8gZG8gdG9rZW4gU2VuaW9yXG4gICAqL1xuICBnZXRVc2VySW5mbygpOiB7IHVzZXJJZD86IHN0cmluZzsgdXNlck5hbWU/OiBzdHJpbmc7IGxvY2FsZT86IHN0cmluZzsgZW1haWw/OiBzdHJpbmc7IGZ1bGxOYW1lPzogc3RyaW5nIH0gfCBudWxsIHtcbiAgICBjb25zdCB0b2tlbkRhdGEgPSB0aGlzLmdldFNlbmlvclRva2VuRGF0YSgpO1xuICAgIFxuICAgIGlmICghdG9rZW5EYXRhKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBCYXNlYWRvIG5hIGVzdHJ1dHVyYSBkbyBBdXRoU2VydmljZSwgb3MgY2FtcG9zIGRldmVtIGVzdGFyIG5vIG7DrXZlbCByYWl6XG4gICAgcmV0dXJuIHtcbiAgICAgIHVzZXJJZDogdG9rZW5EYXRhLnVzZXJJZCB8fCB0b2tlbkRhdGFbJ3N1YiddIHx8IHRva2VuRGF0YVsndXNlcl9pZCddIHx8IHRva2VuRGF0YS51c2VybmFtZSxcbiAgICAgIHVzZXJOYW1lOiB0b2tlbkRhdGEudXNlck5hbWUgfHwgdG9rZW5EYXRhWyduYW1lJ10gfHwgdG9rZW5EYXRhWyd1c2VyX25hbWUnXSB8fCB0b2tlbkRhdGEudXNlcm5hbWUgfHwgdG9rZW5EYXRhLmZ1bGxOYW1lLFxuICAgICAgbG9jYWxlOiB0b2tlbkRhdGEubG9jYWxlLFxuICAgICAgZW1haWw6IHRva2VuRGF0YS5lbWFpbCxcbiAgICAgIGZ1bGxOYW1lOiB0b2tlbkRhdGEuZnVsbE5hbWVcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWNhIHNlIG8gdXN1w6FyaW8gZXN0w6EgbG9nYWRvICh0b2tlbiBleGlzdGUgZSDDqSB2w6FsaWRvKVxuICAgKi9cbiAgaXNVc2VyTG9nZ2VkSW4oKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdG9rZW5EYXRhID0gdGhpcy5nZXRTZW5pb3JUb2tlbkRhdGEoKTtcbiAgICBcbiAgICBpZiAoIXRva2VuRGF0YSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFZlcmlmaWNhciBleHBpcmHDp8OjbyBzZSBleGlzdGlyXG4gICAgaWYgKHRva2VuRGF0YVsnZXhwJ10pIHtcbiAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuICAgICAgaWYgKHRva2VuRGF0YVsnZXhwJ10gPCBub3cpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdTZW5pb3IgdG9rZW4gaGFzIGV4cGlyZWQnKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vbml0b3JhIG11ZGFuw6dhcyBubyBjb29raWUgZG8gdG9rZW4gKHBhcmEgZGV0ZWN0YXIgbG9naW4vbG9nb3V0KVxuICAgKi9cbiAgd2F0Y2hUb2tlbkNoYW5nZXMoY2FsbGJhY2s6ICh0b2tlbkRhdGE6IFNlbmlvclRva2VuRGF0YSB8IG51bGwpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBsZXQgbGFzdFRva2VuID0gdGhpcy5nZXRTZW5pb3JUb2tlbigpO1xuICAgIFxuICAgIGNvbnN0IGNoZWNrVG9rZW4gPSAoKSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50VG9rZW4gPSB0aGlzLmdldFNlbmlvclRva2VuKCk7XG4gICAgICBcbiAgICAgIGlmIChjdXJyZW50VG9rZW4gIT09IGxhc3RUb2tlbikge1xuICAgICAgICBsYXN0VG9rZW4gPSBjdXJyZW50VG9rZW47XG4gICAgICAgIGNvbnN0IHRva2VuRGF0YSA9IHRoaXMuZ2V0U2VuaW9yVG9rZW5EYXRhKCk7XG4gICAgICAgIGNhbGxiYWNrKHRva2VuRGF0YSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIFZlcmlmaWNhciBhIGNhZGEgNSBzZWd1bmRvc1xuICAgIHNldEludGVydmFsKGNoZWNrVG9rZW4sIDUwMDApO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYSBzZSBvIHRva2VuIHRlbSBhIGVzdHJ1dHVyYSBlc3BlcmFkYSBkbyBTZW5pb3JcbiAgICovXG4gIHZhbGlkYXRlVG9rZW5TdHJ1Y3R1cmUoKTogeyBpc1ZhbGlkOiBib29sZWFuOyBpc3N1ZXM6IHN0cmluZ1tdIH0ge1xuICAgIGNvbnN0IHRva2VuRGF0YSA9IHRoaXMuZ2V0U2VuaW9yVG9rZW5EYXRhKCk7XG4gICAgY29uc3QgaXNzdWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIFxuICAgIGlmICghdG9rZW5EYXRhKSB7XG4gICAgICBpc3N1ZXMucHVzaCgnVG9rZW4gbm90IGZvdW5kIG9yIGNvdWxkIG5vdCBiZSBwYXJzZWQnKTtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBpc3N1ZXMgfTtcbiAgICB9XG4gICAgXG4gICAgLy8gVmVyaWZpY2FyIGNhbXBvcyBvYnJpZ2F0w7NyaW9zIGVzcGVyYWRvc1xuICAgIGNvbnN0IHJlcXVpcmVkRmllbGRzID0gWydhY2Nlc3NfdG9rZW4nXTtcbiAgICBjb25zdCByZWNvbW1lbmRlZEZpZWxkcyA9IFsnbG9jYWxlJywgJ3VzZXJuYW1lJywgJ2VtYWlsJ107XG4gICAgXG4gICAgZm9yIChjb25zdCBmaWVsZCBvZiByZXF1aXJlZEZpZWxkcykge1xuICAgICAgaWYgKCF0b2tlbkRhdGFbZmllbGRdKSB7XG4gICAgICAgIGlzc3Vlcy5wdXNoKGBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkOiAke2ZpZWxkfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHJlY29tbWVuZGVkRmllbGRzKSB7XG4gICAgICBpZiAoIXRva2VuRGF0YVtmaWVsZF0pIHtcbiAgICAgICAgaXNzdWVzLnB1c2goYE1pc3NpbmcgcmVjb21tZW5kZWQgZmllbGQ6ICR7ZmllbGR9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIFZlcmlmaWNhciBzZSBsb2NhbGUgZXN0w6EgcHJlc2VudGUgZSDDqSB2w6FsaWRvXG4gICAgaWYgKHRva2VuRGF0YS5sb2NhbGUpIHtcbiAgICAgIC8vIEltcG9ydGFyIGEgZnVuw6fDo28gZGUgbWFwZWFtZW50byBzZXJpYSBjaXJjdWxhciwgZW50w6NvIGZhemVyIHZlcmlmaWNhw6fDo28gYsOhc2ljYVxuICAgICAgY29uc3Qgc3VwcG9ydGVkTG9jYWxlcyA9IFsncHQtQlInLCAnZW4tVVMnLCAnZXMtRVMnLCAncHQnLCAnZW4nLCAnZXMnXTtcbiAgICAgIGNvbnN0IGxvY2FsZSA9IHRva2VuRGF0YS5sb2NhbGU7XG4gICAgICBjb25zdCBpc1N1cHBvcnRlZCA9IHN1cHBvcnRlZExvY2FsZXMuc29tZShzdXBwb3J0ZWRMb2NhbGUgPT4gXG4gICAgICAgIGxvY2FsZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHN1cHBvcnRlZExvY2FsZS50b0xvd2VyQ2FzZSgpKVxuICAgICAgKTtcbiAgICAgIFxuICAgICAgaWYgKCFpc1N1cHBvcnRlZCkge1xuICAgICAgICBpc3N1ZXMucHVzaChgTG9jYWxlICcke2xvY2FsZX0nIG1pZ2h0IG5vdCBiZSBzdXBwb3J0ZWRgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgY29uc3QgaXNWYWxpZCA9IGlzc3Vlcy5maWx0ZXIoaXNzdWUgPT4gaXNzdWUuaW5jbHVkZXMoJ3JlcXVpcmVkJykpLmxlbmd0aCA9PT0gMDtcbiAgICBcbiAgICBjb25zb2xlLmxvZygnW1NlbmlvclRva2VuU2VydmljZV0gVG9rZW4gdmFsaWRhdGlvbiByZXN1bHQ6JywgeyBpc1ZhbGlkLCBpc3N1ZXMgfSk7XG4gICAgXG4gICAgcmV0dXJuIHsgaXNWYWxpZCwgaXNzdWVzIH07XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,85 @@
1
+ import { Injectable, Inject } from '@angular/core';
2
+ import { DOCUMENT } from '@angular/common';
3
+ import { BehaviorSubject } from 'rxjs';
4
+ import * as i0 from "@angular/core";
5
+ export class ThemeService {
6
+ document;
7
+ isDarkModeSubject = new BehaviorSubject(false);
8
+ isDarkMode$ = this.isDarkModeSubject.asObservable();
9
+ mediaQuery;
10
+ constructor(document) {
11
+ this.document = document;
12
+ // Create media query to watch for system theme changes (kept for compatibility)
13
+ this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
14
+ // Check for saved theme preference, default to light theme
15
+ const savedTheme = localStorage.getItem('theme');
16
+ if (savedTheme === 'dark') {
17
+ // Only use dark theme if explicitly saved as dark
18
+ this.setTheme(true);
19
+ }
20
+ else {
21
+ // Default to light theme, ignoring system preference
22
+ this.setTheme(false);
23
+ // Set default theme preference if not exists
24
+ if (!savedTheme) {
25
+ localStorage.setItem('theme', 'light');
26
+ }
27
+ }
28
+ }
29
+ followSystemTheme() {
30
+ // This method is kept for compatibility but no longer used by default
31
+ // Set theme based on system preference only when explicitly requested
32
+ this.setTheme(this.mediaQuery.matches);
33
+ // Listen for system theme changes only when in auto mode
34
+ this.mediaQuery.addEventListener('change', (e) => {
35
+ const savedTheme = localStorage.getItem('theme');
36
+ if (savedTheme === 'auto') {
37
+ this.setTheme(e.matches);
38
+ }
39
+ });
40
+ }
41
+ toggleTheme() {
42
+ const currentTheme = this.isDarkModeSubject.value;
43
+ this.setTheme(!currentTheme);
44
+ // When manually toggling, save the specific preference
45
+ localStorage.setItem('theme', !currentTheme ? 'dark' : 'light');
46
+ }
47
+ setThemeMode(mode) {
48
+ localStorage.setItem('theme', mode);
49
+ if (mode === 'auto') {
50
+ this.followSystemTheme();
51
+ }
52
+ else {
53
+ this.setTheme(mode === 'dark');
54
+ }
55
+ }
56
+ setTheme(isDark) {
57
+ this.isDarkModeSubject.next(isDark);
58
+ // Apply theme to document
59
+ if (isDark) {
60
+ this.document.documentElement.classList.add('app-dark');
61
+ }
62
+ else {
63
+ this.document.documentElement.classList.remove('app-dark');
64
+ }
65
+ }
66
+ get isDarkMode() {
67
+ return this.isDarkModeSubject.value;
68
+ }
69
+ get currentThemeMode() {
70
+ const savedTheme = localStorage.getItem('theme');
71
+ return savedTheme || 'light'; // Default to light instead of auto
72
+ }
73
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThemeService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
74
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThemeService, providedIn: 'root' });
75
+ }
76
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThemeService, decorators: [{
77
+ type: Injectable,
78
+ args: [{
79
+ providedIn: 'root'
80
+ }]
81
+ }], ctorParameters: () => [{ type: Document, decorators: [{
82
+ type: Inject,
83
+ args: [DOCUMENT]
84
+ }] }] });
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhlbWUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMtYWkvc3JjL2xpYi9zZXJ2aWNlcy90aGVtZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQUt2QyxNQUFNLE9BQU8sWUFBWTtJQUtlO0lBSjlCLGlCQUFpQixHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ3pELFdBQVcsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDbkQsVUFBVSxDQUFpQjtJQUVuQyxZQUFzQyxRQUFrQjtRQUFsQixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ3RELGdGQUFnRjtRQUNoRixJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUVwRSwyREFBMkQ7UUFDM0QsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVqRCxJQUFJLFVBQVUsS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUMxQixrREFBa0Q7WUFDbEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QixDQUFDO2FBQU0sQ0FBQztZQUNOLHFEQUFxRDtZQUNyRCxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JCLDZDQUE2QztZQUM3QyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2hCLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3pDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixzRUFBc0U7UUFDdEUsc0VBQXNFO1FBQ3RFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUV2Qyx5REFBeUQ7UUFDekQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMvQyxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2pELElBQUksVUFBVSxLQUFLLE1BQU0sRUFBRSxDQUFDO2dCQUMxQixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsV0FBVztRQUNULE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7UUFDbEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzdCLHVEQUF1RDtRQUN2RCxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsWUFBWSxDQUFDLElBQStCO1FBQzFDLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXBDLElBQUksSUFBSSxLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzNCLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUM7UUFDakMsQ0FBQztJQUNILENBQUM7SUFFTyxRQUFRLENBQUMsTUFBZTtRQUM5QixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXBDLDBCQUEwQjtRQUMxQixJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMxRCxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7SUFDdEMsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2xCLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakQsT0FBUSxVQUF3QyxJQUFJLE9BQU8sQ0FBQyxDQUFDLG1DQUFtQztJQUNsRyxDQUFDO3dHQTFFVSxZQUFZLGtCQUtILFFBQVE7NEdBTGpCLFlBQVksY0FGWCxNQUFNOzs0RkFFUCxZQUFZO2tCQUh4QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQjs7MEJBTWMsTUFBTTsyQkFBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgVGhlbWVTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBpc0RhcmtNb2RlU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwdWJsaWMgaXNEYXJrTW9kZSQgPSB0aGlzLmlzRGFya01vZGVTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBwcml2YXRlIG1lZGlhUXVlcnk6IE1lZGlhUXVlcnlMaXN0O1xuXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50KSB7XG4gICAgLy8gQ3JlYXRlIG1lZGlhIHF1ZXJ5IHRvIHdhdGNoIGZvciBzeXN0ZW0gdGhlbWUgY2hhbmdlcyAoa2VwdCBmb3IgY29tcGF0aWJpbGl0eSlcbiAgICB0aGlzLm1lZGlhUXVlcnkgPSB3aW5kb3cubWF0Y2hNZWRpYSgnKHByZWZlcnMtY29sb3Itc2NoZW1lOiBkYXJrKScpO1xuICAgIFxuICAgIC8vIENoZWNrIGZvciBzYXZlZCB0aGVtZSBwcmVmZXJlbmNlLCBkZWZhdWx0IHRvIGxpZ2h0IHRoZW1lXG4gICAgY29uc3Qgc2F2ZWRUaGVtZSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCd0aGVtZScpO1xuICAgIFxuICAgIGlmIChzYXZlZFRoZW1lID09PSAnZGFyaycpIHtcbiAgICAgIC8vIE9ubHkgdXNlIGRhcmsgdGhlbWUgaWYgZXhwbGljaXRseSBzYXZlZCBhcyBkYXJrXG4gICAgICB0aGlzLnNldFRoZW1lKHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWZhdWx0IHRvIGxpZ2h0IHRoZW1lLCBpZ25vcmluZyBzeXN0ZW0gcHJlZmVyZW5jZVxuICAgICAgdGhpcy5zZXRUaGVtZShmYWxzZSk7XG4gICAgICAvLyBTZXQgZGVmYXVsdCB0aGVtZSBwcmVmZXJlbmNlIGlmIG5vdCBleGlzdHNcbiAgICAgIGlmICghc2F2ZWRUaGVtZSkge1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgndGhlbWUnLCAnbGlnaHQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZvbGxvd1N5c3RlbVRoZW1lKCk6IHZvaWQge1xuICAgIC8vIFRoaXMgbWV0aG9kIGlzIGtlcHQgZm9yIGNvbXBhdGliaWxpdHkgYnV0IG5vIGxvbmdlciB1c2VkIGJ5IGRlZmF1bHRcbiAgICAvLyBTZXQgdGhlbWUgYmFzZWQgb24gc3lzdGVtIHByZWZlcmVuY2Ugb25seSB3aGVuIGV4cGxpY2l0bHkgcmVxdWVzdGVkXG4gICAgdGhpcy5zZXRUaGVtZSh0aGlzLm1lZGlhUXVlcnkubWF0Y2hlcyk7XG4gICAgXG4gICAgLy8gTGlzdGVuIGZvciBzeXN0ZW0gdGhlbWUgY2hhbmdlcyBvbmx5IHdoZW4gaW4gYXV0byBtb2RlXG4gICAgdGhpcy5tZWRpYVF1ZXJ5LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICBjb25zdCBzYXZlZFRoZW1lID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3RoZW1lJyk7XG4gICAgICBpZiAoc2F2ZWRUaGVtZSA9PT0gJ2F1dG8nKSB7XG4gICAgICAgIHRoaXMuc2V0VGhlbWUoZS5tYXRjaGVzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHRvZ2dsZVRoZW1lKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRUaGVtZSA9IHRoaXMuaXNEYXJrTW9kZVN1YmplY3QudmFsdWU7XG4gICAgdGhpcy5zZXRUaGVtZSghY3VycmVudFRoZW1lKTtcbiAgICAvLyBXaGVuIG1hbnVhbGx5IHRvZ2dsaW5nLCBzYXZlIHRoZSBzcGVjaWZpYyBwcmVmZXJlbmNlXG4gICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ3RoZW1lJywgIWN1cnJlbnRUaGVtZSA/ICdkYXJrJyA6ICdsaWdodCcpO1xuICB9XG5cbiAgc2V0VGhlbWVNb2RlKG1vZGU6ICdsaWdodCcgfCAnZGFyaycgfCAnYXV0bycpOiB2b2lkIHtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgndGhlbWUnLCBtb2RlKTtcbiAgICBcbiAgICBpZiAobW9kZSA9PT0gJ2F1dG8nKSB7XG4gICAgICB0aGlzLmZvbGxvd1N5c3RlbVRoZW1lKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0VGhlbWUobW9kZSA9PT0gJ2RhcmsnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldFRoZW1lKGlzRGFyazogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuaXNEYXJrTW9kZVN1YmplY3QubmV4dChpc0RhcmspO1xuICAgIFxuICAgIC8vIEFwcGx5IHRoZW1lIHRvIGRvY3VtZW50XG4gICAgaWYgKGlzRGFyaykge1xuICAgICAgdGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnYXBwLWRhcmsnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnYXBwLWRhcmsnKTtcbiAgICB9XG4gIH1cblxuICBnZXQgaXNEYXJrTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pc0RhcmtNb2RlU3ViamVjdC52YWx1ZTtcbiAgfVxuXG4gIGdldCBjdXJyZW50VGhlbWVNb2RlKCk6ICdsaWdodCcgfCAnZGFyaycgfCAnYXV0bycge1xuICAgIGNvbnN0IHNhdmVkVGhlbWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndGhlbWUnKTtcbiAgICByZXR1cm4gKHNhdmVkVGhlbWUgYXMgJ2xpZ2h0JyB8ICdkYXJrJyB8ICdhdXRvJykgfHwgJ2xpZ2h0JzsgLy8gRGVmYXVsdCB0byBsaWdodCBpbnN0ZWFkIG9mIGF1dG9cbiAgfVxufVxuIl19
@@ -0,0 +1,232 @@
1
+ import { Injectable, Optional, Inject } from '@angular/core';
2
+ import { BehaviorSubject } from 'rxjs';
3
+ import { TRANSLATION_CONFIG, mapTokenLocaleToLanguage } from '../config/translation.config';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "./senior-token.service";
6
+ export class TranslationService {
7
+ seniorTokenService;
8
+ currentLanguage = new BehaviorSubject(TRANSLATION_CONFIG.defaultLanguage);
9
+ translations = {};
10
+ loadingLanguages = new Set();
11
+ translationLoader;
12
+ constructor(seniorTokenService, loader) {
13
+ this.seniorTokenService = seniorTokenService;
14
+ this.translationLoader = loader;
15
+ this.loadStoredLanguage();
16
+ // Carregar traduções do idioma inicial imediatamente
17
+ this.loadTranslations();
18
+ // Monitorar mudanças no token para atualizar idioma
19
+ this.watchTokenChanges();
20
+ }
21
+ get currentLanguage$() {
22
+ return this.currentLanguage.asObservable();
23
+ }
24
+ getCurrentLanguage() {
25
+ return this.currentLanguage.value;
26
+ }
27
+ async setLanguage(language) {
28
+ this.currentLanguage.next(language);
29
+ localStorage.setItem(TRANSLATION_CONFIG.storageKey, language);
30
+ await this.loadTranslations();
31
+ }
32
+ async waitForTranslations() {
33
+ const language = this.currentLanguage.value;
34
+ if (!this.isLanguageLoaded(language)) {
35
+ await this.loadTranslations();
36
+ }
37
+ }
38
+ /**
39
+ * Verifica se as traduções do idioma atual estão carregadas
40
+ */
41
+ isLanguageLoaded(language) {
42
+ const lang = language || this.currentLanguage.value;
43
+ return !!this.translations[lang] && Object.keys(this.translations[lang]).length > 0;
44
+ }
45
+ translate(key, params) {
46
+ const currentLang = this.currentLanguage.value;
47
+ const translations = this.translations[currentLang];
48
+ if (!translations || Object.keys(translations).length === 0) {
49
+ // Se as traduções não estão carregadas, tentar carregar de forma assíncrona
50
+ if (!this.loadingLanguages.has(currentLang)) {
51
+ this.loadTranslations().catch(error => {
52
+ console.error('Error loading translations:', error);
53
+ });
54
+ }
55
+ console.warn(`No translations loaded for language: ${currentLang}`);
56
+ return key;
57
+ }
58
+ // Para estrutura plana, buscar diretamente pela chave
59
+ const translation = translations[key];
60
+ if (!translation) {
61
+ console.warn(`Translation key not found: ${key}`);
62
+ return key;
63
+ }
64
+ if (typeof translation !== 'string') {
65
+ console.warn(`Translation key is not a string: ${key}`);
66
+ return key;
67
+ }
68
+ // Replace parameters if provided
69
+ if (params) {
70
+ return this.replaceParams(translation, params);
71
+ }
72
+ return translation;
73
+ }
74
+ async loadTranslations() {
75
+ const language = this.currentLanguage.value;
76
+ // Se já está carregado, não carregar novamente
77
+ if (this.isLanguageLoaded(language)) {
78
+ return;
79
+ }
80
+ // Evitar carregamentos duplicados
81
+ if (this.loadingLanguages.has(language)) {
82
+ // Aguardar um pouco e tentar novamente
83
+ await new Promise(resolve => setTimeout(resolve, 100));
84
+ if (this.isLanguageLoaded(language)) {
85
+ return;
86
+ }
87
+ }
88
+ this.loadingLanguages.add(language);
89
+ try {
90
+ await this.doLoadTranslations(language);
91
+ }
92
+ catch (error) {
93
+ console.error('Error in loadTranslations:', error);
94
+ }
95
+ finally {
96
+ this.loadingLanguages.delete(language);
97
+ }
98
+ }
99
+ async doLoadTranslations(language) {
100
+ try {
101
+ // Se há um loader customizado, usar ele
102
+ if (this.translationLoader) {
103
+ const translations = await this.translationLoader.loadTranslations(language);
104
+ this.translations[language] = translations;
105
+ console.log(`Translations loaded for ${language}:`, Object.keys(this.translations[language]).length, 'keys');
106
+ return;
107
+ }
108
+ // Caso contrário, avisar que não há traduções
109
+ console.warn(`No translation loader provided. Translations for ${language} not loaded.`);
110
+ this.translations[language] = {};
111
+ }
112
+ catch (error) {
113
+ console.error(`Error loading translations for ${language}:`, error);
114
+ // Fallback para o idioma padrão se houver erro
115
+ if (language !== TRANSLATION_CONFIG.fallbackLanguage) {
116
+ try {
117
+ if (this.translationLoader) {
118
+ const fallbackTranslations = await this.translationLoader.loadTranslations(TRANSLATION_CONFIG.fallbackLanguage);
119
+ this.translations[language] = fallbackTranslations;
120
+ console.log(`Fallback translations loaded for ${language}`);
121
+ }
122
+ }
123
+ catch (fallbackError) {
124
+ console.error(`Error loading fallback translations:`, fallbackError);
125
+ }
126
+ }
127
+ }
128
+ }
129
+ loadStoredLanguage() {
130
+ // 1. Primeiro, tentar obter do token Senior
131
+ const tokenLocale = this.seniorTokenService.getUserLocale();
132
+ if (tokenLocale) {
133
+ const mappedLanguage = mapTokenLocaleToLanguage(tokenLocale);
134
+ if (mappedLanguage) {
135
+ console.log(`Using language from Senior token: ${tokenLocale} -> ${mappedLanguage}`);
136
+ this.currentLanguage.next(mappedLanguage);
137
+ return;
138
+ }
139
+ }
140
+ // 2. Segundo, tentar obter do localStorage
141
+ const stored = localStorage.getItem(TRANSLATION_CONFIG.storageKey);
142
+ const supportedCodes = TRANSLATION_CONFIG.supportedLanguages.map(lang => lang.code);
143
+ if (stored && supportedCodes.includes(stored)) {
144
+ console.log('Using language from localStorage:', stored);
145
+ this.currentLanguage.next(stored);
146
+ return;
147
+ }
148
+ // 3. Por último, usar idioma padrão
149
+ console.log('Using default language:', TRANSLATION_CONFIG.defaultLanguage);
150
+ this.currentLanguage.next(TRANSLATION_CONFIG.defaultLanguage);
151
+ }
152
+ replaceParams(text, params) {
153
+ return text.replace(/\{\{(\w+)\}\}/g, (match, key) => {
154
+ return params[key] !== undefined ? params[key] : match;
155
+ });
156
+ }
157
+ getSupportedLanguages() {
158
+ return TRANSLATION_CONFIG.supportedLanguages;
159
+ }
160
+ /**
161
+ * Força o recarregamento das traduções (útil para desenvolvimento)
162
+ */
163
+ async reloadTranslations() {
164
+ const language = this.currentLanguage.value;
165
+ delete this.translations[language];
166
+ await this.loadTranslations();
167
+ }
168
+ /**
169
+ * Obtém todas as chaves de tradução carregadas
170
+ */
171
+ getLoadedKeys() {
172
+ const language = this.currentLanguage.value;
173
+ const translations = this.translations[language];
174
+ return translations ? Object.keys(translations) : [];
175
+ }
176
+ /**
177
+ * Verifica se um código de idioma é suportado
178
+ */
179
+ isValidLanguage(locale) {
180
+ const supportedCodes = TRANSLATION_CONFIG.supportedLanguages.map(lang => lang.code);
181
+ return supportedCodes.includes(locale);
182
+ }
183
+ /**
184
+ * Monitora mudanças no token Senior para atualizar idioma automaticamente
185
+ */
186
+ watchTokenChanges() {
187
+ this.seniorTokenService.watchTokenChanges((tokenData) => {
188
+ if (tokenData?.locale) {
189
+ const mappedLanguage = mapTokenLocaleToLanguage(tokenData.locale);
190
+ if (mappedLanguage) {
191
+ const newLocale = mappedLanguage;
192
+ const currentLocale = this.currentLanguage.value;
193
+ if (newLocale !== currentLocale) {
194
+ console.log(`Token locale changed: ${tokenData.locale} -> ${newLocale}`);
195
+ this.setLanguage(newLocale);
196
+ }
197
+ }
198
+ }
199
+ });
200
+ }
201
+ /**
202
+ * Força atualização do idioma baseado no token atual
203
+ */
204
+ async syncWithToken() {
205
+ const tokenLocale = this.seniorTokenService.getUserLocale();
206
+ if (tokenLocale) {
207
+ const mappedLanguage = mapTokenLocaleToLanguage(tokenLocale);
208
+ if (mappedLanguage) {
209
+ const newLocale = mappedLanguage;
210
+ const currentLocale = this.currentLanguage.value;
211
+ if (newLocale !== currentLocale) {
212
+ console.log(`Syncing language with token: ${tokenLocale} -> ${newLocale}`);
213
+ await this.setLanguage(newLocale);
214
+ }
215
+ }
216
+ }
217
+ }
218
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TranslationService, deps: [{ token: i1.SeniorTokenService }, { token: 'TranslationLoader', optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
219
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TranslationService, providedIn: 'root' });
220
+ }
221
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TranslationService, decorators: [{
222
+ type: Injectable,
223
+ args: [{
224
+ providedIn: 'root'
225
+ }]
226
+ }], ctorParameters: () => [{ type: i1.SeniorTokenService }, { type: undefined, decorators: [{
227
+ type: Optional
228
+ }, {
229
+ type: Inject,
230
+ args: ['TranslationLoader']
231
+ }] }] });
232
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMtYWkvc3JjL2xpYi9zZXJ2aWNlcy90cmFuc2xhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxrQkFBa0IsRUFBa0Isd0JBQXdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQzs7O0FBYTVHLE1BQU0sT0FBTyxrQkFBa0I7SUFTbkI7SUFSRixlQUFlLEdBQUcsSUFBSSxlQUFlLENBQzNDLGtCQUFrQixDQUFDLGVBQW9DLENBQ3hELENBQUM7SUFDTSxZQUFZLEdBQTJCLEVBQUUsQ0FBQztJQUMxQyxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQ3JDLGlCQUFpQixDQUFxQjtJQUU5QyxZQUNVLGtCQUFzQyxFQUNMLE1BQTBCO1FBRDNELHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFHOUMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQztRQUNoQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMxQixxREFBcUQ7UUFDckQsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFeEIsb0RBQW9EO1FBQ3BELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxJQUFJLGdCQUFnQjtRQUNsQixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDN0MsQ0FBQztJQUVELGtCQUFrQjtRQUNoQixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVyxD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RUFBRSxDQUFDO3dCQUNoQyxPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixTQUFTLENBQUMsTUFBTSxPQUFPLFNBQVMsRUFBRSxDQUFDLENBQUM7d0JBQ3pFLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQzlCLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxhQUFhO1FBQ2pCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUM1RCxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sY0FBYyxHQUFHLHdCQUF3QixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzdELElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ25CLE1BQU0sU0FBUyxHQUFHLGNBQW1DLENBQUM7Z0JBQ3RELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDO2dCQUVqRCxJQUFJLFNBQVMsS0FBSyxhQUFhLEVBQUUsQ0FBQztvQkFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsV0FBVyxPQUFPLFNBQVMsRUFBRSxDQUFDLENBQUM7b0JBQzNFLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDcEMsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQzt3R0FuUFUsa0JBQWtCLG9EQVVQLG1CQUFtQjs0R0FWOUIsa0JBQWtCLGNBRmpCLE1BQU07OzRGQUVQLGtCQUFrQjtrQkFIOUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkI7OzBCQVdJLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgT3B0aW9uYWwsIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBUUkFOU0xBVElPTl9DT05GSUcsIExhbmd1YWdlQ29uZmlnLCBtYXBUb2tlbkxvY2FsZVRvTGFuZ3VhZ2UgfSBmcm9tICcuLi9jb25maWcvdHJhbnNsYXRpb24uY29uZmlnJztcbmltcG9ydCB7IFNlbmlvclRva2VuU2VydmljZSB9IGZyb20gJy4vc2VuaW9yLXRva2VuLnNlcnZpY2UnO1xuXG5leHBvcnQgdHlwZSBTdXBwb3J0ZWRMYW5ndWFnZSA9ICdwdC1CUicgfCAnZW4tVVMnIHwgJ2VzLUVTJztcblxuLy8gSW50ZXJmYWNlIHBhcmEgbyBsb2FkZXIgZGUgdHJhZHXDp8O1ZXMgKGR1Y2sgdHlwaW5nKVxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbkxvYWRlciB7XG4gIGxvYWRUcmFuc2xhdGlvbnMobGFuZ3VhZ2U6IHN0cmluZyk6IFByb21pc2U8YW55Pjtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSBjdXJyZW50TGFuZ3VhZ2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFN1cHBvcnRlZExhbmd1YWdlPihcbiAgICBUUkFOU0xBVElPTl9DT05GSUcuZGVmYXVsdExhbmd1YWdlIGFzIFN1cHBvcnRlZExhbmd1YWdlXG4gICk7XG4gIHByaXZhdGUgdHJhbnNsYXRpb25zOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XG4gIHByaXZhdGUgbG9hZGluZ0xhbmd1YWdlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcml2YXRlIHRyYW5zbGF0aW9uTG9hZGVyPzogVHJhbnNsYXRpb25Mb2FkZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzZW5pb3JUb2tlblNlcnZpY2U6IFNlbmlvclRva2VuU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KCdUcmFuc2xhdGlvbkxvYWRlcicpIGxvYWRlcj86IFRyYW5zbGF0aW9uTG9hZGVyXG4gICkge1xuICAgIHRoaXMudHJhbnNsYXRpb25Mb2FkZXIgPSBsb2FkZXI7XG4gICAgdGhpcy5sb2FkU3RvcmVkTGFuZ3VhZ2UoKTtcbiAgICAvLyBDYXJyZWdhciB0cmFkdcOnw7VlcyBkbyBpZGlvbWEgaW5pY2lhbCBpbWVkaWF0YW1lbnRlXG4gICAgdGhpcy5sb2FkVHJhbnNsYXRpb25zKCk7XG4gICAgXG4gICAgLy8gTW9uaXRvcmFyIG11ZGFuw6dhcyBubyB0b2tlbiBwYXJhIGF0dWFsaXphciBpZGlvbWFcbiAgICB0aGlzLndhdGNoVG9rZW5DaGFuZ2VzKCk7XG4gIH1cblxuICBnZXQgY3VycmVudExhbmd1YWdlJCgpOiBPYnNlcnZhYmxlPFN1cHBvcnRlZExhbmd1YWdlPiB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVudExhbmd1YWdlLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgZ2V0Q3VycmVudExhbmd1YWdlKCk6IFN1cHBvcnRlZExhbmd1YWdlIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50TGFuZ3VhZ2UudmFsdWU7XG4gIH1cblxuICBhc3luYyBzZXRMYW5ndWFnZShsYW5ndWFnZTogU3VwcG9ydGVkTGFuZ3VhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmN1cnJlbnRMYW5ndWFnZS5uZXh0KGxhbmd1YWdlKTtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShUUkFOU0xBVElPTl9DT05GSUcuc3RvcmFnZUtleSwgbGFuZ3VhZ2UpO1xuICAgIGF3YWl0IHRoaXMubG9hZFRyYW5zbGF0aW9ucygpO1xuICB9XG5cbiAgYXN5bmMgd2FpdEZvclRyYW5zbGF0aW9ucygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsYW5ndWFnZSA9IHRoaXMuY3VycmVudExhbmd1YWdlLnZhbHVlO1xuICAgIGlmICghdGhpcy5pc0xhbmd1YWdlTG9hZGVkKGxhbmd1YWdlKSkge1xuICAgICAgYXdhaXQgdGhpcy5sb2FkVHJhbnNsYXRpb25zKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWNhIHNlIGFzIHRyYWR1w6fDtWVzIGRvIGlkaW9tYSBhdHVhbCBlc3TDo28gY2FycmVnYWRhc1xuICAgKi9cbiAgaXNMYW5ndWFnZUxvYWRlZChsYW5ndWFnZT86IFN1cHBvcnRlZExhbmd1YWdlKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbGFuZyA9IGxhbmd1YWdlIHx8IHRoaXMuY3VycmVudExhbmd1YWdlLnZhbHVlO1xuICAgIHJldHVybiAhIXRoaXMudHJhbnNsYXRpb25zW2xhbmddICYmIE9iamVjdC5rZXlzKHRoaXMudHJhbnNsYXRpb25zW2xhbmddKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgdHJhbnNsYXRlKGtleTogc3RyaW5nLCBwYXJhbXM/OiB7IFtrZXk6IHN0cmluZ106IGFueSB9KTogc3RyaW5nIHtcbiAgICBjb25zdCBjdXJyZW50TGFuZyA9IHRoaXMuY3VycmVudExhbmd1YWdlLnZhbHVlO1xuICAgIGNvbnN0IHRyYW5zbGF0aW9ucyA9IHRoaXMudHJhbnNsYXRpb25zW2N1cnJlbnRMYW5nXTtcbiAgICBcbiAgICBpZiAoIXRyYW5zbGF0aW9ucyB8fCBPYmplY3Qua2V5cyh0cmFuc2xhdGlvbnMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgLy8gU2UgYXMgdHJhZHXDp8O1ZXMgbsOjbyBlc3TDo28gY2FycmVnYWRhcywgdGVudGFyIGNhcnJlZ2FyIGRlIGZvcm1hIGFzc8OtbmNyb25hXG4gICAgICBpZiAoIXRoaXMubG9hZGluZ0xhbmd1YWdlcy5oYXMoY3VycmVudExhbmcpKSB7XG4gICAgICAgIHRoaXMubG9hZFRyYW5zbGF0aW9ucygpLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBsb2FkaW5nIHRyYW5zbGF0aW9uczonLCBlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc29sZS53YXJuKGBObyB0cmFuc2xhdGlvbnMgbG9hZGVkIGZvciBsYW5ndWFnZTogJHtjdXJyZW50TGFuZ31gKTtcbiAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuXG4gICAgLy8gUGFyYSBlc3RydXR1cmEgcGxhbmEsIGJ1c2NhciBkaXJldGFtZW50ZSBwZWxhIGNoYXZlXG4gICAgY29uc3QgdHJhbnNsYXRpb24gPSB0cmFuc2xhdGlvbnNba2V5XTtcbiAgICBcbiAgICBpZiAoIXRyYW5zbGF0aW9uKSB7XG4gICAgICBjb25zb2xlLndhcm4oYFRyYW5zbGF0aW9uIGtleSBub3QgZm91bmQ6ICR7a2V5fWApO1xuICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRyYW5zbGF0aW9uICE9PSAnc3RyaW5nJykge1xuICAgICAgY29uc29sZS53YXJuKGBUcmFuc2xhdGlvbiBrZXkgaXMgbm90IGEgc3RyaW5nOiAke2tleX1gKTtcbiAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuXG4gICAgLy8gUmVwbGFjZSBwYXJhbWV0ZXJzIGlmIHByb3ZpZGVkXG4gICAgaWYgKHBhcmFtcykge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZVBhcmFtcyh0cmFuc2xhdGlvbiwgcGFyYW1zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJhbnNsYXRpb247XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRUcmFuc2xhdGlvbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbGFuZ3VhZ2UgPSB0aGlzLmN1cnJlbnRMYW5ndWFnZS52YWx1ZTtcbiAgICBcbiAgICAvLyBTZSBqw6EgZXN0w6EgY2FycmVnYWRvLCBuw6NvIGNhcnJlZ2FyIG5vdmFtZW50ZVxuICAgIGlmICh0aGlzLmlzTGFuZ3VhZ2VMb2FkZWQobGFuZ3VhZ2UpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFxuICAgIC8vIEV2aXRhciBjYXJyZWdhbWVudG9zIGR1cGxpY2Fkb3NcbiAgICBpZiAodGhpcy5sb2FkaW5nTGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHtcbiAgICAgIC8vIEFndWFyZGFyIHVtIHBvdWNvIGUgdGVudGFyIG5vdmFtZW50ZVxuICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDEwMCkpO1xuICAgICAgaWYgKHRoaXMuaXNMYW5ndWFnZUxvYWRlZChsYW5ndWFnZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICB0aGlzLmxvYWRpbmdMYW5ndWFnZXMuYWRkKGxhbmd1YWdlKTtcbiAgICBcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5kb0xvYWRUcmFuc2xhdGlvbnMobGFuZ3VhZ2UpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbiBsb2FkVHJhbnNsYXRpb25zOicsIGVycm9yKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5sb2FkaW5nTGFuZ3VhZ2VzLmRlbGV0ZShsYW5ndWFnZSk7XG4gICAgfVxuICB9XG4gIFxuICBwcml2YXRlIGFzeW5jIGRvTG9hZFRyYW5zbGF0aW9ucyhsYW5ndWFnZTogU3VwcG9ydGVkTGFuZ3VhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gU2UgaMOhIHVtIGxvYWRlciBjdXN0b21pemFkbywgdXNhciBlbGVcbiAgICAgIGlmICh0aGlzLnRyYW5zbGF0aW9uTG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IHRyYW5zbGF0aW9ucyA9IGF3YWl0IHRoaXMudHJhbnNsYXRpb25Mb2FkZXIubG9hZFRyYW5zbGF0aW9ucyhsYW5ndWFnZSk7XG4gICAgICAgIHRoaXMudHJhbnNsYXRpb25zW2xhbmd1YWdlXSA9IHRyYW5zbGF0aW9ucztcbiAgICAgICAgY29uc29sZS5sb2coYFRyYW5zbGF0aW9ucyBsb2FkZWQgZm9yICR7bGFuZ3VhZ2V9OmAsIE9iamVjdC5rZXlzKHRoaXMudHJhbnNsYXRpb25zW2xhbmd1YWdlXSkubGVuZ3RoLCAna2V5cycpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIENhc28gY29udHLDoXJpbywgYXZpc2FyIHF1ZSBuw6NvIGjDoSB0cmFkdcOnw7Vlc1xuICAgICAgY29uc29sZS53YXJuKGBObyB0cmFuc2xhdGlvbiBsb2FkZXIgcHJvdmlkZWQuIFRyYW5zbGF0aW9ucyBmb3IgJHtsYW5ndWFnZX0gbm90IGxvYWRlZC5gKTtcbiAgICAgIHRoaXMudHJhbnNsYXRpb25zW2xhbmd1YWdlXSA9IHt9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBsb2FkaW5nIHRyYW5zbGF0aW9ucyBmb3IgJHtsYW5ndWFnZX06YCwgZXJyb3IpO1xuICAgICAgLy8gRmFsbGJhY2sgcGFyYSBvIGlkaW9tYSBwYWRyw6NvIHNlIGhvdXZlciBlcnJvXG4gICAgICBpZiAobGFuZ3VhZ2UgIT09IFRSQU5TTEFUSU9OX0NPTkZJRy5mYWxsYmFja0xhbmd1YWdlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKHRoaXMudHJhbnNsYXRpb25Mb2FkZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGZhbGxiYWNrVHJhbnNsYXRpb25zID0gYXdhaXQgdGhpcy50cmFuc2xhdGlvbkxvYWRlci5sb2FkVHJhbnNsYXRpb25zKFRSQU5TTEFUSU9OX0NPTkZJRy5mYWxsYmFja0xhbmd1YWdlKTtcbiAgICAgICAgICAgIHRoaXMudHJhbnNsYXRpb25zW2xhbmd1YWdlXSA9IGZhbGxiYWNrVHJhbnNsYXRpb25zO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYEZhbGxiYWNrIHRyYW5zbGF0aW9ucyBsb2FkZWQgZm9yICR7bGFuZ3VhZ2V9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChmYWxsYmFja0Vycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgbG9hZGluZyBmYWxsYmFjayB0cmFuc2xhdGlvbnM6YCwgZmFsbGJhY2tFcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvYWRTdG9yZWRMYW5ndWFnZSgpOiB2b2lkIHtcbiAgICAvLyAxLiBQcmltZWlybywgdGVudGFyIG9idGVyIGRvIHRva2VuIFNlbmlvclxuICAgIGNvbnN0IHRva2VuTG9jYWxlID0gdGhpcy5zZW5pb3JUb2tlblNlcnZpY2UuZ2V0VXNlckxvY2FsZSgpO1xuICAgIGlmICh0b2tlbkxvY2FsZSkge1xuICAgICAgY29uc3QgbWFwcGVkTGFuZ3VhZ2UgPSBtYXBUb2tlbkxvY2FsZVRvTGFuZ3VhZ2UodG9rZW5Mb2NhbGUpO1xuICAgICAgaWYgKG1hcHBlZExhbmd1YWdlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBVc2luZyBsYW5ndWFnZSBmcm9tIFNlbmlvciB0b2tlbjogJHt0b2tlbkxvY2FsZX0gLT4gJHttYXBwZWRMYW5ndWFnZX1gKTtcbiAgICAgICAgdGhpcy5jdXJyZW50TGFuZ3VhZ2UubmV4dChtYXBwZWRMYW5ndWFnZSBhcyBTdXBwb3J0ZWRMYW5ndWFnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAyLiBTZWd1bmRvLCB0ZW50YXIgb2J0ZXIgZG8gbG9jYWxTdG9yYWdlXG4gICAgY29uc3Qgc3RvcmVkID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oVFJBTlNMQVRJT05fQ09ORklHLnN0b3JhZ2VLZXkpIGFzIFN1cHBvcnRlZExhbmd1YWdlO1xuICAgIGNvbnN0IHN1cHBvcnRlZENvZGVzID0gVFJBTlNMQVRJT05fQ09ORklHLnN1cHBvcnRlZExhbmd1YWdlcy5tYXAobGFuZyA9PiBsYW5nLmNvZGUpO1xuICAgIGlmIChzdG9yZWQgJiYgc3VwcG9ydGVkQ29kZXMuaW5jbHVkZXMoc3RvcmVkKSkge1xuICAgICAgY29uc29sZS5sb2coJ1VzaW5nIGxhbmd1YWdlIGZyb20gbG9jYWxTdG9yYWdlOicsIHN0b3JlZCk7XG4gICAgICB0aGlzLmN1cnJlbnRMYW5ndWFnZS5uZXh0KHN0b3JlZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gMy4gUG9yIMO6bHRpbW8sIHVzYXIgaWRpb21hIHBhZHLDo29cbiAgICBjb25zb2xlLmxvZygnVXNpbmcgZGVmYXVsdCBsYW5ndWFnZTonLCBUUkFOU0xBVElPTl9DT05GSUcuZGVmYXVsdExhbmd1YWdlKTtcbiAgICB0aGlzLmN1cnJlbnRMYW5ndWFnZS5uZXh0KFRSQU5TTEFUSU9OX0NPTkZJRy5kZWZhdWx0TGFuZ3VhZ2UgYXMgU3VwcG9ydGVkTGFuZ3VhZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSByZXBsYWNlUGFyYW1zKHRleHQ6IHN0cmluZywgcGFyYW1zOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGV4dC5yZXBsYWNlKC9cXHtcXHsoXFx3KylcXH1cXH0vZywgKG1hdGNoLCBrZXkpID0+IHtcbiAgICAgIHJldHVybiBwYXJhbXNba2V5XSAhPT0gdW5kZWZpbmVkID8gcGFyYW1zW2tleV0gOiBtYXRjaDtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFN1cHBvcnRlZExhbmd1YWdlcygpOiBMYW5ndWFnZUNvbmZpZ1tdIHtcbiAgICByZXR1cm4gVFJBTlNMQVRJT05fQ09ORklHLnN1cHBvcnRlZExhbmd1YWdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3LDp2EgbyByZWNhcnJlZ2FtZW50byBkYXMgdHJhZHXDp8O1ZXMgKMO6dGlsIHBhcmEgZGVzZW52b2x2aW1lbnRvKVxuICAgKi9cbiAgYXN5bmMgcmVsb2FkVHJhbnNsYXRpb25zKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGxhbmd1YWdlID0gdGhpcy5jdXJyZW50TGFuZ3VhZ2UudmFsdWU7XG4gICAgZGVsZXRlIHRoaXMudHJhbnNsYXRpb25zW2xhbmd1YWdlXTtcbiAgICBhd2FpdCB0aGlzLmxvYWRUcmFuc2xhdGlvbnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPYnTDqW0gdG9kYXMgYXMgY2hhdmVzIGRlIHRyYWR1w6fDo28gY2FycmVnYWRhc1xuICAgKi9cbiAgZ2V0TG9hZGVkS2V5cygpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgbGFuZ3VhZ2UgPSB0aGlzLmN1cnJlbnRMYW5ndWFnZS52YWx1ZTtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSB0aGlzLnRyYW5zbGF0aW9uc1tsYW5ndWFnZV07XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9ucyA/IE9iamVjdC5rZXlzKHRyYW5zbGF0aW9ucykgOiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmljYSBzZSB1bSBjw7NkaWdvIGRlIGlkaW9tYSDDqSBzdXBvcnRhZG9cbiAgICovXG4gIHByaXZhdGUgaXNWYWxpZExhbmd1YWdlKGxvY2FsZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc3VwcG9ydGVkQ29kZXMgPSBUUkFOU0xBVElPTl9DT05GSUcuc3VwcG9ydGVkTGFuZ3VhZ2VzLm1hcChsYW5nID0+IGxhbmcuY29kZSk7XG4gICAgcmV0dXJuIHN1cHBvcnRlZENvZGVzLmluY2x1ZGVzKGxvY2FsZSk7XG4gIH1cblxuICAvKipcbiAgICogTW9uaXRvcmEgbXVkYW7Dp2FzIG5vIHRva2VuIFNlbmlvciBwYXJhIGF0dWFsaXphciBpZGlvbWEgYXV0b21hdGljYW1lbnRlXG4gICAqL1xuICBwcml2YXRlIHdhdGNoVG9rZW5DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuc2VuaW9yVG9rZW5TZXJ2aWNlLndhdGNoVG9rZW5DaGFuZ2VzKCh0b2tlbkRhdGEpID0+IHtcbiAgICAgIGlmICh0b2tlbkRhdGE/LmxvY2FsZSkge1xuICAgICAgICBjb25zdCBtYXBwZWRMYW5ndWFnZSA9IG1hcFRva2VuTG9jYWxlVG9MYW5ndWFnZSh0b2tlbkRhdGEubG9jYWxlKTtcbiAgICAgICAgaWYgKG1hcHBlZExhbmd1YWdlKSB7XG4gICAgICAgICAgY29uc3QgbmV3TG9jYWxlID0gbWFwcGVkTGFuZ3VhZ2UgYXMgU3VwcG9ydGVkTGFuZ3VhZ2U7XG4gICAgICAgICAgY29uc3QgY3VycmVudExvY2FsZSA9IHRoaXMuY3VycmVudExhbmd1YWdlLnZhbHVlO1xuICAgICAgICAgIFxuICAgICAgICAgIGlmIChuZXdMb2NhbGUgIT09IGN1cnJlbnRMb2NhbGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBUb2tlbiBsb2NhbGUgY2hhbmdlZDogJHt0b2tlbkRhdGEubG9jYWxlfSAtPiAke25ld0xvY2FsZX1gKTtcbiAgICAgICAgICAgIHRoaXMuc2V0TGFuZ3VhZ2UobmV3TG9jYWxlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3LDp2EgYXR1YWxpemHDp8OjbyBkbyBpZGlvbWEgYmFzZWFkbyBubyB0b2tlbiBhdHVhbFxuICAgKi9cbiAgYXN5bmMgc3luY1dpdGhUb2tlbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0b2tlbkxvY2FsZSA9IHRoaXMuc2VuaW9yVG9rZW5TZXJ2aWNlLmdldFVzZXJMb2NhbGUoKTtcbiAgICBpZiAodG9rZW5Mb2NhbGUpIHtcbiAgICAgIGNvbnN0IG1hcHBlZExhbmd1YWdlID0gbWFwVG9rZW5Mb2NhbGVUb0xhbmd1YWdlKHRva2VuTG9jYWxlKTtcbiAgICAgIGlmIChtYXBwZWRMYW5ndWFnZSkge1xuICAgICAgICBjb25zdCBuZXdMb2NhbGUgPSBtYXBwZWRMYW5ndWFnZSBhcyBTdXBwb3J0ZWRMYW5ndWFnZTtcbiAgICAgICAgY29uc3QgY3VycmVudExvY2FsZSA9IHRoaXMuY3VycmVudExhbmd1YWdlLnZhbHVlO1xuICAgICAgICBcbiAgICAgICAgaWYgKG5ld0xvY2FsZSAhPT0gY3VycmVudExvY2FsZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBTeW5jaW5nIGxhbmd1YWdlIHdpdGggdG9rZW46ICR7dG9rZW5Mb2NhbGV9IC0+ICR7bmV3TG9jYWxlfWApO1xuICAgICAgICAgIGF3YWl0IHRoaXMuc2V0TGFuZ3VhZ2UobmV3TG9jYWxlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19