@techextensor/tab-core-utility 2.2.191 → 2.2.193
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/index.mjs +6 -1
- package/esm2022/lib/tab-core-utility/app/constants/api-constants.mjs +38 -22
- package/esm2022/lib/tab-core-utility/app/constants/common.mjs +14 -50
- package/esm2022/lib/tab-core-utility/app/constants/storage-constants.mjs +3 -2
- package/esm2022/lib/tab-core-utility/app/crud/tab-blueprint.service.mjs +41 -14
- package/esm2022/lib/tab-core-utility/app/crud/tab-crud.service.mjs +38 -49
- package/esm2022/lib/tab-core-utility/app/crud/tab-delete.service.mjs +84 -30
- package/esm2022/lib/tab-core-utility/app/crud/tab-formio.service.mjs +141 -12
- package/esm2022/lib/tab-core-utility/app/crud/tab-get.service.mjs +141 -46
- package/esm2022/lib/tab-core-utility/app/crud/tab-insert.service.mjs +89 -38
- package/esm2022/lib/tab-core-utility/app/crud/tab-update.service.mjs +156 -128
- package/esm2022/lib/tab-core-utility/app/enums/query.enum.mjs +7 -7
- package/esm2022/lib/tab-core-utility/app/helpers/auth-response.adapter.mjs +79 -0
- package/esm2022/lib/tab-core-utility/app/helpers/common/app.helpers.mjs +30 -25
- package/esm2022/lib/tab-core-utility/app/helpers/common/dsq.helpers.mjs +9 -11
- package/esm2022/lib/tab-core-utility/app/helpers/common/meta-data.helpers.mjs +13 -13
- package/esm2022/lib/tab-core-utility/app/helpers/common/req-res.helpers.mjs +7 -45
- package/esm2022/lib/tab-core-utility/app/helpers/common/where-clause.helpers.mjs +79 -76
- package/esm2022/lib/tab-core-utility/app/helpers/login-response.adapter.mjs +76 -0
- package/esm2022/lib/tab-core-utility/app/helpers/response.adapter.mjs +38 -0
- package/esm2022/lib/tab-core-utility/app/helpers/screen/grid.helpers.mjs +8 -4
- package/esm2022/lib/tab-core-utility/app/helpers/screen/media-upload.helpers.mjs +4 -4
- package/esm2022/lib/tab-core-utility/app/helpers/screen/screen.helpers.mjs +8 -33
- package/esm2022/lib/tab-core-utility/app/helpers/transition-response.adapter.mjs +83 -0
- package/esm2022/lib/tab-core-utility/app/interfaces/auth.interface.mjs +1 -1
- package/esm2022/lib/tab-core-utility/app/interfaces/common.interface.mjs +1 -1
- package/esm2022/lib/tab-core-utility/app/interfaces/signalr.interface.mjs +42 -0
- package/esm2022/lib/tab-core-utility/app/models/api-query.class.mjs +39 -1
- package/esm2022/lib/tab-core-utility/app/models/app-field.model.mjs +36 -7
- package/esm2022/lib/tab-core-utility/app/models/app-object.model.mjs +84 -47
- package/esm2022/lib/tab-core-utility/app/models/app-screen.model.mjs +24 -13
- package/esm2022/lib/tab-core-utility/app/models/data-source-query.model.mjs +57 -23
- package/esm2022/lib/tab-core-utility/app/models/filter.model.mjs +21 -10
- package/esm2022/lib/tab-core-utility/app/models/parameter.model.mjs +12 -6
- package/esm2022/lib/tab-core-utility/app/models/sort.model.mjs +11 -4
- package/esm2022/lib/tab-core-utility/app/utils/json.util.mjs +17 -16
- package/esm2022/lib/tab-core-utility/app/utils/req-res.util.mjs +1 -55
- package/esm2022/lib/tab-core-utility/app/utils/tab-app.util.mjs +1 -164
- package/esm2022/lib/tab-core-utility/auth/auth.service.mjs +36 -11
- package/esm2022/lib/tab-core-utility/core/http-client/api.service.mjs +78 -1
- package/esm2022/lib/tab-core-utility/core/service/signalr/operation-tracker.service.mjs +90 -0
- package/esm2022/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.mjs +268 -0
- package/esm2022/lib/tab-core-utility/core/service/signalr/signalr.service.mjs +207 -0
- package/index.d.ts +5 -0
- package/lib/tab-core-utility/app/constants/api-constants.d.ts +25 -18
- package/lib/tab-core-utility/app/constants/common.d.ts +9 -0
- package/lib/tab-core-utility/app/constants/storage-constants.d.ts +2 -1
- package/lib/tab-core-utility/app/crud/tab-blueprint.service.d.ts +14 -8
- package/lib/tab-core-utility/app/crud/tab-crud.service.d.ts +8 -1
- package/lib/tab-core-utility/app/crud/tab-delete.service.d.ts +20 -10
- package/lib/tab-core-utility/app/crud/tab-formio.service.d.ts +33 -6
- package/lib/tab-core-utility/app/crud/tab-get.service.d.ts +52 -10
- package/lib/tab-core-utility/app/crud/tab-insert.service.d.ts +16 -21
- package/lib/tab-core-utility/app/crud/tab-update.service.d.ts +34 -19
- package/lib/tab-core-utility/app/enums/query.enum.d.ts +3 -6
- package/lib/tab-core-utility/app/helpers/auth-response.adapter.d.ts +32 -0
- package/lib/tab-core-utility/app/helpers/common/app.helpers.d.ts +6 -9
- package/lib/tab-core-utility/app/helpers/common/dsq.helpers.d.ts +3 -0
- package/lib/tab-core-utility/app/helpers/common/meta-data.helpers.d.ts +3 -3
- package/lib/tab-core-utility/app/helpers/common/req-res.helpers.d.ts +7 -51
- package/lib/tab-core-utility/app/helpers/common/where-clause.helpers.d.ts +1 -0
- package/lib/tab-core-utility/app/helpers/login-response.adapter.d.ts +29 -0
- package/lib/tab-core-utility/app/helpers/response.adapter.d.ts +22 -0
- package/lib/tab-core-utility/app/helpers/screen/grid.helpers.d.ts +2 -1
- package/lib/tab-core-utility/app/helpers/screen/media-upload.helpers.d.ts +1 -1
- package/lib/tab-core-utility/app/helpers/screen/screen.helpers.d.ts +1 -0
- package/lib/tab-core-utility/app/helpers/transition-response.adapter.d.ts +30 -0
- package/lib/tab-core-utility/app/interfaces/auth.interface.d.ts +1 -1
- package/lib/tab-core-utility/app/interfaces/common.interface.d.ts +56 -6
- package/lib/tab-core-utility/app/interfaces/signalr.interface.d.ts +84 -0
- package/lib/tab-core-utility/app/models/api-query.class.d.ts +54 -9
- package/lib/tab-core-utility/app/models/app-field.model.d.ts +4 -2
- package/lib/tab-core-utility/app/models/app-object.model.d.ts +5 -3
- package/lib/tab-core-utility/app/models/app-screen.model.d.ts +2 -2
- package/lib/tab-core-utility/app/models/data-source-query.model.d.ts +7 -2
- package/lib/tab-core-utility/app/models/filter.model.d.ts +2 -2
- package/lib/tab-core-utility/app/models/parameter.model.d.ts +2 -2
- package/lib/tab-core-utility/app/models/sort.model.d.ts +1 -1
- package/lib/tab-core-utility/app/utils/json.util.d.ts +3 -2
- package/lib/tab-core-utility/app/utils/req-res.util.d.ts +1 -9
- package/lib/tab-core-utility/app/utils/tab-app.util.d.ts +0 -61
- package/lib/tab-core-utility/auth/auth.service.d.ts +6 -0
- package/lib/tab-core-utility/core/http-client/api.service.d.ts +46 -0
- package/lib/tab-core-utility/core/service/signalr/operation-tracker.service.d.ts +40 -0
- package/lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service.d.ts +73 -0
- package/lib/tab-core-utility/core/service/signalr/signalr.service.d.ts +122 -0
- package/package.json +3 -2
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { inject, Injectable, signal } from '@angular/core';
|
|
2
|
+
import * as signalR from '@microsoft/signalr';
|
|
3
|
+
import { Subject } from 'rxjs';
|
|
4
|
+
import { Common } from '../../../app/constants/common';
|
|
5
|
+
import { SIGNALR_HUB_METHODS, SIGNALR_EVENTS, CRUD_OPERATION, CONNECTION_STATE, } from '../../../app/interfaces/signalr.interface';
|
|
6
|
+
import { StorageConstants } from '../../../app/constants/storage-constants';
|
|
7
|
+
import { SessionStorageService } from '../../../auth/session-storage.service';
|
|
8
|
+
import { LocalStorageService } from '../../../auth/local-storage.service';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
/**
|
|
11
|
+
* SignalR Infrastructure Service
|
|
12
|
+
* Handles low-level WebSocket connection, group management, and reconnection
|
|
13
|
+
* Internal use only - components should use SignalRService instead
|
|
14
|
+
*/
|
|
15
|
+
export class SignalRInfrastructure {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.hubConnection = null;
|
|
18
|
+
// Session storage
|
|
19
|
+
this.sessionStorageService = inject(SessionStorageService);
|
|
20
|
+
// local storage
|
|
21
|
+
this.localStorageService = inject(LocalStorageService);
|
|
22
|
+
// Connection state as signal
|
|
23
|
+
this.connectionState = signal(CONNECTION_STATE.DISCONNECTED);
|
|
24
|
+
// Notification stream (internal - emits to SignalRService)
|
|
25
|
+
this.notifications$ = new Subject();
|
|
26
|
+
// Track active groups to rejoin after reconnection
|
|
27
|
+
this.activeGroups = new Set();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Helper method to get value from storage
|
|
31
|
+
* @param type The type of storage, 'Session' or 'Local'
|
|
32
|
+
* @param key The key to retrieve the value for
|
|
33
|
+
* @returns The value from storage, or null if not available
|
|
34
|
+
*/
|
|
35
|
+
getFromStorage(type, key) {
|
|
36
|
+
try {
|
|
37
|
+
let info = null;
|
|
38
|
+
if (type === 'Session') {
|
|
39
|
+
// Get value from session storage
|
|
40
|
+
info = this.sessionStorageService.getSessionStorage(key);
|
|
41
|
+
}
|
|
42
|
+
if (type === 'Local') {
|
|
43
|
+
// Get value from local storage
|
|
44
|
+
info = this.localStorageService.getLocalStorage(key);
|
|
45
|
+
}
|
|
46
|
+
if (info && typeof info === 'string') {
|
|
47
|
+
// Parse the value if it's a string
|
|
48
|
+
info = JSON.parse(info);
|
|
49
|
+
}
|
|
50
|
+
return info;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// Log error if failed to get value from storage
|
|
54
|
+
console.warn('Failed to get current app ID from session:', error);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
get appId() {
|
|
59
|
+
const appInfo = this.getFromStorage('Session', StorageConstants.appInfo);
|
|
60
|
+
return appInfo?.Id || null;
|
|
61
|
+
}
|
|
62
|
+
get environmentId() {
|
|
63
|
+
const envInfo = this.getFromStorage('Session', StorageConstants.environmentInfo);
|
|
64
|
+
return envInfo?.Id || null;
|
|
65
|
+
}
|
|
66
|
+
get tenantId() {
|
|
67
|
+
const tenantInfo = this.getFromStorage('Local', StorageConstants.orgInfo);
|
|
68
|
+
return tenantInfo?.Id || null;
|
|
69
|
+
}
|
|
70
|
+
get token() {
|
|
71
|
+
const authInfo = this.getFromStorage('Local', StorageConstants.tokenInfo);
|
|
72
|
+
return authInfo?.token || null;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Connect to SignalR hub
|
|
76
|
+
*/
|
|
77
|
+
async connect() {
|
|
78
|
+
if (this.hubConnection?.state === signalR.HubConnectionState.Connected) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Get hub URL from Common (set during app initialization via Common.init())
|
|
82
|
+
const hubUrl = Common.signalRHubUrl;
|
|
83
|
+
if (!hubUrl) {
|
|
84
|
+
console.error('[SignalR] Hub URL not configured. Make sure Common.init() is called with environment.');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
this.connectionState.set(CONNECTION_STATE.CONNECTING);
|
|
89
|
+
this.hubConnection = new signalR.HubConnectionBuilder()
|
|
90
|
+
.withUrl(hubUrl, {
|
|
91
|
+
accessTokenFactory: () => this.token || '',
|
|
92
|
+
skipNegotiation: false,
|
|
93
|
+
transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.ServerSentEvents,
|
|
94
|
+
})
|
|
95
|
+
.withAutomaticReconnect({
|
|
96
|
+
nextRetryDelayInMilliseconds: (retryContext) => {
|
|
97
|
+
// Exponential backoff: 0s, 2s, 10s, 30s, max 60s
|
|
98
|
+
if (retryContext.elapsedMilliseconds < 60000) {
|
|
99
|
+
return Math.min(1000 * Math.pow(2, retryContext.previousRetryCount), 60000);
|
|
100
|
+
}
|
|
101
|
+
return null; // Stop retrying after 1 minute
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
.configureLogging(signalR.LogLevel.Information)
|
|
105
|
+
.build();
|
|
106
|
+
this.registerEventHandlers();
|
|
107
|
+
this.registerConnectionLifecycle();
|
|
108
|
+
await this.hubConnection.start();
|
|
109
|
+
this.connectionState.set(CONNECTION_STATE.CONNECTED);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
this.connectionState.set(CONNECTION_STATE.FAILED);
|
|
113
|
+
// Retry after 1 minute
|
|
114
|
+
setTimeout(() => this.connect(), 60 * 1000);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Register SignalR event handlers for CRUD notifications
|
|
119
|
+
*/
|
|
120
|
+
registerEventHandlers() {
|
|
121
|
+
if (!this.hubConnection)
|
|
122
|
+
return;
|
|
123
|
+
// INSERT notifications
|
|
124
|
+
this.hubConnection.on(SIGNALR_EVENTS.INSERT_COMPLETED, (...args) => {
|
|
125
|
+
const notification = this.extractNotification(args);
|
|
126
|
+
const enriched = { ...notification, operation: CRUD_OPERATION.INSERT, receivedAt: new Date() };
|
|
127
|
+
this.notifications$.next(enriched);
|
|
128
|
+
});
|
|
129
|
+
// UPDATE notifications
|
|
130
|
+
this.hubConnection.on(SIGNALR_EVENTS.UPDATE_COMPLETED, (...args) => {
|
|
131
|
+
const notification = this.extractNotification(args);
|
|
132
|
+
const enriched = { ...notification, operation: CRUD_OPERATION.UPDATE, receivedAt: new Date() };
|
|
133
|
+
this.notifications$.next(enriched);
|
|
134
|
+
});
|
|
135
|
+
// DELETE notifications
|
|
136
|
+
this.hubConnection.on(SIGNALR_EVENTS.DELETE_COMPLETED, (...args) => {
|
|
137
|
+
const notification = this.extractNotification(args);
|
|
138
|
+
const enriched = { ...notification, operation: CRUD_OPERATION.DELETE, receivedAt: new Date() };
|
|
139
|
+
this.notifications$.next(enriched);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Extract notification from SignalR callback args
|
|
144
|
+
* Handles both unwrapped (direct object) and wrapped ({ type, target, arguments }) formats
|
|
145
|
+
*/
|
|
146
|
+
extractNotification(args) {
|
|
147
|
+
const data = args[0];
|
|
148
|
+
// If SignalR didn't unwrap: data is raw SignalRMessage with { type, target, arguments: [...] }
|
|
149
|
+
if (data?.arguments && Array.isArray(data.arguments)) {
|
|
150
|
+
return data.arguments[0];
|
|
151
|
+
}
|
|
152
|
+
// If SignalR unwrapped: data is the notification directly
|
|
153
|
+
return data;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Register connection lifecycle handlers
|
|
157
|
+
*/
|
|
158
|
+
registerConnectionLifecycle() {
|
|
159
|
+
if (!this.hubConnection)
|
|
160
|
+
return;
|
|
161
|
+
this.hubConnection.onreconnecting(() => {
|
|
162
|
+
this.connectionState.set(CONNECTION_STATE.RECONNECTING);
|
|
163
|
+
});
|
|
164
|
+
this.hubConnection.onreconnected(() => {
|
|
165
|
+
this.connectionState.set(CONNECTION_STATE.CONNECTED);
|
|
166
|
+
// Rejoin all groups after reconnection
|
|
167
|
+
this.rejoinGroups();
|
|
168
|
+
});
|
|
169
|
+
this.hubConnection.onclose(() => {
|
|
170
|
+
this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
|
|
171
|
+
// Try to reconnect
|
|
172
|
+
setTimeout(() => this.connect(), 60 * 1000);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Join SignalR group for an AppObject
|
|
177
|
+
*/
|
|
178
|
+
async joinGroup(appObjectId) {
|
|
179
|
+
if (!this.hubConnection || this.hubConnection.state !== signalR.HubConnectionState.Connected) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
if (!this.tenantId || !this.appId || !this.environmentId || !appObjectId) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
await this.hubConnection.invoke(SIGNALR_HUB_METHODS.JOIN_GROUP, this.tenantId, this.appId, this.environmentId, appObjectId);
|
|
187
|
+
// Track this group for reconnection
|
|
188
|
+
this.activeGroups.add(appObjectId);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
console.error(`[SignalR] Failed to join group: ${appObjectId}`, error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Leave SignalR group
|
|
196
|
+
*/
|
|
197
|
+
async leaveGroup(appObjectId) {
|
|
198
|
+
if (!this.hubConnection || this.hubConnection.state !== signalR.HubConnectionState.Connected) {
|
|
199
|
+
// Remove from tracking even if not connected
|
|
200
|
+
this.activeGroups.delete(appObjectId);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (!this.tenantId || !this.appId || !this.environmentId || !appObjectId) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
await this.hubConnection.invoke(SIGNALR_HUB_METHODS.LEAVE_GROUP, this.tenantId, this.appId, this.environmentId, appObjectId);
|
|
208
|
+
// Remove from tracking
|
|
209
|
+
this.activeGroups.delete(appObjectId);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
console.error(`[SignalR] Failed to leave group: ${appObjectId}`, error);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Rejoin all active groups after reconnection
|
|
217
|
+
* This ensures components continue receiving notifications after network interruption
|
|
218
|
+
*/
|
|
219
|
+
async rejoinGroups() {
|
|
220
|
+
if (this.activeGroups.size === 0) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Get list of groups to rejoin
|
|
224
|
+
const groups = Array.from(this.activeGroups);
|
|
225
|
+
// Clear the set (will be re-added during joinGroup)
|
|
226
|
+
this.activeGroups.clear();
|
|
227
|
+
// Rejoin each group
|
|
228
|
+
for (const appObjectId of groups) {
|
|
229
|
+
await this.joinGroup(appObjectId);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Check if connected
|
|
234
|
+
*/
|
|
235
|
+
isConnected() {
|
|
236
|
+
return this.hubConnection?.state === signalR.HubConnectionState.Connected;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Disconnect from SignalR hub (cleanup)
|
|
240
|
+
*/
|
|
241
|
+
async disconnect() {
|
|
242
|
+
if (this.hubConnection) {
|
|
243
|
+
try {
|
|
244
|
+
await this.hubConnection.stop();
|
|
245
|
+
this.hubConnection = null;
|
|
246
|
+
this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
console.error('[SignalR] Error during disconnect:', error);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get active groups (for debugging)
|
|
255
|
+
*/
|
|
256
|
+
getActiveGroups() {
|
|
257
|
+
return Array.from(this.activeGroups);
|
|
258
|
+
}
|
|
259
|
+
static { this.ɵfac = function SignalRInfrastructure_Factory(t) { return new (t || SignalRInfrastructure)(); }; }
|
|
260
|
+
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: SignalRInfrastructure, factory: SignalRInfrastructure.ɵfac, providedIn: 'root' }); }
|
|
261
|
+
}
|
|
262
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SignalRInfrastructure, [{
|
|
263
|
+
type: Injectable,
|
|
264
|
+
args: [{
|
|
265
|
+
providedIn: 'root',
|
|
266
|
+
}]
|
|
267
|
+
}], null, null); })();
|
|
268
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFJTCxtQkFBbUIsRUFDbkIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7QUFFMUU7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJVSxrQkFBYSxHQUFpQyxJQUFJLENBQUM7UUFFM0Qsa0JBQWtCO1FBQ1QsMEJBQXFCLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFFL0QsZ0JBQWdCO1FBQ1Asd0JBQW1CLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFM0QsNkJBQTZCO1FBQ3BCLG9CQUFlLEdBQUcsTUFBTSxDQUFrQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRiwyREFBMkQ7UUFDbEQsbUJBQWMsR0FBRyxJQUFJLE9BQU8sRUFBb0IsQ0FBQztRQUUxRCxtREFBbUQ7UUFDM0MsaUJBQVksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0tBMFIxQztJQXhSQzs7Ozs7T0FLRztJQUNLLGNBQWMsQ0FBQyxJQUFZLEVBQUUsR0FBVztRQUM5QyxJQUFJLENBQUM7WUFDSCxJQUFJLElBQUksR0FBUSxJQUFJLENBQUM7WUFFckIsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZCLGlDQUFpQztnQkFDakMsSUFBSSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzRCxDQUFDO1lBRUQsSUFBSSxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQ3JCLCtCQUErQjtnQkFDL0IsSUFBSSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdkQsQ0FBQztZQUVELElBQUksSUFBSSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUNyQyxtQ0FBbUM7Z0JBQ25DLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFCLENBQUM7WUFFRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsZ0RBQWdEO1lBQ2hELE9BQU8sQ0FBQyxJQUFJLENBQUMsNENBQTRDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbEUsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksS0FBSztRQUNQLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3pFLE9BQU8sT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLENBQUM7SUFDN0IsQ0FBQztJQUVELElBQUksYUFBYTtRQUNmLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2pGLE9BQU8sT0FBTyxFQUFFLEVBQUUsSUFBSSxJQUFJLENBQUM7SUFDN0IsQ0FBQztJQUVELElBQUksUUFBUTtRQUNWLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFFLE9BQU8sVUFBVSxFQUFFLEVBQUUsSUFBSSxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVELElBQUksS0FBSztRQUNQLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sUUFBUSxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUM7SUFDakMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLE9BQU87UUFDWCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsS0FBSyxLQUFLLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN2RSxPQUFPO1FBQ1QsQ0FBQztRQUVELDRFQUE0RTtRQUM1RSxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDO1FBRXBDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLE9BQU8sQ0FBQyxLQUFLLENBQUMsdUZBQXVGLENBQUMsQ0FBQztZQUN2RyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRXRELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxPQUFPLENBQUMsb0JBQW9CLEVBQUU7aUJBQ3BELE9BQU8sQ0FBQyxNQUFNLEVBQUU7Z0JBQ2Ysa0JBQWtCLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO2dCQUMxQyxlQUFlLEVBQUUsS0FBSztnQkFDdEIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQjthQUM3RixDQUFDO2lCQUNELHNCQUFzQixDQUFDO2dCQUN0Qiw0QkFBNEIsRUFBRSxDQUFDLFlBQWlCLEVBQUUsRUFBRTtvQkFDbEQsaURBQWlEO29CQUNqRCxJQUFJLFlBQVksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLEVBQUUsQ0FBQzt3QkFDN0MsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsa0JBQWtCLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDOUUsQ0FBQztvQkFDRCxPQUFPLElBQUksQ0FBQyxDQUFDLCtCQUErQjtnQkFDOUMsQ0FBQzthQUNGLENBQUM7aUJBQ0QsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7aUJBQzlDLEtBQUssRUFBRSxDQUFDO1lBRVgsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7WUFFbkMsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRWpDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFbEQsdUJBQXVCO1lBQ3ZCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQzlDLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxxQkFBcUI7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUVoQyx1QkFBdUI7UUFDdkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUFFLENBQUMsR0FBRyxJQUFXLEVBQUUsRUFBRTtZQUN4RSxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEQsTUFBTSxRQUFRLEdBQUcsRUFBRSxHQUFHLFlBQVksRUFBRSxTQUFTLEVBQUUsY0FBYyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQy9GLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO1FBRUgsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLEdBQUcsSUFBVyxFQUFFLEVBQUU7WUFDeEUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BELE1BQU0sUUFBUSxHQUFHLEVBQUUsR0FBRyxZQUFZLEVBQUUsU0FBUyxFQUFFLGNBQWMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUMvRixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztRQUVILHVCQUF1QjtRQUN2QixJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxHQUFHLElBQVcsRUFBRSxFQUFFO1lBQ3hFLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxNQUFNLFFBQVEsR0FBRyxFQUFFLEdBQUcsWUFBWSxFQUFFLFNBQVMsRUFBRSxjQUFjLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLElBQUksRUFBRSxFQUFFLENBQUM7WUFDL0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssbUJBQW1CLENBQUMsSUFBVztRQUNyQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFckIsK0ZBQStGO1FBQy9GLElBQUksSUFBSSxFQUFFLFNBQVMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3JELE9BQVEsSUFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUVELDBEQUEwRDtRQUMxRCxPQUFPLElBQXdCLENBQUM7SUFDbEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssMkJBQTJCO1FBQ2pDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFFaEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFO1lBQ3JDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzFELENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFO1lBQ3BDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRXJELHVDQUF1QztZQUN2QyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDOUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7WUFFeEQsbUJBQW1CO1lBQ25CLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FBQyxXQUFtQjtRQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssS0FBSyxPQUFPLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDN0YsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3pFLE9BQU87WUFDVCxDQUFDO1lBRUQsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FDN0IsbUJBQW1CLENBQUMsVUFBVSxFQUM5QixJQUFJLENBQUMsUUFBUSxFQUNiLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLGFBQWEsRUFDbEIsV0FBVyxDQUNaLENBQUM7WUFFRixvQ0FBb0M7WUFDcEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxXQUFXLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6RSxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFVBQVUsQ0FBQyxXQUFtQjtRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssS0FBSyxPQUFPLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDN0YsNkNBQTZDO1lBQzdDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3RDLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3pFLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FDN0IsbUJBQW1CLENBQUMsV0FBVyxFQUMvQixJQUFJLENBQUMsUUFBUSxFQUNiLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLGFBQWEsRUFDbEIsV0FBVyxDQUNaLENBQUM7WUFFRix1QkFBdUI7WUFDdkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxXQUFXLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMxRSxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLEtBQUssQ0FBQyxZQUFZO1FBQ3hCLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDakMsT0FBTztRQUNULENBQUM7UUFFRCwrQkFBK0I7UUFDL0IsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFN0Msb0RBQW9EO1FBQ3BELElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFMUIsb0JBQW9CO1FBQ3BCLEtBQUssTUFBTSxXQUFXLElBQUksTUFBTSxFQUFFLENBQUM7WUFDakMsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLEtBQUssS0FBSyxPQUFPLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDO0lBQzVFLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxVQUFVO1FBQ2QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzFELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDN0QsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDO3NGQXpTVSxxQkFBcUI7dUVBQXJCLHFCQUFxQixXQUFyQixxQkFBcUIsbUJBRnBCLE1BQU07O2lGQUVQLHFCQUFxQjtjQUhqQyxVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgKiBhcyBzaWduYWxSIGZyb20gJ0BtaWNyb3NvZnQvc2lnbmFscic7XHJcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgQ29tbW9uIH0gZnJvbSAnLi4vLi4vLi4vYXBwL2NvbnN0YW50cy9jb21tb24nO1xyXG5pbXBvcnQge1xyXG4gIENvbm5lY3Rpb25TdGF0ZSxcclxuICBDcnVkTm90aWZpY2F0aW9uLFxyXG4gIFNpZ25hbFJNZXNzYWdlLFxyXG4gIFNJR05BTFJfSFVCX01FVEhPRFMsXHJcbiAgU0lHTkFMUl9FVkVOVFMsXHJcbiAgQ1JVRF9PUEVSQVRJT04sXHJcbiAgQ09OTkVDVElPTl9TVEFURSxcclxufSBmcm9tICcuLi8uLi8uLi9hcHAvaW50ZXJmYWNlcy9zaWduYWxyLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IFN0b3JhZ2VDb25zdGFudHMgfSBmcm9tICcuLi8uLi8uLi9hcHAvY29uc3RhbnRzL3N0b3JhZ2UtY29uc3RhbnRzJztcclxuaW1wb3J0IHsgU2Vzc2lvblN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vYXV0aC9zZXNzaW9uLXN0b3JhZ2Uuc2VydmljZSc7XHJcbmltcG9ydCB7IExvY2FsU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9hdXRoL2xvY2FsLXN0b3JhZ2Uuc2VydmljZSc7XHJcblxyXG4vKipcclxuICogU2lnbmFsUiBJbmZyYXN0cnVjdHVyZSBTZXJ2aWNlXHJcbiAqIEhhbmRsZXMgbG93LWxldmVsIFdlYlNvY2tldCBjb25uZWN0aW9uLCBncm91cCBtYW5hZ2VtZW50LCBhbmQgcmVjb25uZWN0aW9uXHJcbiAqIEludGVybmFsIHVzZSBvbmx5IC0gY29tcG9uZW50cyBzaG91bGQgdXNlIFNpZ25hbFJTZXJ2aWNlIGluc3RlYWRcclxuICovXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTaWduYWxSSW5mcmFzdHJ1Y3R1cmUge1xyXG4gIHByaXZhdGUgaHViQ29ubmVjdGlvbjogc2lnbmFsUi5IdWJDb25uZWN0aW9uIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8vIFNlc3Npb24gc3RvcmFnZVxyXG4gIHJlYWRvbmx5IHNlc3Npb25TdG9yYWdlU2VydmljZSA9IGluamVjdChTZXNzaW9uU3RvcmFnZVNlcnZpY2UpO1xyXG5cclxuICAvLyBsb2NhbCBzdG9yYWdlXHJcbiAgcmVhZG9ubHkgbG9jYWxTdG9yYWdlU2VydmljZSA9IGluamVjdChMb2NhbFN0b3JhZ2VTZXJ2aWNlKTtcclxuXHJcbiAgLy8gQ29ubmVjdGlvbiBzdGF0ZSBhcyBzaWduYWxcclxuICByZWFkb25seSBjb25uZWN0aW9uU3RhdGUgPSBzaWduYWw8Q29ubmVjdGlvblN0YXRlPihDT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gIC8vIE5vdGlmaWNhdGlvbiBzdHJlYW0gKGludGVybmFsIC0gZW1pdHMgdG8gU2lnbmFsUlNlcnZpY2UpXHJcbiAgcmVhZG9ubHkgbm90aWZpY2F0aW9ucyQgPSBuZXcgU3ViamVjdDxDcnVkTm90aWZpY2F0aW9uPigpO1xyXG5cclxuICAvLyBUcmFjayBhY3RpdmUgZ3JvdXBzIHRvIHJlam9pbiBhZnRlciByZWNvbm5lY3Rpb25cclxuICBwcml2YXRlIGFjdGl2ZUdyb3VwcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xyXG5cclxuICAvKipcclxuICAgKiBIZWxwZXIgbWV0aG9kIHRvIGdldCB2YWx1ZSBmcm9tIHN0b3JhZ2VcclxuICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiBzdG9yYWdlLCAnU2Vzc2lvbicgb3IgJ0xvY2FsJ1xyXG4gICAqIEBwYXJhbSBrZXkgVGhlIGtleSB0byByZXRyaWV2ZSB0aGUgdmFsdWUgZm9yXHJcbiAgICogQHJldHVybnMgVGhlIHZhbHVlIGZyb20gc3RvcmFnZSwgb3IgbnVsbCBpZiBub3QgYXZhaWxhYmxlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRGcm9tU3RvcmFnZSh0eXBlOiBzdHJpbmcsIGtleTogc3RyaW5nKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBsZXQgaW5mbzogYW55ID0gbnVsbDtcclxuXHJcbiAgICAgIGlmICh0eXBlID09PSAnU2Vzc2lvbicpIHtcclxuICAgICAgICAvLyBHZXQgdmFsdWUgZnJvbSBzZXNzaW9uIHN0b3JhZ2VcclxuICAgICAgICBpbmZvID0gdGhpcy5zZXNzaW9uU3RvcmFnZVNlcnZpY2UuZ2V0U2Vzc2lvblN0b3JhZ2Uoa2V5KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHR5cGUgPT09ICdMb2NhbCcpIHtcclxuICAgICAgICAvLyBHZXQgdmFsdWUgZnJvbSBsb2NhbCBzdG9yYWdlXHJcbiAgICAgICAgaW5mbyA9IHRoaXMubG9jYWxTdG9yYWdlU2VydmljZS5nZXRMb2NhbFN0b3JhZ2Uoa2V5KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGluZm8gJiYgdHlwZW9mIGluZm8gPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgLy8gUGFyc2UgdGhlIHZhbHVlIGlmIGl0J3MgYSBzdHJpbmdcclxuICAgICAgICBpbmZvID0gSlNPTi5wYXJzZShpbmZvKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGluZm87XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAvLyBMb2cgZXJyb3IgaWYgZmFpbGVkIHRvIGdldCB2YWx1ZSBmcm9tIHN0b3JhZ2VcclxuICAgICAgY29uc29sZS53YXJuKCdGYWlsZWQgdG8gZ2V0IGN1cnJlbnQgYXBwIElEIGZyb20gc2Vzc2lvbjonLCBlcnJvcik7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IGFwcElkKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgYXBwSW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ1Nlc3Npb24nLCBTdG9yYWdlQ29uc3RhbnRzLmFwcEluZm8pO1xyXG4gICAgcmV0dXJuIGFwcEluZm8/LklkIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXQgZW52aXJvbm1lbnRJZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGVudkluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdTZXNzaW9uJywgU3RvcmFnZUNvbnN0YW50cy5lbnZpcm9ubWVudEluZm8pO1xyXG4gICAgcmV0dXJuIGVudkluZm8/LklkIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXQgdGVuYW50SWQoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCB0ZW5hbnRJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnTG9jYWwnLCBTdG9yYWdlQ29uc3RhbnRzLm9yZ0luZm8pO1xyXG4gICAgcmV0dXJuIHRlbmFudEluZm8/LklkIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXQgdG9rZW4oKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBhdXRoSW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ0xvY2FsJywgU3RvcmFnZUNvbnN0YW50cy50b2tlbkluZm8pO1xyXG4gICAgcmV0dXJuIGF1dGhJbmZvPy50b2tlbiB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29ubmVjdCB0byBTaWduYWxSIGh1YlxyXG4gICAqL1xyXG4gIGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAodGhpcy5odWJDb25uZWN0aW9uPy5zdGF0ZSA9PT0gc2lnbmFsUi5IdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBHZXQgaHViIFVSTCBmcm9tIENvbW1vbiAoc2V0IGR1cmluZyBhcHAgaW5pdGlhbGl6YXRpb24gdmlhIENvbW1vbi5pbml0KCkpXHJcbiAgICBjb25zdCBodWJVcmwgPSBDb21tb24uc2lnbmFsUkh1YlVybDtcclxuXHJcbiAgICBpZiAoIWh1YlVybCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdbU2lnbmFsUl0gSHViIFVSTCBub3QgY29uZmlndXJlZC4gTWFrZSBzdXJlIENvbW1vbi5pbml0KCkgaXMgY2FsbGVkIHdpdGggZW52aXJvbm1lbnQuJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNUSU5HKTtcclxuXHJcbiAgICAgIHRoaXMuaHViQ29ubmVjdGlvbiA9IG5ldyBzaWduYWxSLkh1YkNvbm5lY3Rpb25CdWlsZGVyKClcclxuICAgICAgICAud2l0aFVybChodWJVcmwsIHtcclxuICAgICAgICAgIGFjY2Vzc1Rva2VuRmFjdG9yeTogKCkgPT4gdGhpcy50b2tlbiB8fCAnJyxcclxuICAgICAgICAgIHNraXBOZWdvdGlhdGlvbjogZmFsc2UsXHJcbiAgICAgICAgICB0cmFuc3BvcnQ6IHNpZ25hbFIuSHR0cFRyYW5zcG9ydFR5cGUuV2ViU29ja2V0cyB8IHNpZ25hbFIuSHR0cFRyYW5zcG9ydFR5cGUuU2VydmVyU2VudEV2ZW50cyxcclxuICAgICAgICB9KVxyXG4gICAgICAgIC53aXRoQXV0b21hdGljUmVjb25uZWN0KHtcclxuICAgICAgICAgIG5leHRSZXRyeURlbGF5SW5NaWxsaXNlY29uZHM6IChyZXRyeUNvbnRleHQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAvLyBFeHBvbmVudGlhbCBiYWNrb2ZmOiAwcywgMnMsIDEwcywgMzBzLCBtYXggNjBzXHJcbiAgICAgICAgICAgIGlmIChyZXRyeUNvbnRleHQuZWxhcHNlZE1pbGxpc2Vjb25kcyA8IDYwMDAwKSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKDEwMDAgKiBNYXRoLnBvdygyLCByZXRyeUNvbnRleHQucHJldmlvdXNSZXRyeUNvdW50KSwgNjAwMDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyBTdG9wIHJldHJ5aW5nIGFmdGVyIDEgbWludXRlXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmNvbmZpZ3VyZUxvZ2dpbmcoc2lnbmFsUi5Mb2dMZXZlbC5JbmZvcm1hdGlvbilcclxuICAgICAgICAuYnVpbGQoKTtcclxuXHJcbiAgICAgIHRoaXMucmVnaXN0ZXJFdmVudEhhbmRsZXJzKCk7XHJcbiAgICAgIHRoaXMucmVnaXN0ZXJDb25uZWN0aW9uTGlmZWN5Y2xlKCk7XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhcnQoKTtcclxuXHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG5cclxuICAgICAgLy8gUmV0cnkgYWZ0ZXIgMSBtaW51dGVcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNvbm5lY3QoKSwgNjAgKiAxMDAwKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdGVyIFNpZ25hbFIgZXZlbnQgaGFuZGxlcnMgZm9yIENSVUQgbm90aWZpY2F0aW9uc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVnaXN0ZXJFdmVudEhhbmRsZXJzKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24pIHJldHVybjtcclxuXHJcbiAgICAvLyBJTlNFUlQgbm90aWZpY2F0aW9uc1xyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKFNJR05BTFJfRVZFTlRTLklOU0VSVF9DT01QTEVURUQsICguLi5hcmdzOiBhbnlbXSkgPT4ge1xyXG4gICAgICBjb25zdCBub3RpZmljYXRpb24gPSB0aGlzLmV4dHJhY3ROb3RpZmljYXRpb24oYXJncyk7XHJcbiAgICAgIGNvbnN0IGVucmljaGVkID0geyAuLi5ub3RpZmljYXRpb24sIG9wZXJhdGlvbjogQ1JVRF9PUEVSQVRJT04uSU5TRVJULCByZWNlaXZlZEF0OiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyQubmV4dChlbnJpY2hlZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBVUERBVEUgbm90aWZpY2F0aW9uc1xyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKFNJR05BTFJfRVZFTlRTLlVQREFURV9DT01QTEVURUQsICguLi5hcmdzOiBhbnlbXSkgPT4ge1xyXG4gICAgICBjb25zdCBub3RpZmljYXRpb24gPSB0aGlzLmV4dHJhY3ROb3RpZmljYXRpb24oYXJncyk7XHJcbiAgICAgIGNvbnN0IGVucmljaGVkID0geyAuLi5ub3RpZmljYXRpb24sIG9wZXJhdGlvbjogQ1JVRF9PUEVSQVRJT04uVVBEQVRFLCByZWNlaXZlZEF0OiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyQubmV4dChlbnJpY2hlZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBERUxFVEUgbm90aWZpY2F0aW9uc1xyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKFNJR05BTFJfRVZFTlRTLkRFTEVURV9DT01QTEVURUQsICguLi5hcmdzOiBhbnlbXSkgPT4ge1xyXG4gICAgICBjb25zdCBub3RpZmljYXRpb24gPSB0aGlzLmV4dHJhY3ROb3RpZmljYXRpb24oYXJncyk7XHJcbiAgICAgIGNvbnN0IGVucmljaGVkID0geyAuLi5ub3RpZmljYXRpb24sIG9wZXJhdGlvbjogQ1JVRF9PUEVSQVRJT04uREVMRVRFLCByZWNlaXZlZEF0OiBuZXcgRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyQubmV4dChlbnJpY2hlZCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4dHJhY3Qgbm90aWZpY2F0aW9uIGZyb20gU2lnbmFsUiBjYWxsYmFjayBhcmdzXHJcbiAgICogSGFuZGxlcyBib3RoIHVud3JhcHBlZCAoZGlyZWN0IG9iamVjdCkgYW5kIHdyYXBwZWQgKHsgdHlwZSwgdGFyZ2V0LCBhcmd1bWVudHMgfSkgZm9ybWF0c1xyXG4gICAqL1xyXG4gIHByaXZhdGUgZXh0cmFjdE5vdGlmaWNhdGlvbihhcmdzOiBhbnlbXSk6IENydWROb3RpZmljYXRpb24ge1xyXG4gICAgY29uc3QgZGF0YSA9IGFyZ3NbMF07XHJcblxyXG4gICAgLy8gSWYgU2lnbmFsUiBkaWRuJ3QgdW53cmFwOiBkYXRhIGlzIHJhdyBTaWduYWxSTWVzc2FnZSB3aXRoIHsgdHlwZSwgdGFyZ2V0LCBhcmd1bWVudHM6IFsuLi5dIH1cclxuICAgIGlmIChkYXRhPy5hcmd1bWVudHMgJiYgQXJyYXkuaXNBcnJheShkYXRhLmFyZ3VtZW50cykpIHtcclxuICAgICAgcmV0dXJuIChkYXRhIGFzIFNpZ25hbFJNZXNzYWdlKS5hcmd1bWVudHNbMF07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgU2lnbmFsUiB1bndyYXBwZWQ6IGRhdGEgaXMgdGhlIG5vdGlmaWNhdGlvbiBkaXJlY3RseVxyXG4gICAgcmV0dXJuIGRhdGEgYXMgQ3J1ZE5vdGlmaWNhdGlvbjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdGVyIGNvbm5lY3Rpb24gbGlmZWN5Y2xlIGhhbmRsZXJzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZWdpc3RlckNvbm5lY3Rpb25MaWZlY3ljbGUoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbikgcmV0dXJuO1xyXG5cclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbnJlY29ubmVjdGluZygoKSA9PiB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLlJFQ09OTkVDVElORyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25yZWNvbm5lY3RlZCgoKSA9PiB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcblxyXG4gICAgICAvLyBSZWpvaW4gYWxsIGdyb3VwcyBhZnRlciByZWNvbm5lY3Rpb25cclxuICAgICAgdGhpcy5yZWpvaW5Hcm91cHMoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbmNsb3NlKCgpID0+IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuRElTQ09OTkVDVEVEKTtcclxuXHJcbiAgICAgIC8vIFRyeSB0byByZWNvbm5lY3RcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNvbm5lY3QoKSwgNjAgKiAxMDAwKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSm9pbiBTaWduYWxSIGdyb3VwIGZvciBhbiBBcHBPYmplY3RcclxuICAgKi9cclxuICBhc3luYyBqb2luR3JvdXAoYXBwT2JqZWN0SWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24gfHwgdGhpcy5odWJDb25uZWN0aW9uLnN0YXRlICE9PSBzaWduYWxSLkh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIGlmICghdGhpcy50ZW5hbnRJZCB8fCAhdGhpcy5hcHBJZCB8fCAhdGhpcy5lbnZpcm9ubWVudElkIHx8ICFhcHBPYmplY3RJZCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLmludm9rZShcclxuICAgICAgICBTSUdOQUxSX0hVQl9NRVRIT0RTLkpPSU5fR1JPVVAsXHJcbiAgICAgICAgdGhpcy50ZW5hbnRJZCxcclxuICAgICAgICB0aGlzLmFwcElkLFxyXG4gICAgICAgIHRoaXMuZW52aXJvbm1lbnRJZCxcclxuICAgICAgICBhcHBPYmplY3RJZFxyXG4gICAgICApO1xyXG5cclxuICAgICAgLy8gVHJhY2sgdGhpcyBncm91cCBmb3IgcmVjb25uZWN0aW9uXHJcbiAgICAgIHRoaXMuYWN0aXZlR3JvdXBzLmFkZChhcHBPYmplY3RJZCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBbU2lnbmFsUl0gRmFpbGVkIHRvIGpvaW4gZ3JvdXA6ICR7YXBwT2JqZWN0SWR9YCwgZXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTGVhdmUgU2lnbmFsUiBncm91cFxyXG4gICAqL1xyXG4gIGFzeW5jIGxlYXZlR3JvdXAoYXBwT2JqZWN0SWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24gfHwgdGhpcy5odWJDb25uZWN0aW9uLnN0YXRlICE9PSBzaWduYWxSLkh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQpIHtcclxuICAgICAgLy8gUmVtb3ZlIGZyb20gdHJhY2tpbmcgZXZlbiBpZiBub3QgY29ubmVjdGVkXHJcbiAgICAgIHRoaXMuYWN0aXZlR3JvdXBzLmRlbGV0ZShhcHBPYmplY3RJZCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMudGVuYW50SWQgfHwgIXRoaXMuYXBwSWQgfHwgIXRoaXMuZW52aXJvbm1lbnRJZCB8fCAhYXBwT2JqZWN0SWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5pbnZva2UoXHJcbiAgICAgICAgU0lHTkFMUl9IVUJfTUVUSE9EUy5MRUFWRV9HUk9VUCxcclxuICAgICAgICB0aGlzLnRlbmFudElkLFxyXG4gICAgICAgIHRoaXMuYXBwSWQsXHJcbiAgICAgICAgdGhpcy5lbnZpcm9ubWVudElkLFxyXG4gICAgICAgIGFwcE9iamVjdElkXHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyBSZW1vdmUgZnJvbSB0cmFja2luZ1xyXG4gICAgICB0aGlzLmFjdGl2ZUdyb3Vwcy5kZWxldGUoYXBwT2JqZWN0SWQpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgW1NpZ25hbFJdIEZhaWxlZCB0byBsZWF2ZSBncm91cDogJHthcHBPYmplY3RJZH1gLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWpvaW4gYWxsIGFjdGl2ZSBncm91cHMgYWZ0ZXIgcmVjb25uZWN0aW9uXHJcbiAgICogVGhpcyBlbnN1cmVzIGNvbXBvbmVudHMgY29udGludWUgcmVjZWl2aW5nIG5vdGlmaWNhdGlvbnMgYWZ0ZXIgbmV0d29yayBpbnRlcnJ1cHRpb25cclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIHJlam9pbkdyb3VwcygpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLmFjdGl2ZUdyb3Vwcy5zaXplID09PSAwKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBHZXQgbGlzdCBvZiBncm91cHMgdG8gcmVqb2luXHJcbiAgICBjb25zdCBncm91cHMgPSBBcnJheS5mcm9tKHRoaXMuYWN0aXZlR3JvdXBzKTtcclxuXHJcbiAgICAvLyBDbGVhciB0aGUgc2V0ICh3aWxsIGJlIHJlLWFkZGVkIGR1cmluZyBqb2luR3JvdXApXHJcbiAgICB0aGlzLmFjdGl2ZUdyb3Vwcy5jbGVhcigpO1xyXG5cclxuICAgIC8vIFJlam9pbiBlYWNoIGdyb3VwXHJcbiAgICBmb3IgKGNvbnN0IGFwcE9iamVjdElkIG9mIGdyb3Vwcykge1xyXG4gICAgICBhd2FpdCB0aGlzLmpvaW5Hcm91cChhcHBPYmplY3RJZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayBpZiBjb25uZWN0ZWRcclxuICAgKi9cclxuICBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmh1YkNvbm5lY3Rpb24/LnN0YXRlID09PSBzaWduYWxSLkh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEaXNjb25uZWN0IGZyb20gU2lnbmFsUiBodWIgKGNsZWFudXApXHJcbiAgICovXHJcbiAgYXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLmh1YkNvbm5lY3Rpb24pIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RvcCgpO1xyXG4gICAgICAgIHRoaXMuaHViQ29ubmVjdGlvbiA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuRElTQ09OTkVDVEVEKTtcclxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdbU2lnbmFsUl0gRXJyb3IgZHVyaW5nIGRpc2Nvbm5lY3Q6JywgZXJyb3IpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYWN0aXZlIGdyb3VwcyAoZm9yIGRlYnVnZ2luZylcclxuICAgKi9cclxuICBnZXRBY3RpdmVHcm91cHMoKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5hY3RpdmVHcm91cHMpO1xyXG4gIH1cclxufSJdfQ==
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Injectable, inject, computed } from '@angular/core';
|
|
2
|
+
import { SignalRInfrastructure } from './signalr-infrastructure.service';
|
|
3
|
+
import { OperationTrackerService } from './operation-tracker.service';
|
|
4
|
+
import { CONNECTION_STATE, } from '../../../app/interfaces/signalr.interface';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* SignalR Service
|
|
8
|
+
* Public API for:
|
|
9
|
+
* 1. Components to register for real-time CRUD notifications
|
|
10
|
+
* 2. Services (TabFormioService) to track async operations
|
|
11
|
+
*
|
|
12
|
+
* Usage in components:
|
|
13
|
+
* ```typescript
|
|
14
|
+
* ngOnInit() {
|
|
15
|
+
* this.signalRService.register(
|
|
16
|
+
* this.componentId,
|
|
17
|
+
* this.appObjectId,
|
|
18
|
+
* (notification) => this.handleNotification(notification)
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* ngOnDestroy() {
|
|
23
|
+
* this.signalRService.unregister(this.componentId, this.appObjectId);
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* Usage in services (TabFormioService):
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const correlationId = response.correlationId;
|
|
30
|
+
* this.signalRService.waitForOperation(correlationId).subscribe(notification => {
|
|
31
|
+
* // Handle completed operation
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export class SignalRService {
|
|
36
|
+
constructor() {
|
|
37
|
+
this.infrastructure = inject(SignalRInfrastructure);
|
|
38
|
+
this.operationTracker = inject(OperationTrackerService);
|
|
39
|
+
// Registry: Map<appObjectId, Map<componentId, callback>>
|
|
40
|
+
this.componentRegistry = new Map();
|
|
41
|
+
/**
|
|
42
|
+
* Get connection state (for UI indicators)
|
|
43
|
+
*/
|
|
44
|
+
this.connectionState = this.infrastructure.connectionState;
|
|
45
|
+
/**
|
|
46
|
+
* Check if currently connected
|
|
47
|
+
*/
|
|
48
|
+
this.isConnected = computed(() => this.connectionState() === CONNECTION_STATE.CONNECTED);
|
|
49
|
+
// Listen to notifications from infrastructure and route them
|
|
50
|
+
this.infrastructure.notifications$.subscribe((notification) => {
|
|
51
|
+
// 1. Check if this is a tracked async operation (processRequest)
|
|
52
|
+
this.operationTracker.handleNotification(notification);
|
|
53
|
+
// 2. Also notify components subscribed to this appObjectId (Grid, etc.)
|
|
54
|
+
this.notifyComponents(notification);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Establish a connection to the SignalR hub
|
|
59
|
+
*
|
|
60
|
+
* This method is idempotent - if the connection is already established, it will not be re-established.
|
|
61
|
+
* Hub URL is read from Common.signalRHubUrl (set during app initialization via Common.init())
|
|
62
|
+
*/
|
|
63
|
+
connect() {
|
|
64
|
+
this.infrastructure.connect();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Register component for real-time notifications
|
|
68
|
+
*
|
|
69
|
+
* @param componentId - Unique component identifier (generated by component)
|
|
70
|
+
* @param appObjectId - AppObject ID to subscribe to
|
|
71
|
+
* @param callback - Function to call when notification received
|
|
72
|
+
*/
|
|
73
|
+
register(componentId, appObjectId, callback) {
|
|
74
|
+
// Initialize map for this AppObject if doesn't exist
|
|
75
|
+
if (!this.componentRegistry.has(appObjectId)) {
|
|
76
|
+
this.componentRegistry.set(appObjectId, new Map());
|
|
77
|
+
}
|
|
78
|
+
const components = this.componentRegistry.get(appObjectId);
|
|
79
|
+
// First component for this AppObject? Join SignalR group
|
|
80
|
+
if (components.size === 0) {
|
|
81
|
+
this.infrastructure.joinGroup(appObjectId);
|
|
82
|
+
}
|
|
83
|
+
// Add component to registry
|
|
84
|
+
components.set(componentId, callback);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Unregister component (cleanup on component destroy)
|
|
88
|
+
*
|
|
89
|
+
* @param componentId - Component identifier to remove
|
|
90
|
+
* @param appObjectId - AppObject ID to unsubscribe from
|
|
91
|
+
*/
|
|
92
|
+
unregister(componentId, appObjectId) {
|
|
93
|
+
const components = this.componentRegistry.get(appObjectId);
|
|
94
|
+
if (!components) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// Remove component from registry
|
|
98
|
+
components.delete(componentId);
|
|
99
|
+
// Last component for this AppObject? Leave SignalR group
|
|
100
|
+
if (components.size === 0) {
|
|
101
|
+
this.infrastructure.leaveGroup(appObjectId);
|
|
102
|
+
this.componentRegistry.delete(appObjectId);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Wait for specific async operation to complete
|
|
107
|
+
* Used by TabFormioService for async processRequest operations
|
|
108
|
+
*
|
|
109
|
+
* @param correlationId - Correlation ID from backend response
|
|
110
|
+
* @param timeout - Optional timeout in milliseconds
|
|
111
|
+
* @returns Observable that emits when operation completes
|
|
112
|
+
*/
|
|
113
|
+
waitForOperation(correlationId, timeout) {
|
|
114
|
+
return this.operationTracker.waitForOperation(correlationId, timeout);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Register async operation for tracking
|
|
118
|
+
* Optional - waitForOperation handles registration automatically
|
|
119
|
+
*
|
|
120
|
+
* @param operation - Pending operation details
|
|
121
|
+
*/
|
|
122
|
+
registerOperation(operation) {
|
|
123
|
+
this.operationTracker.registerOperation(operation);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Check if operation is pending
|
|
127
|
+
*/
|
|
128
|
+
isOperationPending(correlationId) {
|
|
129
|
+
return this.operationTracker.isPending(correlationId);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Notify all registered components for an AppObject
|
|
133
|
+
* Called when notification received from SignalR hub
|
|
134
|
+
*/
|
|
135
|
+
notifyComponents(notification) {
|
|
136
|
+
const components = this.componentRegistry.get(notification.appObjectId);
|
|
137
|
+
if (!components || components.size === 0) {
|
|
138
|
+
// No components registered for this AppObject - ignore notification
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// Call each component's callback
|
|
142
|
+
components.forEach((callback, componentId) => {
|
|
143
|
+
try {
|
|
144
|
+
callback(notification);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
console.error(`[SignalR Service] Callback failed for component ${componentId}:`, error);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get active AppObject groups (for debugging)
|
|
153
|
+
*/
|
|
154
|
+
getActiveGroups() {
|
|
155
|
+
return Array.from(this.componentRegistry.keys());
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get component count for an AppObject (for debugging)
|
|
159
|
+
*/
|
|
160
|
+
getComponentCount(appObjectId) {
|
|
161
|
+
return this.componentRegistry.get(appObjectId)?.size || 0;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get total registered components across all AppObjects (for debugging)
|
|
165
|
+
*/
|
|
166
|
+
getTotalComponentCount() {
|
|
167
|
+
let total = 0;
|
|
168
|
+
this.componentRegistry.forEach((components) => {
|
|
169
|
+
total += components.size;
|
|
170
|
+
});
|
|
171
|
+
return total;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Get registry state (for debugging)
|
|
175
|
+
*/
|
|
176
|
+
getRegistryState() {
|
|
177
|
+
const state = [];
|
|
178
|
+
this.componentRegistry.forEach((components, appObjectId) => {
|
|
179
|
+
state.push({
|
|
180
|
+
appObjectId,
|
|
181
|
+
componentCount: components.size,
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
return state;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get pending operations count (for debugging)
|
|
188
|
+
*/
|
|
189
|
+
getPendingOperationsCount() {
|
|
190
|
+
return this.operationTracker.getPendingCount();
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get all pending operations (for debugging)
|
|
194
|
+
*/
|
|
195
|
+
getPendingOperations() {
|
|
196
|
+
return this.operationTracker.getAllPending();
|
|
197
|
+
}
|
|
198
|
+
static { this.ɵfac = function SignalRService_Factory(t) { return new (t || SignalRService)(); }; }
|
|
199
|
+
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: SignalRService, factory: SignalRService.ɵfac, providedIn: 'root' }); }
|
|
200
|
+
}
|
|
201
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SignalRService, [{
|
|
202
|
+
type: Injectable,
|
|
203
|
+
args: [{
|
|
204
|
+
providedIn: 'root',
|
|
205
|
+
}]
|
|
206
|
+
}], () => [], null); })();
|
|
207
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUN6RSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLEVBSUwsZ0JBQWdCLEdBQ2pCLE1BQU0sMkNBQTJDLENBQUM7O0FBRW5EOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNEJHO0FBSUgsTUFBTSxPQUFPLGNBQWM7SUFpQnpCO1FBaEJRLG1CQUFjLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDL0MscUJBQWdCLEdBQUcsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFFM0QseURBQXlEO1FBQ2pELHNCQUFpQixHQUFHLElBQUksR0FBRyxFQUE2QyxDQUFDO1FBRWpGOztXQUVHO1FBQ00sb0JBQWUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQztRQUUvRDs7V0FFRztRQUNNLGdCQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsS0FBSyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUczRiw2REFBNkQ7UUFDN0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7WUFDNUQsaUVBQWlFO1lBQ2pFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FB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O0lBQy9DLENBQUM7K0VBNUxVLGNBQWM7dUVBQWQsY0FBYyxXQUFkLGNBQWMsbUJBRmIsTUFBTTs7aUZBRVAsY0FBYztjQUgxQixVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QsIGNvbXB1dGVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgU2lnbmFsUkluZnJhc3RydWN0dXJlIH0gZnJvbSAnLi9zaWduYWxyLWluZnJhc3RydWN0dXJlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBPcGVyYXRpb25UcmFja2VyU2VydmljZSB9IGZyb20gJy4vb3BlcmF0aW9uLXRyYWNrZXIuc2VydmljZSc7XHJcbmltcG9ydCB7XHJcbiAgQ3J1ZE5vdGlmaWNhdGlvbixcclxuICBOb3RpZmljYXRpb25DYWxsYmFjayxcclxuICBQZW5kaW5nT3BlcmF0aW9uLFxyXG4gIENPTk5FQ1RJT05fU1RBVEUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvc2lnbmFsci5pbnRlcmZhY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNpZ25hbFIgU2VydmljZVxyXG4gKiBQdWJsaWMgQVBJIGZvcjpcclxuICogMS4gQ29tcG9uZW50cyB0byByZWdpc3RlciBmb3IgcmVhbC10aW1lIENSVUQgbm90aWZpY2F0aW9uc1xyXG4gKiAyLiBTZXJ2aWNlcyAoVGFiRm9ybWlvU2VydmljZSkgdG8gdHJhY2sgYXN5bmMgb3BlcmF0aW9uc1xyXG4gKlxyXG4gKiBVc2FnZSBpbiBjb21wb25lbnRzOlxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIG5nT25Jbml0KCkge1xyXG4gKiAgIHRoaXMuc2lnbmFsUlNlcnZpY2UucmVnaXN0ZXIoXHJcbiAqICAgICB0aGlzLmNvbXBvbmVudElkLFxyXG4gKiAgICAgdGhpcy5hcHBPYmplY3RJZCxcclxuICogICAgIChub3RpZmljYXRpb24pID0+IHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uKG5vdGlmaWNhdGlvbilcclxuICogICApO1xyXG4gKiB9XHJcbiAqXHJcbiAqIG5nT25EZXN0cm95KCkge1xyXG4gKiAgIHRoaXMuc2lnbmFsUlNlcnZpY2UudW5yZWdpc3Rlcih0aGlzLmNvbXBvbmVudElkLCB0aGlzLmFwcE9iamVjdElkKTtcclxuICogfVxyXG4gKiBgYGBcclxuICpcclxuICogVXNhZ2UgaW4gc2VydmljZXMgKFRhYkZvcm1pb1NlcnZpY2UpOlxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSByZXNwb25zZS5jb3JyZWxhdGlvbklkO1xyXG4gKiB0aGlzLnNpZ25hbFJTZXJ2aWNlLndhaXRGb3JPcGVyYXRpb24oY29ycmVsYXRpb25JZCkuc3Vic2NyaWJlKG5vdGlmaWNhdGlvbiA9PiB7XHJcbiAqICAgLy8gSGFuZGxlIGNvbXBsZXRlZCBvcGVyYXRpb25cclxuICogfSk7XHJcbiAqIGBgYFxyXG4gKi9cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFNpZ25hbFJTZXJ2aWNlIHtcclxuICBwcml2YXRlIGluZnJhc3RydWN0dXJlID0gaW5qZWN0KFNpZ25hbFJJbmZyYXN0cnVjdHVyZSk7XHJcbiAgcHJpdmF0ZSBvcGVyYXRpb25UcmFja2VyID0gaW5qZWN0KE9wZXJhdGlvblRyYWNrZXJTZXJ2aWNlKTtcclxuXHJcbiAgLy8gUmVnaXN0cnk6IE1hcDxhcHBPYmplY3RJZCwgTWFwPGNvbXBvbmVudElkLCBjYWxsYmFjaz4+XHJcbiAgcHJpdmF0ZSBjb21wb25lbnRSZWdpc3RyeSA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBOb3RpZmljYXRpb25DYWxsYmFjaz4+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBjb25uZWN0aW9uIHN0YXRlIChmb3IgVUkgaW5kaWNhdG9ycylcclxuICAgKi9cclxuICByZWFkb25seSBjb25uZWN0aW9uU3RhdGUgPSB0aGlzLmluZnJhc3RydWN0dXJlLmNvbm5lY3Rpb25TdGF0ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgY3VycmVudGx5IGNvbm5lY3RlZFxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzQ29ubmVjdGVkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb25uZWN0aW9uU3RhdGUoKSA9PT0gQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG5cclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIC8vIExpc3RlbiB0byBub3RpZmljYXRpb25zIGZyb20gaW5mcmFzdHJ1Y3R1cmUgYW5kIHJvdXRlIHRoZW1cclxuICAgIHRoaXMuaW5mcmFzdHJ1Y3R1cmUubm90aWZpY2F0aW9ucyQuc3Vic2NyaWJlKChub3RpZmljYXRpb24pID0+IHtcclxuICAgICAgLy8gMS4gQ2hlY2sgaWYgdGhpcyBpcyBhIHRyYWNrZWQgYXN5bmMgb3BlcmF0aW9uIChwcm9jZXNzUmVxdWVzdClcclxuICAgICAgdGhpcy5vcGVyYXRpb25UcmFja2VyLmhhbmRsZU5vdGlmaWNhdGlvbihub3RpZmljYXRpb24pO1xyXG5cclxuICAgICAgLy8gMi4gQWxzbyBub3RpZnkgY29tcG9uZW50cyBzdWJzY3JpYmVkIHRvIHRoaXMgYXBwT2JqZWN0SWQgKEdyaWQsIGV0Yy4pXHJcbiAgICAgIHRoaXMubm90aWZ5Q29tcG9uZW50cyhub3RpZmljYXRpb24pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFc3RhYmxpc2ggYSBjb25uZWN0aW9uIHRvIHRoZSBTaWduYWxSIGh1YlxyXG4gICAqXHJcbiAgICogVGhpcyBtZXRob2QgaXMgaWRlbXBvdGVudCAtIGlmIHRoZSBjb25uZWN0aW9uIGlzIGFscmVhZHkgZXN0YWJsaXNoZWQsIGl0IHdpbGwgbm90IGJlIHJlLWVzdGFibGlzaGVkLlxyXG4gICAqIEh1YiBVUkwgaXMgcmVhZCBmcm9tIENvbW1vbi5zaWduYWxSSHViVXJsIChzZXQgZHVyaW5nIGFwcCBpbml0aWFsaXphdGlvbiB2aWEgQ29tbW9uLmluaXQoKSlcclxuICAgKi9cclxuICBjb25uZWN0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5pbmZyYXN0cnVjdHVyZS5jb25uZWN0KCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBjb21wb25lbnQgZm9yIHJlYWwtdGltZSBub3RpZmljYXRpb25zXHJcbiAgICpcclxuICAgKiBAcGFyYW0gY29tcG9uZW50SWQgLSBVbmlxdWUgY29tcG9uZW50IGlkZW50aWZpZXIgKGdlbmVyYXRlZCBieSBjb21wb25lbnQpXHJcbiAgICogQHBhcmFtIGFwcE9iamVjdElkIC0gQXBwT2JqZWN0IElEIHRvIHN1YnNjcmliZSB0b1xyXG4gICAqIEBwYXJhbSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBub3RpZmljYXRpb24gcmVjZWl2ZWRcclxuICAgKi9cclxuICByZWdpc3Rlcihjb21wb25lbnRJZDogc3RyaW5nLCBhcHBPYmplY3RJZDogc3RyaW5nLCBjYWxsYmFjazogTm90aWZpY2F0aW9uQ2FsbGJhY2spOiB2b2lkIHtcclxuICAgIC8vIEluaXRpYWxpemUgbWFwIGZvciB0aGlzIEFwcE9iamVjdCBpZiBkb2Vzbid0IGV4aXN0XHJcbiAgICBpZiAoIXRoaXMuY29tcG9uZW50UmVnaXN0cnkuaGFzKGFwcE9iamVjdElkKSkge1xyXG4gICAgICB0aGlzLmNvbXBvbmVudFJlZ2lzdHJ5LnNldChhcHBPYmplY3RJZCwgbmV3IE1hcCgpKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjb21wb25lbnRzID0gdGhpcy5jb21wb25lbnRSZWdpc3RyeS5nZXQoYXBwT2JqZWN0SWQpITtcclxuXHJcbiAgICAvLyBGaXJzdCBjb21wb25lbnQgZm9yIHRoaXMgQXBwT2JqZWN0PyBKb2luIFNpZ25hbFIgZ3JvdXBcclxuICAgIGlmIChjb21wb25lbnRzLnNpemUgPT09IDApIHtcclxuICAgICAgdGhpcy5pbmZyYXN0cnVjdHVyZS5qb2luR3JvdXAoYXBwT2JqZWN0SWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEFkZCBjb21wb25lbnQgdG8gcmVnaXN0cnlcclxuICAgIGNvbXBvbmVudHMuc2V0KGNvbXBvbmVudElkLCBjYWxsYmFjayk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVbnJlZ2lzdGVyIGNvbXBvbmVudCAoY2xlYW51cCBvbiBjb21wb25lbnQgZGVzdHJveSlcclxuICAgKlxyXG4gICAqIEBwYXJhbSBjb21wb25lbnRJZCAtIENvbXBvbmVudCBpZGVudGlmaWVyIHRvIHJlbW92ZVxyXG4gICAqIEBwYXJhbSBhcHBPYmplY3RJZCAtIEFwcE9iamVjdCBJRCB0byB1bnN1YnNjcmliZSBmcm9tXHJcbiAgICovXHJcbiAgdW5yZWdpc3Rlcihjb21wb25lbnRJZDogc3RyaW5nLCBhcHBPYmplY3RJZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBjb25zdCBjb21wb25lbnRzID0gdGhpcy5jb21wb25lbnRSZWdpc3RyeS5nZXQoYXBwT2JqZWN0SWQpO1xyXG4gICAgaWYgKCFjb21wb25lbnRzKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZW1vdmUgY29tcG9uZW50IGZyb20gcmVnaXN0cnlcclxuICAgIGNvbXBvbmVudHMuZGVsZXRlKGNvbXBvbmVudElkKTtcclxuXHJcbiAgICAvLyBMYXN0IGNvbXBvbmVudCBmb3IgdGhpcyBBcHBPYmplY3Q/IExlYXZlIFNpZ25hbFIgZ3JvdXBcclxuICAgIGlmIChjb21wb25lbnRzLnNpemUgPT09IDApIHtcclxuICAgICAgdGhpcy5pbmZyYXN0cnVjdHVyZS5sZWF2ZUdyb3VwKGFwcE9iamVjdElkKTtcclxuICAgICAgdGhpcy5jb21wb25lbnRSZWdpc3RyeS5kZWxldGUoYXBwT2JqZWN0SWQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogV2FpdCBmb3Igc3BlY2lmaWMgYXN5bmMgb3BlcmF0aW9uIHRvIGNvbXBsZXRlXHJcbiAgICogVXNlZCBieSBUYWJGb3JtaW9TZXJ2aWNlIGZvciBhc3luYyBwcm9jZXNzUmVxdWVzdCBvcGVyYXRpb25zXHJcbiAgICpcclxuICAgKiBAcGFyYW0gY29ycmVsYXRpb25JZCAtIENvcnJlbGF0aW9uIElEIGZyb20gYmFja2VuZCByZXNwb25zZVxyXG4gICAqIEBwYXJhbSB0aW1lb3V0IC0gT3B0aW9uYWwgdGltZW91dCBpbiBtaWxsaXNlY29uZHNcclxuICAgKiBAcmV0dXJucyBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiBvcGVyYXRpb24gY29tcGxldGVzXHJcbiAgICovXHJcbiAgd2FpdEZvck9wZXJhdGlvbihjb3JyZWxhdGlvbklkOiBzdHJpbmcsIHRpbWVvdXQ/OiBudW1iZXIpOiBPYnNlcnZhYmxlPENydWROb3RpZmljYXRpb24+IHtcclxuICAgIHJldHVybiB0aGlzLm9wZXJhdGlvblRyYWNrZXIud2FpdEZvck9wZXJhdGlvbihjb3JyZWxhdGlvbklkLCB0aW1lb3V0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdGVyIGFzeW5jIG9wZXJhdGlvbiBmb3IgdHJhY2tpbmdcclxuICAgKiBPcHRpb25hbCAtIHdhaXRGb3JPcGVyYXRpb24gaGFuZGxlcyByZWdpc3RyYXRpb24gYXV0b21hdGljYWxseVxyXG4gICAqXHJcbiAgICogQHBhcmFtIG9wZXJhdGlvbiAtIFBlbmRpbmcgb3BlcmF0aW9uIGRldGFpbHNcclxuICAgKi9cclxuICByZWdpc3Rlck9wZXJhdGlvbihvcGVyYXRpb246IFBlbmRpbmdPcGVyYXRpb24pOiB2b2lkIHtcclxuICAgIHRoaXMub3BlcmF0aW9uVHJhY2tlci5yZWdpc3Rlck9wZXJhdGlvbihvcGVyYXRpb24pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgb3BlcmF0aW9uIGlzIHBlbmRpbmdcclxuICAgKi9cclxuICBpc09wZXJhdGlvblBlbmRpbmcoY29ycmVsYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5vcGVyYXRpb25UcmFja2VyLmlzUGVuZGluZyhjb3JyZWxhdGlvbklkKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE5vdGlmeSBhbGwgcmVnaXN0ZXJlZCBjb21wb25lbnRzIGZvciBhbiBBcHBPYmplY3RcclxuICAgKiBDYWxsZWQgd2hlbiBub3RpZmljYXRpb24gcmVjZWl2ZWQgZnJvbSBTaWduYWxSIGh1YlxyXG4gICAqL1xyXG4gIHByaXZhdGUgbm90aWZ5Q29tcG9uZW50cyhub3RpZmljYXRpb246IENydWROb3RpZmljYXRpb24pOiB2b2lkIHtcclxuICAgIGNvbnN0IGNvbXBvbmVudHMgPSB0aGlzLmNvbXBvbmVudFJlZ2lzdHJ5LmdldChub3RpZmljYXRpb24uYXBwT2JqZWN0SWQpO1xyXG5cclxuICAgIGlmICghY29tcG9uZW50cyB8fCBjb21wb25lbnRzLnNpemUgPT09IDApIHtcclxuICAgICAgLy8gTm8gY29tcG9uZW50cyByZWdpc3RlcmVkIGZvciB0aGlzIEFwcE9iamVjdCAtIGlnbm9yZSBub3RpZmljYXRpb25cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENhbGwgZWFjaCBjb21wb25lbnQncyBjYWxsYmFja1xyXG4gICAgY29tcG9uZW50cy5mb3JFYWNoKChjYWxsYmFjaywgY29tcG9uZW50SWQpID0+IHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjYWxsYmFjayhub3RpZmljYXRpb24pO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFtTaWduYWxSIFNlcnZpY2VdIENhbGxiYWNrIGZhaWxlZCBmb3IgY29tcG9uZW50ICR7Y29tcG9uZW50SWR9OmAsIGVycm9yKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYWN0aXZlIEFwcE9iamVjdCBncm91cHMgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0QWN0aXZlR3JvdXBzKCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuY29tcG9uZW50UmVnaXN0cnkua2V5cygpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBjb21wb25lbnQgY291bnQgZm9yIGFuIEFwcE9iamVjdCAoZm9yIGRlYnVnZ2luZylcclxuICAgKi9cclxuICBnZXRDb21wb25lbnRDb3VudChhcHBPYmplY3RJZDogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudFJlZ2lzdHJ5LmdldChhcHBPYmplY3RJZCk/LnNpemUgfHwgMDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0b3RhbCByZWdpc3RlcmVkIGNvbXBvbmVudHMgYWNyb3NzIGFsbCBBcHBPYmplY3RzIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldFRvdGFsQ29tcG9uZW50Q291bnQoKTogbnVtYmVyIHtcclxuICAgIGxldCB0b3RhbCA9IDA7XHJcbiAgICB0aGlzLmNvbXBvbmVudFJlZ2lzdHJ5LmZvckVhY2goKGNvbXBvbmVudHMpID0+IHtcclxuICAgICAgdG90YWwgKz0gY29tcG9uZW50cy5zaXplO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdG90YWw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgcmVnaXN0cnkgc3RhdGUgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0UmVnaXN0cnlTdGF0ZSgpOiB7IGFwcE9iamVjdElkOiBzdHJpbmc7IGNvbXBvbmVudENvdW50OiBudW1iZXIgfVtdIHtcclxuICAgIGNvbnN0IHN0YXRlOiB7IGFwcE9iamVjdElkOiBzdHJpbmc7IGNvbXBvbmVudENvdW50OiBudW1iZXIgfVtdID0gW107XHJcblxyXG4gICAgdGhpcy5jb21wb25lbnRSZWdpc3RyeS5mb3JFYWNoKChjb21wb25lbnRzLCBhcHBPYmplY3RJZCkgPT4ge1xyXG4gICAgICBzdGF0ZS5wdXNoKHtcclxuICAgICAgICBhcHBPYmplY3RJZCxcclxuICAgICAgICBjb21wb25lbnRDb3VudDogY29tcG9uZW50cy5zaXplLFxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBzdGF0ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBwZW5kaW5nIG9wZXJhdGlvbnMgY291bnQgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0UGVuZGluZ09wZXJhdGlvbnNDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMub3BlcmF0aW9uVHJhY2tlci5nZXRQZW5kaW5nQ291bnQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhbGwgcGVuZGluZyBvcGVyYXRpb25zIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldFBlbmRpbmdPcGVyYXRpb25zKCk6IFBlbmRpbmdPcGVyYXRpb25bXSB7XHJcbiAgICByZXR1cm4gdGhpcy5vcGVyYXRpb25UcmFja2VyLmdldEFsbFBlbmRpbmcoKTtcclxuICB9XHJcbn0iXX0=
|
package/index.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export * from './lib/tab-core-utility/app/helpers/common/req-res.helpers';
|
|
|
24
24
|
export * from './lib/tab-core-utility/app/helpers/common/where-clause.helpers';
|
|
25
25
|
export * from './lib/tab-core-utility/app/helpers/common/template.helpers';
|
|
26
26
|
export * from './lib/tab-core-utility/app/helpers/common/meta-data.helpers';
|
|
27
|
+
export * from './lib/tab-core-utility/app/helpers/login-response.adapter';
|
|
27
28
|
export * from './lib/tab-core-utility/app/helpers/screen/forms.helpers';
|
|
28
29
|
export * from './lib/tab-core-utility/app/helpers/screen/grid-column-data.helpers';
|
|
29
30
|
export * from './lib/tab-core-utility/app/helpers/screen/grid.helpers';
|
|
@@ -36,6 +37,7 @@ export * from './lib/tab-core-utility/app/interfaces/user.interface';
|
|
|
36
37
|
export * from './lib/tab-core-utility/app/interfaces/orgInfo.interface';
|
|
37
38
|
export * from './lib/tab-core-utility/app/interfaces/schema.interface';
|
|
38
39
|
export * from './lib/tab-core-utility/app/interfaces/grid.interface';
|
|
40
|
+
export * from './lib/tab-core-utility/app/interfaces/signalr.interface';
|
|
39
41
|
export * from './lib/tab-core-utility/app/models/api-query.class';
|
|
40
42
|
export * from './lib/tab-core-utility/app/models/app-object.class';
|
|
41
43
|
export * from './lib/tab-core-utility/app/models/common.class';
|
|
@@ -56,6 +58,9 @@ export * from './lib/tab-core-utility/core/service/translation.service';
|
|
|
56
58
|
export * from './lib/tab-core-utility/core/service/notification.service';
|
|
57
59
|
export * from './lib/tab-core-utility/core/service/confirmation.service';
|
|
58
60
|
export * from './lib/tab-core-utility/core/service/encryption.service';
|
|
61
|
+
export * from './lib/tab-core-utility/core/service/signalr/signalr.service';
|
|
62
|
+
export * from './lib/tab-core-utility/core/service/signalr/signalr-infrastructure.service';
|
|
63
|
+
export * from './lib/tab-core-utility/core/service/signalr/operation-tracker.service';
|
|
59
64
|
export * from './lib/tab-core-utility/core/pipe/translate.pipe';
|
|
60
65
|
export * from './lib/tab-core-utility/core/provider/translation.provider';
|
|
61
66
|
export * from './lib/tab-core-utility/core/provider/notification.provider';
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
+
import type { APIServiceName } from '../interfaces/common.interface';
|
|
1
2
|
export declare const API: {
|
|
2
3
|
applicationIdentifier: string;
|
|
3
4
|
applicationIdentifierForPMS: string;
|
|
4
5
|
novuBackendUrl: string;
|
|
5
6
|
novuSocketUrl: string;
|
|
6
|
-
insert: string;
|
|
7
7
|
bulkInsert: string;
|
|
8
|
-
update: string;
|
|
9
|
-
delete: string;
|
|
10
8
|
select: string;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
getListFromDsq: string;
|
|
9
|
+
screen: string;
|
|
10
|
+
listsGet: string;
|
|
14
11
|
buildApp: string;
|
|
15
|
-
|
|
12
|
+
metadataSchema: string;
|
|
16
13
|
login: string;
|
|
17
14
|
pluginUpload: string;
|
|
18
15
|
getFile: string;
|
|
@@ -24,37 +21,37 @@ export declare const API: {
|
|
|
24
21
|
multipleFileUpload: string;
|
|
25
22
|
deleteFile: string;
|
|
26
23
|
getMediaFile: string;
|
|
27
|
-
|
|
24
|
+
auditGetHistory: string;
|
|
28
25
|
changePassword: string;
|
|
29
26
|
restpassword: string;
|
|
30
27
|
getImage: string;
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
importData: string;
|
|
29
|
+
screenData: string;
|
|
33
30
|
processRequest: string;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
statusAvailable: string;
|
|
32
|
+
statusUpdate: string;
|
|
33
|
+
authRegisterUser: string;
|
|
37
34
|
getUserDetails: string;
|
|
38
35
|
getPermission: string;
|
|
39
36
|
testConnection: string;
|
|
40
37
|
performValidation: string;
|
|
41
38
|
setTabComponents: string;
|
|
42
39
|
BuildFormIOComponents: string;
|
|
43
|
-
|
|
40
|
+
applicationRegisterAppObjects: string;
|
|
44
41
|
languageResource: string;
|
|
45
42
|
refreshToken: string;
|
|
46
|
-
|
|
43
|
+
globalSearch: string;
|
|
47
44
|
cloneDsq: string;
|
|
48
45
|
InsertScreenPerformanceAnalytics: string;
|
|
49
46
|
GenerateHttpRequest: string;
|
|
50
47
|
GetDetailOfPerformanceAnalytics: string;
|
|
51
48
|
GetSummaryOfPerformanceAnalytics: string;
|
|
52
49
|
GetDataJsonByType: string;
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
applicationSyncAppFields: string;
|
|
51
|
+
reportExport: string;
|
|
55
52
|
RefreshGlobalSearchData: string;
|
|
56
53
|
RefreshRecordInfoData: string;
|
|
57
|
-
|
|
54
|
+
reportDownload: string;
|
|
58
55
|
sendReport: string;
|
|
59
56
|
GetReleaseJSONDifference: string;
|
|
60
57
|
GetDataDifference: string;
|
|
@@ -63,4 +60,14 @@ export declare const API: {
|
|
|
63
60
|
GetAllDocumnets: string;
|
|
64
61
|
GetDocumentById: string;
|
|
65
62
|
ExecuteWorkflow: string;
|
|
63
|
+
QueriesExecute: string;
|
|
64
|
+
QueriesSelect: string;
|
|
65
|
+
recordsInsert: string;
|
|
66
|
+
recordsUpdate: string;
|
|
67
|
+
recordsDelete: string;
|
|
68
|
+
fileManagerFileOperations: string;
|
|
69
|
+
fileManagerGetImage: string;
|
|
70
|
+
fileManagerUpload: string;
|
|
71
|
+
fileManagerDownload: string;
|
|
66
72
|
};
|
|
73
|
+
export declare const APIServices: Record<APIServiceName, APIServiceName>;
|