@techextensor/tab-core-utility 2.2.199 → 2.2.200

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.
@@ -0,0 +1,209 @@
1
+ import { Injectable, signal } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+ import { webSocket } from 'rxjs/webSocket';
4
+ import { Common } from '../../../app/constants/common';
5
+ import { NOTIFICATION_WS_CONFIG, WS_CONNECTION_STATE, WS_MESSAGE_TYPE, } from '../../../app/interfaces/notification.interface';
6
+ import * as i0 from "@angular/core";
7
+ /**
8
+ * Low-level Notification WebSocket transport.
9
+ *
10
+ * Pure — no storage / auth coupling. The caller (SDK facade or app layer)
11
+ * supplies all auth identifiers via `connect(params)`.
12
+ *
13
+ * Mirrors the SignalR infrastructure pattern:
14
+ * - connect() is idempotent, dedupes concurrent calls, tears down stale sockets
15
+ * - disconnect() flips an explicit-disconnected flag so retries don't revive
16
+ * - state exposed as Angular signal
17
+ * - inbound messages forwarded on `messages$` for higher-level service to route
18
+ *
19
+ * Internal use — consumers should use `NotificationInboxService` instead.
20
+ */
21
+ export class NotificationWebSocketService {
22
+ constructor() {
23
+ this.socket = null;
24
+ this.socketSub = null;
25
+ // In-flight connect promise — used to dedupe concurrent connect() calls
26
+ this.connectingPromise = null;
27
+ // Set true on explicit disconnect() so scheduled retries don't resurrect the connection
28
+ this.explicitlyDisconnected = false;
29
+ // Last connect params — kept so reconnect can rebuild the URL without the caller
30
+ // re-supplying them. Cleared on disconnect().
31
+ this.lastParams = null;
32
+ // Reconnect attempt counter (resets on successful connect)
33
+ this.reconnectAttempt = 0;
34
+ this.reconnectTimer = null;
35
+ // Connection state as Angular signal — for UI indicators / route resolvers
36
+ this.connectionState = signal(WS_CONNECTION_STATE.DISCONNECTED);
37
+ // Inbound message stream — NotificationInboxService subscribes and routes per type
38
+ this.messages$ = new Subject();
39
+ }
40
+ // ----------- public API -----------
41
+ /**
42
+ * Establish the WebSocket connection.
43
+ *
44
+ * Idempotent — if already OPEN, resolves immediately.
45
+ * In-flight calls are de-duplicated.
46
+ * Any stale (non-OPEN) socket is torn down before rebuild.
47
+ */
48
+ async connect(params) {
49
+ this.explicitlyDisconnected = false;
50
+ this.lastParams = params;
51
+ if (this.connectionState() === WS_CONNECTION_STATE.CONNECTED) {
52
+ return;
53
+ }
54
+ if (this.connectingPromise) {
55
+ return this.connectingPromise;
56
+ }
57
+ if (this.socket) {
58
+ try {
59
+ this.socket.complete();
60
+ }
61
+ catch { /* ignore */ }
62
+ this.socket = null;
63
+ this.socketSub?.unsubscribe();
64
+ this.socketSub = null;
65
+ }
66
+ this.connectingPromise = this.doConnect(params);
67
+ try {
68
+ await this.connectingPromise;
69
+ }
70
+ finally {
71
+ this.connectingPromise = null;
72
+ }
73
+ }
74
+ async doConnect(params) {
75
+ const baseUrl = Common.notificationWebSocketUrl;
76
+ if (!baseUrl) {
77
+ this.connectionState.set(WS_CONNECTION_STATE.DISCONNECTED);
78
+ return;
79
+ }
80
+ if (!params.userId) {
81
+ console.warn('[NotificationWS] No userId provided — skipping connect');
82
+ this.connectionState.set(WS_CONNECTION_STATE.FAILED);
83
+ return;
84
+ }
85
+ // BE doc: ws://host/ws?userId=...&appId=...&tenantId=...
86
+ const url = `${baseUrl}?userId=${encodeURIComponent(params.userId)}` +
87
+ (params.appId ? `&appId=${encodeURIComponent(params.appId)}` : '') +
88
+ (params.tenantId ? `&tenantId=${encodeURIComponent(params.tenantId)}` : '');
89
+ this.connectionState.set(WS_CONNECTION_STATE.CONNECTING);
90
+ return new Promise((resolve) => {
91
+ this.socket = webSocket({
92
+ url,
93
+ openObserver: {
94
+ next: () => {
95
+ this.connectionState.set(WS_CONNECTION_STATE.CONNECTED);
96
+ this.reconnectAttempt = 0;
97
+ resolve();
98
+ },
99
+ },
100
+ closeObserver: {
101
+ next: () => {
102
+ if (this.connectionState() !== WS_CONNECTION_STATE.CLOSED) {
103
+ this.connectionState.set(WS_CONNECTION_STATE.DISCONNECTED);
104
+ }
105
+ this.scheduleReconnect();
106
+ resolve();
107
+ },
108
+ },
109
+ });
110
+ this.socketSub = this.socket.subscribe({
111
+ next: (msg) => this.handleIncoming(msg),
112
+ error: (err) => {
113
+ console.error('[NotificationWS] Socket error:', err);
114
+ this.connectionState.set(WS_CONNECTION_STATE.FAILED);
115
+ this.scheduleReconnect();
116
+ resolve();
117
+ },
118
+ });
119
+ });
120
+ }
121
+ /**
122
+ * Send a message over the socket. Silently no-ops if not connected.
123
+ */
124
+ send(message) {
125
+ if (!this.socket || this.connectionState() !== WS_CONNECTION_STATE.CONNECTED) {
126
+ return;
127
+ }
128
+ try {
129
+ this.socket.next(message);
130
+ }
131
+ catch (error) {
132
+ console.error('[NotificationWS] Failed to send message:', error);
133
+ }
134
+ }
135
+ /**
136
+ * Tear down the socket.
137
+ *
138
+ * Sets explicitlyDisconnected so any pending retry timers become no-ops,
139
+ * then closes the socket and clears state.
140
+ */
141
+ async disconnect() {
142
+ this.explicitlyDisconnected = true;
143
+ this.connectingPromise = null;
144
+ this.lastParams = null;
145
+ if (this.reconnectTimer) {
146
+ clearTimeout(this.reconnectTimer);
147
+ this.reconnectTimer = null;
148
+ }
149
+ if (this.socket) {
150
+ try {
151
+ this.socket.complete();
152
+ }
153
+ catch { /* ignore */ }
154
+ this.socket = null;
155
+ }
156
+ this.socketSub?.unsubscribe();
157
+ this.socketSub = null;
158
+ this.reconnectAttempt = 0;
159
+ this.connectionState.set(WS_CONNECTION_STATE.CLOSED);
160
+ }
161
+ // ----------- internal -----------
162
+ handleIncoming(message) {
163
+ if (!message || typeof message !== 'object')
164
+ return;
165
+ // Heartbeat: server pings every ~30s; we MUST reply or BE will close the socket.
166
+ if (message.type === WS_MESSAGE_TYPE.HEARTBEAT) {
167
+ this.send({ type: WS_MESSAGE_TYPE.HEARTBEAT });
168
+ return;
169
+ }
170
+ if (message.type === WS_MESSAGE_TYPE.CONNECTION_ESTABLISHED) {
171
+ this.connectionState.set(WS_CONNECTION_STATE.CONNECTED);
172
+ }
173
+ if (message.type === WS_MESSAGE_TYPE.ERROR) {
174
+ console.warn('[NotificationWS] Server error:', message.error);
175
+ }
176
+ this.messages$.next(message);
177
+ }
178
+ scheduleReconnect() {
179
+ if (this.explicitlyDisconnected)
180
+ return;
181
+ if (this.reconnectTimer)
182
+ return;
183
+ if (!this.lastParams)
184
+ return; // can't reconnect without params
185
+ const delays = NOTIFICATION_WS_CONFIG.RECONNECT_DELAYS_MS;
186
+ const delay = delays[Math.min(this.reconnectAttempt, delays.length - 1)];
187
+ this.reconnectAttempt++;
188
+ this.connectionState.set(WS_CONNECTION_STATE.RECONNECTING);
189
+ this.reconnectTimer = setTimeout(() => {
190
+ this.reconnectTimer = null;
191
+ if (!this.explicitlyDisconnected && this.lastParams) {
192
+ this.connect(this.lastParams);
193
+ }
194
+ }, delay);
195
+ }
196
+ /**
197
+ * Snapshot of current connection state — for debugging.
198
+ */
199
+ isConnected() {
200
+ return this.connectionState() === WS_CONNECTION_STATE.CONNECTED;
201
+ }
202
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
203
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, providedIn: 'root' }); }
204
+ }
205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: NotificationWebSocketService, decorators: [{
206
+ type: Injectable,
207
+ args: [{ providedIn: 'root' }]
208
+ }] });
209
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLXdlYnNvY2tldC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL25vdGlmaWNhdGlvbi9ub3RpZmljYXRpb24td2Vic29ja2V0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBb0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDdkQsT0FBTyxFQUNMLHNCQUFzQixFQUV0QixtQkFBbUIsRUFDbkIsZUFBZSxHQUVoQixNQUFNLGdEQUFnRCxDQUFDOztBQUV4RDs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsTUFBTSxPQUFPLDRCQUE0QjtJQUR6QztRQUVVLFdBQU0sR0FBaUMsSUFBSSxDQUFDO1FBQzVDLGNBQVMsR0FBd0IsSUFBSSxDQUFDO1FBRTlDLHdFQUF3RTtRQUNoRSxzQkFBaUIsR0FBeUIsSUFBSSxDQUFDO1FBRXZELHdGQUF3RjtRQUNoRiwyQkFBc0IsR0FBRyxLQUFLLENBQUM7UUFFdkMsaUZBQWlGO1FBQ2pGLDhDQUE4QztRQUN0QyxlQUFVLEdBQThDLElBQUksQ0FBQztRQUVyRSwyREFBMkQ7UUFDbkQscUJBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLG1CQUFjLEdBQXlDLElBQUksQ0FBQztRQUVwRSwyRUFBMkU7UUFDbEUsb0JBQWUsR0FBRyxNQUFNLENBQW9CLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXZGLG1GQUFtRjtRQUMxRSxjQUFTLEdBQUcsSUFBSSxP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QUNwRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNoQyxDQUFDO1FBQ0gsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ1osQ0FBQztJQUVEOztPQUVHO0lBQ0gsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLGVBQWUsRUFBRSxLQUFLLG1CQUFtQixDQUFDLFNBQVMsQ0FBQztJQUNsRSxDQUFDOytHQXpNVSw0QkFBNEI7bUhBQTVCLDRCQUE0QixjQURmLE1BQU07OzRGQUNuQiw0QkFBNEI7a0JBRHhDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyB3ZWJTb2NrZXQsIFdlYlNvY2tldFN1YmplY3QgfSBmcm9tICdyeGpzL3dlYlNvY2tldCc7XHJcbmltcG9ydCB7IENvbW1vbiB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBOT1RJRklDQVRJT05fV1NfQ09ORklHLFxyXG4gIE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMsXHJcbiAgV1NfQ09OTkVDVElPTl9TVEFURSxcclxuICBXU19NRVNTQUdFX1RZUEUsXHJcbiAgV3NDb25uZWN0aW9uU3RhdGUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvbm90aWZpY2F0aW9uLmludGVyZmFjZSc7XHJcblxyXG4vKipcclxuICogTG93LWxldmVsIE5vdGlmaWNhdGlvbiBXZWJTb2NrZXQgdHJhbnNwb3J0LlxyXG4gKlxyXG4gKiBQdXJlIOKAlCBubyBzdG9yYWdlIC8gYXV0aCBjb3VwbGluZy4gVGhlIGNhbGxlciAoU0RLIGZhY2FkZSBvciBhcHAgbGF5ZXIpXHJcbiAqIHN1cHBsaWVzIGFsbCBhdXRoIGlkZW50aWZpZXJzIHZpYSBgY29ubmVjdChwYXJhbXMpYC5cclxuICpcclxuICogTWlycm9ycyB0aGUgU2lnbmFsUiBpbmZyYXN0cnVjdHVyZSBwYXR0ZXJuOlxyXG4gKiAgLSBjb25uZWN0KCkgaXMgaWRlbXBvdGVudCwgZGVkdXBlcyBjb25jdXJyZW50IGNhbGxzLCB0ZWFycyBkb3duIHN0YWxlIHNvY2tldHNcclxuICogIC0gZGlzY29ubmVjdCgpIGZsaXBzIGFuIGV4cGxpY2l0LWRpc2Nvbm5lY3RlZCBmbGFnIHNvIHJldHJpZXMgZG9uJ3QgcmV2aXZlXHJcbiAqICAtIHN0YXRlIGV4cG9zZWQgYXMgQW5ndWxhciBzaWduYWxcclxuICogIC0gaW5ib3VuZCBtZXNzYWdlcyBmb3J3YXJkZWQgb24gYG1lc3NhZ2VzJGAgZm9yIGhpZ2hlci1sZXZlbCBzZXJ2aWNlIHRvIHJvdXRlXHJcbiAqXHJcbiAqIEludGVybmFsIHVzZSDigJQgY29uc3VtZXJzIHNob3VsZCB1c2UgYE5vdGlmaWNhdGlvbkluYm94U2VydmljZWAgaW5zdGVhZC5cclxuICovXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBOb3RpZmljYXRpb25XZWJTb2NrZXRTZXJ2aWNlIHtcclxuICBwcml2YXRlIHNvY2tldDogV2ViU29ja2V0U3ViamVjdDxhbnk+IHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBzb2NrZXRTdWI6IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBJbi1mbGlnaHQgY29ubmVjdCBwcm9taXNlIOKAlCB1c2VkIHRvIGRlZHVwZSBjb25jdXJyZW50IGNvbm5lY3QoKSBjYWxsc1xyXG4gIHByaXZhdGUgY29ubmVjdGluZ1Byb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gU2V0IHRydWUgb24gZXhwbGljaXQgZGlzY29ubmVjdCgpIHNvIHNjaGVkdWxlZCByZXRyaWVzIGRvbid0IHJlc3VycmVjdCB0aGUgY29ubmVjdGlvblxyXG4gIHByaXZhdGUgZXhwbGljaXRseURpc2Nvbm5lY3RlZCA9IGZhbHNlO1xyXG5cclxuICAvLyBMYXN0IGNvbm5lY3QgcGFyYW1zIOKAlCBrZXB0IHNvIHJlY29ubmVjdCBjYW4gcmVidWlsZCB0aGUgVVJMIHdpdGhvdXQgdGhlIGNhbGxlclxyXG4gIC8vIHJlLXN1cHBseWluZyB0aGVtLiBDbGVhcmVkIG9uIGRpc2Nvbm5lY3QoKS5cclxuICBwcml2YXRlIGxhc3RQYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gUmVjb25uZWN0IGF0dGVtcHQgY291bnRlciAocmVzZXRzIG9uIHN1Y2Nlc3NmdWwgY29ubmVjdClcclxuICBwcml2YXRlIHJlY29ubmVjdEF0dGVtcHQgPSAwO1xyXG4gIHByaXZhdGUgcmVjb25uZWN0VGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8vIENvbm5lY3Rpb24gc3RhdGUgYXMgQW5ndWxhciBzaWduYWwg4oCUIGZvciBVSSBpbmRpY2F0b3JzIC8gcm91dGUgcmVzb2x2ZXJzXHJcbiAgcmVhZG9ubHkgY29ubmVjdGlvblN0YXRlID0gc2lnbmFsPFdzQ29ubmVjdGlvblN0YXRlPihXU19DT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gIC8vIEluYm91bmQgbWVzc2FnZSBzdHJlYW0g4oCUIE5vdGlmaWNhdGlvbkluYm94U2VydmljZSBzdWJzY3JpYmVzIGFuZCByb3V0ZXMgcGVyIHR5cGVcclxuICByZWFkb25seSBtZXNzYWdlcyQgPSBuZXcgU3ViamVjdDxhbnk+KCk7XHJcblxyXG4gIC8vIC0tLS0tLS0tLS0tIHB1YmxpYyBBUEkgLS0tLS0tLS0tLS1cclxuXHJcbiAgLyoqXHJcbiAgICogRXN0YWJsaXNoIHRoZSBXZWJTb2NrZXQgY29ubmVjdGlvbi5cclxuICAgKlxyXG4gICAqIElkZW1wb3RlbnQg4oCUIGlmIGFscmVhZHkgT1BFTiwgcmVzb2x2ZXMgaW1tZWRpYXRlbHkuXHJcbiAgICogSW4tZmxpZ2h0IGNhbGxzIGFyZSBkZS1kdXBsaWNhdGVkLlxyXG4gICAqIEFueSBzdGFsZSAobm9uLU9QRU4pIHNvY2tldCBpcyB0b3JuIGRvd24gYmVmb3JlIHJlYnVpbGQuXHJcbiAgICovXHJcbiAgYXN5bmMgY29ubmVjdChwYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMuZXhwbGljaXRseURpc2Nvbm5lY3RlZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5sYXN0UGFyYW1zID0gcGFyYW1zO1xyXG5cclxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpID09PSBXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuY29ubmVjdGluZ1Byb21pc2UpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGluZ1Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuc29ja2V0KSB7XHJcbiAgICAgIHRyeSB7IHRoaXMuc29ja2V0LmNvbXBsZXRlKCk7IH0gY2F0Y2ggeyAvKiBpZ25vcmUgKi8gfVxyXG4gICAgICB0aGlzLnNvY2tldCA9IG51bGw7XHJcbiAgICAgIHRoaXMuc29ja2V0U3ViPy51bnN1YnNjcmliZSgpO1xyXG4gICAgICB0aGlzLnNvY2tldFN1YiA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jb25uZWN0aW5nUHJvbWlzZSA9IHRoaXMuZG9Db25uZWN0KHBhcmFtcyk7XHJcbiAgICB0cnkge1xyXG4gICAgICBhd2FpdCB0aGlzLmNvbm5lY3RpbmdQcm9taXNlO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW5nUHJvbWlzZSA9IG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGRvQ29ubmVjdChwYXJhbXM6IE5vdGlmaWNhdGlvbldlYlNvY2tldENvbm5lY3RQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGJhc2VVcmwgPSBDb21tb24ubm90aWZpY2F0aW9uV2ViU29ja2V0VXJsO1xyXG4gICAgaWYgKCFiYXNlVXJsKSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChXU19DT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXBhcmFtcy51c2VySWQpIHtcclxuICAgICAgY29uc29sZS53YXJuKCdbTm90aWZpY2F0aW9uV1NdIE5vIHVzZXJJZCBwcm92aWRlZCDigJQgc2tpcHBpbmcgY29ubmVjdCcpO1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQkUgZG9jOiB3czovL2hvc3Qvd3M/dXNlcklkPS4uLiZhcHBJZD0uLi4mdGVuYW50SWQ9Li4uXHJcbiAgICBjb25zdCB1cmwgPSBgJHtiYXNlVXJsfT91c2VySWQ9JHtlbmNvZGVVUklDb21wb25lbnQocGFyYW1zLnVzZXJJZCl9YCArXHJcbiAgICAgIChwYXJhbXMuYXBwSWQgPyBgJmFwcElkPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtcy5hcHBJZCl9YCA6ICcnKSArXHJcbiAgICAgIChwYXJhbXMudGVuYW50SWQgPyBgJnRlbmFudElkPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtcy50ZW5hbnRJZCl9YCA6ICcnKTtcclxuXHJcbiAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DT05ORUNUSU5HKTtcclxuXHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcclxuICAgICAgdGhpcy5zb2NrZXQgPSB3ZWJTb2NrZXQ8YW55Pih7XHJcbiAgICAgICAgdXJsLFxyXG4gICAgICAgIG9wZW5PYnNlcnZlcjoge1xyXG4gICAgICAgICAgbmV4dDogKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG4gICAgICAgICAgICB0aGlzLnJlY29ubmVjdEF0dGVtcHQgPSAwO1xyXG4gICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY2xvc2VPYnNlcnZlcjoge1xyXG4gICAgICAgICAgbmV4dDogKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGUoKSAhPT0gV1NfQ09OTkVDVElPTl9TVEFURS5DTE9TRUQpIHtcclxuICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVSZWNvbm5lY3QoKTtcclxuICAgICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHRoaXMuc29ja2V0U3ViID0gdGhpcy5zb2NrZXQuc3Vic2NyaWJlKHtcclxuICAgICAgICBuZXh0OiAobXNnKSA9PiB0aGlzLmhhbmRsZUluY29taW5nKG1zZyksXHJcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tOb3RpZmljYXRpb25XU10gU29ja2V0IGVycm9yOicsIGVycik7XHJcbiAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG4gICAgICAgICAgdGhpcy5zY2hlZHVsZVJlY29ubmVjdCgpO1xyXG4gICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZW5kIGEgbWVzc2FnZSBvdmVyIHRoZSBzb2NrZXQuIFNpbGVudGx5IG5vLW9wcyBpZiBub3QgY29ubmVjdGVkLlxyXG4gICAqL1xyXG4gIHNlbmQobWVzc2FnZTogUmVjb3JkPHN0cmluZywgYW55Pik6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnNvY2tldCB8fCB0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpICE9PSBXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLnNvY2tldC5uZXh0KG1lc3NhZ2UpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignW05vdGlmaWNhdGlvbldTXSBGYWlsZWQgdG8gc2VuZCBtZXNzYWdlOicsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRlYXIgZG93biB0aGUgc29ja2V0LlxyXG4gICAqXHJcbiAgICogU2V0cyBleHBsaWNpdGx5RGlzY29ubmVjdGVkIHNvIGFueSBwZW5kaW5nIHJldHJ5IHRpbWVycyBiZWNvbWUgbm8tb3BzLFxyXG4gICAqIHRoZW4gY2xvc2VzIHRoZSBzb2NrZXQgYW5kIGNsZWFycyBzdGF0ZS5cclxuICAgKi9cclxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgdGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkID0gdHJ1ZTtcclxuICAgIHRoaXMuY29ubmVjdGluZ1Byb21pc2UgPSBudWxsO1xyXG4gICAgdGhpcy5sYXN0UGFyYW1zID0gbnVsbDtcclxuXHJcbiAgICBpZiAodGhpcy5yZWNvbm5lY3RUaW1lcikge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5yZWNvbm5lY3RUaW1lcik7XHJcbiAgICAgIHRoaXMucmVjb25uZWN0VGltZXIgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnNvY2tldCkge1xyXG4gICAgICB0cnkgeyB0aGlzLnNvY2tldC5jb21wbGV0ZSgpOyB9IGNhdGNoIHsgLyogaWdub3JlICovIH1cclxuICAgICAgdGhpcy5zb2NrZXQgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc29ja2V0U3ViPy51bnN1YnNjcmliZSgpO1xyXG4gICAgdGhpcy5zb2NrZXRTdWIgPSBudWxsO1xyXG5cclxuICAgIHRoaXMucmVjb25uZWN0QXR0ZW1wdCA9IDA7XHJcbiAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoV1NfQ09OTkVDVElPTl9TVEFURS5DTE9TRUQpO1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0gaW50ZXJuYWwgLS0tLS0tLS0tLS1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVJbmNvbWluZyhtZXNzYWdlOiBhbnkpOiB2b2lkIHtcclxuICAgIGlmICghbWVzc2FnZSB8fCB0eXBlb2YgbWVzc2FnZSAhPT0gJ29iamVjdCcpIHJldHVybjtcclxuXHJcbiAgICAvLyBIZWFydGJlYXQ6IHNlcnZlciBwaW5ncyBldmVyeSB+MzBzOyB3ZSBNVVNUIHJlcGx5IG9yIEJFIHdpbGwgY2xvc2UgdGhlIHNvY2tldC5cclxuICAgIGlmIChtZXNzYWdlLnR5cGUgPT09IFdTX01FU1NBR0VfVFlQRS5IRUFSVEJFQVQpIHtcclxuICAgICAgdGhpcy5zZW5kKHsgdHlwZTogV1NfTUVTU0FHRV9UWVBFLkhFQVJUQkVBVCB9KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtZXNzYWdlLnR5cGUgPT09IFdTX01FU1NBR0VfVFlQRS5DT05ORUNUSU9OX0VTVEFCTElTSEVEKSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChXU19DT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG1lc3NhZ2UudHlwZSA9PT0gV1NfTUVTU0FHRV9UWVBFLkVSUk9SKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybignW05vdGlmaWNhdGlvbldTXSBTZXJ2ZXIgZXJyb3I6JywgbWVzc2FnZS5lcnJvcik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2NoZWR1bGVSZWNvbm5lY3QoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkKSByZXR1cm47XHJcbiAgICBpZiAodGhpcy5yZWNvbm5lY3RUaW1lcikgcmV0dXJuO1xyXG4gICAgaWYgKCF0aGlzLmxhc3RQYXJhbXMpIHJldHVybjsgLy8gY2FuJ3QgcmVjb25uZWN0IHdpdGhvdXQgcGFyYW1zXHJcblxyXG4gICAgY29uc3QgZGVsYXlzID0gTk9USUZJQ0FUSU9OX1dTX0NPTkZJRy5SRUNPTk5FQ1RfREVMQVlTX01TO1xyXG4gICAgY29uc3QgZGVsYXkgPSBkZWxheXNbTWF0aC5taW4odGhpcy5yZWNvbm5lY3RBdHRlbXB0LCBkZWxheXMubGVuZ3RoIC0gMSldO1xyXG4gICAgdGhpcy5yZWNvbm5lY3RBdHRlbXB0Kys7XHJcblxyXG4gICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KFdTX0NPTk5FQ1RJT05fU1RBVEUuUkVDT05ORUNUSU5HKTtcclxuXHJcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMucmVjb25uZWN0VGltZXIgPSBudWxsO1xyXG4gICAgICBpZiAoIXRoaXMuZXhwbGljaXRseURpc2Nvbm5lY3RlZCAmJiB0aGlzLmxhc3RQYXJhbXMpIHtcclxuICAgICAgICB0aGlzLmNvbm5lY3QodGhpcy5sYXN0UGFyYW1zKTtcclxuICAgICAgfVxyXG4gICAgfSwgZGVsYXkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU25hcHNob3Qgb2YgY3VycmVudCBjb25uZWN0aW9uIHN0YXRlIOKAlCBmb3IgZGVidWdnaW5nLlxyXG4gICAqL1xyXG4gIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvblN0YXRlKCkgPT09IFdTX0NPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVEVEO1xyXG4gIH1cclxufVxyXG4iXX0=
@@ -1,6 +1,6 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { Subject, throwError, TimeoutError } from 'rxjs';
3
- import { filter, take, timeout, catchError } from 'rxjs/operators';
2
+ import { merge, Subject, throwError, TimeoutError } from 'rxjs';
3
+ import { filter, take, timeout, catchError, switchMap } from 'rxjs/operators';
4
4
  import { SIGNALR_CONFIG, } from '../../../app/interfaces/signalr.interface';
5
5
  import * as i0 from "@angular/core";
6
6
  /**
@@ -14,6 +14,8 @@ export class OperationTrackerService {
14
14
  this.pendingOperations = new Map();
15
15
  // Observable for completed operations
16
16
  this.operationCompleted$ = new Subject();
17
+ // Cancellation channel — emitted by cancelAll() to error any open waitForOperation observers
18
+ this.cancellation$ = new Subject();
17
19
  }
18
20
  /**
19
21
  * Register an async operation for tracking
@@ -29,7 +31,8 @@ export class OperationTrackerService {
29
31
  }
30
32
  /**
31
33
  * Wait for operation to complete via SignalR notification
32
- * Returns Observable that emits when notification with matching correlationId is received
34
+ * Returns Observable that emits when notification with matching correlationId is received,
35
+ * or errors if cancelAll() is invoked (e.g. on disconnect / signOut).
33
36
  */
34
37
  waitForOperation(correlationId, timeoutMs = SIGNALR_CONFIG.DEFAULT_TIMEOUT) {
35
38
  // Auto-register so handleNotification can match it
@@ -40,8 +43,10 @@ export class OperationTrackerService {
40
43
  timeout: timeoutMs
41
44
  });
42
45
  }
43
- return this.operationCompleted$.pipe(filter((notification) => notification.correlationId === correlationId), take(1), timeout(timeoutMs), catchError((error) => {
44
- // Cleanup on timeout
46
+ const completed$ = this.operationCompleted$.pipe(filter((notification) => notification.correlationId === correlationId), take(1));
47
+ const cancelled$ = this.cancellation$.pipe(take(1), switchMap((reason) => throwError(() => new Error(`SignalR operation cancelled: ${reason}`))));
48
+ return merge(completed$, cancelled$).pipe(take(1), timeout(timeoutMs), catchError((error) => {
49
+ // Cleanup on timeout / cancellation
45
50
  this.pendingOperations.delete(correlationId);
46
51
  if (error instanceof TimeoutError) {
47
52
  return throwError(() => new Error('Operation timed out'));
@@ -62,6 +67,18 @@ export class OperationTrackerService {
62
67
  this.pendingOperations.delete(notification.correlationId);
63
68
  }
64
69
  }
70
+ /**
71
+ * Cancel all pending operations — errors all open waitForOperation() observers.
72
+ * Called by SignalRService.disconnect() so in-flight CRUD UIs resolve fast
73
+ * instead of stranding until the 120s timeout.
74
+ */
75
+ cancelAll(reason) {
76
+ if (this.pendingOperations.size === 0) {
77
+ return;
78
+ }
79
+ this.pendingOperations.clear();
80
+ this.cancellation$.next(reason);
81
+ }
65
82
  /**
66
83
  * Check if operation is pending
67
84
  */
@@ -87,4 +104,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
87
104
  type: Injectable,
88
105
  args: [{ providedIn: 'root' }]
89
106
  }] });
90
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0aW9uLXRyYWNrZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZGF0YS1hY2Nlc3Mvc3JjL2xpYi90YWItY29yZS11dGlsaXR5L2NvcmUvc2VydmljZS9zaWduYWxyL29wZXJhdGlvbi10cmFja2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDckUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ25FLE9BQU8sRUFHTCxjQUFjLEdBQ2YsTUFBTSwyQ0FBMkMsQ0FBQzs7QUFFbkQ7Ozs7R0FJRztBQUVILE1BQU0sT0FBTyx1QkFBdUI7SUFEcEM7UUFFRSx1Q0FBdUM7UUFDL0Isc0JBQWlCLEdBQUcsSUFBSSxHQUFHLEVBQTRCLENBQUM7UUFFaEUsc0NBQXNDO1FBQzlCLHdCQUFtQixHQUFHLElBQUksT0FBTyxFQUFvQixDQUFDO0tBZ0YvRDtJQTlFQzs7T0FFRztJQUNILGlCQUFpQixDQUFDLFNBQTJCO1FBQzNDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUUvRCw2QkFBNkI7UUFDN0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztnQkFDeEQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDekQsQ0FBQztRQUNILENBQUMsRUFBRSxTQUFTLENBQUMsT0FBTyxJQUFJLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZ0JBQWdCLENBQUMsYUFBcUIsRUFBRSxZQUFvQixjQUFjLENBQUMsZUFBZTtRQUN4RixtREFBbUQ7UUFDbkQsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsaUJBQWlCLENBQUM7Z0JBQ3JCLGFBQWE7Z0JBQ2IsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFO2dCQUNyQixPQUFPLEVBQUUsU0FBUzthQUNuQixDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUNsQyxNQUFNLENBQUMsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxhQUFhLEtBQUssYUFBYSxDQUFDLEVBQ3RFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQ2xCLFVBQVUsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ25CLHFCQUFxQjtZQUNyQixJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBRTdDLElBQUksS0FBSyxZQUFZLFlBQVksRUFBRSxDQUFDO2dCQUNsQyxPQUFPLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUM7WUFDNUQsQ0FBQztZQUNELE9BQU8sVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsa0JBQWtCLENBQUMsWUFBOEI7UUFDL0MsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDekUsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLCtDQUErQztZQUMvQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTVDLFVBQVU7WUFDVixJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM1RCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxDQUFDLGFBQXFCO1FBQzdCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7T0FFRztJQUNILGFBQWE7UUFDWCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDckQsQ0FBQzsrR0FwRlUsdUJBQXVCO21IQUF2Qix1QkFBdUIsY0FEVixNQUFNOzs0RkFDbkIsdUJBQXVCO2tCQURuQyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgdGhyb3dFcnJvciwgVGltZW91dEVycm9yIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGZpbHRlciwgdGFrZSwgdGltZW91dCwgY2F0Y2hFcnJvciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHtcclxuICBDcnVkTm90aWZpY2F0aW9uLFxyXG4gIFBlbmRpbmdPcGVyYXRpb24sXHJcbiAgU0lHTkFMUl9DT05GSUcsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvc2lnbmFsci5pbnRlcmZhY2UnO1xyXG5cclxuLyoqXHJcbiAqIE9wZXJhdGlvbiBUcmFja2VyIFNlcnZpY2VcclxuICogVHJhY2tzIGFzeW5jIG9wZXJhdGlvbnMgYnkgY29ycmVsYXRpb25JZCBhbmQgbWF0Y2hlcyB0aGVtIHdpdGggU2lnbmFsUiBub3RpZmljYXRpb25zXHJcbiAqIFVzZWQgYnkgVGFiRm9ybWlvU2VydmljZSBmb3IgaGFuZGxpbmcgYXN5bmMgcHJvY2Vzc1JlcXVlc3Qgb3BlcmF0aW9uc1xyXG4gKi9cclxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcclxuZXhwb3J0IGNsYXNzIE9wZXJhdGlvblRyYWNrZXJTZXJ2aWNlIHtcclxuICAvLyBNYXA8Y29ycmVsYXRpb25JZCwgUGVuZGluZ09wZXJhdGlvbj5cclxuICBwcml2YXRlIHBlbmRpbmdPcGVyYXRpb25zID0gbmV3IE1hcDxzdHJpbmcsIFBlbmRpbmdPcGVyYXRpb24+KCk7XHJcblxyXG4gIC8vIE9ic2VydmFibGUgZm9yIGNvbXBsZXRlZCBvcGVyYXRpb25zXHJcbiAgcHJpdmF0ZSBvcGVyYXRpb25Db21wbGV0ZWQkID0gbmV3IFN1YmplY3Q8Q3J1ZE5vdGlmaWNhdGlvbj4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogUmVnaXN0ZXIgYW4gYXN5bmMgb3BlcmF0aW9uIGZvciB0cmFja2luZ1xyXG4gICAqL1xyXG4gIHJlZ2lzdGVyT3BlcmF0aW9uKG9wZXJhdGlvbjogUGVuZGluZ09wZXJhdGlvbik6IHZvaWQge1xyXG4gICAgdGhpcy5wZW5kaW5nT3BlcmF0aW9ucy5zZXQob3BlcmF0aW9uLmNvcnJlbGF0aW9uSWQsIG9wZXJhdGlvbik7XHJcblxyXG4gICAgLy8gQXV0by1jbGVhbnVwIGFmdGVyIHRpbWVvdXRcclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5wZW5kaW5nT3BlcmF0aW9ucy5oYXMob3BlcmF0aW9uLmNvcnJlbGF0aW9uSWQpKSB7XHJcbiAgICAgICAgdGhpcy5wZW5kaW5nT3BlcmF0aW9ucy5kZWxldGUob3BlcmF0aW9uLmNvcnJlbGF0aW9uSWQpO1xyXG4gICAgICB9XHJcbiAgICB9LCBvcGVyYXRpb24udGltZW91dCB8fCBTSUdOQUxSX0NPTkZJRy5ERUZBVUxUX1RJTUVPVVQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogV2FpdCBmb3Igb3BlcmF0aW9uIHRvIGNvbXBsZXRlIHZpYSBTaWduYWxSIG5vdGlmaWNhdGlvblxyXG4gICAqIFJldHVybnMgT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHdoZW4gbm90aWZpY2F0aW9uIHdpdGggbWF0Y2hpbmcgY29ycmVsYXRpb25JZCBpcyByZWNlaXZlZFxyXG4gICAqL1xyXG4gIHdhaXRGb3JPcGVyYXRpb24oY29ycmVsYXRpb25JZDogc3RyaW5nLCB0aW1lb3V0TXM6IG51bWJlciA9IFNJR05BTFJfQ09ORklHLkRFRkFVTFRfVElNRU9VVCk6IE9ic2VydmFibGU8Q3J1ZE5vdGlmaWNhdGlvbj4ge1xyXG4gICAgLy8gQXV0by1yZWdpc3RlciBzbyBoYW5kbGVOb3RpZmljYXRpb24gY2FuIG1hdGNoIGl0XHJcbiAgICBpZiAoIXRoaXMucGVuZGluZ09wZXJhdGlvbnMuaGFzKGNvcnJlbGF0aW9uSWQpKSB7XHJcbiAgICAgIHRoaXMucmVnaXN0ZXJPcGVyYXRpb24oe1xyXG4gICAgICAgIGNvcnJlbGF0aW9uSWQsXHJcbiAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLFxyXG4gICAgICAgIHRpbWVvdXQ6IHRpbWVvdXRNc1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbkNvbXBsZXRlZCQucGlwZShcclxuICAgICAgZmlsdGVyKChub3RpZmljYXRpb24pID0+IG5vdGlmaWNhdGlvbi5jb3JyZWxhdGlvbklkID09PSBjb3JyZWxhdGlvbklkKSxcclxuICAgICAgdGFrZSgxKSxcclxuICAgICAgdGltZW91dCh0aW1lb3V0TXMpLFxyXG4gICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgIC8vIENsZWFudXAgb24gdGltZW91dFxyXG4gICAgICAgIHRoaXMucGVuZGluZ09wZXJhdGlvbnMuZGVsZXRlKGNvcnJlbGF0aW9uSWQpO1xyXG5cclxuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBUaW1lb3V0RXJyb3IpIHtcclxuICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBFcnJvcignT3BlcmF0aW9uIHRpbWVkIG91dCcpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xyXG4gICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSBpbmNvbWluZyBTaWduYWxSIG5vdGlmaWNhdGlvblxyXG4gICAqIENhbGxlZCBieSBTaWduYWxSU2VydmljZSB3aGVuIG5vdGlmaWNhdGlvbiBpcyByZWNlaXZlZFxyXG4gICAqL1xyXG4gIGhhbmRsZU5vdGlmaWNhdGlvbihub3RpZmljYXRpb246IENydWROb3RpZmljYXRpb24pOiB2b2lkIHtcclxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IHRoaXMucGVuZGluZ09wZXJhdGlvbnMuZ2V0KG5vdGlmaWNhdGlvbi5jb3JyZWxhdGlvbklkKTtcclxuICAgIGlmIChvcGVyYXRpb24pIHtcclxuICAgICAgLy8gRW1pdCB0byBvYnNlcnZlcnMgd2FpdGluZyBmb3IgdGhpcyBvcGVyYXRpb25cclxuICAgICAgdGhpcy5vcGVyYXRpb25Db21wbGV0ZWQkLm5leHQobm90aWZpY2F0aW9uKTtcclxuXHJcbiAgICAgIC8vIENsZWFudXBcclxuICAgICAgdGhpcy5wZW5kaW5nT3BlcmF0aW9ucy5kZWxldGUobm90aWZpY2F0aW9uLmNvcnJlbGF0aW9uSWQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgb3BlcmF0aW9uIGlzIHBlbmRpbmdcclxuICAgKi9cclxuICBpc1BlbmRpbmcoY29ycmVsYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5wZW5kaW5nT3BlcmF0aW9ucy5oYXMoY29ycmVsYXRpb25JZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgcGVuZGluZyBvcGVyYXRpb25zIGNvdW50IChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldFBlbmRpbmdDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMucGVuZGluZ09wZXJhdGlvbnMuc2l6ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhbGwgcGVuZGluZyBvcGVyYXRpb25zIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldEFsbFBlbmRpbmcoKTogUGVuZGluZ09wZXJhdGlvbltdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMucGVuZGluZ09wZXJhdGlvbnMudmFsdWVzKCkpO1xyXG4gIH1cclxufSJdfQ==
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0aW9uLXRyYWNrZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZGF0YS1hY2Nlc3Mvc3JjL2xpYi90YWItY29yZS11dGlsaXR5L2NvcmUvc2VydmljZS9zaWduYWxyL29wZXJhdGlvbi10cmFja2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsS0FBSyxFQUFjLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUUsT0FBTyxFQUdMLGNBQWMsR0FDZixNQUFNLDJDQUEyQyxDQUFDOztBQUVuRDs7OztHQUlHO0FBRUgsTUFBTSxPQUFPLHVCQUF1QjtJQURwQztRQUVFLHVDQUF1QztRQUMvQixzQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBNEIsQ0FBQztRQUVoRSxzQ0FBc0M7UUFDOUIsd0JBQW1CLEdBQUcsSUFBSSxPQUFPLEVBQW9CLENBQUM7UUFFOUQsNkZBQTZGO1FBQ3JGLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztLQXdHL0M7SUF0R0M7O09BRUc7SUFDSCxpQkFBaUIsQ0FBQyxTQUEyQjtRQUMzQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFL0QsNkJBQTZCO1FBQzdCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hELElBQUksQ0FBQyxp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QUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQztJQUNyQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxhQUFhO1FBQ1gsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3JELENBQUM7K0dBL0dVLHVCQUF1QjttSEFBdkIsdUJBQXVCLGNBRFYsTUFBTTs7NEZBQ25CLHVCQUF1QjtrQkFEbkMsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IG1lcmdlLCBPYnNlcnZhYmxlLCBTdWJqZWN0LCB0aHJvd0Vycm9yLCBUaW1lb3V0RXJyb3IgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZmlsdGVyLCB0YWtlLCB0aW1lb3V0LCBjYXRjaEVycm9yLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7XHJcbiAgQ3J1ZE5vdGlmaWNhdGlvbixcclxuICBQZW5kaW5nT3BlcmF0aW9uLFxyXG4gIFNJR05BTFJfQ09ORklHLFxyXG59IGZyb20gJy4uLy4uLy4uL2FwcC9pbnRlcmZhY2VzL3NpZ25hbHIuaW50ZXJmYWNlJztcclxuXHJcbi8qKlxyXG4gKiBPcGVyYXRpb24gVHJhY2tlciBTZXJ2aWNlXHJcbiAqIFRyYWNrcyBhc3luYyBvcGVyYXRpb25zIGJ5IGNvcnJlbGF0aW9uSWQgYW5kIG1hdGNoZXMgdGhlbSB3aXRoIFNpZ25hbFIgbm90aWZpY2F0aW9uc1xyXG4gKiBVc2VkIGJ5IFRhYkZvcm1pb1NlcnZpY2UgZm9yIGhhbmRsaW5nIGFzeW5jIHByb2Nlc3NSZXF1ZXN0IG9wZXJhdGlvbnNcclxuICovXHJcbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXHJcbmV4cG9ydCBjbGFzcyBPcGVyYXRpb25UcmFja2VyU2VydmljZSB7XHJcbiAgLy8gTWFwPGNvcnJlbGF0aW9uSWQsIFBlbmRpbmdPcGVyYXRpb24+XHJcbiAgcHJpdmF0ZSBwZW5kaW5nT3BlcmF0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBQZW5kaW5nT3BlcmF0aW9uPigpO1xyXG5cclxuICAvLyBPYnNlcnZhYmxlIGZvciBjb21wbGV0ZWQgb3BlcmF0aW9uc1xyXG4gIHByaXZhdGUgb3BlcmF0aW9uQ29tcGxldGVkJCA9IG5ldyBTdWJqZWN0PENydWROb3RpZmljYXRpb24+KCk7XHJcblxyXG4gIC8vIENhbmNlbGxhdGlvbiBjaGFubmVsIOKAlCBlbWl0dGVkIGJ5IGNhbmNlbEFsbCgpIHRvIGVycm9yIGFueSBvcGVuIHdhaXRGb3JPcGVyYXRpb24gb2JzZXJ2ZXJzXHJcbiAgcHJpdmF0ZSBjYW5jZWxsYXRpb24kID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBhbiBhc3luYyBvcGVyYXRpb24gZm9yIHRyYWNraW5nXHJcbiAgICovXHJcbiAgcmVnaXN0ZXJPcGVyYXRpb24ob3BlcmF0aW9uOiBQZW5kaW5nT3BlcmF0aW9uKTogdm9pZCB7XHJcbiAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLnNldChvcGVyYXRpb24uY29ycmVsYXRpb25JZCwgb3BlcmF0aW9uKTtcclxuXHJcbiAgICAvLyBBdXRvLWNsZWFudXAgYWZ0ZXIgdGltZW91dFxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmhhcyhvcGVyYXRpb24uY29ycmVsYXRpb25JZCkpIHtcclxuICAgICAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmRlbGV0ZShvcGVyYXRpb24uY29ycmVsYXRpb25JZCk7XHJcbiAgICAgIH1cclxuICAgIH0sIG9wZXJhdGlvbi50aW1lb3V0IHx8IFNJR05BTFJfQ09ORklHLkRFRkFVTFRfVElNRU9VVCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBXYWl0IGZvciBvcGVyYXRpb24gdG8gY29tcGxldGUgdmlhIFNpZ25hbFIgbm90aWZpY2F0aW9uXHJcbiAgICogUmV0dXJucyBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgd2hlbiBub3RpZmljYXRpb24gd2l0aCBtYXRjaGluZyBjb3JyZWxhdGlvbklkIGlzIHJlY2VpdmVkLFxyXG4gICAqIG9yIGVycm9ycyBpZiBjYW5jZWxBbGwoKSBpcyBpbnZva2VkIChlLmcuIG9uIGRpc2Nvbm5lY3QgLyBzaWduT3V0KS5cclxuICAgKi9cclxuICB3YWl0Rm9yT3BlcmF0aW9uKGNvcnJlbGF0aW9uSWQ6IHN0cmluZywgdGltZW91dE1zOiBudW1iZXIgPSBTSUdOQUxSX0NPTkZJRy5ERUZBVUxUX1RJTUVPVVQpOiBPYnNlcnZhYmxlPENydWROb3RpZmljYXRpb24+IHtcclxuICAgIC8vIEF1dG8tcmVnaXN0ZXIgc28gaGFuZGxlTm90aWZpY2F0aW9uIGNhbiBtYXRjaCBpdFxyXG4gICAgaWYgKCF0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmhhcyhjb3JyZWxhdGlvbklkKSkge1xyXG4gICAgICB0aGlzLnJlZ2lzdGVyT3BlcmF0aW9uKHtcclxuICAgICAgICBjb3JyZWxhdGlvbklkLFxyXG4gICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcclxuICAgICAgICB0aW1lb3V0OiB0aW1lb3V0TXNcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY29tcGxldGVkJCA9IHRoaXMub3BlcmF0aW9uQ29tcGxldGVkJC5waXBlKFxyXG4gICAgICBmaWx0ZXIoKG5vdGlmaWNhdGlvbikgPT4gbm90aWZpY2F0aW9uLmNvcnJlbGF0aW9uSWQgPT09IGNvcnJlbGF0aW9uSWQpLFxyXG4gICAgICB0YWtlKDEpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGNhbmNlbGxlZCQgPSB0aGlzLmNhbmNlbGxhdGlvbiQucGlwZShcclxuICAgICAgdGFrZSgxKSxcclxuICAgICAgc3dpdGNoTWFwKChyZWFzb24pID0+IHRocm93RXJyb3IoKCkgPT4gbmV3IEVycm9yKGBTaWduYWxSIG9wZXJhdGlvbiBjYW5jZWxsZWQ6ICR7cmVhc29ufWApKSlcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIG1lcmdlKGNvbXBsZXRlZCQsIGNhbmNlbGxlZCQpLnBpcGUoXHJcbiAgICAgIHRha2UoMSksXHJcbiAgICAgIHRpbWVvdXQodGltZW91dE1zKSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICAvLyBDbGVhbnVwIG9uIHRpbWVvdXQgLyBjYW5jZWxsYXRpb25cclxuICAgICAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmRlbGV0ZShjb3JyZWxhdGlvbklkKTtcclxuXHJcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgVGltZW91dEVycm9yKSB7XHJcbiAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgRXJyb3IoJ09wZXJhdGlvbiB0aW1lZCBvdXQnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgaW5jb21pbmcgU2lnbmFsUiBub3RpZmljYXRpb25cclxuICAgKiBDYWxsZWQgYnkgU2lnbmFsUlNlcnZpY2Ugd2hlbiBub3RpZmljYXRpb24gaXMgcmVjZWl2ZWRcclxuICAgKi9cclxuICBoYW5kbGVOb3RpZmljYXRpb24obm90aWZpY2F0aW9uOiBDcnVkTm90aWZpY2F0aW9uKTogdm9pZCB7XHJcbiAgICBjb25zdCBvcGVyYXRpb24gPSB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmdldChub3RpZmljYXRpb24uY29ycmVsYXRpb25JZCk7XHJcbiAgICBpZiAob3BlcmF0aW9uKSB7XHJcbiAgICAgIC8vIEVtaXQgdG8gb2JzZXJ2ZXJzIHdhaXRpbmcgZm9yIHRoaXMgb3BlcmF0aW9uXHJcbiAgICAgIHRoaXMub3BlcmF0aW9uQ29tcGxldGVkJC5uZXh0KG5vdGlmaWNhdGlvbik7XHJcblxyXG4gICAgICAvLyBDbGVhbnVwXHJcbiAgICAgIHRoaXMucGVuZGluZ09wZXJhdGlvbnMuZGVsZXRlKG5vdGlmaWNhdGlvbi5jb3JyZWxhdGlvbklkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhbmNlbCBhbGwgcGVuZGluZyBvcGVyYXRpb25zIOKAlCBlcnJvcnMgYWxsIG9wZW4gd2FpdEZvck9wZXJhdGlvbigpIG9ic2VydmVycy5cclxuICAgKiBDYWxsZWQgYnkgU2lnbmFsUlNlcnZpY2UuZGlzY29ubmVjdCgpIHNvIGluLWZsaWdodCBDUlVEIFVJcyByZXNvbHZlIGZhc3RcclxuICAgKiBpbnN0ZWFkIG9mIHN0cmFuZGluZyB1bnRpbCB0aGUgMTIwcyB0aW1lb3V0LlxyXG4gICAqL1xyXG4gIGNhbmNlbEFsbChyZWFzb246IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMucGVuZGluZ09wZXJhdGlvbnMuc2l6ZSA9PT0gMCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLnBlbmRpbmdPcGVyYXRpb25zLmNsZWFyKCk7XHJcbiAgICB0aGlzLmNhbmNlbGxhdGlvbiQubmV4dChyZWFzb24pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgb3BlcmF0aW9uIGlzIHBlbmRpbmdcclxuICAgKi9cclxuICBpc1BlbmRpbmcoY29ycmVsYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5wZW5kaW5nT3BlcmF0aW9ucy5oYXMoY29ycmVsYXRpb25JZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgcGVuZGluZyBvcGVyYXRpb25zIGNvdW50IChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldFBlbmRpbmdDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMucGVuZGluZ09wZXJhdGlvbnMuc2l6ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhbGwgcGVuZGluZyBvcGVyYXRpb25zIChmb3IgZGVidWdnaW5nKVxyXG4gICAqL1xyXG4gIGdldEFsbFBlbmRpbmcoKTogUGVuZGluZ09wZXJhdGlvbltdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMucGVuZGluZ09wZXJhdGlvbnMudmFsdWVzKCkpO1xyXG4gIH1cclxufSJdfQ==
@@ -15,6 +15,10 @@ import * as i0 from "@angular/core";
15
15
  export class SignalRInfrastructure {
16
16
  constructor() {
17
17
  this.hubConnection = null;
18
+ // In-flight connect() promise — used to dedupe concurrent calls
19
+ this.connectingPromise = null;
20
+ // Set true on explicit disconnect() so scheduled retries don't resurrect the connection
21
+ this.explicitlyDisconnected = false;
18
22
  // Session storage
19
23
  this.sessionStorageService = inject(SessionStorageService);
20
24
  // local storage
@@ -73,11 +77,39 @@ export class SignalRInfrastructure {
73
77
  }
74
78
  /**
75
79
  * Connect to SignalR hub
80
+ *
81
+ * Idempotent and safe to call from multiple sites:
82
+ * - already CONNECTED → returns immediately
83
+ * - already CONNECTING → returns the in-flight promise
84
+ * - any non-Connected leftover hubConnection → torn down before rebuild
76
85
  */
77
86
  async connect() {
87
+ this.explicitlyDisconnected = false;
78
88
  if (this.hubConnection?.state === signalR.HubConnectionState.Connected) {
79
89
  return;
80
90
  }
91
+ if (this.connectingPromise) {
92
+ return this.connectingPromise;
93
+ }
94
+ // Tear down any stale (non-Connected) hubConnection before rebuilding
95
+ if (this.hubConnection) {
96
+ try {
97
+ await this.hubConnection.stop();
98
+ }
99
+ catch {
100
+ // ignore — we're discarding it anyway
101
+ }
102
+ this.hubConnection = null;
103
+ }
104
+ this.connectingPromise = this.doConnect();
105
+ try {
106
+ await this.connectingPromise;
107
+ }
108
+ finally {
109
+ this.connectingPromise = null;
110
+ }
111
+ }
112
+ async doConnect() {
81
113
  // Get hub URL from Common (set during app initialization via Common.init())
82
114
  const hubUrl = Common.signalRHubUrl;
83
115
  if (!hubUrl) {
@@ -110,8 +142,12 @@ export class SignalRInfrastructure {
110
142
  }
111
143
  catch (error) {
112
144
  this.connectionState.set(CONNECTION_STATE.FAILED);
113
- // Retry after 1 minute
114
- setTimeout(() => this.connect(), 60 * 1000);
145
+ // Retry after 1 minute, but only if the caller hasn't explicitly disconnected
146
+ setTimeout(() => {
147
+ if (!this.explicitlyDisconnected) {
148
+ this.connect();
149
+ }
150
+ }, 60 * 1000);
115
151
  }
116
152
  }
117
153
  /**
@@ -168,8 +204,12 @@ export class SignalRInfrastructure {
168
204
  });
169
205
  this.hubConnection.onclose(() => {
170
206
  this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
171
- // Try to reconnect
172
- setTimeout(() => this.connect(), 60 * 1000);
207
+ // Try to reconnect — but only if the caller hasn't explicitly disconnected
208
+ setTimeout(() => {
209
+ if (!this.explicitlyDisconnected) {
210
+ this.connect();
211
+ }
212
+ }, 60 * 1000);
173
213
  });
174
214
  }
175
215
  /**
@@ -237,18 +277,24 @@ export class SignalRInfrastructure {
237
277
  }
238
278
  /**
239
279
  * Disconnect from SignalR hub (cleanup)
280
+ *
281
+ * Sets explicitlyDisconnected so any pending retry timers from connect()/onclose
282
+ * become no-ops, then stops the hub and clears tracked groups.
240
283
  */
241
284
  async disconnect() {
285
+ this.explicitlyDisconnected = true;
286
+ this.connectingPromise = null;
242
287
  if (this.hubConnection) {
243
288
  try {
244
289
  await this.hubConnection.stop();
245
- this.hubConnection = null;
246
- this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
247
290
  }
248
291
  catch (error) {
249
292
  console.error('[SignalR] Error during disconnect:', error);
250
293
  }
294
+ this.hubConnection = null;
251
295
  }
296
+ this.activeGroups.clear();
297
+ this.connectionState.set(CONNECTION_STATE.DISCONNECTED);
252
298
  }
253
299
  /**
254
300
  * Get active groups (for debugging)
@@ -265,4 +311,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
265
311
  providedIn: 'root',
266
312
  }]
267
313
  }] });
268
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFJTCxtQkFBbUIsRUFDbkIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7QUFFMUU7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJVSxrQkFBYSxHQUFpQyxJQUFJLENBQUM7UUFFM0Qsa0JBQWtCO1FBQ1QsMEJBQXFCLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFFL0QsZ0JBQWdCO1FBQ1Asd0JBQW1CLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFM0QsNkJBQTZCO1FBQ3BCLG9CQUFlLEdBQUcsTUFBTSxDQUFrQixnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRiwyREFBMkQ7UUFDbEQs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SCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLEtBQUssS0FBSyxPQUFPLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDO0lBQzVFLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxVQUFVO1FBQ2QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzFELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDN0QsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDOytHQXpTVSxxQkFBcUI7bUhBQXJCLHFCQUFxQixjQUZwQixNQUFNOzs0RkFFUCxxQkFBcUI7a0JBSGpDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgc2lnbmFsUiBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IENvbW1vbiB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBDb25uZWN0aW9uU3RhdGUsXHJcbiAgQ3J1ZE5vdGlmaWNhdGlvbixcclxuICBTaWduYWxSTWVzc2FnZSxcclxuICBTSUdOQUxSX0hVQl9NRVRIT0RTLFxyXG4gIFNJR05BTFJfRVZFTlRTLFxyXG4gIENSVURfT1BFUkFUSU9OLFxyXG4gIENPTk5FQ1RJT05fU1RBVEUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvc2lnbmFsci5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBTdG9yYWdlQ29uc3RhbnRzIH0gZnJvbSAnLi4vLi4vLi4vYXBwL2NvbnN0YW50cy9zdG9yYWdlLWNvbnN0YW50cyc7XHJcbmltcG9ydCB7IFNlc3Npb25TdG9yYWdlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2F1dGgvc2Vzc2lvbi1zdG9yYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2NhbFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vYXV0aC9sb2NhbC1zdG9yYWdlLnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNpZ25hbFIgSW5mcmFzdHJ1Y3R1cmUgU2VydmljZVxyXG4gKiBIYW5kbGVzIGxvdy1sZXZlbCBXZWJTb2NrZXQgY29ubmVjdGlvbiwgZ3JvdXAgbWFuYWdlbWVudCwgYW5kIHJlY29ubmVjdGlvblxyXG4gKiBJbnRlcm5hbCB1c2Ugb25seSAtIGNvbXBvbmVudHMgc2hvdWxkIHVzZSBTaWduYWxSU2VydmljZSBpbnN0ZWFkXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2lnbmFsUkluZnJhc3RydWN0dXJlIHtcclxuICBwcml2YXRlIGh1YkNvbm5lY3Rpb246IHNpZ25hbFIuSHViQ29ubmVjdGlvbiB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBTZXNzaW9uIHN0b3JhZ2VcclxuICByZWFkb25seSBzZXNzaW9uU3RvcmFnZVNlcnZpY2UgPSBpbmplY3QoU2Vzc2lvblN0b3JhZ2VTZXJ2aWNlKTtcclxuXHJcbiAgLy8gbG9jYWwgc3RvcmFnZVxyXG4gIHJlYWRvbmx5IGxvY2FsU3RvcmFnZVNlcnZpY2UgPSBpbmplY3QoTG9jYWxTdG9yYWdlU2VydmljZSk7XHJcblxyXG4gIC8vIENvbm5lY3Rpb24gc3RhdGUgYXMgc2lnbmFsXHJcbiAgcmVhZG9ubHkgY29ubmVjdGlvblN0YXRlID0gc2lnbmFsPENvbm5lY3Rpb25TdGF0ZT4oQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG5cclxuICAvLyBOb3RpZmljYXRpb24gc3RyZWFtIChpbnRlcm5hbCAtIGVtaXRzIHRvIFNpZ25hbFJTZXJ2aWNlKVxyXG4gIHJlYWRvbmx5IG5vdGlmaWNhdGlvbnMkID0gbmV3IFN1YmplY3Q8Q3J1ZE5vdGlmaWNhdGlvbj4oKTtcclxuXHJcbiAgLy8gVHJhY2sgYWN0aXZlIGdyb3VwcyB0byByZWpvaW4gYWZ0ZXIgcmVjb25uZWN0aW9uXHJcbiAgcHJpdmF0ZSBhY3RpdmVHcm91cHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogSGVscGVyIG1ldGhvZCB0byBnZXQgdmFsdWUgZnJvbSBzdG9yYWdlXHJcbiAgICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgb2Ygc3RvcmFnZSwgJ1Nlc3Npb24nIG9yICdMb2NhbCdcclxuICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgdG8gcmV0cmlldmUgdGhlIHZhbHVlIGZvclxyXG4gICAqIEByZXR1cm5zIFRoZSB2YWx1ZSBmcm9tIHN0b3JhZ2UsIG9yIG51bGwgaWYgbm90IGF2YWlsYWJsZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0RnJvbVN0b3JhZ2UodHlwZTogc3RyaW5nLCBrZXk6IHN0cmluZykge1xyXG4gICAgdHJ5IHtcclxuICAgICAgbGV0IGluZm86IGFueSA9IG51bGw7XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ1Nlc3Npb24nKSB7XHJcbiAgICAgICAgLy8gR2V0IHZhbHVlIGZyb20gc2Vzc2lvbiBzdG9yYWdlXHJcbiAgICAgICAgaW5mbyA9IHRoaXMuc2Vzc2lvblN0b3JhZ2VTZXJ2aWNlLmdldFNlc3Npb25TdG9yYWdlKGtleSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0eXBlID09PSAnTG9jYWwnKSB7XHJcbiAgICAgICAgLy8gR2V0IHZhbHVlIGZyb20gbG9jYWwgc3RvcmFnZVxyXG4gICAgICAgIGluZm8gPSB0aGlzLmxvY2FsU3RvcmFnZVNlcnZpY2UuZ2V0TG9jYWxTdG9yYWdlKGtleSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChpbmZvICYmIHR5cGVvZiBpbmZvID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIC8vIFBhcnNlIHRoZSB2YWx1ZSBpZiBpdCdzIGEgc3RyaW5nXHJcbiAgICAgICAgaW5mbyA9IEpTT04ucGFyc2UoaW5mbyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBpbmZvO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgLy8gTG9nIGVycm9yIGlmIGZhaWxlZCB0byBnZXQgdmFsdWUgZnJvbSBzdG9yYWdlXHJcbiAgICAgIGNvbnNvbGUud2FybignRmFpbGVkIHRvIGdldCBjdXJyZW50IGFwcCBJRCBmcm9tIHNlc3Npb246JywgZXJyb3IpO1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBhcHBJZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGFwcEluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdTZXNzaW9uJywgU3RvcmFnZUNvbnN0YW50cy5hcHBJbmZvKTtcclxuICAgIHJldHVybiBhcHBJbmZvPy5JZCB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGVudmlyb25tZW50SWQoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBlbnZJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnU2Vzc2lvbicsIFN0b3JhZ2VDb25zdGFudHMuZW52aXJvbm1lbnRJbmZvKTtcclxuICAgIHJldHVybiBlbnZJbmZvPy5JZCB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHRlbmFudElkKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgdGVuYW50SW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ0xvY2FsJywgU3RvcmFnZUNvbnN0YW50cy5vcmdJbmZvKTtcclxuICAgIHJldHVybiB0ZW5hbnRJbmZvPy5JZCB8fCBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHRva2VuKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgYXV0aEluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdMb2NhbCcsIFN0b3JhZ2VDb25zdGFudHMudG9rZW5JbmZvKTtcclxuICAgIHJldHVybiBhdXRoSW5mbz8udG9rZW4gfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbm5lY3QgdG8gU2lnbmFsUiBodWJcclxuICAgKi9cclxuICBhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbj8uc3RhdGUgPT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGh1YiBVUkwgZnJvbSBDb21tb24gKHNldCBkdXJpbmcgYXBwIGluaXRpYWxpemF0aW9uIHZpYSBDb21tb24uaW5pdCgpKVxyXG4gICAgY29uc3QgaHViVXJsID0gQ29tbW9uLnNpZ25hbFJIdWJVcmw7XHJcblxyXG4gICAgaWYgKCFodWJVcmwpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignW1NpZ25hbFJdIEh1YiBVUkwgbm90IGNvbmZpZ3VyZWQuIE1ha2Ugc3VyZSBDb21tb24uaW5pdCgpIGlzIGNhbGxlZCB3aXRoIGVudmlyb25tZW50LicpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuQ09OTkVDVElORyk7XHJcblxyXG4gICAgICB0aGlzLmh1YkNvbm5lY3Rpb24gPSBuZXcgc2lnbmFsUi5IdWJDb25uZWN0aW9uQnVpbGRlcigpXHJcbiAgICAgICAgLndpdGhVcmwoaHViVXJsLCB7XHJcbiAgICAgICAgICBhY2Nlc3NUb2tlbkZhY3Rvcnk6ICgpID0+IHRoaXMudG9rZW4gfHwgJycsXHJcbiAgICAgICAgICBza2lwTmVnb3RpYXRpb246IGZhbHNlLFxyXG4gICAgICAgICAgdHJhbnNwb3J0OiBzaWduYWxSLkh0dHBUcmFuc3BvcnRUeXBlLldlYlNvY2tldHMgfCBzaWduYWxSLkh0dHBUcmFuc3BvcnRUeXBlLlNlcnZlclNlbnRFdmVudHMsXHJcbiAgICAgICAgfSlcclxuICAgICAgICAud2l0aEF1dG9tYXRpY1JlY29ubmVjdCh7XHJcbiAgICAgICAgICBuZXh0UmV0cnlEZWxheUluTWlsbGlzZWNvbmRzOiAocmV0cnlDb250ZXh0OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgLy8gRXhwb25lbnRpYWwgYmFja29mZjogMHMsIDJzLCAxMHMsIDMwcywgbWF4IDYwc1xyXG4gICAgICAgICAgICBpZiAocmV0cnlDb250ZXh0LmVsYXBzZWRNaWxsaXNlY29uZHMgPCA2MDAwMCkge1xyXG4gICAgICAgICAgICAgIHJldHVybiBNYXRoLm1pbigxMDAwICogTWF0aC5wb3coMiwgcmV0cnlDb250ZXh0LnByZXZpb3VzUmV0cnlDb3VudCksIDYwMDAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDsgLy8gU3RvcCByZXRyeWluZyBhZnRlciAxIG1pbnV0ZVxyXG4gICAgICAgICAgfSxcclxuICAgICAgICB9KVxyXG4gICAgICAgIC5jb25maWd1cmVMb2dnaW5nKHNpZ25hbFIuTG9nTGV2ZWwuSW5mb3JtYXRpb24pXHJcbiAgICAgICAgLmJ1aWxkKCk7XHJcblxyXG4gICAgICB0aGlzLnJlZ2lzdGVyRXZlbnRIYW5kbGVycygpO1xyXG4gICAgICB0aGlzLnJlZ2lzdGVyQ29ubmVjdGlvbkxpZmVjeWNsZSgpO1xyXG5cclxuICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLnN0YXJ0KCk7XHJcblxyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgdGhpcy5jb25uZWN0aW9uU3RhdGUuc2V0KENPTk5FQ1RJT05fU1RBVEUuRkFJTEVEKTtcclxuXHJcbiAgICAgIC8vIFJldHJ5IGFmdGVyIDEgbWludXRlXHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jb25uZWN0KCksIDYwICogMTAwMCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBTaWduYWxSIGV2ZW50IGhhbmRsZXJzIGZvciBDUlVEIG5vdGlmaWNhdGlvbnNcclxuICAgKi9cclxuICBwcml2YXRlIHJlZ2lzdGVyRXZlbnRIYW5kbGVycygpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uKSByZXR1cm47XHJcblxyXG4gICAgLy8gSU5TRVJUIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5JTlNFUlRfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLklOU0VSVCwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gVVBEQVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5VUERBVEVfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLlVQREFURSwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gREVMRVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5ERUxFVEVfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLkRFTEVURSwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeHRyYWN0IG5vdGlmaWNhdGlvbiBmcm9tIFNpZ25hbFIgY2FsbGJhY2sgYXJnc1xyXG4gICAqIEhhbmRsZXMgYm90aCB1bndyYXBwZWQgKGRpcmVjdCBvYmplY3QpIGFuZCB3cmFwcGVkICh7IHR5cGUsIHRhcmdldCwgYXJndW1lbnRzIH0pIGZvcm1hdHNcclxuICAgKi9cclxuICBwcml2YXRlIGV4dHJhY3ROb3RpZmljYXRpb24oYXJnczogYW55W10pOiBDcnVkTm90aWZpY2F0aW9uIHtcclxuICAgIGNvbnN0IGRhdGEgPSBhcmdzWzBdO1xyXG5cclxuICAgIC8vIElmIFNpZ25hbFIgZGlkbid0IHVud3JhcDogZGF0YSBpcyByYXcgU2lnbmFsUk1lc3NhZ2Ugd2l0aCB7IHR5cGUsIHRhcmdldCwgYXJndW1lbnRzOiBbLi4uXSB9XHJcbiAgICBpZiAoZGF0YT8uYXJndW1lbnRzICYmIEFycmF5LmlzQXJyYXkoZGF0YS5hcmd1bWVudHMpKSB7XHJcbiAgICAgIHJldHVybiAoZGF0YSBhcyBTaWduYWxSTWVzc2FnZSkuYXJndW1lbnRzWzBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIFNpZ25hbFIgdW53cmFwcGVkOiBkYXRhIGlzIHRoZSBub3RpZmljYXRpb24gZGlyZWN0bHlcclxuICAgIHJldHVybiBkYXRhIGFzIENydWROb3RpZmljYXRpb247XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBjb25uZWN0aW9uIGxpZmVjeWNsZSBoYW5kbGVyc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVnaXN0ZXJDb25uZWN0aW9uTGlmZWN5Y2xlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24pIHJldHVybjtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25yZWNvbm5lY3RpbmcoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5SRUNPTk5FQ1RJTkcpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9ucmVjb25uZWN0ZWQoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG5cclxuICAgICAgLy8gUmVqb2luIGFsbCBncm91cHMgYWZ0ZXIgcmVjb25uZWN0aW9uXHJcbiAgICAgIHRoaXMucmVqb2luR3JvdXBzKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25jbG9zZSgoKSA9PiB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gICAgICAvLyBUcnkgdG8gcmVjb25uZWN0XHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jb25uZWN0KCksIDYwICogMTAwMCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEpvaW4gU2lnbmFsUiBncm91cCBmb3IgYW4gQXBwT2JqZWN0XHJcbiAgICovXHJcbiAgYXN5bmMgam9pbkdyb3VwKGFwcE9iamVjdElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uIHx8IHRoaXMuaHViQ29ubmVjdGlvbi5zdGF0ZSAhPT0gc2lnbmFsUi5IdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBpZiAoIXRoaXMudGVuYW50SWQgfHwgIXRoaXMuYXBwSWQgfHwgIXRoaXMuZW52aXJvbm1lbnRJZCB8fCAhYXBwT2JqZWN0SWQpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5pbnZva2UoXHJcbiAgICAgICAgU0lHTkFMUl9IVUJfTUVUSE9EUy5KT0lOX0dST1VQLFxyXG4gICAgICAgIHRoaXMudGVuYW50SWQsXHJcbiAgICAgICAgdGhpcy5hcHBJZCxcclxuICAgICAgICB0aGlzLmVudmlyb25tZW50SWQsXHJcbiAgICAgICAgYXBwT2JqZWN0SWRcclxuICAgICAgKTtcclxuXHJcbiAgICAgIC8vIFRyYWNrIHRoaXMgZ3JvdXAgZm9yIHJlY29ubmVjdGlvblxyXG4gICAgICB0aGlzLmFjdGl2ZUdyb3Vwcy5hZGQoYXBwT2JqZWN0SWQpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgW1NpZ25hbFJdIEZhaWxlZCB0byBqb2luIGdyb3VwOiAke2FwcE9iamVjdElkfWAsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlIFNpZ25hbFIgZ3JvdXBcclxuICAgKi9cclxuICBhc3luYyBsZWF2ZUdyb3VwKGFwcE9iamVjdElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uIHx8IHRoaXMuaHViQ29ubmVjdGlvbi5zdGF0ZSAhPT0gc2lnbmFsUi5IdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkKSB7XHJcbiAgICAgIC8vIFJlbW92ZSBmcm9tIHRyYWNraW5nIGV2ZW4gaWYgbm90IGNvbm5lY3RlZFxyXG4gICAgICB0aGlzLmFjdGl2ZUdyb3Vwcy5kZWxldGUoYXBwT2JqZWN0SWQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLnRlbmFudElkIHx8ICF0aGlzLmFwcElkIHx8ICF0aGlzLmVudmlyb25tZW50SWQgfHwgIWFwcE9iamVjdElkKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uaW52b2tlKFxyXG4gICAgICAgIFNJR05BTFJfSFVCX01FVEhPRFMuTEVBVkVfR1JPVVAsXHJcbiAgICAgICAgdGhpcy50ZW5hbnRJZCxcclxuICAgICAgICB0aGlzLmFwcElkLFxyXG4gICAgICAgIHRoaXMuZW52aXJvbm1lbnRJZCxcclxuICAgICAgICBhcHBPYmplY3RJZFxyXG4gICAgICApO1xyXG5cclxuICAgICAgLy8gUmVtb3ZlIGZyb20gdHJhY2tpbmdcclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuZGVsZXRlKGFwcE9iamVjdElkKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtTaWduYWxSXSBGYWlsZWQgdG8gbGVhdmUgZ3JvdXA6ICR7YXBwT2JqZWN0SWR9YCwgZXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVqb2luIGFsbCBhY3RpdmUgZ3JvdXBzIGFmdGVyIHJlY29ubmVjdGlvblxyXG4gICAqIFRoaXMgZW5zdXJlcyBjb21wb25lbnRzIGNvbnRpbnVlIHJlY2VpdmluZyBub3RpZmljYXRpb25zIGFmdGVyIG5ldHdvcmsgaW50ZXJydXB0aW9uXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyByZWpvaW5Hcm91cHMoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAodGhpcy5hY3RpdmVHcm91cHMuc2l6ZSA9PT0gMCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGxpc3Qgb2YgZ3JvdXBzIHRvIHJlam9pblxyXG4gICAgY29uc3QgZ3JvdXBzID0gQXJyYXkuZnJvbSh0aGlzLmFjdGl2ZUdyb3Vwcyk7XHJcblxyXG4gICAgLy8gQ2xlYXIgdGhlIHNldCAod2lsbCBiZSByZS1hZGRlZCBkdXJpbmcgam9pbkdyb3VwKVxyXG4gICAgdGhpcy5hY3RpdmVHcm91cHMuY2xlYXIoKTtcclxuXHJcbiAgICAvLyBSZWpvaW4gZWFjaCBncm91cFxyXG4gICAgZm9yIChjb25zdCBhcHBPYmplY3RJZCBvZiBncm91cHMpIHtcclxuICAgICAgYXdhaXQgdGhpcy5qb2luR3JvdXAoYXBwT2JqZWN0SWQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgY29ubmVjdGVkXHJcbiAgICovXHJcbiAgaXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5odWJDb25uZWN0aW9uPy5zdGF0ZSA9PT0gc2lnbmFsUi5IdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGlzY29ubmVjdCBmcm9tIFNpZ25hbFIgaHViIChjbGVhbnVwKVxyXG4gICAqL1xyXG4gIGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAodGhpcy5odWJDb25uZWN0aW9uKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLnN0b3AoKTtcclxuICAgICAgICB0aGlzLmh1YkNvbm5lY3Rpb24gPSBudWxsO1xyXG4gICAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignW1NpZ25hbFJdIEVycm9yIGR1cmluZyBkaXNjb25uZWN0OicsIGVycm9yKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGFjdGl2ZSBncm91cHMgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0QWN0aXZlR3JvdXBzKCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuYWN0aXZlR3JvdXBzKTtcclxuICB9XHJcbn0iXX0=
314
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9kYXRhLWFjY2Vzcy9zcmMvbGliL3RhYi1jb3JlLXV0aWxpdHkvY29yZS9zZXJ2aWNlL3NpZ25hbHIvc2lnbmFsci1pbmZyYXN0cnVjdHVyZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZELE9BQU8sRUFJTCxtQkFBbUIsRUFDbkIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSwyQ0FBMkMsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM1RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQzs7QUFFMUU7Ozs7R0FJRztBQUlILE1BQU0sT0FBTyxxQkFBcUI7SUFIbEM7UUFJVSxrQkFBYSxHQUFpQyxJQUFJLENBQUM7UUFFM0QsZ0VBQWdFO1FBQ3hELHNCQUFpQixHQUF5QixJQUFJLENBQUM7UUFFdkQsd0ZBQXdGO1FBQ2hGLDJCQUFzQixHQUFHLEtBQUssQ0FBQztRQUV2QyxrQkFBa0I7UUFDVCwwQkFBcUIsR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUUvRCxnQkFBZ0I7UUFDUCx3QkFBbUIsR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUUz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QXNCLEdBQUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFFOUIsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNsQyxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixPQUFPLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzdELENBQUM7WUFDRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUM1QixDQUFDO1FBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDOytHQTdWVSxxQkFBcUI7bUhBQXJCLHFCQUFxQixjQUZwQixNQUFNOzs0RkFFUCxxQkFBcUI7a0JBSGpDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgc2lnbmFsUiBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IENvbW1vbiB9IGZyb20gJy4uLy4uLy4uL2FwcC9jb25zdGFudHMvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBDb25uZWN0aW9uU3RhdGUsXHJcbiAgQ3J1ZE5vdGlmaWNhdGlvbixcclxuICBTaWduYWxSTWVzc2FnZSxcclxuICBTSUdOQUxSX0hVQl9NRVRIT0RTLFxyXG4gIFNJR05BTFJfRVZFTlRTLFxyXG4gIENSVURfT1BFUkFUSU9OLFxyXG4gIENPTk5FQ1RJT05fU1RBVEUsXHJcbn0gZnJvbSAnLi4vLi4vLi4vYXBwL2ludGVyZmFjZXMvc2lnbmFsci5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBTdG9yYWdlQ29uc3RhbnRzIH0gZnJvbSAnLi4vLi4vLi4vYXBwL2NvbnN0YW50cy9zdG9yYWdlLWNvbnN0YW50cyc7XHJcbmltcG9ydCB7IFNlc3Npb25TdG9yYWdlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2F1dGgvc2Vzc2lvbi1zdG9yYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2NhbFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vYXV0aC9sb2NhbC1zdG9yYWdlLnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNpZ25hbFIgSW5mcmFzdHJ1Y3R1cmUgU2VydmljZVxyXG4gKiBIYW5kbGVzIGxvdy1sZXZlbCBXZWJTb2NrZXQgY29ubmVjdGlvbiwgZ3JvdXAgbWFuYWdlbWVudCwgYW5kIHJlY29ubmVjdGlvblxyXG4gKiBJbnRlcm5hbCB1c2Ugb25seSAtIGNvbXBvbmVudHMgc2hvdWxkIHVzZSBTaWduYWxSU2VydmljZSBpbnN0ZWFkXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2lnbmFsUkluZnJhc3RydWN0dXJlIHtcclxuICBwcml2YXRlIGh1YkNvbm5lY3Rpb246IHNpZ25hbFIuSHViQ29ubmVjdGlvbiB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBJbi1mbGlnaHQgY29ubmVjdCgpIHByb21pc2Ug4oCUIHVzZWQgdG8gZGVkdXBlIGNvbmN1cnJlbnQgY2FsbHNcclxuICBwcml2YXRlIGNvbm5lY3RpbmdQcm9taXNlOiBQcm9taXNlPHZvaWQ+IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8vIFNldCB0cnVlIG9uIGV4cGxpY2l0IGRpc2Nvbm5lY3QoKSBzbyBzY2hlZHVsZWQgcmV0cmllcyBkb24ndCByZXN1cnJlY3QgdGhlIGNvbm5lY3Rpb25cclxuICBwcml2YXRlIGV4cGxpY2l0bHlEaXNjb25uZWN0ZWQgPSBmYWxzZTtcclxuXHJcbiAgLy8gU2Vzc2lvbiBzdG9yYWdlXHJcbiAgcmVhZG9ubHkgc2Vzc2lvblN0b3JhZ2VTZXJ2aWNlID0gaW5qZWN0KFNlc3Npb25TdG9yYWdlU2VydmljZSk7XHJcblxyXG4gIC8vIGxvY2FsIHN0b3JhZ2VcclxuICByZWFkb25seSBsb2NhbFN0b3JhZ2VTZXJ2aWNlID0gaW5qZWN0KExvY2FsU3RvcmFnZVNlcnZpY2UpO1xyXG5cclxuICAvLyBDb25uZWN0aW9uIHN0YXRlIGFzIHNpZ25hbFxyXG4gIHJlYWRvbmx5IGNvbm5lY3Rpb25TdGF0ZSA9IHNpZ25hbDxDb25uZWN0aW9uU3RhdGU+KENPTk5FQ1RJT05fU1RBVEUuRElTQ09OTkVDVEVEKTtcclxuXHJcbiAgLy8gTm90aWZpY2F0aW9uIHN0cmVhbSAoaW50ZXJuYWwgLSBlbWl0cyB0byBTaWduYWxSU2VydmljZSlcclxuICByZWFkb25seSBub3RpZmljYXRpb25zJCA9IG5ldyBTdWJqZWN0PENydWROb3RpZmljYXRpb24+KCk7XHJcblxyXG4gIC8vIFRyYWNrIGFjdGl2ZSBncm91cHMgdG8gcmVqb2luIGFmdGVyIHJlY29ubmVjdGlvblxyXG4gIHByaXZhdGUgYWN0aXZlR3JvdXBzID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEhlbHBlciBtZXRob2QgdG8gZ2V0IHZhbHVlIGZyb20gc3RvcmFnZVxyXG4gICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHN0b3JhZ2UsICdTZXNzaW9uJyBvciAnTG9jYWwnXHJcbiAgICogQHBhcmFtIGtleSBUaGUga2V5IHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmb3JcclxuICAgKiBAcmV0dXJucyBUaGUgdmFsdWUgZnJvbSBzdG9yYWdlLCBvciBudWxsIGlmIG5vdCBhdmFpbGFibGVcclxuICAgKi9cclxuICBwcml2YXRlIGdldEZyb21TdG9yYWdlKHR5cGU6IHN0cmluZywga2V5OiBzdHJpbmcpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCBpbmZvOiBhbnkgPSBudWxsO1xyXG5cclxuICAgICAgaWYgKHR5cGUgPT09ICdTZXNzaW9uJykge1xyXG4gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIHNlc3Npb24gc3RvcmFnZVxyXG4gICAgICAgIGluZm8gPSB0aGlzLnNlc3Npb25TdG9yYWdlU2VydmljZS5nZXRTZXNzaW9uU3RvcmFnZShrZXkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ0xvY2FsJykge1xyXG4gICAgICAgIC8vIEdldCB2YWx1ZSBmcm9tIGxvY2FsIHN0b3JhZ2VcclxuICAgICAgICBpbmZvID0gdGhpcy5sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldExvY2FsU3RvcmFnZShrZXkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaW5mbyAmJiB0eXBlb2YgaW5mbyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAvLyBQYXJzZSB0aGUgdmFsdWUgaWYgaXQncyBhIHN0cmluZ1xyXG4gICAgICAgIGluZm8gPSBKU09OLnBhcnNlKGluZm8pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gaW5mbztcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIC8vIExvZyBlcnJvciBpZiBmYWlsZWQgdG8gZ2V0IHZhbHVlIGZyb20gc3RvcmFnZVxyXG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBnZXQgY3VycmVudCBhcHAgSUQgZnJvbSBzZXNzaW9uOicsIGVycm9yKTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgYXBwSWQoKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgICBjb25zdCBhcHBJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnU2Vzc2lvbicsIFN0b3JhZ2VDb25zdGFudHMuYXBwSW5mbyk7XHJcbiAgICByZXR1cm4gYXBwSW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCBlbnZpcm9ubWVudElkKCk6IHN0cmluZyB8IG51bGwge1xyXG4gICAgY29uc3QgZW52SW5mbyA9IHRoaXMuZ2V0RnJvbVN0b3JhZ2UoJ1Nlc3Npb24nLCBTdG9yYWdlQ29uc3RhbnRzLmVudmlyb25tZW50SW5mbyk7XHJcbiAgICByZXR1cm4gZW52SW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCB0ZW5hbnRJZCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IHRlbmFudEluZm8gPSB0aGlzLmdldEZyb21TdG9yYWdlKCdMb2NhbCcsIFN0b3JhZ2VDb25zdGFudHMub3JnSW5mbyk7XHJcbiAgICByZXR1cm4gdGVuYW50SW5mbz8uSWQgfHwgbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCB0b2tlbigpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGNvbnN0IGF1dGhJbmZvID0gdGhpcy5nZXRGcm9tU3RvcmFnZSgnTG9jYWwnLCBTdG9yYWdlQ29uc3RhbnRzLnRva2VuSW5mbyk7XHJcbiAgICByZXR1cm4gYXV0aEluZm8/LnRva2VuIHx8IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb25uZWN0IHRvIFNpZ25hbFIgaHViXHJcbiAgICpcclxuICAgKiBJZGVtcG90ZW50IGFuZCBzYWZlIHRvIGNhbGwgZnJvbSBtdWx0aXBsZSBzaXRlczpcclxuICAgKiAtIGFscmVhZHkgQ09OTkVDVEVEIOKGkiByZXR1cm5zIGltbWVkaWF0ZWx5XHJcbiAgICogLSBhbHJlYWR5IENPTk5FQ1RJTkcg4oaSIHJldHVybnMgdGhlIGluLWZsaWdodCBwcm9taXNlXHJcbiAgICogLSBhbnkgbm9uLUNvbm5lY3RlZCBsZWZ0b3ZlciBodWJDb25uZWN0aW9uIOKGkiB0b3JuIGRvd24gYmVmb3JlIHJlYnVpbGRcclxuICAgKi9cclxuICBhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgdGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbj8uc3RhdGUgPT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuY29ubmVjdGluZ1Byb21pc2UpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGluZ1Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGVhciBkb3duIGFueSBzdGFsZSAobm9uLUNvbm5lY3RlZCkgaHViQ29ubmVjdGlvbiBiZWZvcmUgcmVidWlsZGluZ1xyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbikge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5zdG9wKCk7XHJcbiAgICAgIH0gY2F0Y2gge1xyXG4gICAgICAgIC8vIGlnbm9yZSDigJQgd2UncmUgZGlzY2FyZGluZyBpdCBhbnl3YXlcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmh1YkNvbm5lY3Rpb24gPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY29ubmVjdGluZ1Byb21pc2UgPSB0aGlzLmRvQ29ubmVjdCgpO1xyXG4gICAgdHJ5IHtcclxuICAgICAgYXdhaXQgdGhpcy5jb25uZWN0aW5nUHJvbWlzZTtcclxuICAgIH0gZmluYWxseSB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGluZ1Byb21pc2UgPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBkb0Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAvLyBHZXQgaHViIFVSTCBmcm9tIENvbW1vbiAoc2V0IGR1cmluZyBhcHAgaW5pdGlhbGl6YXRpb24gdmlhIENvbW1vbi5pbml0KCkpXHJcbiAgICBjb25zdCBodWJVcmwgPSBDb21tb24uc2lnbmFsUkh1YlVybDtcclxuXHJcbiAgICBpZiAoIWh1YlVybCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdbU2lnbmFsUl0gSHViIFVSTCBub3QgY29uZmlndXJlZC4gTWFrZSBzdXJlIENvbW1vbi5pbml0KCkgaXMgY2FsbGVkIHdpdGggZW52aXJvbm1lbnQuJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNUSU5HKTtcclxuXHJcbiAgICAgIHRoaXMuaHViQ29ubmVjdGlvbiA9IG5ldyBzaWduYWxSLkh1YkNvbm5lY3Rpb25CdWlsZGVyKClcclxuICAgICAgICAud2l0aFVybChodWJVcmwsIHtcclxuICAgICAgICAgIGFjY2Vzc1Rva2VuRmFjdG9yeTogKCkgPT4gdGhpcy50b2tlbiB8fCAnJyxcclxuICAgICAgICAgIHNraXBOZWdvdGlhdGlvbjogZmFsc2UsXHJcbiAgICAgICAgICB0cmFuc3BvcnQ6IHNpZ25hbFIuSHR0cFRyYW5zcG9ydFR5cGUuV2ViU29ja2V0cyB8IHNpZ25hbFIuSHR0cFRyYW5zcG9ydFR5cGUuU2VydmVyU2VudEV2ZW50cyxcclxuICAgICAgICB9KVxyXG4gICAgICAgIC53aXRoQXV0b21hdGljUmVjb25uZWN0KHtcclxuICAgICAgICAgIG5leHRSZXRyeURlbGF5SW5NaWxsaXNlY29uZHM6IChyZXRyeUNvbnRleHQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAvLyBFeHBvbmVudGlhbCBiYWNrb2ZmOiAwcywgMnMsIDEwcywgMzBzLCBtYXggNjBzXHJcbiAgICAgICAgICAgIGlmIChyZXRyeUNvbnRleHQuZWxhcHNlZE1pbGxpc2Vjb25kcyA8IDYwMDAwKSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKDEwMDAgKiBNYXRoLnBvdygyLCByZXRyeUNvbnRleHQucHJldmlvdXNSZXRyeUNvdW50KSwgNjAwMDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyBTdG9wIHJldHJ5aW5nIGFmdGVyIDEgbWludXRlXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmNvbmZpZ3VyZUxvZ2dpbmcoc2lnbmFsUi5Mb2dMZXZlbC5JbmZvcm1hdGlvbilcclxuICAgICAgICAuYnVpbGQoKTtcclxuXHJcbiAgICAgIHRoaXMucmVnaXN0ZXJFdmVudEhhbmRsZXJzKCk7XHJcbiAgICAgIHRoaXMucmVnaXN0ZXJDb25uZWN0aW9uTGlmZWN5Y2xlKCk7XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhcnQoKTtcclxuXHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkNPTk5FQ1RFRCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5GQUlMRUQpO1xyXG5cclxuICAgICAgLy8gUmV0cnkgYWZ0ZXIgMSBtaW51dGUsIGJ1dCBvbmx5IGlmIHRoZSBjYWxsZXIgaGFzbid0IGV4cGxpY2l0bHkgZGlzY29ubmVjdGVkXHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIGlmICghdGhpcy5leHBsaWNpdGx5RGlzY29ubmVjdGVkKSB7XHJcbiAgICAgICAgICB0aGlzLmNvbm5lY3QoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIDYwICogMTAwMCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBTaWduYWxSIGV2ZW50IGhhbmRsZXJzIGZvciBDUlVEIG5vdGlmaWNhdGlvbnNcclxuICAgKi9cclxuICBwcml2YXRlIHJlZ2lzdGVyRXZlbnRIYW5kbGVycygpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5odWJDb25uZWN0aW9uKSByZXR1cm47XHJcblxyXG4gICAgLy8gSU5TRVJUIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5JTlNFUlRfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLklOU0VSVCwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gVVBEQVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5VUERBVEVfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLlVQREFURSwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gREVMRVRFIG5vdGlmaWNhdGlvbnNcclxuICAgIHRoaXMuaHViQ29ubmVjdGlvbi5vbihTSUdOQUxSX0VWRU5UUy5ERUxFVEVfQ09NUExFVEVELCAoLi4uYXJnczogYW55W10pID0+IHtcclxuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uID0gdGhpcy5leHRyYWN0Tm90aWZpY2F0aW9uKGFyZ3MpO1xyXG4gICAgICBjb25zdCBlbnJpY2hlZCA9IHsgLi4ubm90aWZpY2F0aW9uLCBvcGVyYXRpb246IENSVURfT1BFUkFUSU9OLkRFTEVURSwgcmVjZWl2ZWRBdDogbmV3IERhdGUoKSB9O1xyXG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMkLm5leHQoZW5yaWNoZWQpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeHRyYWN0IG5vdGlmaWNhdGlvbiBmcm9tIFNpZ25hbFIgY2FsbGJhY2sgYXJnc1xyXG4gICAqIEhhbmRsZXMgYm90aCB1bndyYXBwZWQgKGRpcmVjdCBvYmplY3QpIGFuZCB3cmFwcGVkICh7IHR5cGUsIHRhcmdldCwgYXJndW1lbnRzIH0pIGZvcm1hdHNcclxuICAgKi9cclxuICBwcml2YXRlIGV4dHJhY3ROb3RpZmljYXRpb24oYXJnczogYW55W10pOiBDcnVkTm90aWZpY2F0aW9uIHtcclxuICAgIGNvbnN0IGRhdGEgPSBhcmdzWzBdO1xyXG5cclxuICAgIC8vIElmIFNpZ25hbFIgZGlkbid0IHVud3JhcDogZGF0YSBpcyByYXcgU2lnbmFsUk1lc3NhZ2Ugd2l0aCB7IHR5cGUsIHRhcmdldCwgYXJndW1lbnRzOiBbLi4uXSB9XHJcbiAgICBpZiAoZGF0YT8uYXJndW1lbnRzICYmIEFycmF5LmlzQXJyYXkoZGF0YS5hcmd1bWVudHMpKSB7XHJcbiAgICAgIHJldHVybiAoZGF0YSBhcyBTaWduYWxSTWVzc2FnZSkuYXJndW1lbnRzWzBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIFNpZ25hbFIgdW53cmFwcGVkOiBkYXRhIGlzIHRoZSBub3RpZmljYXRpb24gZGlyZWN0bHlcclxuICAgIHJldHVybiBkYXRhIGFzIENydWROb3RpZmljYXRpb247XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlciBjb25uZWN0aW9uIGxpZmVjeWNsZSBoYW5kbGVyc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVnaXN0ZXJDb25uZWN0aW9uTGlmZWN5Y2xlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmh1YkNvbm5lY3Rpb24pIHJldHVybjtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25yZWNvbm5lY3RpbmcoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5SRUNPTk5FQ1RJTkcpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5odWJDb25uZWN0aW9uLm9ucmVjb25uZWN0ZWQoKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5DT05ORUNURUQpO1xyXG5cclxuICAgICAgLy8gUmVqb2luIGFsbCBncm91cHMgYWZ0ZXIgcmVjb25uZWN0aW9uXHJcbiAgICAgIHRoaXMucmVqb2luR3JvdXBzKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmh1YkNvbm5lY3Rpb24ub25jbG9zZSgoKSA9PiB7XHJcbiAgICAgIHRoaXMuY29ubmVjdGlvblN0YXRlLnNldChDT05ORUNUSU9OX1NUQVRFLkRJU0NPTk5FQ1RFRCk7XHJcblxyXG4gICAgICAvLyBUcnkgdG8gcmVjb25uZWN0IOKAlCBidXQgb25seSBpZiB0aGUgY2FsbGVyIGhhc24ndCBleHBsaWNpdGx5IGRpc2Nvbm5lY3RlZFxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRseURpc2Nvbm5lY3RlZCkge1xyXG4gICAgICAgICAgdGhpcy5jb25uZWN0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LCA2MCAqIDEwMDApO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBKb2luIFNpZ25hbFIgZ3JvdXAgZm9yIGFuIEFwcE9iamVjdFxyXG4gICAqL1xyXG4gIGFzeW5jIGpvaW5Hcm91cChhcHBPYmplY3RJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbiB8fCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhdGUgIT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgaWYgKCF0aGlzLnRlbmFudElkIHx8ICF0aGlzLmFwcElkIHx8ICF0aGlzLmVudmlyb25tZW50SWQgfHwgIWFwcE9iamVjdElkKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLmh1YkNvbm5lY3Rpb24uaW52b2tlKFxyXG4gICAgICAgIFNJR05BTFJfSFVCX01FVEhPRFMuSk9JTl9HUk9VUCxcclxuICAgICAgICB0aGlzLnRlbmFudElkLFxyXG4gICAgICAgIHRoaXMuYXBwSWQsXHJcbiAgICAgICAgdGhpcy5lbnZpcm9ubWVudElkLFxyXG4gICAgICAgIGFwcE9iamVjdElkXHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyBUcmFjayB0aGlzIGdyb3VwIGZvciByZWNvbm5lY3Rpb25cclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuYWRkKGFwcE9iamVjdElkKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFtTaWduYWxSXSBGYWlsZWQgdG8gam9pbiBncm91cDogJHthcHBPYmplY3RJZH1gLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMZWF2ZSBTaWduYWxSIGdyb3VwXHJcbiAgICovXHJcbiAgYXN5bmMgbGVhdmVHcm91cChhcHBPYmplY3RJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuaHViQ29ubmVjdGlvbiB8fCB0aGlzLmh1YkNvbm5lY3Rpb24uc3RhdGUgIT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZCkge1xyXG4gICAgICAvLyBSZW1vdmUgZnJvbSB0cmFja2luZyBldmVuIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgdGhpcy5hY3RpdmVHcm91cHMuZGVsZXRlKGFwcE9iamVjdElkKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy50ZW5hbnRJZCB8fCAhdGhpcy5hcHBJZCB8fCAhdGhpcy5lbnZpcm9ubWVudElkIHx8ICFhcHBPYmplY3RJZCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgYXdhaXQgdGhpcy5odWJDb25uZWN0aW9uLmludm9rZShcclxuICAgICAgICBTSUdOQUxSX0hVQl9NRVRIT0RTLkxFQVZFX0dST1VQLFxyXG4gICAgICAgIHRoaXMudGVuYW50SWQsXHJcbiAgICAgICAgdGhpcy5hcHBJZCxcclxuICAgICAgICB0aGlzLmVudmlyb25tZW50SWQsXHJcbiAgICAgICAgYXBwT2JqZWN0SWRcclxuICAgICAgKTtcclxuXHJcbiAgICAgIC8vIFJlbW92ZSBmcm9tIHRyYWNraW5nXHJcbiAgICAgIHRoaXMuYWN0aXZlR3JvdXBzLmRlbGV0ZShhcHBPYmplY3RJZCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBbU2lnbmFsUl0gRmFpbGVkIHRvIGxlYXZlIGdyb3VwOiAke2FwcE9iamVjdElkfWAsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlam9pbiBhbGwgYWN0aXZlIGdyb3VwcyBhZnRlciByZWNvbm5lY3Rpb25cclxuICAgKiBUaGlzIGVuc3VyZXMgY29tcG9uZW50cyBjb250aW51ZSByZWNlaXZpbmcgbm90aWZpY2F0aW9ucyBhZnRlciBuZXR3b3JrIGludGVycnVwdGlvblxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVqb2luR3JvdXBzKCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgaWYgKHRoaXMuYWN0aXZlR3JvdXBzLnNpemUgPT09IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEdldCBsaXN0IG9mIGdyb3VwcyB0byByZWpvaW5cclxuICAgIGNvbnN0IGdyb3VwcyA9IEFycmF5LmZyb20odGhpcy5hY3RpdmVHcm91cHMpO1xyXG5cclxuICAgIC8vIENsZWFyIHRoZSBzZXQgKHdpbGwgYmUgcmUtYWRkZWQgZHVyaW5nIGpvaW5Hcm91cClcclxuICAgIHRoaXMuYWN0aXZlR3JvdXBzLmNsZWFyKCk7XHJcblxyXG4gICAgLy8gUmVqb2luIGVhY2ggZ3JvdXBcclxuICAgIGZvciAoY29uc3QgYXBwT2JqZWN0SWQgb2YgZ3JvdXBzKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuam9pbkdyb3VwKGFwcE9iamVjdElkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGNvbm5lY3RlZFxyXG4gICAqL1xyXG4gIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuaHViQ29ubmVjdGlvbj8uc3RhdGUgPT09IHNpZ25hbFIuSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc2Nvbm5lY3QgZnJvbSBTaWduYWxSIGh1YiAoY2xlYW51cClcclxuICAgKlxyXG4gICAqIFNldHMgZXhwbGljaXRseURpc2Nvbm5lY3RlZCBzbyBhbnkgcGVuZGluZyByZXRyeSB0aW1lcnMgZnJvbSBjb25uZWN0KCkvb25jbG9zZVxyXG4gICAqIGJlY29tZSBuby1vcHMsIHRoZW4gc3RvcHMgdGhlIGh1YiBhbmQgY2xlYXJzIHRyYWNrZWQgZ3JvdXBzLlxyXG4gICAqL1xyXG4gIGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICB0aGlzLmV4cGxpY2l0bHlEaXNjb25uZWN0ZWQgPSB0cnVlO1xyXG4gICAgdGhpcy5jb25uZWN0aW5nUHJvbWlzZSA9IG51bGw7XHJcblxyXG4gICAgaWYgKHRoaXMuaHViQ29ubmVjdGlvbikge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvbi5zdG9wKCk7XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignW1NpZ25hbFJdIEVycm9yIGR1cmluZyBkaXNjb25uZWN0OicsIGVycm9yKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmh1YkNvbm5lY3Rpb24gPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuYWN0aXZlR3JvdXBzLmNsZWFyKCk7XHJcbiAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZS5zZXQoQ09OTkVDVElPTl9TVEFURS5ESVNDT05ORUNURUQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGFjdGl2ZSBncm91cHMgKGZvciBkZWJ1Z2dpbmcpXHJcbiAgICovXHJcbiAgZ2V0QWN0aXZlR3JvdXBzKCk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuYWN0aXZlR3JvdXBzKTtcclxuICB9XHJcbn0iXX0=