valtech-components 2.0.732 → 2.0.734
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/molecules/username-input/username-input.component.mjs +32 -9
- package/esm2022/lib/components/organisms/form/form.component.mjs +37 -5
- package/esm2022/lib/components/types.mjs +2 -1
- package/esm2022/lib/services/auth/auth.service.mjs +13 -5
- package/esm2022/lib/services/legal-link/legal-link.service.mjs +22 -5
- package/esm2022/lib/services/preferences/preferences.service.mjs +4 -2
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +1 -5
- package/fesm2022/valtech-components.mjs +10383 -10559
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/molecules/username-input/username-input.component.d.ts +13 -0
- package/lib/components/organisms/article/article.component.d.ts +2 -2
- package/lib/components/organisms/form/form.component.d.ts +8 -0
- package/lib/components/organisms/toolbar/toolbar.component.d.ts +1 -1
- package/lib/components/types.d.ts +2 -1
- package/lib/services/auth/auth.service.d.ts +2 -0
- package/lib/services/legal-link/legal-link.service.d.ts +17 -3
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +0 -1
- package/esm2022/lib/services/devices/devices.service.mjs +0 -259
- package/esm2022/lib/services/devices/index.mjs +0 -3
- package/esm2022/lib/services/devices/types.mjs +0 -8
- package/lib/services/devices/devices.service.d.ts +0 -73
- package/lib/services/devices/index.d.ts +0 -2
- package/lib/services/devices/types.d.ts +0 -11
|
@@ -23,6 +23,12 @@ import * as i0 from "@angular/core";
|
|
|
23
23
|
*/
|
|
24
24
|
export declare class UsernameInputComponent implements OnInit, OnDestroy {
|
|
25
25
|
props: UsernameInputMetadata;
|
|
26
|
+
/**
|
|
27
|
+
* AuthService optional — si está inyectado y `props.checkAvailability` no se provee,
|
|
28
|
+
* el component cae automáticamente a `AuthService.checkHandleAvailability` (backend
|
|
29
|
+
* de Valtech). Consumers que quieran otro endpoint pasan su propio callback.
|
|
30
|
+
*/
|
|
31
|
+
private authService;
|
|
26
32
|
private destroy$;
|
|
27
33
|
private checkAvailability$;
|
|
28
34
|
isFocused: import("@angular/core").WritableSignal<boolean>;
|
|
@@ -37,6 +43,13 @@ export declare class UsernameInputComponent implements OnInit, OnDestroy {
|
|
|
37
43
|
onFocus(): void;
|
|
38
44
|
onBlur(): void;
|
|
39
45
|
onInput(event: CustomEvent): void;
|
|
46
|
+
/**
|
|
47
|
+
* Resolve la fn de check de disponibilidad:
|
|
48
|
+
* 1. Si el caller pasa `props.checkAvailability` → usar esa
|
|
49
|
+
* 2. Si AuthService está inyectado → caer a `checkHandleAvailability` (backend Valtech)
|
|
50
|
+
* 3. Sino → undefined (no se muestra status indicator)
|
|
51
|
+
*/
|
|
52
|
+
private resolveCheckFn;
|
|
40
53
|
private setupAvailabilityCheck;
|
|
41
54
|
private normalizeUsername;
|
|
42
55
|
private isValidFormat;
|
|
@@ -90,9 +90,9 @@ export declare class ArticleComponent implements OnInit {
|
|
|
90
90
|
contentInterpolation?: Record<string, string | number>;
|
|
91
91
|
icon?: import("valtech-components").IconMetada;
|
|
92
92
|
shape?: "round";
|
|
93
|
-
size?: "
|
|
93
|
+
size?: "small" | "large" | "default";
|
|
94
94
|
fill?: "default" | "clear" | "outline" | "solid";
|
|
95
|
-
type: "
|
|
95
|
+
type: "button" | "submit" | "reset";
|
|
96
96
|
token?: string;
|
|
97
97
|
ref?: any;
|
|
98
98
|
handler?: (value: any) => any;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DoCheck, ElementRef, EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
|
2
2
|
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
|
3
|
+
import { UsernameInputMetadata } from '../../molecules/username-input/types';
|
|
3
4
|
import { ButtonMetadata, FormMetadata, FormSubmit, InputMetadata, InputType } from '../../types';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
export declare class FormComponent implements OnInit, OnChanges, DoCheck {
|
|
@@ -34,6 +35,13 @@ export declare class FormComponent implements OnInit, OnChanges, DoCheck {
|
|
|
34
35
|
submitHandler(token?: string): Promise<void>;
|
|
35
36
|
getControl(field: string): FormControl;
|
|
36
37
|
getFieldProp(field: InputMetadata): InputMetadata;
|
|
38
|
+
/**
|
|
39
|
+
* Adapter — convierte un `InputMetadata` (con type=HANDLE) a `UsernameInputMetadata`.
|
|
40
|
+
* El check de disponibilidad se resuelve dentro del component (AuthService inyectado);
|
|
41
|
+
* el caller puede sobrescribirlo pasando `field.errors` o un `UsernameInputMetadata`
|
|
42
|
+
* custom usando type=TEXT si necesita otra fuente de truth.
|
|
43
|
+
*/
|
|
44
|
+
getUsernameProp(field: InputMetadata): UsernameInputMetadata;
|
|
37
45
|
get isAtEndOfForm(): boolean;
|
|
38
46
|
get Form(): FormGroup;
|
|
39
47
|
get FormState(): {
|
|
@@ -72,7 +72,7 @@ export declare class ToolbarComponent implements OnInit {
|
|
|
72
72
|
};
|
|
73
73
|
showFlags?: boolean;
|
|
74
74
|
color: import("@ionic/core").Color;
|
|
75
|
-
size?: "
|
|
75
|
+
size?: "small" | "large" | "default";
|
|
76
76
|
fill?: "default" | "clear" | "outline" | "solid";
|
|
77
77
|
shape?: "round";
|
|
78
78
|
expand?: "full" | "block";
|
|
@@ -336,6 +336,8 @@ export declare class AuthService implements OnDestroy {
|
|
|
336
336
|
*/
|
|
337
337
|
checkHandleAvailability(handle: string): Observable<CheckHandleResponse>;
|
|
338
338
|
private get baseUrl();
|
|
339
|
+
/** Base for /v2/users endpoints (separate from /v2/auth). */
|
|
340
|
+
private get usersBaseUrl();
|
|
339
341
|
private handleSuccessfulAuth;
|
|
340
342
|
private clearState;
|
|
341
343
|
private startRefreshTimer;
|
|
@@ -34,12 +34,26 @@ export declare class LegalLinkService {
|
|
|
34
34
|
get openInNewTab(): boolean;
|
|
35
35
|
/**
|
|
36
36
|
* Returns the URL to use for a given internal path. Absolute URLs pass through.
|
|
37
|
+
*
|
|
38
|
+
* When `locale` is provided AND the resolved URL would be cross-origin, appends
|
|
39
|
+
* `?lang={locale}` so the main site can render the legal doc in the user's
|
|
40
|
+
* active language (instead of its default). Locale is omitted for same-origin
|
|
41
|
+
* resolves since the main site reads locale from its own `LocaleService`.
|
|
42
|
+
*
|
|
37
43
|
* @example
|
|
38
|
-
* resolve('/legal/terms')
|
|
39
|
-
*
|
|
44
|
+
* resolve('/legal/terms')
|
|
45
|
+
* // main site: '/legal/terms'
|
|
46
|
+
* // satellite: 'https://myvaltech.com/legal/terms'
|
|
47
|
+
*
|
|
48
|
+
* resolve('/legal/terms', { locale: 'pt' })
|
|
49
|
+
* // main site: '/legal/terms' (locale stays implicit)
|
|
50
|
+
* // satellite: 'https://myvaltech.com/legal/terms?lang=pt'
|
|
51
|
+
*
|
|
40
52
|
* resolve('https://x.com/y') // unchanged
|
|
41
53
|
*/
|
|
42
|
-
resolve(path: string
|
|
54
|
+
resolve(path: string, options?: {
|
|
55
|
+
locale?: string;
|
|
56
|
+
}): string;
|
|
43
57
|
/** `true` if the path would be resolved to a cross-origin URL. */
|
|
44
58
|
isExternal(path: string): boolean;
|
|
45
59
|
static ɵfac: i0.ɵɵFactoryDeclaration<LegalLinkService, never>;
|
package/lib/version.d.ts
CHANGED
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -249,7 +249,6 @@ export * from './lib/services/firebase';
|
|
|
249
249
|
export * from './lib/services/auth';
|
|
250
250
|
export * from './lib/services/i18n';
|
|
251
251
|
export * from './lib/services/preferences';
|
|
252
|
-
export * from './lib/services/devices';
|
|
253
252
|
export * from './lib/services/app-config';
|
|
254
253
|
export * from './lib/services/presets';
|
|
255
254
|
export * from './lib/services/skeleton';
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { DestroyRef, Inject, Injectable, PLATFORM_ID, computed, effect, inject, signal, } from '@angular/core';
|
|
2
|
-
import { isPlatformBrowser } from '@angular/common';
|
|
3
|
-
import { firstValueFrom } from 'rxjs';
|
|
4
|
-
import { VALTECH_AUTH_CONFIG } from '../auth/config';
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "@angular/common/http";
|
|
7
|
-
import * as i2 from "../firebase/messaging.service";
|
|
8
|
-
import * as i3 from "../preferences/preferences.service";
|
|
9
|
-
import * as i4 from "../auth/auth.service";
|
|
10
|
-
/**
|
|
11
|
-
* DeviceRegistrationService — orquesta el flow combinado de:
|
|
12
|
-
* - `PreferencesService.notificationsMaster` (flag user)
|
|
13
|
-
* - `Notification.permission` del browser
|
|
14
|
-
* - `MessagingService` (FCM: requestPermission, getToken, deleteToken)
|
|
15
|
-
* - Backend `/v2/users/me/devices` (POST/GET/DELETE)
|
|
16
|
-
*
|
|
17
|
-
* Auto-sync:
|
|
18
|
-
* - master=true & permission=granted & sin token → auto-register (silent, sin prompt).
|
|
19
|
-
* - master=false & device registrado → auto-unregister (FCM deleteToken + DELETE backend).
|
|
20
|
-
* - permission=denied → status='error', requiere acción manual del user.
|
|
21
|
-
*
|
|
22
|
-
* Cliente:
|
|
23
|
-
* - `requestAndRegister()` para CTA "permitir notificaciones" (dispara browser prompt).
|
|
24
|
-
* - `unregister()` para "olvidar este dispositivo".
|
|
25
|
-
* - `refreshPermission()` tras volver al tab (focus) — el browser puede haber cambiado el estado.
|
|
26
|
-
*/
|
|
27
|
-
export class DeviceRegistrationService {
|
|
28
|
-
constructor(config, platformId, http, messaging, prefs, auth) {
|
|
29
|
-
this.config = config;
|
|
30
|
-
this.platformId = platformId;
|
|
31
|
-
this.http = http;
|
|
32
|
-
this.messaging = messaging;
|
|
33
|
-
this.prefs = prefs;
|
|
34
|
-
this.auth = auth;
|
|
35
|
-
this._permission = signal('default');
|
|
36
|
-
this._status = signal('idle');
|
|
37
|
-
this._currentToken = signal(null);
|
|
38
|
-
this._currentDeviceId = signal(null);
|
|
39
|
-
this._lastError = signal(null);
|
|
40
|
-
this._isSupported = signal(false);
|
|
41
|
-
this.permission = this._permission.asReadonly();
|
|
42
|
-
this.status = this._status.asReadonly();
|
|
43
|
-
this.currentToken = this._currentToken.asReadonly();
|
|
44
|
-
this.currentDeviceId = this._currentDeviceId.asReadonly();
|
|
45
|
-
this.lastError = this._lastError.asReadonly();
|
|
46
|
-
this.isSupported = this._isSupported.asReadonly();
|
|
47
|
-
/** true si el browser puede recibir push y el user ya autorizó */
|
|
48
|
-
this.canReceive = computed(() => this._isSupported() && this._permission() === 'granted' && this._status() === 'registered');
|
|
49
|
-
this.autoSyncInFlight = false;
|
|
50
|
-
if (!isPlatformBrowser(this.platformId))
|
|
51
|
-
return;
|
|
52
|
-
this._isSupported.set(this.detectSupport());
|
|
53
|
-
this.refreshPermission();
|
|
54
|
-
// Refrescar permission al volver al tab — el user pudo cambiarla en browser settings.
|
|
55
|
-
window.addEventListener('focus', () => this.refreshPermission());
|
|
56
|
-
const destroyRef = inject(DestroyRef);
|
|
57
|
-
destroyRef.onDestroy(() => {
|
|
58
|
-
window.removeEventListener('focus', () => this.refreshPermission());
|
|
59
|
-
});
|
|
60
|
-
// Auto-sync: reaccionar a cambios de master / permission / user.
|
|
61
|
-
effect(() => {
|
|
62
|
-
const user = this.auth.user();
|
|
63
|
-
const master = this.prefs.notificationsMaster();
|
|
64
|
-
const perm = this._permission();
|
|
65
|
-
const hasDevice = !!this._currentDeviceId();
|
|
66
|
-
if (!user)
|
|
67
|
-
return;
|
|
68
|
-
if (!this.prefs.synced())
|
|
69
|
-
return;
|
|
70
|
-
if (this.autoSyncInFlight)
|
|
71
|
-
return;
|
|
72
|
-
// Master OFF + device registrado → unregister.
|
|
73
|
-
if (!master && hasDevice) {
|
|
74
|
-
void this.unregister();
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
// Master ON + granted + sin device → register silent (no prompt, ya granted).
|
|
78
|
-
if (master && perm === 'granted' && !hasDevice && this._status() === 'idle') {
|
|
79
|
-
void this.registerSilent();
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* CTA explícito del user: dispara `Notification.requestPermission()` + registro.
|
|
85
|
-
* Único método que puede generar el browser prompt.
|
|
86
|
-
*/
|
|
87
|
-
async requestAndRegister() {
|
|
88
|
-
if (!this._isSupported()) {
|
|
89
|
-
this._lastError.set('not-supported');
|
|
90
|
-
this._status.set('error');
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
this.autoSyncInFlight = true;
|
|
94
|
-
this._status.set('registering');
|
|
95
|
-
this._lastError.set(null);
|
|
96
|
-
try {
|
|
97
|
-
const token = await this.messaging.requestPermission();
|
|
98
|
-
this.refreshPermission();
|
|
99
|
-
if (!token) {
|
|
100
|
-
this._status.set('error');
|
|
101
|
-
this._lastError.set(this._permission() === 'denied' ? 'permission-denied' : 'no-token');
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
await this.registerDeviceBackend(token);
|
|
105
|
-
}
|
|
106
|
-
catch (err) {
|
|
107
|
-
this._status.set('error');
|
|
108
|
-
this._lastError.set(this.errorMessage(err));
|
|
109
|
-
}
|
|
110
|
-
finally {
|
|
111
|
-
this.autoSyncInFlight = false;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Unregister: borra token FCM + DELETE backend del device actual.
|
|
116
|
-
* Idempotente: si no hay device, no hace nada.
|
|
117
|
-
*/
|
|
118
|
-
async unregister() {
|
|
119
|
-
const deviceId = this._currentDeviceId();
|
|
120
|
-
if (!deviceId && !this._currentToken()) {
|
|
121
|
-
this._status.set('idle');
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
this.autoSyncInFlight = true;
|
|
125
|
-
this._status.set('unregistering');
|
|
126
|
-
this._lastError.set(null);
|
|
127
|
-
try {
|
|
128
|
-
if (deviceId) {
|
|
129
|
-
await firstValueFrom(this.http.delete(`${this.config.apiUrl}/v2/users/me/devices/${deviceId}`));
|
|
130
|
-
}
|
|
131
|
-
try {
|
|
132
|
-
await this.messaging.deleteToken();
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
// deleteToken puede fallar si el token ya no existe; aceptable.
|
|
136
|
-
}
|
|
137
|
-
this._currentToken.set(null);
|
|
138
|
-
this._currentDeviceId.set(null);
|
|
139
|
-
this._status.set('idle');
|
|
140
|
-
}
|
|
141
|
-
catch (err) {
|
|
142
|
-
this._status.set('error');
|
|
143
|
-
this._lastError.set(this.errorMessage(err));
|
|
144
|
-
}
|
|
145
|
-
finally {
|
|
146
|
-
this.autoSyncInFlight = false;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/** Refresca `permission` desde `Notification.permission` del browser. */
|
|
150
|
-
refreshPermission() {
|
|
151
|
-
if (!isPlatformBrowser(this.platformId) || !('Notification' in window)) {
|
|
152
|
-
this._permission.set('default');
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
this._permission.set(Notification.permission);
|
|
156
|
-
}
|
|
157
|
-
/** Lista devices del user actual desde backend. Útil para vista Seguridad. */
|
|
158
|
-
async listDevices() {
|
|
159
|
-
const res = await firstValueFrom(this.http.get(`${this.config.apiUrl}/v2/users/me/devices`));
|
|
160
|
-
return res.devices;
|
|
161
|
-
}
|
|
162
|
-
/** Reintenta el último flow fallido. */
|
|
163
|
-
async retry() {
|
|
164
|
-
if (this._permission() === 'granted') {
|
|
165
|
-
await this.registerSilent();
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
await this.requestAndRegister();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// ---------------------------------------------------------------------------
|
|
172
|
-
// Privados
|
|
173
|
-
// ---------------------------------------------------------------------------
|
|
174
|
-
/** Register sin prompt — asume permission ya granted. */
|
|
175
|
-
async registerSilent() {
|
|
176
|
-
this.autoSyncInFlight = true;
|
|
177
|
-
this._status.set('registering');
|
|
178
|
-
this._lastError.set(null);
|
|
179
|
-
try {
|
|
180
|
-
const token = await this.messaging.getToken();
|
|
181
|
-
if (!token) {
|
|
182
|
-
this._status.set('error');
|
|
183
|
-
this._lastError.set('no-token');
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
await this.registerDeviceBackend(token);
|
|
187
|
-
}
|
|
188
|
-
catch (err) {
|
|
189
|
-
this._status.set('error');
|
|
190
|
-
this._lastError.set(this.errorMessage(err));
|
|
191
|
-
}
|
|
192
|
-
finally {
|
|
193
|
-
this.autoSyncInFlight = false;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
async registerDeviceBackend(token) {
|
|
197
|
-
const env = this.detectEnv();
|
|
198
|
-
const body = {
|
|
199
|
-
token,
|
|
200
|
-
platform: 'web',
|
|
201
|
-
browser: env.browser,
|
|
202
|
-
os: env.os,
|
|
203
|
-
appVersion: env.appVersion,
|
|
204
|
-
};
|
|
205
|
-
const res = await firstValueFrom(this.http.post(`${this.config.apiUrl}/v2/users/me/devices`, body));
|
|
206
|
-
this._currentToken.set(token);
|
|
207
|
-
this._currentDeviceId.set(res.device.deviceId);
|
|
208
|
-
this._status.set('registered');
|
|
209
|
-
}
|
|
210
|
-
detectSupport() {
|
|
211
|
-
if (!isPlatformBrowser(this.platformId))
|
|
212
|
-
return false;
|
|
213
|
-
return 'Notification' in window && 'serviceWorker' in navigator;
|
|
214
|
-
}
|
|
215
|
-
detectEnv() {
|
|
216
|
-
const ua = navigator.userAgent;
|
|
217
|
-
let browser = 'Unknown';
|
|
218
|
-
if (/edg/i.test(ua))
|
|
219
|
-
browser = 'Edge';
|
|
220
|
-
else if (/chrome|chromium|crios/i.test(ua))
|
|
221
|
-
browser = 'Chrome';
|
|
222
|
-
else if (/firefox|fxios/i.test(ua))
|
|
223
|
-
browser = 'Firefox';
|
|
224
|
-
else if (/safari/i.test(ua))
|
|
225
|
-
browser = 'Safari';
|
|
226
|
-
let os = 'Unknown';
|
|
227
|
-
if (/Windows/i.test(ua))
|
|
228
|
-
os = 'Windows';
|
|
229
|
-
else if (/Android/i.test(ua))
|
|
230
|
-
os = 'Android';
|
|
231
|
-
else if (/iPhone|iPad|iPod/i.test(ua))
|
|
232
|
-
os = 'iOS';
|
|
233
|
-
else if (/Mac OS X/i.test(ua))
|
|
234
|
-
os = 'macOS';
|
|
235
|
-
else if (/Linux/i.test(ua))
|
|
236
|
-
os = 'Linux';
|
|
237
|
-
return { browser, os, appVersion: 'web-1.0' };
|
|
238
|
-
}
|
|
239
|
-
errorMessage(err) {
|
|
240
|
-
if (err instanceof Error)
|
|
241
|
-
return err.message;
|
|
242
|
-
if (typeof err === 'string')
|
|
243
|
-
return err;
|
|
244
|
-
return 'unknown-error';
|
|
245
|
-
}
|
|
246
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DeviceRegistrationService, deps: [{ token: VALTECH_AUTH_CONFIG }, { token: PLATFORM_ID }, { token: i1.HttpClient }, { token: i2.MessagingService }, { token: i3.PreferencesService }, { token: i4.AuthService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
247
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DeviceRegistrationService, providedIn: 'root' }); }
|
|
248
|
-
}
|
|
249
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DeviceRegistrationService, decorators: [{
|
|
250
|
-
type: Injectable,
|
|
251
|
-
args: [{ providedIn: 'root' }]
|
|
252
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
253
|
-
type: Inject,
|
|
254
|
-
args: [VALTECH_AUTH_CONFIG]
|
|
255
|
-
}] }, { type: Object, decorators: [{
|
|
256
|
-
type: Inject,
|
|
257
|
-
args: [PLATFORM_ID]
|
|
258
|
-
}] }, { type: i1.HttpClient }, { type: i2.MessagingService }, { type: i3.PreferencesService }, { type: i4.AuthService }] });
|
|
259
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2aWNlcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9kZXZpY2VzL2RldmljZXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsVUFBVSxFQUNWLE1BQU0sRUFDTixVQUFVLEVBQ1YsV0FBVyxFQUNYLFFBQVEsRUFDUixNQUFNLEVBQ04sTUFBTSxFQUNOLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3RDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7QUFhckQ7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFFSCxNQUFNLE9BQU8seUJBQXlCO0lBc0JwQyxZQUN1QyxNQUF5QixFQUNqQyxVQUFrQixFQUN2QyxJQUFnQixFQUNoQixTQUEyQixFQUMzQixLQUF5QixFQUN6QixJQUFpQjtRQUxZLFdBQU0sR0FBTixNQUFNLENBQW1CO1FBQ2pDLGVBQVUsR0FBVixVQUFVLENBQVE7UUFDdkMsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUNoQixjQUFTLEdBQVQsU0FBUyxDQUFrQjtRQUMzQixVQUFLLEdBQUwsS0FBSyxDQUFvQjtRQUN6QixTQUFJLEdBQUosSUFBSSxDQUFhO1FBM0JWLGdCQUFXLEdBQUcsTUFBTSxDQUF5QixTQUFTLENBQUMsQ0FBQztRQUN4RCxZQUFPLEdBQUcsTUFBTSxDQUEyQixNQUFNLENBQUMsQ0FBQztRQUNuRCxrQkFBYSxHQUFHLE1BQU0sQ0FBZ0IsSUFBSSxDQUFDLENBQUM7UUFDNUMscUJBQWdCLEdBQUcsTUFBTSxDQUFnQixJQUFJLENBQUMsQ0FBQztRQUMvQyxlQUFVLEdBQUcsTUFBTSxDQUFnQixJQUFJLENBQUMsQ0FB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QUM7YUFDN0MsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUFFLEVBQUUsR0FBRyxPQUFPLENBQUM7YUFDdkMsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUFFLEVBQUUsR0FBRyxPQUFPLENBQUM7UUFFekMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxDQUFDO0lBQ2hELENBQUM7SUFFTyxZQUFZLENBQUMsR0FBWTtRQUMvQixJQUFJLEdBQUcsWUFBWSxLQUFLO1lBQUUsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDO1FBQzdDLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUTtZQUFFLE9BQU8sR0FBRyxDQUFDO1FBQ3hDLE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7K0dBM09VLHlCQUF5QixrQkF1QjFCLG1CQUFtQixhQUNuQixXQUFXO21IQXhCVix5QkFBeUIsY0FEWixNQUFNOzs0RkFDbkIseUJBQXlCO2tCQURyQyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTs7MEJBd0I3QixNQUFNOzJCQUFDLG1CQUFtQjs7MEJBQzFCLE1BQU07MkJBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIERlc3Ryb3lSZWYsXG4gIEluamVjdCxcbiAgSW5qZWN0YWJsZSxcbiAgUExBVEZPUk1fSUQsXG4gIGNvbXB1dGVkLFxuICBlZmZlY3QsXG4gIGluamVjdCxcbiAgc2lnbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBmaXJzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4uL2F1dGgvYXV0aC5zZXJ2aWNlJztcbmltcG9ydCB7IFZBTFRFQ0hfQVVUSF9DT05GSUcgfSBmcm9tICcuLi9hdXRoL2NvbmZpZyc7XG5pbXBvcnQge1xuICBEZXZpY2VJbmZvLFxuICBMaXN0RGV2aWNlc1Jlc3BvbnNlLFxuICBSZWdpc3RlckRldmljZVJlcXVlc3QsXG4gIFJlZ2lzdGVyRGV2aWNlUmVzcG9uc2UsXG4gIFZhbHRlY2hBdXRoQ29uZmlnLFxufSBmcm9tICcuLi9hdXRoL3R5cGVzJztcbmltcG9ydCB7IE1lc3NhZ2luZ1NlcnZpY2UgfSBmcm9tICcuLi9maXJlYmFzZS9tZXNzYWdpbmcuc2VydmljZSc7XG5pbXBvcnQgeyBOb3RpZmljYXRpb25QZXJtaXNzaW9uIH0gZnJvbSAnLi4vZmlyZWJhc2UvdHlwZXMnO1xuaW1wb3J0IHsgUHJlZmVyZW5jZXNTZXJ2aWNlIH0gZnJvbSAnLi4vcHJlZmVyZW5jZXMvcHJlZmVyZW5jZXMuc2VydmljZSc7XG5pbXBvcnQgeyBEZWxldGVEZXZpY2VSZXNwb25zZSwgRGV2aWNlUmVnaXN0cmF0aW9uU3RhdHVzIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogRGV2aWNlUmVnaXN0cmF0aW9uU2VydmljZSDigJQgb3JxdWVzdGEgZWwgZmxvdyBjb21iaW5hZG8gZGU6XG4gKiAgLSBgUHJlZmVyZW5jZXNTZXJ2aWNlLm5vdGlmaWNhdGlvbnNNYXN0ZXJgIChmbGFnIHVzZXIpXG4gKiAgLSBgTm90aWZpY2F0aW9uLnBlcm1pc3Npb25gIGRlbCBicm93c2VyXG4gKiAgLSBgTWVzc2FnaW5nU2VydmljZWAgKEZDTTogcmVxdWVzdFBlcm1pc3Npb24sIGdldFRva2VuLCBkZWxldGVUb2tlbilcbiAqICAtIEJhY2tlbmQgYC92Mi91c2Vycy9tZS9kZXZpY2VzYCAoUE9TVC9HRVQvREVMRVRFKVxuICpcbiAqIEF1dG8tc3luYzpcbiAqICAtIG1hc3Rlcj10cnVlICYgcGVybWlzc2lvbj1ncmFudGVkICYgc2luIHRva2VuIOKGkiBhdXRvLXJlZ2lzdGVyIChzaWxlbnQsIHNpbiBwcm9tcHQpLlxuICogIC0gbWFzdGVyPWZhbHNlICYgZGV2aWNlIHJlZ2lzdHJhZG8g4oaSIGF1dG8tdW5yZWdpc3RlciAoRkNNIGRlbGV0ZVRva2VuICsgREVMRVRFIGJhY2tlbmQpLlxuICogIC0gcGVybWlzc2lvbj1kZW5pZWQg4oaSIHN0YXR1cz0nZXJyb3InLCByZXF1aWVyZSBhY2Npw7NuIG1hbnVhbCBkZWwgdXNlci5cbiAqXG4gKiBDbGllbnRlOlxuICogIC0gYHJlcXVlc3RBbmRSZWdpc3RlcigpYCBwYXJhIENUQSBcInBlcm1pdGlyIG5vdGlmaWNhY2lvbmVzXCIgKGRpc3BhcmEgYnJvd3NlciBwcm9tcHQpLlxuICogIC0gYHVucmVnaXN0ZXIoKWAgcGFyYSBcIm9sdmlkYXIgZXN0ZSBkaXNwb3NpdGl2b1wiLlxuICogIC0gYHJlZnJlc2hQZXJtaXNzaW9uKClgIHRyYXMgdm9sdmVyIGFsIHRhYiAoZm9jdXMpIOKAlCBlbCBicm93c2VyIHB1ZWRlIGhhYmVyIGNhbWJpYWRvIGVsIGVzdGFkby5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBEZXZpY2VSZWdpc3RyYXRpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBfcGVybWlzc2lvbiA9IHNpZ25hbDxOb3RpZmljYXRpb25QZXJtaXNzaW9uPignZGVmYXVsdCcpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9zdGF0dXMgPSBzaWduYWw8RGV2aWNlUmVnaXN0cmF0aW9uU3RhdHVzPignaWRsZScpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9jdXJyZW50VG9rZW4gPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2N1cnJlbnREZXZpY2VJZCA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbGFzdEVycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9pc1N1cHBvcnRlZCA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG5cbiAgcmVhZG9ubHkgcGVybWlzc2lvbiA9IHRoaXMuX3Blcm1pc3Npb24uYXNSZWFkb25seSgpO1xuICByZWFkb25seSBzdGF0dXMgPSB0aGlzLl9zdGF0dXMuYXNSZWFkb25seSgpO1xuICByZWFkb25seSBjdXJyZW50VG9rZW4gPSB0aGlzLl9jdXJyZW50VG9rZW4uYXNSZWFkb25seSgpO1xuICByZWFkb25seSBjdXJyZW50RGV2aWNlSWQgPSB0aGlzLl9jdXJyZW50RGV2aWNlSWQuYXNSZWFkb25seSgpO1xuICByZWFkb25seSBsYXN0RXJyb3IgPSB0aGlzLl9sYXN0RXJyb3IuYXNSZWFkb25seSgpO1xuICByZWFkb25seSBpc1N1cHBvcnRlZCA9IHRoaXMuX2lzU3VwcG9ydGVkLmFzUmVhZG9ubHkoKTtcblxuICAvKiogdHJ1ZSBzaSBlbCBicm93c2VyIHB1ZWRlIHJlY2liaXIgcHVzaCB5IGVsIHVzZXIgeWEgYXV0b3JpesOzICovXG4gIHJlYWRvbmx5IGNhblJlY2VpdmUgPSBjb21wdXRlZChcbiAgICAoKSA9PiB0aGlzLl9pc1N1cHBvcnRlZCgpICYmIHRoaXMuX3Blcm1pc3Npb24oKSA9PT0gJ2dyYW50ZWQnICYmIHRoaXMuX3N0YXR1cygpID09PSAncmVnaXN0ZXJlZCdcbiAgKTtcblxuICBwcml2YXRlIGF1dG9TeW5jSW5GbGlnaHQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KFZBTFRFQ0hfQVVUSF9DT05GSUcpIHByaXZhdGUgY29uZmlnOiBWYWx0ZWNoQXV0aENvbmZpZyxcbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgcHJpdmF0ZSBtZXNzYWdpbmc6IE1lc3NhZ2luZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBwcmVmczogUHJlZmVyZW5jZXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgYXV0aDogQXV0aFNlcnZpY2VcbiAgKSB7XG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSByZXR1cm47XG5cbiAgICB0aGlzLl9pc1N1cHBvcnRlZC5zZXQodGhpcy5kZXRlY3RTdXBwb3J0KCkpO1xuICAgIHRoaXMucmVmcmVzaFBlcm1pc3Npb24oKTtcblxuICAgIC8vIFJlZnJlc2NhciBwZXJtaXNzaW9uIGFsIHZvbHZlciBhbCB0YWIg4oCUIGVsIHVzZXIgcHVkbyBjYW1iaWFybGEgZW4gYnJvd3NlciBzZXR0aW5ncy5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCAoKSA9PiB0aGlzLnJlZnJlc2hQZXJtaXNzaW9uKCkpO1xuXG4gICAgY29uc3QgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgICBkZXN0cm95UmVmLm9uRGVzdHJveSgoKSA9PiB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZm9jdXMnLCAoKSA9PiB0aGlzLnJlZnJlc2hQZXJtaXNzaW9uKCkpO1xuICAgIH0pO1xuXG4gICAgLy8gQXV0by1zeW5jOiByZWFjY2lvbmFyIGEgY2FtYmlvcyBkZSBtYXN0ZXIgLyBwZXJtaXNzaW9uIC8gdXNlci5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgdXNlciA9IHRoaXMuYXV0aC51c2VyKCk7XG4gICAgICBjb25zdCBtYXN0ZXIgPSB0aGlzLnByZWZzLm5vdGlmaWNhdGlvbnNNYXN0ZXIoKTtcbiAgICAgIGNvbnN0IHBlcm0gPSB0aGlzLl9wZXJtaXNzaW9uKCk7XG4gICAgICBjb25zdCBoYXNEZXZpY2UgPSAhIXRoaXMuX2N1cnJlbnREZXZpY2VJZCgpO1xuXG4gICAgICBpZiAoIXVzZXIpIHJldHVybjtcbiAgICAgIGlmICghdGhpcy5wcmVmcy5zeW5jZWQoKSkgcmV0dXJuO1xuICAgICAgaWYgKHRoaXMuYXV0b1N5bmNJbkZsaWdodCkgcmV0dXJuO1xuXG4gICAgICAvLyBNYXN0ZXIgT0ZGICsgZGV2aWNlIHJlZ2lzdHJhZG8g4oaSIHVucmVnaXN0ZXIuXG4gICAgICBpZiAoIW1hc3RlciAmJiBoYXNEZXZpY2UpIHtcbiAgICAgICAgdm9pZCB0aGlzLnVucmVnaXN0ZXIoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBNYXN0ZXIgT04gKyBncmFudGVkICsgc2luIGRldmljZSDihpIgcmVnaXN0ZXIgc2lsZW50IChubyBwcm9tcHQsIHlhIGdyYW50ZWQpLlxuICAgICAgaWYgKG1hc3RlciAmJiBwZXJtID09PSAnZ3JhbnRlZCcgJiYgIWhhc0RldmljZSAmJiB0aGlzLl9zdGF0dXMoKSA9PT0gJ2lkbGUnKSB7XG4gICAgICAgIHZvaWQgdGhpcy5yZWdpc3RlclNpbGVudCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENUQSBleHBsw61jaXRvIGRlbCB1c2VyOiBkaXNwYXJhIGBOb3RpZmljYXRpb24ucmVxdWVzdFBlcm1pc3Npb24oKWAgKyByZWdpc3Ryby5cbiAgICogw5puaWNvIG3DqXRvZG8gcXVlIHB1ZWRlIGdlbmVyYXIgZWwgYnJvd3NlciBwcm9tcHQuXG4gICAqL1xuICBhc3luYyByZXF1ZXN0QW5kUmVnaXN0ZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLl9pc1N1cHBvcnRlZCgpKSB7XG4gICAgICB0aGlzLl9sYXN0RXJyb3Iuc2V0KCdub3Qtc3VwcG9ydGVkJyk7XG4gICAgICB0aGlzLl9zdGF0dXMuc2V0KCdlcnJvcicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYXV0b1N5bmNJbkZsaWdodCA9IHRydWU7XG4gICAgdGhpcy5fc3RhdHVzLnNldCgncmVnaXN0ZXJpbmcnKTtcbiAgICB0aGlzLl9sYXN0RXJyb3Iuc2V0KG51bGwpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgdGhpcy5tZXNzYWdpbmcucmVxdWVzdFBlcm1pc3Npb24oKTtcbiAgICAgIHRoaXMucmVmcmVzaFBlcm1pc3Npb24oKTtcblxuICAgICAgaWYgKCF0b2tlbikge1xuICAgICAgICB0aGlzLl9zdGF0dXMuc2V0KCdlcnJvcicpO1xuICAgICAgICB0aGlzLl9sYXN0RXJyb3Iuc2V0KHRoaXMuX3Blcm1pc3Npb24oKSA9PT0gJ2RlbmllZCcgPyAncGVybWlzc2lvbi1kZW5pZWQnIDogJ25vLXRva2VuJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckRldmljZUJhY2tlbmQodG9rZW4pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fc3RhdHVzLnNldCgnZXJyb3InKTtcbiAgICAgIHRoaXMuX2xhc3RFcnJvci5zZXQodGhpcy5lcnJvck1lc3NhZ2UoZXJyKSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuYXV0b1N5bmNJbkZsaWdodCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVyOiBib3JyYSB0b2tlbiBGQ00gKyBERUxFVEUgYmFja2VuZCBkZWwgZGV2aWNlIGFjdHVhbC5cbiAgICogSWRlbXBvdGVudGU6IHNpIG5vIGhheSBkZXZpY2UsIG5vIGhhY2UgbmFkYS5cbiAgICovXG4gIGFzeW5jIHVucmVnaXN0ZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGV2aWNlSWQgPSB0aGlzLl9jdXJyZW50RGV2aWNlSWQoKTtcbiAgICBpZiAoIWRldmljZUlkICYmICF0aGlzLl9jdXJyZW50VG9rZW4oKSkge1xuICAgICAgdGhpcy5fc3RhdHVzLnNldCgnaWRsZScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYXV0b1N5bmNJbkZsaWdodCA9IHRydWU7XG4gICAgdGhpcy5fc3RhdHVzLnNldCgndW5yZWdpc3RlcmluZycpO1xuICAgIHRoaXMuX2xhc3RFcnJvci5zZXQobnVsbCk7XG5cbiAgICB0cnkge1xuICAgICAgaWYgKGRldmljZUlkKSB7XG4gICAgICAgIGF3YWl0IGZpcnN0VmFsdWVGcm9tKFxuICAgICAgICAgIHRoaXMuaHR0cC5kZWxldGU8RGVsZXRlRGV2aWNlUmVzcG9uc2U+KFxuICAgICAgICAgICAgYCR7dGhpcy5jb25maWcuYXBpVXJsfS92Mi91c2Vycy9tZS9kZXZpY2VzLyR7ZGV2aWNlSWR9YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMubWVzc2FnaW5nLmRlbGV0ZVRva2VuKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gZGVsZXRlVG9rZW4gcHVlZGUgZmFsbGFyIHNpIGVsIHRva2VuIHlhIG5vIGV4aXN0ZTsgYWNlcHRhYmxlLlxuICAgICAgfVxuICAgICAgdGhpcy5fY3VycmVudFRva2VuLnNldChudWxsKTtcbiAgICAgIHRoaXMuX2N1cnJlbnREZXZpY2VJZC5zZXQobnVsbCk7XG4gICAgICB0aGlzLl9zdGF0dXMuc2V0KCdpZGxlJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLl9zdGF0dXMuc2V0KCdlcnJvcicpO1xuICAgICAgdGhpcy5fbGFzdEVycm9yLnNldCh0aGlzLmVycm9yTWVzc2FnZShlcnIpKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5hdXRvU3luY0luRmxpZ2h0ID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJlZnJlc2NhIGBwZXJtaXNzaW9uYCBkZXNkZSBgTm90aWZpY2F0aW9uLnBlcm1pc3Npb25gIGRlbCBicm93c2VyLiAqL1xuICByZWZyZXNoUGVybWlzc2lvbigpOiB2b2lkIHtcbiAgICBpZiAoIWlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkgfHwgISgnTm90aWZpY2F0aW9uJyBpbiB3aW5kb3cpKSB7XG4gICAgICB0aGlzLl9wZXJtaXNzaW9uLnNldCgnZGVmYXVsdCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9wZXJtaXNzaW9uLnNldChOb3RpZmljYXRpb24ucGVybWlzc2lvbiBhcyBOb3RpZmljYXRpb25QZXJtaXNzaW9uKTtcbiAgfVxuXG4gIC8qKiBMaXN0YSBkZXZpY2VzIGRlbCB1c2VyIGFjdHVhbCBkZXNkZSBiYWNrZW5kLiDDmnRpbCBwYXJhIHZpc3RhIFNlZ3VyaWRhZC4gKi9cbiAgYXN5bmMgbGlzdERldmljZXMoKTogUHJvbWlzZTxEZXZpY2VJbmZvW10+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbShcbiAgICAgIHRoaXMuaHR0cC5nZXQ8TGlzdERldmljZXNSZXNwb25zZT4oYCR7dGhpcy5jb25maWcuYXBpVXJsfS92Mi91c2Vycy9tZS9kZXZpY2VzYClcbiAgICApO1xuICAgIHJldHVybiByZXMuZGV2aWNlcztcbiAgfVxuXG4gIC8qKiBSZWludGVudGEgZWwgw7psdGltbyBmbG93IGZhbGxpZG8uICovXG4gIGFzeW5jIHJldHJ5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLl9wZXJtaXNzaW9uKCkgPT09ICdncmFudGVkJykge1xuICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlclNpbGVudCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCB0aGlzLnJlcXVlc3RBbmRSZWdpc3RlcigpO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBQcml2YWRvc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvKiogUmVnaXN0ZXIgc2luIHByb21wdCDigJQgYXN1bWUgcGVybWlzc2lvbiB5YSBncmFudGVkLiAqL1xuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyU2lsZW50KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYXV0b1N5bmNJbkZsaWdodCA9IHRydWU7XG4gICAgdGhpcy5fc3RhdHVzLnNldCgncmVnaXN0ZXJpbmcnKTtcbiAgICB0aGlzLl9sYXN0RXJyb3Iuc2V0KG51bGwpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IHRoaXMubWVzc2FnaW5nLmdldFRva2VuKCk7XG4gICAgICBpZiAoIXRva2VuKSB7XG4gICAgICAgIHRoaXMuX3N0YXR1cy5zZXQoJ2Vycm9yJyk7XG4gICAgICAgIHRoaXMuX2xhc3RFcnJvci5zZXQoJ25vLXRva2VuJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJEZXZpY2VCYWNrZW5kKHRva2VuKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuX3N0YXR1cy5zZXQoJ2Vycm9yJyk7XG4gICAgICB0aGlzLl9sYXN0RXJyb3Iuc2V0KHRoaXMuZXJyb3JNZXNzYWdlKGVycikpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmF1dG9TeW5jSW5GbGlnaHQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyRGV2aWNlQmFja2VuZCh0b2tlbjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZW52ID0gdGhpcy5kZXRlY3RFbnYoKTtcbiAgICBjb25zdCBib2R5OiBSZWdpc3RlckRldmljZVJlcXVlc3QgPSB7XG4gICAgICB0b2tlbixcbiAgICAgIHBsYXRmb3JtOiAnd2ViJyxcbiAgICAgIGJyb3dzZXI6IGVudi5icm93c2VyLFxuICAgICAgb3M6IGVudi5vcyxcbiAgICAgIGFwcFZlcnNpb246IGVudi5hcHBWZXJzaW9uLFxuICAgIH07XG4gICAgY29uc3QgcmVzID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20oXG4gICAgICB0aGlzLmh0dHAucG9zdDxSZWdpc3RlckRldmljZVJlc3BvbnNlPihgJHt0aGlzLmNvbmZpZy5hcGlVcmx9L3YyL3VzZXJzL21lL2RldmljZXNgLCBib2R5KVxuICAgICk7XG4gICAgdGhpcy5fY3VycmVudFRva2VuLnNldCh0b2tlbik7XG4gICAgdGhpcy5fY3VycmVudERldmljZUlkLnNldChyZXMuZGV2aWNlLmRldmljZUlkKTtcbiAgICB0aGlzLl9zdGF0dXMuc2V0KCdyZWdpc3RlcmVkJyk7XG4gIH1cblxuICBwcml2YXRlIGRldGVjdFN1cHBvcnQoKTogYm9vbGVhbiB7XG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuICdOb3RpZmljYXRpb24nIGluIHdpbmRvdyAmJiAnc2VydmljZVdvcmtlcicgaW4gbmF2aWdhdG9yO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXRlY3RFbnYoKTogeyBicm93c2VyOiBzdHJpbmc7IG9zOiBzdHJpbmc7IGFwcFZlcnNpb246IHN0cmluZyB9IHtcbiAgICBjb25zdCB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgbGV0IGJyb3dzZXIgPSAnVW5rbm93bic7XG4gICAgaWYgKC9lZGcvaS50ZXN0KHVhKSkgYnJvd3NlciA9ICdFZGdlJztcbiAgICBlbHNlIGlmICgvY2hyb21lfGNocm9taXVtfGNyaW9zL2kudGVzdCh1YSkpIGJyb3dzZXIgPSAnQ2hyb21lJztcbiAgICBlbHNlIGlmICgvZmlyZWZveHxmeGlvcy9pLnRlc3QodWEpKSBicm93c2VyID0gJ0ZpcmVmb3gnO1xuICAgIGVsc2UgaWYgKC9zYWZhcmkvaS50ZXN0KHVhKSkgYnJvd3NlciA9ICdTYWZhcmknO1xuXG4gICAgbGV0IG9zID0gJ1Vua25vd24nO1xuICAgIGlmICgvV2luZG93cy9pLnRlc3QodWEpKSBvcyA9ICdXaW5kb3dzJztcbiAgICBlbHNlIGlmICgvQW5kcm9pZC9pLnRlc3QodWEpKSBvcyA9ICdBbmRyb2lkJztcbiAgICBlbHNlIGlmICgvaVBob25lfGlQYWR8aVBvZC9pLnRlc3QodWEpKSBvcyA9ICdpT1MnO1xuICAgIGVsc2UgaWYgKC9NYWMgT1MgWC9pLnRlc3QodWEpKSBvcyA9ICdtYWNPUyc7XG4gICAgZWxzZSBpZiAoL0xpbnV4L2kudGVzdCh1YSkpIG9zID0gJ0xpbnV4JztcblxuICAgIHJldHVybiB7IGJyb3dzZXIsIG9zLCBhcHBWZXJzaW9uOiAnd2ViLTEuMCcgfTtcbiAgfVxuXG4gIHByaXZhdGUgZXJyb3JNZXNzYWdlKGVycjogdW5rbm93bik6IHN0cmluZyB7XG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yKSByZXR1cm4gZXJyLm1lc3NhZ2U7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSByZXR1cm4gZXJyO1xuICAgIHJldHVybiAndW5rbm93bi1lcnJvcic7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export * from './devices.service';
|
|
2
|
-
export * from './types';
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2RldmljZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLFNBQVMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vZGV2aWNlcy5zZXJ2aWNlJztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMnO1xuIl19
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Devices types específicos del `DeviceRegistrationService`.
|
|
3
|
-
* Los contratos base (`RegisterDeviceRequest`, `RegisterDeviceResponse`,
|
|
4
|
-
* `ListDevicesResponse`, `DeviceInfo`, `DevicePlatform`) viven en `auth/types.ts`
|
|
5
|
-
* — este archivo solo agrega lo que falta.
|
|
6
|
-
*/
|
|
7
|
-
export {};
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2RldmljZXMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0ciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIERldmljZXMgdHlwZXMgZXNwZWPDrWZpY29zIGRlbCBgRGV2aWNlUmVnaXN0cmF0aW9uU2VydmljZWAuXG4gKiBMb3MgY29udHJhdG9zIGJhc2UgKGBSZWdpc3RlckRldmljZVJlcXVlc3RgLCBgUmVnaXN0ZXJEZXZpY2VSZXNwb25zZWAsXG4gKiBgTGlzdERldmljZXNSZXNwb25zZWAsIGBEZXZpY2VJbmZvYCwgYERldmljZVBsYXRmb3JtYCkgdml2ZW4gZW4gYGF1dGgvdHlwZXMudHNgXG4gKiDigJQgZXN0ZSBhcmNoaXZvIHNvbG8gYWdyZWdhIGxvIHF1ZSBmYWx0YS5cbiAqL1xuXG5leHBvcnQgdHlwZSBEZXZpY2VSZWdpc3RyYXRpb25TdGF0dXMgPVxuICB8ICdpZGxlJ1xuICB8ICdyZWdpc3RlcmluZydcbiAgfCAncmVnaXN0ZXJlZCdcbiAgfCAndW5yZWdpc3RlcmluZydcbiAgfCAnZXJyb3InO1xuXG5leHBvcnQgaW50ZXJmYWNlIERlbGV0ZURldmljZVJlc3BvbnNlIHtcbiAgb3BlcmF0aW9uSWQ6IHN0cmluZztcbiAgZGVsZXRlZDogYm9vbGVhbjtcbn1cbiJdfQ==
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '@angular/common/http';
|
|
2
|
-
import { AuthService } from '../auth/auth.service';
|
|
3
|
-
import { DeviceInfo, ValtechAuthConfig } from '../auth/types';
|
|
4
|
-
import { MessagingService } from '../firebase/messaging.service';
|
|
5
|
-
import { NotificationPermission } from '../firebase/types';
|
|
6
|
-
import { PreferencesService } from '../preferences/preferences.service';
|
|
7
|
-
import { DeviceRegistrationStatus } from './types';
|
|
8
|
-
import * as i0 from "@angular/core";
|
|
9
|
-
/**
|
|
10
|
-
* DeviceRegistrationService — orquesta el flow combinado de:
|
|
11
|
-
* - `PreferencesService.notificationsMaster` (flag user)
|
|
12
|
-
* - `Notification.permission` del browser
|
|
13
|
-
* - `MessagingService` (FCM: requestPermission, getToken, deleteToken)
|
|
14
|
-
* - Backend `/v2/users/me/devices` (POST/GET/DELETE)
|
|
15
|
-
*
|
|
16
|
-
* Auto-sync:
|
|
17
|
-
* - master=true & permission=granted & sin token → auto-register (silent, sin prompt).
|
|
18
|
-
* - master=false & device registrado → auto-unregister (FCM deleteToken + DELETE backend).
|
|
19
|
-
* - permission=denied → status='error', requiere acción manual del user.
|
|
20
|
-
*
|
|
21
|
-
* Cliente:
|
|
22
|
-
* - `requestAndRegister()` para CTA "permitir notificaciones" (dispara browser prompt).
|
|
23
|
-
* - `unregister()` para "olvidar este dispositivo".
|
|
24
|
-
* - `refreshPermission()` tras volver al tab (focus) — el browser puede haber cambiado el estado.
|
|
25
|
-
*/
|
|
26
|
-
export declare class DeviceRegistrationService {
|
|
27
|
-
private config;
|
|
28
|
-
private platformId;
|
|
29
|
-
private http;
|
|
30
|
-
private messaging;
|
|
31
|
-
private prefs;
|
|
32
|
-
private auth;
|
|
33
|
-
private readonly _permission;
|
|
34
|
-
private readonly _status;
|
|
35
|
-
private readonly _currentToken;
|
|
36
|
-
private readonly _currentDeviceId;
|
|
37
|
-
private readonly _lastError;
|
|
38
|
-
private readonly _isSupported;
|
|
39
|
-
readonly permission: import("@angular/core").Signal<NotificationPermission>;
|
|
40
|
-
readonly status: import("@angular/core").Signal<DeviceRegistrationStatus>;
|
|
41
|
-
readonly currentToken: import("@angular/core").Signal<string>;
|
|
42
|
-
readonly currentDeviceId: import("@angular/core").Signal<string>;
|
|
43
|
-
readonly lastError: import("@angular/core").Signal<string>;
|
|
44
|
-
readonly isSupported: import("@angular/core").Signal<boolean>;
|
|
45
|
-
/** true si el browser puede recibir push y el user ya autorizó */
|
|
46
|
-
readonly canReceive: import("@angular/core").Signal<boolean>;
|
|
47
|
-
private autoSyncInFlight;
|
|
48
|
-
constructor(config: ValtechAuthConfig, platformId: Object, http: HttpClient, messaging: MessagingService, prefs: PreferencesService, auth: AuthService);
|
|
49
|
-
/**
|
|
50
|
-
* CTA explícito del user: dispara `Notification.requestPermission()` + registro.
|
|
51
|
-
* Único método que puede generar el browser prompt.
|
|
52
|
-
*/
|
|
53
|
-
requestAndRegister(): Promise<void>;
|
|
54
|
-
/**
|
|
55
|
-
* Unregister: borra token FCM + DELETE backend del device actual.
|
|
56
|
-
* Idempotente: si no hay device, no hace nada.
|
|
57
|
-
*/
|
|
58
|
-
unregister(): Promise<void>;
|
|
59
|
-
/** Refresca `permission` desde `Notification.permission` del browser. */
|
|
60
|
-
refreshPermission(): void;
|
|
61
|
-
/** Lista devices del user actual desde backend. Útil para vista Seguridad. */
|
|
62
|
-
listDevices(): Promise<DeviceInfo[]>;
|
|
63
|
-
/** Reintenta el último flow fallido. */
|
|
64
|
-
retry(): Promise<void>;
|
|
65
|
-
/** Register sin prompt — asume permission ya granted. */
|
|
66
|
-
private registerSilent;
|
|
67
|
-
private registerDeviceBackend;
|
|
68
|
-
private detectSupport;
|
|
69
|
-
private detectEnv;
|
|
70
|
-
private errorMessage;
|
|
71
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<DeviceRegistrationService, never>;
|
|
72
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<DeviceRegistrationService>;
|
|
73
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Devices types específicos del `DeviceRegistrationService`.
|
|
3
|
-
* Los contratos base (`RegisterDeviceRequest`, `RegisterDeviceResponse`,
|
|
4
|
-
* `ListDevicesResponse`, `DeviceInfo`, `DevicePlatform`) viven en `auth/types.ts`
|
|
5
|
-
* — este archivo solo agrega lo que falta.
|
|
6
|
-
*/
|
|
7
|
-
export type DeviceRegistrationStatus = 'idle' | 'registering' | 'registered' | 'unregistering' | 'error';
|
|
8
|
-
export interface DeleteDeviceResponse {
|
|
9
|
-
operationId: string;
|
|
10
|
-
deleted: boolean;
|
|
11
|
-
}
|