http-request-manager 18.4.9 → 18.5.0
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/fesm2022/http-request-manager.mjs +48 -49
- package/fesm2022/http-request-manager.mjs.map +1 -1
- package/http-request-manager-18.5.0.tgz +0 -0
- package/package.json +3 -5
- package/types/http-request-manager.d.ts +1731 -0
- package/esm2022/http-request-manager.mjs +0 -5
- package/esm2022/lib/http-request-manager.module.mjs +0 -173
- package/esm2022/lib/http-request-services-demo/database-data-demo/database-data-demo.component.mjs +0 -152
- package/esm2022/lib/http-request-services-demo/http-request-services-demo.component.mjs +0 -63
- package/esm2022/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.mjs +0 -173
- package/esm2022/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.mjs +0 -184
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.mjs +0 -80
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.mjs +0 -42
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.mjs +0 -88
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.mjs +0 -11
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.mjs +0 -29
- package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.mjs +0 -9
- package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.mjs +0 -12
- package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.mjs +0 -14
- package/esm2022/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.mjs +0 -325
- package/esm2022/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.mjs +0 -277
- package/esm2022/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.mjs +0 -64
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/components/services/state-data-request.service.mjs +0 -92
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.mjs +0 -14
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.mjs +0 -57
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.mjs +0 -107
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.mjs +0 -14
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/models/oidc-client.model.mjs +0 -13
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/models/user-data.model.mjs +0 -12
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.mjs +0 -114
- package/esm2022/lib/http-request-services-demo/request-manager-ws-demo/services/state-request-demo.service.mjs +0 -71
- package/esm2022/lib/http-request-services-demo/request-signals-manager-demo/models/sample-ai-prompt.mjs +0 -9
- package/esm2022/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-info.mjs +0 -12
- package/esm2022/lib/http-request-services-demo/request-signals-manager-demo/models/sample-mapper-client-info.mjs +0 -14
- package/esm2022/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.mjs +0 -336
- package/esm2022/lib/http-request-services-demo/store-state-manager-demo/models/settings.model.mjs +0 -12
- package/esm2022/lib/http-request-services-demo/store-state-manager-demo/services/settings-state.service.mjs +0 -36
- package/esm2022/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.mjs +0 -34
- package/esm2022/lib/index.mjs +0 -4
- package/esm2022/lib/interceptors/credentials.interceptor.mjs +0 -14
- package/esm2022/lib/interceptors/index.mjs +0 -6
- package/esm2022/lib/interceptors/models/error-settings.model.mjs +0 -10
- package/esm2022/lib/interceptors/models/index.mjs +0 -2
- package/esm2022/lib/interceptors/proxy-debugger.interceptor.mjs +0 -47
- package/esm2022/lib/interceptors/request-error.interceptor.mjs +0 -49
- package/esm2022/lib/interceptors/request-header.interceptor.mjs +0 -41
- package/esm2022/lib/models/config-http-options.model.mjs +0 -18
- package/esm2022/lib/models/config-local-storage-options.model.mjs +0 -12
- package/esm2022/lib/models/config-options.model.mjs +0 -12
- package/esm2022/lib/models/config-token.model.mjs +0 -8
- package/esm2022/lib/models/data-type.enum.mjs +0 -7
- package/esm2022/lib/models/database-storage.model.mjs +0 -12
- package/esm2022/lib/models/index.mjs +0 -8
- package/esm2022/lib/models/retry-options.model.mjs +0 -10
- package/esm2022/lib/services/database-manager-service/database.manager.service.mjs +0 -171
- package/esm2022/lib/services/database-manager-service/db.storage.service.mjs +0 -183
- package/esm2022/lib/services/database-manager-service/index.mjs +0 -4
- package/esm2022/lib/services/database-manager-service/models/index.mjs +0 -2
- package/esm2022/lib/services/database-manager-service/models/table-schema.mjs +0 -19
- package/esm2022/lib/services/index.mjs +0 -9
- package/esm2022/lib/services/local-storage-manager-service/index.mjs +0 -4
- package/esm2022/lib/services/local-storage-manager-service/local-storage-manager.service.mjs +0 -308
- package/esm2022/lib/services/local-storage-manager-service/local-storage-signals-manager.service.mjs +0 -277
- package/esm2022/lib/services/local-storage-manager-service/models/global-store-options.model.mjs +0 -13
- package/esm2022/lib/services/local-storage-manager-service/models/index.mjs +0 -6
- package/esm2022/lib/services/local-storage-manager-service/models/setting-options.model.mjs +0 -17
- package/esm2022/lib/services/local-storage-manager-service/models/storage-data.model.mjs +0 -10
- package/esm2022/lib/services/local-storage-manager-service/models/storage-option.model.mjs +0 -13
- package/esm2022/lib/services/local-storage-manager-service/models/storage-type.enum.mjs +0 -7
- package/esm2022/lib/services/request-manager-services/http-manager-signals.service.mjs +0 -199
- package/esm2022/lib/services/request-manager-services/http-manager.service.mjs +0 -207
- package/esm2022/lib/services/request-manager-services/index.mjs +0 -7
- package/esm2022/lib/services/request-manager-services/request-signals.service.mjs +0 -170
- package/esm2022/lib/services/request-manager-services/request.service.mjs +0 -195
- package/esm2022/lib/services/request-manager-services/rxjs-operators/countdown.mjs +0 -9
- package/esm2022/lib/services/request-manager-services/rxjs-operators/delay-retry.mjs +0 -10
- package/esm2022/lib/services/request-manager-services/rxjs-operators/index.mjs +0 -5
- package/esm2022/lib/services/request-manager-services/rxjs-operators/request-polling.mjs +0 -33
- package/esm2022/lib/services/request-manager-services/rxjs-operators/request-streaming.mjs +0 -19
- package/esm2022/lib/services/request-manager-state-service/http-manager-state.store.mjs +0 -594
- package/esm2022/lib/services/request-manager-state-service/index.mjs +0 -3
- package/esm2022/lib/services/request-manager-state-service/models/api-request.model.mjs +0 -22
- package/esm2022/lib/services/request-manager-state-service/models/index.mjs +0 -5
- package/esm2022/lib/services/request-manager-state-service/models/request-options.model.mjs +0 -10
- package/esm2022/lib/services/request-manager-state-service/models/ws-options.model.mjs +0 -15
- package/esm2022/lib/services/request-manager-state-service/models/ws-user.model.mjs +0 -10
- package/esm2022/lib/services/store-state-manager-service/index.mjs +0 -3
- package/esm2022/lib/services/store-state-manager-service/models/index.mjs +0 -2
- package/esm2022/lib/services/store-state-manager-service/models/state-storage-options.model.mjs +0 -12
- package/esm2022/lib/services/store-state-manager-service/store-state-manager.service.mjs +0 -71
- package/esm2022/lib/services/utils/app.service.mjs +0 -26
- package/esm2022/lib/services/utils/encryption/asymmetrical-encryption.service.mjs +0 -186
- package/esm2022/lib/services/utils/encryption/encryption-test.service.mjs +0 -35
- package/esm2022/lib/services/utils/encryption/index.mjs +0 -5
- package/esm2022/lib/services/utils/encryption/random.mjs +0 -64
- package/esm2022/lib/services/utils/encryption/symmetrical-encryption.service.mjs +0 -77
- package/esm2022/lib/services/utils/headers.service.mjs +0 -21
- package/esm2022/lib/services/utils/index.mjs +0 -7
- package/esm2022/lib/services/utils/object-merger.service.mjs +0 -70
- package/esm2022/lib/services/utils/path-query.service.mjs +0 -54
- package/esm2022/lib/services/utils/utils.service.mjs +0 -155
- package/esm2022/lib/services/ws-manager-service/index.mjs +0 -3
- package/esm2022/lib/services/ws-manager-service/models/channel-info.model.mjs +0 -10
- package/esm2022/lib/services/ws-manager-service/models/channel-notification.model.mjs +0 -14
- package/esm2022/lib/services/ws-manager-service/models/communication-type.enum.mjs +0 -7
- package/esm2022/lib/services/ws-manager-service/models/index.mjs +0 -5
- package/esm2022/lib/services/ws-manager-service/models/user-message.model.mjs +0 -12
- package/esm2022/lib/services/ws-manager-service/services/index.mjs +0 -2
- package/esm2022/lib/services/ws-manager-service/services/websocket.service.mjs +0 -187
- package/esm2022/public-api.mjs +0 -11
- package/http-request-manager-18.4.9.tgz +0 -0
- package/index.d.ts +0 -5
- package/lib/http-request-manager.module.d.ts +0 -43
- package/lib/http-request-services-demo/database-data-demo/database-data-demo.component.d.ts +0 -46
- package/lib/http-request-services-demo/http-request-services-demo.component.d.ts +0 -39
- package/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.d.ts +0 -56
- package/lib/http-request-services-demo/local-storage-signals-demo/local-storage-signals-demo.component.d.ts +0 -55
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.d.ts +0 -26
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.d.ts +0 -13
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.d.ts +0 -27
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.d.ts +0 -12
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.d.ts +0 -16
- package/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.d.ts +0 -8
- package/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.d.ts +0 -14
- package/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.d.ts +0 -14
- package/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.d.ts +0 -110
- package/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.d.ts +0 -124
- package/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.d.ts +0 -15
- package/lib/http-request-services-demo/request-manager-ws-demo/components/services/state-data-request.service.d.ts +0 -15
- package/lib/http-request-services-demo/request-manager-ws-demo/components/ws-ai-messaging/ws-ai-messaging.component.d.ts +0 -8
- package/lib/http-request-services-demo/request-manager-ws-demo/components/ws-data-control/ws-data-control.component.d.ts +0 -20
- package/lib/http-request-services-demo/request-manager-ws-demo/components/ws-messaging/ws-messaging.component.d.ts +0 -33
- package/lib/http-request-services-demo/request-manager-ws-demo/components/ws-notifications/ws-notifications.component.d.ts +0 -8
- package/lib/http-request-services-demo/request-manager-ws-demo/models/oidc-client.model.d.ts +0 -16
- package/lib/http-request-services-demo/request-manager-ws-demo/models/user-data.model.d.ts +0 -12
- package/lib/http-request-services-demo/request-manager-ws-demo/request-manager-ws-demo.component.d.ts +0 -40
- package/lib/http-request-services-demo/request-manager-ws-demo/services/state-request-demo.service.d.ts +0 -11
- package/lib/http-request-services-demo/request-signals-manager-demo/models/sample-ai-prompt.d.ts +0 -8
- package/lib/http-request-services-demo/request-signals-manager-demo/models/sample-client-info.d.ts +0 -14
- package/lib/http-request-services-demo/request-signals-manager-demo/models/sample-mapper-client-info.d.ts +0 -14
- package/lib/http-request-services-demo/request-signals-manager-demo/request-signals-manager-demo.component.d.ts +0 -106
- package/lib/http-request-services-demo/store-state-manager-demo/models/settings.model.d.ts +0 -14
- package/lib/http-request-services-demo/store-state-manager-demo/services/settings-state.service.d.ts +0 -11
- package/lib/http-request-services-demo/store-state-manager-demo/store-state-manager-demo.component.d.ts +0 -14
- package/lib/index.d.ts +0 -3
- package/lib/interceptors/credentials.interceptor.d.ts +0 -8
- package/lib/interceptors/index.d.ts +0 -5
- package/lib/interceptors/models/error-settings.model.d.ts +0 -10
- package/lib/interceptors/models/index.d.ts +0 -1
- package/lib/interceptors/proxy-debugger.interceptor.d.ts +0 -12
- package/lib/interceptors/request-error.interceptor.d.ts +0 -10
- package/lib/interceptors/request-header.interceptor.d.ts +0 -15
- package/lib/models/config-http-options.model.d.ts +0 -21
- package/lib/models/config-local-storage-options.model.d.ts +0 -13
- package/lib/models/config-options.model.d.ts +0 -12
- package/lib/models/config-token.model.d.ts +0 -8
- package/lib/models/data-type.enum.d.ts +0 -5
- package/lib/models/database-storage.model.d.ts +0 -10
- package/lib/models/index.d.ts +0 -7
- package/lib/models/retry-options.model.d.ts +0 -10
- package/lib/services/database-manager-service/database.manager.service.d.ts +0 -33
- package/lib/services/database-manager-service/db.storage.service.d.ts +0 -26
- package/lib/services/database-manager-service/index.d.ts +0 -3
- package/lib/services/database-manager-service/models/index.d.ts +0 -1
- package/lib/services/database-manager-service/models/table-schema.d.ts +0 -11
- package/lib/services/index.d.ts +0 -7
- package/lib/services/local-storage-manager-service/index.d.ts +0 -3
- package/lib/services/local-storage-manager-service/local-storage-manager.service.d.ts +0 -86
- package/lib/services/local-storage-manager-service/local-storage-signals-manager.service.d.ts +0 -64
- package/lib/services/local-storage-manager-service/models/global-store-options.model.d.ts +0 -15
- package/lib/services/local-storage-manager-service/models/index.d.ts +0 -5
- package/lib/services/local-storage-manager-service/models/setting-options.model.d.ts +0 -15
- package/lib/services/local-storage-manager-service/models/storage-data.model.d.ts +0 -10
- package/lib/services/local-storage-manager-service/models/storage-option.model.d.ts +0 -15
- package/lib/services/local-storage-manager-service/models/storage-type.enum.d.ts +0 -5
- package/lib/services/request-manager-services/http-manager-signals.service.d.ts +0 -38
- package/lib/services/request-manager-services/http-manager.service.d.ts +0 -41
- package/lib/services/request-manager-services/index.d.ts +0 -6
- package/lib/services/request-manager-services/request-signals.service.d.ts +0 -26
- package/lib/services/request-manager-services/request.service.d.ts +0 -28
- package/lib/services/request-manager-services/rxjs-operators/countdown.d.ts +0 -2
- package/lib/services/request-manager-services/rxjs-operators/delay-retry.d.ts +0 -2
- package/lib/services/request-manager-services/rxjs-operators/index.d.ts +0 -4
- package/lib/services/request-manager-services/rxjs-operators/request-polling.d.ts +0 -2
- package/lib/services/request-manager-services/rxjs-operators/request-streaming.d.ts +0 -2
- package/lib/services/request-manager-state-service/http-manager-state.store.d.ts +0 -92
- package/lib/services/request-manager-state-service/index.d.ts +0 -2
- package/lib/services/request-manager-state-service/models/api-request.model.d.ts +0 -32
- package/lib/services/request-manager-state-service/models/index.d.ts +0 -4
- package/lib/services/request-manager-state-service/models/request-options.model.d.ts +0 -10
- package/lib/services/request-manager-state-service/models/ws-options.model.d.ts +0 -21
- package/lib/services/request-manager-state-service/models/ws-user.model.d.ts +0 -10
- package/lib/services/store-state-manager-service/index.d.ts +0 -2
- package/lib/services/store-state-manager-service/models/index.d.ts +0 -1
- package/lib/services/store-state-manager-service/models/state-storage-options.model.d.ts +0 -13
- package/lib/services/store-state-manager-service/store-state-manager.service.d.ts +0 -23
- package/lib/services/utils/app.service.d.ts +0 -8
- package/lib/services/utils/encryption/asymmetrical-encryption.service.d.ts +0 -17
- package/lib/services/utils/encryption/encryption-test.service.d.ts +0 -10
- package/lib/services/utils/encryption/index.d.ts +0 -4
- package/lib/services/utils/encryption/random.d.ts +0 -11
- package/lib/services/utils/encryption/symmetrical-encryption.service.d.ts +0 -14
- package/lib/services/utils/headers.service.d.ts +0 -10
- package/lib/services/utils/index.d.ts +0 -6
- package/lib/services/utils/object-merger.service.d.ts +0 -14
- package/lib/services/utils/path-query.service.d.ts +0 -11
- package/lib/services/utils/utils.service.d.ts +0 -24
- package/lib/services/ws-manager-service/index.d.ts +0 -2
- package/lib/services/ws-manager-service/models/channel-info.model.d.ts +0 -10
- package/lib/services/ws-manager-service/models/channel-notification.model.d.ts +0 -17
- package/lib/services/ws-manager-service/models/communication-type.enum.d.ts +0 -5
- package/lib/services/ws-manager-service/models/index.d.ts +0 -4
- package/lib/services/ws-manager-service/models/user-message.model.d.ts +0 -14
- package/lib/services/ws-manager-service/services/index.d.ts +0 -1
- package/lib/services/ws-manager-service/services/websocket.service.d.ts +0 -26
- package/public-api.d.ts +0 -7
|
@@ -1,594 +0,0 @@
|
|
|
1
|
-
import { inject, Inject, Injectable, InjectionToken } from '@angular/core';
|
|
2
|
-
import { ComponentStore } from '@ngrx/component-store';
|
|
3
|
-
import { BehaviorSubject, of, Subject, timer, merge } from 'rxjs';
|
|
4
|
-
import { tap, switchMap, concatMap, scan, delay, take, map, distinctUntilChanged, takeUntil, takeWhile, filter } from 'rxjs/operators';
|
|
5
|
-
import { DatabaseStorage } from '../../models/database-storage.model';
|
|
6
|
-
import { ApiRequest, RequestOptions, WSOptions } from './models';
|
|
7
|
-
import { ChannelMessage } from '../ws-manager-service/models';
|
|
8
|
-
import { HTTPManagerService, DataType } from '../request-manager-services';
|
|
9
|
-
import { DatabaseManagerService } from '../database-manager-service';
|
|
10
|
-
import { TableSchemaDef } from '../database-manager-service/models/table-schema';
|
|
11
|
-
import { LocalStorageManagerService, StorageType } from '../local-storage-manager-service';
|
|
12
|
-
import { SettingOptions } from '../local-storage-manager-service/models/setting-options.model';
|
|
13
|
-
import { UtilsService } from '../..';
|
|
14
|
-
import * as i0 from "@angular/core";
|
|
15
|
-
const API_OPTS = new InjectionToken('API_OPTS');
|
|
16
|
-
const defaultState = {
|
|
17
|
-
data: [],
|
|
18
|
-
dataObject: null,
|
|
19
|
-
};
|
|
20
|
-
export class HTTPManagerStateService extends ComponentStore {
|
|
21
|
-
constructor(apiOptions = ApiRequest.adapt(), dataType, database) {
|
|
22
|
-
super(defaultState);
|
|
23
|
-
this.apiOptions = apiOptions;
|
|
24
|
-
this.dataType = dataType;
|
|
25
|
-
this.database = database;
|
|
26
|
-
this.httpManagerService = inject(HTTPManagerService);
|
|
27
|
-
this.dbManagerService = inject(DatabaseManagerService);
|
|
28
|
-
this.localStorageManagerService = inject(LocalStorageManagerService);
|
|
29
|
-
this.utils = inject(UtilsService);
|
|
30
|
-
this.error$ = this.httpManagerService.error$;
|
|
31
|
-
this.isPending$ = this.httpManagerService.isPending$.pipe(delay(1));
|
|
32
|
-
// PAGINATION
|
|
33
|
-
this.page = new BehaviorSubject(0);
|
|
34
|
-
this.page$ = this.page.asObservable();
|
|
35
|
-
this.totalPages = new BehaviorSubject(0);
|
|
36
|
-
this.totalPages$ = this.totalPages.asObservable();
|
|
37
|
-
this.percentage = new BehaviorSubject(0);
|
|
38
|
-
this.percentage$ = this.percentage.asObservable();
|
|
39
|
-
this.hasDatabase = false;
|
|
40
|
-
this.streamedResponse = [];
|
|
41
|
-
this.shouldRetry = true;
|
|
42
|
-
this.wsRetryAttempts = new BehaviorSubject(0);
|
|
43
|
-
this.wsRetryAttempts$ = this.wsRetryAttempts.asObservable();
|
|
44
|
-
this.messages$ = null;
|
|
45
|
-
this.connectionStatus$ = null;
|
|
46
|
-
this.userList = new BehaviorSubject([]);
|
|
47
|
-
this.userList$ = this.userList.asObservable();
|
|
48
|
-
this.user = new BehaviorSubject(null);
|
|
49
|
-
this.user$ = this.user.asObservable();
|
|
50
|
-
this.communicationMessages = new BehaviorSubject([]);
|
|
51
|
-
this.communicationMessages$ = this.communicationMessages.asObservable();
|
|
52
|
-
this.latestCommunicationMessages = new BehaviorSubject(null);
|
|
53
|
-
this.latestCommunicationMessages$ = this.latestCommunicationMessages.asObservable();
|
|
54
|
-
this.userAction = new BehaviorSubject(null);
|
|
55
|
-
this.userAction$ = this.userAction.asObservable();
|
|
56
|
-
this.channels = [];
|
|
57
|
-
this.channelList = [];
|
|
58
|
-
this.messages = [];
|
|
59
|
-
this.wsConnection = false;
|
|
60
|
-
this.wsOptions = WSOptions.adapt();
|
|
61
|
-
// WebSocket
|
|
62
|
-
this.initWS = this.effect((wsOptions$) => wsOptions$.pipe(tap((wsOptions) => {
|
|
63
|
-
this.wsOptions = wsOptions;
|
|
64
|
-
if (wsOptions?.wsServer)
|
|
65
|
-
this.httpManagerService.connect(wsOptions, wsOptions.jwtToken);
|
|
66
|
-
}), switchMap((wsOptions) => merge(this.httpManagerService.connectionStatus$.pipe(tap((isConnected) => {
|
|
67
|
-
this.wsConnection = isConnected;
|
|
68
|
-
if (isConnected) {
|
|
69
|
-
console.log('🟢 WebSocket connection is open.');
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
console.log('🔴 WebSocket connection is closed.');
|
|
73
|
-
}
|
|
74
|
-
})), this.httpManagerService.messages$.pipe(tap((message) => {
|
|
75
|
-
if (!message)
|
|
76
|
-
return;
|
|
77
|
-
console.log('Received:', message.type);
|
|
78
|
-
if (message.error === 'JWT_INVALID') {
|
|
79
|
-
this.shouldRetry = false;
|
|
80
|
-
this.httpManagerService.disconnect();
|
|
81
|
-
}
|
|
82
|
-
if (message.type === 'success') {
|
|
83
|
-
this.user.next(message.data);
|
|
84
|
-
}
|
|
85
|
-
switch (message.type) {
|
|
86
|
-
case 'channelsList':
|
|
87
|
-
console.log('💬 Channels:', message.channels);
|
|
88
|
-
this.channelList = message.channels;
|
|
89
|
-
if (this.channelList.includes(wsOptions.id)) {
|
|
90
|
-
this.httpManagerService.subscribeToChannel(wsOptions.id);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
this.httpManagerService.createChannel(wsOptions.id);
|
|
94
|
-
}
|
|
95
|
-
break;
|
|
96
|
-
case 'stateMangerMessage':
|
|
97
|
-
if (message.data.sessionId !== this.user.value.sessionId) {
|
|
98
|
-
console.log('💬 Message:', message.data);
|
|
99
|
-
this.userAction.next(message.data);
|
|
100
|
-
this.fetchRecord(RequestOptions.adapt({ path: message.content.path }), message.content.method);
|
|
101
|
-
}
|
|
102
|
-
break;
|
|
103
|
-
// case 'channelMessage':
|
|
104
|
-
// console.log('💬 Message:', message.data)
|
|
105
|
-
// this.fetchRecord(RequestOptions.adapt({ path: message.content.path }), message.content.method)
|
|
106
|
-
// break;
|
|
107
|
-
// case 'channelCommunication':
|
|
108
|
-
// console.log('💬 Message Communication:', message.data)
|
|
109
|
-
// this.appendMessages(message.data)
|
|
110
|
-
// break;
|
|
111
|
-
// case 'channelAlerts':
|
|
112
|
-
// console.log('💬 Message Alerts:', message.data)
|
|
113
|
-
// break;
|
|
114
|
-
case 'usersInChannel':
|
|
115
|
-
console.log('👥 Users:', message.data.users);
|
|
116
|
-
this.userList.next(message.data.users);
|
|
117
|
-
break;
|
|
118
|
-
default:
|
|
119
|
-
if (message)
|
|
120
|
-
this.messages.push(message);
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
}))))));
|
|
124
|
-
this.initDBStorage = this.effect((trigger$) => trigger$.pipe(tap(() => {
|
|
125
|
-
if (this.dataType !== DataType.ARRAY)
|
|
126
|
-
console.warn('Database storage requires dataType to be ARRAY');
|
|
127
|
-
if (!this.apiOptions.adapter)
|
|
128
|
-
console.warn('Database storage requires an adapter to define the data shape');
|
|
129
|
-
if (this.database && this.database?.table === '')
|
|
130
|
-
console.warn('Database storage requires a table name');
|
|
131
|
-
}), filter(() => this.dataType === DataType.ARRAY && !!this.apiOptions.adapter && !!this.database?.table), switchMap(() => {
|
|
132
|
-
const sampleData = this.apiOptions.adapter?.({}) || {};
|
|
133
|
-
const schemaKeys = Object.keys(sampleData).filter(key => sampleData[key] !== undefined);
|
|
134
|
-
let schema = '++id';
|
|
135
|
-
if (schemaKeys.length > 0) {
|
|
136
|
-
const otherKeys = schemaKeys.filter(k => k !== 'id');
|
|
137
|
-
if (otherKeys.length > 0) {
|
|
138
|
-
schema += ', ' + otherKeys.join(', ');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const tableDef = TableSchemaDef.adapt({
|
|
142
|
-
table: this.database?.table,
|
|
143
|
-
schema: schema
|
|
144
|
-
});
|
|
145
|
-
return this.dbManagerService.createDatabaseTable(tableDef);
|
|
146
|
-
})));
|
|
147
|
-
// --------------------------------------------------------------------------------------------------
|
|
148
|
-
// SELECTORS
|
|
149
|
-
this.data$ = this.select(({ data, dataObject }) => {
|
|
150
|
-
const isArray = (this.dataType === DataType.ARRAY) ? true : false;
|
|
151
|
-
return (isArray) ? data : dataObject;
|
|
152
|
-
});
|
|
153
|
-
this.selectRecord$ = (id) => this.select(this.data$, (data) => {
|
|
154
|
-
if (this.dataType === DataType.ARRAY && Array.isArray(data)) {
|
|
155
|
-
return data.find(item => item.id === id);
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
return data.id === id ? data : null;
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
// --------------------------------------------------------------------------------------------------
|
|
162
|
-
// UPDATERS
|
|
163
|
-
this.setData$ = this.updater((state, data) => {
|
|
164
|
-
if (!data)
|
|
165
|
-
return state;
|
|
166
|
-
if (this.dataType === DataType.ARRAY) {
|
|
167
|
-
const dataArray = Array.isArray(data) ? data : [data];
|
|
168
|
-
const stateDataSample = (state.data.length > 0) ? Object.keys(state.data[0]) : [];
|
|
169
|
-
const newDataSample = (dataArray.length > 0) ? Object.keys(dataArray[0]) : [];
|
|
170
|
-
const isSame = (state.data.length === 0) ? false : stateDataSample.every((value, index) => value === newDataSample[index]);
|
|
171
|
-
const updatedData = (!isSame && dataArray.length !== 0) ? this.updateArrayState([], dataArray) : this.updateArrayState(state.data, dataArray);
|
|
172
|
-
return { ...state, data: updatedData, dataObject: null };
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
const dataObject = this.isEmpty(data) ? null : data;
|
|
176
|
-
return { ...state, data: [], dataObject: dataObject };
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
this.addData$ = this.updater((state, data) => {
|
|
180
|
-
if (this.dataType === DataType.ARRAY) {
|
|
181
|
-
const exists = state.data.some(item => item.id === data.id);
|
|
182
|
-
if (exists) {
|
|
183
|
-
const updatedData = state.data.map(item => item.id === data.id ? data : item);
|
|
184
|
-
return { ...state, data: updatedData };
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
const newState = [...state.data, data];
|
|
188
|
-
return { ...state, data: newState };
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
return { ...state, dataObject: data };
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
this.deleteData$ = this.updater((state, data) => {
|
|
196
|
-
if (this.dataType === DataType.ARRAY) {
|
|
197
|
-
const newState = state.data.filter(item => item.id !== data.id);
|
|
198
|
-
return { ...state, ...{ data: newState } };
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
return { ...state, ...{ dataObject: null } };
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
this.updateData$ = this.updater((state, data) => {
|
|
205
|
-
if (this.dataType === DataType.ARRAY) {
|
|
206
|
-
const objIndex = state.data.findIndex(item => item.id === data.id);
|
|
207
|
-
if (objIndex > -1) {
|
|
208
|
-
const newState = [...state.data];
|
|
209
|
-
newState[objIndex] = data;
|
|
210
|
-
return { ...state, ...{ data: newState } };
|
|
211
|
-
}
|
|
212
|
-
return state;
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
return { ...state, ...{ dataObject: data } };
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
// --------------------------------------------------------------------------------------------------
|
|
219
|
-
// EFFECTS
|
|
220
|
-
this.clearRecords = this.effect(data => data.pipe(tap(() => {
|
|
221
|
-
if (this.dataType === DataType.ARRAY) {
|
|
222
|
-
this.setData$([]);
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
this.setData$({});
|
|
226
|
-
}
|
|
227
|
-
}), concatMap(() => {
|
|
228
|
-
if (this.hasDatabase && this.database?.table) {
|
|
229
|
-
const currentData = this.get()?.data;
|
|
230
|
-
const idsToDelete = Array.isArray(currentData) ? currentData.map((r) => r.id) : [];
|
|
231
|
-
if (idsToDelete.length > 0) {
|
|
232
|
-
return this.dbManagerService.deleteTableRecords(this.database.table, idsToDelete);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return of(null);
|
|
236
|
-
})));
|
|
237
|
-
// --------------------------------------------------------------------------------------------------
|
|
238
|
-
// CRUD OPERATIONS
|
|
239
|
-
// FETCH RECORDS
|
|
240
|
-
this.fetchRecords = (options) => this.effect(() => of(RequestOptions.adapt(options)).pipe(switchMap(() => {
|
|
241
|
-
this.streamedResponse = [];
|
|
242
|
-
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
243
|
-
const fetchFromAPI = () => {
|
|
244
|
-
return this.httpManagerService.getRequest(requestOptions, options?.path).pipe(tap((data) => {
|
|
245
|
-
data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
|
|
246
|
-
this.setData$(data);
|
|
247
|
-
}), concatMap((data) => {
|
|
248
|
-
if (this.hasDatabase && this.database?.table && Array.isArray(data) && data.length > 0) {
|
|
249
|
-
this.localStorageManagerService.updateStore({
|
|
250
|
-
name: this.database.table,
|
|
251
|
-
data: { ...this.database, ...{ expires: this.utils.expires(this.database.expiresIn) } }
|
|
252
|
-
});
|
|
253
|
-
return this.dbManagerService.createTableRecords(this.database.table, data);
|
|
254
|
-
}
|
|
255
|
-
return of(data);
|
|
256
|
-
}));
|
|
257
|
-
};
|
|
258
|
-
if (this.hasDatabase && this.database?.table) {
|
|
259
|
-
return this.dbManagerService.databaseExists().pipe(switchMap((dbExists) => {
|
|
260
|
-
if (!dbExists) {
|
|
261
|
-
const initObs = this.initDBStorageAsync();
|
|
262
|
-
return initObs.pipe(switchMap(() => fetchFromAPI()));
|
|
263
|
-
}
|
|
264
|
-
return this.dbManagerService.hasDatabaseTable(this.database.table).pipe(switchMap((tableExists) => {
|
|
265
|
-
if (!tableExists) {
|
|
266
|
-
const initObs = this.initDBStorageAsync();
|
|
267
|
-
return initObs.pipe(switchMap(() => fetchFromAPI()));
|
|
268
|
-
}
|
|
269
|
-
return this.localStorageManagerService.store$(this.database.table).pipe(take(1), switchMap((storeData) => {
|
|
270
|
-
const expires = storeData?.expires || 0;
|
|
271
|
-
const hasExpired = expires > 0 && this.utils.hasExpired(expires);
|
|
272
|
-
if (hasExpired) {
|
|
273
|
-
return this.dbManagerService.clearTable(this.database.table).pipe(switchMap(() => fetchFromAPI()), tap(() => {
|
|
274
|
-
this.localStorageManagerService.updateStore({
|
|
275
|
-
name: this.database.table,
|
|
276
|
-
data: { ...this.database, ...{ expires: this.utils.expires(this.database.expiresIn) } }
|
|
277
|
-
});
|
|
278
|
-
}));
|
|
279
|
-
}
|
|
280
|
-
return this.dbManagerService.getTableRecords(this.database.table).pipe(switchMap((dbData) => {
|
|
281
|
-
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
282
|
-
this.setData$(dbData);
|
|
283
|
-
return of(dbData);
|
|
284
|
-
}
|
|
285
|
-
return fetchFromAPI();
|
|
286
|
-
}));
|
|
287
|
-
}));
|
|
288
|
-
}));
|
|
289
|
-
}));
|
|
290
|
-
}
|
|
291
|
-
return fetchFromAPI();
|
|
292
|
-
})));
|
|
293
|
-
// FETCH RECORD
|
|
294
|
-
this.fetchRecord = (options, method) => this.effect(() => of(RequestOptions.adapt(options)).pipe(switchMap((options) => {
|
|
295
|
-
this.streamedResponse = [];
|
|
296
|
-
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
297
|
-
return this.httpManagerService.getRequest(requestOptions, options?.path)
|
|
298
|
-
.pipe(tap((data) => {
|
|
299
|
-
data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
|
|
300
|
-
const id = options.path?.length ? options.path[options.path.length - 1] : null;
|
|
301
|
-
if (method === 'DELETE')
|
|
302
|
-
this.deleteData$({ id });
|
|
303
|
-
if (method === 'UPDATE')
|
|
304
|
-
this.updateData$(data);
|
|
305
|
-
if (method === 'CREATE')
|
|
306
|
-
this.addData$(data);
|
|
307
|
-
}), concatMap((data) => {
|
|
308
|
-
if (this.hasDatabase && this.database?.table) {
|
|
309
|
-
const id = options.path?.length ? options.path[options.path.length - 1] : null;
|
|
310
|
-
if (method === 'DELETE' && id)
|
|
311
|
-
return this.dbManagerService.deleteTableRecord(this.database.table, id);
|
|
312
|
-
if (method === 'UPDATE' && data)
|
|
313
|
-
return this.dbManagerService.updateTableRecord(this.database.table, data);
|
|
314
|
-
if (method === 'CREATE' && data)
|
|
315
|
-
return this.dbManagerService.createTableRecord(this.database.table, data);
|
|
316
|
-
}
|
|
317
|
-
return of(data);
|
|
318
|
-
}));
|
|
319
|
-
})));
|
|
320
|
-
// CREATE RECORD
|
|
321
|
-
this.createRecord = (data, options) => this.effect(() => of(data).pipe(switchMap((data) => {
|
|
322
|
-
this.streamedResponse = [];
|
|
323
|
-
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
324
|
-
return this.httpManagerService.postRequest(data, requestOptions, options?.path)
|
|
325
|
-
.pipe(tap((data) => {
|
|
326
|
-
data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
|
|
327
|
-
this.addData$(data);
|
|
328
|
-
if (this.wsConnection)
|
|
329
|
-
this.wsCommunication('CREATE', [...options?.path || [], data.id]);
|
|
330
|
-
}), concatMap((data) => {
|
|
331
|
-
if (this.hasDatabase && this.database?.table && data?.id) {
|
|
332
|
-
return this.dbManagerService.createTableRecord(this.database.table, data);
|
|
333
|
-
}
|
|
334
|
-
return of(data);
|
|
335
|
-
}));
|
|
336
|
-
})));
|
|
337
|
-
// UPDATE RECORD
|
|
338
|
-
this.updateRecord = (data, options) => this.effect(() => of(data).pipe(concatMap((data) => {
|
|
339
|
-
this.streamedResponse = [];
|
|
340
|
-
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
341
|
-
return this.httpManagerService.putRequest(data, requestOptions, options?.path)
|
|
342
|
-
.pipe(tap((data) => {
|
|
343
|
-
data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
|
|
344
|
-
this.updateData$(data);
|
|
345
|
-
if (this.wsConnection)
|
|
346
|
-
this.wsCommunication('UPDATE', [...options?.path || []]);
|
|
347
|
-
}), concatMap((data) => {
|
|
348
|
-
if (this.hasDatabase && this.database?.table && data?.id) {
|
|
349
|
-
return this.dbManagerService.updateTableRecord(this.database.table, data);
|
|
350
|
-
}
|
|
351
|
-
return of(data);
|
|
352
|
-
}));
|
|
353
|
-
})));
|
|
354
|
-
// DELETE RECORD
|
|
355
|
-
this.deleteRecord = (options) => this.effect(() => of(options).pipe(concatMap((data) => {
|
|
356
|
-
this.streamedResponse = [];
|
|
357
|
-
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
358
|
-
return this.httpManagerService.deleteRequest(requestOptions, options?.path)
|
|
359
|
-
.pipe(tap((data) => {
|
|
360
|
-
data = (!data) ? (this.dataType === DataType.ARRAY) ? [] : {} : data;
|
|
361
|
-
this.deleteData$(data);
|
|
362
|
-
if (this.wsConnection)
|
|
363
|
-
this.wsCommunication('DELETE', [...options?.path || []]);
|
|
364
|
-
}), concatMap((data) => {
|
|
365
|
-
if (this.hasDatabase && this.database?.table && data?.id) {
|
|
366
|
-
return this.dbManagerService.deleteTableRecord(this.database.table, data.id);
|
|
367
|
-
}
|
|
368
|
-
return of(data);
|
|
369
|
-
}));
|
|
370
|
-
})));
|
|
371
|
-
// --------------------------------------------------------------------------------------------------
|
|
372
|
-
// FETCH STREAM
|
|
373
|
-
this.createStream = (data, options) => this.effect(() => of(data).pipe(tap(() => this.httpManagerService.isPending.next(true)), switchMap((data) => {
|
|
374
|
-
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
375
|
-
return this.httpManagerService.postRequest(data, requestOptions, options?.path)
|
|
376
|
-
.pipe(tap((res) => {
|
|
377
|
-
if (res.length > 0)
|
|
378
|
-
this.setData$(res);
|
|
379
|
-
this.streamedResponse = res;
|
|
380
|
-
}), scan((acc, res) => {
|
|
381
|
-
const previous = acc.current;
|
|
382
|
-
const current = res;
|
|
383
|
-
return { previous, current };
|
|
384
|
-
}, { previous: null, current: null }), tap(({ previous, current }) => {
|
|
385
|
-
if (previous && JSON.stringify(previous) === JSON.stringify(current)) {
|
|
386
|
-
this.httpManagerService.isPending.next(false);
|
|
387
|
-
this.setData$([]);
|
|
388
|
-
}
|
|
389
|
-
else {
|
|
390
|
-
this.httpManagerService.isPending.next(true);
|
|
391
|
-
}
|
|
392
|
-
}));
|
|
393
|
-
})));
|
|
394
|
-
this.fetchStream = (options) => this.effect(() => of(options).pipe(tap(() => this.httpManagerService.isPending.next(true)), switchMap((options) => {
|
|
395
|
-
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
396
|
-
requestOptions.stream = true;
|
|
397
|
-
return this.httpManagerService.getRequest(requestOptions, options?.path)
|
|
398
|
-
.pipe(tap((res) => {
|
|
399
|
-
if (res.length > 0)
|
|
400
|
-
this.setData$(res);
|
|
401
|
-
this.streamedResponse = res;
|
|
402
|
-
}), scan((acc, res) => {
|
|
403
|
-
const previous = acc.current;
|
|
404
|
-
const current = res;
|
|
405
|
-
return { previous, current };
|
|
406
|
-
}, { previous: null, current: null }), tap(({ previous, current }) => {
|
|
407
|
-
if (previous && JSON.stringify(previous) === JSON.stringify(current)) {
|
|
408
|
-
this.httpManagerService.isPending.next(false);
|
|
409
|
-
this.setData$([]);
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
this.httpManagerService.isPending.next(true);
|
|
413
|
-
}
|
|
414
|
-
}));
|
|
415
|
-
})));
|
|
416
|
-
this.maxRetries = this.apiOptions.ws?.retry?.times || 3;
|
|
417
|
-
this.retryDelay = (this.apiOptions.ws?.retry?.delay && this.apiOptions.ws.retry.delay * 1000) || 5 * 1000;
|
|
418
|
-
this.wsNextRetry = new BehaviorSubject(this.retryDelay);
|
|
419
|
-
this.wsNextRetry$ = this.wsNextRetry.asObservable();
|
|
420
|
-
this.setApiRequestOptions(apiOptions, dataType, database);
|
|
421
|
-
this.status$ = this.setupConnectionStatus();
|
|
422
|
-
if (this.database && this.database.table) {
|
|
423
|
-
this.localStorageManagerService.createStore({
|
|
424
|
-
name: this.database.table,
|
|
425
|
-
data: { ...this.database, ...{ expires: this.utils.expires(this.database.expiresIn) } },
|
|
426
|
-
options: SettingOptions.adapt({
|
|
427
|
-
storage: StorageType.GLOBAL,
|
|
428
|
-
encrypted: false,
|
|
429
|
-
})
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
setApiRequestOptions(apiOptions, dataType, database) {
|
|
434
|
-
this.apiOptions = ApiRequest.adapt(apiOptions);
|
|
435
|
-
this.dataType = (dataType) ? dataType : DataType.ARRAY;
|
|
436
|
-
this.hasDatabase = (this.database?.table) ? true : false;
|
|
437
|
-
this.database = (this.hasDatabase) ? DatabaseStorage.adapt(database) : undefined;
|
|
438
|
-
if (this.database)
|
|
439
|
-
this.initDBStorage();
|
|
440
|
-
if (this.apiOptions.ws)
|
|
441
|
-
this.initWS(this.apiOptions.ws);
|
|
442
|
-
}
|
|
443
|
-
// WebSocket
|
|
444
|
-
setupConnectionStatus() {
|
|
445
|
-
return this.httpManagerService.connectionStatus$.pipe(distinctUntilChanged(), switchMap(status => {
|
|
446
|
-
if (status === true) {
|
|
447
|
-
this.shouldRetry = true;
|
|
448
|
-
this.wsRetryAttempts.next(0);
|
|
449
|
-
this.wsNextRetry.next(0);
|
|
450
|
-
return of(true);
|
|
451
|
-
}
|
|
452
|
-
if (!this.shouldRetry)
|
|
453
|
-
return of(false);
|
|
454
|
-
const countdownEnder$ = new Subject();
|
|
455
|
-
return timer(0, this.retryDelay)
|
|
456
|
-
.pipe(take(this.maxRetries), tap(i => {
|
|
457
|
-
const attempt = i + 1;
|
|
458
|
-
this.wsRetryAttempts.next(attempt);
|
|
459
|
-
countdownEnder$.next();
|
|
460
|
-
if (this.apiOptions.ws?.jwtToken !== '' && this.apiOptions.ws?.wsServer !== '')
|
|
461
|
-
this.initWS(this.apiOptions.ws);
|
|
462
|
-
if (attempt === this.maxRetries) {
|
|
463
|
-
this.wsNextRetry.next(0);
|
|
464
|
-
// console.error(`🚨 FAILED CONNECTION: Tried #${attempt} times`);
|
|
465
|
-
}
|
|
466
|
-
else {
|
|
467
|
-
// console.log(`⚠️ Retry Attempt #${attempt}: Retrying in ${this.retryDelay / 1000}s`);
|
|
468
|
-
const seconds = this.retryDelay / 1000;
|
|
469
|
-
timer(0, 1000).pipe(map(tick => seconds - tick), takeWhile(val => val >= 0), takeUntil(countdownEnder$)).subscribe(remaining => {
|
|
470
|
-
this.wsNextRetry.next(remaining);
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
}), map(() => false));
|
|
474
|
-
}));
|
|
475
|
-
}
|
|
476
|
-
appendMessages(message) {
|
|
477
|
-
const currentMessages = this.communicationMessages.value;
|
|
478
|
-
this.communicationMessages.next([...currentMessages, message]);
|
|
479
|
-
this.latestMessage();
|
|
480
|
-
}
|
|
481
|
-
latestMessage() {
|
|
482
|
-
const messages = this.communicationMessages.value;
|
|
483
|
-
const latestMessage = messages[messages.length - 1];
|
|
484
|
-
this.latestCommunicationMessages.next(latestMessage);
|
|
485
|
-
}
|
|
486
|
-
clearMessages() {
|
|
487
|
-
this.communicationMessages.next([]);
|
|
488
|
-
}
|
|
489
|
-
get ApiRequestOptions() {
|
|
490
|
-
return this.apiOptions;
|
|
491
|
-
}
|
|
492
|
-
initializeState(data) {
|
|
493
|
-
this.setData$(data);
|
|
494
|
-
}
|
|
495
|
-
updateArrayState(currentData, newData) {
|
|
496
|
-
const filterCurrentData = () => {
|
|
497
|
-
const ids = this.streamedResponse.map((obj) => obj.id);
|
|
498
|
-
return currentData.filter(obj => (obj.id) ? ids.includes(obj.id) : obj);
|
|
499
|
-
};
|
|
500
|
-
const filteredCurrentData = (this.httpManagerService.isPending.value) ? currentData : filterCurrentData();
|
|
501
|
-
const updatedData = filteredCurrentData.map(item => {
|
|
502
|
-
const newItem = newData.find(newItem => {
|
|
503
|
-
const hasId = (newItem?.id && item?.id) ? true : false;
|
|
504
|
-
return (hasId) ? newItem.id === item.id : JSON.stringify(newItem) === JSON.stringify(item);
|
|
505
|
-
});
|
|
506
|
-
return (newItem) ? { ...item, ...newItem } : item;
|
|
507
|
-
});
|
|
508
|
-
const addedData = newData.filter(newItem => {
|
|
509
|
-
return !filteredCurrentData.some(item => {
|
|
510
|
-
const hasId = (newItem?.id && item?.id) ? true : false;
|
|
511
|
-
return (hasId) ? item.id === newItem.id : JSON.stringify(newItem) === JSON.stringify(item);
|
|
512
|
-
});
|
|
513
|
-
});
|
|
514
|
-
return [...updatedData, ...addedData];
|
|
515
|
-
}
|
|
516
|
-
initDBStorageAsync() {
|
|
517
|
-
if (this.dataType !== DataType.ARRAY) {
|
|
518
|
-
console.warn('Database storage requires dataType to be ARRAY');
|
|
519
|
-
return of(null);
|
|
520
|
-
}
|
|
521
|
-
if (!this.apiOptions.adapter) {
|
|
522
|
-
console.warn('Database storage requires an adapter to define the data shape');
|
|
523
|
-
return of(null);
|
|
524
|
-
}
|
|
525
|
-
if (!this.database?.table) {
|
|
526
|
-
console.warn('Database storage requires a table name');
|
|
527
|
-
return of(null);
|
|
528
|
-
}
|
|
529
|
-
const sampleData = this.apiOptions.adapter?.({}) || {};
|
|
530
|
-
const schemaKeys = Object.keys(sampleData).filter(key => sampleData[key] !== undefined);
|
|
531
|
-
let schema = '++id';
|
|
532
|
-
if (schemaKeys.length > 0) {
|
|
533
|
-
const otherKeys = schemaKeys.filter(k => k !== 'id');
|
|
534
|
-
if (otherKeys.length > 0) {
|
|
535
|
-
schema += ', ' + otherKeys.join(', ');
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
const tableDef = TableSchemaDef.adapt({
|
|
539
|
-
table: this.database?.table,
|
|
540
|
-
schema: schema
|
|
541
|
-
});
|
|
542
|
-
return this.dbManagerService.createDatabaseTable(tableDef);
|
|
543
|
-
}
|
|
544
|
-
// WEBSOCKET COMMUNICATION (STATE MANAGER)
|
|
545
|
-
wsCommunication(method, path) {
|
|
546
|
-
if (this.wsConnection && this.apiOptions.ws) {
|
|
547
|
-
const wsServer = this.apiOptions.ws.id;
|
|
548
|
-
this.httpManagerService.sendMessageInChannel(wsServer, { method, path, user: this.apiOptions.ws.user });
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
wsMessaging(message, channel) {
|
|
552
|
-
const user = this.user.value || this.user.value;
|
|
553
|
-
const messageInfo = ChannelMessage.adapt({ ...message, fromUser: user });
|
|
554
|
-
if (this.wsConnection && this.apiOptions.ws) {
|
|
555
|
-
const wsServer = (channel) ? channel : this.apiOptions.ws.id;
|
|
556
|
-
if (messageInfo.toUser === 'allChannels') {
|
|
557
|
-
this.httpManagerService.sendBroadcast(messageInfo);
|
|
558
|
-
}
|
|
559
|
-
else if (messageInfo.toUser === 'allInChannel') {
|
|
560
|
-
this.httpManagerService.sendMessageInChannel(wsServer, messageInfo);
|
|
561
|
-
}
|
|
562
|
-
else {
|
|
563
|
-
this.httpManagerService.sendMessageToUser(wsServer, messageInfo);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
// --------------------------------------------------------------------------------------------------
|
|
568
|
-
// MISC
|
|
569
|
-
isEmpty(obj) {
|
|
570
|
-
return Object.keys(obj).length === 0;
|
|
571
|
-
}
|
|
572
|
-
updateRequestOptions(headers) {
|
|
573
|
-
const options = ApiRequest.adapt({ ...this.apiOptions });
|
|
574
|
-
options.headers = (headers)
|
|
575
|
-
? { ...options.headers, ...headers }
|
|
576
|
-
: { ...options.headers };
|
|
577
|
-
return options;
|
|
578
|
-
}
|
|
579
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HTTPManagerStateService, deps: [{ token: API_OPTS }, { token: "dataType" }, { token: "database" }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
580
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HTTPManagerStateService }); }
|
|
581
|
-
}
|
|
582
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HTTPManagerStateService, decorators: [{
|
|
583
|
-
type: Injectable
|
|
584
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
585
|
-
type: Inject,
|
|
586
|
-
args: [API_OPTS]
|
|
587
|
-
}] }, { type: undefined, decorators: [{
|
|
588
|
-
type: Inject,
|
|
589
|
-
args: ["dataType"]
|
|
590
|
-
}] }, { type: undefined, decorators: [{
|
|
591
|
-
type: Inject,
|
|
592
|
-
args: ["database"]
|
|
593
|
-
}] }] });
|
|
594
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1tYW5hZ2VyLXN0YXRlLnN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaHR0cC1yZXF1ZXN0LW1hbmFnZXIvc3JjL2xpYi9zZXJ2aWNlcy9yZXF1ZXN0LW1hbmFnZXItc3RhdGUtc2VydmljZS9odHRwLW1hbmFnZXItc3RhdGUuc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFdkQsT0FBTyxFQUFFLGVBQWUsRUFBYyxFQUFFLEVBQUUsT0FBTyxFQUFnQixLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVGLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsb0JBQW9CLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2SSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ2pFLE9BQU8sRUFBZSxjQUFjLEVBQWUsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsUUFBUSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDM0UsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlEQUFpRCxDQUFDO0FBQ2pGLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxXQUFXLEVBQUUsTUFBTSxr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LENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQTtJQUN0QyxDQUFDO0lBRU8sb0JBQW9CLENBQUMsT0FBYTtRQUV4QyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQTtRQUV4RCxPQUFPLENBQUMsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDO1lBQ3JCLENBQUMsQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLE9BQU8sRUFBRTtZQUNwQyxDQUFDLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUU5QixPQUFPLE9BQU8sQ0FBQTtJQUNoQixDQUFDOytHQWgxQlUsdUJBQXVCLGtCQWdFeEIsUUFBUSxhQUNSLFVBQVUsYUFDVixVQUFVO21IQWxFVCx1QkFBdUI7OzRGQUF2Qix1QkFBdUI7a0JBRG5DLFVBQVU7OzBCQWlFTixNQUFNOzJCQUFDLFFBQVE7OzBCQUNmLE1BQU07MkJBQUMsVUFBVTs7MEJBQ2pCLE1BQU07MkJBQUMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3Rpb25Ub2tlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tcG9uZW50U3RvcmUgfSBmcm9tICdAbmdyeC9jb21wb25lbnQtc3RvcmUnO1xuXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIHRpbWVyLCBtZXJnZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwLCBzd2l0Y2hNYXAsIGNvbmNhdE1hcCwgc2NhbiwgZGVsYXksIHRha2UsIG1hcCwgZGlzdGluY3RVbnRpbENoYW5nZWQsIHRha2VVbnRpbCwgdGFrZVdoaWxlLCBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBEYXRhYmFzZVN0b3JhZ2UgfSBmcm9tICcuLi8uLi9tb2RlbHMvZGF0YWJhc2Utc3RvcmFnZS5tb2RlbCc7XG5pbXBvcnQgeyBBcGlSZXF1ZXN0LCBSZXF1ZXN0T3B0aW9ucywgV1NPcHRpb25zIH0gZnJvbSAnLi9tb2RlbHMnO1xuaW1wb3J0IHsgQ2hhbm5lbEluZm8sIENoYW5uZWxNZXNzYWdlLCBVc2VyTWVzc2FnZSB9IGZyb20gJy4uL3dzLW1hbmFnZXItc2VydmljZS9tb2RlbHMnO1xuaW1wb3J0IHsgSFRUUE1hbmFnZXJTZXJ2aWNlLCBEYXRhVHlwZSB9IGZyb20gJy4uL3JlcXVlc3QtbWFuYWdlci1zZXJ2aWNlcyc7XG5pbXBvcnQgeyBEYXRhYmFzZU1hbmFnZXJTZXJ2aWNlIH0gZnJvbSAnLi4vZGF0YWJhc2UtbWFuYWdlci1zZXJ2aWNlJztcbmltcG9ydCB7IFRhYmxlU2NoZW1hRGVmIH0gZnJvbSAnLi4vZGF0YWJhc2UtbWFuYWdlci1zZXJ2aWNlL21vZGVscy90YWJsZS1zY2hlbWEnO1xuaW1wb3J0IHsgTG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2UsIFN0b3JhZ2VUeXBlIH0gZnJvbSAnLi4vbG9jYWwtc3RvcmFnZS1tYW5hZ2VyLXNlcnZpY2UnO1xuaW1wb3J0IHsgU2V0dGluZ09wdGlvbnMgfSBmcm9tICcuLi9sb2NhbC1zdG9yYWdlLW1hbmFnZXItc2VydmljZS9tb2RlbHMvc2V0dGluZy1vcHRpb25zLm1vZGVsJztcbmltcG9ydCB7IFV0aWxzU2VydmljZSB9IGZyb20gJy4uLy4uJztcblxuY29uc3QgQVBJX09QVFMgPSBuZXcgSW5qZWN0aW9uVG9rZW48QXBpUmVxdWVzdD4oJ0FQSV9PUFRTJyk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQVBJU3RhdGVNYW5hZ2VyRGF0YTxUPiB7XG4gIGRhdGE6IFRbXVxuICBkYXRhT2JqZWN0OiBUIHwgbnVsbFxufVxuXG5jb25zdCBkZWZhdWx0U3RhdGU6IEFQSVN0YXRlTWFuYWdlckRhdGE8YW55PiA9IHtcbiAgZGF0YTogW10sXG4gIGRhdGFPYmplY3Q6IG51bGwsXG59O1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgSFRUUE1hbmFnZXJTdGF0ZVNlcnZpY2U8VCBleHRlbmRzIHsgaWQ6IG51bWJlcnxzdHJpbmcgfT4gZXh0ZW5kcyBDb21wb25lbnRTdG9yZTxBUElTdGF0ZU1hbmFnZXJEYXRhPFQ+PiB7XG5cbiAgaHR0cE1hbmFnZXJTZXJ2aWNlID0gaW5qZWN0KEhUVFBNYW5hZ2VyU2VydmljZSlcbiAgZGJNYW5hZ2VyU2VydmljZSA9IGluamVjdChEYXRhYmFzZU1hbmFnZXJTZXJ2aWNlKVxuICBsb2NhbFN0b3JhZ2VNYW5hZ2VyU2VydmljZSA9IGluamVjdChMb2NhbFN0b3JhZ2VNYW5hZ2VyU2VydmljZSlcbiAgdXRpbHMgPSBpbmplY3QoVXRpbHNTZXJ2aWNlKVxuXG4gIGVycm9yJCA9IHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLmVycm9yJFxuICBpc1BlbmRpbmckID0gdGhpcy5odHRwTWFuYWdlclNlcnZpY2UuaXNQZW5kaW5nJC5waXBlKGRlbGF5KDEpKVxuXG4gIC8vIFBBR0lOQVRJT05cbiAgcHJpdmF0ZSBwYWdlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDApXG4gIHBhZ2UkID0gdGhpcy5wYWdlLmFzT2JzZXJ2YWJsZSgpXG5cbiAgcHJpdmF0ZSB0b3RhbFBhZ2VzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDApXG4gIHRvdGFsUGFnZXMkID0gdGhpcy50b3RhbFBhZ2VzLmFzT2JzZXJ2YWJsZSgpXG5cbiAgcHJpdmF0ZSBwZXJjZW50YWdlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDApXG4gIHBlcmNlbnRhZ2UkID0gdGhpcy5wZXJjZW50YWdlLmFzT2JzZXJ2YWJsZSgpXG5cbiAgcHJpdmF0ZSBoYXNEYXRhYmFzZSA9IGZhbHNlXG5cbiAgc3RyZWFtZWRSZXNwb25zZSA9IFtdXG5cbiAgLy8gV1NcbiAgcHJpdmF0ZSBtYXhSZXRyaWVzOiBudW1iZXJcbiAgcHJpdmF0ZSByZXRyeURlbGF5OiBudW1iZXJcbiAgcHJpdmF0ZSBzaG91bGRSZXRyeSA9IHRydWVcblxuICBwcml2YXRlIHdzUmV0cnlBdHRlbXB0cyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigwKVxuICB3c1JldHJ5QXR0ZW1wdHMkID0gdGhpcy53c1JldHJ5QXR0ZW1wdHMuYXNPYnNlcnZhYmxlKClcblxuICBwcml2YXRlIHdzTmV4dFJldHJ5OiBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPlxuICB3c05leHRSZXRyeSQ6IE9ic2VydmFibGU8bnVtYmVyPlxuXG5cbiAgbWVzc2FnZXMkOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbDtcbiAgY29ubmVjdGlvblN0YXR1cyQ6IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgdXNlckxpc3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueVtdPihbXSlcbiAgdXNlckxpc3QkID0gdGhpcy51c2VyTGlzdC5hc09ic2VydmFibGUoKVxuXG4gIHByaXZhdGUgdXNlciA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55fG51bGw+KG51bGwpXG4gIHVzZXIkID0gdGhpcy51c2VyLmFzT2JzZXJ2YWJsZSgpXG5cbiAgcHJpdmF0ZSBjb21tdW5pY2F0aW9uTWVzc2FnZXMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFVzZXJNZXNzYWdlW10+KFtdKVxuICBjb21tdW5pY2F0aW9uTWVzc2FnZXMkID0gdGhpcy5jb21tdW5pY2F0aW9uTWVzc2FnZXMuYXNPYnNlcnZhYmxlKClcblxuICBwcml2YXRlIGxhdGVzdENvbW11bmljYXRpb25NZXNzYWdlcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8VXNlck1lc3NhZ2V8bnVsbD4obnVsbClcbiAgbGF0ZXN0Q29tbXVuaWNhdGlvbk1lc3NhZ2VzJCA9IHRoaXMubGF0ZXN0Q29tbXVuaWNhdGlvbk1lc3NhZ2VzLmFzT2JzZXJ2YWJsZSgpXG5cbiAgcHJpdmF0ZSB1c2VyQWN0aW9uID0gbmV3IEJlaGF2aW9yU3ViamVjdDxhbnl8bnVsbD4obnVsbClcbiAgdXNlckFjdGlvbiQgPSB0aGlzLnVzZXJBY3Rpb24uYXNPYnNlcnZhYmxlKClcblxuICBjaGFubmVsczogQ2hhbm5lbEluZm9bXSA9IFtdXG4gIGNoYW5uZWxMaXN0OiBzdHJpbmdbXSA9IFtdXG4gIG1lc3NhZ2VzOiBhbnlbXSA9IFtdXG5cbiAgd3NDb25uZWN0aW9uID0gZmFsc2VcbiAgd3NPcHRpb25zID0gV1NPcHRpb25zLmFkYXB0KClcblxuICBwdWJsaWMgc3RhdHVzJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KEFQSV9PUFRTKSBwcml2YXRlIGFwaU9wdGlvbnMgPSBBcGlSZXF1ZXN0LmFkYXB0KCksXG4gICAgQEluamVjdChcImRhdGFUeXBlXCIpIHByaXZhdGUgZGF0YVR5cGU6IERhdGFUeXBlIHwgdW5kZWZpbmVkLFxuICAgIEBJbmplY3QoXCJkYXRhYmFzZVwiKSBwcml2YXRlIGRhdGFiYXNlPzogRGF0YWJhc2VTdG9yYWdlIHwgdW5kZWZpbmVkXG4gICkge1xuXG4gICAgc3VwZXIoZGVmYXVsdFN0YXRlKTtcblxuICAgIHRoaXMubWF4UmV0cmllcyA9IHRoaXMuYXBpT3B0aW9ucy53cz8ucmV0cnk/LnRpbWVzIHx8IDNcbiAgICB0aGlzLnJldHJ5RGVsYXkgPSAodGhpcy5hcGlPcHRpb25zLndzPy5yZXRyeT8uZGVsYXkgJiYgdGhpcy5hcGlPcHRpb25zLndzLnJldHJ5LmRlbGF5ICogMTAwMCkgfHwgNSAqIDEwMDBcbiAgICB0aGlzLndzTmV4dFJldHJ5ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KHRoaXMucmV0cnlEZWxheSlcbiAgICB0aGlzLndzTmV4dFJldHJ5JCA9IHRoaXMud3NOZXh0UmV0cnkuYXNPYnNlcnZhYmxlKClcblxuICAgIHRoaXMuc2V0QXBpUmVxdWVzdE9wdGlvbnMoYXBpT3B0aW9ucywgZGF0YVR5cGUsIGRhdGFiYXNlKVxuICAgIHRoaXMuc3RhdHVzJCA9IHRoaXMuc2V0dXBDb25uZWN0aW9uU3RhdHVzKCk7XG5cbiAgICBpZiAodGhpcy5kYXRhYmFzZSAmJiB0aGlzLmRhdGFiYXNlLnRhYmxlKSB7XG5cbiAgICAgIHRoaXMubG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2UuY3JlYXRlU3RvcmUoe1xuICAgICAgICBuYW1lOiB0aGlzLmRhdGFiYXNlLnRhYmxlLFxuICAgICAgICBkYXRhOiB7IC4uLnRoaXMuZGF0YWJhc2UsIC4uLnsgZXhwaXJlczogdGhpcy51dGlscy5leHBpcmVzKHRoaXMuZGF0YWJhc2UuZXhwaXJlc0luKX0gfSxcbiAgICAgICAgb3B0aW9uczogU2V0dGluZ09wdGlvbnMuYWRhcHQoe1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VUeXBlLkdMT0JBTCxcbiAgICAgICAgICBlbmNyeXB0ZWQ6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgfSlcblxuICAgIH1cblxuICB9XG5cbiAgc2V0QXBpUmVxdWVzdE9wdGlvbnMoYXBpT3B0aW9ucz86IEFwaVJlcXVlc3QsIGRhdGFUeXBlPzogRGF0YVR5cGUsIGRhdGFiYXNlPzogRGF0YWJhc2VTdG9yYWdlKSB7XG5cbiAgICB0aGlzLmFwaU9wdGlvbnMgPSBBcGlSZXF1ZXN0LmFkYXB0KGFwaU9wdGlvbnMpXG4gICAgdGhpcy5kYXRhVHlwZSA9IChkYXRhVHlwZSkgPyBkYXRhVHlwZSA6IERhdGFUeXBlLkFSUkFZXG5cbiAgICB0aGlzLmhhc0RhdGFiYXNlID0gKHRoaXMuZGF0YWJhc2U/LnRhYmxlKSA/IHRydWUgOiBmYWxzZVxuICAgIHRoaXMuZGF0YWJhc2UgPSAodGhpcy5oYXNEYXRhYmFzZSkgPyBEYXRhYmFzZVN0b3JhZ2UuYWRhcHQoZGF0YWJhc2UpIDogdW5kZWZpbmVkXG5cbiAgICBpZih0aGlzLmRhdGFiYXNlKSB0aGlzLmluaXREQlN0b3JhZ2UoKVxuICAgIGlmKHRoaXMuYXBpT3B0aW9ucy53cykgdGhpcy5pbml0V1ModGhpcy5hcGlPcHRpb25zLndzIGFzIFdTT3B0aW9ucylcblxuICB9XG5cbiAgLy8gV2ViU29ja2V0XG4gIHByaXZhdGUgc2V0dXBDb25uZWN0aW9uU3RhdHVzKCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5jb25uZWN0aW9uU3RhdHVzJC5waXBlKFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgIHN3aXRjaE1hcChzdGF0dXMgPT4ge1xuXG4gICAgICAgIGlmIChzdGF0dXMgPT09IHRydWUpIHtcbiAgICAgICAgICB0aGlzLnNob3VsZFJldHJ5ID0gdHJ1ZVxuICAgICAgICAgIHRoaXMud3NSZXRyeUF0dGVtcHRzLm5leHQoMCk7XG4gICAgICAgICAgdGhpcy53c05leHRSZXRyeS5uZXh0KDApO1xuICAgICAgICAgIHJldHVybiBvZih0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZXRyeSkgcmV0dXJuIG9mKGZhbHNlKVxuXG4gICAgICAgIGNvbnN0IGNvdW50ZG93bkVuZGVyJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICAgICAgcmV0dXJuIHRpbWVyKDAsIHRoaXMucmV0cnlEZWxheSlcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFrZSh0aGlzLm1heFJldHJpZXMpLFxuICAgICAgICAgIHRhcChpID0+IHtcblxuICAgICAgICAgICAgY29uc3QgYXR0ZW1wdCA9IGkgKyAxO1xuICAgICAgICAgICAgdGhpcy53c1JldHJ5QXR0ZW1wdHMubmV4dChhdHRlbXB0KTtcbiAgICAgICAgICAgIGNvdW50ZG93bkVuZGVyJC5uZXh0KCk7XG5cbiAgICAgICAgICAgIGlmKHRoaXMuYXBpT3B0aW9ucy53cz8uand0VG9rZW4gIT09ICcnICYmIHRoaXMuYXBpT3B0aW9ucy53cz8ud3NTZXJ2ZXIgIT09ICcnKSB0aGlzLmluaXRXUyh0aGlzLmFwaU9wdGlvbnMud3MgYXMgV1NPcHRpb25zKTtcblxuICAgICAgICAgICAgaWYgKGF0dGVtcHQgPT09IHRoaXMubWF4UmV0cmllcykge1xuICAgICAgICAgICAgICB0aGlzLndzTmV4dFJldHJ5Lm5leHQoMClcbiAgICAgICAgICAgICAgLy8gICBjb25zb2xlLmVycm9yKGDwn5qoIEZBSUxFRCBDT05ORUNUSU9OOiBUcmllZCAjJHthdHRlbXB0fSB0aW1lc2ApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gICBjb25zb2xlLmxvZyhg4pqg77iPIFJldHJ5IEF0dGVtcHQgIyR7YXR0ZW1wdH06IFJldHJ5aW5nIGluICR7dGhpcy5yZXRyeURlbGF5IC8gMTAwMH1zYCk7XG4gICAgICAgICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnJldHJ5RGVsYXkgLyAxMDAwO1xuXG4gICAgICAgICAgICAgIHRpbWVyKDAsIDEwMDApLnBpcGUoXG4gICAgICAgICAgICAgICAgbWFwKHRpY2sgPT4gc2Vjb25kcyAtIHRpY2spLFxuICAgICAgICAgICAgICAgIHRha2VXaGlsZSh2YWwgPT4gdmFsID49IDApLFxuICAgICAgICAgICAgICAgIHRha2VVbnRpbChjb3VudGRvd25FbmRlciQpXG4gICAgICAgICAgICAgICkuc3Vic2NyaWJlKHJlbWFpbmluZyA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy53c05leHRSZXRyeS5uZXh0KHJlbWFpbmluZyk7XG4gICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0pLFxuICAgICAgICAgIG1hcCgoKSA9PiBmYWxzZSlcbiAgICAgICAgKVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLy8gV2ViU29ja2V0XG4gIHJlYWRvbmx5IGluaXRXUyA9IHRoaXMuZWZmZWN0PFdTT3B0aW9ucz4oKHdzT3B0aW9ucyQpID0+XG4gICAgd3NPcHRpb25zJC5waXBlKFxuICAgICAgdGFwKCh3c09wdGlvbnMpID0+IHtcbiAgICAgICAgdGhpcy53c09wdGlvbnMgPSB3c09wdGlvbnNcbiAgICAgICAgaWYgKHdzT3B0aW9ucz8ud3NTZXJ2ZXIpIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLmNvbm5lY3Qod3NPcHRpb25zLCB3c09wdGlvbnMuand0VG9rZW4pXG4gICAgICB9KSxcbiAgICAgIHN3aXRjaE1hcCgod3NPcHRpb25zKSA9PlxuICAgICAgICBtZXJnZShcbiAgICAgICAgICB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5jb25uZWN0aW9uU3RhdHVzJC5waXBlKFxuICAgICAgICAgICAgdGFwKChpc0Nvbm5lY3RlZDogYW55KSA9PiB7XG5cbiAgICAgICAgICAgICAgdGhpcy53c0Nvbm5lY3Rpb24gPSBpc0Nvbm5lY3RlZFxuXG4gICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCfwn5+iIFdlYlNvY2tldCBjb25uZWN0aW9uIGlzIG9wZW4uJylcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygn8J+UtCBXZWJTb2NrZXQgY29ubmVjdGlvbiBpcyBjbG9zZWQuJylcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICksXG4gICAgICAgICAgdGhpcy5odHRwTWFuYWdlclNlcnZpY2UubWVzc2FnZXMkLnBpcGUoXG4gICAgICAgICAgICB0YXAoKG1lc3NhZ2U6IGFueSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIW1lc3NhZ2UpIHJldHVyblxuXG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdSZWNlaXZlZDonLCBtZXNzYWdlLnR5cGUpXG5cbiAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZXJyb3IgPT09ICdKV1RfSU5WQUxJRCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3VsZFJldHJ5ID0gZmFsc2VcbiAgICAgICAgICAgICAgICB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5kaXNjb25uZWN0KClcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGUgPT09ICdzdWNjZXNzJykge1xuICAgICAgICAgICAgICAgIHRoaXMudXNlci5uZXh0KG1lc3NhZ2UuZGF0YSlcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHN3aXRjaCAobWVzc2FnZS50eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2hhbm5lbHNMaXN0JzpcblxuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ/CfkqwgQ2hhbm5lbHM6JywgbWVzc2FnZS5jaGFubmVscylcblxuICAgICAgICAgICAgICAgICAgdGhpcy5jaGFubmVsTGlzdCA9IG1lc3NhZ2UuY2hhbm5lbHNcblxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY2hhbm5lbExpc3QuaW5jbHVkZXMod3NPcHRpb25zLmlkKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5zdWJzY3JpYmVUb0NoYW5uZWwod3NPcHRpb25zLmlkKVxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5odHRwTWFuYWdlclNlcnZpY2UuY3JlYXRlQ2hhbm5lbCh3c09wdGlvbnMuaWQpXG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAnc3RhdGVNYW5nZXJNZXNzYWdlJzpcbiAgICAgICAgICAgICAgICAgIGlmKG1lc3NhZ2UuZGF0YS5zZXNzaW9uSWQgIT09IHRoaXMudXNlci52YWx1ZS5zZXNzaW9uSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ/CfkqwgTWVzc2FnZTonLCBtZXNzYWdlLmRhdGEpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXNlckFjdGlvbi5uZXh0KG1lc3NhZ2UuZGF0YSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZXRjaFJlY29yZChSZXF1ZXN0T3B0aW9ucy5hZGFwdCh7IHBhdGg6IG1lc3NhZ2UuY29udGVudC5wYXRoIH0pLCBtZXNzYWdlLmNvbnRlbnQubWV0aG9kKVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAvLyBjYXNlICdjaGFubmVsTWVzc2FnZSc6XG4gICAgICAgICAgICAgICAgLy8gICBjb25zb2xlLmxvZygn8J+SrCBNZXNzYWdlOicsIG1lc3NhZ2UuZGF0YSlcbiAgICAgICAgICAgICAgICAvLyAgIHRoaXMuZmV0Y2hSZWNvcmQoUmVxdWVzdE9wdGlvbnMuYWRhcHQoeyBwYXRoOiBtZXNzYWdlLmNvbnRlbnQucGF0aCB9KSwgbWVzc2FnZS5jb250ZW50Lm1ldGhvZClcbiAgICAgICAgICAgICAgICAvLyAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgLy8gY2FzZSAnY2hhbm5lbENvbW11bmljYXRpb24nOlxuICAgICAgICAgICAgICAgIC8vICAgY29uc29sZS5sb2coJ/CfkqwgTWVzc2FnZSBDb21tdW5pY2F0aW9uOicsIG1lc3NhZ2UuZGF0YSlcbiAgICAgICAgICAgICAgICAvLyAgIHRoaXMuYXBwZW5kTWVzc2FnZXMobWVzc2FnZS5kYXRhKVxuICAgICAgICAgICAgICAgIC8vICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAvLyBjYXNlICdjaGFubmVsQWxlcnRzJzpcbiAgICAgICAgICAgICAgICAvLyAgIGNvbnNvbGUubG9nKCfwn5KsIE1lc3NhZ2UgQWxlcnRzOicsIG1lc3NhZ2UuZGF0YSlcbiAgICAgICAgICAgICAgICAvLyAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAndXNlcnNJbkNoYW5uZWwnOlxuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ/CfkaUgVXNlcnM6JywgbWVzc2FnZS5kYXRhLnVzZXJzKVxuICAgICAgICAgICAgICAgICAgdGhpcy51c2VyTGlzdC5uZXh0KG1lc3NhZ2UuZGF0YS51c2VycylcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlKSB0aGlzLm1lc3NhZ2VzLnB1c2gobWVzc2FnZSlcbiAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICApXG4gICAgKVxuICApO1xuXG4gIGFwcGVuZE1lc3NhZ2VzKG1lc3NhZ2U6IFVzZXJNZXNzYWdlKSB7XG4gICAgY29uc3QgY3VycmVudE1lc3NhZ2VzID0gdGhpcy5jb21tdW5pY2F0aW9uTWVzc2FnZXMudmFsdWVcbiAgICB0aGlzLmNvbW11bmljYXRpb25NZXNzYWdlcy5uZXh0KFsuLi5jdXJyZW50TWVzc2FnZXMsIG1lc3NhZ2VdKVxuICAgIHRoaXMubGF0ZXN0TWVzc2FnZSgpXG4gIH1cblxuICBsYXRlc3RNZXNzYWdlKCkge1xuICAgIGNvbnN0IG1lc3NhZ2VzID0gdGhpcy5jb21tdW5pY2F0aW9uTWVzc2FnZXMudmFsdWVcbiAgICBjb25zdCBsYXRlc3RNZXNzYWdlID0gbWVzc2FnZXNbbWVzc2FnZXMubGVuZ3RoIC0xXVxuICAgIHRoaXMubGF0ZXN0Q29tbXVuaWNhdGlvbk1lc3NhZ2VzLm5leHQobGF0ZXN0TWVzc2FnZSlcbiAgfVxuXG4gIGNsZWFyTWVzc2FnZXMoKSB7XG4gICAgdGhpcy5jb21tdW5pY2F0aW9uTWVzc2FnZXMubmV4dChbXSlcbiAgfVxuXG4gIGdldCBBcGlSZXF1ZXN0T3B0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5hcGlPcHRpb25zXG4gIH1cblxuICByZWFkb25seSBpbml0REJTdG9yYWdlID0gdGhpcy5lZmZlY3Q8dm9pZD4oKHRyaWdnZXIkKSA9PlxuICAgIHRyaWdnZXIkLnBpcGUoXG4gICAgICB0YXAoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuQVJSQVkpIGNvbnNvbGUud2FybignRGF0YWJhc2Ugc3RvcmFnZSByZXF1aXJlcyBkYXRhVHlwZSB0byBiZSBBUlJBWScpXG4gICAgICAgIGlmICghdGhpcy5hcGlPcHRpb25zLmFkYXB0ZXIpIGNvbnNvbGUud2FybignRGF0YWJhc2Ugc3RvcmFnZSByZXF1aXJlcyBhbiBhZGFwdGVyIHRvIGRlZmluZSB0aGUgZGF0YSBzaGFwZScpXG4gICAgICAgIGlmICh0aGlzLmRhdGFiYXNlICYmIHRoaXMuZGF0YWJhc2U/LnRhYmxlID09PSAnJykgY29uc29sZS53YXJuKCdEYXRhYmFzZSBzdG9yYWdlIHJlcXVpcmVzIGEgdGFibGUgbmFtZScpXG4gICAgICB9KSxcbiAgICAgIGZpbHRlcigoKSA9PiB0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5BUlJBWSAmJiAhIXRoaXMuYXBpT3B0aW9ucy5hZGFwdGVyICYmICEhdGhpcy5kYXRhYmFzZT8udGFibGUpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FtcGxlRGF0YSA9IHRoaXMuYXBpT3B0aW9ucy5hZGFwdGVyPy4oe30pIHx8IHt9XG4gICAgICAgIGNvbnN0IHNjaGVtYUtleXMgPSBPYmplY3Qua2V5cyhzYW1wbGVEYXRhKS5maWx0ZXIoa2V5ID0+IHNhbXBsZURhdGFba2V5XSAhPT0gdW5kZWZpbmVkKVxuXG4gICAgICAgIGxldCBzY2hlbWEgPSAnKytpZCdcblxuICAgICAgICBpZiAoc2NoZW1hS2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3Qgb3RoZXJLZXlzID0gc2NoZW1hS2V5cy5maWx0ZXIoayA9PiBrICE9PSAnaWQnKVxuICAgICAgICAgIGlmIChvdGhlcktleXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgc2NoZW1hICs9ICcsICcgKyBvdGhlcktleXMuam9pbignLCAnKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRhYmxlRGVmID0gVGFibGVTY2hlbWFEZWYuYWRhcHQoe1xuICAgICAgICAgIHRhYmxlOiB0aGlzLmRhdGFiYXNlPy50YWJsZSxcbiAgICAgICAgICBzY2hlbWE6IHNjaGVtYVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5kYk1hbmFnZXJTZXJ2aWNlLmNyZWF0ZURhdGFiYXNlVGFibGUodGFibGVEZWYpXG4gICAgICB9KVxuICAgIClcbiAgKVxuXG4gIGluaXRpYWxpemVTdGF0ZShkYXRhOiBhbnkpIHtcbiAgICB0aGlzLnNldERhdGEkKGRhdGEpXG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBTRUxFQ1RPUlNcblxuICByZWFkb25seSBkYXRhJCA9IHRoaXMuc2VsZWN0KCh7IGRhdGEsIGRhdGFPYmplY3QgfSkgPT4ge1xuICAgIGNvbnN0IGlzQXJyYXkgPSggdGhpcy5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuQVJSQVkpID8gdHJ1ZSA6IGZhbHNlXG4gICAgcmV0dXJuIChpc0FycmF5KSA/IGRhdGEgOiBkYXRhT2JqZWN0XG4gIH0pXG5cbiAgcmVhZG9ubHkgc2VsZWN0UmVjb3JkJCA9IChpZDogbnVtYmVyKSA9PiB0aGlzLnNlbGVjdChcbiAgICB0aGlzLmRhdGEkLFxuICAgIChkYXRhKSA9PiB7XG4gICAgICBpZiAodGhpcy5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuQVJSQVkgJiYgQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICByZXR1cm4gZGF0YS5maW5kKGl0ZW0gPT4gaXRlbS5pZCA9PT0gaWQpIGFzIFQgfCBudWxsXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKGRhdGEgYXMgVCkuaWQgPT09IGlkID8gZGF0YSA6IG51bGxcbiAgICAgIH1cbiAgICB9XG4gIClcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8vIFVQREFURVJTXG4gIHByaXZhdGUgcmVhZG9ubHkgc2V0RGF0YSQgPSB0aGlzLnVwZGF0ZXIoKHN0YXRlOiBBUElTdGF0ZU1hbmFnZXJEYXRhPFQ+LCBkYXRhOiBUIHwgVFtdIHwgYW55KSA9PiB7XG5cbiAgICBpZiAoIWRhdGEpIHJldHVybiBzdGF0ZTtcblxuICAgIGlmICh0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5BUlJBWSkge1xuXG4gICAgICBjb25zdCBkYXRhQXJyYXkgPSBBcnJheS5pc0FycmF5KGRhdGEpID8gZGF0YSA6IFtkYXRhXVxuXG4gICAgICBjb25zdCBzdGF0ZURhdGFTYW1wbGUgPSAoc3RhdGUuZGF0YS5sZW5ndGggPiAwKSA/IE9iamVjdC5rZXlzKHN0YXRlLmRhdGFbMF0pIDogW11cbiAgICAgIGNvbnN0IG5ld0RhdGFTYW1wbGUgPSAoZGF0YUFycmF5Lmxlbmd0aCA+IDApID8gT2JqZWN0LmtleXMoZGF0YUFycmF5WzBdKSA6IFtdXG5cbiAgICAgIGNvbnN0IGlzU2FtZSA9IChzdGF0ZS5kYXRhLmxlbmd0aCA9PT0gMCkgPyBmYWxzZSA6IHN0YXRlRGF0YVNhbXBsZS5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSA9PT0gbmV3RGF0YVNhbXBsZVtpbmRleF0pXG4gICAgICBjb25zdCB1cGRhdGVkRGF0YSA9ICghaXNTYW1lICYmIGRhdGFBcnJheS5sZW5ndGggIT09IDApID8gdGhpcy51cGRhdGVBcnJheVN0YXRlKFtdLCBkYXRhQXJyYXkpIDogdGhpcy51cGRhdGVBcnJheVN0YXRlKHN0YXRlLmRhdGEsIGRhdGFBcnJheSlcblxuICAgICAgcmV0dXJuIHsgLi4uc3RhdGUsIGRhdGE6IHVwZGF0ZWREYXRhLCBkYXRhT2JqZWN0OiBudWxsIH0gYXMgQVBJU3RhdGVNYW5hZ2VyRGF0YTxUPjtcblxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBkYXRhT2JqZWN0ID0gdGhpcy5pc0VtcHR5KGRhdGEpID8gbnVsbCA6IGRhdGE7XG4gICAgICByZXR1cm4geyAuLi5zdGF0ZSwgZGF0YTogW10sIGRhdGFPYmplY3Q6IGRhdGFPYmplY3QgfSBhcyBBUElTdGF0ZU1hbmFnZXJEYXRhPFQ+O1xuICAgIH1cblxuICB9KVxuXG4gIHByaXZhdGUgdXBkYXRlQXJyYXlTdGF0ZShjdXJyZW50RGF0YTogYW55W10sIG5ld0RhdGE6IGFueVtdKTogYW55W10ge1xuXG4gICAgY29uc3QgZmlsdGVyQ3VycmVudERhdGEgPSAoKSA9PiB7XG4gICAgICBjb25zdCBpZHMgPSB0aGlzLnN0cmVhbWVkUmVzcG9uc2UubWFwKChvYmo6IGFueSkgPT4gb2JqLmlkKVxuICAgICAgcmV0dXJuIGN1cnJlbnREYXRhLmZpbHRlcihvYmogPT4gKG9iai5pZCkgPyBpZHMuaW5jbHVkZXMob2JqLmlkKSA6IG9iailcbiAgICB9XG5cbiAgICBjb25zdCBmaWx0ZXJlZEN1cnJlbnREYXRhID0gKHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLmlzUGVuZGluZy52YWx1ZSkgPyBjdXJyZW50RGF0YSA6IGZpbHRlckN1cnJlbnREYXRhKClcblxuICAgIGNvbnN0IHVwZGF0ZWREYXRhID0gZmlsdGVyZWRDdXJyZW50RGF0YS5tYXAoaXRlbSA9PiB7XG4gICAgICAgIGNvbnN0IG5ld0l0ZW0gPSBuZXdEYXRhLmZpbmQobmV3SXRlbSA9PiB7XG4gICAgICAgICAgY29uc3QgaGFzSWQgPSAobmV3SXRlbT8uaWQgJiYgaXRlbT8uaWQpID8gdHJ1ZSA6IGZhbHNlXG4gICAgICAgICAgcmV0dXJuIChoYXNJZCkgPyBuZXdJdGVtLmlkID09PSBpdGVtLmlkIDogSlNPTi5zdHJpbmdpZnkobmV3SXRlbSkgPT09IEpTT04uc3RyaW5naWZ5KGl0ZW0pXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiAobmV3SXRlbSkgPyB7IC4uLml0ZW0sIC4uLm5ld0l0ZW0gfSA6IGl0ZW1cbiAgICB9KVxuXG4gICAgY29uc3QgYWRkZWREYXRhID0gbmV3RGF0YS5maWx0ZXIobmV3SXRlbSA9PiB7XG4gICAgICByZXR1cm4gIWZpbHRlcmVkQ3VycmVudERhdGEuc29tZShpdGVtID0+IHtcbiAgICAgICAgICBjb25zdCBoYXNJZCA9IChuZXdJdGVtPy5pZCAmJiBpdGVtPy5pZCkgPyB0cnVlIDogZmFsc2VcbiAgICAgICAgICByZXR1cm4gKGhhc0lkKSA/IGl0ZW0uaWQgPT09IG5ld0l0ZW0uaWQgOiBKU09OLnN0cmluZ2lmeShuZXdJdGVtKSA9PT0gSlNPTi5zdHJpbmdpZnkoaXRlbSlcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIHJldHVybiBbLi4udXBkYXRlZERhdGEsIC4uLmFkZGVkRGF0YV1cblxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhZGREYXRhJCA9IHRoaXMudXBkYXRlcigoc3RhdGU6IEFQSVN0YXRlTWFuYWdlckRhdGE8VD4sIGRhdGE6IFQpID0+IHtcblxuICBpZiAodGhpcy5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuQVJSQVkpIHtcbiAgICAgIGNvbnN0IGV4aXN0cyA9IHN0YXRlLmRhdGEuc29tZShpdGVtID0+IGl0ZW0uaWQgPT09IGRhdGEuaWQpO1xuXG4gICAgICBpZiAoZXhpc3RzKSB7XG4gICAgICAgICAgY29uc3QgdXBkYXRlZERhdGEgPSBzdGF0ZS5kYXRhLm1hcChpdGVtID0+XG4gICAgICAgICAgaXRlbS5pZCA9PT0gZGF0YS5pZCA/IGRhdGEgOiBpdGVtXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHsgLi4uc3RhdGUsIGRhdGE6IHVwZGF0ZWREYXRhIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuZXdTdGF0ZSA9IFsuLi5zdGF0ZS5kYXRhLCBkYXRhXTtcbiAgICAgICAgcmV0dXJuIHsgLi4uc3RhdGUsIGRhdGE6IG5ld1N0YXRlIH07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IC4uLnN0YXRlLCBkYXRhT2JqZWN0OiBkYXRhIH07XG4gICAgfVxuXG4gIH0pXG5cbiAgcHJpdmF0ZSByZWFkb25seSBkZWxldGVEYXRhJCA9IHRoaXMudXBkYXRlcigoc3RhdGU6IEFQSVN0YXRlTWFuYWdlckRhdGE8VD4sIGRhdGE6IFQgJiB7IGlkOiBudW1iZXIgfSkgPT4ge1xuICAgIGlmICh0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5BUlJBWSkge1xuICAgIGNvbnN0IG5ld1N0YXRlID0gc3RhdGUuZGF0YS5maWx0ZXIoaXRlbSA9PiBpdGVtLmlkICE9PSBkYXRhLmlkKVxuICAgIHJldHVybiB7IC4uLnN0YXRlLCAuLi57IGRhdGE6IG5ld1N0YXRlIH0gfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4geyAuLi5zdGF0ZSwgLi4ueyBkYXRhT2JqZWN0OiBudWxsIH0gfVxuICAgIH1cbiAgfSlcblxuICBwcml2YXRlIHJlYWRvbmx5IHVwZGF0ZURhdGEkID0gdGhpcy51cGRhdGVyKChzdGF0ZTogQVBJU3RhdGVNYW5hZ2VyRGF0YTxUPiwgZGF0YTogVCkgPT4ge1xuXG4gICAgaWYgKHRoaXMuZGF0YVR5cGUgPT09IERhdGFUeXBlLkFSUkFZKSB7XG5cbiAgICAgIGNvbnN0IG9iakluZGV4ID0gc3RhdGUuZGF0YS5maW5kSW5kZXgoaXRlbSA9PiBpdGVtLmlkID09PSBkYXRhLmlkKVxuXG4gICAgICBpZiAob2JqSW5kZXggPiAtMSkge1xuICAgICAgICBjb25zdCBuZXdTdGF0ZSA9IFsuLi5zdGF0ZS5kYXRhXVxuICAgICAgICBuZXdTdGF0ZVtvYmpJbmRleF0gPSBkYXRhXG4gICAgICAgIHJldHVybiB7IC4uLnN0YXRlLCAuLi57IGRhdGE6IG5ld1N0YXRlIH0gfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gc3RhdGVcblxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4geyAuLi5zdGF0ZSwgLi4ueyBkYXRhT2JqZWN0OiBkYXRhIH0gfVxuICAgIH1cblxuICB9KVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIEVGRkVDVFNcblxuICByZWFkb25seSBjbGVhclJlY29yZHMgPSB0aGlzLmVmZmVjdChkYXRhID0+XG4gICAgZGF0YS5waXBlKFxuXG4gICAgICB0YXAoKCkgPT4ge1xuXG4gICAgICAgIGlmICh0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5BUlJBWSkge1xuICAgICAgICAgIHRoaXMuc2V0RGF0YSQoW10pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXREYXRhJCh7fSlcbiAgICAgICAgfVxuXG4gICAgICB9KSxcbiAgICAgIGNvbmNhdE1hcCgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmhhc0RhdGFiYXNlICYmIHRoaXMuZGF0YWJhc2U/LnRhYmxlKSB7XG5cbiAgICAgICAgICBjb25zdCBjdXJyZW50RGF0YSA9IHRoaXMuZ2V0KCk/LmRhdGE7XG4gICAgICAgICAgY29uc3QgaWRzVG9EZWxldGUgPSBBcnJheS5pc0FycmF5KGN1cnJlbnREYXRhKSA/IGN1cnJlbnREYXRhLm1hcCgocjogYW55KSA9PiByLmlkKSA6IFtdO1xuXG4gICAgICAgICAgaWYgKGlkc1RvRGVsZXRlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRiTWFuYWdlclNlcnZpY2UuZGVsZXRlVGFibGVSZWNvcmRzKHRoaXMuZGF0YWJhc2UudGFibGUsIGlkc1RvRGVsZXRlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICB9KVxuICApKVxuXG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gQ1JVRCBPUEVSQVRJT05TXG5cbiAgLy8gRkVUQ0ggUkVDT1JEU1xuICByZWFkb25seSBmZXRjaFJlY29yZHMgPSAob3B0aW9ucz86IFJlcXVlc3RPcHRpb25zKSA9PlxuICAgIHRoaXMuZWZmZWN0PGFueT4oKCkgPT5cbiAgICBvZihSZXF1ZXN0T3B0aW9ucy5hZGFwdChvcHRpb25zKSkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XG5cbiAgICAgICAgdGhpcy5zdHJlYW1lZFJlc3BvbnNlID0gW11cbiAgICAgICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB0aGlzLnVwZGF0ZVJlcXVlc3RPcHRpb25zKG9wdGlvbnM/LmhlYWRlcnMpXG5cbiAgICAgICAgY29uc3QgZmV0Y2hGcm9tQVBJID0gKCkgPT4ge1xuXG4gICAgICAgICAgcmV0dXJuIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLmdldFJlcXVlc3QocmVxdWVzdE9wdGlvbnMsIG9wdGlvbnM/LnBhdGgpLnBpcGUoXG4gICAgICAgICAgICB0YXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICBkYXRhID0gKCFkYXRhKSA/ICh0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5BUlJBWSkgPyBbXSA6IHt9IDogZGF0YVxuICAgICAgICAgICAgICB0aGlzLnNldERhdGEkKGRhdGEpXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGNvbmNhdE1hcCgoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmhhc0RhdGFiYXNlICYmIHRoaXMuZGF0YWJhc2U/LnRhYmxlICYmIEFycmF5LmlzQXJyYXkoZGF0YSkgJiYgZGF0YS5sZW5ndGggPiAwKSB7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsU3RvcmFnZU1hbmFnZXJTZXJ2aWNlLnVwZGF0ZVN0b3JlKHtcbiAgICAgICAgICAgICAgICAgIG5hbWU6IHRoaXMuZGF0YWJhc2UhLnRhYmxlLFxuICAgICAgICAgICAgICAgICAgZGF0YTogeyAuLi50aGlzLmRhdGFiYXNlLCAuLi57IGV4cGlyZXM6IHRoaXMudXRpbHMuZXhwaXJlcyh0aGlzLmRhdGFiYXNlIS5leHBpcmVzSW4pfSB9XG4gICAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRiTWFuYWdlclNlcnZpY2UuY3JlYXRlVGFibGVSZWNvcmRzKHRoaXMuZGF0YWJhc2UudGFibGUsIGRhdGEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBvZihkYXRhKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaGFzRGF0YWJhc2UgJiYgdGhpcy5kYXRhYmFzZT8udGFibGUpIHtcblxuICAgICAgICAgIHJldHVybiB0aGlzLmRiTWFuYWdlclNlcnZpY2UuZGF0YWJhc2VFeGlzdHMoKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChkYkV4aXN0czogYm9vbGVhbikgPT4ge1xuXG4gICAgICAgICAgICAgIGlmICghZGJFeGlzdHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbml0T2JzOiBPYnNlcnZhYmxlPGFueT4gPSB0aGlzLmluaXREQlN0b3JhZ2VBc3luYygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpbml0T2JzLnBpcGUoXG4gICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gZmV0Y2hGcm9tQVBJKCkpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmRiTWFuYWdlclNlcnZpY2UuaGFzRGF0YWJhc2VUYWJsZSh0aGlzLmRhdGFiYXNlIS50YWJsZSkucGlwZShcbiAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHRhYmxlRXhpc3RzOiBib29sZWFuKTogT2JzZXJ2YWJsZTxhbnk+ID0+IHtcblxuICAgICAgICAgICAgICAgICAgaWYgKCF0YWJsZUV4aXN0cykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbml0T2JzOiBPYnNlcnZhYmxlPGFueT4gPSB0aGlzLmluaXREQlN0b3JhZ2VBc3luYygpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5pdE9icy5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiBmZXRjaEZyb21BUEkoKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2Uuc3RvcmUkKHRoaXMuZGF0YWJhc2UhLnRhYmxlKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHN0b3JlRGF0YTogYW55KSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleHBpcmVzID0gc3RvcmVEYXRhPy5leHBpcmVzIHx8IDA7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGFzRXhwaXJlZCA9IGV4cGlyZXMgPiAwICYmIHRoaXMudXRpbHMuaGFzRXhwaXJlZChleHBpcmVzKTtcblxuICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNFeHBpcmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kYk1hbmFnZXJTZXJ2aWNlLmNsZWFyVGFibGUodGhpcy5kYXRhYmFzZSEudGFibGUpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiBmZXRjaEZyb21BUEkoKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2NhbFN0b3JhZ2VNYW5hZ2VyU2VydmljZS51cGRhdGVTdG9yZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiB0aGlzLmRhdGFiYXNlIS50YWJsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHsgLi4udGhpcy5kYXRhYmFzZSwgLi4ueyBleHBpcmVzOiB0aGlzLnV0aWxzLmV4cGlyZXModGhpcy5kYXRhYmFzZSEuZXhwaXJlc0luKX0gfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRiTWFuYWdlclNlcnZpY2UuZ2V0VGFibGVSZWNvcmRzKHRoaXMuZGF0YWJhc2UhLnRhYmxlKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoTWFwKChkYkRhdGE6IGFueSkgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRiRGF0YSkgJiYgZGJEYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldERhdGEkKGRiRGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKGRiRGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmV0Y2hGcm9tQVBJKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmV0Y2hGcm9tQVBJKCk7XG5cbiAgICAgIH0pXG4gICAgKVxuICApXG5cbiAgcHJpdmF0ZSBpbml0REJTdG9yYWdlQXN5bmMoKSB7XG5cbiAgICBpZiAodGhpcy5kYXRhVHlwZSAhPT0gRGF0YVR5cGUuQVJSQVkpIHtcbiAgICAgIGNvbnNvbGUud2FybignRGF0YWJhc2Ugc3RvcmFnZSByZXF1aXJlcyBkYXRhVHlwZSB0byBiZSBBUlJBWScpO1xuICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5hcGlPcHRpb25zLmFkYXB0ZXIpIHtcbiAgICAgIGNvbnNvbGUud2FybignRGF0YWJhc2Ugc3RvcmFnZSByZXF1aXJlcyBhbiBhZGFwdGVyIHRvIGRlZmluZSB0aGUgZGF0YSBzaGFwZScpO1xuICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5kYXRhYmFzZT8udGFibGUpIHtcbiAgICAgIGNvbnNvbGUud2FybignRGF0YWJhc2Ugc3RvcmFnZSByZXF1aXJlcyBhIHRhYmxlIG5hbWUnKTtcbiAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICB9XG5cbiAgICBjb25zdCBzYW1wbGVEYXRhID0gdGhpcy5hcGlPcHRpb25zLmFkYXB0ZXI/Lih7fSkgfHwge307XG4gICAgY29uc3Qgc2NoZW1hS2V5cyA9IE9iamVjdC5rZXlzKHNhbXBsZURhdGEpLmZpbHRlcihrZXkgPT4gc2FtcGxlRGF0YVtrZXldICE9PSB1bmRlZmluZWQpO1xuXG4gICAgbGV0IHNjaGVtYSA9ICcrK2lkJztcblxuICAgIGlmIChzY2hlbWFLZXlzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IG90aGVyS2V5cyA9IHNjaGVtYUtleXMuZmlsdGVyKGsgPT4gayAhPT0gJ2lkJyk7XG4gICAgICBpZiAob3RoZXJLZXlzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc2NoZW1hICs9ICcsICcgKyBvdGhlcktleXMuam9pbignLCAnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0YWJsZURlZiA9IFRhYmxlU2NoZW1hRGVmLmFkYXB0KHtcbiAgICAgIHRhYmxlOiB0aGlzLmRhdGFiYXNlPy50YWJsZSxcbiAgICAgIHNjaGVtYTogc2NoZW1hXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5kYk1hbmFnZXJTZXJ2aWNlLmNyZWF0ZURhdGFiYXNlVGFibGUodGFibGVEZWYpO1xuXG4gIH1cblxuICAvLyBGRVRDSCBSRUNPUkRcbiAgcmVhZG9ubHkgZmV0Y2hSZWNvcmQgPSAob3B0aW9uczogUmVxdWVzdE9wdGlvbnMsIG1ldGhvZDogc3RyaW5nKSA9PlxuICAgIHRoaXMuZWZmZWN0PGFueT4oKCkgPT5cbiAgICBvZihSZXF1ZXN0T3B0aW9ucy5hZGFwdChvcHRpb25zKSkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgob3B0aW9ucykgPT4ge1xuXG4gICAgICAgIHRoaXMuc3RyZWFtZWRSZXNwb25zZSA9IFtdXG4gICAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0gdGhpcy51cGRhdGVSZXF1ZXN0T3B0aW9ucyhvcHRpb25zPy5oZWFkZXJzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5nZXRSZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCBvcHRpb25zPy5wYXRoKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YXAoKGRhdGE6IGFueSkgPT4ge1xuXG4gICAgICAgICAgICBkYXRhID0gKCFkYXRhKSA/ICh0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5BUlJBWSkgPyBbXSA6IHt9IDogZGF0YVxuXG4gICAgICAgICAgICBjb25zdCBpZCA9IChvcHRpb25zIGFzIGFueSkucGF0aD8ubGVuZ3RoID8gb3B0aW9ucy5wYXRoW29wdGlvbnMucGF0aC5sZW5ndGggLTFdIDogbnVsbFxuXG4gICAgICAgICAgICBpZihtZXRob2QgPT09ICdERUxFVEUnKSB0aGlzLmRlbGV0ZURhdGEkKHsgaWQgfSBhcyBUICYgeyBpZDogbnVtYmVyIH0pXG4gICAgICAgICAgICBpZihtZXRob2QgPT09ICdVUERBVEUnKSB0aGlzLnVwZGF0ZURhdGEkKGRhdGEpXG4gICAgICAgICAgICBpZihtZXRob2QgPT09ICdDUkVBVEUnKSB0aGlzLmFkZERhdGEkKGRhdGEpXG5cbiAgICAgICAgICB9KSxcbiAgICAgICAgICBjb25jYXRNYXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzRGF0YWJhc2UgJiYgdGhpcy5kYXRhYmFzZT8udGFibGUpIHtcbiAgICAgICAgICAgICAgY29uc3QgaWQgPSAob3B0aW9ucyBhcyBhbnkpLnBhdGg/Lmxlbmd0aCA/IG9wdGlvbnMucGF0aFtvcHRpb25zLnBhdGgubGVuZ3RoIC0xXSA6IG51bGxcblxuICAgICAgICAgICAgICBpZihtZXRob2QgPT09ICdERUxFVEUnICYmIGlkKSByZXR1cm4gdGhpcy5kYk1hbmFnZXJTZXJ2aWNlLmRlbGV0ZVRhYmxlUmVjb3JkKHRoaXMuZGF0YWJhc2UudGFibGUsIGlkKVxuICAgICAgICAgICAgICBpZihtZXRob2QgPT09ICdVUERBVEUnICYmIGRhdGEpIHJldHVybiB0aGlzLmRiTWFuYWdlclNlcnZpY2UudXBkYXRlVGFibGVSZWNvcmQodGhpcy5kYXRhYmFzZS50YWJsZSwgZGF0YSlcbiAgICAgICAgICAgICAgaWYobWV0aG9kID09PSAnQ1JFQVRFJyAmJiBkYXRhKSByZXR1cm4gdGhpcy5kYk1hbmFnZXJTZXJ2aWNlLmNyZWF0ZVRhYmxlUmVjb3JkKHRoaXMuZGF0YWJhc2UudGFibGUsIGRhdGEpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2YoZGF0YSlcbiAgICAgICAgICB9KVxuICAgICAgICApXG5cbiAgICAgIH0pXG4gICAgKVxuICApXG5cbiAgLy8gQ1JFQVRFIFJFQ09SRFxuICByZWFkb25seSBjcmVhdGVSZWNvcmQgPSAoZGF0YTogYW55fG51bGwsIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucykgPT5cbiAgICB0aGlzLmVmZmVjdDxhbnk+KCgpID0+XG4gICAgICBvZihkYXRhKS5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKGRhdGE6IGFueSkgPT4ge1xuXG4gICAgICAgIHRoaXMuc3RyZWFtZWRSZXNwb25zZSA9IFtdXG4gICAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0gdGhpcy51cGRhdGVSZXF1ZXN0T3B0aW9ucyhvcHRpb25zPy5oZWFkZXJzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5wb3N0UmVxdWVzdChkYXRhLCByZXF1ZXN0T3B0aW9ucywgb3B0aW9ucz8ucGF0aClcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFwKChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGRhdGEgPSAoIWRhdGEpID8gKHRoaXMuZGF0YVR5cGUgPT09IERhdGFUeXBlLkFSUkFZKSA/IFtdIDoge30gOiBkYXRhXG4gICAgICAgICAgICB0aGlzLmFkZERhdGEkKGRhdGEpXG4gICAgICAgICAgICBpZih0aGlzLndzQ29ubmVjdGlvbikgdGhpcy53c0NvbW11bmljYXRpb24oJ0NSRUFURScsIFsuLi5vcHRpb25zPy5wYXRoIHx8IFtdLCBkYXRhLmlkXSlcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBjb25jYXRNYXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzRGF0YWJhc2UgJiYgdGhpcy5kYXRhYmFzZT8udGFibGUgJiYgZGF0YT8uaWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGJNYW5hZ2VyU2VydmljZS5jcmVhdGVUYWJsZVJlY29yZCh0aGlzLmRhdGFiYXNlLnRhYmxlLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvZihkYXRhKTtcbiAgICAgICAgICB9KVxuICAgICAgICApXG5cbiAgICAgIH0pXG4gICAgKVxuICApXG5cbiAgLy8gVVBEQVRFIFJFQ09SRFxuICByZWFkb25seSB1cGRhdGVSZWNvcmQgPSAoZGF0YTogYW55fG51bGwsIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucykgPT5cbiAgICB0aGlzLmVmZmVjdDxhbnk+KCgpID0+XG4gICAgb2YoZGF0YSkucGlwZShcbiAgICAgIGNvbmNhdE1hcCgoZGF0YTogYW55KSA9PiB7XG5cbiAgICAgICAgdGhpcy5zdHJlYW1lZFJlc3BvbnNlID0gW11cbiAgICAgICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB0aGlzLnVwZGF0ZVJlcXVlc3RPcHRpb25zKG9wdGlvbnM/LmhlYWRlcnMpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLnB1dFJlcXVlc3QoZGF0YSwgcmVxdWVzdE9wdGlvbnMsIG9wdGlvbnM/LnBhdGgpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHRhcCgoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICBkYXRhID0gKCFkYXRhKSA/ICh0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5BUlJBWSkgPyBbXSA6IHt9IDogZGF0YVxuICAgICAgICAgICAgdGhpcy51cGRhdGVEYXRhJChkYXRhKVxuICAgICAgICAgICAgaWYodGhpcy53c0Nvbm5lY3Rpb24pIHRoaXMud3NDb21tdW5pY2F0aW9uKCdVUERBVEUnLCBbLi4ub3B0aW9ucz8ucGF0aCB8fCBbXV0pXG4gICAgICAgICAgfSksXG4gICAgICAgICAgY29uY2F0TWFwKChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0RhdGFiYXNlICYmIHRoaXMuZGF0YWJhc2U/LnRhYmxlICYmIGRhdGE/LmlkKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmRiTWFuYWdlclNlcnZpY2UudXBkYXRlVGFibGVSZWNvcmQodGhpcy5kYXRhYmFzZS50YWJsZSwgZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2YoZGF0YSk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuXG4gICAgICB9KVxuICAgIClcbiAgKVxuXG4gIC8vIERFTEVURSBSRUNPUkRcbiAgcmVhZG9ubHkgZGVsZXRlUmVjb3JkID0gKG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucykgPT5cbiAgICB0aGlzLmVmZmVjdDxhbnk+KCgpID0+XG4gICAgb2Yob3B0aW9ucykucGlwZShcbiAgICAgIGNvbmNhdE1hcCgoZGF0YTogYW55KSA9PiB7XG5cbiAgICAgICAgdGhpcy5zdHJlYW1lZFJlc3BvbnNlID0gW11cbiAgICAgICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB0aGlzLnVwZGF0ZVJlcXVlc3RPcHRpb25zKG9wdGlvbnM/LmhlYWRlcnMpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLmRlbGV0ZVJlcXVlc3QocmVxdWVzdE9wdGlvbnMsIG9wdGlvbnM/LnBhdGgpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHRhcCgoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgICBkYXRhID0gKCFkYXRhKSA/ICh0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5BUlJBWSkgPyBbXSA6IHt9IDogZGF0YVxuICAgICAgICAgICAgdGhpcy5kZWxldGVEYXRhJChkYXRhKVxuICAgICAgICAgICAgaWYodGhpcy53c0Nvbm5lY3Rpb24pIHRoaXMud3NDb21tdW5pY2F0aW9uKCdERUxFVEUnLCBbLi4ub3B0aW9ucz8ucGF0aCB8fCBbXV0pXG4gICAgICAgICAgfSksXG4gICAgICAgICAgY29uY2F0TWFwKChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0RhdGFiYXNlICYmIHRoaXMuZGF0YWJhc2U/LnRhYmxlICYmIGRhdGE/LmlkKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmRiTWFuYWdlclNlcnZpY2UuZGVsZXRlVGFibGVSZWNvcmQodGhpcy5kYXRhYmFzZS50YWJsZSwgZGF0YS5pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2YoZGF0YSk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuXG4gICAgICB9KVxuICAgIClcbiAgKVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIEZFVENIIFNUUkVBTVxuICByZWFkb25seSBjcmVhdGVTdHJlYW0gPSAoZGF0YTogYW55fG51bGwsIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucykgPT5cbiAgICB0aGlzLmVmZmVjdDxhbnk+KCgpID0+XG4gICAgb2YoZGF0YSkucGlwZShcbiAgICAgIHRhcCgoKSA9PiB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5pc1BlbmRpbmcubmV4dCh0cnVlKSksXG4gICAgICBzd2l0Y2hNYXAoKGRhdGE6IGFueSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0gdGhpcy51cGRhdGVSZXF1ZXN0T3B0aW9ucyhvcHRpb25zPy5oZWFkZXJzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5wb3N0UmVxdWVzdChkYXRhLCByZXF1ZXN0T3B0aW9ucywgb3B0aW9ucz8ucGF0aClcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFwKChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYocmVzLmxlbmd0aCA+IDApIHRoaXMuc2V0RGF0YSQocmVzKVxuICAgICAgICAgICAgdGhpcy5zdHJlYW1lZFJlc3BvbnNlID0gcmVzXG4gICAgICAgICAgfSksXG4gICAgICAgICAgc2NhbigoYWNjLCByZXM6IGFueSkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IGFjYy5jdXJyZW50XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50ID0gcmVzXG4gICAgICAgICAgICByZXR1cm4geyBwcmV2aW91cywgY3VycmVudCB9O1xuXG4gICAgICAgICAgfSwgeyBwcmV2aW91czogbnVsbCwgY3VycmVudDogbnVsbCB9KSxcbiAgICAgICAgICB0YXAoKHsgcHJldmlvdXMsIGN1cnJlbnQgfSkgPT4ge1xuXG4gICAgICAgICAgICBpZihwcmV2aW91cyAmJiBKU09OLnN0cmluZ2lmeShwcmV2aW91cykgPT09IEpTT04uc3RyaW5naWZ5KGN1cnJlbnQpKSB7XG4gICAgICAgICAgICAgIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLmlzUGVuZGluZy5uZXh0KGZhbHNlKVxuICAgICAgICAgICAgICB0aGlzLnNldERhdGEkKFtdKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5odHRwTWFuYWdlclNlcnZpY2UuaXNQZW5kaW5nLm5leHQodHJ1ZSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0pXG4gICAgICAgIClcblxuICAgICAgfSlcbiAgICApXG5cbiAgKVxuXG4gIHJlYWRvbmx5IGZldGNoU3RyZWFtID0gKG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucykgPT5cbiAgICB0aGlzLmVmZmVjdDxhbnk+KCgpID0+XG4gICAgb2Yob3B0aW9ucykucGlwZShcbiAgICAgIHRhcCgoKSA9PiB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5pc1BlbmRpbmcubmV4dCh0cnVlKSksXG4gICAgICBzd2l0Y2hNYXAoKG9wdGlvbnM6IGFueSkgPT4ge1xuXG4gICAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0gdGhpcy51cGRhdGVSZXF1ZXN0T3B0aW9ucyhvcHRpb25zPy5oZWFkZXJzKVxuICAgICAgICByZXF1ZXN0T3B0aW9ucy5zdHJlYW0gPSB0cnVlXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLmdldFJlcXVlc3QocmVxdWVzdE9wdGlvbnMsIG9wdGlvbnM/LnBhdGgpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHRhcCgocmVzOiBhbnkpID0+IHtcblxuICAgICAgICAgICAgaWYocmVzLmxlbmd0aCA+IDApIHRoaXMuc2V0RGF0YSQocmVzKVxuICAgICAgICAgICAgdGhpcy5zdHJlYW1lZFJlc3BvbnNlID0gcmVzXG4gICAgICAgICAgfSksXG4gICAgICAgICAgc2NhbigoYWNjLCByZXM6IGFueSkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IGFjYy5jdXJyZW50XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50ID0gcmVzXG4gICAgICAgICAgICByZXR1cm4geyBwcmV2aW91cywgY3VycmVudCB9XG5cbiAgICAgICAgICB9LCB7IHByZXZpb3VzOiBudWxsLCBjdXJyZW50OiBudWxsIH0pLFxuICAgICAgICAgIHRhcCgoeyBwcmV2aW91cywgY3VycmVudCB9KSA9PiB7XG5cbiAgICAgICAgICAgIGlmKHByZXZpb3VzICYmIEpTT04uc3RyaW5naWZ5KHByZXZpb3VzKSA9PT0gSlNPTi5zdHJpbmdpZnkoY3VycmVudCkpIHtcbiAgICAgICAgICAgICAgdGhpcy5odHRwTWFuYWdlclNlcnZpY2UuaXNQZW5kaW5nLm5leHQoZmFsc2UpXG4gICAgICAgICAgICAgIHRoaXMuc2V0RGF0YSQoW10pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmh0dHBNYW5hZ2VyU2VydmljZS5pc1BlbmRpbmcubmV4dCh0cnVlKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuXG4gICAgICB9KSxcbiAgICApXG4gIClcblxuICAvLyBXRUJTT0NLRVQgQ09NTVVOSUNBVElPTiAoU1RBVEUgTUFOQUdFUilcbiAgcHJpdmF0ZSB3c0NvbW11bmljYXRpb24obWV0aG9kOiBzdHJpbmcsIHBhdGg/OiBzdHJpbmd8bnVtYmVyW10pIHtcblxuICAgIGlmKHRoaXMud3NDb25uZWN0aW9uICYmIHRoaXMuYXBpT3B0aW9ucy53cykge1xuICAgICAgY29uc3Qgd3NTZXJ2ZXIgPSB0aGlzLmFwaU9wdGlvbnMud3MuaWRcbiAgICAgIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLnNlbmRNZXNzYWdlSW5DaGFubmVsKHdzU2VydmVyLCB7IG1ldGhvZCwgcGF0aCwgdXNlcjogdGhpcy5hcGlPcHRpb25zLndzLnVzZXIgfSlcbiAgICB9XG5cbiAgfVxuXG4gIHdzTWVzc2FnaW5nKG1lc3NhZ2U6IENoYW5uZWxNZXNzYWdlLCBjaGFubmVsPzogc3RyaW5nKSB7XG5cbiAgICBjb25zdCB1c2VyID0gdGhpcy51c2VyLnZhbHVlIHx8IHRoaXMudXNlci52YWx1ZVxuICAgIGNvbnN0IG1lc3NhZ2VJbmZvID0gQ2hhbm5lbE1lc3NhZ2UuYWRhcHQoeyAuLi5tZXNzYWdlLCBmcm9tVXNlcjogdXNlciB9KVxuXG4gICAgaWYodGhpcy53c0Nvbm5lY3Rpb24gJiYgdGhpcy5hcGlPcHRpb25zLndzKSB7XG5cbiAgICAgIGNvbnN0IHdzU2VydmVyID0gKGNoYW5uZWwpID8gY2hhbm5lbCA6IHRoaXMuYXBpT3B0aW9ucy53cy5pZFxuXG4gICAgICBpZihtZXNzYWdlSW5mby50b1VzZXIgPT09ICdhbGxDaGFubmVscycpIHtcbiAgICAgICAgdGhpcy5odHRwTWFuYWdlclNlcnZpY2Uuc2VuZEJyb2FkY2FzdChtZXNzYWdlSW5mbylcbiAgICAgIH0gZWxzZSBpZihtZXNzYWdlSW5mby50b1VzZXIgPT09ICdhbGxJbkNoYW5uZWwnKSB7XG4gICAgICAgIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLnNlbmRNZXNzYWdlSW5DaGFubmVsKHdzU2VydmVyLCBtZXNzYWdlSW5mbylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaHR0cE1hbmFnZXJTZXJ2aWNlLnNlbmRNZXNzYWdlVG9Vc2VyKHdzU2VydmVyLCBtZXNzYWdlSW5mbylcbiAgICAgIH1cblxuICAgIH1cblxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gTUlTQ1xuXG4gIHByaXZhdGUgaXNFbXB0eShvYmo6IGFueSkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhvYmopLmxlbmd0aCA9PT0gMFxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVSZXF1ZXN0T3B0aW9ucyhoZWFkZXJzPzogYW55KTogQXBpUmVxdWVzdCB7XG5cbiAgICBjb25zdCBvcHRpb25zID0gQXBpUmVxdWVzdC5hZGFwdCh7IC4uLnRoaXMuYXBpT3B0aW9ucyB9KVxuXG4gICAgb3B0aW9ucy5oZWFkZXJzID0gKGhlYWRlcnMpXG4gICAgICAgICAgPyB7IC4uLm9wdGlvbnMuaGVhZGVycywgLi4uaGVhZGVycyB9XG4gICAgICAgICAgOiB7IC4uLm9wdGlvbnMuaGVhZGVycyB9XG5cbiAgICByZXR1cm4gb3B0aW9uc1xuICB9XG5cbn1cbiJdfQ==
|