valtech-components 2.0.452 → 2.0.453

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 (47) hide show
  1. package/esm2022/lib/services/auth/auth-state.service.mjs +173 -0
  2. package/esm2022/lib/services/auth/auth.service.mjs +454 -0
  3. package/esm2022/lib/services/auth/config.mjs +76 -0
  4. package/esm2022/lib/services/auth/guards.mjs +194 -0
  5. package/esm2022/lib/services/auth/index.mjs +70 -0
  6. package/esm2022/lib/services/auth/interceptor.mjs +98 -0
  7. package/esm2022/lib/services/auth/storage.service.mjs +141 -0
  8. package/esm2022/lib/services/auth/sync.service.mjs +149 -0
  9. package/esm2022/lib/services/auth/token.service.mjs +113 -0
  10. package/esm2022/lib/services/auth/types.mjs +29 -0
  11. package/esm2022/lib/services/firebase/config.mjs +108 -0
  12. package/esm2022/lib/services/firebase/firebase.service.mjs +288 -0
  13. package/esm2022/lib/services/firebase/firestore-collection.mjs +254 -0
  14. package/esm2022/lib/services/firebase/firestore.service.mjs +509 -0
  15. package/esm2022/lib/services/firebase/index.mjs +49 -0
  16. package/esm2022/lib/services/firebase/messaging.service.mjs +512 -0
  17. package/esm2022/lib/services/firebase/shared-config.mjs +138 -0
  18. package/esm2022/lib/services/firebase/storage.service.mjs +422 -0
  19. package/esm2022/lib/services/firebase/types.mjs +8 -0
  20. package/esm2022/lib/services/firebase/utils/path-builder.mjs +195 -0
  21. package/esm2022/lib/services/firebase/utils/query-builder.mjs +302 -0
  22. package/esm2022/public-api.mjs +3 -5
  23. package/fesm2022/valtech-components.mjs +4195 -4
  24. package/fesm2022/valtech-components.mjs.map +1 -1
  25. package/lib/services/auth/auth-state.service.d.ts +85 -0
  26. package/lib/services/auth/auth.service.d.ts +146 -0
  27. package/lib/services/auth/config.d.ts +38 -0
  28. package/lib/services/auth/guards.d.ts +123 -0
  29. package/lib/services/auth/index.d.ts +63 -0
  30. package/lib/services/auth/interceptor.d.ts +22 -0
  31. package/lib/services/auth/storage.service.d.ts +48 -0
  32. package/lib/services/auth/sync.service.d.ts +49 -0
  33. package/lib/services/auth/token.service.d.ts +51 -0
  34. package/lib/services/auth/types.d.ts +315 -0
  35. package/lib/services/firebase/config.d.ts +49 -0
  36. package/lib/services/firebase/firebase.service.d.ts +140 -0
  37. package/lib/services/firebase/firestore-collection.d.ts +175 -0
  38. package/lib/services/firebase/firestore.service.d.ts +304 -0
  39. package/lib/services/firebase/index.d.ts +39 -0
  40. package/lib/services/firebase/messaging.service.d.ts +263 -0
  41. package/lib/services/firebase/shared-config.d.ts +126 -0
  42. package/lib/services/firebase/storage.service.d.ts +206 -0
  43. package/lib/services/firebase/types.d.ts +281 -0
  44. package/lib/services/firebase/utils/path-builder.d.ts +132 -0
  45. package/lib/services/firebase/utils/query-builder.d.ts +210 -0
  46. package/package.json +1 -1
  47. package/public-api.d.ts +2 -0
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Firebase Shared Configuration
3
+ *
4
+ * Configuración base de Firebase compartida entre todas las apps del monorepo.
5
+ * Los secrets (apiKey, appId) se inyectan en build time via environment.
6
+ */
7
+ export const APP_IDS = {
8
+ DEMO: 'demo',
9
+ SHOWCASE: 'showcase',
10
+ ADMIN_PORTAL: 'admin-portal',
11
+ APP: 'app',
12
+ };
13
+ // ============================================================================
14
+ // FIREBASE PROJECT IDS
15
+ // ============================================================================
16
+ /**
17
+ * IDs de los proyectos Firebase por ambiente.
18
+ * Deben coincidir con los proyectos creados en Firebase Console.
19
+ */
20
+ export const FIREBASE_PROJECTS = {
21
+ development: 'myvaltech-dev',
22
+ production: 'myvaltech-prod',
23
+ };
24
+ // ============================================================================
25
+ // EMULATOR CONFIGURATION (shared across all apps)
26
+ // ============================================================================
27
+ /**
28
+ * Configuración de emuladores compartida.
29
+ * Todos los puertos deben coincidir con frontend/firebase/firebase.json
30
+ */
31
+ export const SHARED_EMULATOR_CONFIG = {
32
+ firestore: { host: 'localhost', port: 9080 },
33
+ storage: { host: 'localhost', port: 9199 },
34
+ auth: { host: 'localhost', port: 9099 },
35
+ };
36
+ // ============================================================================
37
+ // STORAGE PATH BUILDERS
38
+ // ============================================================================
39
+ /**
40
+ * Genera paths de Storage con namespace por app.
41
+ *
42
+ * @example
43
+ * // Path específico de la app
44
+ * storagePaths.forApp('showcase', 'uploads', 'image.jpg')
45
+ * // => 'showcase/uploads/image.jpg'
46
+ *
47
+ * // Path compartido
48
+ * storagePaths.shared.profilePhoto('user123', 'avatar.jpg')
49
+ * // => 'profile-photos/user123/avatar.jpg'
50
+ */
51
+ export const storagePaths = {
52
+ /** Carpeta específica de la app: {appId}/{...paths} */
53
+ forApp: (appId, ...paths) => [appId, ...paths].join('/'),
54
+ /** Carpetas compartidas (sin namespace) */
55
+ shared: {
56
+ /** Foto de perfil de usuario */
57
+ profilePhoto: (userId, fileName) => `profile-photos/${userId}/${fileName}`,
58
+ /** Archivos públicos accesibles sin autenticación */
59
+ public: (...paths) => `public/${paths.join('/')}`,
60
+ },
61
+ /** Carpetas de desarrollo (acceso libre en emuladores) */
62
+ demo: (...paths) => `demo/${paths.join('/')}`,
63
+ };
64
+ // ============================================================================
65
+ // FIRESTORE COLLECTION BUILDERS
66
+ // ============================================================================
67
+ /**
68
+ * Genera paths de colecciones con namespace por app.
69
+ *
70
+ * IMPORTANTE: La estructura es /apps/{appId}/{collection}/{docId}
71
+ * Firestore requiere número impar de segmentos para paths de colección.
72
+ *
73
+ * @example
74
+ * // Colección específica de la app
75
+ * collections.forApp('showcase', 'items')
76
+ * // => 'apps/showcase/items'
77
+ *
78
+ * // Colección de desarrollo
79
+ * collections.forApp('demo', 'items')
80
+ * // => 'apps/demo/items'
81
+ *
82
+ * // Colección compartida
83
+ * collections.shared.users
84
+ * // => 'users'
85
+ */
86
+ export const collections = {
87
+ /** Colección específica de la app: apps/{appId}/{collection} */
88
+ forApp: (appId, collectionName) => `apps/${appId}/${collectionName}`,
89
+ /** Colecciones compartidas (sin namespace, nivel raíz) */
90
+ shared: {
91
+ /** Usuarios del sistema */
92
+ users: 'users',
93
+ /** Perfiles públicos */
94
+ profiles: 'profiles',
95
+ /** Notificaciones de usuarios */
96
+ notifications: 'notifications',
97
+ },
98
+ };
99
+ /**
100
+ * Crea la configuración completa de Firebase desde variables de entorno.
101
+ * Usa esto en el environment.ts de cada app.
102
+ *
103
+ * @example
104
+ * // environment.ts
105
+ * export const environment = {
106
+ * firebase: createFirebaseConfig(
107
+ * {
108
+ * apiKey: 'AIza...',
109
+ * authDomain: 'myvaltech-dev.firebaseapp.com',
110
+ * projectId: 'myvaltech-dev',
111
+ * storageBucket: 'myvaltech-dev.appspot.com',
112
+ * messagingSenderId: '123456789',
113
+ * appId: '1:123456789:web:abc123',
114
+ * },
115
+ * { useEmulators: true, persistence: true }
116
+ * ),
117
+ * };
118
+ */
119
+ export function createFirebaseConfig(envConfig, options = {}) {
120
+ const { useEmulators = false, persistence = true, enableMessaging = false, messagingVapidKey } = options;
121
+ return {
122
+ firebase: envConfig,
123
+ persistence,
124
+ enableMessaging,
125
+ messagingVapidKey,
126
+ emulator: useEmulators ? SHARED_EMULATOR_CONFIG : undefined,
127
+ };
128
+ }
129
+ // ============================================================================
130
+ // UTILITY: Check if running in emulator mode
131
+ // ============================================================================
132
+ /**
133
+ * Verifica si la configuración tiene emuladores habilitados
134
+ */
135
+ export function isEmulatorMode(config) {
136
+ return config.emulator !== undefined;
137
+ }
138
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLWNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc2VydmljZXMvZmlyZWJhc2Uvc2hhcmVkLWNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQWNILE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRztJQUNyQixJQUFJLEVBQUUsTUFBZTtJQUNyQixRQUFRLEVBQUUsVUFBbUI7SUFDN0IsWUFBWSxFQUFFLGNBQXVCO0lBQ3JDLEdBQUcsRUFBRSxLQUFjO0NBQ1gsQ0FBQztBQUVYLCtFQUErRTtBQUMvRSx1QkFBdUI7QUFDdkIsK0VBQStFO0FBRS9FOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHO0lBQy9CLFdBQVcsRUFBRSxlQUFlO0lBQzVCLFVBQVUsRUFBRSxnQkFBZ0I7Q0FDcEIsQ0FBQztBQUVYLCtFQUErRTtBQUMvRSxrREFBa0Q7QUFDbEQsK0VBQStFO0FBRS9FOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFtQjtJQUNwRCxTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUU7SUFDNUMsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFO0lBQzFDLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRTtDQUN4QyxDQUFDO0FBRUYsK0VBQStFO0FBQy9FLHdCQUF3QjtBQUN4QiwrRUFBK0U7QUFFL0U7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUc7SUFDMUIsdURBQXVEO0lBQ3ZELE1BQU0sRUFBRSxDQUFDLEtBQVksRUFBRSxHQUFHLEtBQWUsRUFBVSxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBRWpGLDJDQUEyQztJQUMzQyxNQUFNLEVBQUU7UUFDTixnQ0FBZ0M7UUFDaEMsWUFBWSxFQUFFLENBQUMsTUFBYyxFQUFFLFFBQWdCLEVBQVUsRUFBRSxDQUN6RCxrQkFBa0IsTUFBTSxJQUFJLFFBQVEsRUFBRTtRQUV4QyxxREFBcUQ7UUFDckQsTUFBTSxFQUFFLENBQUMsR0FBRyxLQUFlLEVBQVUsRUFBRSxDQUFDLFVBQVUsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRTtLQUNwRTtJQUVELDBEQUEwRDtJQUMxRCxJQUFJLEVBQUUsQ0FBQyxHQUFHLEtBQWUsRUFBVSxFQUFFLENBQUMsUUFBUSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO0NBQ2hFLENBQUM7QUFFRiwrRUFBK0U7QUFDL0UsZ0NBQWdDO0FBQ2hDLCtFQUErRTtBQUUvRTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHO0lBQ3pCLGdFQUFnRTtJQUNoRSxNQUFNLEVBQUUsQ0FBQyxLQUFZLEVBQUUsY0FBc0IsRUFBVSxFQUFFLENBQUMsUUFBUSxLQUFLLElBQUksY0FBYyxFQUFFO0lBRTNGLDBEQUEwRDtJQUMxRCxNQUFNLEVBQUU7UUFDTiwyQkFBMkI7UUFDM0IsS0FBSyxFQUFFLE9BQU87UUFDZCx3QkFBd0I7UUFDeEIsUUFBUSxFQUFFLFVBQVU7UUFDcEIsaUNBQWlDO1FBQ2pDLGFBQWEsRUFBRSxlQUFlO0tBQy9CO0NBQ0YsQ0FBQztBQW9CRjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FDbEMsU0FBeUIsRUFDekIsVUFBdUMsRUFBRTtJQUV6QyxNQUFNLEVBQUUsWUFBWSxHQUFHLEtBQUssRUFBRSxXQUFXLEdBQUcsSUFBSSxFQUFFLGVBQWUsR0FBRyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsR0FDNUYsT0FBTyxDQUFDO0lBRVYsT0FBTztRQUNMLFFBQVEsRUFBRSxTQUFTO1FBQ25CLFdBQVc7UUFDWCxlQUFlO1FBQ2YsaUJBQWlCO1FBQ2pCLFFBQVEsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxTQUFTO0tBQzVELENBQUM7QUFDSixDQUFDO0FBRUQsK0VBQStFO0FBQy9FLDZDQUE2QztBQUM3QywrRUFBK0U7QUFFL0U7O0dBRUc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLE1BQTZCO0lBQzFELE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLENBQUM7QUFDdkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRmlyZWJhc2UgU2hhcmVkIENvbmZpZ3VyYXRpb25cbiAqXG4gKiBDb25maWd1cmFjacOzbiBiYXNlIGRlIEZpcmViYXNlIGNvbXBhcnRpZGEgZW50cmUgdG9kYXMgbGFzIGFwcHMgZGVsIG1vbm9yZXBvLlxuICogTG9zIHNlY3JldHMgKGFwaUtleSwgYXBwSWQpIHNlIGlueWVjdGFuIGVuIGJ1aWxkIHRpbWUgdmlhIGVudmlyb25tZW50LlxuICovXG5cbmltcG9ydCB7IEVtdWxhdG9yQ29uZmlnLCBGaXJlYmFzZUNvbmZpZywgVmFsdGVjaEZpcmViYXNlQ29uZmlnIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEFQUCBJRFMgLSBJZGVudGlmaWNhZG9yZXMgw7puaWNvcyBwb3IgYXBsaWNhY2nDs25cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBJZGVudGlmaWNhZG9yZXMgZGUgbGFzIGFwcHMgZGVsIG1vbm9yZXBvLlxuICogVXNhZG9zIHBhcmEgbmFtZXNwYWNpbmcgZGUgY29sZWNjaW9uZXMgRmlyZXN0b3JlIHkgcGF0aHMgZGUgU3RvcmFnZS5cbiAqL1xuZXhwb3J0IHR5cGUgQXBwSWQgPSAnZGVtbycgfCAnc2hvd2Nhc2UnIHwgJ2FkbWluLXBvcnRhbCcgfCAnYXBwJztcblxuZXhwb3J0IGNvbnN0IEFQUF9JRFMgPSB7XG4gIERFTU86ICdkZW1vJyBhcyBBcHBJZCxcbiAgU0hPV0NBU0U6ICdzaG93Y2FzZScgYXMgQXBwSWQsXG4gIEFETUlOX1BPUlRBTDogJ2FkbWluLXBvcnRhbCcgYXMgQXBwSWQsXG4gIEFQUDogJ2FwcCcgYXMgQXBwSWQsXG59IGFzIGNvbnN0O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBGSVJFQkFTRSBQUk9KRUNUIElEU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIElEcyBkZSBsb3MgcHJveWVjdG9zIEZpcmViYXNlIHBvciBhbWJpZW50ZS5cbiAqIERlYmVuIGNvaW5jaWRpciBjb24gbG9zIHByb3llY3RvcyBjcmVhZG9zIGVuIEZpcmViYXNlIENvbnNvbGUuXG4gKi9cbmV4cG9ydCBjb25zdCBGSVJFQkFTRV9QUk9KRUNUUyA9IHtcbiAgZGV2ZWxvcG1lbnQ6ICdteXZhbHRlY2gtZGV2JyxcbiAgcHJvZHVjdGlvbjogJ215dmFsdGVjaC1wcm9kJyxcbn0gYXMgY29uc3Q7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEVNVUxBVE9SIENPTkZJR1VSQVRJT04gKHNoYXJlZCBhY3Jvc3MgYWxsIGFwcHMpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ29uZmlndXJhY2nDs24gZGUgZW11bGFkb3JlcyBjb21wYXJ0aWRhLlxuICogVG9kb3MgbG9zIHB1ZXJ0b3MgZGViZW4gY29pbmNpZGlyIGNvbiBmcm9udGVuZC9maXJlYmFzZS9maXJlYmFzZS5qc29uXG4gKi9cbmV4cG9ydCBjb25zdCBTSEFSRURfRU1VTEFUT1JfQ09ORklHOiBFbXVsYXRvckNvbmZpZyA9IHtcbiAgZmlyZXN0b3JlOiB7IGhvc3Q6ICdsb2NhbGhvc3QnLCBwb3J0OiA5MDgwIH0sXG4gIHN0b3JhZ2U6IHsgaG9zdDogJ2xvY2FsaG9zdCcsIHBvcnQ6IDkxOTkgfSxcbiAgYXV0aDogeyBob3N0OiAnbG9jYWxob3N0JywgcG9ydDogOTA5OSB9LFxufTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gU1RPUkFHRSBQQVRIIEJVSUxERVJTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogR2VuZXJhIHBhdGhzIGRlIFN0b3JhZ2UgY29uIG5hbWVzcGFjZSBwb3IgYXBwLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBQYXRoIGVzcGVjw61maWNvIGRlIGxhIGFwcFxuICogc3RvcmFnZVBhdGhzLmZvckFwcCgnc2hvd2Nhc2UnLCAndXBsb2FkcycsICdpbWFnZS5qcGcnKVxuICogLy8gPT4gJ3Nob3djYXNlL3VwbG9hZHMvaW1hZ2UuanBnJ1xuICpcbiAqIC8vIFBhdGggY29tcGFydGlkb1xuICogc3RvcmFnZVBhdGhzLnNoYXJlZC5wcm9maWxlUGhvdG8oJ3VzZXIxMjMnLCAnYXZhdGFyLmpwZycpXG4gKiAvLyA9PiAncHJvZmlsZS1waG90b3MvdXNlcjEyMy9hdmF0YXIuanBnJ1xuICovXG5leHBvcnQgY29uc3Qgc3RvcmFnZVBhdGhzID0ge1xuICAvKiogQ2FycGV0YSBlc3BlY8OtZmljYSBkZSBsYSBhcHA6IHthcHBJZH0vey4uLnBhdGhzfSAqL1xuICBmb3JBcHA6IChhcHBJZDogQXBwSWQsIC4uLnBhdGhzOiBzdHJpbmdbXSk6IHN0cmluZyA9PiBbYXBwSWQsIC4uLnBhdGhzXS5qb2luKCcvJyksXG5cbiAgLyoqIENhcnBldGFzIGNvbXBhcnRpZGFzIChzaW4gbmFtZXNwYWNlKSAqL1xuICBzaGFyZWQ6IHtcbiAgICAvKiogRm90byBkZSBwZXJmaWwgZGUgdXN1YXJpbyAqL1xuICAgIHByb2ZpbGVQaG90bzogKHVzZXJJZDogc3RyaW5nLCBmaWxlTmFtZTogc3RyaW5nKTogc3RyaW5nID0+XG4gICAgICBgcHJvZmlsZS1waG90b3MvJHt1c2VySWR9LyR7ZmlsZU5hbWV9YCxcblxuICAgIC8qKiBBcmNoaXZvcyBww7pibGljb3MgYWNjZXNpYmxlcyBzaW4gYXV0ZW50aWNhY2nDs24gKi9cbiAgICBwdWJsaWM6ICguLi5wYXRoczogc3RyaW5nW10pOiBzdHJpbmcgPT4gYHB1YmxpYy8ke3BhdGhzLmpvaW4oJy8nKX1gLFxuICB9LFxuXG4gIC8qKiBDYXJwZXRhcyBkZSBkZXNhcnJvbGxvIChhY2Nlc28gbGlicmUgZW4gZW11bGFkb3JlcykgKi9cbiAgZGVtbzogKC4uLnBhdGhzOiBzdHJpbmdbXSk6IHN0cmluZyA9PiBgZGVtby8ke3BhdGhzLmpvaW4oJy8nKX1gLFxufTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRklSRVNUT1JFIENPTExFQ1RJT04gQlVJTERFUlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBHZW5lcmEgcGF0aHMgZGUgY29sZWNjaW9uZXMgY29uIG5hbWVzcGFjZSBwb3IgYXBwLlxuICpcbiAqIElNUE9SVEFOVEU6IExhIGVzdHJ1Y3R1cmEgZXMgL2FwcHMve2FwcElkfS97Y29sbGVjdGlvbn0ve2RvY0lkfVxuICogRmlyZXN0b3JlIHJlcXVpZXJlIG7Dum1lcm8gaW1wYXIgZGUgc2VnbWVudG9zIHBhcmEgcGF0aHMgZGUgY29sZWNjacOzbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ29sZWNjacOzbiBlc3BlY8OtZmljYSBkZSBsYSBhcHBcbiAqIGNvbGxlY3Rpb25zLmZvckFwcCgnc2hvd2Nhc2UnLCAnaXRlbXMnKVxuICogLy8gPT4gJ2FwcHMvc2hvd2Nhc2UvaXRlbXMnXG4gKlxuICogLy8gQ29sZWNjacOzbiBkZSBkZXNhcnJvbGxvXG4gKiBjb2xsZWN0aW9ucy5mb3JBcHAoJ2RlbW8nLCAnaXRlbXMnKVxuICogLy8gPT4gJ2FwcHMvZGVtby9pdGVtcydcbiAqXG4gKiAvLyBDb2xlY2Npw7NuIGNvbXBhcnRpZGFcbiAqIGNvbGxlY3Rpb25zLnNoYXJlZC51c2Vyc1xuICogLy8gPT4gJ3VzZXJzJ1xuICovXG5leHBvcnQgY29uc3QgY29sbGVjdGlvbnMgPSB7XG4gIC8qKiBDb2xlY2Npw7NuIGVzcGVjw61maWNhIGRlIGxhIGFwcDogYXBwcy97YXBwSWR9L3tjb2xsZWN0aW9ufSAqL1xuICBmb3JBcHA6IChhcHBJZDogQXBwSWQsIGNvbGxlY3Rpb25OYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4gYGFwcHMvJHthcHBJZH0vJHtjb2xsZWN0aW9uTmFtZX1gLFxuXG4gIC8qKiBDb2xlY2Npb25lcyBjb21wYXJ0aWRhcyAoc2luIG5hbWVzcGFjZSwgbml2ZWwgcmHDrXopICovXG4gIHNoYXJlZDoge1xuICAgIC8qKiBVc3VhcmlvcyBkZWwgc2lzdGVtYSAqL1xuICAgIHVzZXJzOiAndXNlcnMnLFxuICAgIC8qKiBQZXJmaWxlcyBww7pibGljb3MgKi9cbiAgICBwcm9maWxlczogJ3Byb2ZpbGVzJyxcbiAgICAvKiogTm90aWZpY2FjaW9uZXMgZGUgdXN1YXJpb3MgKi9cbiAgICBub3RpZmljYXRpb25zOiAnbm90aWZpY2F0aW9ucycsXG4gIH0sXG59O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBIRUxQRVI6IENyZWF0ZSBGaXJlYmFzZSBDb25maWcgZnJvbSBFbnZpcm9ubWVudFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIE9wY2lvbmVzIHBhcmEgY3JlYXIgbGEgY29uZmlndXJhY2nDs24gZGUgRmlyZWJhc2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVGaXJlYmFzZUNvbmZpZ09wdGlvbnMge1xuICAvKiogVXNhciBlbXVsYWRvcmVzIGxvY2FsZXMgKHBhcmEgZGVzYXJyb2xsbykgKi9cbiAgdXNlRW11bGF0b3JzPzogYm9vbGVhbjtcbiAgLyoqIEhhYmlsaXRhciBwZXJzaXN0ZW5jaWEgb2ZmbGluZSBkZSBGaXJlc3RvcmUgKi9cbiAgcGVyc2lzdGVuY2U/OiBib29sZWFuO1xuICAvKiogSGFiaWxpdGFyIEZpcmViYXNlIENsb3VkIE1lc3NhZ2luZyAqL1xuICBlbmFibGVNZXNzYWdpbmc/OiBib29sZWFuO1xuICAvKiogVkFQSUQga2V5IHBhcmEgRkNNIChyZXF1ZXJpZG8gc2kgZW5hYmxlTWVzc2FnaW5nIGVzIHRydWUpICovXG4gIG1lc3NhZ2luZ1ZhcGlkS2V5Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIENyZWEgbGEgY29uZmlndXJhY2nDs24gY29tcGxldGEgZGUgRmlyZWJhc2UgZGVzZGUgdmFyaWFibGVzIGRlIGVudG9ybm8uXG4gKiBVc2EgZXN0byBlbiBlbCBlbnZpcm9ubWVudC50cyBkZSBjYWRhIGFwcC5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gZW52aXJvbm1lbnQudHNcbiAqIGV4cG9ydCBjb25zdCBlbnZpcm9ubWVudCA9IHtcbiAqICAgZmlyZWJhc2U6IGNyZWF0ZUZpcmViYXNlQ29uZmlnKFxuICogICAgIHtcbiAqICAgICAgIGFwaUtleTogJ0FJemEuLi4nLFxuICogICAgICAgYXV0aERvbWFpbjogJ215dmFsdGVjaC1kZXYuZmlyZWJhc2VhcHAuY29tJyxcbiAqICAgICAgIHByb2plY3RJZDogJ215dmFsdGVjaC1kZXYnLFxuICogICAgICAgc3RvcmFnZUJ1Y2tldDogJ215dmFsdGVjaC1kZXYuYXBwc3BvdC5jb20nLFxuICogICAgICAgbWVzc2FnaW5nU2VuZGVySWQ6ICcxMjM0NTY3ODknLFxuICogICAgICAgYXBwSWQ6ICcxOjEyMzQ1Njc4OTp3ZWI6YWJjMTIzJyxcbiAqICAgICB9LFxuICogICAgIHsgdXNlRW11bGF0b3JzOiB0cnVlLCBwZXJzaXN0ZW5jZTogdHJ1ZSB9XG4gKiAgICksXG4gKiB9O1xuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRmlyZWJhc2VDb25maWcoXG4gIGVudkNvbmZpZzogRmlyZWJhc2VDb25maWcsXG4gIG9wdGlvbnM6IENyZWF0ZUZpcmViYXNlQ29uZmlnT3B0aW9ucyA9IHt9XG4pOiBWYWx0ZWNoRmlyZWJhc2VDb25maWcge1xuICBjb25zdCB7IHVzZUVtdWxhdG9ycyA9IGZhbHNlLCBwZXJzaXN0ZW5jZSA9IHRydWUsIGVuYWJsZU1lc3NhZ2luZyA9IGZhbHNlLCBtZXNzYWdpbmdWYXBpZEtleSB9ID1cbiAgICBvcHRpb25zO1xuXG4gIHJldHVybiB7XG4gICAgZmlyZWJhc2U6IGVudkNvbmZpZyxcbiAgICBwZXJzaXN0ZW5jZSxcbiAgICBlbmFibGVNZXNzYWdpbmcsXG4gICAgbWVzc2FnaW5nVmFwaWRLZXksXG4gICAgZW11bGF0b3I6IHVzZUVtdWxhdG9ycyA/IFNIQVJFRF9FTVVMQVRPUl9DT05GSUcgOiB1bmRlZmluZWQsXG4gIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFVUSUxJVFk6IENoZWNrIGlmIHJ1bm5pbmcgaW4gZW11bGF0b3IgbW9kZVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFZlcmlmaWNhIHNpIGxhIGNvbmZpZ3VyYWNpw7NuIHRpZW5lIGVtdWxhZG9yZXMgaGFiaWxpdGFkb3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW11bGF0b3JNb2RlKGNvbmZpZzogVmFsdGVjaEZpcmViYXNlQ29uZmlnKTogYm9vbGVhbiB7XG4gIHJldHVybiBjb25maWcuZW11bGF0b3IgIT09IHVuZGVmaW5lZDtcbn1cbiJdfQ==
@@ -0,0 +1,422 @@
1
+ /**
2
+ * Storage Service
3
+ *
4
+ * Servicio para operaciones de Firebase Storage.
5
+ * Soporta upload con tracking de progreso, download y gestión de archivos.
6
+ */
7
+ import { Injectable } from '@angular/core';
8
+ import { deleteObject, getDownloadURL, getMetadata, listAll, ref, uploadBytesResumable, } from '@angular/fire/storage';
9
+ import { BehaviorSubject } from 'rxjs';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/fire/storage";
12
+ /**
13
+ * Servicio para Firebase Storage.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * @Component({...})
18
+ * export class FileUploadComponent {
19
+ * private storage = inject(StorageService);
20
+ *
21
+ * uploadProgress = signal<number>(0);
22
+ * downloadUrl = signal<string | null>(null);
23
+ *
24
+ * async onFileSelected(event: Event) {
25
+ * const file = (event.target as HTMLInputElement).files?.[0];
26
+ * if (!file) return;
27
+ *
28
+ * // Upload con progreso
29
+ * this.storage.upload(`uploads/${file.name}`, file).subscribe({
30
+ * next: (progress) => this.uploadProgress.set(progress.percentage),
31
+ * complete: async () => {
32
+ * const url = await this.storage.getDownloadUrl(`uploads/${file.name}`);
33
+ * this.downloadUrl.set(url);
34
+ * }
35
+ * });
36
+ * }
37
+ * }
38
+ * ```
39
+ */
40
+ export class StorageService {
41
+ constructor(storage) {
42
+ this.storage = storage;
43
+ }
44
+ // ===========================================================================
45
+ // UPLOAD
46
+ // ===========================================================================
47
+ /**
48
+ * Sube un archivo con tracking de progreso.
49
+ *
50
+ * @param path - Ruta en Storage donde guardar el archivo
51
+ * @param file - Archivo a subir (File o Blob)
52
+ * @param metadata - Metadata opcional (contentType, customMetadata)
53
+ * @returns Observable que emite el progreso y completa cuando termina
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * // Upload básico
58
+ * storage.upload('images/photo.jpg', file).subscribe({
59
+ * next: (progress) => console.log(`${progress.percentage}%`),
60
+ * complete: () => console.log('Upload completado')
61
+ * });
62
+ *
63
+ * // Con metadata
64
+ * storage.upload('docs/report.pdf', file, {
65
+ * contentType: 'application/pdf',
66
+ * customMetadata: { uploadedBy: 'user123' }
67
+ * }).subscribe(...);
68
+ * ```
69
+ */
70
+ upload(path, file, metadata) {
71
+ const storageRef = ref(this.storage, path);
72
+ const uploadMetadata = {
73
+ contentType: metadata?.contentType || (file instanceof File ? file.type : undefined),
74
+ customMetadata: metadata?.customMetadata,
75
+ cacheControl: metadata?.cacheControl,
76
+ };
77
+ const task = uploadBytesResumable(storageRef, file, uploadMetadata);
78
+ const progress$ = new BehaviorSubject({
79
+ bytesTransferred: 0,
80
+ totalBytes: file.size,
81
+ percentage: 0,
82
+ state: 'running',
83
+ });
84
+ task.on('state_changed', (snapshot) => {
85
+ progress$.next({
86
+ bytesTransferred: snapshot.bytesTransferred,
87
+ totalBytes: snapshot.totalBytes,
88
+ percentage: Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100),
89
+ state: this.mapTaskState(snapshot.state),
90
+ });
91
+ }, (error) => {
92
+ progress$.next({
93
+ bytesTransferred: 0,
94
+ totalBytes: file.size,
95
+ percentage: 0,
96
+ state: 'error',
97
+ });
98
+ progress$.error(this.getErrorMessage(error));
99
+ }, () => {
100
+ progress$.next({
101
+ bytesTransferred: file.size,
102
+ totalBytes: file.size,
103
+ percentage: 100,
104
+ state: 'success',
105
+ });
106
+ progress$.complete();
107
+ });
108
+ return progress$.asObservable();
109
+ }
110
+ /**
111
+ * Sube un archivo y retorna la URL de descarga al completar.
112
+ *
113
+ * @param path - Ruta en Storage
114
+ * @param file - Archivo a subir
115
+ * @param metadata - Metadata opcional
116
+ * @returns Resultado del upload con URL de descarga
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * const result = await storage.uploadAndGetUrl('avatars/user123.jpg', file);
121
+ * console.log('URL:', result.downloadUrl);
122
+ * ```
123
+ */
124
+ async uploadAndGetUrl(path, file, metadata) {
125
+ return new Promise((resolve, reject) => {
126
+ this.upload(path, file, metadata).subscribe({
127
+ complete: async () => {
128
+ try {
129
+ const storageRef = ref(this.storage, path);
130
+ const downloadUrl = await getDownloadURL(storageRef);
131
+ const storedMetadata = await getMetadata(storageRef);
132
+ resolve({
133
+ downloadUrl,
134
+ fullPath: storedMetadata.fullPath,
135
+ name: storedMetadata.name,
136
+ size: storedMetadata.size,
137
+ contentType: storedMetadata.contentType || 'application/octet-stream',
138
+ metadata: storedMetadata.customMetadata || {},
139
+ });
140
+ }
141
+ catch (error) {
142
+ reject(this.getErrorMessage(error));
143
+ }
144
+ },
145
+ error: (error) => reject(error),
146
+ });
147
+ });
148
+ }
149
+ /**
150
+ * Sube un archivo desde una Data URL (base64).
151
+ *
152
+ * @param path - Ruta en Storage
153
+ * @param dataUrl - Data URL (ej: 'data:image/png;base64,...')
154
+ * @param metadata - Metadata opcional
155
+ * @returns Resultado del upload
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * // Desde canvas
160
+ * const dataUrl = canvas.toDataURL('image/png');
161
+ * const result = await storage.uploadFromDataUrl('images/drawing.png', dataUrl);
162
+ * ```
163
+ */
164
+ async uploadFromDataUrl(path, dataUrl, metadata) {
165
+ // Extraer content type y datos base64
166
+ const matches = dataUrl.match(/^data:([^;]+);base64,(.+)$/);
167
+ if (!matches) {
168
+ throw new Error('Data URL inválida');
169
+ }
170
+ const contentType = matches[1];
171
+ const base64Data = matches[2];
172
+ // Convertir base64 a Blob
173
+ const byteCharacters = atob(base64Data);
174
+ const byteNumbers = new Array(byteCharacters.length);
175
+ for (let i = 0; i < byteCharacters.length; i++) {
176
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
177
+ }
178
+ const byteArray = new Uint8Array(byteNumbers);
179
+ const blob = new Blob([byteArray], { type: contentType });
180
+ return this.uploadAndGetUrl(path, blob, {
181
+ contentType,
182
+ ...metadata,
183
+ });
184
+ }
185
+ // ===========================================================================
186
+ // DOWNLOAD
187
+ // ===========================================================================
188
+ /**
189
+ * Obtiene la URL de descarga de un archivo.
190
+ *
191
+ * @param path - Ruta del archivo en Storage
192
+ * @returns URL de descarga
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * const url = await storage.getDownloadUrl('images/photo.jpg');
197
+ * // Usar en <img [src]="url">
198
+ * ```
199
+ */
200
+ async getDownloadUrl(path) {
201
+ try {
202
+ const storageRef = ref(this.storage, path);
203
+ return await getDownloadURL(storageRef);
204
+ }
205
+ catch (error) {
206
+ throw new Error(this.getErrorMessage(error));
207
+ }
208
+ }
209
+ /**
210
+ * Obtiene la metadata de un archivo.
211
+ *
212
+ * @param path - Ruta del archivo
213
+ * @returns Metadata del archivo
214
+ */
215
+ async getMetadata(path) {
216
+ try {
217
+ const storageRef = ref(this.storage, path);
218
+ const metadata = await getMetadata(storageRef);
219
+ return {
220
+ contentType: metadata.contentType,
221
+ customMetadata: metadata.customMetadata,
222
+ cacheControl: metadata.cacheControl,
223
+ size: metadata.size,
224
+ name: metadata.name,
225
+ };
226
+ }
227
+ catch (error) {
228
+ throw new Error(this.getErrorMessage(error));
229
+ }
230
+ }
231
+ // ===========================================================================
232
+ // DELETE
233
+ // ===========================================================================
234
+ /**
235
+ * Elimina un archivo.
236
+ *
237
+ * @param path - Ruta del archivo a eliminar
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * await storage.delete('images/old-photo.jpg');
242
+ * ```
243
+ */
244
+ async delete(path) {
245
+ try {
246
+ const storageRef = ref(this.storage, path);
247
+ await deleteObject(storageRef);
248
+ }
249
+ catch (error) {
250
+ throw new Error(this.getErrorMessage(error));
251
+ }
252
+ }
253
+ /**
254
+ * Elimina múltiples archivos.
255
+ *
256
+ * @param paths - Array de rutas a eliminar
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * await storage.deleteMultiple([
261
+ * 'images/photo1.jpg',
262
+ * 'images/photo2.jpg'
263
+ * ]);
264
+ * ```
265
+ */
266
+ async deleteMultiple(paths) {
267
+ await Promise.all(paths.map((path) => this.delete(path)));
268
+ }
269
+ // ===========================================================================
270
+ // LIST
271
+ // ===========================================================================
272
+ /**
273
+ * Lista archivos en un directorio.
274
+ *
275
+ * @param path - Ruta del directorio
276
+ * @returns Lista de rutas de archivos
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * const result = await storage.list('images/');
281
+ * console.log(result.items); // ['images/photo1.jpg', 'images/photo2.jpg']
282
+ * ```
283
+ */
284
+ async list(path) {
285
+ try {
286
+ const storageRef = ref(this.storage, path);
287
+ const result = await listAll(storageRef);
288
+ return {
289
+ items: result.items.map((item) => item.fullPath),
290
+ nextPageToken: undefined, // listAll no soporta paginación
291
+ };
292
+ }
293
+ catch (error) {
294
+ throw new Error(this.getErrorMessage(error));
295
+ }
296
+ }
297
+ // ===========================================================================
298
+ // UTILIDADES
299
+ // ===========================================================================
300
+ /**
301
+ * Genera un nombre de archivo único con timestamp.
302
+ *
303
+ * @param originalName - Nombre original del archivo
304
+ * @param prefix - Prefijo opcional
305
+ * @returns Nombre único
306
+ *
307
+ * @example
308
+ * ```typescript
309
+ * const uniqueName = storage.generateFileName('photo.jpg', 'user123');
310
+ * // => 'user123_1703091234567_photo.jpg'
311
+ * ```
312
+ */
313
+ generateFileName(originalName, prefix) {
314
+ const timestamp = Date.now();
315
+ const sanitizedName = originalName.replace(/[^a-zA-Z0-9.-]/g, '_');
316
+ if (prefix) {
317
+ return `${prefix}_${timestamp}_${sanitizedName}`;
318
+ }
319
+ return `${timestamp}_${sanitizedName}`;
320
+ }
321
+ /**
322
+ * Genera una ruta única para un archivo.
323
+ *
324
+ * @param directory - Directorio base
325
+ * @param originalName - Nombre original
326
+ * @param prefix - Prefijo opcional
327
+ * @returns Ruta completa única
328
+ *
329
+ * @example
330
+ * ```typescript
331
+ * const path = storage.generatePath('uploads', 'photo.jpg', 'user123');
332
+ * // => 'uploads/user123_1703091234567_photo.jpg'
333
+ * ```
334
+ */
335
+ generatePath(directory, originalName, prefix) {
336
+ const fileName = this.generateFileName(originalName, prefix);
337
+ const cleanDir = directory.replace(/\/+$/, ''); // Remover / final
338
+ return `${cleanDir}/${fileName}`;
339
+ }
340
+ /**
341
+ * Obtiene la extensión de un archivo.
342
+ *
343
+ * @param filename - Nombre del archivo
344
+ * @returns Extensión (sin el punto)
345
+ */
346
+ getExtension(filename) {
347
+ const parts = filename.split('.');
348
+ return parts.length > 1 ? parts.pop().toLowerCase() : '';
349
+ }
350
+ /**
351
+ * Verifica si un archivo es una imagen basándose en su extensión.
352
+ */
353
+ isImage(filename) {
354
+ const ext = this.getExtension(filename);
355
+ return ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'].includes(ext);
356
+ }
357
+ /**
358
+ * Verifica si un archivo es un documento.
359
+ */
360
+ isDocument(filename) {
361
+ const ext = this.getExtension(filename);
362
+ return ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'].includes(ext);
363
+ }
364
+ // ===========================================================================
365
+ // MÉTODOS PRIVADOS
366
+ // ===========================================================================
367
+ /**
368
+ * Mapea el estado de la tarea de upload
369
+ */
370
+ mapTaskState(state) {
371
+ switch (state) {
372
+ case 'running':
373
+ return 'running';
374
+ case 'paused':
375
+ return 'paused';
376
+ case 'success':
377
+ return 'success';
378
+ case 'canceled':
379
+ return 'canceled';
380
+ case 'error':
381
+ return 'error';
382
+ default:
383
+ return 'running';
384
+ }
385
+ }
386
+ /**
387
+ * Convierte errores de Storage a mensajes en español
388
+ */
389
+ getErrorMessage(error) {
390
+ if (error instanceof Error) {
391
+ const code = error.code;
392
+ switch (code) {
393
+ case 'storage/object-not-found':
394
+ return 'El archivo no existe';
395
+ case 'storage/unauthorized':
396
+ return 'No tienes permiso para acceder a este archivo';
397
+ case 'storage/canceled':
398
+ return 'La operación fue cancelada';
399
+ case 'storage/quota-exceeded':
400
+ return 'Se ha excedido la cuota de almacenamiento';
401
+ case 'storage/invalid-checksum':
402
+ return 'El archivo está corrupto';
403
+ case 'storage/retry-limit-exceeded':
404
+ return 'Error de conexión. Intenta de nuevo';
405
+ case 'storage/invalid-url':
406
+ return 'URL de archivo inválida';
407
+ case 'storage/invalid-argument':
408
+ return 'Argumento inválido';
409
+ default:
410
+ return error.message || 'Error de almacenamiento desconocido';
411
+ }
412
+ }
413
+ return 'Error de almacenamiento desconocido';
414
+ }
415
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StorageService, deps: [{ token: i1.Storage }], target: i0.ɵɵFactoryTarget.Injectable }); }
416
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StorageService, providedIn: 'root' }); }
417
+ }
418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StorageService, decorators: [{
419
+ type: Injectable,
420
+ args: [{ providedIn: 'root' }]
421
+ }], ctorParameters: () => [{ type: i1.Storage }] });
422
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9maXJlYmFzZS9zdG9yYWdlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxZQUFZLEVBQ1osY0FBYyxFQUNkLFdBQVcsRUFDWCxPQUFPLEVBQ1AsR0FBRyxFQUVILG9CQUFvQixHQUdyQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxlQUFlLEVBQWMsTUFBTSxNQUFNLENBQUM7OztBQUluRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkJHO0FBRUgsTUFBTSxPQUFPLGNBQWM7SUFDekIsWUFBb0IsT0FBZ0I7UUFBaEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztJQUFHLENBQUM7SUFFeEMsOEVBQThFO0lBQzlFLFNBQVM7SUFDVCw4RUFBOEU7SUFFOUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzQkc7SUFDSCxNQUFNLENBQUMsSUFBWSxFQUFFLElBQWlCLEVBQUUsUUFBMEI7UUFDaEUsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0MsTUFBTSxjQUFjLEdBQW1CO1lBQ3JDLFdBQVcsRUFBRSxRQUFRLEVBQUUsV0FBVyxJQUFJLENBQUMsSUFBSSxZQUFZLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3BGLGNBQWMsRUFBRSxRQUFRLEVBQUUsY0FBYztZQUN4QyxZQUFZLEVBQUUsUUFBUSxFQUFFLFlBQVk7U0FDckMsQ0FBQztRQUVGLE1BQU0sSUFBSSxHQUFHLG9CQUFvQixDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDcEUsTUFBTSxTQUFTLEdBQUcsSUFBSSxlQUFlLENBQWlCO1lBQ3BELGdCQUFnQixFQUFFLENBQUM7WUFDbkIsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ3JCLFVBQVUsRUFBRSxDQUFDO1lBQ2IsS0FBSyxFQUFFLFNBQVM7U0FDakIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLEVBQUUsQ0FDTCxlQUFlLEVBQ2YsQ0FBQyxRQUE0QixFQUFFLEVBQUU7WUFDL0IsU0FBUyxDQUFDLElBQUksQ0FBQztnQkFDYixnQkFBZ0IsRUFBRSxRQUFRLENBQUMsZ0JBQWdCO2dCQUMzQyxVQUFVLEVBQUUsUUFBUSxDQUFDLFVBQVU7Z0JBQy9CLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUM7Z0JBQy9FLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7YUFDekMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxFQUNELENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDUixTQUFTLENBQUMsSUFBSSxDQUFDO2dCQUNiLGdCQUFnQixFQUFFLENBQUM7Z0JBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUMsSUFBSTtnQkFDckIsVUFBVSxFQUFFLENBQUM7Z0JBQ2IsS0FBSyxFQUFFLE9BQU87YUFDZixDQUFDLENBQUM7WUFDSCxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDLEVBQ0QsR0FBRyxFQUFFO1lBQ0gsU0FBUyxDQUFDLElBQUksQ0FBQztnQkFDYixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsSUFBSTtnQkFDM0IsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJO2dCQUNyQixVQUFVLEVBQUUsR0FBRztnQkFDZixLQUFLLEVBQUUsU0FBUzthQUNqQixDQUFDLENBQUM7WUFDSCxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDdkIsQ0FBQyxDQUNGLENBQUM7UUFFRixPQUFPLFNBQVMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNILEtBQUssQ0FBQyxlQUFlLENBQ25CLElBQVksRUFDWixJQUFpQixFQUNqQixRQUEwQjtRQUUxQixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQzFDLFFBQVEsRUFBRSxLQUFLLElBQUksRUFBRTtvQkFDbkIsSUFBSSxDQUFDO3dCQUNILE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO3dCQUMzQyxNQUFNLFdBQVcsR0FBRyxNQUFNLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQzt3QkFDckQsTUFBTSxjQUFjLEdBQUcsTUFBTSxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7d0JBRXJELE9BQU8sQ0FBQzs0QkFDTixXQUFXOzRCQUNYLFFBQVEsRUFBRSxjQUFjLENBQUMsUUFBUTs0QkFDakMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxJQUFJOzRCQUN6QixJQUFJLEVBQUUsY0FBYyxDQUFDLElBQUk7NEJBQ3pCLFdBQVcsRUFBRSxjQUFjLENBQUMsV0FBVyxJQUFJLDBCQUEwQjs0QkFDckUsUUFBUSxFQUFFLGNBQWMsQ0FBQyxjQUFjLElBQUksRUFBRTt5QkFDOUMsQ0FBQyxDQUFDO29CQUNMLENBQUM7b0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzt3QkFDZixNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO29CQUN0QyxDQUFDO2dCQUNILENBQUM7Z0JBQ0QsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO2FBQ2hDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQixDQUNyQixJQUFZLEVBQ1osT0FBZSxFQUNmLFFBQTBCO1FBRTFCLHNDQUFzQztRQUN0QyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0IsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTlCLDBCQUEwQjtRQUMxQixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDeEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDL0MsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLElBQUksVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUUxRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRTtZQUN0QyxXQUFXO1lBQ1gsR0FBRyxRQUFRO1NBQ1osQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELDhFQUE4RTtJQUM5RSxXQUFXO0lBQ1gsOEVBQThFO0lBRTlFOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFZO1FBQy9CLElBQUksQ0FBQztZQUNILE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzNDLE9BQU8sTUFBTSxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFZO1FBQzVCLElBQUksQ0FBQztZQUNILE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzNDLE1BQU0sUUFBUSxHQUFHLE1BQU0sV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQy9DLE9BQU87Z0JBQ0wsV0FBVyxFQUFFLFFBQVEsQ0FBQyxXQUFXO2dCQUNqQyxjQUFjLEVBQUUsUUFBUSxDQUFDLGNBQWM7Z0JBQ3ZDLFlBQVksRUFBRSxRQUFRLENBQUMsWUFBWTtnQkFDbkMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJO2dCQUNuQixJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUk7YUFDcEIsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDL0MsQ0FBQztJQUNILENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsU0FBUztJQUNULDhFQUE4RTtJQUU5RTs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsTUFBTSxDQUFDLElBQVk7UUFDdkIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDM0MsTUFBTSxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBZTtRQUNsQyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELDhFQUE4RTtJQUM5RSxPQUFPO0lBQ1AsOEVBQThFO0lBRTlFOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFZO1FBQ3JCLElBQUksQ0FBQztZQUNILE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzNDLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRXpDLE9BQU87Z0JBQ0wsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUNoRCxhQUFhLEVBQUUsU0FBUyxFQUFFLGdDQUFnQzthQUMzRCxDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDO0lBQ0gsQ0FBQztJQUVELDhFQUE4RTtJQUM5RSxhQUFhO0lBQ2IsOEVBQThFO0lBRTlFOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILGdCQUFnQixDQUFDLFlBQW9CLEVBQUUsTUFBZTtRQUNwRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDN0IsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUVuRSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsT0FBTyxHQUFHLE1BQU0sSUFBSSxTQUFTLElBQUksYUFBYSxFQUFFLENBQUM7UUFDbkQsQ0FBQztRQUNELE9BQU8sR0FBRyxTQUFTLElBQUksYUFBYSxFQUFFLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxZQUFZLENBQUMsU0FBaUIsRUFBRSxZQUFvQixFQUFFLE1BQWU7UUFDbkUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM3RCxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLGtCQUFrQjtRQUNsRSxPQUFPLEdBQUcsUUFBUSxJQUFJLFFBQVEsRUFBRSxDQUFDO0lBQ25DLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFlBQVksQ0FBQyxRQUFnQjtRQUMzQixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xDLE9BQU8sS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQzVELENBQUM7SUFFRDs7T0FFRztJQUNILE9BQU8sQ0FBQyxRQUFnQjtRQUN0QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUVEOztPQUVHO0lBQ0gsVUFBVSxDQUFDLFFBQWdCO1FBQ3pCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEMsT0FBTyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVELDhFQUE4RTtJQUM5RSxtQkFBbUI7SUFDbkIsOEVBQThFO0lBRTlFOztPQUVHO0lBQ0ssWUFBWSxDQUFDLEtBQWE7UUFDaEMsUUFBUSxLQUFLLEVBQUUsQ0FBQztZQUNkLEtBQUssU0FBUztnQkFDWixPQUFPLFNBQVMsQ0FBQztZQUNuQixLQUFLLFFBQVE7Z0JBQ1gsT0FBTyxRQUFRLENBQUM7WUFDbEIsS0FBSyxTQUFTO2dCQUNaLE9BQU8sU0FBUyxDQUFDO1lBQ25CLEtBQUssVUFBVTtnQkFDYixPQUFPLFVBQVUsQ0FBQztZQUNwQixLQUFLLE9BQU87Z0JBQ1YsT0FBTyxPQUFPLENBQUM7WUFDakI7Z0JBQ0UsT0FBTyxTQUFTLENBQUM7UUFDckIsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLGVBQWUsQ0FBQyxLQUFjO1FBQ3BDLElBQUksS0FBSyxZQUFZLEtBQUssRUFBRSxDQUFDO1lBQzNCLE1BQU0sSUFBSSxHQUFJLEtBQTJCLENBQUMsSUFBSSxDQUFDO1lBRS9DLFFBQVEsSUFBSSxFQUFFLENBQUM7Z0JBQ2IsS0FBSywwQkFBMEI7b0JBQzdCLE9BQU8sc0JBQXNCLENBQUM7Z0JBQ2hDLEtBQUssc0JBQXNCO29CQUN6QixPQUFPLCtDQUErQyxDQUFDO2dCQUN6RCxLQUFLLGtCQUFrQjtvQkFDckIsT0FBTyw0QkFBNEIsQ0FBQztnQkFDdEMsS0FBSyx3QkFBd0I7b0JBQzNCLE9BQU8sMkNBQTJDLENBQUM7Z0JBQ3JELEtBQUssMEJBQTBCO29CQUM3QixPQUFPLDBCQUEwQixDQUFDO2dCQUNwQyxLQUFLLDhCQUE4QjtvQkFDakMsT0FBTyxxQ0FBcUMsQ0FBQztnQkFDL0MsS0FBSyxxQkFBcUI7b0JBQ3hCLE9BQU8seUJBQXlCLENBQUM7Z0JBQ25DLEtBQUssMEJBQTBCO29CQUM3QixPQUFPLG9CQUFvQixDQUFDO2dCQUM5QjtvQkFDRSxPQUFPLEtBQUssQ0FBQyxPQUFPLElBQUkscUNBQXFDLENBQUM7WUFDbEUsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLHFDQUFxQyxDQUFDO0lBQy9DLENBQUM7K0dBNVpVLGNBQWM7bUhBQWQsY0FBYyxjQURELE1BQU07OzRGQUNuQixjQUFjO2tCQUQxQixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU3RvcmFnZSBTZXJ2aWNlXG4gKlxuICogU2VydmljaW8gcGFyYSBvcGVyYWNpb25lcyBkZSBGaXJlYmFzZSBTdG9yYWdlLlxuICogU29wb3J0YSB1cGxvYWQgY29uIHRyYWNraW5nIGRlIHByb2dyZXNvLCBkb3dubG9hZCB5IGdlc3Rpw7NuIGRlIGFyY2hpdm9zLlxuICovXG5cbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIGRlbGV0ZU9iamVjdCxcbiAgZ2V0RG93bmxvYWRVUkwsXG4gIGdldE1ldGFkYXRhLFxuICBsaXN0QWxsLFxuICByZWYsXG4gIFN0b3JhZ2UsXG4gIHVwbG9hZEJ5dGVzUmVzdW1hYmxlLFxuICBVcGxvYWRNZXRhZGF0YSxcbiAgVXBsb2FkVGFza1NuYXBzaG90LFxufSBmcm9tICdAYW5ndWxhci9maXJlL3N0b3JhZ2UnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFN0b3JhZ2VMaXN0UmVzdWx0LCBTdG9yYWdlTWV0YWRhdGEsIFVwbG9hZFByb2dyZXNzLCBVcGxvYWRSZXN1bHQsIFVwbG9hZFN0YXRlIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogU2VydmljaW8gcGFyYSBGaXJlYmFzZSBTdG9yYWdlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBAQ29tcG9uZW50KHsuLi59KVxuICogZXhwb3J0IGNsYXNzIEZpbGVVcGxvYWRDb21wb25lbnQge1xuICogICBwcml2YXRlIHN0b3JhZ2UgPSBpbmplY3QoU3RvcmFnZVNlcnZpY2UpO1xuICpcbiAqICAgdXBsb2FkUHJvZ3Jlc3MgPSBzaWduYWw8bnVtYmVyPigwKTtcbiAqICAgZG93bmxvYWRVcmwgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gKlxuICogICBhc3luYyBvbkZpbGVTZWxlY3RlZChldmVudDogRXZlbnQpIHtcbiAqICAgICBjb25zdCBmaWxlID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS5maWxlcz8uWzBdO1xuICogICAgIGlmICghZmlsZSkgcmV0dXJuO1xuICpcbiAqICAgICAvLyBVcGxvYWQgY29uIHByb2dyZXNvXG4gKiAgICAgdGhpcy5zdG9yYWdlLnVwbG9hZChgdXBsb2Fkcy8ke2ZpbGUubmFtZX1gLCBmaWxlKS5zdWJzY3JpYmUoe1xuICogICAgICAgbmV4dDogKHByb2dyZXNzKSA9PiB0aGlzLnVwbG9hZFByb2dyZXNzLnNldChwcm9ncmVzcy5wZXJjZW50YWdlKSxcbiAqICAgICAgIGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG4gKiAgICAgICAgIGNvbnN0IHVybCA9IGF3YWl0IHRoaXMuc3RvcmFnZS5nZXREb3dubG9hZFVybChgdXBsb2Fkcy8ke2ZpbGUubmFtZX1gKTtcbiAqICAgICAgICAgdGhpcy5kb3dubG9hZFVybC5zZXQodXJsKTtcbiAqICAgICAgIH1cbiAqICAgICB9KTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgU3RvcmFnZVNlcnZpY2Uge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0b3JhZ2U6IFN0b3JhZ2UpIHt9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFVQTE9BRFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogU3ViZSB1biBhcmNoaXZvIGNvbiB0cmFja2luZyBkZSBwcm9ncmVzby5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBSdXRhIGVuIFN0b3JhZ2UgZG9uZGUgZ3VhcmRhciBlbCBhcmNoaXZvXG4gICAqIEBwYXJhbSBmaWxlIC0gQXJjaGl2byBhIHN1YmlyIChGaWxlIG8gQmxvYilcbiAgICogQHBhcmFtIG1ldGFkYXRhIC0gTWV0YWRhdGEgb3BjaW9uYWwgKGNvbnRlbnRUeXBlLCBjdXN0b21NZXRhZGF0YSlcbiAgICogQHJldHVybnMgT2JzZXJ2YWJsZSBxdWUgZW1pdGUgZWwgcHJvZ3Jlc28geSBjb21wbGV0YSBjdWFuZG8gdGVybWluYVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIC8vIFVwbG9hZCBiw6FzaWNvXG4gICAqIHN0b3JhZ2UudXBsb2FkKCdpbWFnZXMvcGhvdG8uanBnJywgZmlsZSkuc3Vic2NyaWJlKHtcbiAgICogICBuZXh0OiAocHJvZ3Jlc3MpID0+IGNvbnNvbGUubG9nKGAke3Byb2dyZXNzLnBlcmNlbnRhZ2V9JWApLFxuICAgKiAgIGNvbXBsZXRlOiAoKSA9PiBjb25zb2xlLmxvZygnVXBsb2FkIGNvbXBsZXRhZG8nKVxuICAgKiB9KTtcbiAgICpcbiAgICogLy8gQ29uIG1ldGFkYXRhXG4gICAqIHN0b3JhZ2UudXBsb2FkKCdkb2NzL3JlcG9ydC5wZGYnLCBmaWxlLCB7XG4gICAqICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9wZGYnLFxuICAgKiAgIGN1c3RvbU1ldGFkYXRhOiB7IHVwbG9hZGVkQnk6ICd1c2VyMTIzJyB9XG4gICAqIH0pLnN1YnNjcmliZSguLi4pO1xuICAgKiBgYGBcbiAgICovXG4gIHVwbG9hZChwYXRoOiBzdHJpbmcsIGZpbGU6IEZpbGUgfCBCbG9iLCBtZXRhZGF0YT86IFN0b3JhZ2VNZXRhZGF0YSk6IE9ic2VydmFibGU8VXBsb2FkUHJvZ3Jlc3M+IHtcbiAgICBjb25zdCBzdG9yYWdlUmVmID0gcmVmKHRoaXMuc3RvcmFnZSwgcGF0aCk7XG4gICAgY29uc3QgdXBsb2FkTWV0YWRhdGE6IFVwbG9hZE1ldGFkYXRhID0ge1xuICAgICAgY29udGVudFR5cGU6IG1ldGFkYXRhPy5jb250ZW50VHlwZSB8fCAoZmlsZSBpbnN0YW5jZW9mIEZpbGUgPyBmaWxlLnR5cGUgOiB1bmRlZmluZWQpLFxuICAgICAgY3VzdG9tTWV0YWRhdGE6IG1ldGFkYXRhPy5jdXN0b21NZXRhZGF0YSxcbiAgICAgIGNhY2hlQ29udHJvbDogbWV0YWRhdGE/LmNhY2hlQ29udHJvbCxcbiAgICB9O1xuXG4gICAgY29uc3QgdGFzayA9IHVwbG9hZEJ5dGVzUmVzdW1hYmxlKHN0b3JhZ2VSZWYsIGZpbGUsIHVwbG9hZE1ldGFkYXRhKTtcbiAgICBjb25zdCBwcm9ncmVzcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFVwbG9hZFByb2dyZXNzPih7XG4gICAgICBieXRlc1RyYW5zZmVycmVkOiAwLFxuICAgICAgdG90YWxCeXRlczogZmlsZS5zaXplLFxuICAgICAgcGVyY2VudGFnZTogMCxcbiAgICAgIHN0YXRlOiAncnVubmluZycsXG4gICAgfSk7XG5cbiAgICB0YXNrLm9uKFxuICAgICAgJ3N0YXRlX2NoYW5nZWQnLFxuICAgICAgKHNuYXBzaG90OiBVcGxvYWRUYXNrU25hcHNob3QpID0+IHtcbiAgICAgICAgcHJvZ3Jlc3MkLm5leHQoe1xuICAgICAgICAgIGJ5dGVzVHJhbnNmZXJyZWQ6IHNuYXBzaG90LmJ5dGVzVHJhbnNmZXJyZWQsXG4gICAgICAgICAgdG90YWxCeXRlczogc25hcHNob3QudG90YWxCeXRlcyxcbiAgICAgICAgICBwZXJjZW50YWdlOiBNYXRoLnJvdW5kKChzbmFwc2hvdC5ieXRlc1RyYW5zZmVycmVkIC8gc25hcHNob3QudG90YWxCeXRlcykgKiAxMDApLFxuICAgICAgICAgIHN0YXRlOiB0aGlzLm1hcFRhc2tTdGF0ZShzbmFwc2hvdC5zdGF0ZSksXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBwcm9ncmVzcyQubmV4dCh7XG4gICAgICAgICAgYnl0ZXNUcmFuc2ZlcnJlZDogMCxcbiAgICAgICAgICB0b3RhbEJ5dGVzOiBmaWxlLnNpemUsXG4gICAgICAgICAgcGVyY2VudGFnZTogMCxcbiAgICAgICAgICBzdGF0ZTogJ2Vycm9yJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHByb2dyZXNzJC5lcnJvcih0aGlzLmdldEVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgICAgfSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgcHJvZ3Jlc3MkLm5leHQoe1xuICAgICAgICAgIGJ5dGVzVHJhbnNmZXJyZWQ6IGZpbGUuc2l6ZSxcbiAgICAgICAgICB0b3RhbEJ5dGVzOiBmaWxlLnNpemUsXG4gICAgICAgICAgcGVyY2VudGFnZTogMTAwLFxuICAgICAgICAgIHN0YXRlOiAnc3VjY2VzcycsXG4gICAgICAgIH0pO1xuICAgICAgICBwcm9ncmVzcyQuY29tcGxldGUoKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgcmV0dXJuIHByb2dyZXNzJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJlIHVuIGFyY2hpdm8geSByZXRvcm5hIGxhIFVSTCBkZSBkZXNjYXJnYSBhbCBjb21wbGV0YXIuXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIC0gUnV0YSBlbiBTdG9yYWdlXG4gICAqIEBwYXJhbSBmaWxlIC0gQXJjaGl2byBhIHN1YmlyXG4gICAqIEBwYXJhbSBtZXRhZGF0YSAtIE1ldGFkYXRhIG9wY2lvbmFsXG4gICAqIEByZXR1cm5zIFJlc3VsdGFkbyBkZWwgdXBsb2FkIGNvbiBVUkwgZGUgZGVzY2FyZ2FcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLnVwbG9hZEFuZEdldFVybCgnYXZhdGFycy91c2VyMTIzLmpwZycsIGZpbGUpO1xuICAgKiBjb25zb2xlLmxvZygnVVJMOicsIHJlc3VsdC5kb3dubG9hZFVybCk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgdXBsb2FkQW5kR2V0VXJsKFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBmaWxlOiBGaWxlIHwgQmxvYixcbiAgICBtZXRhZGF0YT86IFN0b3JhZ2VNZXRhZGF0YVxuICApOiBQcm9taXNlPFVwbG9hZFJlc3VsdD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnVwbG9hZChwYXRoLCBmaWxlLCBtZXRhZGF0YSkuc3Vic2NyaWJlKHtcbiAgICAgICAgY29tcGxldGU6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc3RvcmFnZVJlZiA9IHJlZih0aGlzLnN0b3JhZ2UsIHBhdGgpO1xuICAgICAgICAgICAgY29uc3QgZG93bmxvYWRVcmwgPSBhd2FpdCBnZXREb3dubG9hZFVSTChzdG9yYWdlUmVmKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlZE1ldGFkYXRhID0gYXdhaXQgZ2V0TWV0YWRhdGEoc3RvcmFnZVJlZik7XG5cbiAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICBkb3dubG9hZFVybCxcbiAgICAgICAgICAgICAgZnVsbFBhdGg6IHN0b3JlZE1ldGFkYXRhLmZ1bGxQYXRoLFxuICAgICAgICAgICAgICBuYW1lOiBzdG9yZWRNZXRhZGF0YS5uYW1lLFxuICAgICAgICAgICAgICBzaXplOiBzdG9yZWRNZXRhZGF0YS5zaXplLFxuICAgICAgICAgICAgICBjb250ZW50VHlwZTogc3RvcmVkTWV0YWRhdGEuY29udGVudFR5cGUgfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScsXG4gICAgICAgICAgICAgIG1ldGFkYXRhOiBzdG9yZWRNZXRhZGF0YS5jdXN0b21NZXRhZGF0YSB8fCB7fSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICByZWplY3QodGhpcy5nZXRFcnJvck1lc3NhZ2UoZXJyb3IpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHJlamVjdChlcnJvciksXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJlIHVuIGFyY2hpdm8gZGVzZGUgdW5hIERhdGEgVVJMIChiYXNlNjQpLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCAtIFJ1dGEgZW4gU3RvcmFnZVxuICAgKiBAcGFyYW0gZGF0YVVybCAtIERhdGEgVVJMIChlajogJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwuLi4nKVxuICAgKiBAcGFyYW0gbWV0YWRhdGEgLSBNZXRhZGF0YSBvcGNpb25hbFxuICAgKiBAcmV0dXJucyBSZXN1bHRhZG8gZGVsIHVwbG9hZFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIC8vIERlc2RlIGNhbnZhc1xuICAgKiBjb25zdCBkYXRhVXJsID0gY2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XG4gICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2UudXBsb2FkRnJvbURhdGFVcmwoJ2ltYWdlcy9kcmF3aW5nLnBuZycsIGRhdGFVcmwpO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIHVwbG9hZEZyb21EYXRhVXJsKFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBkYXRhVXJsOiBzdHJpbmcsXG4gICAgbWV0YWRhdGE/OiBTdG9yYWdlTWV0YWRhdGFcbiAgKTogUHJvbWlzZTxVcGxvYWRSZXN1bHQ+IHtcbiAgICAvLyBFeHRyYWVyIGNvbnRlbnQgdHlwZSB5IGRhdG9zIGJhc2U2NFxuICAgIGNvbnN0IG1hdGNoZXMgPSBkYXRhVXJsLm1hdGNoKC9eZGF0YTooW147XSspO2Jhc2U2NCwoLispJC8pO1xuICAgIGlmICghbWF0Y2hlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdEYXRhIFVSTCBpbnbDoWxpZGEnKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZW50VHlwZSA9IG1hdGNoZXNbMV07XG4gICAgY29uc3QgYmFzZTY0RGF0YSA9IG1hdGNoZXNbMl07XG5cbiAgICAvLyBDb252ZXJ0aXIgYmFzZTY0IGEgQmxvYlxuICAgIGNvbnN0IGJ5dGVDaGFyYWN0ZXJzID0gYXRvYihiYXNlNjREYXRhKTtcbiAgICBjb25zdCBieXRlTnVtYmVycyA9IG5ldyBBcnJheShieXRlQ2hhcmFjdGVycy5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZUNoYXJhY3RlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGJ5dGVOdW1iZXJzW2ldID0gYnl0ZUNoYXJhY3RlcnMuY2hhckNvZGVBdChpKTtcbiAgICB9XG4gICAgY29uc3QgYnl0ZUFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZU51bWJlcnMpO1xuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbYnl0ZUFycmF5XSwgeyB0eXBlOiBjb250ZW50VHlwZSB9KTtcblxuICAgIHJldHVybiB0aGlzLnVwbG9hZEFuZEdldFVybChwYXRoLCBibG9iLCB7XG4gICAgICBjb250ZW50VHlwZSxcbiAgICAgIC4uLm1ldGFkYXRhLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIERPV05MT0FEXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBPYnRpZW5lIGxhIFVSTCBkZSBkZXNjYXJnYSBkZSB1biBhcmNoaXZvLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCAtIFJ1dGEgZGVsIGFyY2hpdm8gZW4gU3RvcmFnZVxuICAgKiBAcmV0dXJucyBVUkwgZGUgZGVzY2FyZ2FcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCB1cmwgPSBhd2FpdCBzdG9yYWdlLmdldERvd25sb2FkVXJsKCdpbWFnZXMvcGhvdG8uanBnJyk7XG4gICAqIC8vIFVzYXIgZW4gPGltZyBbc3JjXT1cInVybFwiPlxuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGdldERvd25sb2FkVXJsKHBhdGg6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0b3JhZ2VSZWYgPSByZWYodGhpcy5zdG9yYWdlLCBwYXRoKTtcbiAgICAgIHJldHVybiBhd2FpdCBnZXREb3dubG9hZFVSTChzdG9yYWdlUmVmKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMuZ2V0RXJyb3JNZXNzYWdlKGVycm9yKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE9idGllbmUgbGEgbWV0YWRhdGEgZGUgdW4gYXJjaGl2by5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBSdXRhIGRlbCBhcmNoaXZvXG4gICAqIEByZXR1cm5zIE1ldGFkYXRhIGRlbCBhcmNoaXZvXG4gICAqL1xuICBhc3luYyBnZXRNZXRhZGF0YShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPFN0b3JhZ2VNZXRhZGF0YSAmIHsgc2l6ZTogbnVtYmVyOyBuYW1lOiBzdHJpbmcgfT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzdG9yYWdlUmVmID0gcmVmKHRoaXMuc3RvcmFnZSwgcGF0aCk7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGF3YWl0IGdldE1ldGFkYXRhKHN0b3JhZ2VSZWYpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudFR5cGU6IG1ldGFkYXRhLmNvbnRlbnRUeXBlLFxuICAgICAgICBjdXN0b21NZXRhZGF0YTogbWV0YWRhdGEuY3VzdG9tTWV0YWRhdGEsXG4gICAgICAgIGNhY2hlQ29udHJvbDogbWV0YWRhdGEuY2FjaGVDb250cm9sLFxuICAgICAgICBzaXplOiBtZXRhZGF0YS5zaXplLFxuICAgICAgICBuYW1lOiBtZXRhZGF0YS5uYW1lLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMuZ2V0RXJyb3JNZXNzYWdlKGVycm9yKSk7XG4gICAgfVxuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIERFTEVURVxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogRWxpbWluYSB1biBhcmNoaXZvLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCAtIFJ1dGEgZGVsIGFyY2hpdm8gYSBlbGltaW5hclxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGF3YWl0IHN0b3JhZ2UuZGVsZXRlKCdpbWFnZXMvb2xkLXBob3RvLmpwZycpO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGRlbGV0ZShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3RvcmFnZVJlZiA9IHJlZih0aGlzLnN0b3JhZ2UsIHBhdGgpO1xuICAgICAgYXdhaXQgZGVsZXRlT2JqZWN0KHN0b3JhZ2VSZWYpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5nZXRFcnJvck1lc3NhZ2UoZXJyb3IpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRWxpbWluYSBtw7psdGlwbGVzIGFyY2hpdm9zLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aHMgLSBBcnJheSBkZSBydXRhcyBhIGVsaW1pbmFyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogYXdhaXQgc3RvcmFnZS5kZWxldGVNdWx0aXBsZShbXG4gICAqICAgJ2ltYWdlcy9waG90bzEuanBnJyxcbiAgICogICAnaW1hZ2VzL3Bob3RvMi5qcGcnXG4gICAqIF0pO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGRlbGV0ZU11bHRpcGxlKHBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKHBhdGhzLm1hcCgocGF0aCkgPT4gdGhpcy5kZWxldGUocGF0aCkpKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBMSVNUXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBMaXN0YSBhcmNoaXZvcyBlbiB1biBkaXJlY3RvcmlvLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCAtIFJ1dGEgZGVsIGRpcmVjdG9yaW9cbiAgICogQHJldHVybnMgTGlzdGEgZGUgcnV0YXMgZGUgYXJjaGl2b3NcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLmxpc3QoJ2ltYWdlcy8nKTtcbiAgICogY29uc29sZS5sb2cocmVzdWx0Lml0ZW1zKTsgLy8gWydpbWFnZXMvcGhvdG8xLmpwZycsICdpbWFnZXMvcGhvdG8yLmpwZyddXG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgbGlzdChwYXRoOiBzdHJpbmcpOiBQcm9taXNlPFN0b3JhZ2VMaXN0UmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0b3JhZ2VSZWYgPSByZWYodGhpcy5zdG9yYWdlLCBwYXRoKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGxpc3RBbGwoc3RvcmFnZVJlZik7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGl0ZW1zOiByZXN1bHQuaXRlbXMubWFwKChpdGVtKSA9PiBpdGVtLmZ1bGxQYXRoKSxcbiAgICAgICAgbmV4dFBhZ2VUb2tlbjogdW5kZWZpbmVkLCAvLyBsaXN0QWxsIG5vIHNvcG9ydGEgcGFnaW5hY2nDs25cbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLmdldEVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgIH1cbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBVVElMSURBREVTXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBHZW5lcmEgdW4gbm9tYnJlIGRlIGFyY2hpdm8gw7puaWNvIGNvbiB0aW1lc3RhbXAuXG4gICAqXG4gICAqIEBwYXJhbSBvcmlnaW5hbE5hbWUgLSBOb21icmUgb3JpZ2luYWwgZGVsIGFyY2hpdm9cbiAgICogQHBhcmFtIHByZWZpeCAtIFByZWZpam8gb3BjaW9uYWxcbiAgICogQHJldHVybnMgTm9tYnJlIMO6bmljb1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHVuaXF1ZU5hbWUgPSBzdG9yYWdlLmdlbmVyYXRlRmlsZU5hbWUoJ3Bob3RvLmpwZycsICd1c2VyMTIzJyk7XG4gICAqIC8vID0+ICd1c2VyMTIzXzE3MDMwOTEyMzQ1NjdfcGhvdG8uanBnJ1xuICAgKiBgYGBcbiAgICovXG4gIGdlbmVyYXRlRmlsZU5hbWUob3JpZ2luYWxOYW1lOiBzdHJpbmcsIHByZWZpeD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBzYW5pdGl6ZWROYW1lID0gb3JpZ2luYWxOYW1lLnJlcGxhY2UoL1teYS16QS1aMC05Li1dL2csICdfJyk7XG5cbiAgICBpZiAocHJlZml4KSB7XG4gICAgICByZXR1cm4gYCR7cHJlZml4fV8ke3RpbWVzdGFtcH1fJHtzYW5pdGl6ZWROYW1lfWA7XG4gICAgfVxuICAgIHJldHVybiBgJHt0aW1lc3RhbXB9XyR7c2FuaXRpemVkTmFtZX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYSB1bmEgcnV0YSDDum5pY2EgcGFyYSB1biBhcmNoaXZvLlxuICAgKlxuICAgKiBAcGFyYW0gZGlyZWN0b3J5IC0gRGlyZWN0b3JpbyBiYXNlXG4gICAqIEBwYXJhbSBvcmlnaW5hbE5hbWUgLSBOb21icmUgb3JpZ2luYWxcbiAgICogQHBhcmFtIHByZWZpeCAtIFByZWZpam8gb3BjaW9uYWxcbiAgICogQHJldHVybnMgUnV0YSBjb21wbGV0YSDDum5pY2FcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBwYXRoID0gc3RvcmFnZS5nZW5lcmF0ZVBhdGgoJ3VwbG9hZHMnLCAncGhvdG8uanBnJywgJ3VzZXIxMjMnKTtcbiAgICogLy8gPT4gJ3VwbG9hZHMvdXNlcjEyM18xNzAzMDkxMjM0NTY3X3Bob3RvLmpwZydcbiAgICogYGBgXG4gICAqL1xuICBnZW5lcmF0ZVBhdGgoZGlyZWN0b3J5OiBzdHJpbmcsIG9yaWdpbmFsTmFtZTogc3RyaW5nLCBwcmVmaXg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGZpbGVOYW1lID0gdGhpcy5nZW5lcmF0ZUZpbGVOYW1lKG9yaWdpbmFsTmFtZSwgcHJlZml4KTtcbiAgICBjb25zdCBjbGVhbkRpciA9IGRpcmVjdG9yeS5yZXBsYWNlKC9cXC8rJC8sICcnKTsgLy8gUmVtb3ZlciAvIGZpbmFsXG4gICAgcmV0dXJuIGAke2NsZWFuRGlyfS8ke2ZpbGVOYW1lfWA7XG4gIH1cblxuICAvKipcbiAgICogT2J0aWVuZSBsYSBleHRlbnNpw7NuIGRlIHVuIGFyY2hpdm8uXG4gICAqXG4gICAqIEBwYXJhbSBmaWxlbmFtZSAtIE5vbWJyZSBkZWwgYXJjaGl2b1xuICAgKiBAcmV0dXJucyBFeHRlbnNpw7NuIChzaW4gZWwgcHVudG8pXG4gICAqL1xuICBnZXRFeHRlbnNpb24oZmlsZW5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgcGFydHMgPSBmaWxlbmFtZS5zcGxpdCgnLicpO1xuICAgIHJldHVybiBwYXJ0cy5sZW5ndGggPiAxID8gcGFydHMucG9wKCkhLnRvTG93ZXJDYXNlKCkgOiAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmljYSBzaSB1biBhcmNoaXZvIGVzIHVuYSBpbWFnZW4gYmFzw6FuZG9zZSBlbiBzdSBleHRlbnNpw7NuLlxuICAgKi9cbiAgaXNJbWFnZShmaWxlbmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZXh0ID0gdGhpcy5nZXRFeHRlbnNpb24oZmlsZW5hbWUpO1xuICAgIHJldHVybiBbJ2pwZycsICdqcGVnJywgJ3BuZycsICdnaWYnLCAnd2VicCcsICdzdmcnLCAnYm1wJ10uaW5jbHVkZXMoZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmljYSBzaSB1biBhcmNoaXZvIGVzIHVuIGRvY3VtZW50by5cbiAgICovXG4gIGlzRG9jdW1lbnQoZmlsZW5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGV4dCA9IHRoaXMuZ2V0RXh0ZW5zaW9uKGZpbGVuYW1lKTtcbiAgICByZXR1cm4gWydwZGYnLCAnZG9jJywgJ2RvY3gnLCAneGxzJywgJ3hsc3gnLCAncHB0JywgJ3BwdHgnLCAndHh0J10uaW5jbHVkZXMoZXh0KTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBNw4lUT0RPUyBQUklWQURPU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogTWFwZWEgZWwgZXN0YWRvIGRlIGxhIHRhcmVhIGRlIHVwbG9hZFxuICAgKi9cbiAgcHJpdmF0ZSBtYXBUYXNrU3RhdGUoc3RhdGU6IHN0cmluZyk6IFVwbG9hZFN0YXRlIHtcbiAgICBzd2l0Y2ggKHN0YXRlKSB7XG4gICAgICBjYXNlICdydW5uaW5nJzpcbiAgICAgICAgcmV0dXJuICdydW5uaW5nJztcbiAgICAgIGNhc2UgJ3BhdXNlZCc6XG4gICAgICAgIHJldHVybiAncGF1c2VkJztcbiAgICAgIGNhc2UgJ3N1Y2Nlc3MnOlxuICAgICAgICByZXR1cm4gJ3N1Y2Nlc3MnO1xuICAgICAgY2FzZSAnY2FuY2VsZWQnOlxuICAgICAgICByZXR1cm4gJ2NhbmNlbGVkJztcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuICdlcnJvcic7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gJ3J1bm5pbmcnO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252aWVydGUgZXJyb3JlcyBkZSBTdG9yYWdlIGEgbWVuc2FqZXMgZW4gZXNwYcOxb2xcbiAgICovXG4gIHByaXZhdGUgZ2V0RXJyb3JNZXNzYWdlKGVycm9yOiB1bmtub3duKTogc3RyaW5nIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc3QgY29kZSA9IChlcnJvciBhcyB7IGNvZGU/OiBzdHJpbmcgfSkuY29kZTtcblxuICAgICAgc3dpdGNoIChjb2RlKSB7XG4gICAgICAgIGNhc2UgJ3N0b3JhZ2Uvb2JqZWN0LW5vdC1mb3VuZCc6XG4gICAgICAgICAgcmV0dXJuICdFbCBhcmNoaXZvIG5vIGV4aXN0ZSc7XG4gICAgICAgIGNhc2UgJ3N0b3JhZ2UvdW5hdXRob3JpemVkJzpcbiAgICAgICAgICByZXR1cm4gJ05vIHRpZW5lcyBwZXJtaXNvIHBhcmEgYWNjZWRlciBhIGVzdGUgYXJjaGl2byc7XG4gICAgICAgIGNhc2UgJ3N0b3JhZ2UvY2FuY2VsZWQnOlxuICAgICAgICAgIHJldHVybiAnTGEgb3BlcmFjacOzbiBmdWUgY2FuY2VsYWRhJztcbiAgICAgICAgY2FzZSAnc3RvcmFnZS9xdW90YS1leGNlZWRlZCc6XG4gICAgICAgICAgcmV0dXJuICdTZSBoYSBleGNlZGlkbyBsYSBjdW90YSBkZSBhbG1hY2VuYW1pZW50byc7XG4gICAgICAgIGNhc2UgJ3N0b3JhZ2UvaW52YWxpZC1jaGVja3N1bSc6XG4gICAgICAgICAgcmV0dXJuICdFbCBhcmNoaXZvIGVzdMOhIGNvcnJ1cHRvJztcbiAgICAgICAgY2FzZSAnc3RvcmFnZS9yZXRyeS1saW1pdC1leGNlZWRlZCc6XG4gICAgICAgICAgcmV0dXJuICdFcnJvciBkZSBjb25leGnDs24uIEludGVudGEgZGUgbnVldm8nO1xuICAgICAgICBjYXNlICdzdG9yYWdlL2ludmFsaWQtdXJsJzpcbiAgICAgICAgICByZXR1cm4gJ1VSTCBkZSBhcmNoaXZvIGludsOhbGlkYSc7XG4gICAgICAgIGNhc2UgJ3N0b3JhZ2UvaW52YWxpZC1hcmd1bWVudCc6XG4gICAgICAgICAgcmV0dXJuICdBcmd1bWVudG8gaW52w6FsaWRvJztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gZXJyb3IubWVzc2FnZSB8fCAnRXJyb3IgZGUgYWxtYWNlbmFtaWVudG8gZGVzY29ub2NpZG8nO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAnRXJyb3IgZGUgYWxtYWNlbmFtaWVudG8gZGVzY29ub2NpZG8nO1xuICB9XG59XG4iXX0=