UNPKG

@acontplus/ng-auth

Version:

Comprehensive Angular authentication module with JWT token management, route guards, CSRF protection, URL redirection, session handling, and clean architecture patterns. Includes login components, auth interceptors, and DDD-based repositories.

1 lines 196 kB
{"version":3,"file":"acontplus-ng-auth.mjs","sources":["../tmp-esm2022/lib/domain/repositories/auth-repository.js","../tmp-esm2022/lib/repositories/auth-token-repository-impl.js","../tmp-esm2022/lib/ui/stores/auth-store.js","../tmp-esm2022/lib/services/auth-url-redirect.js","../tmp-esm2022/lib/application/use-cases/login-use-case.js","../tmp-esm2022/lib/application/use-cases/register-use-case.js","../tmp-esm2022/lib/application/use-cases/refresh-token-use-case.js","../tmp-esm2022/lib/application/use-cases/logout-use-case.js","../tmp-esm2022/lib/application/use-cases/index.js","../tmp-esm2022/lib/application/index.js","../tmp-esm2022/lib/data/repositories/auth-http-repository.js","../tmp-esm2022/lib/data/repositories/index.js","../tmp-esm2022/lib/data/index.js","../tmp-esm2022/lib/domain/models/auth.js","../tmp-esm2022/lib/domain/models/index.js","../tmp-esm2022/lib/domain/repositories/index.js","../tmp-esm2022/lib/guards/auth-guard.js","../tmp-esm2022/lib/interceptors/auth-redirect-interceptor.js","../tmp-esm2022/lib/services/csrf-api.js","../tmp-esm2022/lib/interceptors/csrf-interceptor.js","../tmp-esm2022/lib/providers/auth-providers.js","../tmp-esm2022/lib/providers/index.js","../tmp-esm2022/lib/ui/stores/index.js","../tmp-esm2022/lib/ui/login/login.js","../tmp-esm2022/lib/ui/login/index.js","../tmp-esm2022/lib/ui/index.js","../tmp-esm2022/acontplus-ng-auth.js"],"sourcesContent":["export class AuthRepository {\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1yZXBvc2l0b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbmctYXV0aC9zcmMvbGliL2RvbWFpbi9yZXBvc2l0b3JpZXMvYXV0aC1yZXBvc2l0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE1BQU0sT0FBZ0IsY0FBYztDQUtuQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNyYy9saWIvZG9tYWluL3JlcG9zaXRvcmllcy9hdXRoLmJhc2UtcmVwb3NpdG9yeS50c1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgTG9naW5SZXF1ZXN0LCBSZWdpc3RlclJlcXVlc3QsIFJlZnJlc2hUb2tlblJlcXVlc3QgfSBmcm9tICcuLi9tb2RlbHMvYXV0aCc7XG5pbXBvcnQgeyBBdXRoVG9rZW5zIH0gZnJvbSAnQGFjb250cGx1cy9jb3JlJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEF1dGhSZXBvc2l0b3J5IHtcbiAgYWJzdHJhY3QgbG9naW4ocmVxdWVzdDogTG9naW5SZXF1ZXN0KTogT2JzZXJ2YWJsZTxBdXRoVG9rZW5zPjtcbiAgYWJzdHJhY3QgcmVnaXN0ZXIocmVxdWVzdDogUmVnaXN0ZXJSZXF1ZXN0KTogT2JzZXJ2YWJsZTxBdXRoVG9rZW5zPjtcbiAgYWJzdHJhY3QgcmVmcmVzaFRva2VuKHJlcXVlc3Q6IFJlZnJlc2hUb2tlblJlcXVlc3QpOiBPYnNlcnZhYmxlPEF1dGhUb2tlbnM+O1xuICBhYnN0cmFjdCBsb2dvdXQoZW1haWw6IHN0cmluZywgcmVmcmVzaFRva2VuOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHZvaWQ+O1xufVxuIl19","import { Injectable, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { jwtDecode } from 'jwt-decode';\nimport { ENVIRONMENT } from '@acontplus/ng-config';\nimport * as i0 from \"@angular/core\";\nexport class AuthTokenRepositoryImpl {\n environment = inject(ENVIRONMENT);\n platformId = inject(PLATFORM_ID);\n saveTokens(tokens, rememberMe = false) {\n if (isPlatformBrowser(this.platformId)) {\n this.setToken(tokens.token, rememberMe);\n this.setRefreshToken(tokens.refreshToken, rememberMe);\n }\n }\n getToken() {\n if (!isPlatformBrowser(this.platformId)) {\n return null;\n }\n return (localStorage.getItem(this.environment.tokenKey) ||\n sessionStorage.getItem(this.environment.tokenKey));\n }\n getRefreshToken() {\n if (!isPlatformBrowser(this.platformId)) {\n return null;\n }\n return (localStorage.getItem(this.environment.refreshTokenKey) ||\n sessionStorage.getItem(this.environment.refreshTokenKey));\n }\n setToken(token, rememberMe = false) {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n if (rememberMe) {\n localStorage.setItem(this.environment.tokenKey, token);\n }\n else {\n sessionStorage.setItem(this.environment.tokenKey, token);\n }\n }\n setRefreshToken(refreshToken, rememberMe = false) {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n if (rememberMe) {\n localStorage.setItem(this.environment.refreshTokenKey, refreshToken);\n }\n else {\n sessionStorage.setItem(this.environment.refreshTokenKey, refreshToken);\n }\n }\n clearTokens() {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n localStorage.removeItem(this.environment.tokenKey);\n localStorage.removeItem(this.environment.refreshTokenKey);\n sessionStorage.removeItem(this.environment.tokenKey);\n sessionStorage.removeItem(this.environment.refreshTokenKey);\n }\n isAuthenticated() {\n const accessToken = this.getToken();\n if (!accessToken) {\n return false;\n }\n try {\n const decodedAccessToken = jwtDecode(accessToken);\n const accessExpiration = Number(decodedAccessToken.exp);\n const currentTimeUTC = Math.floor(Date.now() / 1000);\n return accessExpiration > currentTimeUTC;\n }\n catch {\n return false;\n }\n }\n needsRefresh() {\n const accessToken = this.getToken();\n if (!accessToken) {\n return false;\n }\n try {\n const decodedToken = jwtDecode(accessToken);\n const expiration = Number(decodedToken.exp);\n const currentTimeUTC = Math.floor(Date.now() / 1000);\n const timeUntilExpiry = expiration - currentTimeUTC;\n return timeUntilExpiry <= 300; // 5 minutes\n }\n catch {\n return false;\n }\n }\n getTokenPayload() {\n const token = this.getToken();\n if (!token)\n return null;\n try {\n return jwtDecode(token);\n }\n catch {\n return null;\n }\n }\n /**\n * Determines if tokens are stored persistently (localStorage) vs session (sessionStorage)\n */\n isRememberMeEnabled() {\n if (!isPlatformBrowser(this.platformId)) {\n return false;\n }\n // Check if tokens exist in localStorage (persistent storage)\n const tokenInLocalStorage = localStorage.getItem(this.environment.tokenKey);\n const refreshTokenInLocalStorage = localStorage.getItem(this.environment.refreshTokenKey);\n return !!(tokenInLocalStorage || refreshTokenInLocalStorage);\n }\n getUserData() {\n const token = this.getToken();\n if (!token) {\n return null;\n }\n try {\n const decodedToken = jwtDecode(token);\n const email = decodedToken['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'] ??\n decodedToken['email'] ??\n decodedToken['sub'] ??\n decodedToken['user_id'];\n const displayName = decodedToken['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'] ??\n decodedToken['displayName'] ??\n decodedToken['display_name'] ??\n decodedToken['name'] ??\n decodedToken['given_name'];\n const name = decodedToken['name'] ?? displayName;\n if (!email) {\n return null;\n }\n const userData = {\n email: email.toString(),\n displayName: displayName?.toString() ?? 'Unknown User',\n name: name?.toString(),\n roles: this.extractArrayField(decodedToken, ['roles', 'role']),\n permissions: this.extractArrayField(decodedToken, ['permissions', 'perms']),\n tenantId: decodedToken['tenantId']?.toString() ??\n decodedToken['tenant_id']?.toString() ??\n decodedToken['tenant']?.toString(),\n companyId: decodedToken['companyId']?.toString() ??\n decodedToken['company_id']?.toString() ??\n decodedToken['organizationId']?.toString() ??\n decodedToken['org_id']?.toString(),\n locale: decodedToken['locale']?.toString(),\n timezone: decodedToken['timezone']?.toString() ?? decodedToken['tz']?.toString(),\n };\n return userData;\n }\n catch {\n return null;\n }\n }\n /**\n * Extract array field from decoded token, trying multiple possible field names\n */\n extractArrayField(decodedToken, fieldNames) {\n for (const fieldName of fieldNames) {\n const value = decodedToken[fieldName];\n if (Array.isArray(value)) {\n return value.map(v => v.toString());\n }\n if (typeof value === 'string') {\n // Handle comma-separated string values\n return value\n .split(',')\n .map(v => v.trim())\n .filter(v => v.length > 0);\n }\n }\n return undefined;\n }\n static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"20.3.4\", ngImport: i0, type: AuthTokenRepositoryImpl, deps: [], target: i0.ɵɵFactoryTarget.Injectable });\n static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"20.3.4\", ngImport: i0, type: AuthTokenRepositoryImpl, providedIn: 'root' });\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"20.3.4\", ngImport: i0, type: AuthTokenRepositoryImpl, decorators: [{\n type: Injectable,\n args: [{\n providedIn: 'root',\n }]\n }] });\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC10b2tlbi1yZXBvc2l0b3J5LWltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9uZy1hdXRoL3NyYy9saWIvcmVwb3NpdG9yaWVzL2F1dGgtdG9rZW4tcmVwb3NpdG9yeS1pbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXZDLE9BQU8sRUFBdUIsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7O0FBS3hFLE1BQU0sT0FBTyx1QkFBdUI7SUFDMUIsV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNsQyxVQUFVLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBRXpDLFVBQVUsQ0FBQyxNQUFrQixFQUFFLFVBQVUsR0FBRyxLQUFLO1FBQy9DLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxVQUFVLENBQUMsQ0FBQztRQUN4RCxDQUFDO0lBQ0gsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsT0FBTyxDQUNMLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUM7WUFDL0MsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUNsRCxDQUFDO0lBQ0osQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsT0FBTyxDQUNMLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUM7WUFDdEQsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUN6RCxDQUFDO0lBQ0osQ0FBQztJQUVELFFBQVEsQ0FBQyxLQUFhLEVBQUUsVUFBVSxHQUFHLEtBQUs7UUFDeEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekQsQ0FBQzthQUFNLENBQUM7WUFDTixjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzNELENBQUM7SUFDSCxDQUFDO0lBRUQsZUFBZSxDQUFDLFlBQW9CLEVBQUUsVUFBVSxHQUFHLEtBQUs7UUFDdEQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDdkUsQ0FBQzthQUFNLENBQUM7WUFDTixjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ3pFLENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUN4QyxPQUFPO1FBQ1QsQ0FBQztRQUNELFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRCxZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDMUQsY0FBYyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JELGNBQWMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsZUFBZTtRQUNiLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUVwQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxrQkFBa0IsR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDbEQsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFFckQsT0FBTyxnQkFBZ0IsR0FBRyxjQUFjLENBQUM7UUFDM0MsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFRCxZQUFZO1FBQ1YsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDNUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNyRCxNQUFNLGVBQWUsR0FBRyxVQUFVLEdBQUcsY0FBYyxDQUFDO1lBRXBELE9BQU8sZUFBZSxJQUFJLEdBQUcsQ0FBQyxDQUFDLFlBQVk7UUFDN0MsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFRCxlQUFlO1FBQ2IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFeEIsSUFBSSxDQUFDO1lBQ0gsT0FBTyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILG1CQUFtQjtRQUNqQixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsNkRBQTZEO1FBQzdELE1BQU0sbUJBQW1CLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVFLE1BQU0sMEJBQTBCLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRTFGLE9BQU8sQ0FBQyxDQUFDLENBQUMsbUJBQW1CLElBQUksMEJBQTBCLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQsV0FBVztRQUNULE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCxNQUFNLFlBQVksR0FBRyxTQUFTLENBQTBCLEtBQUssQ0FBQyxDQUFDO1lBRS9ELE1BQU0sS0FBSyxHQUNULFlBQVksQ0FBQyxvRUFBb0UsQ0FBQztnQkFDbEYsWUFBWSxDQUFDLE9BQU8sQ0FBQztnQkFDckIsWUFBWSxDQUFDLEtBQUssQ0FBQztnQkFDbkIsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRTFCLE1BQU0sV0FBVyxHQUNmLFlBQVksQ0FBQyxpRUFBaUUsQ0FBQztnQkFDL0UsWUFBWSxDQUFDLGFBQWEsQ0FBQztnQkFDM0IsWUFBWSxDQUFDLGNBQWMsQ0FBQztnQkFDNUIsWUFBWSxDQUFDLE1BQU0sQ0FBQztnQkFDcEIsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTdCLE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxXQUFXLENBQUM7WUFFakQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztZQUVELE1BQU0sUUFBUSxHQUFhO2dCQUN6QixLQUFLLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRTtnQkFDdkIsV0FBVyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxjQUFjO2dCQUN0RCxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtnQkFDdEIsS0FBSyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzlELFdBQVcsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUMzRSxRQUFRLEVBQ04sWUFBWSxDQUFDLFVBQVUsQ0FBQyxFQUFFLFFBQVEsRUFBRTtvQkFDcEMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFLFFBQVEsRUFBRTtvQkFDckMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsRUFBRTtnQkFDcEMsU0FBUyxFQUNQLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFBRSxRQUFRLEVBQUU7b0JBQ3JDLFlBQVksQ0FBQyxZQUFZLENBQUMsRUFBRSxRQUFRLEVBQUU7b0JBQ3RDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLFFBQVEsRUFBRTtvQkFDMUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsRUFBRTtnQkFDcEMsTUFBTSxFQUFFLFlBQVksQ0FBQyxRQUFRLENBQUMsRUFBRSxRQUFRLEVBQUU7Z0JBQzFDLFFBQVEsRUFBRSxZQUFZLENBQUMsVUFBVSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRTthQUNqRixDQUFDO1lBRUYsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLGlCQUFpQixDQUN2QixZQUFxQyxFQUNyQyxVQUFvQjtRQUVwQixLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ25DLE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN0QyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDekIsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDdEMsQ0FBQztZQUNELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQzlCLHVDQUF1QztnQkFDdkMsT0FBTyxLQUFLO3FCQUNULEtBQUssQ0FBQyxHQUFHLENBQUM7cUJBQ1YsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO3FCQUNsQixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQy9CLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQzt1R0F2TVUsdUJBQXVCOzJHQUF2Qix1QkFBdUIsY0FGdEIsTUFBTTs7MkZBRVAsdUJBQXVCO2tCQUhuQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCwgUExBVEZPUk1fSUQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGp3dERlY29kZSB9IGZyb20gJ2p3dC1kZWNvZGUnO1xuaW1wb3J0IHsgQXV0aFRva2VucywgVXNlckRhdGEgfSBmcm9tICdAYWNvbnRwbHVzL2NvcmUnO1xuaW1wb3J0IHsgQXV0aFRva2VuUmVwb3NpdG9yeSwgRU5WSVJPTk1FTlQgfSBmcm9tICdAYWNvbnRwbHVzL25nLWNvbmZpZyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBBdXRoVG9rZW5SZXBvc2l0b3J5SW1wbCBpbXBsZW1lbnRzIEF1dGhUb2tlblJlcG9zaXRvcnkge1xuICBwcml2YXRlIGVudmlyb25tZW50ID0gaW5qZWN0KEVOVklST05NRU5UKTtcbiAgcHJpdmF0ZSBwbGF0Zm9ybUlkID0gaW5qZWN0KFBMQVRGT1JNX0lEKTtcblxuICBzYXZlVG9rZW5zKHRva2VuczogQXV0aFRva2VucywgcmVtZW1iZXJNZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHRoaXMuc2V0VG9rZW4odG9rZW5zLnRva2VuLCByZW1lbWJlck1lKTtcbiAgICAgIHRoaXMuc2V0UmVmcmVzaFRva2VuKHRva2Vucy5yZWZyZXNoVG9rZW4sIHJlbWVtYmVyTWUpO1xuICAgIH1cbiAgfVxuXG4gIGdldFRva2VuKCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiAoXG4gICAgICBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmVudmlyb25tZW50LnRva2VuS2V5KSB8fFxuICAgICAgc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmVudmlyb25tZW50LnRva2VuS2V5KVxuICAgICk7XG4gIH1cblxuICBnZXRSZWZyZXNoVG9rZW4oKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMuZW52aXJvbm1lbnQucmVmcmVzaFRva2VuS2V5KSB8fFxuICAgICAgc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmVudmlyb25tZW50LnJlZnJlc2hUb2tlbktleSlcbiAgICApO1xuICB9XG5cbiAgc2V0VG9rZW4odG9rZW46IHN0cmluZywgcmVtZW1iZXJNZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyZW1lbWJlck1lKSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLmVudmlyb25tZW50LnRva2VuS2V5LCB0b2tlbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0odGhpcy5lbnZpcm9ubWVudC50b2tlbktleSwgdG9rZW4pO1xuICAgIH1cbiAgfVxuXG4gIHNldFJlZnJlc2hUb2tlbihyZWZyZXNoVG9rZW46IHN0cmluZywgcmVtZW1iZXJNZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKCFpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyZW1lbWJlck1lKSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLmVudmlyb25tZW50LnJlZnJlc2hUb2tlbktleSwgcmVmcmVzaFRva2VuKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSh0aGlzLmVudmlyb25tZW50LnJlZnJlc2hUb2tlbktleSwgcmVmcmVzaFRva2VuKTtcbiAgICB9XG4gIH1cblxuICBjbGVhclRva2VucygpOiB2b2lkIHtcbiAgICBpZiAoIWlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5lbnZpcm9ubWVudC50b2tlbktleSk7XG4gICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5lbnZpcm9ubWVudC5yZWZyZXNoVG9rZW5LZXkpO1xuICAgIHNlc3Npb25TdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5lbnZpcm9ubWVudC50b2tlbktleSk7XG4gICAgc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbSh0aGlzLmVudmlyb25tZW50LnJlZnJlc2hUb2tlbktleSk7XG4gIH1cblxuICBpc0F1dGhlbnRpY2F0ZWQoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWNjZXNzVG9rZW4gPSB0aGlzLmdldFRva2VuKCk7XG5cbiAgICBpZiAoIWFjY2Vzc1Rva2VuKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRlY29kZWRBY2Nlc3NUb2tlbiA9IGp3dERlY29kZShhY2Nlc3NUb2tlbik7XG4gICAgICBjb25zdCBhY2Nlc3NFeHBpcmF0aW9uID0gTnVtYmVyKGRlY29kZWRBY2Nlc3NUb2tlbi5leHApO1xuICAgICAgY29uc3QgY3VycmVudFRpbWVVVEMgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcblxuICAgICAgcmV0dXJuIGFjY2Vzc0V4cGlyYXRpb24gPiBjdXJyZW50VGltZVVUQztcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBuZWVkc1JlZnJlc2goKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWNjZXNzVG9rZW4gPSB0aGlzLmdldFRva2VuKCk7XG4gICAgaWYgKCFhY2Nlc3NUb2tlbikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkVG9rZW4gPSBqd3REZWNvZGUoYWNjZXNzVG9rZW4pO1xuICAgICAgY29uc3QgZXhwaXJhdGlvbiA9IE51bWJlcihkZWNvZGVkVG9rZW4uZXhwKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRUaW1lVVRDID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG4gICAgICBjb25zdCB0aW1lVW50aWxFeHBpcnkgPSBleHBpcmF0aW9uIC0gY3VycmVudFRpbWVVVEM7XG5cbiAgICAgIHJldHVybiB0aW1lVW50aWxFeHBpcnkgPD0gMzAwOyAvLyA1IG1pbnV0ZXNcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBnZXRUb2tlblBheWxvYWQoKTogdW5rbm93biB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLmdldFRva2VuKCk7XG4gICAgaWYgKCF0b2tlbikgcmV0dXJuIG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGp3dERlY29kZSh0b2tlbik7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiB0b2tlbnMgYXJlIHN0b3JlZCBwZXJzaXN0ZW50bHkgKGxvY2FsU3RvcmFnZSkgdnMgc2Vzc2lvbiAoc2Vzc2lvblN0b3JhZ2UpXG4gICAqL1xuICBpc1JlbWVtYmVyTWVFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHRva2VucyBleGlzdCBpbiBsb2NhbFN0b3JhZ2UgKHBlcnNpc3RlbnQgc3RvcmFnZSlcbiAgICBjb25zdCB0b2tlbkluTG9jYWxTdG9yYWdlID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5lbnZpcm9ubWVudC50b2tlbktleSk7XG4gICAgY29uc3QgcmVmcmVzaFRva2VuSW5Mb2NhbFN0b3JhZ2UgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmVudmlyb25tZW50LnJlZnJlc2hUb2tlbktleSk7XG5cbiAgICByZXR1cm4gISEodG9rZW5JbkxvY2FsU3RvcmFnZSB8fCByZWZyZXNoVG9rZW5JbkxvY2FsU3RvcmFnZSk7XG4gIH1cblxuICBnZXRVc2VyRGF0YSgpOiBVc2VyRGF0YSB8IG51bGwge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy5nZXRUb2tlbigpO1xuICAgIGlmICghdG9rZW4pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkVG9rZW4gPSBqd3REZWNvZGU8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHRva2VuKTtcblxuICAgICAgY29uc3QgZW1haWwgPVxuICAgICAgICBkZWNvZGVkVG9rZW5bJ2h0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VtYWlsYWRkcmVzcyddID8/XG4gICAgICAgIGRlY29kZWRUb2tlblsnZW1haWwnXSA/P1xuICAgICAgICBkZWNvZGVkVG9rZW5bJ3N1YiddID8/XG4gICAgICAgIGRlY29kZWRUb2tlblsndXNlcl9pZCddO1xuXG4gICAgICBjb25zdCBkaXNwbGF5TmFtZSA9XG4gICAgICAgIGRlY29kZWRUb2tlblsnaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvZ2l2ZW5uYW1lJ10gPz9cbiAgICAgICAgZGVjb2RlZFRva2VuWydkaXNwbGF5TmFtZSddID8/XG4gICAgICAgIGRlY29kZWRUb2tlblsnZGlzcGxheV9uYW1lJ10gPz9cbiAgICAgICAgZGVjb2RlZFRva2VuWyduYW1lJ10gPz9cbiAgICAgICAgZGVjb2RlZFRva2VuWydnaXZlbl9uYW1lJ107XG5cbiAgICAgIGNvbnN0IG5hbWUgPSBkZWNvZGVkVG9rZW5bJ25hbWUnXSA/PyBkaXNwbGF5TmFtZTtcblxuICAgICAgaWYgKCFlbWFpbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXNlckRhdGE6IFVzZXJEYXRhID0ge1xuICAgICAgICBlbWFpbDogZW1haWwudG9TdHJpbmcoKSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGRpc3BsYXlOYW1lPy50b1N0cmluZygpID8/ICdVbmtub3duIFVzZXInLFxuICAgICAgICBuYW1lOiBuYW1lPy50b1N0cmluZygpLFxuICAgICAgICByb2xlczogdGhpcy5leHRyYWN0QXJyYXlGaWVsZChkZWNvZGVkVG9rZW4sIFsncm9sZXMnLCAncm9sZSddKSxcbiAgICAgICAgcGVybWlzc2lvbnM6IHRoaXMuZXh0cmFjdEFycmF5RmllbGQoZGVjb2RlZFRva2VuLCBbJ3Blcm1pc3Npb25zJywgJ3Blcm1zJ10pLFxuICAgICAgICB0ZW5hbnRJZDpcbiAgICAgICAgICBkZWNvZGVkVG9rZW5bJ3RlbmFudElkJ10/LnRvU3RyaW5nKCkgPz9cbiAgICAgICAgICBkZWNvZGVkVG9rZW5bJ3RlbmFudF9pZCddPy50b1N0cmluZygpID8/XG4gICAgICAgICAgZGVjb2RlZFRva2VuWyd0ZW5hbnQnXT8udG9TdHJpbmcoKSxcbiAgICAgICAgY29tcGFueUlkOlxuICAgICAgICAgIGRlY29kZWRUb2tlblsnY29tcGFueUlkJ10/LnRvU3RyaW5nKCkgPz9cbiAgICAgICAgICBkZWNvZGVkVG9rZW5bJ2NvbXBhbnlfaWQnXT8udG9TdHJpbmcoKSA/P1xuICAgICAgICAgIGRlY29kZWRUb2tlblsnb3JnYW5pemF0aW9uSWQnXT8udG9TdHJpbmcoKSA/P1xuICAgICAgICAgIGRlY29kZWRUb2tlblsnb3JnX2lkJ10/LnRvU3RyaW5nKCksXG4gICAgICAgIGxvY2FsZTogZGVjb2RlZFRva2VuWydsb2NhbGUnXT8udG9TdHJpbmcoKSxcbiAgICAgICAgdGltZXpvbmU6IGRlY29kZWRUb2tlblsndGltZXpvbmUnXT8udG9TdHJpbmcoKSA/PyBkZWNvZGVkVG9rZW5bJ3R6J10/LnRvU3RyaW5nKCksXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gdXNlckRhdGE7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCBhcnJheSBmaWVsZCBmcm9tIGRlY29kZWQgdG9rZW4sIHRyeWluZyBtdWx0aXBsZSBwb3NzaWJsZSBmaWVsZCBuYW1lc1xuICAgKi9cbiAgcHJpdmF0ZSBleHRyYWN0QXJyYXlGaWVsZChcbiAgICBkZWNvZGVkVG9rZW46IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgIGZpZWxkTmFtZXM6IHN0cmluZ1tdLFxuICApOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCB7XG4gICAgZm9yIChjb25zdCBmaWVsZE5hbWUgb2YgZmllbGROYW1lcykge1xuICAgICAgY29uc3QgdmFsdWUgPSBkZWNvZGVkVG9rZW5bZmllbGROYW1lXTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWUubWFwKHYgPT4gdi50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIC8vIEhhbmRsZSBjb21tYS1zZXBhcmF0ZWQgc3RyaW5nIHZhbHVlc1xuICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgICAuc3BsaXQoJywnKVxuICAgICAgICAgIC5tYXAodiA9PiB2LnRyaW0oKSlcbiAgICAgICAgICAuZmlsdGVyKHYgPT4gdi5sZW5ndGggPiAwKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuIl19","// src/lib/presentation/stores/auth-store.ts\nimport { Injectable, inject, signal, NgZone } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { of, tap, catchError } from 'rxjs';\nimport { AuthRepository } from '../../domain/repositories/auth-repository';\nimport { AuthTokenRepositoryImpl } from '../../repositories/auth-token-repository-impl';\nimport * as i0 from \"@angular/core\";\nexport class AuthStore {\n authRepository = inject(AuthRepository);\n tokenRepository = inject(AuthTokenRepositoryImpl);\n router = inject(Router);\n ngZone = inject(NgZone);\n // Authentication state signals\n _isAuthenticated = signal(false, ...(ngDevMode ? [{ debugName: \"_isAuthenticated\" }] : []));\n _isLoading = signal(false, ...(ngDevMode ? [{ debugName: \"_isLoading\" }] : []));\n _user = signal(null, ...(ngDevMode ? [{ debugName: \"_user\" }] : []));\n // Public readonly signals\n isAuthenticated = this._isAuthenticated.asReadonly();\n isLoading = this._isLoading.asReadonly();\n user = this._user.asReadonly();\n // Private refresh token timeout (instead of interval)\n refreshTokenTimeout;\n refreshInProgress$;\n constructor() {\n this.initializeAuthentication();\n }\n /**\n * Initialize authentication state on app startup\n */\n initializeAuthentication() {\n this._isLoading.set(true);\n try {\n const isAuthenticated = this.tokenRepository.isAuthenticated();\n this._isAuthenticated.set(isAuthenticated);\n if (isAuthenticated) {\n const userData = this.tokenRepository.getUserData();\n this._user.set(userData);\n this.scheduleTokenRefresh();\n }\n }\n catch {\n this.logout();\n }\n finally {\n this._isLoading.set(false);\n }\n }\n /**\n * Schedule token refresh based on actual expiration time\n */\n scheduleTokenRefresh() {\n const accessToken = this.tokenRepository.getToken();\n if (!accessToken) {\n return;\n }\n try {\n const decodedToken = this.decodeToken(accessToken);\n const currentTime = Math.floor(Date.now() / 1000);\n const timeUntilExpiry = decodedToken.exp - currentTime;\n // Refresh 5 minutes before expiry (300 seconds)\n const refreshTime = Math.max((timeUntilExpiry - 300) * 1000, 1000);\n // Clear any existing timeout\n if (this.refreshTokenTimeout) {\n clearTimeout(this.refreshTokenTimeout);\n }\n this.ngZone.runOutsideAngular(() => {\n this.refreshTokenTimeout = window.setTimeout(() => {\n this.ngZone.run(() => {\n // Check if refresh is still needed before executing\n if (this.tokenRepository.needsRefresh()) {\n this.refreshToken().subscribe();\n }\n });\n }, refreshTime);\n });\n }\n catch {\n // Silent fail - token might be invalid\n }\n }\n /**\n * Stop token refresh timer\n */\n stopTokenRefreshTimer() {\n if (this.refreshTokenTimeout) {\n clearTimeout(this.refreshTokenTimeout);\n this.refreshTokenTimeout = undefined;\n }\n }\n /**\n * Refresh authentication tokens\n */\n refreshToken() {\n // Return existing refresh request if one is in progress\n if (this.refreshInProgress$) {\n return this.refreshInProgress$;\n }\n const userData = this.tokenRepository.getUserData();\n const refreshToken = this.tokenRepository.getRefreshToken();\n if (!userData?.email || !refreshToken) {\n this.logout();\n return of(null);\n }\n this.refreshInProgress$ = this.authRepository\n .refreshToken({\n email: userData.email,\n refreshToken,\n })\n .pipe(tap(tokens => {\n this.setAuthenticated(tokens);\n }), catchError(() => {\n this.logout();\n return of(null);\n }), tap({\n complete: () => {\n this.refreshInProgress$ = undefined;\n },\n error: () => {\n this.refreshInProgress$ = undefined;\n },\n }));\n return this.refreshInProgress$;\n }\n /**\n * Set authentication state after successful login\n */\n setAuthenticated(tokens, rememberMe = false) {\n this.tokenRepository.saveTokens(tokens, rememberMe);\n this._isAuthenticated.set(true);\n const userData = this.tokenRepository.getUserData();\n this._user.set(userData);\n this.scheduleTokenRefresh();\n }\n /**\n * Logout user and clear all authentication data\n */\n logout() {\n const user = this._user();\n if (user) {\n // Call server-side logout first\n this.authRepository.logout(user.email, '').subscribe({\n next: () => {\n // Server logout successful, clear client-side data\n this.performClientLogout();\n },\n error: () => {\n // Server logout failed, still clear client-side data for security\n this.performClientLogout();\n },\n });\n }\n else {\n // No user data, just clear client-side data\n this.performClientLogout();\n }\n }\n /**\n * Perform client-side logout operations\n */\n performClientLogout() {\n this.stopTokenRefreshTimer();\n this.tokenRepository.clearTokens();\n this._isAuthenticated.set(false);\n this._user.set(null);\n // Navigate to login page\n this.router.navigate(['/auth']);\n }\n /**\n * Check if user is authenticated\n */\n checkAuthentication() {\n const isAuthenticated = this.tokenRepository.isAuthenticated();\n this._isAuthenticated.set(isAuthenticated);\n if (!isAuthenticated) {\n this.logout();\n }\n return isAuthenticated;\n }\n /**\n * Decode JWT token\n */\n decodeToken(token) {\n try {\n const base64Url = token.split('.')[1];\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(atob(base64)\n .split('')\n .map(c => {\n return `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`;\n })\n .join(''));\n return JSON.parse(jsonPayload);\n }\n catch {\n throw new Error('Invalid token format');\n }\n }\n /**\n * Cleanup on store destruction\n */\n ngOnDestroy() {\n this.stopTokenRefreshTimer();\n }\n static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"20.3.4\", ngImport: i0, type: AuthStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });\n static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"20.3.4\", ngImport: i0, type: AuthStore, providedIn: 'root' });\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"20.3.4\", ngImport: i0, type: AuthStore, decorators: [{\n type: Injectable,\n args: [{\n providedIn: 'root',\n }]\n }], ctorParameters: () => [] });\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL25nLWF1dGgvc3JjL2xpYi91aS9zdG9yZXMvYXV0aC1zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw0Q0FBNEM7QUFDNUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFhLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFjLEVBQUUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUMzRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQzs7QUFNeEYsTUFBTSxPQUFPLFNBQVM7SUFDSCxjQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3hDLGVBQWUsR0FBRyxNQUFNLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUNsRCxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3hCLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFekMsK0JBQStCO0lBQ2QsZ0JBQWdCLEdBQUcsTUFBTSxDQUFVLEtBQUssNERBQUMsQ0FBQztJQUMxQyxVQUFVLEdBQUcsTUFBTSxDQUFVLEtBQUssc0RBQUMsQ0FBQztJQUNwQyxLQUFLLEdBQUcsTUFBTSxDQUFrQixJQUFJLGlEQUFDLENBQUM7SUFFdkQsMEJBQTBCO0lBQ2pCLGVBQWUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDckQsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDekMsSUFBSSxHQUFHLElBQUks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QUMsV0FBVyxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUMxQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsV0FBVztRQUNULElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQy9CLENBQUM7dUdBL05VLFNBQVM7MkdBQVQsU0FBUyxjQUZSLE1BQU07OzJGQUVQLFNBQVM7a0JBSHJCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiLy8gc3JjL2xpYi9wcmVzZW50YXRpb24vc3RvcmVzL2F1dGgtc3RvcmUudHNcbmltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCwgc2lnbmFsLCBPbkRlc3Ryb3ksIE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCB0YXAsIGNhdGNoRXJyb3IgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEF1dGhSZXBvc2l0b3J5IH0gZnJvbSAnLi4vLi4vZG9tYWluL3JlcG9zaXRvcmllcy9hdXRoLXJlcG9zaXRvcnknO1xuaW1wb3J0IHsgQXV0aFRva2VuUmVwb3NpdG9yeUltcGwgfSBmcm9tICcuLi8uLi9yZXBvc2l0b3JpZXMvYXV0aC10b2tlbi1yZXBvc2l0b3J5LWltcGwnO1xuaW1wb3J0IHsgQXV0aFRva2VucywgVXNlckRhdGEsIERlY29kZWRUb2tlbiB9IGZyb20gJ0BhY29udHBsdXMvY29yZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBBdXRoU3RvcmUgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IGF1dGhSZXBvc2l0b3J5ID0gaW5qZWN0KEF1dGhSZXBvc2l0b3J5KTtcbiAgcHJpdmF0ZSByZWFkb25seSB0b2tlblJlcG9zaXRvcnkgPSBpbmplY3QoQXV0aFRva2VuUmVwb3NpdG9yeUltcGwpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gIC8vIEF1dGhlbnRpY2F0aW9uIHN0YXRlIHNpZ25hbHNcbiAgcHJpdmF0ZSByZWFkb25seSBfaXNBdXRoZW50aWNhdGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfaXNMb2FkaW5nID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfdXNlciA9IHNpZ25hbDxVc2VyRGF0YSB8IG51bGw+KG51bGwpO1xuXG4gIC8vIFB1YmxpYyByZWFkb25seSBzaWduYWxzXG4gIHJlYWRvbmx5IGlzQXV0aGVudGljYXRlZCA9IHRoaXMuX2lzQXV0aGVudGljYXRlZC5hc1JlYWRvbmx5KCk7XG4gIHJlYWRvbmx5IGlzTG9hZGluZyA9IHRoaXMuX2lzTG9hZGluZy5hc1JlYWRvbmx5KCk7XG4gIHJlYWRvbmx5IHVzZXIgPSB0aGlzLl91c2VyLmFzUmVhZG9ubHkoKTtcblxuICAvLyBQcml2YXRlIHJlZnJlc2ggdG9rZW4gdGltZW91dCAoaW5zdGVhZCBvZiBpbnRlcnZhbClcbiAgcHJpdmF0ZSByZWZyZXNoVG9rZW5UaW1lb3V0PzogbnVtYmVyO1xuICBwcml2YXRlIHJlZnJlc2hJblByb2dyZXNzJD86IE9ic2VydmFibGU8QXV0aFRva2VucyB8IG51bGw+O1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaW5pdGlhbGl6ZUF1dGhlbnRpY2F0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhdXRoZW50aWNhdGlvbiBzdGF0ZSBvbiBhcHAgc3RhcnR1cFxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplQXV0aGVudGljYXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5faXNMb2FkaW5nLnNldCh0cnVlKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBpc0F1dGhlbnRpY2F0ZWQgPSB0aGlzLnRva2VuUmVwb3NpdG9yeS5pc0F1dGhlbnRpY2F0ZWQoKTtcbiAgICAgIHRoaXMuX2lzQXV0aGVudGljYXRlZC5zZXQoaXNBdXRoZW50aWNhdGVkKTtcblxuICAgICAgaWYgKGlzQXV0aGVudGljYXRlZCkge1xuICAgICAgICBjb25zdCB1c2VyRGF0YSA9IHRoaXMudG9rZW5SZXBvc2l0b3J5LmdldFVzZXJEYXRhKCk7XG4gICAgICAgIHRoaXMuX3VzZXIuc2V0KHVzZXJEYXRhKTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZVRva2VuUmVmcmVzaCgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgdGhpcy5sb2dvdXQoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5faXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNjaGVkdWxlIHRva2VuIHJlZnJlc2ggYmFzZWQgb24gYWN0dWFsIGV4cGlyYXRpb24gdGltZVxuICAgKi9cbiAgcHJpdmF0ZSBzY2hlZHVsZVRva2VuUmVmcmVzaCgpOiB2b2lkIHtcbiAgICBjb25zdCBhY2Nlc3NUb2tlbiA9IHRoaXMudG9rZW5SZXBvc2l0b3J5LmdldFRva2VuKCk7XG4gICAgaWYgKCFhY2Nlc3NUb2tlbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkVG9rZW4gPSB0aGlzLmRlY29kZVRva2VuKGFjY2Vzc1Rva2VuKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG4gICAgICBjb25zdCB0aW1lVW50aWxFeHBpcnkgPSBkZWNvZGVkVG9rZW4uZXhwIC0gY3VycmVudFRpbWU7XG5cbiAgICAgIC8vIFJlZnJlc2ggNSBtaW51dGVzIGJlZm9yZSBleHBpcnkgKDMwMCBzZWNvbmRzKVxuICAgICAgY29uc3QgcmVmcmVzaFRpbWUgPSBNYXRoLm1heCgodGltZVVudGlsRXhwaXJ5IC0gMzAwKSAqIDEwMDAsIDEwMDApO1xuXG4gICAgICAvLyBDbGVhciBhbnkgZXhpc3RpbmcgdGltZW91dFxuICAgICAgaWYgKHRoaXMucmVmcmVzaFRva2VuVGltZW91dCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5yZWZyZXNoVG9rZW5UaW1lb3V0KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICB0aGlzLnJlZnJlc2hUb2tlblRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHJlZnJlc2ggaXMgc3RpbGwgbmVlZGVkIGJlZm9yZSBleGVjdXRpbmdcbiAgICAgICAgICAgIGlmICh0aGlzLnRva2VuUmVwb3NpdG9yeS5uZWVkc1JlZnJlc2goKSkge1xuICAgICAgICAgICAgICB0aGlzLnJlZnJlc2hUb2tlbigpLnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9LCByZWZyZXNoVGltZSk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFNpbGVudCBmYWlsIC0gdG9rZW4gbWlnaHQgYmUgaW52YWxpZFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wIHRva2VuIHJlZnJlc2ggdGltZXJcbiAgICovXG4gIHByaXZhdGUgc3RvcFRva2VuUmVmcmVzaFRpbWVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnJlZnJlc2hUb2tlblRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnJlZnJlc2hUb2tlblRpbWVvdXQpO1xuICAgICAgdGhpcy5yZWZyZXNoVG9rZW5UaW1lb3V0ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZyZXNoIGF1dGhlbnRpY2F0aW9uIHRva2Vuc1xuICAgKi9cbiAgcmVmcmVzaFRva2VuKCk6IE9ic2VydmFibGU8QXV0aFRva2VucyB8IG51bGw+IHtcbiAgICAvLyBSZXR1cm4gZXhpc3RpbmcgcmVmcmVzaCByZXF1ZXN0IGlmIG9uZSBpcyBpbiBwcm9ncmVzc1xuICAgIGlmICh0aGlzLnJlZnJlc2hJblByb2dyZXNzJCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaEluUHJvZ3Jlc3MkO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJEYXRhID0gdGhpcy50b2tlblJlcG9zaXRvcnkuZ2V0VXNlckRhdGEoKTtcbiAgICBjb25zdCByZWZyZXNoVG9rZW4gPSB0aGlzLnRva2VuUmVwb3NpdG9yeS5nZXRSZWZyZXNoVG9rZW4oKTtcblxuICAgIGlmICghdXNlckRhdGE/LmVtYWlsIHx8ICFyZWZyZXNoVG9rZW4pIHtcbiAgICAgIHRoaXMubG9nb3V0KCk7XG4gICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWZyZXNoSW5Qcm9ncmVzcyQgPSB0aGlzLmF1dGhSZXBvc2l0b3J5XG4gICAgICAucmVmcmVzaFRva2VuKHtcbiAgICAgICAgZW1haWw6IHVzZXJEYXRhLmVtYWlsLFxuICAgICAgICByZWZyZXNoVG9rZW4sXG4gICAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCh0b2tlbnMgPT4ge1xuICAgICAgICAgIHRoaXMuc2V0QXV0aGVudGljYXRlZCh0b2tlbnMpO1xuICAgICAgICB9KSxcbiAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5sb2dvdXQoKTtcbiAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgIH0pLFxuICAgICAgICB0YXAoe1xuICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hJblByb2dyZXNzJCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hJblByb2dyZXNzJCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICByZXR1cm4gdGhpcy5yZWZyZXNoSW5Qcm9ncmVzcyQ7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGF1dGhlbnRpY2F0aW9uIHN0YXRlIGFmdGVyIHN1Y2Nlc3NmdWwgbG9naW5cbiAgICovXG4gIHNldEF1dGhlbnRpY2F0ZWQodG9rZW5zOiBBdXRoVG9rZW5zLCByZW1lbWJlck1lID0gZmFsc2UpOiB2b2lkIHtcbiAgICB0aGlzLnRva2VuUmVwb3NpdG9yeS5zYXZlVG9rZW5zKHRva2VucywgcmVtZW1iZXJNZSk7XG4gICAgdGhpcy5faXNBdXRoZW50aWNhdGVkLnNldCh0cnVlKTtcbiAgICBjb25zdCB1c2VyRGF0YSA9IHRoaXMudG9rZW5SZXBvc2l0b3J5LmdldFVzZXJEYXRhKCk7XG4gICAgdGhpcy5fdXNlci5zZXQodXNlckRhdGEpO1xuICAgIHRoaXMuc2NoZWR1bGVUb2tlblJlZnJlc2goKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dvdXQgdXNlciBhbmQgY2xlYXIgYWxsIGF1dGhlbnRpY2F0aW9uIGRhdGFcbiAgICovXG4gIGxvZ291dCgpOiB2b2lkIHtcbiAgICBjb25zdCB1c2VyID0gdGhpcy5fdXNlcigpO1xuICAgIGlmICh1c2VyKSB7XG4gICAgICAvLyBDYWxsIHNlcnZlci1zaWRlIGxvZ291dCBmaXJzdFxuICAgICAgdGhpcy5hdXRoUmVwb3NpdG9yeS5sb2dvdXQodXNlci5lbWFpbCwgJycpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICAvLyBTZXJ2ZXIgbG9nb3V0IHN1Y2Nlc3NmdWwsIGNsZWFyIGNsaWVudC1zaWRlIGRhdGFcbiAgICAgICAgICB0aGlzLnBlcmZvcm1DbGllbnRMb2dvdXQoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICAvLyBTZXJ2ZXIgbG9nb3V0IGZhaWxlZCwgc3RpbGwgY2xlYXIgY2xpZW50LXNpZGUgZGF0YSBmb3Igc2VjdXJpdHlcbiAgICAgICAgICB0aGlzLnBlcmZvcm1DbGllbnRMb2dvdXQoKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyB1c2VyIGRhdGEsIGp1c3QgY2xlYXIgY2xpZW50LXNpZGUgZGF0YVxuICAgICAgdGhpcy5wZXJmb3JtQ2xpZW50TG9nb3V0KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gY2xpZW50LXNpZGUgbG9nb3V0IG9wZXJhdGlvbnNcbiAgICovXG4gIHByaXZhdGUgcGVyZm9ybUNsaWVudExvZ291dCgpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3BUb2tlblJlZnJlc2hUaW1lcigpO1xuICAgIHRoaXMudG9rZW5SZXBvc2l0b3J5LmNsZWFyVG9rZW5zKCk7XG4gICAgdGhpcy5faXNBdXRoZW50aWNhdGVkLnNldChmYWxzZSk7XG4gICAgdGhpcy5fdXNlci5zZXQobnVsbCk7XG5cbiAgICAvLyBOYXZpZ2F0ZSB0byBsb2dpbiBwYWdlXG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvYXV0aCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB1c2VyIGlzIGF1dGhlbnRpY2F0ZWRcbiAgICovXG4gIGNoZWNrQXV0aGVudGljYXRpb24oKTogYm9vbGVhbiB7XG4gICAgY29uc3QgaXNBdXRoZW50aWNhdGVkID0gdGhpcy50b2tlblJlcG9zaXRvcnkuaXNBdXRoZW50aWNhdGVkKCk7XG4gICAgdGhpcy5faXNBdXRoZW50aWNhdGVkLnNldChpc0F1dGhlbnRpY2F0ZWQpO1xuXG4gICAgaWYgKCFpc0F1dGhlbnRpY2F0ZWQpIHtcbiAgICAgIHRoaXMubG9nb3V0KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzQXV0aGVudGljYXRlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvZGUgSldUIHRva2VuXG4gICAqL1xuICBwcml2YXRlIGRlY29kZVRva2VuKHRva2VuOiBzdHJpbmcpOiBEZWNvZGVkVG9rZW4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBiYXNlNjRVcmwgPSB0b2tlbi5zcGxpdCgnLicpWzFdO1xuICAgICAgY29uc3QgYmFzZTY0ID0gYmFzZTY0VXJsLnJlcGxhY2UoLy0vZywgJysnKS5yZXBsYWNlKC9fL2csICcvJyk7XG4gICAgICBjb25zdCBqc29uUGF5bG9hZCA9IGRlY29kZVVSSUNvbXBvbmVudChcbiAgICAgICAgYXRvYihiYXNlNjQpXG4gICAgICAgICAgLnNwbGl0KCcnKVxuICAgICAgICAgIC5tYXAoYyA9PiB7XG4gICAgICAgICAgICByZXR1cm4gYCUke2AwMCR7Yy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KX1gLnNsaWNlKC0yKX1gO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmpvaW4oJycpLFxuICAgICAgKTtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKGpzb25QYXlsb