@nauth-toolkit/client-angular 0.1.63 → 0.1.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/auth-interceptor.shared.mjs +136 -0
- package/esm2022/lib/auth.guard.mjs +17 -10
- package/esm2022/lib/auth.interceptor.mjs +4 -263
- package/esm2022/ngmodule/auth.interceptor.class.mjs +10 -63
- package/esm2022/ngmodule/auth.service.mjs +17 -1
- package/fesm2022/nauth-toolkit-client-angular.mjs +162 -319
- package/fesm2022/nauth-toolkit-client-angular.mjs.map +1 -1
- package/lib/auth-interceptor.shared.d.ts +13 -0
- package/lib/auth.guard.d.ts +3 -0
- package/ngmodule/auth.service.d.ts +14 -0
- package/package.json +2 -2
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { HttpErrorResponse } from '@angular/common/http';
|
|
2
|
+
import { BehaviorSubject, catchError, filter, from, map, of, switchMap, take, throwError } from 'rxjs';
|
|
3
|
+
/**
|
|
4
|
+
* Shared interceptor logic for both:
|
|
5
|
+
* - Functional interceptor (Angular 17+ standalone)
|
|
6
|
+
* - Class-based interceptor (NgModule apps)
|
|
7
|
+
*
|
|
8
|
+
* WHY:
|
|
9
|
+
* - Keep one implementation for cookies + json mode behavior.
|
|
10
|
+
* - Avoid divergence between standalone and NgModule integrations.
|
|
11
|
+
*/
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Refresh state management (module-level)
|
|
14
|
+
// ============================================================================
|
|
15
|
+
let isRefreshing = false;
|
|
16
|
+
const refreshTokenSubject = new BehaviorSubject(null);
|
|
17
|
+
const retriedRequests = new WeakSet();
|
|
18
|
+
/**
|
|
19
|
+
* Get CSRF token from cookie.
|
|
20
|
+
*/
|
|
21
|
+
function getCsrfToken(cookieName) {
|
|
22
|
+
if (typeof document === 'undefined')
|
|
23
|
+
return null;
|
|
24
|
+
const match = document.cookie.match(new RegExp(`(^| )${cookieName}=([^;]+)`));
|
|
25
|
+
return match ? decodeURIComponent(match[2]) : null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build retry request with appropriate auth.
|
|
29
|
+
*
|
|
30
|
+
* In cookies mode: Browser automatically sends updated httpOnly cookies (access/refresh tokens).
|
|
31
|
+
* We must re-read CSRF token after refresh to avoid stale headers.
|
|
32
|
+
*
|
|
33
|
+
* In JSON mode: Clones the request and adds the new Bearer token.
|
|
34
|
+
*/
|
|
35
|
+
function buildRetryRequest(originalReq, tokenDelivery, newToken, csrfConfig) {
|
|
36
|
+
if (tokenDelivery === 'json' && newToken && newToken !== 'success') {
|
|
37
|
+
return originalReq.clone({ setHeaders: { Authorization: `Bearer ${newToken}` } });
|
|
38
|
+
}
|
|
39
|
+
if (tokenDelivery === 'cookies' && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(originalReq.method)) {
|
|
40
|
+
const csrfCookieName = csrfConfig?.cookieName ?? 'nauth_csrf_token';
|
|
41
|
+
const csrfHeaderName = csrfConfig?.headerName ?? 'x-csrf-token';
|
|
42
|
+
const freshCsrfToken = getCsrfToken(csrfCookieName);
|
|
43
|
+
if (freshCsrfToken) {
|
|
44
|
+
return originalReq.clone({ setHeaders: { [csrfHeaderName]: freshCsrfToken } });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return originalReq;
|
|
48
|
+
}
|
|
49
|
+
export function createNAuthAuthHttpInterceptor(params) {
|
|
50
|
+
const { config, http, authService, router, next, req } = params;
|
|
51
|
+
const tokenDelivery = config.tokenDelivery;
|
|
52
|
+
const baseUrl = config.baseUrl;
|
|
53
|
+
const endpoints = config.endpoints ?? {};
|
|
54
|
+
const refreshPath = endpoints.refresh ?? '/refresh';
|
|
55
|
+
const loginPath = endpoints.login ?? '/login';
|
|
56
|
+
const signupPath = endpoints.signup ?? '/signup';
|
|
57
|
+
const socialExchangePath = endpoints.socialExchange ?? '/social/exchange';
|
|
58
|
+
const refreshUrl = `${baseUrl}${refreshPath}`;
|
|
59
|
+
const isAuthApiRequest = req.url.includes(baseUrl);
|
|
60
|
+
const isRefreshEndpoint = req.url.includes(refreshPath);
|
|
61
|
+
const isPublicEndpoint = req.url.includes(loginPath) || req.url.includes(signupPath) || req.url.includes(socialExchangePath);
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// Build request for cookies mode (withCredentials + CSRF)
|
|
64
|
+
// ============================================================================
|
|
65
|
+
let authReq = req;
|
|
66
|
+
if (tokenDelivery === 'cookies') {
|
|
67
|
+
authReq = authReq.clone({ withCredentials: true });
|
|
68
|
+
if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) {
|
|
69
|
+
const csrfCookieName = config.csrf?.cookieName ?? 'nauth_csrf_token';
|
|
70
|
+
const csrfHeaderName = config.csrf?.headerName ?? 'x-csrf-token';
|
|
71
|
+
const csrfToken = getCsrfToken(csrfCookieName);
|
|
72
|
+
if (csrfToken) {
|
|
73
|
+
authReq = authReq.clone({ setHeaders: { [csrfHeaderName]: csrfToken } });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// JSON mode: attach Authorization header for HttpClient calls
|
|
79
|
+
// ============================================================================
|
|
80
|
+
const attachJsonAuth$ = tokenDelivery === 'json' &&
|
|
81
|
+
isAuthApiRequest &&
|
|
82
|
+
!isRefreshEndpoint &&
|
|
83
|
+
!isPublicEndpoint &&
|
|
84
|
+
!authReq.headers.has('Authorization')
|
|
85
|
+
? from(authService.getAccessToken()).pipe(map((token) => {
|
|
86
|
+
if (!token)
|
|
87
|
+
return authReq;
|
|
88
|
+
return authReq.clone({ setHeaders: { Authorization: `Bearer ${token}` } });
|
|
89
|
+
}))
|
|
90
|
+
: of(authReq);
|
|
91
|
+
return attachJsonAuth$.pipe(switchMap((requestWithAuth) => next(requestWithAuth).pipe(catchError((error) => {
|
|
92
|
+
const shouldHandle = error instanceof HttpErrorResponse &&
|
|
93
|
+
error.status === 401 &&
|
|
94
|
+
isAuthApiRequest &&
|
|
95
|
+
!isRefreshEndpoint &&
|
|
96
|
+
!isPublicEndpoint &&
|
|
97
|
+
!retriedRequests.has(req);
|
|
98
|
+
if (!shouldHandle) {
|
|
99
|
+
return throwError(() => error);
|
|
100
|
+
}
|
|
101
|
+
retriedRequests.add(req);
|
|
102
|
+
if (!isRefreshing) {
|
|
103
|
+
isRefreshing = true;
|
|
104
|
+
refreshTokenSubject.next(null);
|
|
105
|
+
// Refresh based on mode
|
|
106
|
+
const refresh$ = tokenDelivery === 'cookies'
|
|
107
|
+
? http.post(refreshUrl, {}, { withCredentials: true })
|
|
108
|
+
: from(authService.refresh());
|
|
109
|
+
return refresh$.pipe(switchMap((response) => {
|
|
110
|
+
isRefreshing = false;
|
|
111
|
+
const newToken = 'accessToken' in response ? response.accessToken : 'success';
|
|
112
|
+
refreshTokenSubject.next(newToken ?? 'success');
|
|
113
|
+
const retryReq = buildRetryRequest(requestWithAuth, tokenDelivery, newToken, config.csrf);
|
|
114
|
+
return next(retryReq).pipe(catchError((retryErr) => {
|
|
115
|
+
return throwError(() => retryErr);
|
|
116
|
+
}));
|
|
117
|
+
}), catchError((err) => {
|
|
118
|
+
isRefreshing = false;
|
|
119
|
+
refreshTokenSubject.next(null);
|
|
120
|
+
// Refresh failed -> redirect if configured
|
|
121
|
+
if (config.redirects?.sessionExpired) {
|
|
122
|
+
router.navigateByUrl(config.redirects.sessionExpired).catch(() => { });
|
|
123
|
+
}
|
|
124
|
+
return throwError(() => err);
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
// Wait for ongoing refresh
|
|
128
|
+
return refreshTokenSubject.pipe(filter((token) => token !== null), take(1), switchMap((token) => {
|
|
129
|
+
const retryReq = buildRetryRequest(requestWithAuth, tokenDelivery, token, config.csrf);
|
|
130
|
+
return next(retryReq).pipe(catchError((retryErr) => {
|
|
131
|
+
return throwError(() => retryErr);
|
|
132
|
+
}));
|
|
133
|
+
}));
|
|
134
|
+
}))));
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1pbnRlcmNlcHRvci5zaGFyZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2F1dGgtaW50ZXJjZXB0b3Iuc2hhcmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBYyxpQkFBaUIsRUFBeUMsTUFBTSxzQkFBc0IsQ0FBQztBQUU1RyxPQUFPLEVBQUUsZUFBZSxFQUFjLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJbkg7Ozs7Ozs7O0dBUUc7QUFFSCwrRUFBK0U7QUFDL0UsMENBQTBDO0FBQzFDLCtFQUErRTtBQUMvRSxJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7QUFDekIsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBZ0IsSUFBSSxDQUFDLENBQUM7QUFDckUsTUFBTSxlQUFlLEdBQUcsSUFBSSxPQUFPLEVBQXdCLENBQUM7QUFFNUQ7O0dBRUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxVQUFrQjtJQUN0QyxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVc7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLFVBQVUsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUM5RSxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUNyRCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsaUJBQWlCLENBQ3hCLFdBQWlDLEVBQ2pDLGFBQXFCLEVBQ3JCLFFBQWlCLEVBQ2pCLFVBQXlEO0lBRXpELElBQUksYUFBYSxLQUFLLE1BQU0sSUFBSSxRQUFR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LENBQUMsQ0FDSCxDQUNGLENBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50LCBIdHRwRXJyb3JSZXNwb25zZSwgSHR0cEV2ZW50LCBIdHRwSGFuZGxlckZuLCBIdHRwUmVxdWVzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIGNhdGNoRXJyb3IsIGZpbHRlciwgZnJvbSwgbWFwLCBvZiwgc3dpdGNoTWFwLCB0YWtlLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgdHlwZSB7IE5BdXRoQ2xpZW50Q29uZmlnIH0gZnJvbSAnQG5hdXRoLXRvb2xraXQvY2xpZW50JztcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vbmdtb2R1bGUvYXV0aC5zZXJ2aWNlJztcblxuLyoqXG4gKiBTaGFyZWQgaW50ZXJjZXB0b3IgbG9naWMgZm9yIGJvdGg6XG4gKiAtIEZ1bmN0aW9uYWwgaW50ZXJjZXB0b3IgKEFuZ3VsYXIgMTcrIHN0YW5kYWxvbmUpXG4gKiAtIENsYXNzLWJhc2VkIGludGVyY2VwdG9yIChOZ01vZHVsZSBhcHBzKVxuICpcbiAqIFdIWTpcbiAqIC0gS2VlcCBvbmUgaW1wbGVtZW50YXRpb24gZm9yIGNvb2tpZXMgKyBqc29uIG1vZGUgYmVoYXZpb3IuXG4gKiAtIEF2b2lkIGRpdmVyZ2VuY2UgYmV0d2VlbiBzdGFuZGFsb25lIGFuZCBOZ01vZHVsZSBpbnRlZ3JhdGlvbnMuXG4gKi9cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUmVmcmVzaCBzdGF0ZSBtYW5hZ2VtZW50IChtb2R1bGUtbGV2ZWwpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5sZXQgaXNSZWZyZXNoaW5nID0gZmFsc2U7XG5jb25zdCByZWZyZXNoVG9rZW5TdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmcgfCBudWxsPihudWxsKTtcbmNvbnN0IHJldHJpZWRSZXF1ZXN0cyA9IG5ldyBXZWFrU2V0PEh0dHBSZXF1ZXN0PHVua25vd24+PigpO1xuXG4vKipcbiAqIEdldCBDU1JGIHRva2VuIGZyb20gY29va2llLlxuICovXG5mdW5jdGlvbiBnZXRDc3JmVG9rZW4oY29va2llTmFtZTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgbWF0Y2ggPSBkb2N1bWVudC5jb29raWUubWF0Y2gobmV3IFJlZ0V4cChgKF58ICkke2Nvb2tpZU5hbWV9PShbXjtdKylgKSk7XG4gIHJldHVybiBtYXRjaCA/IGRlY29kZVVSSUNvbXBvbmVudChtYXRjaFsyXSkgOiBudWxsO1xufVxuXG4vKipcbiAqIEJ1aWxkIHJldHJ5IHJlcXVlc3Qgd2l0aCBhcHByb3ByaWF0ZSBhdXRoLlxuICpcbiAqIEluIGNvb2tpZXMgbW9kZTogQnJvd3NlciBhdXRvbWF0aWNhbGx5IHNlbmRzIHVwZGF0ZWQgaHR0cE9ubHkgY29va2llcyAoYWNjZXNzL3JlZnJlc2ggdG9rZW5zKS5cbiAqIFdlIG11c3QgcmUtcmVhZCBDU1JGIHRva2VuIGFmdGVyIHJlZnJlc2ggdG8gYXZvaWQgc3RhbGUgaGVhZGVycy5cbiAqXG4gKiBJbiBKU09OIG1vZGU6IENsb25lcyB0aGUgcmVxdWVzdCBhbmQgYWRkcyB0aGUgbmV3IEJlYXJlciB0b2tlbi5cbiAqL1xuZnVuY3Rpb24gYnVpbGRSZXRyeVJlcXVlc3QoXG4gIG9yaWdpbmFsUmVxOiBIdHRwUmVxdWVzdDx1bmtub3duPixcbiAgdG9rZW5EZWxpdmVyeTogc3RyaW5nLFxuICBuZXdUb2tlbj86IHN0cmluZyxcbiAgY3NyZkNvbmZpZz86IHsgY29va2llTmFtZT86IHN0cmluZzsgaGVhZGVyTmFtZT86IHN0cmluZyB9LFxuKTogSHR0cFJlcXVlc3Q8dW5rbm93bj4ge1xuICBpZiAodG9rZW5EZWxpdmVyeSA9PT0gJ2pzb24nICYmIG5ld1Rva2VuICYmIG5ld1Rva2VuICE9PSAnc3VjY2VzcycpIHtcbiAgICByZXR1cm4gb3JpZ2luYWxSZXEuY2xvbmUoeyBzZXRIZWFkZXJzOiB7IEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtuZXdUb2tlbn1gIH0gfSk7XG4gIH1cblxuICBpZiAodG9rZW5EZWxpdmVyeSA9PT0gJ2Nvb2tpZXMnICYmIFsnUE9TVCcsICdQVVQnLCAnUEFUQ0gnLCAnREVMRVRFJ10uaW5jbHVkZXMob3JpZ2luYWxSZXEubWV0aG9kKSkge1xuICAgIGNvbnN0IGNzcmZDb29raWVOYW1lID0gY3NyZkNvbmZpZz8uY29va2llTmFtZSA/PyAnbmF1dGhfY3NyZl90b2tlbic7XG4gICAgY29uc3QgY3NyZkhlYWRlck5hbWUgPSBjc3JmQ29uZmlnPy5oZWFkZXJOYW1lID8/ICd4LWNzcmYtdG9rZW4nO1xuICAgIGNvbnN0IGZyZXNoQ3NyZlRva2VuID0gZ2V0Q3NyZlRva2VuKGNzcmZDb29raWVOYW1lKTtcbiAgICBpZiAoZnJlc2hDc3JmVG9rZW4pIHtcbiAgICAgIHJldHVybiBvcmlnaW5hbFJlcS5jbG9uZSh7IHNldEhlYWRlcnM6IHsgW2NzcmZIZWFkZXJOYW1lXTogZnJlc2hDc3JmVG9rZW4gfSB9KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3JpZ2luYWxSZXE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOQXV0aEF1dGhIdHRwSW50ZXJjZXB0b3IocGFyYW1zOiB7XG4gIGNvbmZpZzogTkF1dGhDbGllbnRDb25maWc7XG4gIGh0dHA6IEh0dHBDbGllbnQ7XG4gIGF1dGhTZXJ2aWNlOiBBdXRoU2VydmljZTtcbiAgcm91dGVyOiBSb3V0ZXI7XG4gIG5leHQ6IEh0dHBIYW5kbGVyRm47XG4gIHJlcTogSHR0cFJlcXVlc3Q8dW5rbm93bj47XG59KTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8dW5rbm93bj4+IHtcbiAgY29uc3QgeyBjb25maWcsIGh0dHAsIGF1dGhTZXJ2aWNlLCByb3V0ZXIsIG5leHQsIHJlcSB9ID0gcGFyYW1zO1xuXG4gIGNvbnN0IHRva2VuRGVsaXZlcnkgPSBjb25maWcudG9rZW5EZWxpdmVyeTtcbiAgY29uc3QgYmFzZVVybCA9IGNvbmZpZy5iYXNlVXJsO1xuICBjb25zdCBlbmRwb2ludHMgPSBjb25maWcuZW5kcG9pbnRzID8/IHt9O1xuXG4gIGNvbnN0IHJlZnJlc2hQYXRoID0gZW5kcG9pbnRzLnJlZnJlc2ggPz8gJy9yZWZyZXNoJztcbiAgY29uc3QgbG9naW5QYXRoID0gZW5kcG9pbnRzLmxvZ2luID8/ICcvbG9naW4nO1xuICBjb25zdCBzaWdudXBQYXRoID0gZW5kcG9pbnRzLnNpZ251cCA/PyAnL3NpZ251cCc7XG4gIGNvbnN0IHNvY2lhbEV4Y2hhbmdlUGF0aCA9IGVuZHBvaW50cy5zb2NpYWxFeGNoYW5nZSA/PyAnL3NvY2lhbC9leGNoYW5nZSc7XG4gIGNvbnN0IHJlZnJlc2hVcmwgPSBgJHtiYXNlVXJsfSR7cmVmcmVzaFBhdGh9YDtcblxuICBjb25zdCBpc0F1dGhBcGlSZXF1ZXN0ID0gcmVxLnVybC5pbmNsdWRlcyhiYXNlVXJsKTtcbiAgY29uc3QgaXNSZWZyZXNoRW5kcG9pbnQgPSByZXEudXJsLmluY2x1ZGVzKHJlZnJlc2hQYXRoKTtcbiAgY29uc3QgaXNQdWJsaWNFbmRwb2ludCA9XG4gICAgcmVxLnVybC5pbmNsdWRlcyhsb2dpblBhdGgpIHx8IHJlcS51cmwuaW5jbHVkZXMoc2lnbnVwUGF0aCkgfHwgcmVxLnVybC5pbmNsdWRlcyhzb2NpYWxFeGNoYW5nZVBhdGgpO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gQnVpbGQgcmVxdWVzdCBmb3IgY29va2llcyBtb2RlICh3aXRoQ3JlZGVudGlhbHMgKyBDU1JGKVxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGxldCBhdXRoUmVxID0gcmVxO1xuICBpZiAodG9rZW5EZWxpdmVyeSA9PT0gJ2Nvb2tpZXMnKSB7XG4gICAgYXV0aFJlcSA9IGF1dGhSZXEuY2xvbmUoeyB3aXRoQ3JlZGVudGlhbHM6IHRydWUgfSk7XG4gICAgaWYgKFsnUE9TVCcsICdQVVQnLCAnUEFUQ0gnLCAnREVMRVRFJ10uaW5jbHVkZXMocmVxLm1ldGhvZCkpIHtcbiAgICAgIGNvbnN0IGNzcmZDb29raWVOYW1lID0gY29uZmlnLmNzcmY/LmNvb2tpZU5hbWUgPz8gJ25hdXRoX2NzcmZfdG9rZW4nO1xuICAgICAgY29uc3QgY3NyZkhlYWRlck5hbWUgPSBjb25maWcuY3NyZj8uaGVhZGVyTmFtZSA/PyAneC1jc3JmLXRva2VuJztcbiAgICAgIGNvbnN0IGNzcmZUb2tlbiA9IGdldENzcmZUb2tlbihjc3JmQ29va2llTmFtZSk7XG4gICAgICBpZiAoY3NyZlRva2VuKSB7XG4gICAgICAgIGF1dGhSZXEgPSBhdXRoUmVxLmNsb25lKHsgc2V0SGVhZGVyczogeyBbY3NyZkhlYWRlck5hbWVdOiBjc3JmVG9rZW4gfSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEpTT04gbW9kZTogYXR0YWNoIEF1dGhvcml6YXRpb24gaGVhZGVyIGZvciBIdHRwQ2xpZW50IGNhbGxzXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgY29uc3QgYXR0YWNoSnNvbkF1dGgkID1cbiAgICB0b2tlbkRlbGl2ZXJ5ID09PSAnanNvbicgJiZcbiAgICBpc0F1dGhBcGlSZXF1ZXN0ICYmXG4gICAgIWlzUmVmcmVzaEVuZHBvaW50ICYmXG4gICAgIWlzUHVibGljRW5kcG9pbnQgJiZcbiAgICAhYXV0aFJlcS5oZWFkZXJzLmhhcygnQXV0aG9yaXphdGlvbicpXG4gICAgICA/IGZyb20oYXV0aFNlcnZpY2UuZ2V0QWNjZXNzVG9rZW4oKSkucGlwZShcbiAgICAgICAgICBtYXAoKHRva2VuKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRva2VuKSByZXR1cm4gYXV0aFJlcTtcbiAgICAgICAgICAgIHJldHVybiBhdXRoUmVxLmNsb25lKHsgc2V0SGVhZGVyczogeyBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7dG9rZW59YCB9IH0pO1xuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICA6IG9mKGF1dGhSZXEpO1xuXG4gIHJldHVybiBhdHRhY2hKc29uQXV0aCQucGlwZShcbiAgICBzd2l0Y2hNYXAoKHJlcXVlc3RXaXRoQXV0aCkgPT5cbiAgICAgIG5leHQocmVxdWVzdFdpdGhBdXRoKS5waXBlKFxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgIGNvbnN0IHNob3VsZEhhbmRsZSA9XG4gICAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlICYmXG4gICAgICAgICAgICBlcnJvci5zdGF0dXMgPT09IDQwMSAmJlxuICAgICAgICAgICAgaXNBdXRoQXBpUmVxdWVzdCAmJlxuICAgICAgICAgICAgIWlzUmVmcmVzaEVuZHBvaW50ICYmXG4gICAgICAgICAgICAhaXNQdWJsaWNFbmRwb2ludCAmJlxuICAgICAgICAgICAgIXJldHJpZWRSZXF1ZXN0cy5oYXMocmVxKTtcblxuICAgICAgICAgIGlmICghc2hvdWxkSGFuZGxlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0cmllZFJlcXVlc3RzLmFkZChyZXEpO1xuXG4gICAgICAgICAgaWYgKCFpc1JlZnJlc2hpbmcpIHtcbiAgICAgICAgICAgIGlzUmVmcmVzaGluZyA9IHRydWU7XG4gICAgICAgICAgICByZWZyZXNoVG9rZW5TdWJqZWN0Lm5leHQobnVsbCk7XG5cbiAgICAgICAgICAgIC8vIFJlZnJlc2ggYmFzZWQgb24gbW9kZVxuICAgICAgICAgICAgY29uc3QgcmVmcmVzaCQgPVxuICAgICAgICAgICAgICB0b2tlbkRlbGl2ZXJ5ID09PSAnY29va2llcydcbiAgICAgICAgICAgICAgICA/IGh0dHAucG9zdDx7IGFjY2Vzc1Rva2VuPzogc3RyaW5nIH0+KHJlZnJlc2hVcmwsIHt9LCB7IHdpdGhDcmVkZW50aWFsczogdHJ1ZSB9KVxuICAgICAgICAgICAgICAgIDogZnJvbShhdXRoU2VydmljZS5yZWZyZXNoKCkpO1xuXG4gICAgICAgICAgICByZXR1cm4gcmVmcmVzaCQucGlwZShcbiAgICAgICAgICAgICAgc3dpdGNoTWFwKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlzUmVmcmVzaGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1Rva2VuID0gJ2FjY2Vzc1Rva2VuJyBpbiByZXNwb25zZSA/IHJlc3BvbnNlLmFjY2Vzc1Rva2VuIDogJ3N1Y2Nlc3MnO1xuICAgICAgICAgICAgICAgIHJlZnJlc2hUb2tlblN1YmplY3QubmV4dChuZXdUb2tlbiA/PyAnc3VjY2VzcycpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgcmV0cnlSZXEgPSBidWlsZFJldHJ5UmVxdWVzdChyZXF1ZXN0V2l0aEF1dGgsIHRva2VuRGVsaXZlcnksIG5ld1Rva2VuLCBjb25maWcuY3NyZik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5leHQocmV0cnlSZXEpLnBpcGUoXG4gICAgICAgICAgICAgICAgICBjYXRjaEVycm9yKChyZXRyeUVycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiByZXRyeUVycik7XG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaXNSZWZyZXNoaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmVmcmVzaFRva2VuU3ViamVjdC5uZXh0KG51bGwpO1xuXG4gICAgICAgICAgICAgICAgLy8gUmVmcmVzaCBmYWlsZWQgLT4gcmVkaXJlY3QgaWYgY29uZmlndXJlZFxuICAgICAgICAgICAgICAgIGlmIChjb25maWcucmVkaXJlY3RzPy5zZXNzaW9uRXhwaXJlZCkge1xuICAgICAgICAgICAgICAgICAgcm91dGVyLm5hdmlnYXRlQnlVcmwoY29uZmlnLnJlZGlyZWN0cy5zZXNzaW9uRXhwaXJlZCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnIpO1xuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gV2FpdCBmb3Igb25nb2luZyByZWZyZXNoXG4gICAgICAgICAgcmV0dXJuIHJlZnJlc2hUb2tlblN1YmplY3QucGlwZShcbiAgICAgICAgICAgIGZpbHRlcigodG9rZW4pOiB0b2tlbiBpcyBzdHJpbmcgPT4gdG9rZW4gIT09IG51bGwpLFxuICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCgodG9rZW4pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgcmV0cnlSZXEgPSBidWlsZFJldHJ5UmVxdWVzdChyZXF1ZXN0V2l0aEF1dGgsIHRva2VuRGVsaXZlcnksIHRva2VuLCBjb25maWcuY3NyZik7XG4gICAgICAgICAgICAgIHJldHVybiBuZXh0KHJldHJ5UmVxKS5waXBlKFxuICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKHJldHJ5RXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiByZXRyeUVycik7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgKSxcbiAgKTtcbn1cbiJdfQ==
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { inject, Inject, Optional } from '@angular/core';
|
|
1
|
+
import { inject, Inject, Injectable, Optional } from '@angular/core';
|
|
3
2
|
import { Router } from '@angular/router';
|
|
4
3
|
import { AuthService } from '../ngmodule/auth.service';
|
|
5
4
|
import { NAUTH_CLIENT_CONFIG } from '../ngmodule/tokens';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "../ngmodule/auth.service";
|
|
7
|
+
import * as i2 from "@angular/router";
|
|
6
8
|
/**
|
|
7
9
|
* Functional route guard for authentication (Angular 17+).
|
|
8
10
|
*
|
|
@@ -82,7 +84,7 @@ export function authGuard(redirectTo) {
|
|
|
82
84
|
* export class FeatureModule {}
|
|
83
85
|
* ```
|
|
84
86
|
*/
|
|
85
|
-
|
|
87
|
+
export class AuthGuard {
|
|
86
88
|
auth;
|
|
87
89
|
router;
|
|
88
90
|
config;
|
|
@@ -109,10 +111,15 @@ let AuthGuard = class AuthGuard {
|
|
|
109
111
|
const redirectPath = this.config?.redirects?.sessionExpired ?? '/login';
|
|
110
112
|
return this.router.createUrlTree([redirectPath]);
|
|
111
113
|
}
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthGuard, deps: [{ token: i1.AuthService }, { token: i2.Router }, { token: NAUTH_CLIENT_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
115
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthGuard });
|
|
116
|
+
}
|
|
117
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthGuard, decorators: [{
|
|
118
|
+
type: Injectable
|
|
119
|
+
}], ctorParameters: () => [{ type: i1.AuthService }, { type: i2.Router }, { type: undefined, decorators: [{
|
|
120
|
+
type: Optional
|
|
121
|
+
}, {
|
|
122
|
+
type: Inject,
|
|
123
|
+
args: [NAUTH_CLIENT_CONFIG]
|
|
124
|
+
}] }] });
|
|
125
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5ndWFyZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvYXV0aC5ndWFyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JFLE9BQU8sRUFBaUIsTUFBTSxFQUFXLE1BQU0saUJBQWlCLENBQUM7QUFDakUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7O0FBR3pEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZCRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsVUFBbUI7SUFDM0MsT0FBTyxHQUFzQixFQUFFO1FBQzdCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNqQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFFL0QsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQztZQUMzQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxzRkFBc0Y7UUFDdEYsTUFBTSxZQUFZLEdBQUcsVUFBVSxJQUFJLE1BQU0sRUFBRSxTQUFTLEVBQUUsY0FBYyxJQUFJLFFBQVEsQ0FBQztRQUVqRixPQUFPLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQzlDLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQ0c7QUFFSCxNQUFNLE9BQU8sU0FBUztJQU9WO0lBQ0E7SUFDeUM7SUFSbkQ7Ozs7T0FJRztJQUNILFlBQ1UsSUFBaUIsRUFDakIsTUFBYyxFQUMyQixNQUEwQjtRQUZuRSxTQUFJLEdBQUosSUFBSSxDQUFhO1FBQ2pCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDMkIsV0FBTSxHQUFOLE1BQU0sQ0FBb0I7SUFDMUUsQ0FBQztJQUVKOzs7O09BSUc7SUFDSCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7WUFDaEMsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsNkRBQTZEO1FBQzdELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLGNBQWMsSUFBSSxRQUFRLENBQUM7UUFFeEUsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDbkQsQ0FBQzt3R0ExQlUsU0FBUyxtRUFTRSxtQkFBbUI7NEdBVDlCLFNBQVM7OzRGQUFULFNBQVM7a0JBRHJCLFVBQVU7OzBCQVVOLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3QsIEluamVjdGFibGUsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDYW5BY3RpdmF0ZUZuLCBSb3V0ZXIsIFVybFRyZWUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi9uZ21vZHVsZS9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgTkFVVEhfQ0xJRU5UX0NPTkZJRyB9IGZyb20gJy4uL25nbW9kdWxlL3Rva2Vucyc7XG5pbXBvcnQgdHlwZSB7IE5BdXRoQ2xpZW50Q29uZmlnIH0gZnJvbSAnQG5hdXRoLXRvb2xraXQvY2xpZW50JztcblxuLyoqXG4gKiBGdW5jdGlvbmFsIHJvdXRlIGd1YXJkIGZvciBhdXRoZW50aWNhdGlvbiAoQW5ndWxhciAxNyspLlxuICpcbiAqIFByb3RlY3RzIHJvdXRlcyBieSBjaGVja2luZyBpZiB1c2VyIGlzIGF1dGhlbnRpY2F0ZWQuXG4gKiBSZWRpcmVjdHMgdG8gY29uZmlndXJlZCBzZXNzaW9uIGV4cGlyZWQgcm91dGUgKG9yIGxvZ2luKSBpZiBub3QgYXV0aGVudGljYXRlZC5cbiAqXG4gKiBAcGFyYW0gcmVkaXJlY3RUbyAtIE9wdGlvbmFsIHBhdGggdG8gcmVkaXJlY3QgdG8gaWYgbm90IGF1dGhlbnRpY2F0ZWQuIElmIG5vdCBwcm92aWRlZCwgdXNlcyBgcmVkaXJlY3RzLnNlc3Npb25FeHBpcmVkYCBmcm9tIGNvbmZpZyAoZGVmYXVsdHMgdG8gJy9sb2dpbicpXG4gKiBAcmV0dXJucyBDYW5BY3RpdmF0ZUZuIGd1YXJkIGZ1bmN0aW9uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIEluIHJvdXRlIGNvbmZpZ3VyYXRpb24gLSB1c2VzIGNvbmZpZy5yZWRpcmVjdHMuc2Vzc2lvbkV4cGlyZWRcbiAqIGNvbnN0IHJvdXRlczogUm91dGVzID0gW1xuICogICB7XG4gKiAgICAgcGF0aDogJ2hvbWUnLFxuICogICAgIGNvbXBvbmVudDogSG9tZUNvbXBvbmVudCxcbiAqICAgICBjYW5BY3RpdmF0ZTogW2F1dGhHdWFyZCgpXVxuICogICB9XG4gKiBdO1xuICpcbiAqIC8vIE92ZXJyaWRlIHdpdGggY3VzdG9tIHJvdXRlXG4gKiBjb25zdCByb3V0ZXM6IFJvdXRlcyA9IFtcbiAqICAge1xuICogICAgIHBhdGg6ICdhZG1pbicsXG4gKiAgICAgY29tcG9uZW50OiBBZG1pbkNvbXBvbmVudCxcbiAqICAgICBjYW5BY3RpdmF0ZTogW2F1dGhHdWFyZCgnL2FkbWluL2xvZ2luJyldXG4gKiAgIH1cbiAqIF07XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF1dGhHdWFyZChyZWRpcmVjdFRvPzogc3RyaW5nKTogQ2FuQWN0aXZhdGVGbiB7XG4gIHJldHVybiAoKTogYm9vbGVhbiB8IFVybFRyZWUgPT4ge1xuICAgIGNvbnN0IGF1dGggPSBpbmplY3QoQXV0aFNlcnZpY2UpO1xuICAgIGNvbnN0IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuICAgIGNvbnN0IGNvbmZpZyA9IGluamVjdChOQVVUSF9DTElFTlRfQ09ORklHLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gICAgaWYgKGF1dGguaXNBdXRoZW50aWNhdGVkKCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIFVzZSBwcm92aWRlZCByZWRpcmVjdFRvLCBvciBjb25maWcucmVkaXJlY3RzLnNlc3Npb25FeHBpcmVkLCBvciBkZWZhdWx0IHRvICcvbG9naW4nXG4gICAgY29uc3QgcmVkaXJlY3RQYXRoID0gcmVkaXJlY3RUbyA/PyBjb25maWc/LnJlZGlyZWN0cz8uc2Vzc2lvbkV4cGlyZWQgPz8gJy9sb2dpbic7XG5cbiAgICByZXR1cm4gcm91dGVyLmNyZWF0ZVVybFRyZWUoW3JlZGlyZWN0UGF0aF0pO1xuICB9O1xufVxuXG4vKipcbiAqIENsYXNzLWJhc2VkIGF1dGhlbnRpY2F0aW9uIGd1YXJkIGZvciBOZ01vZHVsZSBjb21wYXRpYmlsaXR5LlxuICpcbiAqICoqTm90ZToqKiBXaGVuIHVzaW5nIGBOQXV0aE1vZHVsZS5mb3JSb290KClgLCBgQXV0aEd1YXJkYCBpcyBhdXRvbWF0aWNhbGx5IHByb3ZpZGVkXG4gKiBhbmQgaGFzIGFjY2VzcyB0byB0aGUgY29uZmlndXJhdGlvbi4gWW91IGRvbid0IG5lZWQgdG8gYWRkIGl0IHRvIHlvdXIgbW9kdWxlJ3MgcHJvdmlkZXJzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBhcHAubW9kdWxlLnRzIC0gQXV0aEd1YXJkIGlzIGF1dG9tYXRpY2FsbHkgcHJvdmlkZWQgYnkgTkF1dGhNb2R1bGUuZm9yUm9vdCgpXG4gKiBATmdNb2R1bGUoe1xuICogICBpbXBvcnRzOiBbXG4gKiAgICAgTkF1dGhNb2R1bGUuZm9yUm9vdCh7XG4gKiAgICAgICBiYXNlVXJsOiAnaHR0cHM6Ly9hcGkuZXhhbXBsZS5jb20vYXV0aCcsXG4gKiAgICAgICB0b2tlbkRlbGl2ZXJ5OiAnY29va2llcycsXG4gKiAgICAgICByZWRpcmVjdHM6IHtcbiAqICAgICAgICAgc2Vzc2lvbkV4cGlyZWQ6ICcvbG9naW4/ZXhwaXJlZD10cnVlJyxcbiAqICAgICAgIH0sXG4gKiAgICAgfSksXG4gKiAgICAgUm91dGVyTW9kdWxlLmZvclJvb3QoW1xuICogICAgICAge1xuICogICAgICAgICBwYXRoOiAnaG9tZScsXG4gKiAgICAgICAgIGNvbXBvbmVudDogSG9tZUNvbXBvbmVudCxcbiAqICAgICAgICAgY2FuQWN0aXZhdGU6IFtBdXRoR3VhcmRdLCAvLyBVc2VzIGNvbmZpZy5yZWRpcmVjdHMuc2Vzc2lvbkV4cGlyZWRcbiAqICAgICAgIH0sXG4gKiAgICAgXSksXG4gKiAgIF0sXG4gKiB9KVxuICogZXhwb3J0IGNsYXNzIEFwcE1vZHVsZSB7fVxuICpcbiAqIC8vIE9yIHByb3ZpZGUgbWFudWFsbHkgaW4gYSBmZWF0dXJlIG1vZHVsZSAoc3RpbGwgaGFzIGFjY2VzcyB0byByb290IGNvbmZpZylcbiAqIEBOZ01vZHVsZSh7XG4gKiAgIHByb3ZpZGVyczogW0F1dGhHdWFyZF0sXG4gKiB9KVxuICogZXhwb3J0IGNsYXNzIEZlYXR1cmVNb2R1bGUge31cbiAqIGBgYFxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQXV0aEd1YXJkIHtcbiAgLyoqXG4gICAqIEBwYXJhbSBhdXRoIC0gQXV0aGVudGljYXRpb24gc2VydmljZVxuICAgKiBAcGFyYW0gcm91dGVyIC0gQW5ndWxhciByb3V0ZXJcbiAgICogQHBhcmFtIGNvbmZpZyAtIE9wdGlvbmFsIGNsaWVudCBjb25maWd1cmF0aW9uIChpbmplY3RlZCBhdXRvbWF0aWNhbGx5KVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhdXRoOiBBdXRoU2VydmljZSxcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTkFVVEhfQ0xJRU5UX0NPTkZJRykgcHJpdmF0ZSBjb25maWc/OiBOQXV0aENsaWVudENvbmZpZyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiByb3V0ZSBjYW4gYmUgYWN0aXZhdGVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBUcnVlIGlmIGF1dGhlbnRpY2F0ZWQsIG90aGVyd2lzZSByZWRpcmVjdHMgdG8gY29uZmlndXJlZCBzZXNzaW9uIGV4cGlyZWQgcm91dGUgKG9yICcvbG9naW4nKVxuICAgKi9cbiAgY2FuQWN0aXZhdGUoKTogYm9vbGVhbiB8IFVybFRyZWUge1xuICAgIGlmICh0aGlzLmF1dGguaXNBdXRoZW50aWNhdGVkKCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIFVzZSBjb25maWcucmVkaXJlY3RzLnNlc3Npb25FeHBpcmVkIG9yIGRlZmF1bHQgdG8gJy9sb2dpbidcbiAgICBjb25zdCByZWRpcmVjdFBhdGggPSB0aGlzLmNvbmZpZz8ucmVkaXJlY3RzPy5zZXNzaW9uRXhwaXJlZCA/PyAnL2xvZ2luJztcblxuICAgIHJldHVybiB0aGlzLnJvdXRlci5jcmVhdGVVcmxUcmVlKFtyZWRpcmVjdFBhdGhdKTtcbiAgfVxufVxuIl19
|
|
@@ -1,29 +1,10 @@
|
|
|
1
1
|
import { inject, PLATFORM_ID } from '@angular/core';
|
|
2
2
|
import { isPlatformBrowser } from '@angular/common';
|
|
3
|
-
import { HttpClient
|
|
3
|
+
import { HttpClient } from '@angular/common/http';
|
|
4
4
|
import { Router } from '@angular/router';
|
|
5
|
-
import { catchError, switchMap, throwError, filter, take, BehaviorSubject, from } from 'rxjs';
|
|
6
5
|
import { NAUTH_CLIENT_CONFIG } from '../ngmodule/tokens';
|
|
7
6
|
import { AuthService } from '../ngmodule/auth.service';
|
|
8
|
-
|
|
9
|
-
* Refresh state management.
|
|
10
|
-
* BehaviorSubject pattern is the industry-standard for token refresh.
|
|
11
|
-
*/
|
|
12
|
-
let isRefreshing = false;
|
|
13
|
-
const refreshTokenSubject = new BehaviorSubject(null);
|
|
14
|
-
/**
|
|
15
|
-
* Track retried requests to prevent infinite loops.
|
|
16
|
-
*/
|
|
17
|
-
const retriedRequests = new WeakSet();
|
|
18
|
-
/**
|
|
19
|
-
* Get CSRF token from cookie.
|
|
20
|
-
*/
|
|
21
|
-
function getCsrfToken(cookieName) {
|
|
22
|
-
if (typeof document === 'undefined')
|
|
23
|
-
return null;
|
|
24
|
-
const match = document.cookie.match(new RegExp(`(^| )${cookieName}=([^;]+)`));
|
|
25
|
-
return match ? decodeURIComponent(match[2]) : null;
|
|
26
|
-
}
|
|
7
|
+
import { createNAuthAuthHttpInterceptor } from './auth-interceptor.shared';
|
|
27
8
|
/**
|
|
28
9
|
* Angular HTTP interceptor for nauth-toolkit.
|
|
29
10
|
*
|
|
@@ -41,248 +22,8 @@ export const authInterceptor = (req, next) => {
|
|
|
41
22
|
if (!isBrowser) {
|
|
42
23
|
return next(req);
|
|
43
24
|
}
|
|
44
|
-
|
|
45
|
-
if (req.url.includes('/profile') && req.method === 'PUT') {
|
|
46
|
-
fetch('http://127.0.0.1:7242/ingest/97f9fe53-6a8b-43e2-ae9b-4b2d0f725816', {
|
|
47
|
-
method: 'POST',
|
|
48
|
-
headers: { 'Content-Type': 'application/json' },
|
|
49
|
-
body: JSON.stringify({
|
|
50
|
-
location: 'auth.interceptor.ts:entry',
|
|
51
|
-
message: 'Original request entry',
|
|
52
|
-
data: { reqBody: req.body, reqBodyType: typeof req.body, reqMethod: req.method, reqUrl: req.url },
|
|
53
|
-
timestamp: Date.now(),
|
|
54
|
-
sessionId: 'debug-session',
|
|
55
|
-
hypothesisId: 'A',
|
|
56
|
-
}),
|
|
57
|
-
}).catch(() => { });
|
|
58
|
-
}
|
|
59
|
-
// #endregion
|
|
60
|
-
const tokenDelivery = config.tokenDelivery;
|
|
61
|
-
const baseUrl = config.baseUrl;
|
|
62
|
-
const endpoints = config.endpoints ?? {};
|
|
63
|
-
const refreshPath = endpoints.refresh ?? '/refresh';
|
|
64
|
-
const loginPath = endpoints.login ?? '/login';
|
|
65
|
-
const signupPath = endpoints.signup ?? '/signup';
|
|
66
|
-
const socialExchangePath = endpoints.socialExchange ?? '/social/exchange';
|
|
67
|
-
const refreshUrl = `${baseUrl}${refreshPath}`;
|
|
68
|
-
const isAuthApiRequest = req.url.includes(baseUrl);
|
|
69
|
-
const isRefreshEndpoint = req.url.includes(refreshPath);
|
|
70
|
-
const isPublicEndpoint = req.url.includes(loginPath) || req.url.includes(signupPath) || req.url.includes(socialExchangePath);
|
|
71
|
-
// Build request with credentials (cookies mode only)
|
|
72
|
-
let authReq = req;
|
|
73
|
-
if (tokenDelivery === 'cookies') {
|
|
74
|
-
authReq = authReq.clone({ withCredentials: true });
|
|
75
|
-
if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) {
|
|
76
|
-
const csrfCookieName = config.csrf?.cookieName ?? 'nauth_csrf_token';
|
|
77
|
-
const csrfHeaderName = config.csrf?.headerName ?? 'x-csrf-token';
|
|
78
|
-
const csrfToken = getCsrfToken(csrfCookieName);
|
|
79
|
-
if (csrfToken) {
|
|
80
|
-
authReq = authReq.clone({ setHeaders: { [csrfHeaderName]: csrfToken } });
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return next(authReq).pipe(catchError((error) => {
|
|
85
|
-
const shouldHandle = error instanceof HttpErrorResponse &&
|
|
86
|
-
error.status === 401 &&
|
|
87
|
-
isAuthApiRequest &&
|
|
88
|
-
!isRefreshEndpoint &&
|
|
89
|
-
!isPublicEndpoint &&
|
|
90
|
-
!retriedRequests.has(req);
|
|
91
|
-
if (!shouldHandle) {
|
|
92
|
-
return throwError(() => error);
|
|
93
|
-
}
|
|
94
|
-
// Mark original request as retried to prevent infinite loops
|
|
95
|
-
retriedRequests.add(req);
|
|
96
|
-
if (config.debug) {
|
|
97
|
-
console.warn('[nauth-interceptor] 401 detected:', req.url);
|
|
98
|
-
}
|
|
99
|
-
if (!isRefreshing) {
|
|
100
|
-
isRefreshing = true;
|
|
101
|
-
refreshTokenSubject.next(null);
|
|
102
|
-
if (config.debug) {
|
|
103
|
-
console.warn('[nauth-interceptor] Starting refresh...');
|
|
104
|
-
}
|
|
105
|
-
// Refresh based on mode
|
|
106
|
-
const refresh$ = tokenDelivery === 'cookies'
|
|
107
|
-
? http.post(refreshUrl, {}, { withCredentials: true })
|
|
108
|
-
: from(authService.refresh());
|
|
109
|
-
return refresh$.pipe(switchMap((response) => {
|
|
110
|
-
if (config.debug) {
|
|
111
|
-
console.warn('[nauth-interceptor] Refresh successful');
|
|
112
|
-
}
|
|
113
|
-
isRefreshing = false;
|
|
114
|
-
// Get new token (JSON mode) or signal success (cookies mode)
|
|
115
|
-
const newToken = 'accessToken' in response ? response.accessToken : 'success';
|
|
116
|
-
refreshTokenSubject.next(newToken ?? 'success');
|
|
117
|
-
// #region agent log
|
|
118
|
-
fetch('http://127.0.0.1:7242/ingest/97f9fe53-6a8b-43e2-ae9b-4b2d0f725816', {
|
|
119
|
-
method: 'POST',
|
|
120
|
-
headers: { 'Content-Type': 'application/json' },
|
|
121
|
-
body: JSON.stringify({
|
|
122
|
-
location: 'auth.interceptor.ts:125',
|
|
123
|
-
message: 'Before buildRetryRequest',
|
|
124
|
-
data: {
|
|
125
|
-
authReqBody: authReq.body,
|
|
126
|
-
authReqMethod: authReq.method,
|
|
127
|
-
authReqUrl: authReq.url,
|
|
128
|
-
authReqBodyType: typeof authReq.body,
|
|
129
|
-
},
|
|
130
|
-
timestamp: Date.now(),
|
|
131
|
-
sessionId: 'debug-session',
|
|
132
|
-
hypothesisId: 'A',
|
|
133
|
-
}),
|
|
134
|
-
}).catch(() => { });
|
|
135
|
-
// #endregion
|
|
136
|
-
// Build retry request with fresh CSRF token (re-read from cookie after refresh)
|
|
137
|
-
const retryReq = buildRetryRequest(authReq, tokenDelivery, newToken, config.csrf);
|
|
138
|
-
// #region agent log
|
|
139
|
-
fetch('http://127.0.0.1:7242/ingest/97f9fe53-6a8b-43e2-ae9b-4b2d0f725816', {
|
|
140
|
-
method: 'POST',
|
|
141
|
-
headers: { 'Content-Type': 'application/json' },
|
|
142
|
-
body: JSON.stringify({
|
|
143
|
-
location: 'auth.interceptor.ts:130',
|
|
144
|
-
message: 'After buildRetryRequest',
|
|
145
|
-
data: {
|
|
146
|
-
retryReqBody: retryReq.body,
|
|
147
|
-
retryReqMethod: retryReq.method,
|
|
148
|
-
retryReqUrl: retryReq.url,
|
|
149
|
-
retryReqBodyType: typeof retryReq.body,
|
|
150
|
-
headersKeys: retryReq.headers.keys(),
|
|
151
|
-
},
|
|
152
|
-
timestamp: Date.now(),
|
|
153
|
-
sessionId: 'debug-session',
|
|
154
|
-
hypothesisId: 'B',
|
|
155
|
-
}),
|
|
156
|
-
}).catch(() => { });
|
|
157
|
-
// #endregion
|
|
158
|
-
if (config.debug) {
|
|
159
|
-
console.warn('[nauth-interceptor] Retrying:', req.url);
|
|
160
|
-
}
|
|
161
|
-
// Retry the request with fresh token/CSRF
|
|
162
|
-
// IMPORTANT: Errors from the retry (e.g., 400 validation) should NOT trigger
|
|
163
|
-
// session expiration redirect. Only the refresh failure should redirect.
|
|
164
|
-
return next(retryReq).pipe(catchError((retryErr) => {
|
|
165
|
-
// Retry failed (could be 400, 403, 500, etc.)
|
|
166
|
-
// Just propagate the error - don't redirect to login
|
|
167
|
-
if (config.debug) {
|
|
168
|
-
console.warn('[nauth-interceptor] Retry request failed:', retryErr);
|
|
169
|
-
}
|
|
170
|
-
return throwError(() => retryErr);
|
|
171
|
-
}));
|
|
172
|
-
}), catchError((err) => {
|
|
173
|
-
// This only catches REFRESH failures, not retry failures
|
|
174
|
-
if (config.debug) {
|
|
175
|
-
console.error('[nauth-interceptor] Refresh failed:', err);
|
|
176
|
-
}
|
|
177
|
-
isRefreshing = false;
|
|
178
|
-
refreshTokenSubject.next(null);
|
|
179
|
-
// Handle session expiration - redirect to configured URL
|
|
180
|
-
// Only redirect if refresh itself failed (not if retry failed)
|
|
181
|
-
if (config.redirects?.sessionExpired) {
|
|
182
|
-
router.navigateByUrl(config.redirects.sessionExpired).catch((navError) => {
|
|
183
|
-
if (config.debug) {
|
|
184
|
-
console.error('[nauth-interceptor] Navigation failed:', navError);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
return throwError(() => err);
|
|
189
|
-
}));
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
// Wait for ongoing refresh
|
|
193
|
-
if (config.debug) {
|
|
194
|
-
console.warn('[nauth-interceptor] Waiting for refresh...');
|
|
195
|
-
}
|
|
196
|
-
return refreshTokenSubject.pipe(filter((token) => token !== null), take(1), switchMap((token) => {
|
|
197
|
-
if (config.debug) {
|
|
198
|
-
console.warn('[nauth-interceptor] Refresh done, retrying:', req.url);
|
|
199
|
-
}
|
|
200
|
-
const retryReq = buildRetryRequest(authReq, tokenDelivery, token, config.csrf);
|
|
201
|
-
// Retry the request - errors here should propagate normally
|
|
202
|
-
// without triggering session expiration redirect
|
|
203
|
-
return next(retryReq).pipe(catchError((retryErr) => {
|
|
204
|
-
if (config.debug) {
|
|
205
|
-
console.warn('[nauth-interceptor] Retry request failed:', retryErr);
|
|
206
|
-
}
|
|
207
|
-
return throwError(() => retryErr);
|
|
208
|
-
}));
|
|
209
|
-
}));
|
|
210
|
-
}
|
|
211
|
-
}));
|
|
25
|
+
return createNAuthAuthHttpInterceptor({ config, http, authService, router, next, req });
|
|
212
26
|
};
|
|
213
|
-
/**
|
|
214
|
-
* Build retry request with appropriate auth.
|
|
215
|
-
*
|
|
216
|
-
* CRITICAL FIX: In cookies mode, after refresh the server may send updated cookies.
|
|
217
|
-
* We MUST re-read the CSRF token from the cookie before retrying to ensure we have
|
|
218
|
-
* the current CSRF token that matches what the server expects.
|
|
219
|
-
*
|
|
220
|
-
* In JSON mode: Clones the request and adds the new Bearer token.
|
|
221
|
-
*
|
|
222
|
-
* @param originalReq - The base request (already has withCredentials if cookies mode)
|
|
223
|
-
* @param tokenDelivery - 'cookies' or 'json'
|
|
224
|
-
* @param newToken - The new access token (JSON mode only)
|
|
225
|
-
* @param csrfConfig - CSRF configuration to re-read token from cookie
|
|
226
|
-
* @returns The request ready for retry with fresh auth
|
|
227
|
-
*/
|
|
228
|
-
function buildRetryRequest(originalReq, tokenDelivery, newToken, csrfConfig) {
|
|
229
|
-
if (tokenDelivery === 'json' && newToken && newToken !== 'success') {
|
|
230
|
-
return originalReq.clone({
|
|
231
|
-
setHeaders: { Authorization: `Bearer ${newToken}` },
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
// Cookies mode: Browser automatically sends updated httpOnly cookies (access/refresh tokens).
|
|
235
|
-
// However, CSRF token must match the cookie value at the moment of retry.
|
|
236
|
-
// We ALWAYS re-read from document.cookie here (using defaults when csrfConfig
|
|
237
|
-
// is not provided) to avoid stale header values after refresh or across tabs.
|
|
238
|
-
if (tokenDelivery === 'cookies' && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(originalReq.method)) {
|
|
239
|
-
const csrfCookieName = csrfConfig?.cookieName ?? 'nauth_csrf_token';
|
|
240
|
-
const csrfHeaderName = csrfConfig?.headerName ?? 'x-csrf-token';
|
|
241
|
-
const freshCsrfToken = getCsrfToken(csrfCookieName);
|
|
242
|
-
// #region agent log
|
|
243
|
-
fetch('http://127.0.0.1:7242/ingest/97f9fe53-6a8b-43e2-ae9b-4b2d0f725816', {
|
|
244
|
-
method: 'POST',
|
|
245
|
-
headers: { 'Content-Type': 'application/json' },
|
|
246
|
-
body: JSON.stringify({
|
|
247
|
-
location: 'auth.interceptor.ts:buildRetryRequest',
|
|
248
|
-
message: 'Inside buildRetryRequest cookies branch',
|
|
249
|
-
data: {
|
|
250
|
-
originalReqBody: originalReq.body,
|
|
251
|
-
originalReqBodyType: typeof originalReq.body,
|
|
252
|
-
freshCsrfToken: freshCsrfToken?.substring(0, 8),
|
|
253
|
-
method: originalReq.method,
|
|
254
|
-
},
|
|
255
|
-
timestamp: Date.now(),
|
|
256
|
-
sessionId: 'debug-session',
|
|
257
|
-
hypothesisId: 'C',
|
|
258
|
-
}),
|
|
259
|
-
}).catch(() => { });
|
|
260
|
-
// #endregion
|
|
261
|
-
if (freshCsrfToken) {
|
|
262
|
-
// Clone with fresh CSRF token in header
|
|
263
|
-
const cloned = originalReq.clone({
|
|
264
|
-
setHeaders: { [csrfHeaderName]: freshCsrfToken },
|
|
265
|
-
});
|
|
266
|
-
// #region agent log
|
|
267
|
-
fetch('http://127.0.0.1:7242/ingest/97f9fe53-6a8b-43e2-ae9b-4b2d0f725816', {
|
|
268
|
-
method: 'POST',
|
|
269
|
-
headers: { 'Content-Type': 'application/json' },
|
|
270
|
-
body: JSON.stringify({
|
|
271
|
-
location: 'auth.interceptor.ts:buildRetryRequest:afterClone',
|
|
272
|
-
message: 'After clone with setHeaders',
|
|
273
|
-
data: { clonedBody: cloned.body, clonedBodyType: typeof cloned.body, originalBody: originalReq.body },
|
|
274
|
-
timestamp: Date.now(),
|
|
275
|
-
sessionId: 'debug-session',
|
|
276
|
-
hypothesisId: 'D',
|
|
277
|
-
}),
|
|
278
|
-
}).catch(() => { });
|
|
279
|
-
// #endregion
|
|
280
|
-
return cloned;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// No changes needed (GET request or no CSRF token available)
|
|
284
|
-
return originalReq;
|
|
285
|
-
}
|
|
286
27
|
/**
|
|
287
28
|
* Class-based interceptor for NgModule compatibility.
|
|
288
29
|
*/
|
|
@@ -291,4 +32,4 @@ export class AuthInterceptor {
|
|
|
291
32
|
return authInterceptor(req, next);
|
|
292
33
|
}
|
|
293
34
|
}
|
|
294
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5pbnRlcmNlcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvYXV0aC5pbnRlcmNlcHRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNwRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQWlELFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3BILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUV2RDs7O0dBR0c7QUFDSCxJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7QUFDekIsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBZ0IsSUFBSSxDQUFDLENBQUM7QUFFckU7O0dBRUc7QUFDSCxNQUFNLGVBQWUsR0FBRyxJQUFJLE9BQU8sRUFBd0IsQ0FBQztBQUU1RDs7R0FFRztBQUNILFNBQVMsWUFBWSxDQUFDLFVBQWtCO0lBQ3RDLElBQUksT0FBTyxRQUFRLEtBQUssV0FBVztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ2pELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLFFBQVEsVUFBVSxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBQzlFLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENB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QUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFLE9BQU8sTUFBTSxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDLElBQUksRUFBRTtvQkFDckcsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7b0JBQ3JCLFNBQVMsRUFBRSxlQUFlO29CQUMxQixZQUFZLEVBQUUsR0FBRztpQkFDbEIsQ0FBQzthQUNILENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbkIsYUFBYTtZQUViLE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7SUFDSCxDQUFDO0lBRUQsNkRBQTZEO0lBQzdELE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBQzFCLFNBQVMsQ0FBQyxHQUF5QixFQUFFLElBQW1CO1FBQ3RELE9BQU8sZUFBZSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIFBMQVRGT1JNX0lEIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBIdHRwSGFuZGxlckZuLCBIdHRwSW50ZXJjZXB0b3JGbiwgSHR0cFJlcXVlc3QsIEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIHN3aXRjaE1hcCwgdGhyb3dFcnJvciwgZmlsdGVyLCB0YWtlLCBCZWhhdmlvclN1YmplY3QsIGZyb20gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IE5BVVRIX0NMSUVOVF9DT05GSUcgfSBmcm9tICcuLi9uZ21vZHVsZS90b2tlbnMnO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi9uZ21vZHVsZS9hdXRoLnNlcnZpY2UnO1xuXG4vKipcbiAqIFJlZnJlc2ggc3RhdGUgbWFuYWdlbWVudC5cbiAqIEJlaGF2aW9yU3ViamVjdCBwYXR0ZXJuIGlzIHRoZSBpbmR1c3RyeS1zdGFuZGFyZCBmb3IgdG9rZW4gcmVmcmVzaC5cbiAqL1xubGV0IGlzUmVmcmVzaGluZyA9IGZhbHNlO1xuY29uc3QgcmVmcmVzaFRva2VuU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG5cbi8qKlxuICogVHJhY2sgcmV0cmllZCByZXF1ZXN0cyB0byBwcmV2ZW50IGluZmluaXRlIGxvb3BzLlxuICovXG5jb25zdCByZXRyaWVkUmVxdWVzdHMgPSBuZXcgV2Vha1NldDxIdHRwUmVxdWVzdDx1bmtub3duPj4oKTtcblxuLyoqXG4gKiBHZXQgQ1NSRiB0b2tlbiBmcm9tIGNvb2tpZS5cbiAqL1xuZnVuY3Rpb24gZ2V0Q3NyZlRva2VuKGNvb2tpZU5hbWU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykgcmV0dXJuIG51bGw7XG4gIGNvbnN0IG1hdGNoID0gZG9jdW1lbnQuY29va2llLm1hdGNoKG5ldyBSZWdFeHAoYChefCApJHtjb29raWVOYW1lfT0oW147XSspYCkpO1xuICByZXR1cm4gbWF0Y2ggPyBkZWNvZGVVUklDb21wb25lbnQobWF0Y2hbMl0pIDogbnVsbDtcbn1cblxuLyoqXG4gKiBBbmd1bGFyIEhUVFAgaW50ZXJjZXB0b3IgZm9yIG5hdXRoLXRvb2xraXQuXG4gKlxuICogSGFuZGxlczpcbiAqIC0gQ29va2llcyBtb2RlOiB3aXRoQ3JlZGVudGlhbHMgKyBDU1JGIHRva2VucyArIHJlZnJlc2ggdmlhIFBPU1RcbiAqIC0gSlNPTiBtb2RlOiByZWZyZXNoIHZpYSBTREssIHJldHJ5IHdpdGggbmV3IHRva2VuXG4gKi9cbmV4cG9ydCBjb25zdCBhdXRoSW50ZXJjZXB0b3I6IEh0dHBJbnRlcmNlcHRvckZuID0gKHJlcTogSHR0cFJlcXVlc3Q8dW5rbm93bj4sIG5leHQ6IEh0dHBIYW5kbGVyRm4pID0+IHtcbiAgY29uc3QgY29uZmlnID0gaW5qZWN0KE5BVVRIX0NMSUVOVF9DT05GSUcpO1xuICBjb25zdCBodHRwID0gaW5qZWN0KEh0dHBDbGllbnQpO1xuICBjb25zdCBhdXRoU2VydmljZSA9IGluamVjdChBdXRoU2VydmljZSk7XG4gIGNvbnN0IHBsYXRmb3JtSWQgPSBpbmplY3QoUExBVEZPUk1fSUQpO1xuICBjb25zdCByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgY29uc3QgaXNCcm93c2VyID0gaXNQbGF0Zm9ybUJyb3dzZXIocGxhdGZvcm1JZCk7XG5cbiAgaWYgKCFpc0Jyb3dzZXIpIHtcbiAgICByZXR1cm4gbmV4dChyZXEpO1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBhZ2VudCBsb2dcbiAgaWYgKHJlcS51cmwuaW5jbHVkZXMoJy9wcm9maWxlJykgJiYgcmVxLm1ldGhvZCA9PT0gJ1BVVCcpIHtcbiAgICBmZXRjaCgnaHR0cDovLzEyNy4wLjAuMTo3MjQyL2luZ2VzdC85N2Y5ZmU1My02YThiLTQzZTItYWU5Yi00YjJkMGY3MjU4MTYnLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBsb2NhdGlvbjogJ2F1dGguaW50ZXJjZXB0b3IudHM6ZW50cnknLFxuICAgICAgICBtZXNzYWdlOiAnT3JpZ2luYWwgcmVxdWVzdCBlbnRyeScsXG4gICAgICAgIGRhdGE6IHsgcmVxQm9keTogcmVxLmJvZHksIHJlcUJvZHlUeXBlOiB0eXBlb2YgcmVxLmJvZHksIHJlcU1ldGhvZDogcmVxLm1ldGhvZCwgcmVxVXJsOiByZXEudXJsIH0sXG4gICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgc2Vzc2lvbklkOiAnZGVidWctc2Vzc2lvbicsXG4gICAgICAgIGh5cG90aGVzaXNJZDogJ0EnLFxuICAgICAgfSksXG4gICAgfSkuY2F0Y2goKCkgPT4ge30pO1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICBjb25zdCB0b2tlbkRlbGl2ZXJ5ID0gY29uZmlnLnRva2VuRGVsaXZlcnk7XG4gIGNvbnN0IGJhc2VVcmwgPSBjb25maWcuYmFzZVVybDtcbiAgY29uc3QgZW5kcG9pbnRzID0gY29uZmlnLmVuZHBvaW50cyA/PyB7fTtcbiAgY29uc3QgcmVmcmVzaFBhdGggPSBlbmRwb2ludHMucmVmcmVzaCA/PyAnL3JlZnJlc2gnO1xuICBjb25zdCBsb2dpblBhdGggPSBlbmRwb2ludHMubG9naW4gPz8gJy9sb2dpbic7XG4gIGNvbnN0IHNpZ251cFBhdGggPSBlbmRwb2ludHMuc2lnbnVwID8/ICcvc2lnbnVwJztcbiAgY29uc3Qgc29jaWFsRXhjaGFuZ2VQYXRoID0gZW5kcG9pbnRzLnNvY2lhbEV4Y2hhbmdlID8/ICcvc29jaWFsL2V4Y2hhbmdlJztcbiAgY29uc3QgcmVmcmVzaFVybCA9IGAke2Jhc2VVcmx9JHtyZWZyZXNoUGF0aH1gO1xuXG4gIGNvbnN0IGlzQXV0aEFwaVJlcXVlc3QgPSByZXEudXJsLmluY2x1ZGVzKGJhc2VVcmwpO1xuICBjb25zdCBpc1JlZnJlc2hFbmRwb2ludCA9IHJlcS51cmwuaW5jbHVkZXMocmVmcmVzaFBhdGgpO1xuICBjb25zdCBpc1B1YmxpY0VuZHBvaW50ID1cbiAgICByZXEudXJsLmluY2x1ZGVzKGxvZ2luUGF0aCkgfHwgcmVxLnVybC5pbmNsdWRlcyhzaWdudXBQYXRoKSB8fCByZXEudXJsLmluY2x1ZGVzKHNvY2lhbEV4Y2hhbmdlUGF0aCk7XG5cbiAgLy8gQnVpbGQgcmVxdWVzdCB3aXRoIGNyZWRlbnRpYWxzIChjb29raWVzIG1vZGUgb25seSlcbiAgbGV0IGF1dGhSZXEgPSByZXE7XG4gIGlmICh0b2tlbkRlbGl2ZXJ5ID09PSAnY29va2llcycpIHtcbiAgICBhdXRoUmVxID0gYXV0aFJlcS5jbG9uZSh7IHdpdGhDcmVkZW50aWFsczogdHJ1ZSB9KTtcblxuICAgIGlmIChbJ1BPU1QnLCAnUFVUJywgJ1BBVENIJywgJ0RFTEVURSddLmluY2x1ZGVzKHJlcS5tZXRob2QpKSB7XG4gICAgICBjb25zdCBjc3JmQ29va2llTmFtZSA9IGNvbmZpZy5jc3JmPy5jb29raWVOYW1lID8/ICduYXV0aF9jc3JmX3Rva2VuJztcbiAgICAgIGNvbnN0IGNzcmZIZWFkZXJOYW1lID0gY29uZmlnLmNzcmY/LmhlYWRlck5hbWUgPz8gJ3gtY3NyZi10b2tlbic7XG4gICAgICBjb25zdCBjc3JmVG9rZW4gPSBnZXRDc3JmVG9rZW4oY3NyZkNvb2tpZU5hbWUpO1xuICAgICAgaWYgKGNzcmZUb2tlbikge1xuICAgICAgICBhdXRoUmVxID0gYXV0aFJlcS5jbG9uZSh7IHNldEhlYWRlcnM6IHsgW2NzcmZIZWFkZXJOYW1lXTogY3NyZlRva2VuIH0gfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHQoYXV0aFJlcSkucGlwZShcbiAgICBjYXRjaEVycm9yKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgY29uc3Qgc2hvdWxkSGFuZGxlID1cbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSAmJlxuICAgICAgICBlcnJvci5zdGF0dXMgPT09IDQwMSAmJlxuICAgICAgICBpc0F1dGhBcGlSZXF1ZXN0ICYmXG4gICAgICAgICFpc1JlZnJlc2hFbmRwb2ludCAmJlxuICAgICAgICAhaXNQdWJsaWNFbmRwb2ludCAmJlxuICAgICAgICAhcmV0cmllZFJlcXVlc3RzLmhhcyhyZXEpO1xuXG4gICAgICBpZiAoIXNob3VsZEhhbmRsZSkge1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIC8vIE1hcmsgb3JpZ2luYWwgcmVxdWVzdCBhcyByZXRyaWVkIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcHNcbiAgICAgIHJldHJpZWRSZXF1ZXN0cy5hZGQocmVxKTtcblxuICAgICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tuYXV0aC1pbnRlcmNlcHRvcl0gNDAxIGRldGVjdGVkOicsIHJlcS51cmwpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWlzUmVmcmVzaGluZykge1xuICAgICAgICBpc1JlZnJlc2hpbmcgPSB0cnVlO1xuICAgICAgICByZWZyZXNoVG9rZW5TdWJqZWN0Lm5leHQobnVsbCk7XG5cbiAgICAgICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgICAgIGNvbnNvbGUud2FybignW25hdXRoLWludGVyY2VwdG9yXSBTdGFydGluZyByZWZyZXNoLi4uJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWZyZXNoIGJhc2VkIG9uIG1vZGVcbiAgICAgICAgY29uc3QgcmVmcmVzaCQgPVxuICAgICAgICAgIHRva2VuRGVsaXZlcnkgPT09ICdjb29raWVzJ1xuICAgICAgICAgICAgPyBodHRwLnBvc3Q8eyBhY2Nlc3NUb2tlbj86IHN0cmluZyB9PihyZWZyZXNoVXJsLCB7fSwgeyB3aXRoQ3JlZGVudGlhbHM6IHRydWUgfSlcbiAgICAgICAgICAgIDogZnJvbShhdXRoU2VydmljZS5yZWZyZXNoKCkpO1xuXG4gICAgICAgIHJldHVybiByZWZyZXNoJC5waXBlKFxuICAgICAgICAgIHN3aXRjaE1hcCgocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbbmF1dGgtaW50ZXJjZXB0b3JdIFJlZnJlc2ggc3VjY2Vzc2Z1bCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXNSZWZyZXNoaW5nID0gZmFsc2U7XG5cbiAgICAgICAgICAgIC8vIEdldCBuZXcgdG9rZW4gKEpTT04gbW9kZSkgb3Igc2lnbmFsIHN1Y2Nlc3MgKGNvb2tpZXMgbW9kZSlcbiAgICAgICAgICAgIGNvbnN0IG5ld1Rva2VuID0gJ2FjY2Vzc1Rva2VuJyBpbiByZXNwb25zZSA/IHJlc3BvbnNlLmFjY2Vzc1Rva2VuIDogJ3N1Y2Nlc3MnO1xuICAgICAgICAgICAgcmVmcmVzaFRva2VuU3ViamVjdC5uZXh0KG5ld1Rva2VuID8/ICdzdWNjZXNzJyk7XG5cbiAgICAgICAgICAgIC8vICNyZWdpb24gYWdlbnQgbG9nXG4gICAgICAgICAgICBmZXRjaCgnaHR0cDovLzEyNy4wLjAuMTo3MjQyL2luZ2VzdC85N2Y5ZmU1My02YThiLTQzZTItYWU5Yi00YjJkMGY3MjU4MTYnLCB7XG4gICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIGxvY2F0aW9uOiAnYXV0aC5pbnRlcmNlcHRvci50czoxMjUnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdCZWZvcmUgYnVpbGRSZXRyeVJlcXVlc3QnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgIGF1dGhSZXFCb2R5OiBhdXRoUmVxLmJvZHksXG4gICAgICAgICAgICAgICAgICBhdXRoUmVxTWV0aG9kOiBhdXRoUmVxLm1ldGhvZCxcbiAgICAgICAgICAgICAgICAgIGF1dGhSZXFVcmw6IGF1dGhSZXEudXJsLFxuICAgICAgICAgICAgICAgICAgYXV0aFJlcUJvZHlUeXBlOiB0eXBlb2YgYXV0aFJlcS5ib2R5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIHNlc3Npb25JZDogJ2RlYnVnLXNlc3Npb24nLFxuICAgICAgICAgICAgICAgIGh5cG90aGVzaXNJZDogJ0EnLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgICAgICAgIC8vICNlbmRyZWdpb25cblxuICAgICAgICAgICAgLy8gQnVpbGQgcmV0cnkgcmVxdWVzdCB3aXRoIGZyZXNoIENTUkYgdG9rZW4gKHJlLXJlYWQgZnJvbSBjb29raWUgYWZ0ZXIgcmVmcmVzaClcbiAgICAgICAgICAgIGNvbnN0IHJldHJ5UmVxID0gYnVpbGRSZXRyeVJlcXVlc3QoYXV0aFJlcSwgdG9rZW5EZWxpdmVyeSwgbmV3VG9rZW4sIGNvbmZpZy5jc3JmKTtcblxuICAgICAgICAgICAgLy8gI3JlZ2lvbiBhZ2VudCBsb2dcbiAgICAgICAgICAgIGZldGNoKCdodHRwOi8vMTI3LjAuMC4xOjcyNDIvaW5nZXN0Lzk3ZjlmZTUzLTZhOGItNDNlMi1hZTliLTRiMmQwZjcyNTgxNicsIHtcbiAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgbG9jYXRpb246ICdhdXRoLmludGVyY2VwdG9yLnRzOjEzMCcsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ0FmdGVyIGJ1aWxkUmV0cnlSZXF1ZXN0JyxcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICByZXRyeVJlcUJvZHk6IHJldHJ5UmVxLmJvZHksXG4gICAgICAgICAgICAgICAgICByZXRyeVJlcU1ldGhvZDogcmV0cnlSZXEubWV0aG9kLFxuICAgICAgICAgICAgICAgICAgcmV0cnlSZXFVcmw6IHJldHJ5UmVxLnVybCxcbiAgICAgICAgICAgICAgICAgIHJldHJ5UmVxQm9keVR5cGU6IHR5cGVvZiByZXRyeVJlcS5ib2R5LFxuICAgICAgICAgICAgICAgICAgaGVhZGVyc0tleXM6IHJldHJ5UmVxLmhlYWRlcnMua2V5cygpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIHNlc3Npb25JZDogJ2RlYnVnLXNlc3Npb24nLFxuICAgICAgICAgICAgICAgIGh5cG90aGVzaXNJZDogJ0InLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgICAgICAgIC8vICNlbmRyZWdpb25cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tuYXV0aC1pbnRlcmNlcHRvcl0gUmV0cnlpbmc6JywgcmVxLnVybCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJldHJ5IHRoZSByZXF1ZXN0IHdpdGggZnJlc2ggdG9rZW4vQ1NSRlxuICAgICAgICAgICAgLy8gSU1QT1JUQU5UOiBFcnJvcnMgZnJvbSB0aGUgcmV0cnkgKGUuZy4sIDQwMCB2YWxpZGF0aW9uKSBzaG91bGQgTk9UIHRyaWdnZXJcbiAgICAgICAgICAgIC8vIHNlc3Npb24gZXhwaXJhdGlvbiByZWRpcmVjdC4gT25seSB0aGUgcmVmcmVzaCBmYWlsdXJlIHNob3VsZCByZWRpcmVjdC5cbiAgICAgICAgICAgIHJldHVybiBuZXh0KHJldHJ5UmVxKS5waXBlKFxuICAgICAgICAgICAgICBjYXRjaEVycm9yKChyZXRyeUVycikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIFJldHJ5IGZhaWxlZCAoY291bGQgYmUgNDAwLCA0MDMsIDUwMCwgZXRjLilcbiAgICAgICAgICAgICAgICAvLyBKdXN0IHByb3BhZ2F0ZSB0aGUgZXJyb3IgLSBkb24ndCByZWRpcmVjdCB0byBsb2dpblxuICAgICAgICAgICAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignW25hdXRoLWludGVyY2VwdG9yXSBSZXRyeSByZXF1ZXN0IGZhaWxlZDonLCByZXRyeUVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IHJldHJ5RXJyKTtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIGNhdGNoRXJyb3IoKGVycikgPT4ge1xuICAgICAgICAgICAgLy8gVGhpcyBvbmx5IGNhdGNoZXMgUkVGUkVTSCBmYWlsdXJlcywgbm90IHJldHJ5IGZhaWx1cmVzXG4gICAgICAgICAgICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tuYXV0aC1pbnRlcmNlcHRvcl0gUmVmcmVzaCBmYWlsZWQ6JywgZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzUmVmcmVzaGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgcmVmcmVzaFRva2VuU3ViamVjdC5uZXh0KG51bGwpO1xuXG4gICAgICAgICAgICAvLyBIYW5kbGUgc2Vzc2lvbiBleHBpcmF0aW9uIC0gcmVkaXJlY3QgdG8gY29uZmlndXJlZCBVUkxcbiAgICAgICAgICAgIC8vIE9ubHkgcmVkaXJlY3QgaWYgcmVmcmVzaCBpdHNlbGYgZmFpbGVkIChub3QgaWYgcmV0cnkgZmFpbGVkKVxuICAgICAgICAgICAgaWYgKGNvbmZpZy5yZWRpcmVjdHM/LnNlc3Npb25FeHBpcmVkKSB7XG4gICAgICAgICAgICAgIHJvdXRlci5uYXZpZ2F0ZUJ5VXJsKGNvbmZpZy5yZWRpcmVjdHMuc2Vzc2lvbkV4cGlyZWQpLmNhdGNoKChuYXZFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tuYXV0aC1pbnRlcmNlcHRvcl0gTmF2aWdhdGlvbiBmYWlsZWQ6JywgbmF2RXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycik7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBXYWl0IGZvciBvbmdvaW5nIHJlZnJlc2hcbiAgICAgICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgICAgIGNvbnNvbGUud2FybignW25hdXRoLWludGVyY2VwdG9yXSBXYWl0aW5nIGZvciByZWZyZXNoLi4uJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlZnJlc2hUb2tlblN1YmplY3QucGlwZShcbiAgICAgICAgICBmaWx0ZXIoKHRva2VuKTogdG9rZW4gaXMgc3RyaW5nID0+IHRva2VuICE9PSBudWxsKSxcbiAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgIHN3aXRjaE1hcCgodG9rZW4pID0+IHtcbiAgICAgICAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbbmF1dGgtaW50ZXJjZXB0b3JdIFJlZnJlc2ggZG9uZSwgcmV0cnlpbmc6JywgcmVxLnVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByZXRyeVJlcSA9IGJ1aWxkUmV0cnlSZXF1ZXN0KGF1dGhSZXEsIHRva2VuRGVsaXZlcnksIHRva2VuLCBjb25maWcuY3NyZik7XG5cbiAgICAgICAgICAgIC8vIFJldHJ5IHRoZSByZXF1ZXN0IC0gZXJyb3JzIGhlcmUgc2hvdWxkIHByb3BhZ2F0ZSBub3JtYWxseVxuICAgICAgICAgICAgLy8gd2l0aG91dCB0cmlnZ2VyaW5nIHNlc3Npb24gZXhwaXJhdGlvbiByZWRpcmVjdFxuICAgICAgICAgICAgcmV0dXJuIG5leHQocmV0cnlSZXEpLnBpcGUoXG4gICAgICAgICAgICAgIGNhdGNoRXJyb3IoKHJldHJ5RXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbbmF1dGgtaW50ZXJjZXB0b3JdIFJldHJ5IHJlcXVlc3QgZmFpbGVkOicsIHJldHJ5RXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gcmV0cnlFcnIpO1xuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSksXG4gICk7XG59O1xuXG4vKipcbiAqIEJ1aWxkIHJldHJ5IHJlcXVlc3Qgd2l0aCBhcHByb3ByaWF0ZSBhdXRoLlxuICpcbiAqIENSSVRJQ0FMIEZJWDogSW4gY29va2llcyBtb2RlLCBhZnRlciByZWZyZXNoIHRoZSBzZXJ2ZXIgbWF5IHNlbmQgdXBkYXRlZCBjb29raWVzLlxuICogV2UgTVVTVCByZS1yZWFkIHRoZSBDU1JGIHRva2VuIGZyb20gdGhlIGNvb2tpZSBiZWZvcmUgcmV0cnlpbmcgdG8gZW5zdXJlIHdlIGhhdmVcbiAqIHRoZSBjdXJyZW50IENTUkYgdG9rZW4gdGhhdCBtYXRjaGVzIHdoYXQgdGhlIHNlcnZlciBleHBlY3RzLlxuICpcbiAqIEluIEpTT04gbW9kZTogQ2xvbmVzIHRoZSByZXF1ZXN0IGFuZCBhZGRzIHRoZSBuZXcgQmVhcmVyIHRva2VuLlxuICpcbiAqIEBwYXJhbSBvcmlnaW5hbFJlcSAtIFRoZSBiYXNlIHJlcXVlc3QgKGFscmVhZHkgaGFzIHdpdGhDcmVkZW50aWFscyBpZiBjb29raWVzIG1vZGUpXG4gKiBAcGFyYW0gdG9rZW5EZWxpdmVyeSAtICdjb29raWVzJyBvciAnanNvbidcbiAqIEBwYXJhbSBuZXdUb2tlbiAtIFRoZSBuZXcgYWNjZXNzIHRva2VuIChKU09OIG1vZGUgb25seSlcbiAqIEBwYXJhbSBjc3JmQ29uZmlnIC0gQ1NSRiBjb25maWd1cmF0aW9uIHRvIHJlLXJlYWQgdG9rZW4gZnJvbSBjb29raWVcbiAqIEByZXR1cm5zIFRoZSByZXF1ZXN0IHJlYWR5IGZvciByZXRyeSB3aXRoIGZyZXNoIGF1dGhcbiAqL1xuZnVuY3Rpb24gYnVpbGRSZXRyeVJlcXVlc3QoXG4gIG9yaWdpbmFsUmVxOiBIdHRwUmVxdWVzdDx1bmtub3duPixcbiAgdG9rZW5EZWxpdmVyeTogc3RyaW5nLFxuICBuZXdUb2tlbj86IHN0cmluZyxcbiAgY3NyZkNvbmZpZz86IHsgY29va2llTmFtZT86IHN0cmluZzsgaGVhZGVyTmFtZT86IHN0cmluZyB9LFxuKTogSHR0cFJlcXVlc3Q8dW5rbm93bj4ge1xuICBpZiAodG9rZW5EZWxpdmVyeSA9PT0gJ2pzb24nICYmIG5ld1Rva2VuICYmIG5ld1Rva2VuICE9PSAnc3VjY2VzcycpIHtcbiAgICByZXR1cm4gb3JpZ2luYWxSZXEuY2xvbmUoe1xuICAgICAgc2V0SGVhZGVyczogeyBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7bmV3VG9rZW59YCB9LFxuICAgIH0pO1xuICB9XG5cbiAgLy8gQ29va2llcyBtb2RlOiBCcm93c2VyIGF1dG9tYXRpY2FsbHkgc2VuZHMgdXBkYXRlZCBodHRwT25seSBjb29raWVzIChhY2Nlc3MvcmVmcmVzaCB0b2tlbnMpLlxuICAvLyBIb3dldmVyLCBDU1JGIHRva2VuIG11c3QgbWF0Y2ggdGhlIGNvb2tpZSB2YWx1ZSBhdCB0aGUgbW9tZW50IG9mIHJldHJ5LlxuICAvLyBXZSBBTFdBWVMgcmUtcmVhZCBmcm9tIGRvY3VtZW50LmNvb2tpZSBoZXJlICh1c2luZyBkZWZhdWx0cyB3aGVuIGNzcmZDb25maWdcbiAgLy8gaXMgbm90IHByb3ZpZGVkKSB0byBhdm9pZCBzdGFsZSBoZWFkZXIgdmFsdWVzIGFmdGVyIHJlZnJlc2ggb3IgYWNyb3NzIHRhYnMuXG4gIGlmICh0b2tlbkRlbGl2ZXJ5ID09PSAnY29va2llcycgJiYgWydQT1NUJywgJ1BVVCcsICdQQVRDSCcsICdERUxFVEUnXS5pbmNsdWRlcyhvcmlnaW5hbFJlcS5tZXRob2QpKSB7XG4gICAgY29uc3QgY3NyZkNvb2tpZU5hbWUgPSBjc3JmQ29uZmlnPy5jb29raWVOYW1lID8/ICduYXV0aF9jc3JmX3Rva2VuJztcbiAgICBjb25zdCBjc3JmSGVhZGVyTmFtZSA9IGNzcmZDb25maWc/LmhlYWRlck5hbWUgPz8gJ3gtY3NyZi10b2tlbic7XG4gICAgY29uc3QgZnJlc2hDc3JmVG9rZW4gPSBnZXRDc3JmVG9rZW4oY3NyZkNvb2tpZU5hbWUpO1xuXG4gICAgLy8gI3JlZ2lvbiBhZ2VudCBsb2dcbiAgICBmZXRjaCgnaHR0cDovLzEyNy4wLjAuMTo3MjQyL2luZ2VzdC85N2Y5ZmU1My02YThiLTQzZTItYWU5Yi00YjJkMGY3MjU4MTYnLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBsb2NhdGlvbjogJ2F1dGguaW50ZXJjZXB0b3IudHM6YnVpbGRSZXRyeVJlcXVlc3QnLFxuICAgICAgICBtZXNzYWdlOiAnSW5zaWRlIGJ1aWxkUmV0cnlSZXF1ZXN0IGNvb2tpZXMgYnJhbmNoJyxcbiAgICAgICAgZGF0YToge1xuICAgICAgICAgIG9yaWdpbmFsUmVxQm9keTogb3JpZ2luYWxSZXEuYm9keSxcbiAgICAgICAgICBvcmlnaW5hbFJlcUJvZHlUeXBlOiB0eXBlb2Ygb3JpZ2luYWxSZXEuYm9keSxcbiAgICAgICAgICBmcmVzaENzcmZUb2tlbjogZnJlc2hDc3JmVG9rZW4/LnN1YnN0cmluZygwLCA4KSxcbiAgICAgICAgICBtZXRob2Q6IG9yaWdpbmFsUmVxLm1ldGhvZCxcbiAgICAgICAgfSxcbiAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICBzZXNzaW9uSWQ6ICdkZWJ1Zy1zZXNzaW9uJyxcbiAgICAgICAgaHlwb3RoZXNpc0lkOiAnQycsXG4gICAgICB9KSxcbiAgICB9KS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgaWYgKGZyZXNoQ3NyZlRva2VuKSB7XG4gICAgICAvLyBDbG9uZSB3aXRoIGZyZXNoIENTUkYgdG9rZW4gaW4gaGVhZGVyXG4gICAgICBjb25zdCBjbG9uZWQgPSBvcmlnaW5hbFJlcS5jbG9uZSh7XG4gICAgICAgIHNldEhlYWRlcnM6IHsgW2NzcmZIZWFkZXJOYW1lXTogZnJlc2hDc3JmVG9rZW4gfSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyAjcmVnaW9uIGFnZW50IGxvZ1xuICAgICAgZmV0Y2goJ2h0dHA6Ly8xMjcuMC4wLjE6NzI0Mi9pbmdlc3QvOTdmOWZlNTMtNmE4Yi00M2UyLWFlOWItNGIyZDBmNzI1ODE2Jywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBsb2NhdGlvbjogJ2F1dGguaW50ZXJjZXB0b3IudHM6YnVpbGRSZXRyeVJlcXVlc3Q6YWZ0ZXJDbG9uZScsXG4gICAgICAgICAgbWVzc2FnZTogJ0FmdGVyIGNsb25lIHdpdGggc2V0SGVhZGVycycsXG4gICAgICAgICAgZGF0YTogeyBjbG9uZWRCb2R5OiBjbG9uZWQuYm9keSwgY2xvbmVkQm9keVR5cGU6IHR5cGVvZiBjbG9uZWQuYm9keSwgb3JpZ2luYWxCb2R5OiBvcmlnaW5hbFJlcS5ib2R5IH0sXG4gICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgIHNlc3Npb25JZDogJ2RlYnVnLXNlc3Npb24nLFxuICAgICAgICAgIGh5cG90aGVzaXNJZDogJ0QnLFxuICAgICAgICB9KSxcbiAgICAgIH0pLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgIC8vICNlbmRyZWdpb25cblxuICAgICAgcmV0dXJuIGNsb25lZDtcbiAgICB9XG4gIH1cblxuICAvLyBObyBjaGFuZ2VzIG5lZWRlZCAoR0VUIHJlcXVlc3Qgb3Igbm8gQ1NSRiB0b2tlbiBhdmFpbGFibGUpXG4gIHJldHVybiBvcmlnaW5hbFJlcTtcbn1cblxuLyoqXG4gKiBDbGFzcy1iYXNlZCBpbnRlcmNlcHRvciBmb3IgTmdNb2R1bGUgY29tcGF0aWJpbGl0eS5cbiAqL1xuZXhwb3J0IGNsYXNzIEF1dGhJbnRlcmNlcHRvciB7XG4gIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PHVua25vd24+LCBuZXh0OiBIdHRwSGFuZGxlckZuKSB7XG4gICAgcmV0dXJuIGF1dGhJbnRlcmNlcHRvcihyZXEsIG5leHQpO1xuICB9XG59XG4iXX0=
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5pbnRlcmNlcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvYXV0aC5pbnRlcmNlcHRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNwRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQWlELFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2pHLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdkQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFM0U7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFzQixDQUFDLEdBQXlCLEVBQUUsSUFBbUIsRUFBRSxFQUFFO0lBQ25HLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQzNDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNoQyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDeEMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM5QixNQUFNLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUVoRCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDZixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBRUQsT0FBTyw4QkFBOEIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztBQUMxRixDQUFDLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBQzFCLFNBQVMsQ0FBQyxHQUF5QixFQUFFLElBQW1CO1FBQ3RELE9BQU8sZUFBZSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIFBMQVRGT1JNX0lEIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBIdHRwSGFuZGxlckZuLCBIdHRwSW50ZXJjZXB0b3JGbiwgSHR0cFJlcXVlc3QsIEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgTkFVVEhfQ0xJRU5UX0NPTkZJRyB9IGZyb20gJy4uL25nbW9kdWxlL3Rva2Vucyc7XG5pbXBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4uL25nbW9kdWxlL2F1dGguc2VydmljZSc7XG5pbXBvcnQgeyBjcmVhdGVOQXV0aEF1dGhIdHRwSW50ZXJjZXB0b3IgfSBmcm9tICcuL2F1dGgtaW50ZXJjZXB0b3Iuc2hhcmVkJztcblxuLyoqXG4gKiBBbmd1bGFyIEhUVFAgaW50ZXJjZXB0b3IgZm9yIG5hdXRoLXRvb2xraXQuXG4gKlxuICogSGFuZGxlczpcbiAqIC0gQ29va2llcyBtb2RlOiB3aXRoQ3JlZGVudGlhbHMgKyBDU1JGIHRva2VucyArIHJlZnJlc2ggdmlhIFBPU1RcbiAqIC0gSlNPTiBtb2RlOiByZWZyZXNoIHZpYSBTREssIHJldHJ5IHdpdGggbmV3IHRva2VuXG4gKi9cbmV4cG9ydCBjb25zdCBhdXRoSW50ZXJjZXB0b3I6IEh0dHBJbnRlcmNlcHRvckZuID0gKHJlcTogSHR0cFJlcXVlc3Q8dW5rbm93bj4sIG5leHQ6IEh0dHBIYW5kbGVyRm4pID0+IHtcbiAgY29uc3QgY29uZmlnID0gaW5qZWN0KE5BVVRIX0NMSUVOVF9DT05GSUcpO1xuICBjb25zdCBodHRwID0gaW5qZWN0KEh0dHBDbGllbnQpO1xuICBjb25zdCBhdXRoU2VydmljZSA9IGluamVjdChBdXRoU2VydmljZSk7XG4gIGNvbnN0IHBsYXRmb3JtSWQgPSBpbmplY3QoUExBVEZPUk1fSUQpO1xuICBjb25zdCByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgY29uc3QgaXNCcm93c2VyID0gaXNQbGF0Zm9ybUJyb3dzZXIocGxhdGZvcm1JZCk7XG5cbiAgaWYgKCFpc0Jyb3dzZXIpIHtcbiAgICByZXR1cm4gbmV4dChyZXEpO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZU5BdXRoQXV0aEh0dHBJbnRlcmNlcHRvcih7IGNvbmZpZywgaHR0cCwgYXV0aFNlcnZpY2UsIHJvdXRlciwgbmV4dCwgcmVxIH0pO1xufTtcblxuLyoqXG4gKiBDbGFzcy1iYXNlZCBpbnRlcmNlcHRvciBmb3IgTmdNb2R1bGUgY29tcGF0aWJpbGl0eS5cbiAqL1xuZXhwb3J0IGNsYXNzIEF1dGhJbnRlcmNlcHRvciB7XG4gIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PHVua25vd24+LCBuZXh0OiBIdHRwSGFuZGxlckZuKSB7XG4gICAgcmV0dXJuIGF1dGhJbnRlcmNlcHRvcihyZXEsIG5leHQpO1xuICB9XG59XG4iXX0=
|