@arsedizioni/ars-utils 18.2.338 → 18.2.339

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.
@@ -4,7 +4,14 @@ import * as i0 from "@angular/core";
4
4
  export declare class ClipperAuthInterceptor implements HttpInterceptor {
5
5
  private clipperService;
6
6
  private dialogService;
7
+ private router;
7
8
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
9
+ /**
10
+ * Handle 401 error
11
+ * @param request : the request
12
+ * @param next : the http handler
13
+ */
14
+ private handle401Error;
8
15
  /**
9
16
  * Add token to request
10
17
  * @param request : the request
@@ -1,23 +1,22 @@
1
1
  import { OnDestroy, Signal } from '@angular/core';
2
2
  import { ApiResult, FolderTree, NameValueItem } from '@arsedizioni/ars-utils/core';
3
3
  import { LoginOAuthType } from '@arsedizioni/ars-utils/ui.oauth';
4
- import { Observable, Subscription } from 'rxjs';
4
+ import { Subscription } from 'rxjs';
5
5
  import { ClipperDashboard, ClipperDocumentInfo, ClipperDocumentStructure, ClipperDocumentUpdateStateParams, ClipperExportDocumentsParams, ClipperLoginInfo, ClipperLoginResult, ClipperModule, ClipperOTPInfo, ClipperQueryArsEventsParams, ClipperQueryArsEventsResult, ClipperReferencesSearchParams, ClipperSearchFacetsResult, ClipperSearchParams, ClipperSearchResult, ClipperSendDocumentsByEmailParams, ClipperTaxonomyParams, ClipperUserLink, ClipperUserSearch } from '../definitions';
6
6
  import * as i0 from "@angular/core";
7
7
  export declare class ClipperService implements OnDestroy {
8
- private readonly REFRESH_INTERVAL;
9
8
  private httpClient;
9
+ private broadcastServiceSubscription?;
10
10
  private broadcastService;
11
11
  private dialogService;
12
- private tokenRefreshInterval;
13
- private tokenRefreshTimer?;
14
- private tokenRefreshTimerSubscription?;
15
- private broadcastServiceSubscription?;
16
- private refreshing;
17
- private _loginInfo;
18
- get loginInfo(): ClipperLoginInfo;
19
12
  private _serviceUri;
20
13
  get serviceUri(): string;
14
+ private _accessRoute;
15
+ get accessRoute(): string | null;
16
+ private _errorRoute;
17
+ get errorRoute(): string | null;
18
+ private _loginInfo;
19
+ get loginInfo(): ClipperLoginInfo;
21
20
  readonly loggedIn: import("@angular/core").WritableSignal<boolean>;
22
21
  readonly loggingIn: import("@angular/core").WritableSignal<boolean>;
23
22
  readonly snapshot: import("@angular/core").WritableSignal<ClipperSearchResult>;
@@ -27,28 +26,19 @@ export declare class ClipperService implements OnDestroy {
27
26
  readonly bagTotal: Signal<number>;
28
27
  readonly visible: import("@angular/core").WritableSignal<boolean>;
29
28
  readonly supportsRS: import("@angular/core").WritableSignal<boolean>;
30
- constructor();
31
29
  ngOnDestroy(): void;
32
30
  /**
33
31
  * Initialize service
34
32
  * @param serviceUri : the service uri
35
- * @param tokenRefreshInterval : the token refresh interval
33
+ * @param accessRoute : the login route
34
+ * @param errorRoute : the optional route to navigate in case of 403 error
36
35
  */
37
- initialize(serviceUri?: string | null | undefined, tokenRefreshInterval?: number | null | undefined): void;
38
- /**
39
- * Set JWT token
40
- * @param token : token
41
- */
42
- private setToken;
36
+ initialize(serviceUri: string, accessRoute?: string | null | undefined, errorRoute?: string | null | undefined): void;
43
37
  /**
44
38
  * Set JWT tokens
45
- * @param valur : token
39
+ * @param value : the login result
46
40
  */
47
- private setToken2;
48
- /**
49
- * Enable JWT token auto refresh
50
- */
51
- private enableTokenRefresh;
41
+ private setToken;
52
42
  /**
53
43
  * Return current JWT token
54
44
  * @param refresh: true to get the refresh token. Default is false.
@@ -63,21 +53,11 @@ export declare class ClipperService implements OnDestroy {
63
53
  * @param oauthAccessToken: the optional OAuth2 access token
64
54
  * @returns: the login result
65
55
  */
66
- login(email?: string | null | undefined, password?: string | null | undefined, remember?: boolean | null | undefined, oauth?: LoginOAuthType | null | undefined, oauthAccessToken?: string | null | undefined): Observable<ApiResult<ClipperLoginResult>>;
67
- /**
68
- * Perform login
69
- * @param email: the optioanl email if using OAuth2
70
- * @parma password: the optional password if using OAuth2
71
- * @param remember: remember credentials
72
- * @param oauth: the optional open authentication supported
73
- * @param oauthAccessToken: the optional OAuth2 access token
74
- * @returns: the login result
75
- */
76
- login2(email?: string | null | undefined, password?: string | null | undefined, remember?: boolean | null | undefined, oauth?: LoginOAuthType | null | undefined, oauthAccessToken?: string | null | undefined): Observable<ApiResult<ClipperLoginResult>>;
56
+ login(email?: string | null | undefined, password?: string | null | undefined, remember?: boolean | null | undefined, oauth?: LoginOAuthType | null | undefined, oauthAccessToken?: string | null | undefined): import("rxjs").Observable<ApiResult<ClipperLoginResult>>;
77
57
  /**
78
58
  * Perform logout
79
59
  */
80
- logout(): Observable<any>;
60
+ logout(): import("rxjs").Observable<any>;
81
61
  /**
82
62
  * Reset login refresh timer and login state
83
63
  */
@@ -86,95 +66,91 @@ export declare class ClipperService implements OnDestroy {
86
66
  * Clear login data
87
67
  */
88
68
  clear(): void;
89
- /**
90
- * Perform token refresh
91
- */
92
- private refresh;
93
69
  /**
94
70
  * Perform token refresh
95
71
  */
96
- refresh2(): Observable<void>;
72
+ refresh(): import("rxjs").Observable<void>;
97
73
  /**
98
74
  * Get a new one time password
99
75
  * @param id: the optional repository id
100
76
  */
101
- newOTP(id: string): Observable<ApiResult<ClipperOTPInfo>>;
77
+ newOTP(id: string): import("rxjs").Observable<ApiResult<ClipperOTPInfo>>;
102
78
  /**
103
79
  * Load Ars events calendar
104
80
  */
105
- events(params: ClipperQueryArsEventsParams): Observable<ApiResult<ClipperQueryArsEventsResult>>;
81
+ events(params: ClipperQueryArsEventsParams): import("rxjs").Observable<ApiResult<ClipperQueryArsEventsResult>>;
106
82
  /**
107
83
  * Query documents
108
84
  */
109
- query(params: ClipperSearchParams): Observable<ApiResult<ClipperSearchResult>>;
85
+ query(params: ClipperSearchParams): import("rxjs").Observable<ApiResult<ClipperSearchResult>>;
110
86
  /**
111
87
  * Get facets for a query
112
88
  */
113
- queryFacets(params: ClipperSearchParams): Observable<ApiResult<ClipperSearchFacetsResult>>;
89
+ queryFacets(params: ClipperSearchParams): import("rxjs").Observable<ApiResult<ClipperSearchFacetsResult>>;
114
90
  /**
115
91
  * Update document state
116
92
  */
117
- updateState(params: ClipperDocumentUpdateStateParams): Observable<ApiResult<number>>;
93
+ updateState(params: ClipperDocumentUpdateStateParams): import("rxjs").Observable<ApiResult<number>>;
118
94
  /**
119
95
  * Export a document in pdf format
120
96
  */
121
- exportPdf(id: string): Observable<Blob>;
97
+ exportPdf(id: string): import("rxjs").Observable<Blob>;
122
98
  /**
123
99
  * Export document list (query or selected items) or export deadlines as ics
124
100
  */
125
- export(params: ClipperExportDocumentsParams): Observable<Blob>;
101
+ export(params: ClipperExportDocumentsParams): import("rxjs").Observable<Blob>;
126
102
  /**
127
103
  * Send documents link by email
128
104
  */
129
- sendTo(params: ClipperSendDocumentsByEmailParams): Observable<ApiResult<number>>;
105
+ sendTo(params: ClipperSendDocumentsByEmailParams): import("rxjs").Observable<ApiResult<number>>;
130
106
  /**
131
107
  * Display a page the full document report
132
108
  */
133
- report(id: string): Observable<Blob>;
109
+ report(id: string): import("rxjs").Observable<Blob>;
134
110
  /**
135
111
  * Get document comment
136
112
  */
137
- comment(id: string): Observable<ApiResult<string>>;
113
+ comment(id: string): import("rxjs").Observable<ApiResult<string>>;
138
114
  /**
139
115
  * Get document info
140
116
  */
141
- info(id: string): Observable<ApiResult<ClipperDocumentInfo>>;
117
+ info(id: string): import("rxjs").Observable<ApiResult<ClipperDocumentInfo>>;
142
118
  /**
143
119
  * Get document structure
144
120
  */
145
- index(id: string): Observable<ApiResult<ClipperDocumentStructure>>;
121
+ index(id: string): import("rxjs").Observable<ApiResult<ClipperDocumentStructure>>;
146
122
  /**
147
123
  * Get document last update
148
124
  */
149
- lastUpdate(id: string): Observable<ApiResult<string>>;
125
+ lastUpdate(id: string): import("rxjs").Observable<ApiResult<string>>;
150
126
  /**
151
127
  * Query document references
152
128
  */
153
- references(params: ClipperReferencesSearchParams): Observable<ApiResult<ClipperSearchResult>>;
129
+ references(params: ClipperReferencesSearchParams): import("rxjs").Observable<ApiResult<ClipperSearchResult>>;
154
130
  /**
155
131
  * Get facets for a document references
156
132
  */
157
- referencesFacets(params: ClipperReferencesSearchParams): Observable<ApiResult<ClipperSearchFacetsResult>>;
133
+ referencesFacets(params: ClipperReferencesSearchParams): import("rxjs").Observable<ApiResult<ClipperSearchFacetsResult>>;
158
134
  /**
159
135
  * Get document juris articles
160
136
  */
161
- jurisArticles(params: ClipperSearchParams): Observable<ApiResult<ClipperSearchResult>>;
137
+ jurisArticles(params: ClipperSearchParams): import("rxjs").Observable<ApiResult<ClipperSearchResult>>;
162
138
  /**
163
139
  * Get calendar snapshot based on the deadlines
164
140
  */
165
- calendarSnapshot(params: any): Observable<ApiResult<any>>;
141
+ calendarSnapshot(params: any): import("rxjs").Observable<ApiResult<any>>;
166
142
  /**
167
143
  * Retrieve the taxonomy
168
144
  */
169
- getTaxonomy(params?: ClipperTaxonomyParams | null): Observable<ApiResult<FolderTree>>;
145
+ getTaxonomy(params?: ClipperTaxonomyParams | null): import("rxjs").Observable<ApiResult<FolderTree>>;
170
146
  /**
171
147
  * Retrieve topics
172
148
  */
173
- getTopics(): Observable<ApiResult<NameValueItem<string>[]>>;
149
+ getTopics(): import("rxjs").Observable<ApiResult<NameValueItem<string>[]>>;
174
150
  /**
175
151
  * Retrieve tags
176
152
  */
177
- getTags(): Observable<ApiResult<NameValueItem<string>[]>>;
153
+ getTags(): import("rxjs").Observable<ApiResult<NameValueItem<string>[]>>;
178
154
  /**
179
155
  * Retrieve current dashboard
180
156
  */
@@ -189,12 +165,12 @@ export declare class ClipperService implements OnDestroy {
189
165
  * Save a user link
190
166
  * @param item: the user link
191
167
  */
192
- saveLink(item: ClipperUserLink): Observable<ApiResult<boolean>>;
168
+ saveLink(item: ClipperUserLink): import("rxjs").Observable<ApiResult<boolean>>;
193
169
  /**
194
170
  * Delete a user link
195
171
  * @param item: the user link
196
172
  */
197
- deleteLink(item: ClipperUserLink): Observable<ApiResult<boolean>>;
173
+ deleteLink(item: ClipperUserLink): import("rxjs").Observable<ApiResult<boolean>>;
198
174
  /**
199
175
  * Load working documents
200
176
  */
@@ -217,17 +193,17 @@ export declare class ClipperService implements OnDestroy {
217
193
  * Load working searches
218
194
  * @param: module: the module to load searches for
219
195
  */
220
- loadSearches(module: ClipperModule): Observable<ApiResult<ClipperUserSearch[]>>;
196
+ loadSearches(module: ClipperModule): import("rxjs").Observable<ApiResult<ClipperUserSearch[]>>;
221
197
  /**
222
198
  * Save a working search
223
199
  * @param documentIds : the document ids to add
224
200
  */
225
- saveSearch(params: ClipperUserSearch): Observable<ApiResult<ClipperUserSearch>>;
201
+ saveSearch(params: ClipperUserSearch): import("rxjs").Observable<ApiResult<ClipperUserSearch>>;
226
202
  /**
227
203
  * Remove one working search
228
204
  * @param id : the id to remove
229
205
  */
230
- deleteSearch(id: number): Observable<ApiResult<number>>;
206
+ deleteSearch(id: number): import("rxjs").Observable<ApiResult<number>>;
231
207
  static ɵfac: i0.ɵɵFactoryDeclaration<ClipperService, never>;
232
208
  static ɵprov: i0.ɵɵInjectableDeclaration<ClipperService>;
233
209
  }
@@ -1,49 +1,51 @@
1
+ import { HttpErrorResponse } from '@angular/common/http';
1
2
  import { Injectable, inject } from '@angular/core';
3
+ import { Router } from '@angular/router';
2
4
  import { DialogService } from '@arsedizioni/ars-utils/ui';
3
- import { catchError, throwError } from 'rxjs';
5
+ import { catchError, switchMap, throwError } from 'rxjs';
4
6
  import { ClipperService } from '../services/clipper.service';
5
7
  import * as i0 from "@angular/core";
6
8
  export class ClipperAuthInterceptor {
7
9
  constructor() {
8
10
  this.clipperService = inject(ClipperService);
9
11
  this.dialogService = inject(DialogService);
12
+ this.router = inject(Router);
10
13
  }
11
14
  intercept(request, next) {
12
15
  if (request.url.startsWith(this.clipperService.serviceUri)) {
13
16
  request = request.clone({ withCredentials: true });
14
17
  return next.handle(this.addTokenToRequest(request))
15
- .pipe(catchError((err) => {
16
- // Get the message
17
- let message = err.error?.message || err.message || "Impossibile eseguire l'operazione richiesta.";
18
- let invalidSession = err.status === 401;
19
- switch (err.status) {
20
- case 0:
21
- case 500:
22
- case 502:
23
- case 503:
24
- case 504:
25
- message = null; // No messages
26
- break;
27
- case 403:
28
- message = "<p>Non hai i permessi necessari per eseguire l'operazione richiesta.</p>";
29
- break;
30
- default:
31
- message = '<p>' + message.replaceAll('\r\n', '</p><p>') + '</p>';
32
- break;
18
+ .pipe(catchError(error => {
19
+ if (error instanceof HttpErrorResponse &&
20
+ !request.url.includes(this.clipperService.accessRoute) &&
21
+ error.status === 401) {
22
+ return this.handle401Error(request, next);
33
23
  }
34
- // Display message
35
- if (message) {
36
- setTimeout(() => {
37
- this.dialogService.error(message, null, 'Errore in Clipper', 'Ok', 500, invalidSession ? 5000 : null).afterClosed().subscribe(() => {
38
- if (invalidSession) {
39
- if (this.clipperService.loggedIn()) {
40
- this.clipperService.reset();
41
- }
42
- }
43
- });
44
- }, 250);
24
+ // Show a message
25
+ this.dialogService.clearBusy();
26
+ this.dialogService.error('<p>' + (error.error?.message ?? error.message ?? "Impossibile eseguire l'operazione richiesta.").replaceAll('\r\n', '</p><p>') + '</p>', null, 'Errore in Clipper');
27
+ return throwError(() => error);
28
+ }));
29
+ }
30
+ return next.handle(request);
31
+ }
32
+ /**
33
+ * Handle 401 error
34
+ * @param request : the request
35
+ * @param next : the http handler
36
+ */
37
+ handle401Error(request, next) {
38
+ if (this.clipperService.loggedIn()) {
39
+ return this.clipperService.refresh().pipe(switchMap(() => {
40
+ return next.handle(this.addTokenToRequest(request));
41
+ }), catchError(error => {
42
+ if (error instanceof HttpErrorResponse && error.status === 403) {
43
+ this.clipperService.clear();
44
+ if (this.clipperService.errorRoute) {
45
+ this.router.navigateByUrl(this.clipperService.errorRoute);
46
+ }
45
47
  }
46
- return throwError(() => err);
48
+ return throwError(() => error);
47
49
  }));
48
50
  }
49
51
  return next.handle(request);
@@ -74,4 +76,4 @@ export class ClipperAuthInterceptor {
74
76
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: ClipperAuthInterceptor, decorators: [{
75
77
  type: Injectable
76
78
  }] });
77
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5pbnRlcmNlcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fycy11dGlscy9jbGlwcGVyLmNvbW1vbi9jb21tb24vaW50ZXJjZXB0b3JzL2F1dGguaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFBYyxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7QUFHN0QsTUFBTSxPQUFPLHNCQUFzQjtJQURuQztRQUVVLG1CQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3hDLGtCQUFhLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0tBd0UvQztJQXRFQyxTQUFTLENBQ1AsT0FBeUIsRUFDekIsSUFBaUI7UUFFakIsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDM0QsT0FBTyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNuRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2lCQUNoRCxJQUFJLENBQ0gsVUFBVSxDQUFDLENBQUMsR0FBUSxFQUFFLEVBQUU7Z0JBQ3RCLGtCQUFrQjtnQkFDbEIsSUFBSSxPQUFPLEdBQUcsR0FBRyxDQUFDLEtBQUssRUFBRSxPQUFPLElBQUksR0FBRyxDQUFDLE9BQU8sSUFBSSw4Q0FBOEMsQ0FBQztnQkFDbEcsSUFBSSxjQUFjLEdBQUcsR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLENBQUM7Z0JBQ3hDLFFBQVEsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUNuQixLQUFLLENBQUMsQ0FBQztvQkFDUCxLQUFLLEdBQUcsQ0FBQztvQkFDVCxLQUFLLEdBQUcsQ0FBQztvQkFDVCxLQUFLLEdBQUcsQ0FBQztvQkFDVCxLQUFLLEdBQUc7d0JBQ04sT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLGNBQWM7d0JBQzlCLE1BQU07b0JBQ1IsS0FBSyxHQUFHO3dCQUNOLE9BQU8sR0FBRywwRUFBMEUsQ0FBQzt3QkFDckYsTUFBTTtvQkFDUjt3QkFDRSxPQUFPLEdBQUcsS0FBSyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxHQUFHLE1BQU0sQ0FBQzt3QkFDakUsTUFBTTtnQkFDVixDQUFDO2dCQUNELGtCQUFrQjtnQkFDbEIsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixVQUFVLENBQUMsR0FBRyxFQUFFO3dCQUNkLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTs0QkFDakksSUFBSSxjQUFjLEVBQUUsQ0FBQztnQ0FDbkIsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7b0NBQ25DLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLENBQUM7Z0NBQzlCLENBQUM7NEJBQ0gsQ0FBQzt3QkFDSCxDQUFDLENBQUMsQ0FBQztvQkFDTCxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ1YsQ0FBQztnQkFFRCxPQUFPLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMvQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ1YsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBR0Q7Ozs7T0FJRztJQUNLLGlCQUFpQixDQUN2QixPQUF5QixFQUN6QixRQUFnQixJQUFJO1FBRXBCLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQzNELElBQUksQ0FBQyxLQUFLO2dCQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25ELElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ1YsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDO29CQUNuQixVQUFVLEVBQUU7d0JBQ1YsYUFBYSxFQUFFLFNBQVMsR0FBRyxLQUFLO3dCQUNoQyxhQUFhLEVBQUUsYUFBYTtxQkFDN0I7aUJBQ0YsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDOzhHQXhFVSxzQkFBc0I7a0hBQXRCLHNCQUFzQjs7MkZBQXRCLHNCQUFzQjtrQkFEbEMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBFdmVudCwgSHR0cEhhbmRsZXIsIEh0dHBJbnRlcmNlcHRvciwgSHR0cFJlcXVlc3QgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEaWFsb2dTZXJ2aWNlIH0gZnJvbSAnQGFyc2VkaXppb25pL2Fycy11dGlscy91aSc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIGNhdGNoRXJyb3IsIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgQ2xpcHBlclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9jbGlwcGVyLnNlcnZpY2UnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgQ2xpcHBlckF1dGhJbnRlcmNlcHRvciBpbXBsZW1lbnRzIEh0dHBJbnRlcmNlcHRvciB7XHJcbiAgcHJpdmF0ZSBjbGlwcGVyU2VydmljZSA9IGluamVjdChDbGlwcGVyU2VydmljZSk7XHJcbiAgcHJpdmF0ZSBkaWFsb2dTZXJ2aWNlID0gaW5qZWN0KERpYWxvZ1NlcnZpY2UpO1xyXG5cclxuICBpbnRlcmNlcHQoXHJcbiAgICByZXF1ZXN0OiBIdHRwUmVxdWVzdDxhbnk+LFxyXG4gICAgbmV4dDogSHR0cEhhbmRsZXJcclxuICApOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+PiB7XHJcbiAgICBpZiAocmVxdWVzdC51cmwuc3RhcnRzV2l0aCh0aGlzLmNsaXBwZXJTZXJ2aWNlLnNlcnZpY2VVcmkpKSB7XHJcbiAgICAgIHJlcXVlc3QgPSByZXF1ZXN0LmNsb25lKHsgd2l0aENyZWRlbnRpYWxzOiB0cnVlIH0pO1xyXG4gICAgICByZXR1cm4gbmV4dC5oYW5kbGUodGhpcy5hZGRUb2tlblRvUmVxdWVzdChyZXF1ZXN0KSlcclxuICAgICAgICAucGlwZShcclxuICAgICAgICAgIGNhdGNoRXJyb3IoKGVycjogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIEdldCB0aGUgbWVzc2FnZVxyXG4gICAgICAgICAgICBsZXQgbWVzc2FnZSA9IGVyci5lcnJvcj8ubWVzc2FnZSB8fCBlcnIubWVzc2FnZSB8fCBcIkltcG9zc2liaWxlIGVzZWd1aXJlIGwnb3BlcmF6aW9uZSByaWNoaWVzdGEuXCI7XHJcbiAgICAgICAgICAgIGxldCBpbnZhbGlkU2Vzc2lvbiA9IGVyci5zdGF0dXMgPT09IDQwMTtcclxuICAgICAgICAgICAgc3dpdGNoIChlcnIuc3RhdHVzKSB7XHJcbiAgICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgIGNhc2UgNTAwOlxyXG4gICAgICAgICAgICAgIGNhc2UgNTAyOlxyXG4gICAgICAgICAgICAgIGNhc2UgNTAzOlxyXG4gICAgICAgICAgICAgIGNhc2UgNTA0OlxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IG51bGw7IC8vIE5vIG1lc3NhZ2VzXHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICBjYXNlIDQwMzpcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBcIjxwPk5vbiBoYWkgaSBwZXJtZXNzaSBuZWNlc3NhcmkgcGVyIGVzZWd1aXJlIGwnb3BlcmF6aW9uZSByaWNoaWVzdGEuPC9wPlwiO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSAnPHA+JyArIG1lc3NhZ2UucmVwbGFjZUFsbCgnXFxyXFxuJywgJzwvcD48cD4nKSArICc8L3A+JztcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIERpc3BsYXkgbWVzc2FnZVxyXG4gICAgICAgICAgICBpZiAobWVzc2FnZSkge1xyXG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kaWFsb2dTZXJ2aWNlLmVycm9yKG1lc3NhZ2UsIG51bGwsICdFcnJvcmUgaW4gQ2xpcHBlcicsICdPaycsIDUwMCwgaW52YWxpZFNlc3Npb24gPyA1MDAwIDogbnVsbCkuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICBpZiAoaW52YWxpZFNlc3Npb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jbGlwcGVyU2VydmljZS5sb2dnZWRJbigpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsaXBwZXJTZXJ2aWNlLnJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICB9LCAyNTApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnIpO1xyXG4gICAgICAgICAgfSkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5leHQuaGFuZGxlKHJlcXVlc3QpO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCB0b2tlbiB0byByZXF1ZXN0XHJcbiAgICogQHBhcmFtIHJlcXVlc3QgOiB0aGUgcmVxdWVzdFxyXG4gICAqIEBwYXJhbSB0b2tlbjogdGhlIHRva2VuIG9yIG51bGwgdG8gdXNlIGN1cnJlM250XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhZGRUb2tlblRvUmVxdWVzdChcclxuICAgIHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PGFueT4sXHJcbiAgICB0b2tlbjogc3RyaW5nID0gbnVsbFxyXG4gICk6IEh0dHBSZXF1ZXN0PGFueT4ge1xyXG4gICAgaWYgKHJlcXVlc3QudXJsLnN0YXJ0c1dpdGgodGhpcy5jbGlwcGVyU2VydmljZS5zZXJ2aWNlVXJpKSkge1xyXG4gICAgICBpZiAoIXRva2VuKSB0b2tlbiA9IHRoaXMuY2xpcHBlclNlcnZpY2UuZ2V0VG9rZW4oKTtcclxuICAgICAgaWYgKHRva2VuKSB7XHJcbiAgICAgICAgcmV0dXJuIHJlcXVlc3QuY2xvbmUoe1xyXG4gICAgICAgICAgc2V0SGVhZGVyczoge1xyXG4gICAgICAgICAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyB0b2tlbixcclxuICAgICAgICAgICAgJ25nc3ctYnlwYXNzJzogJ25nc3ctYnlwYXNzJ1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlcXVlc3Q7XHJcbiAgfVxyXG5cclxufVxyXG4iXX0=
79
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5pbnRlcmNlcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fycy11dGlscy9jbGlwcGVyLmNvbW1vbi9jb21tb24vaW50ZXJjZXB0b3JzL2F1dGguaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUF3RCxNQUFNLHNCQUFzQixDQUFDO0FBQy9HLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUFjLFVBQVUsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7QUFHN0QsTUFBTSxPQUFPLHNCQUFzQjtJQURuQztRQUVVLG1CQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3hDLGtCQUFhLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3RDLFdBQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7S0ErRWpDO0lBNUVDLFNBQVMsQ0FDUCxPQUF5QixFQUN6QixJQUFpQjtRQUVqQixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUMzRCxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ25ELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQ2hELElBQUks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dCI6WyJpbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSwgSHR0cEV2ZW50LCBIdHRwSGFuZGxlciwgSHR0cEludGVyY2VwdG9yLCBIdHRwUmVxdWVzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcbmltcG9ydCB7IERpYWxvZ1NlcnZpY2UgfSBmcm9tICdAYXJzZWRpemlvbmkvYXJzLXV0aWxzL3VpJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgY2F0Y2hFcnJvciwgc3dpdGNoTWFwLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IENsaXBwZXJTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvY2xpcHBlci5zZXJ2aWNlJztcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIENsaXBwZXJBdXRoSW50ZXJjZXB0b3IgaW1wbGVtZW50cyBIdHRwSW50ZXJjZXB0b3Ige1xyXG4gIHByaXZhdGUgY2xpcHBlclNlcnZpY2UgPSBpbmplY3QoQ2xpcHBlclNlcnZpY2UpO1xyXG4gIHByaXZhdGUgZGlhbG9nU2VydmljZSA9IGluamVjdChEaWFsb2dTZXJ2aWNlKTtcclxuICBwcml2YXRlIHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xyXG5cclxuXHJcbiAgaW50ZXJjZXB0KFxyXG4gICAgcmVxdWVzdDogSHR0cFJlcXVlc3Q8YW55PixcclxuICAgIG5leHQ6IEh0dHBIYW5kbGVyXHJcbiAgKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xyXG4gICAgaWYgKHJlcXVlc3QudXJsLnN0YXJ0c1dpdGgodGhpcy5jbGlwcGVyU2VydmljZS5zZXJ2aWNlVXJpKSkge1xyXG4gICAgICByZXF1ZXN0ID0gcmVxdWVzdC5jbG9uZSh7IHdpdGhDcmVkZW50aWFsczogdHJ1ZSB9KTtcclxuICAgICAgcmV0dXJuIG5leHQuaGFuZGxlKHRoaXMuYWRkVG9rZW5Ub1JlcXVlc3QocmVxdWVzdCkpXHJcbiAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcclxuICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgIGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UgJiZcclxuICAgICAgICAgICAgICAhcmVxdWVzdC51cmwuaW5jbHVkZXModGhpcy5jbGlwcGVyU2VydmljZS5hY2Nlc3NSb3V0ZSkgJiZcclxuICAgICAgICAgICAgICBlcnJvci5zdGF0dXMgPT09IDQwMVxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGU0MDFFcnJvcihyZXF1ZXN0LCBuZXh0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBTaG93IGEgbWVzc2FnZVxyXG4gICAgICAgICAgICB0aGlzLmRpYWxvZ1NlcnZpY2UuY2xlYXJCdXN5KCk7XHJcbiAgICAgICAgICAgIHRoaXMuZGlhbG9nU2VydmljZS5lcnJvcihcclxuICAgICAgICAgICAgICAnPHA+JyArIChlcnJvci5lcnJvcj8ubWVzc2FnZSA/PyBlcnJvci5tZXNzYWdlID8/IFwiSW1wb3NzaWJpbGUgZXNlZ3VpcmUgbCdvcGVyYXppb25lIHJpY2hpZXN0YS5cIikucmVwbGFjZUFsbCgnXFxyXFxuJywgJzwvcD48cD4nKSArICc8L3A+JyxcclxuICAgICAgICAgICAgICBudWxsLFxyXG4gICAgICAgICAgICAgICdFcnJvcmUgaW4gQ2xpcHBlcicpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XHJcbiAgICAgICAgICB9KSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV4dC5oYW5kbGUocmVxdWVzdCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgNDAxIGVycm9yXHJcbiAgICogQHBhcmFtIHJlcXVlc3QgOiB0aGUgcmVxdWVzdFxyXG4gICAqIEBwYXJhbSBuZXh0IDogdGhlIGh0dHAgaGFuZGxlclxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlNDAxRXJyb3IocmVxdWVzdDogSHR0cFJlcXVlc3Q8YW55PiwgbmV4dDogSHR0cEhhbmRsZXIpIHtcclxuICAgIGlmICh0aGlzLmNsaXBwZXJTZXJ2aWNlLmxvZ2dlZEluKCkpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY2xpcHBlclNlcnZpY2UucmVmcmVzaCgpLnBpcGUoXHJcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcclxuICAgICAgICAgIHJldHVybiBuZXh0LmhhbmRsZSh0aGlzLmFkZFRva2VuVG9SZXF1ZXN0KHJlcXVlc3QpKTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcclxuICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlICYmIGVycm9yLnN0YXR1cyA9PT0gNDAzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xpcHBlclNlcnZpY2UuY2xlYXIoKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY2xpcHBlclNlcnZpY2UuZXJyb3JSb3V0ZSkge1xyXG4gICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwodGhpcy5jbGlwcGVyU2VydmljZS5lcnJvclJvdXRlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV4dC5oYW5kbGUocmVxdWVzdCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGQgdG9rZW4gdG8gcmVxdWVzdFxyXG4gICAqIEBwYXJhbSByZXF1ZXN0IDogdGhlIHJlcXVlc3RcclxuICAgKiBAcGFyYW0gdG9rZW46IHRoZSB0b2tlbiBvciBudWxsIHRvIHVzZSBjdXJyZTNudFxyXG4gICAqL1xyXG4gIHByaXZhdGUgYWRkVG9rZW5Ub1JlcXVlc3QoXHJcbiAgICByZXF1ZXN0OiBIdHRwUmVxdWVzdDxhbnk+LFxyXG4gICAgdG9rZW46IHN0cmluZyB8IG51bGwgPSBudWxsXHJcbiAgKTogSHR0cFJlcXVlc3Q8YW55PiB7XHJcbiAgICBpZiAocmVxdWVzdC51cmwuc3RhcnRzV2l0aCh0aGlzLmNsaXBwZXJTZXJ2aWNlLnNlcnZpY2VVcmkpKSB7XHJcbiAgICAgIGlmICghdG9rZW4pIHRva2VuID0gdGhpcy5jbGlwcGVyU2VydmljZS5nZXRUb2tlbigpO1xyXG4gICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICByZXR1cm4gcmVxdWVzdC5jbG9uZSh7XHJcbiAgICAgICAgICBzZXRIZWFkZXJzOiB7XHJcbiAgICAgICAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIHRva2VuLFxyXG4gICAgICAgICAgICAnbmdzdy1ieXBhc3MnOiAnbmdzdy1ieXBhc3MnXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVxdWVzdDtcclxuICB9XHJcblxyXG59XHJcbiJdfQ==