@api.global/typedsocket 5.0.1 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@api.global/typedsocket',
6
- version: '5.0.1',
6
+ version: '5.1.0',
7
7
  description: 'A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx5QkFBeUI7SUFDL0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLCtHQUErRztDQUM3SCxDQUFBIn0=
@@ -18,6 +18,7 @@ export interface ITypedSocketRequestOptions {
18
18
  timeoutMs?: number;
19
19
  abortSignal?: AbortSignal;
20
20
  }
21
+ export type TTypedSocketServerRouterInput = plugins.typedrequest.TypedRouter | readonly plugins.typedrequest.TypedRouter[];
21
22
  /**
22
23
  * Wrapper for SmartServe's IWebSocketPeer to provide tag compatibility
23
24
  */
@@ -54,11 +55,19 @@ export declare class TypedSocket {
54
55
  */
55
56
  static useWindowLocationOriginUrl: () => string;
56
57
  /**
57
- * Creates a TypedSocket server from an existing SmartServe instance.
58
- * This is the only way to create a server-side TypedSocket.
58
+ * Creates a server-side TypedSocket and composes its private protocol
59
+ * handlers into one or more isolated application routers.
59
60
  *
60
- * @param smartServeArg - SmartServe instance with typedRouter configured in websocket options
61
- * @param typedRouterArg - TypedRouter for handling requests (must match SmartServe's typedRouter)
61
+ * Call attachSmartServe() after constructing the SmartServe transport.
62
+ */
63
+ static createServer(typedRouterOrRoutersArg: TTypedSocketServerRouterInput): TypedSocket;
64
+ /**
65
+ * Creates and attaches a TypedSocket server to an existing SmartServe
66
+ * instance. Prefer createServer() plus attachSmartServe() when transport
67
+ * construction needs the composed routers first.
68
+ *
69
+ * @param smartServeArg - SmartServe instance configured with the application router
70
+ * @param typedRouterArg - Application TypedRouter used by SmartServe
62
71
  *
63
72
  * @example
64
73
  * ```typescript
@@ -74,7 +83,7 @@ export declare class TypedSocket {
74
83
  * const typedSocket = TypedSocket.fromSmartServe(smartServe, typedRouter);
75
84
  * ```
76
85
  */
77
- static fromSmartServe(smartServeArg: plugins.SmartServe, typedRouterArg: plugins.typedrequest.TypedRouter): TypedSocket;
86
+ static fromSmartServe(smartServeArg: plugins.SmartServe, typedRouterArg: TTypedSocketServerRouterInput): TypedSocket;
78
87
  /**
79
88
  * Registers built-in TypedHandlers for tag management
80
89
  */
@@ -95,11 +104,17 @@ export declare class TypedSocket {
95
104
  private clientTags;
96
105
  private clientTagMutations;
97
106
  private smartServeRef;
107
+ private serverTypedRouters;
108
+ private detachProtocolRouters;
98
109
  private serverStopping;
99
110
  private unsubscribeSmartServeConnectionClose;
100
111
  private pendingServerRequests;
101
112
  private pendingServerRequestIdsByPeerId;
102
113
  private constructor();
114
+ /**
115
+ * Attaches the SmartServe transport after server router composition.
116
+ */
117
+ attachSmartServe(smartServeArg: plugins.SmartServe): this;
103
118
  /**
104
119
  * Connects the client to the server using native WebSocket
105
120
  */
@@ -15,6 +15,45 @@ function wrapSmartServePeer(peer) {
15
15
  },
16
16
  };
17
17
  }
18
+ function composeAbortSignals(configuredSignalArg, requestSignalArg) {
19
+ if (!configuredSignalArg || configuredSignalArg === requestSignalArg) {
20
+ return {
21
+ signal: requestSignalArg ?? configuredSignalArg,
22
+ cleanup: () => { },
23
+ };
24
+ }
25
+ if (!requestSignalArg) {
26
+ return {
27
+ signal: configuredSignalArg,
28
+ cleanup: () => { },
29
+ };
30
+ }
31
+ const abortController = new AbortController();
32
+ const configuredAbortListener = () => {
33
+ abortController.abort(configuredSignalArg.reason);
34
+ };
35
+ const requestAbortListener = () => {
36
+ abortController.abort(requestSignalArg.reason);
37
+ };
38
+ const cleanup = () => {
39
+ configuredSignalArg.removeEventListener('abort', configuredAbortListener);
40
+ requestSignalArg.removeEventListener('abort', requestAbortListener);
41
+ };
42
+ if (configuredSignalArg.aborted) {
43
+ configuredAbortListener();
44
+ }
45
+ else if (requestSignalArg.aborted) {
46
+ requestAbortListener();
47
+ }
48
+ else {
49
+ configuredSignalArg.addEventListener('abort', configuredAbortListener, { once: true });
50
+ requestSignalArg.addEventListener('abort', requestAbortListener, { once: true });
51
+ }
52
+ return {
53
+ signal: abortController.signal,
54
+ cleanup,
55
+ };
56
+ }
18
57
  export class TypedSocket {
19
58
  // ============================================================================
20
59
  // STATIC METHODS
@@ -75,11 +114,56 @@ export class TypedSocket {
75
114
  return plugins.smarturl.Smarturl.createFromUrl(globalThis.location.origin).toString();
76
115
  }; }
77
116
  /**
78
- * Creates a TypedSocket server from an existing SmartServe instance.
79
- * This is the only way to create a server-side TypedSocket.
117
+ * Creates a server-side TypedSocket and composes its private protocol
118
+ * handlers into one or more isolated application routers.
80
119
  *
81
- * @param smartServeArg - SmartServe instance with typedRouter configured in websocket options
82
- * @param typedRouterArg - TypedRouter for handling requests (must match SmartServe's typedRouter)
120
+ * Call attachSmartServe() after constructing the SmartServe transport.
121
+ */
122
+ static createServer(typedRouterOrRoutersArg) {
123
+ const typedRouters = Array.isArray(typedRouterOrRoutersArg)
124
+ ? [...typedRouterOrRoutersArg]
125
+ : [typedRouterOrRoutersArg];
126
+ if (typedRouters.length === 0) {
127
+ throw new Error('TypedSocket.createServer requires at least one TypedRouter.');
128
+ }
129
+ if (new Set(typedRouters).size !== typedRouters.length) {
130
+ throw new Error('TypedSocket.createServer received the same TypedRouter more than once.');
131
+ }
132
+ const protocolRouter = new plugins.typedrequest.TypedRouter();
133
+ TypedSocket.registerTagHandlers(protocolRouter);
134
+ const protocolMethods = new Set(protocolRouter.getMethodNames());
135
+ for (const typedRouter of typedRouters) {
136
+ const collision = typedRouter
137
+ .getMethodNames()
138
+ .find((methodArg) => protocolMethods.has(methodArg));
139
+ if (collision) {
140
+ throw new Error(`TypedSocket protocol handler collides with application method "${collision}".`);
141
+ }
142
+ }
143
+ const detachProtocolRouters = [];
144
+ try {
145
+ for (const typedRouter of typedRouters) {
146
+ detachProtocolRouters.push(typedRouter.addFallbackRouter(protocolRouter));
147
+ }
148
+ }
149
+ catch (error) {
150
+ for (const detachProtocolRouter of detachProtocolRouters.reverse()) {
151
+ detachProtocolRouter();
152
+ }
153
+ throw error;
154
+ }
155
+ const typedSocket = new TypedSocket('server', typedRouters[0]);
156
+ typedSocket.serverTypedRouters = typedRouters;
157
+ typedSocket.detachProtocolRouters = detachProtocolRouters;
158
+ return typedSocket;
159
+ }
160
+ /**
161
+ * Creates and attaches a TypedSocket server to an existing SmartServe
162
+ * instance. Prefer createServer() plus attachSmartServe() when transport
163
+ * construction needs the composed routers first.
164
+ *
165
+ * @param smartServeArg - SmartServe instance configured with the application router
166
+ * @param typedRouterArg - Application TypedRouter used by SmartServe
83
167
  *
84
168
  * @example
85
169
  * ```typescript
@@ -96,15 +180,9 @@ export class TypedSocket {
96
180
  * ```
97
181
  */
98
182
  static fromSmartServe(smartServeArg, typedRouterArg) {
99
- // Register built-in tag handlers
100
- TypedSocket.registerTagHandlers(typedRouterArg);
101
- const typedSocket = new TypedSocket('server', typedRouterArg);
102
- typedSocket.smartServeRef = smartServeArg;
103
- typedSocket.unsubscribeSmartServeConnectionClose =
104
- smartServeArg.subscribeWebSocketConnectionClose((peerArg) => {
105
- typedSocket.cancelPendingServerRequestsForPeer(peerArg.id, new Error(`TypedSocket target connection closed: ${peerArg.id}`));
106
- });
107
- return typedSocket;
183
+ return TypedSocket
184
+ .createServer(typedRouterArg)
185
+ .attachSmartServe(smartServeArg);
108
186
  }
109
187
  /**
110
188
  * Registers built-in TypedHandlers for tag management
@@ -155,6 +233,8 @@ export class TypedSocket {
155
233
  this.clientTagMutations = new Map();
156
234
  // Server-specific properties (SmartServe mode)
157
235
  this.smartServeRef = null;
236
+ this.serverTypedRouters = [];
237
+ this.detachProtocolRouters = [];
158
238
  this.serverStopping = false;
159
239
  this.unsubscribeSmartServeConnectionClose = null;
160
240
  this.pendingServerRequests = new Map();
@@ -162,6 +242,29 @@ export class TypedSocket {
162
242
  this.side = sideArg;
163
243
  this.typedrouter = typedrouterArg;
164
244
  }
245
+ /**
246
+ * Attaches the SmartServe transport after server router composition.
247
+ */
248
+ attachSmartServe(smartServeArg) {
249
+ if (this.side !== 'server') {
250
+ throw new Error('attachSmartServe is only available on servers.');
251
+ }
252
+ if (this.serverStopping) {
253
+ throw new Error('Cannot attach SmartServe after the TypedSocket server has stopped.');
254
+ }
255
+ if (this.smartServeRef) {
256
+ if (this.smartServeRef === smartServeArg) {
257
+ return this;
258
+ }
259
+ throw new Error('TypedSocket server is already attached to a SmartServe instance.');
260
+ }
261
+ const unsubscribe = smartServeArg.subscribeWebSocketConnectionClose((peerArg) => {
262
+ this.cancelPendingServerRequestsForPeer(peerArg.id, new Error(`TypedSocket target connection closed: ${peerArg.id}`));
263
+ });
264
+ this.smartServeRef = smartServeArg;
265
+ this.unsubscribeSmartServeConnectionClose = unsubscribe;
266
+ return this;
267
+ }
165
268
  // ============================================================================
166
269
  // CLIENT METHODS
167
270
  // ============================================================================
@@ -542,14 +645,33 @@ export class TypedSocket {
542
645
  if (optionsArg.abortSignal?.aborted) {
543
646
  onAbort();
544
647
  }
545
- let destroyInterest;
648
+ const destroyInterests = [];
546
649
  try {
547
- const interest = await this.typedrouter.fireEventInterestMap.addInterest(correlationId, typedRequestDataArg);
548
- destroyInterest = () => interest.destroy();
650
+ const interestPromises = [];
651
+ for (const typedRouter of this.serverTypedRouters) {
652
+ const interestRegistration = typedRouter.fireEventInterestMap
653
+ .addInterest(correlationId, typedRequestDataArg)
654
+ .then((interestArg) => {
655
+ if (cancellationRequested || this.serverStopping) {
656
+ interestArg.destroy();
657
+ }
658
+ return interestArg;
659
+ });
660
+ const interest = await Promise.race([
661
+ interestRegistration,
662
+ cancellation.promise,
663
+ ]);
664
+ if (cancellationRequested || this.serverStopping) {
665
+ interest.destroy();
666
+ await cancellation.promise;
667
+ }
668
+ destroyInterests.push(() => interest.destroy());
669
+ interestPromises.push(interest.interestFullfilled);
670
+ }
549
671
  // Establish the rejecting race before send so synchronous close/abort and
550
672
  // send failures all use the same cleanup path.
551
673
  const response = Promise.race([
552
- interest.interestFullfilled,
674
+ ...interestPromises,
553
675
  cancellation.promise,
554
676
  ]);
555
677
  const targetIsStillConnected = this.smartServeRef
@@ -575,7 +697,9 @@ export class TypedSocket {
575
697
  if (remainingRequestsForPeer?.size === 0) {
576
698
  this.pendingServerRequestIdsByPeerId.delete(peerId);
577
699
  }
578
- destroyInterest?.();
700
+ for (const destroyInterest of destroyInterests) {
701
+ destroyInterest();
702
+ }
579
703
  cleanup.resolve();
580
704
  }
581
705
  }
@@ -588,32 +712,45 @@ export class TypedSocket {
588
712
  * On servers, sends to the specified target connection.
589
713
  */
590
714
  createTypedRequest(methodName, targetConnection, optionsArg = {}) {
591
- const postMethod = async (requestDataArg) => {
715
+ const postMethod = async (requestDataArg, postOptionsArg = {}) => {
592
716
  const typedRequestData = requestDataArg;
593
- if (this.side === 'client') {
594
- return this.sendRequest(typedRequestData, optionsArg);
595
- }
596
- // Server-side: send to target connection
597
- if (!this.smartServeRef) {
598
- throw new Error('Server not initialized');
599
- }
600
- let target = targetConnection;
601
- if (!target) {
602
- const allConnections = this.smartServeRef.getWebSocketConnections();
603
- if (allConnections.length === 1) {
604
- const peer = allConnections[0];
605
- target = wrapSmartServePeer(peer);
717
+ const composedAbortSignal = composeAbortSignals(optionsArg.abortSignal, postOptionsArg.signal);
718
+ const requestOptions = {
719
+ ...optionsArg,
720
+ abortSignal: composedAbortSignal.signal,
721
+ };
722
+ try {
723
+ if (this.side === 'client') {
724
+ return await this.sendRequest(typedRequestData, requestOptions);
606
725
  }
607
- else if (allConnections.length === 0) {
608
- throw new Error('No WebSocket connections available');
726
+ // Server-side: send to target connection
727
+ if (!this.smartServeRef) {
728
+ throw new Error('Server not initialized');
609
729
  }
610
- else {
611
- throw new Error('Multiple connections available - specify targetConnection');
730
+ let target = targetConnection;
731
+ if (!target) {
732
+ const allConnections = this.smartServeRef.getWebSocketConnections();
733
+ if (allConnections.length === 1) {
734
+ const peer = allConnections[0];
735
+ target = wrapSmartServePeer(peer);
736
+ }
737
+ else if (allConnections.length === 0) {
738
+ throw new Error('No WebSocket connections available');
739
+ }
740
+ else {
741
+ throw new Error('Multiple connections available - specify targetConnection');
742
+ }
612
743
  }
744
+ return await this.sendServerRequest(typedRequestData, target, requestOptions);
745
+ }
746
+ finally {
747
+ composedAbortSignal.cleanup();
613
748
  }
614
- return await this.sendServerRequest(typedRequestData, target, optionsArg);
615
749
  };
616
- return new plugins.typedrequest.TypedRequest(new plugins.typedrequest.TypedTarget({ postMethod }), methodName);
750
+ return new plugins.typedrequest.TypedRequest(new plugins.typedrequest.TypedTarget({
751
+ postMethod,
752
+ supportsAbortSignal: true,
753
+ }), methodName);
617
754
  }
618
755
  /**
619
756
  * Gets the current connection status
@@ -657,6 +794,10 @@ export class TypedSocket {
657
794
  this.unsubscribeSmartServeConnectionClose?.();
658
795
  this.unsubscribeSmartServeConnectionClose = null;
659
796
  this.smartServeRef = null;
797
+ for (const detachProtocolRouter of this.detachProtocolRouters.reverse()) {
798
+ detachProtocolRouter();
799
+ }
800
+ this.detachProtocolRouters = [];
660
801
  }
661
802
  }
662
803
  // ============================================================================
@@ -786,4 +927,4 @@ export class TypedSocket {
786
927
  return allResults[0];
787
928
  }
788
929
  }
789
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWRzb2NrZXQuY2xhc3Nlcy50eXBlZHNvY2tldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3R5cGVkc29ja2V0LmNsYXNzZXMudHlwZWRzb2NrZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSwwQkFBMEIsQ0FBQztBQUtwRCxNQUFNLFVBQVUsR0FBRyxxQkFBcUIsQ0FBQztBQWtEekM7O0dBRUc7QUFDSCxTQUFTLGtCQUFrQixDQUFDLElBQTRCO0lBQ3RELE9BQU87UUFDTCxJQUFJO1FBQ0osS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFhO1lBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUMxQixPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1lBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxVQUFVLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUN2RCxPQUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNoQyxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLE9BQU8sV0FBVztJQUN0QiwrRUFBK0U7SUFDL0UsaUJBQWlCO0lBQ2pCLCtFQUErRTtJQUUvRTs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FpQkc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FDOUIsY0FBZ0QsRUFDaEQsWUFBb0IsRUFDcEIsVUFBcUMsRUFBRTtRQUV2QyxNQUFNLGNBQWMsR0FBNkQ7WUFDL0UsYUFBYSxFQUFFLElBQUk7WUFDbkIsVUFBVSxFQUFFLEdBQUc7WUFDZixnQkFBZ0IsRUFBRSxJQUFJO1lBQ3RCLFlBQVksRUFBRSxLQUFLO1NBQ3BCLENBQUM7UUFDRixNQUFNLElBQUksR0FBRyxFQUFFLEdBQUcsY0FBYyxFQUFFLEdBQUcs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
930
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWRzb2NrZXQuY2xhc3Nlcy50eXBlZHNvY2tldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3R5cGVkc29ja2V0LmNsYXNzZXMudHlwZWRzb2NrZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSwwQkFBMEIsQ0FBQztBQUtwRCxNQUFNLFVBQVUsR0FBRyxxQkFBcUIsQ0FBQztBQTJEekM7O0dBRUc7QUFDSCxTQUFTLGtCQUFrQixDQUFDLElBQTRCO0lBQ3RELE9BQU87UUFDTCxJQUFJO1FBQ0osS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFhO1lBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUMxQixPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1lBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxVQUFVLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUN2RCxPQUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNoQyxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLG1CQUFtQixDQUMxQixtQkFBaUMsRUFDakMsZ0JBQThCO0lBRTlCLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxtQkFBbUIsS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3JFLE9BQU87WUFDTCxNQUFNLEVBQUUsZ0JBQWdCLElBQUksbUJBQW1CO1lBQy9DLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDO1NBQ2xCLENBQUM7SUFDSixDQUFDO0lBQ0QsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDdEIsT0FBTztZQUNMLE1BQU0sRUFBRSxtQkFBbUI7WUFDM0IsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUM7U0FDbEIsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLGVBQWUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO0lBQzlDLE1BQU0sdUJBQXVCLEdBQUcsR0FBRyxFQUFFO1FBQ25DLGVBQWUsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDcEQsQ0FBQyxDQUFDO0lBQ0YsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLEVBQUU7UUFDaEMsZUFBZSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNqRCxDQUFDLENBQUM7SUFDRixNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUU7UUFDbkIsbUJBQW1CLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLHVCQUF1QixDQUFDLENBQUM7UUFDMUUsZ0JBQWdCLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDdEUsQ0FBQyxDQUFDO0lBRUYsSUFBSSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoQyx1QkFBdUIsRUFBRSxDQUFDO0lBQzVCLENBQUM7U0FBTSxJQUFJLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BDLG9CQUFvQixFQUFFLENBQUM7SUFDekIsQ0FBQztTQUFNLENBQUM7UUFDTixtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN2RixnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBRUQsT0FBTztRQUNMLE1BQU0sRUFBRSxlQUFlLENBQUMsTUFBTTtRQUM5QixPQUFPO0tBQ1IsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLE9BQU8sV0FBVztJQUN0QiwrRUFBK0U7SUFDL0UsaUJBQWlCO0lBQ2pCLCtFQUErRTtJQUUvRTs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FpQkc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FDOUIsY0FBZ0QsRUFDaEQsWUFBb0IsRUFDcEIsVUFBcUMsRUFBRTtRQUV2QyxNQUFNLGNBQWMsR0FBNkQ7WUFDL0UsYUFBYSxFQUFFLElBQUk7WUFDbkIsVUFBVSxFQUFFLEdBQUc7WUFDZixnQkFBZ0IsRUFBRSxJQUFJO1lBQ3RCLFlBQVksRUFBRSxLQUFLO1NBQ3BCLENBQUM7UUFDRixNQUFNLElBQUksR0FBRyxFQUFFLEdBQUcsY0FBYyxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUM7UUFFL0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxXQUFXLENBQUMsUUFBUSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzlELFdBQVcsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBQ2pDLFdBQVcsQ0FBQyxTQUFTLEdBQUcsWUFBWSxDQUFDO1FBQ3JDLFdBQVcsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBRW5ELElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUM5QixNQUFNLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixXQUFXLENBQUMsbUJBQW1CLEdBQUcsR0FBRyxFQUFFO2dCQUNyQyxLQUFLLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMxQixDQUFDLENBQUM7WUFDRixJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM5RixDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN6QixNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7UUFFRCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0lBRUQ7OztPQUdHO2FBQ1csK0JBQTBCLEdBQUcsR0FBVyxFQUFFO1FBQ3RELE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDeEYsQ0FBQyxBQUZ1QyxDQUV0QztJQUVGOzs7OztPQUtHO0lBQ0ksTUFBTSxDQUFDLFlBQVksQ0FDeEIsdUJBQXNEO1FBRXRELE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUM7WUFDekQsQ0FBQyxDQUFDLENBQUMsR0FBRyx1QkFBdUIsQ0FBQztZQUM5QixDQUFDLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQzlCLElBQUksWUFBWSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7UUFDakYsQ0FBQztRQUNELElBQUksSUFBSSxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxLQUFLLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLHdFQUF3RSxDQUFDLENBQUM7UUFDNUYsQ0FBQztRQUVELE1BQU0sY0FBYyxHQUFHLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM5RCxXQUFXLENBQUMsbUJBQW1CLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDaEQsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7UUFDakUsS0FBSyxNQUFNLFdBQVcsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUN2QyxNQUFNLFNBQVMsR0FBRyxXQUFXO2lCQUMxQixjQUFjLEVBQUU7aUJBQ2hCLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ2QsTUFBTSxJQUFJLEtBQUssQ0FDYixrRUFBa0UsU0FBUyxJQUFJLENBQ2hGLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0scUJBQXFCLEdBQXNCLEVBQUUsQ0FBQztRQUNwRCxJQUFJLENBQUM7WUFDSCxLQUFLLE1BQU0sV0FBVyxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUN2QyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7WUFDNUUsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsS0FBSyxNQUFNLG9CQUFvQixJQUFJLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7Z0JBQ25FLG9CQUFvQixFQUFFLENBQUM7WUFDekIsQ0FBQztZQUNELE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRCxXQUFXLENBQUMsa0JBQWtCLEdBQUcsWUFBWSxDQUFDO1FBQzlDLFdBQVcsQ0FBQyxxQkFBcUIsR0FBRyxxQkFBcUIsQ0FBQztRQUMxRCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXFCRztJQUNJLE1BQU0sQ0FBQyxjQUFjLENBQzFCLGFBQWlDLEVBQ2pDLGNBQTZDO1FBRTdDLE9BQU8sV0FBVzthQUNmLFlBQVksQ0FBQyxjQUFjLENBQUM7YUFDNUIsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssTUFBTSxDQUFDLG1CQUFtQixDQUFDLFdBQTZDO1FBQzlFLGtCQUFrQjtRQUNsQixXQUFXLENBQUMsZUFBZSxDQUN6QixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLHNCQUFzQixFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUU7WUFDakYsTUFBTSxJQUFJLEdBQUcsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUE4QixDQUFDO1lBQzdELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDVixPQUFPLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7Z0JBQ3pELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDNUIsQ0FBQztZQUVELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRXpELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLHFCQUFxQjtRQUNyQixXQUFXLENBQUMsZUFBZSxDQUN6QixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLHlCQUF5QixFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUU7WUFDcEYsTUFBTSxJQUFJLEdBQUcsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUE4QixDQUFDO1lBQzdELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDVixPQUFPLENBQUMsSUFBSSxDQUFDLDZDQUE2QyxDQUFDLENBQUM7Z0JBQzVELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDNUIsQ0FBQztZQUVELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUU5QyxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBd0NELCtFQUErRTtJQUMvRSxjQUFjO0lBQ2QsK0VBQStFO0lBRS9FLFlBQ0UsT0FBeUIsRUFDekIsY0FBZ0Q7UUFyQ2xELCtCQUErQjtRQUN4QixrQkFBYSxHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFxQixDQUFDO1FBQ3JFLHFCQUFnQixHQUFzQixLQUFLLENBQUM7UUFFcEQsNkJBQTZCO1FBQ3JCLGNBQVMsR0FBcUIsSUFBSSxDQUFDO1FBQ25DLGtCQUFhLEdBQXVILElBQUksQ0FBQztRQUN6SSxjQUFTLEdBQVcsRUFBRSxDQUFDO1FBQ3ZCLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFDZixtQkFBYyxHQUFHLElBQUksQ0FBQztRQUN0QixZQUFPLEdBQUcsS0FBSyxDQUFDO1FBRWhCLGtCQUFhLEdBQUcsSUFBSSxHQUFHLEVBQWMsQ0FBQztRQUN0QyxvQkFBZSxHQUFHLElBQUksR0FBRyxFQUc3QixDQUFDO1FBQ0wsNEVBQTRFO1FBQzVFLDBFQUEwRTtRQUNsRSxlQUFVLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7UUFDeEMsdUJBQWtCLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFFdkQsK0NBQStDO1FBQ3ZDLGtCQUFhLEdBQThCLElBQUksQ0FBQztRQUNoRCx1QkFBa0IsR0FBdUMsRUFBRSxDQUFDO1FBQzVELDBCQUFxQixHQUFzQixFQUFFLENBQUM7UUFDOUMsbUJBQWMsR0FBRyxLQUFLLENBQUM7UUFDdkIseUNBQW9DLEdBQXdCLElBQUksQ0FBQztRQUNqRSwwQkFBcUIsR0FBRyxJQUFJLEdBQUcsRUFBaUMsQ0FBQztRQUNqRSxvQ0FBK0IsR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztRQVV2RSxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztRQUNwQixJQUFJLENBQUMsV0FBVyxHQUFHLGNBQWMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxnQkFBZ0IsQ0FBQyxhQUFpQztRQUN2RCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7UUFDeEYsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxhQUFhLEVBQUUsQ0FBQztnQkFDekMsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO1FBQ3RGLENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxhQUFhLENBQUMsaUNBQWlDLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM5RSxJQUFJLENBQUMsa0NBQWtDLENBQ3JDLE9BQU8sQ0FBQyxFQUFFLEVBQ1YsSUFBSSxLQUFLLENBQUMseUNBQXlDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUNqRSxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUNuQyxJQUFJLENBQUMsb0NBQW9DLEdBQUcsV0FBVyxDQUFDO1FBQ3hELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELCtFQUErRTtJQUMvRSxpQkFBaUI7SUFDakIsK0VBQStFO0lBRS9FOztPQUVHO0lBQ0ssS0FBSyxDQUFDLE9BQU87UUFDbkIsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQzdELE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDaEMsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFRLENBQUM7UUFDaEQsSUFBSSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFDOUIsSUFBSSxpQkFBNEQsQ0FBQztRQUNqRSxJQUFJLGVBQXlDLENBQUM7UUFFOUMsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLFFBQWdCLEVBQUUsRUFBRTtZQUM1QyxJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3RCLE9BQU87WUFDVCxDQUFDO1lBQ0QsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1lBQ3pCLElBQUksaUJBQWlCLEVBQUUsQ0FBQztnQkFDdEIsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDbEMsQ0FBQztZQUNELElBQUksZUFBZSxFQUFFLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUMzQyxJQUFJLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7WUFDakYsQ0FBQztZQUNELElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN4QixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLENBQUM7UUFDSCxDQUFDLENBQUM7UUFFRixJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWhDLG9DQUFvQztRQUNwQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsUUFBUSxDQUFDLDZCQUE2QixLQUFLLEtBQUssQ0FBQyxDQUFDO1FBRXZELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsZUFBZSxHQUFHLEdBQUcsRUFBRTtZQUNyQixJQUFJLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQ3hCLGdCQUFnQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRTVGLGlCQUFpQixHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbEMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxZQUFZLENBQUMsc0NBQXNDLEtBQUssRUFBRSxDQUFDLENBQUM7Z0JBQ2pFLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7Z0JBQ3hCLGdCQUFnQixDQUFDLElBQUksS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQztZQUNwRCxDQUFDO1FBQ0gsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRVYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsS0FBSyxJQUFJLEVBQUU7WUFDakMsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUN2QyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLGVBQWUsSUFBSSxlQUFlLEVBQUUsVUFBVSxLQUFLLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDekYsTUFBTSxJQUFJLEtBQUssQ0FBQyw0REFBNEQsQ0FBQyxDQUFDO2dCQUNoRixDQUFDO2dCQUNELElBQUksQ0FBQyxRQUFRLENBQUMseURBQXlELENBQUMsQ0FBQztnQkFDekUsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsSUFBSSxJQUFJLENBQUM7Z0JBQ25FLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQy9CLGdCQUFnQixFQUFFLENBQUM7WUFDckIsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLFlBQVksS0FBSztvQkFDN0MsQ0FBQyxDQUFDLEtBQUs7b0JBQ1AsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUM3QixJQUFJLENBQUMsWUFBWSxDQUFDLHVEQUF1RCxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUNyRyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUNuQyxlQUFlLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVGLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUN6QyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQztRQUVGLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLEdBQUcsRUFBRTtZQUM1QixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDMUIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hFLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsT0FBTztvQkFDdkUsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtvQkFDekIsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUMsQ0FBQztZQUNuRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEdBQUcsR0FBRyxFQUFFO1lBQzVCLDBFQUEwRTtZQUMxRSx3RUFBd0U7WUFDeEUsSUFBSSxDQUFDLFlBQVksQ0FBQyxrQ0FBa0MsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUM7UUFFRixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDckIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3RCLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDO2dCQUMzQixNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2dCQUMvQixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxXQUFXLEVBQUUsQ0FBQztvQkFDMUMsTUFBTSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDakcsQ0FBQztZQUNILENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLEdBQUcsQ0FBQztZQUNaLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssY0FBYyxDQUFDLEdBQVc7UUFDaEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUIsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ2pFLE9BQU8sR0FBRyxVQUFVLEtBQUssTUFBTSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDM0QsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUEwQjtRQUNwRCxJQUFJLENBQUM7WUFDSCxNQUFNLFdBQVcsR0FBRyxPQUFPLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckYsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFpRCxDQUFDO1lBRXJHLG1EQUFtRDtZQUNuRCxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDaEYsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUUsQ0FBQztnQkFDbEUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDcEQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDekIsT0FBTztZQUNULENBQUM7WUFFRCx1REFBdUQ7WUFDdkQsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JFLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxLQUFLLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDOUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUM3RCxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQy9ELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxnQkFBZ0I7UUFDdEIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssY0FBYyxFQUFFLENBQUM7WUFDN0MsT0FBTyxDQUFDLGtCQUFrQjtRQUM1QixDQUFDO1FBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUVsQyw0RkFBNEY7UUFDNUYsSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUMsQ0FBQztRQUV4RSxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsaUJBQWlCO1FBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQUUsT0FBTztRQUNwQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYyxDQUFDO1FBRTFDLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRWxCLGtDQUFrQztRQUNsQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbkUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsY0FBYyxHQUFHLE1BQU0sRUFBRSxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFakYsSUFBSSxDQUFDLFFBQVEsQ0FBQywrQkFBK0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsZUFBZSxJQUFJLENBQUMsVUFBVSxJQUFJLGFBQWEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBRTdILE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXhDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQUUsT0FBTztRQUVwQyxpQ0FBaUM7UUFDakMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVwRixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN2QixDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsNENBQTRDLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEgsQ0FBQztpQkFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxDQUFDO2dCQUN0RSxPQUFPLENBQUMsS0FBSyxDQUNYLDRCQUE0QixJQUFJLENBQUMsU0FBUyxVQUFVLElBQUksQ0FBQyxVQUFVLFlBQVksRUFDL0UsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUN6QyxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssUUFBUSxDQUFDLFVBQWtCO1FBQ2pDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVEOzs7T0FHRztJQUNLLFlBQVksQ0FBQyxVQUFrQjtRQUNyQyxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDNUIsQ0FBQzthQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDdEUsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVPLGVBQWU7UUFDckIsT0FBTyxPQUFPLENBQ1osSUFBSSxDQUFDLGFBQWEsRUFBRSxhQUFhO1lBQ2pDLENBQUMsSUFBSSxDQUFDLE9BQU87WUFDYixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLE9BQU87WUFDeEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FDaEQsQ0FBQztJQUNKLENBQUM7SUFFTyxLQUFLLENBQUMscUJBQXFCLENBQUMsVUFBa0I7UUFDcEQsTUFBTSxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ2xDLElBQUksT0FBa0QsQ0FBQztZQUN2RCxJQUFJLFFBQVEsR0FBRyxLQUFLLENBQUM7WUFDckIsTUFBTSxNQUFNLEdBQUcsR0FBRyxFQUFFO2dCQUNsQixJQUFJLFFBQVE7b0JBQUUsT0FBTztnQkFDckIsUUFBUSxHQUFHLElBQUksQ0FBQztnQkFDaEIsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3hCLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdEUsT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDLENBQUM7WUFDRixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxDQUFDO2dCQUM3QyxNQUFNLEVBQUUsQ0FBQztnQkFDVCxPQUFPO1lBQ1QsQ0FBQztZQUNELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNqQixNQUFNLEVBQUUsQ0FBQztnQkFDVCxPQUFPO1lBQ1QsQ0FBQztZQUNELE9BQU8sR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3pDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNyRixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIsT0FBTyxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFTywyQkFBMkIsQ0FBQyxRQUFlO1FBQ2pELEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1lBQ3BELE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUNELElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVEOztPQUVHO0lBQ0ssWUFBWSxDQUFDLE1BQXlCO1FBQzVDLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxNQUFNLENBQUM7WUFDL0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyxXQUFXLENBQ3ZCLE9BQVUsRUFDVixhQUF5QyxFQUFFO1FBRTNDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNwRSxNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUVELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckUsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsT0FBTyxDQUFDLFdBQVcsS0FBSztZQUN0QixFQUFFLEVBQUUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsd0JBQXdCLEVBQUU7WUFDekQsS0FBSyxFQUFFLFNBQVM7U0FDakIsQ0FBQztRQUNGLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBRTdDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckMsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO1lBQ3BCLE1BQU0sT0FBTyxHQUFHLEdBQUcsRUFBRTtnQkFDbkIsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUN0QixVQUFVLENBQUMsV0FBVyxFQUFFLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDOUQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDN0MsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxNQUFNLEdBQUcsQ0FBQyxRQUFnQixFQUFFLFdBQWUsRUFBRSxFQUFFO2dCQUNuRCxJQUFJLE9BQU8sRUFBRSxDQUFDO29CQUNaLE9BQU87Z0JBQ1QsQ0FBQztnQkFDRCxPQUFPLEdBQUcsSUFBSSxDQUFDO2dCQUNmLE9BQU8sRUFBRSxDQUFDO2dCQUNWLElBQUksUUFBUSxFQUFFLENBQUM7b0JBQ2IsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNuQixDQUFDO3FCQUFNLENBQUM7b0JBQ04sT0FBTyxDQUFDLFdBQVksQ0FBQyxDQUFDO2dCQUN4QixDQUFDO1lBQ0gsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxPQUFPLEdBQUcsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUMsQ0FBQztZQUN2RSxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUM5QixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQyxDQUFDO1lBQ3JELENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVkLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRTtnQkFDdEMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUU7b0JBQ3BCLE1BQU0sQ0FBQyxTQUFTLEVBQUUsUUFBYSxDQUFDLENBQUM7Z0JBQ25DLENBQUM7Z0JBQ0QsTUFBTSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7b0JBQ2hCLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDaEIsQ0FBQzthQUNGLENBQUMsQ0FBQztZQUNILFVBQVUsQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzNFLElBQUksVUFBVSxDQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsQ0FBQztnQkFDcEMsT0FBTyxFQUFFLENBQUM7Z0JBQ1YsT0FBTztZQUNULENBQUM7WUFFRCxJQUFJLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLFNBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUM3RCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixNQUFNLENBQUMsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BFLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyx1QkFBdUIsQ0FBQyxZQUFnQztRQUM5RCxNQUFNLFNBQVMsR0FBRyxZQUFZLElBQUksS0FBSyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNqRCxNQUFNLElBQUksS0FBSyxDQUFDLGtFQUFrRSxDQUFDLENBQUM7UUFDdEYsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFTyxrQ0FBa0MsQ0FBQyxTQUFpQixFQUFFLFFBQWU7UUFDM0UsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLCtCQUErQixDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDcEIsT0FBTztRQUNULENBQUM7UUFDRCxLQUFLLE1BQU0sYUFBYSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztZQUN2RCxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNsRSxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxpQkFBaUIsQ0FDN0IsbUJBQXNCLEVBQ3RCLFNBQXVDLEVBQ3ZDLFVBQXNDO1FBRXRDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckUsSUFBSSxJQUFJLENBQUMsY0FBYyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQy9DLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBQ0QsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsbUJBQW1CLENBQUMsV0FBVyxLQUFLO1lBQ2xDLEVBQUUsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRTtZQUN6RCxLQUFLLEVBQUUsU0FBUztTQUNqQixDQUFDO1FBQ0YsTUFBTSxhQUFhLEdBQUcsbUJBQW1CLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztRQUN6RCxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNqQyxJQUFJLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztZQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ3RGLENBQUM7UUFDRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBUyxDQUFDO1FBQ3pELDRFQUE0RTtRQUM1RSx5RUFBeUU7UUFDekUsK0NBQStDO1FBQy9DLEtBQUssWUFBWSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQVEsQ0FBQztRQUNuRCxJQUFJLHFCQUFxQixHQUFHLEtBQUssQ0FBQztRQUNsQyxNQUFNLE1BQU0sR0FBRyxDQUFDLFFBQWUsRUFBRSxFQUFFO1lBQ2pDLElBQUkscUJBQXFCLEVBQUUsQ0FBQztnQkFDMUIsT0FBTztZQUNULENBQUM7WUFDRCxxQkFBcUIsR0FBRyxJQUFJLENBQUM7WUFDN0IsWUFBWSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoQyxDQUFDLENBQUM7UUFDRixNQUFNLGNBQWMsR0FBMEI7WUFDNUMsTUFBTTtZQUNOLE1BQU07WUFDTixlQUFlLEVBQUUsT0FBTyxDQUFDLE9BQU87U0FDakMsQ0FBQztRQUNGLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzlELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUM5RixlQUFlLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ25DLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBRWxFLE1BQU0sT0FBTyxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLENBQUM7UUFDdkUsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUN4QixHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsdUNBQXVDLFNBQVMsSUFBSSxDQUFDLENBQUMsRUFDN0UsU0FBUyxDQUNWLENBQUM7UUFDRixVQUFVLENBQUMsV0FBVyxFQUFFLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMzRSxJQUFJLFVBQVUsQ0FBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDcEMsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBc0IsRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQztZQUNILE1BQU0sZ0JBQWdCLEdBQXNCLEVBQUUsQ0FBQztZQUMvQyxLQUFLLE1BQU0sV0FBVyxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUNsRCxNQUFNLG9CQUFvQixHQUFHLFdBQVcsQ0FBQyxvQkFBb0I7cUJBQzFELFdBQVcsQ0FBQyxhQUFhLEVBQUUsbUJBQW1CLENBQUM7cUJBQy9DLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFO29CQUNwQixJQUFJLHFCQUFxQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzt3QkFDakQsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUN4QixDQUFDO29CQUNELE9BQU8sV0FBVyxDQUFDO2dCQUNyQixDQUFDLENBQUMsQ0FBQztnQkFDTCxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUM7b0JBQ2xDLG9CQUFvQjtvQkFDcEIsWUFBWSxDQUFDLE9BQU87aUJBQ3JCLENBQUMsQ0FBQztnQkFDSCxJQUFJLHFCQUFxQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDakQsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNuQixNQUFNLFlBQVksQ0FBQyxPQUFPLENBQUM7Z0JBQzdCLENBQUM7Z0JBQ0QsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGtCQUFnQyxDQUFDLENBQUM7WUFDbkUsQ0FBQztZQUNELDBFQUEwRTtZQUMxRSwrQ0FBK0M7WUFDL0MsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztnQkFDNUIsR0FBRyxnQkFBZ0I7Z0JBQ25CLFlBQVksQ0FBQyxPQUFPO2FBQ3JCLENBQUMsQ0FBQztZQUNILE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLGFBQWE7Z0JBQy9DLEVBQUUsdUJBQXVCLEVBQUU7aUJBQzFCLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUM7WUFDckQsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQzVCLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3ZFLENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDeEIsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUMsQ0FBQztZQUNsRCxDQUFDO1lBQ0QsSUFBSSxDQUFDLHFCQUFxQixJQUFJLHNCQUFzQixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUM3RSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUM7WUFDeEUsQ0FBQztZQUNELE9BQU8sTUFBTSxRQUFRLENBQUM7UUFDeEIsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLFVBQVUsQ0FBQyxXQUFXLEVBQUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzlELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDakQsTUFBTSx3QkFBd0IsR0FBRyxJQUFJLENBQUMsK0JBQStCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2xGLHdCQUF3QixFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoRCxJQUFJLHdCQUF3QixFQUFFLElBQUksS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDekMsSUFBSSxDQUFDLCtCQUErQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0RCxDQUFDO1lBQ0QsS0FBSyxNQUFNLGVBQWUsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO2dCQUMvQyxlQUFlLEVBQUUsQ0FBQztZQUNwQixDQUFDO1lBQ0QsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BCLENBQUM7SUFDSCxDQUFDO0lBRUQsK0VBQStFO0lBQy9FLHNCQUFzQjtJQUN0QiwrRUFBK0U7SUFFL0U7Ozs7T0FJRztJQUNJLGtCQUFrQixDQUN2QixVQUF1QixFQUN2QixnQkFBK0MsRUFDL0MsYUFBeUMsRUFBRTtRQUUzQyxNQUFNLFVBQVUsR0FBRyxLQUFLLEVBQ3RCLGNBQTRELEVBQzVELGlCQUErRCxFQUFFLEVBQ1YsRUFBRTtZQUN6RCxNQUFNLGdCQUFnQixHQUFHLGNBQW1CLENBQUM7WUFDN0MsTUFBTSxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FDN0MsVUFBVSxDQUFDLFdBQVcsRUFDdEIsY0FBYyxDQUFDLE1BQU0sQ0FDdEIsQ0FBQztZQUNGLE1BQU0sY0FBYyxHQUErQjtnQkFDakQsR0FBRyxVQUFVO2dCQUNiLFdBQVcsRUFBRSxtQkFBbUIsQ0FBQyxNQUFNO2FBQ3hDLENBQUM7WUFFRixJQUFJLENBQUM7Z0JBQ0gsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO29CQUMzQixPQUFPLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxjQUFjLENBQUMsQ0FBQztnQkFDbEUsQ0FBQztnQkFFRCx5Q0FBeUM7Z0JBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQ3hCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQztnQkFDNUMsQ0FBQztnQkFFRCxJQUFJLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUNaLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztvQkFDcEUsSUFBSSxjQUFjLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO3dCQUNoQyxNQUFNLElBQUksR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQy9CLE1BQU0sR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDcEMsQ0FBQzt5QkFBTSxJQUFJLGNBQWMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7d0JBQ3ZDLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztvQkFDeEQsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQztvQkFDL0UsQ0FBQztnQkFDSCxDQUFDO2dCQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7b0JBQVMsQ0FBQztnQkFDVCxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNoQyxDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsT0FBTyxJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUMxQyxJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDO1lBQ25DLFVBQVU7WUFDVixtQkFBbUIsRUFBRSxJQUFJO1NBQzFCLENBQUMsRUFDRixVQUFVLENBQ1gsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNJLFNBQVM7UUFDZCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztJQUMvQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsSUFBSTtRQUNmLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztZQUNwQixLQUFLLE1BQU0sWUFBWSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7Z0JBQzFELFlBQVksRUFBRSxDQUFDO1lBQ2pCLENBQUM7WUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7Z0JBQ3pDLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7b0JBQy9ELElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztnQkFDeEYsQ0FBQztZQUNILENBQUM7WUFDRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFDO1lBQ3JDLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNuQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUN4QixDQUFDO1lBQ0QsS0FBSyxNQUFNLGNBQWMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7Z0JBQzNELGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDO1lBQzFELENBQUM7WUFDRCxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQy9CLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDM0IsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUN4RSxLQUFLLE1BQU0sY0FBYyxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUM3QyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUMsQ0FBQztZQUNqRSxDQUFDO1lBQ0QsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1lBQzNGLElBQUksQ0FBQyxvQ0FBb0MsRUFBRSxFQUFFLENBQUM7WUFDOUMsSUFBSSxDQUFDLG9DQUFvQyxHQUFHLElBQUksQ0FBQztZQUNqRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztZQUMxQixLQUFLLE1BQU0sb0JBQW9CLElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7Z0JBQ3hFLG9CQUFvQixFQUFFLENBQUM7WUFDekIsQ0FBQztZQUNELElBQUksQ0FBQyxxQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUM7SUFFRCwrRUFBK0U7SUFDL0Usc0JBQXNCO0lBQ3RCLCtFQUErRTtJQUUvRTs7OztPQUlHO0lBQ0ksS0FBSyxDQUFDLE1BQU0sQ0FDakIsSUFBZSxFQUNmLE9BQXFCO1FBRXJCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDekQsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQW9CLHNCQUFzQixDQUFDLENBQUM7WUFDbkYsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFFdkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQ2pELENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ25ELElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNyQyxDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUNuRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLEtBQUssQ0FBQyxpQkFBaUI7UUFDN0IsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUM5QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQW9CLHNCQUFzQixDQUFDLENBQUM7WUFDbkYsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDdkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsSUFBSSxrQkFBa0IsQ0FBQyxDQUFDO1lBQy9FLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNJLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBWTtRQUNqQyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzVELENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUF1Qix5QkFBeUIsQ0FBQyxDQUFDO1lBQ3pGLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFFOUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1lBQ3BELENBQUM7UUFDSCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ25ELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsK0VBQStFO0lBQy9FLHNCQUFzQjtJQUN0QiwrRUFBK0U7SUFFL0U7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLHdCQUF3QixDQUNuQyxnQkFBbUY7UUFFbkYsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLHVEQUF1RCxDQUFDLENBQUM7UUFDM0UsQ0FBQztRQUVELE1BQU0sbUJBQW1CLEdBQW1DLEVBQUUsQ0FBQztRQUMvRCxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsdUJBQXVCLEVBQUUsRUFBRSxDQUFDO1lBQ2hFLE1BQU0sT0FBTyxHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pDLElBQUksTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNwQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDcEMsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLG1CQUFtQixDQUFDO0lBQzdCLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMsb0JBQW9CLENBQy9CLGdCQUFtRjtRQUVuRixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMsNkJBQTZCLENBQ3hDLE1BQW9CLEVBQ3BCLFVBQTRCO1FBRTVCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDbEQsTUFBTSxJQUFJLEtBQUssQ0FBQyw0REFBNEQsQ0FBQyxDQUFDO1FBQ2hGLENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLDRCQUE0QixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sT0FBTyxHQUFtQyxFQUFFLENBQUM7UUFFbkQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN6QixNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV6QywrQ0FBK0M7WUFDL0MsSUFBSSxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sR0FBRyxHQUFHLE1BQU0sT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDN0MsSUFBSSxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLEtBQUssT0FBTyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztvQkFDMUYsU0FBUztnQkFDWCxDQUFDO1lBQ0gsQ0FBQztZQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEIsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMseUJBQXlCLENBQ3BDLE1BQW9CLEVBQ3BCLFVBQTRCO1FBRTVCLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLDZCQUE2QixDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNoRixPQUFPLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QixDQUFDIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api.global/typedsocket",
3
- "version": "5.0.1",
3
+ "version": "5.1.0",
4
4
  "private": false,
5
5
  "description": "A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.",
6
6
  "main": "dist_ts/index.js",
@@ -11,15 +11,15 @@
11
11
  "devDependencies": {
12
12
  "@git.zone/tsbuild": "^4.4.2",
13
13
  "@git.zone/tsbundle": "^2.11.3",
14
- "@git.zone/tsrun": "^2.0.5",
15
- "@git.zone/tstest": "^3.6.6",
14
+ "@git.zone/tsrun": "^2.0.6",
15
+ "@git.zone/tstest": "^3.6.7",
16
16
  "@push.rocks/smartenv": "^6.1.0",
17
- "@push.rocks/smartserve": "^2.3.0",
17
+ "@push.rocks/smartserve": "^2.6.0",
18
18
  "@types/node": "26.1.1"
19
19
  },
20
20
  "dependencies": {
21
- "@api.global/typedrequest": "^3.3.2",
22
- "@api.global/typedrequest-interfaces": "^3.0.19",
21
+ "@api.global/typedrequest": "^3.7.0",
22
+ "@api.global/typedrequest-interfaces": "^4.0.0",
23
23
  "@push.rocks/smartdelay": "^3.1.0",
24
24
  "@push.rocks/smartjson": "^6.0.1",
25
25
  "@push.rocks/smartpromise": "^4.2.4",
package/readme.md CHANGED
@@ -58,7 +58,8 @@ interface IGreetingRequest extends typedrequestInterfaces.implementsTR<
58
58
 
59
59
  ### Server Setup
60
60
 
61
- TypedSocket binds to a SmartServe WebSocket server. Create the SmartServe instance with a typed router, then expose it through `TypedSocket.fromSmartServe()`:
61
+ TypedSocket composes its private protocol handlers into the application router
62
+ before that router is given to SmartServe:
62
63
 
63
64
  ```typescript
64
65
  import { TypedSocket } from '@api.global/typedsocket';
@@ -76,20 +77,21 @@ typedRouter.addTypedHandler<IGreetingRequest>(
76
77
  })
77
78
  );
78
79
 
80
+ const server = TypedSocket.createServer(typedRouter);
79
81
  const smartServe = new SmartServe({
80
82
  port: 3000,
81
83
  websocket: {
82
84
  typedRouter,
83
85
  },
84
86
  });
87
+ server.attachSmartServe(smartServe);
85
88
  await smartServe.start();
86
-
87
- const server = TypedSocket.fromSmartServe(smartServe, typedRouter);
88
89
  ```
89
90
 
90
91
  #### Integration with SmartServe
91
92
 
92
- For SmartServe-based applications, use `fromSmartServe()` for native integration:
93
+ For SmartServe-based applications, compose the protocol router synchronously,
94
+ attach the transport, and then start listening:
93
95
 
94
96
  ```typescript
95
97
  import { TypedSocket } from '@api.global/typedsocket';
@@ -105,7 +107,9 @@ typedRouter.addTypedHandler<IGreetingRequest>(
105
107
  })
106
108
  );
107
109
 
108
- // Create SmartServe with typedRouter in websocket options
110
+ const typedSocket = TypedSocket.createServer(typedRouter);
111
+
112
+ // Create SmartServe with the composed application router
109
113
  const smartServe = new SmartServe({
110
114
  port: 3000,
111
115
  websocket: {
@@ -117,21 +121,51 @@ const smartServe = new SmartServe({
117
121
  }
118
122
  });
119
123
 
124
+ typedSocket.attachSmartServe(smartServe);
120
125
  await smartServe.start();
121
126
 
122
- // Create TypedSocket bound to SmartServe
123
- const typedSocket = TypedSocket.fromSmartServe(smartServe, typedRouter);
124
-
125
127
  // Push notifications to tagged clients
126
128
  const clients = await typedSocket.findAllTargetConnectionsByTag('client');
127
129
  for (const client of clients) {
128
- const request = typedSocket.createTypedRequest<INotifyRequest>('notify', client);
129
- await request.fire({ message: 'Hello from server!' });
130
+ const request = typedSocket.createTypedRequest<IGreetingRequest>('greet', client);
131
+ await request.fire({ name: 'server' });
130
132
  }
131
133
  ```
132
134
 
133
135
  > **Note:** When using SmartServe, the WebSocket transport is managed by SmartServe. TypedSocket acts as a convenience layer for finding connections and sending server-initiated requests.
134
136
 
137
+ Multiple isolated application routers can share one transport without becoming
138
+ reachable from each other:
139
+
140
+ ```typescript
141
+ const typedSocket = TypedSocket.createServer([publicRouter, adminRouter]);
142
+ const smartServe = new SmartServe({
143
+ port: 3000,
144
+ authorityValidation: 'strict',
145
+ websocket: {
146
+ resolveTypedRouter: (context) => {
147
+ if (context.url.hostname === 'example.com') return publicRouter;
148
+ if (context.url.hostname === 'admin.example.com') return adminRouter;
149
+ return undefined;
150
+ },
151
+ },
152
+ });
153
+ typedSocket.attachSmartServe(smartServe);
154
+ await smartServe.start();
155
+ ```
156
+
157
+ TypedSocket adds a private, one-way fallback router containing its protocol
158
+ handlers to every application router. Duplicate protocol method names are
159
+ rejected during composition and on later router mutations; `stop()` releases
160
+ the owned fallback edges. `fromSmartServe()` remains available as a
161
+ compatibility shortcut that delegates to `createServer()` and
162
+ `attachSmartServe()`.
163
+
164
+ Connection lookup and implicit single-peer targeting span every peer on the
165
+ attached SmartServe transport, regardless of the surface router that accepted
166
+ the peer. Multi-surface servers should tag or filter peers by surface and pass
167
+ an explicit target to `createTypedRequest()`.
168
+
135
169
  ### Client Setup
136
170
 
137
171
  Connect to the WebSocket server from a client:
@@ -220,6 +254,33 @@ const connection = await server.findTargetConnection(async (conn) => {
220
254
  const targetedRequest = server.createTypedRequest<IGreetingRequest>('greet', connection);
221
255
  ```
222
256
 
257
+ #### Request Deadlines and Cancellation
258
+
259
+ TypedSocket forwards both configured request cancellation and per-`fire()` deadlines to its client
260
+ and SmartServe server transports. The first timeout or abort to occur cancels the transport work and
261
+ cleans the pending request state.
262
+
263
+ ```typescript
264
+ const requestAbort = new AbortController();
265
+ const request = client.createTypedRequest<IGreetingRequest>(
266
+ 'greet',
267
+ undefined,
268
+ {
269
+ timeoutMs: 10_000,
270
+ abortSignal: requestAbort.signal,
271
+ }
272
+ );
273
+
274
+ const responsePromise = request.fire(
275
+ { name: 'World' },
276
+ { timeoutMs: 3_000 }
277
+ );
278
+
279
+ // A lifecycle owner can independently cancel before either timeout:
280
+ // requestAbort.abort();
281
+ const response = await responsePromise;
282
+ ```
283
+
223
284
  ### Connection Tagging
224
285
 
225
286
  Tag connections for organized, targeted communication:
@@ -251,8 +312,8 @@ const adminConnections = await server.findAllTargetConnectionsByTag<IUserTag>(
251
312
 
252
313
  // Send to all admins
253
314
  for (const conn of adminConnections) {
254
- const request = server.createTypedRequest<INotificationRequest>('notify', conn);
255
- await request.fire({ message: 'Admin notification' });
315
+ const request = server.createTypedRequest<IGreetingRequest>('greet', conn);
316
+ await request.fire({ name: 'admin' });
256
317
  }
257
318
 
258
319
  // Find a single connection
@@ -281,7 +342,8 @@ Properly close connections when done:
281
342
  // Client
282
343
  await client.stop();
283
344
 
284
- // SmartServe owns the server-side WebSocket lifecycle
345
+ // Server integration
346
+ await typedSocket.stop();
285
347
  await smartServe.stop();
286
348
  ```
287
349
 
@@ -294,7 +356,8 @@ await smartServe.stop();
294
356
  | Method | Description |
295
357
  |--------|-------------|
296
358
  | `createClient(router, serverUrl, options?)` | Creates a WebSocket client that connects to the specified server URL. Options include `autoReconnect`, `maxRetries`, `initialBackoffMs`, `maxBackoffMs`, and `abortSignal`. |
297
- | `fromSmartServe(smartServe, router)` | Creates a TypedSocket bound to an existing SmartServe instance. |
359
+ | `createServer(routerOrRouters)` | Synchronously composes TypedSocket protocol handling into one or more isolated application routers. |
360
+ | `fromSmartServe(smartServe, routerOrRouters)` | Compatibility shortcut that creates and attaches a server-side TypedSocket. |
298
361
  | `useWindowLocationOriginUrl()` | Returns the current window location origin (browser only). |
299
362
 
300
363
  #### Instance Properties
@@ -309,14 +372,15 @@ await smartServe.stop();
309
372
 
310
373
  | Method | Description |
311
374
  |--------|-------------|
312
- | `createTypedRequest(method, targetConnection?)` | Creates a typed request for the specified method. |
375
+ | `attachSmartServe(smartServe)` | Attaches one SmartServe transport to a composed server-side TypedSocket before listening. |
376
+ | `createTypedRequest(method, targetConnection?, options?)` | Creates a typed request. Options include the transport `timeoutMs` and `abortSignal`; per-call `fire()` deadlines are also forwarded to the transport. |
313
377
  | `setTag(name, payload)` | Sets a tag on the client connection (client-side only). |
314
378
  | `removeTag(name)` | Immediately removes a tag from local reconnect state, then removes it from the server connection; rejects if the server removal fails. |
315
379
  | `findAllTargetConnections(filterFn)` | Finds all connections matching the filter (server-side only). |
316
380
  | `findTargetConnection(filterFn)` | Finds the first connection matching the filter (server-side only). |
317
381
  | `findAllTargetConnectionsByTag(key, payload?)` | Finds all connections with the specified tag. |
318
382
  | `findTargetConnectionByTag(key, payload?)` | Finds the first connection with the specified tag. |
319
- | `stop()` | Closes the WebSocket connection. |
383
+ | `stop()` | On clients, closes the WebSocket and rejects pending requests. On servers, cancels pending requests, cleans their interests, unsubscribes from SmartServe, and releases protocol-router composition without stopping SmartServe itself. |
320
384
 
321
385
  ## License and Legal Information
322
386
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@api.global/typedsocket',
6
- version: '5.0.1',
6
+ version: '5.1.0',
7
7
  description: 'A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.'
8
8
  }
@@ -39,12 +39,21 @@ export interface ITypedSocketRequestOptions {
39
39
  abortSignal?: AbortSignal;
40
40
  }
41
41
 
42
+ export type TTypedSocketServerRouterInput =
43
+ | plugins.typedrequest.TypedRouter
44
+ | readonly plugins.typedrequest.TypedRouter[];
45
+
42
46
  interface IPendingServerRequest {
43
47
  peerId: string;
44
48
  cancel: (errorArg: Error) => void;
45
49
  cleanupComplete: Promise<void>;
46
50
  }
47
51
 
52
+ interface IComposedAbortSignal {
53
+ signal?: AbortSignal;
54
+ cleanup: () => void;
55
+ }
56
+
48
57
  /**
49
58
  * Wrapper for SmartServe's IWebSocketPeer to provide tag compatibility
50
59
  */
@@ -69,6 +78,50 @@ function wrapSmartServePeer(peer: plugins.IWebSocketPeer): ISmartServeConnection
69
78
  };
70
79
  }
71
80
 
81
+ function composeAbortSignals(
82
+ configuredSignalArg?: AbortSignal,
83
+ requestSignalArg?: AbortSignal,
84
+ ): IComposedAbortSignal {
85
+ if (!configuredSignalArg || configuredSignalArg === requestSignalArg) {
86
+ return {
87
+ signal: requestSignalArg ?? configuredSignalArg,
88
+ cleanup: () => {},
89
+ };
90
+ }
91
+ if (!requestSignalArg) {
92
+ return {
93
+ signal: configuredSignalArg,
94
+ cleanup: () => {},
95
+ };
96
+ }
97
+
98
+ const abortController = new AbortController();
99
+ const configuredAbortListener = () => {
100
+ abortController.abort(configuredSignalArg.reason);
101
+ };
102
+ const requestAbortListener = () => {
103
+ abortController.abort(requestSignalArg.reason);
104
+ };
105
+ const cleanup = () => {
106
+ configuredSignalArg.removeEventListener('abort', configuredAbortListener);
107
+ requestSignalArg.removeEventListener('abort', requestAbortListener);
108
+ };
109
+
110
+ if (configuredSignalArg.aborted) {
111
+ configuredAbortListener();
112
+ } else if (requestSignalArg.aborted) {
113
+ requestAbortListener();
114
+ } else {
115
+ configuredSignalArg.addEventListener('abort', configuredAbortListener, { once: true });
116
+ requestSignalArg.addEventListener('abort', requestAbortListener, { once: true });
117
+ }
118
+
119
+ return {
120
+ signal: abortController.signal,
121
+ cleanup,
122
+ };
123
+ }
124
+
72
125
  export class TypedSocket {
73
126
  // ============================================================================
74
127
  // STATIC METHODS
@@ -139,11 +192,62 @@ export class TypedSocket {
139
192
  };
140
193
 
141
194
  /**
142
- * Creates a TypedSocket server from an existing SmartServe instance.
143
- * This is the only way to create a server-side TypedSocket.
195
+ * Creates a server-side TypedSocket and composes its private protocol
196
+ * handlers into one or more isolated application routers.
144
197
  *
145
- * @param smartServeArg - SmartServe instance with typedRouter configured in websocket options
146
- * @param typedRouterArg - TypedRouter for handling requests (must match SmartServe's typedRouter)
198
+ * Call attachSmartServe() after constructing the SmartServe transport.
199
+ */
200
+ public static createServer(
201
+ typedRouterOrRoutersArg: TTypedSocketServerRouterInput,
202
+ ): TypedSocket {
203
+ const typedRouters = Array.isArray(typedRouterOrRoutersArg)
204
+ ? [...typedRouterOrRoutersArg]
205
+ : [typedRouterOrRoutersArg];
206
+ if (typedRouters.length === 0) {
207
+ throw new Error('TypedSocket.createServer requires at least one TypedRouter.');
208
+ }
209
+ if (new Set(typedRouters).size !== typedRouters.length) {
210
+ throw new Error('TypedSocket.createServer received the same TypedRouter more than once.');
211
+ }
212
+
213
+ const protocolRouter = new plugins.typedrequest.TypedRouter();
214
+ TypedSocket.registerTagHandlers(protocolRouter);
215
+ const protocolMethods = new Set(protocolRouter.getMethodNames());
216
+ for (const typedRouter of typedRouters) {
217
+ const collision = typedRouter
218
+ .getMethodNames()
219
+ .find((methodArg) => protocolMethods.has(methodArg));
220
+ if (collision) {
221
+ throw new Error(
222
+ `TypedSocket protocol handler collides with application method "${collision}".`,
223
+ );
224
+ }
225
+ }
226
+ const detachProtocolRouters: Array<() => void> = [];
227
+ try {
228
+ for (const typedRouter of typedRouters) {
229
+ detachProtocolRouters.push(typedRouter.addFallbackRouter(protocolRouter));
230
+ }
231
+ } catch (error) {
232
+ for (const detachProtocolRouter of detachProtocolRouters.reverse()) {
233
+ detachProtocolRouter();
234
+ }
235
+ throw error;
236
+ }
237
+
238
+ const typedSocket = new TypedSocket('server', typedRouters[0]);
239
+ typedSocket.serverTypedRouters = typedRouters;
240
+ typedSocket.detachProtocolRouters = detachProtocolRouters;
241
+ return typedSocket;
242
+ }
243
+
244
+ /**
245
+ * Creates and attaches a TypedSocket server to an existing SmartServe
246
+ * instance. Prefer createServer() plus attachSmartServe() when transport
247
+ * construction needs the composed routers first.
248
+ *
249
+ * @param smartServeArg - SmartServe instance configured with the application router
250
+ * @param typedRouterArg - Application TypedRouter used by SmartServe
147
251
  *
148
252
  * @example
149
253
  * ```typescript
@@ -161,22 +265,11 @@ export class TypedSocket {
161
265
  */
162
266
  public static fromSmartServe(
163
267
  smartServeArg: plugins.SmartServe,
164
- typedRouterArg: plugins.typedrequest.TypedRouter
268
+ typedRouterArg: TTypedSocketServerRouterInput,
165
269
  ): TypedSocket {
166
- // Register built-in tag handlers
167
- TypedSocket.registerTagHandlers(typedRouterArg);
168
-
169
- const typedSocket = new TypedSocket('server', typedRouterArg);
170
- typedSocket.smartServeRef = smartServeArg;
171
- typedSocket.unsubscribeSmartServeConnectionClose =
172
- smartServeArg.subscribeWebSocketConnectionClose((peerArg) => {
173
- typedSocket.cancelPendingServerRequestsForPeer(
174
- peerArg.id,
175
- new Error(`TypedSocket target connection closed: ${peerArg.id}`),
176
- );
177
- });
178
-
179
- return typedSocket;
270
+ return TypedSocket
271
+ .createServer(typedRouterArg)
272
+ .attachSmartServe(smartServeArg);
180
273
  }
181
274
 
182
275
  /**
@@ -247,6 +340,8 @@ export class TypedSocket {
247
340
 
248
341
  // Server-specific properties (SmartServe mode)
249
342
  private smartServeRef: plugins.SmartServe | null = null;
343
+ private serverTypedRouters: plugins.typedrequest.TypedRouter[] = [];
344
+ private detachProtocolRouters: Array<() => void> = [];
250
345
  private serverStopping = false;
251
346
  private unsubscribeSmartServeConnectionClose: (() => void) | null = null;
252
347
  private pendingServerRequests = new Map<string, IPendingServerRequest>();
@@ -264,6 +359,34 @@ export class TypedSocket {
264
359
  this.typedrouter = typedrouterArg;
265
360
  }
266
361
 
362
+ /**
363
+ * Attaches the SmartServe transport after server router composition.
364
+ */
365
+ public attachSmartServe(smartServeArg: plugins.SmartServe): this {
366
+ if (this.side !== 'server') {
367
+ throw new Error('attachSmartServe is only available on servers.');
368
+ }
369
+ if (this.serverStopping) {
370
+ throw new Error('Cannot attach SmartServe after the TypedSocket server has stopped.');
371
+ }
372
+ if (this.smartServeRef) {
373
+ if (this.smartServeRef === smartServeArg) {
374
+ return this;
375
+ }
376
+ throw new Error('TypedSocket server is already attached to a SmartServe instance.');
377
+ }
378
+
379
+ const unsubscribe = smartServeArg.subscribeWebSocketConnectionClose((peerArg) => {
380
+ this.cancelPendingServerRequestsForPeer(
381
+ peerArg.id,
382
+ new Error(`TypedSocket target connection closed: ${peerArg.id}`),
383
+ );
384
+ });
385
+ this.smartServeRef = smartServeArg;
386
+ this.unsubscribeSmartServeConnectionClose = unsubscribe;
387
+ return this;
388
+ }
389
+
267
390
  // ============================================================================
268
391
  // CLIENT METHODS
269
392
  // ============================================================================
@@ -693,17 +816,33 @@ export class TypedSocket {
693
816
  onAbort();
694
817
  }
695
818
 
696
- let destroyInterest: (() => void) | undefined;
819
+ const destroyInterests: Array<() => void> = [];
697
820
  try {
698
- const interest = await this.typedrouter.fireEventInterestMap.addInterest(
699
- correlationId,
700
- typedRequestDataArg,
701
- );
702
- destroyInterest = () => interest.destroy();
821
+ const interestPromises: Array<Promise<T>> = [];
822
+ for (const typedRouter of this.serverTypedRouters) {
823
+ const interestRegistration = typedRouter.fireEventInterestMap
824
+ .addInterest(correlationId, typedRequestDataArg)
825
+ .then((interestArg) => {
826
+ if (cancellationRequested || this.serverStopping) {
827
+ interestArg.destroy();
828
+ }
829
+ return interestArg;
830
+ });
831
+ const interest = await Promise.race([
832
+ interestRegistration,
833
+ cancellation.promise,
834
+ ]);
835
+ if (cancellationRequested || this.serverStopping) {
836
+ interest.destroy();
837
+ await cancellation.promise;
838
+ }
839
+ destroyInterests.push(() => interest.destroy());
840
+ interestPromises.push(interest.interestFullfilled as Promise<T>);
841
+ }
703
842
  // Establish the rejecting race before send so synchronous close/abort and
704
843
  // send failures all use the same cleanup path.
705
844
  const response = Promise.race([
706
- interest.interestFullfilled as Promise<T>,
845
+ ...interestPromises,
707
846
  cancellation.promise,
708
847
  ]);
709
848
  const targetIsStillConnected = this.smartServeRef
@@ -728,7 +867,9 @@ export class TypedSocket {
728
867
  if (remainingRequestsForPeer?.size === 0) {
729
868
  this.pendingServerRequestIdsByPeerId.delete(peerId);
730
869
  }
731
- destroyInterest?.();
870
+ for (const destroyInterest of destroyInterests) {
871
+ destroyInterest();
872
+ }
732
873
  cleanup.resolve();
733
874
  }
734
875
  }
@@ -749,35 +890,52 @@ export class TypedSocket {
749
890
  ): plugins.typedrequest.TypedRequest<T> {
750
891
  const postMethod = async (
751
892
  requestDataArg: plugins.typedrequestInterfaces.ITypedRequest,
893
+ postOptionsArg: plugins.typedrequest.ITypedTargetPostOptions = {},
752
894
  ): Promise<plugins.typedrequestInterfaces.ITypedRequest> => {
753
895
  const typedRequestData = requestDataArg as T;
754
- if (this.side === 'client') {
755
- return this.sendRequest(typedRequestData, optionsArg);
756
- }
896
+ const composedAbortSignal = composeAbortSignals(
897
+ optionsArg.abortSignal,
898
+ postOptionsArg.signal,
899
+ );
900
+ const requestOptions: ITypedSocketRequestOptions = {
901
+ ...optionsArg,
902
+ abortSignal: composedAbortSignal.signal,
903
+ };
757
904
 
758
- // Server-side: send to target connection
759
- if (!this.smartServeRef) {
760
- throw new Error('Server not initialized');
761
- }
905
+ try {
906
+ if (this.side === 'client') {
907
+ return await this.sendRequest(typedRequestData, requestOptions);
908
+ }
762
909
 
763
- let target = targetConnection;
764
- if (!target) {
765
- const allConnections = this.smartServeRef.getWebSocketConnections();
766
- if (allConnections.length === 1) {
767
- const peer = allConnections[0];
768
- target = wrapSmartServePeer(peer);
769
- } else if (allConnections.length === 0) {
770
- throw new Error('No WebSocket connections available');
771
- } else {
772
- throw new Error('Multiple connections available - specify targetConnection');
910
+ // Server-side: send to target connection
911
+ if (!this.smartServeRef) {
912
+ throw new Error('Server not initialized');
773
913
  }
774
- }
775
914
 
776
- return await this.sendServerRequest(typedRequestData, target, optionsArg);
915
+ let target = targetConnection;
916
+ if (!target) {
917
+ const allConnections = this.smartServeRef.getWebSocketConnections();
918
+ if (allConnections.length === 1) {
919
+ const peer = allConnections[0];
920
+ target = wrapSmartServePeer(peer);
921
+ } else if (allConnections.length === 0) {
922
+ throw new Error('No WebSocket connections available');
923
+ } else {
924
+ throw new Error('Multiple connections available - specify targetConnection');
925
+ }
926
+ }
927
+
928
+ return await this.sendServerRequest(typedRequestData, target, requestOptions);
929
+ } finally {
930
+ composedAbortSignal.cleanup();
931
+ }
777
932
  };
778
933
 
779
934
  return new plugins.typedrequest.TypedRequest<T>(
780
- new plugins.typedrequest.TypedTarget({ postMethod }),
935
+ new plugins.typedrequest.TypedTarget({
936
+ postMethod,
937
+ supportsAbortSignal: true,
938
+ }),
781
939
  methodName
782
940
  );
783
941
  }
@@ -824,6 +982,10 @@ export class TypedSocket {
824
982
  this.unsubscribeSmartServeConnectionClose?.();
825
983
  this.unsubscribeSmartServeConnectionClose = null;
826
984
  this.smartServeRef = null;
985
+ for (const detachProtocolRouter of this.detachProtocolRouters.reverse()) {
986
+ detachProtocolRouter();
987
+ }
988
+ this.detachProtocolRouters = [];
827
989
  }
828
990
  }
829
991