@mtkruto/node 0.70.0 → 0.70.1

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.
Files changed (49) hide show
  1. package/esm/_dnt.polyfills.d.ts +13 -13
  2. package/esm/_dnt.polyfills.d.ts.map +1 -1
  3. package/esm/_dnt.polyfills.js +11 -11
  4. package/esm/client/0_abortable_loop.d.ts +1 -1
  5. package/esm/client/0_abortable_loop.d.ts.map +1 -1
  6. package/esm/client/0_abortable_loop.js +2 -2
  7. package/esm/client/0_client_abstract.d.ts +1 -0
  8. package/esm/client/0_client_abstract.d.ts.map +1 -1
  9. package/esm/client/0_client_abstract.js +3 -0
  10. package/esm/client/2_client_encrypted.d.ts.map +1 -1
  11. package/esm/client/2_client_encrypted.js +26 -23
  12. package/esm/client/2_network_statistics_manager.d.ts +2 -2
  13. package/esm/client/2_network_statistics_manager.d.ts.map +1 -1
  14. package/esm/client/2_network_statistics_manager.js +30 -4
  15. package/esm/client/2_update_manager.js +1 -1
  16. package/esm/client/5_client.js +9 -9
  17. package/esm/session/1_session.d.ts +1 -0
  18. package/esm/session/1_session.d.ts.map +1 -1
  19. package/esm/session/1_session.js +3 -0
  20. package/esm/session/2_session_encrypted.d.ts +1 -1
  21. package/esm/session/2_session_encrypted.d.ts.map +1 -1
  22. package/esm/session/2_session_encrypted.js +153 -89
  23. package/esm/tl/2_telegram.d.ts +1 -1
  24. package/esm/tl/2_telegram.d.ts.map +1 -1
  25. package/package.json +1 -1
  26. package/script/_dnt.polyfills.d.ts +13 -13
  27. package/script/_dnt.polyfills.d.ts.map +1 -1
  28. package/script/_dnt.polyfills.js +11 -11
  29. package/script/client/0_abortable_loop.d.ts +1 -1
  30. package/script/client/0_abortable_loop.d.ts.map +1 -1
  31. package/script/client/0_abortable_loop.js +2 -2
  32. package/script/client/0_client_abstract.d.ts +1 -0
  33. package/script/client/0_client_abstract.d.ts.map +1 -1
  34. package/script/client/0_client_abstract.js +3 -0
  35. package/script/client/2_client_encrypted.d.ts.map +1 -1
  36. package/script/client/2_client_encrypted.js +26 -23
  37. package/script/client/2_network_statistics_manager.d.ts +2 -2
  38. package/script/client/2_network_statistics_manager.d.ts.map +1 -1
  39. package/script/client/2_network_statistics_manager.js +30 -4
  40. package/script/client/2_update_manager.js +1 -1
  41. package/script/client/5_client.js +9 -9
  42. package/script/session/1_session.d.ts +1 -0
  43. package/script/session/1_session.d.ts.map +1 -1
  44. package/script/session/1_session.js +3 -0
  45. package/script/session/2_session_encrypted.d.ts +1 -1
  46. package/script/session/2_session_encrypted.d.ts.map +1 -1
  47. package/script/session/2_session_encrypted.js +153 -89
  48. package/script/tl/2_telegram.d.ts +1 -1
  49. package/script/tl/2_telegram.d.ts.map +1 -1
@@ -40,7 +40,7 @@ class ClientEncrypted extends _0_client_abstract_js_1.ClientAbstract {
40
40
  #L;
41
41
  #plain;
42
42
  session;
43
- #pendingRequests = new Map();
43
+ #sentRequests = new Map();
44
44
  #apiId;
45
45
  #appVersion;
46
46
  #deviceModel;
@@ -179,17 +179,18 @@ class ClientEncrypted extends _0_client_abstract_js_1.ClientAbstract {
179
179
  async #resend(request) {
180
180
  try {
181
181
  const messageId = await this.#send(request.call);
182
- this.#pendingRequests.set(messageId, request);
182
+ this.#sentRequests.set(messageId, request);
183
183
  }
184
184
  catch (err) {
185
- request.reject(err);
185
+ request.promiseWithResolvers.reject(err);
186
186
  }
187
187
  }
188
188
  async invoke(function_) {
189
189
  const messageId = await this.#send(function_);
190
- return (await new Promise((resolve, reject) => {
191
- this.#pendingRequests.set(messageId, { resolve, reject, call: function_ });
192
- }));
190
+ this.#L.debug("sent", function_._, "with msg_id", messageId);
191
+ const sentRequest = { call: function_, promiseWithResolvers: Promise.withResolvers() };
192
+ this.#sentRequests.set(messageId, sentRequest);
193
+ return await sentRequest.promiseWithResolvers.promise;
193
194
  }
194
195
  async #onUpdate(body) {
195
196
  let type;
@@ -212,49 +213,51 @@ class ClientEncrypted extends _0_client_abstract_js_1.ClientAbstract {
212
213
  this.handlers.onNewServerSalt?.(serverSalt);
213
214
  }
214
215
  async #onMessageFailed(msgId, error) {
215
- const request = this.#pendingRequests.get(msgId);
216
+ const request = this.#sentRequests.get(msgId);
216
217
  if (request) {
217
- this.#pendingRequests.delete(msgId);
218
+ this.#sentRequests.delete(msgId);
218
219
  if (error instanceof _4_session_js_1.SessionError) {
219
220
  await this.#resend(request);
220
221
  }
221
222
  else {
222
- request.reject(error);
223
+ request.promiseWithResolvers.reject(error);
223
224
  }
224
225
  }
225
226
  }
226
227
  async #onRpcError(msgId, error) {
227
- const request = this.#pendingRequests.get(msgId);
228
+ const request = this.#sentRequests.get(msgId);
229
+ this.#L.debug("received rpc_error with req_msg_id =", msgId, "for", request === undefined ? "unknown" : "known", "request");
228
230
  if (request) {
229
- this.#pendingRequests.delete(msgId);
231
+ this.#sentRequests.delete(msgId);
230
232
  const reason = (0, _4_errors_js_1.constructTelegramError)(error, request.call);
231
233
  if (reason instanceof _3_errors_js_1.ConnectionNotInited) {
232
234
  this.#connectionInited = false;
233
235
  await this.#resend(request);
234
236
  }
235
237
  else {
236
- request.reject((0, _4_errors_js_1.constructTelegramError)(error, request.call));
238
+ request.promiseWithResolvers.reject((0, _4_errors_js_1.constructTelegramError)(error, request.call));
237
239
  }
238
240
  }
239
241
  }
240
242
  async #onRpcResult(msgId, body) {
241
- const request = this.#pendingRequests.get(msgId);
242
- if (request) {
243
+ const sentRequest = this.#sentRequests.get(msgId);
244
+ this.#L.debug("received rpc_result with req_msg_id =", msgId, "for", sentRequest === undefined ? "unknown" : "known", "request");
245
+ if (sentRequest) {
243
246
  let type;
244
247
  try {
245
- type = await _2_tl_js_1.Api.deserializeType(_2_tl_js_1.Api.mustGetReturnType(request.call._), body);
248
+ type = await _2_tl_js_1.Api.deserializeType(_2_tl_js_1.Api.mustGetReturnType(sentRequest.call._), body);
246
249
  this.#L.in(type);
247
250
  this.#L.debug("received rpc_result", (0, _0_utilities_js_1.repr)(type));
248
- request.resolve(type);
251
+ sentRequest.promiseWithResolvers.resolve(type);
249
252
  }
250
253
  catch (err) {
251
- request.reject(err);
252
- this.#L.error("failed to deserialize RPC result body:", err);
254
+ sentRequest.promiseWithResolvers.reject(err);
255
+ this.#L.error("failed to deserialize rpc_result body:", err);
253
256
  this.handlers.onDeserializationError?.();
254
257
  return;
255
258
  }
256
259
  finally {
257
- this.#pendingRequests.delete(msgId);
260
+ this.#sentRequests.delete(msgId);
258
261
  }
259
262
  }
260
263
  if (!this.#connectionInited) {
@@ -262,10 +265,10 @@ class ClientEncrypted extends _0_client_abstract_js_1.ClientAbstract {
262
265
  }
263
266
  }
264
267
  #onPong(pong) {
265
- const pendingRequest = this.#pendingRequests.get(pong.msg_id);
266
- if (pendingRequest) {
267
- pendingRequest.resolve(pong);
268
- this.#pendingRequests.delete(pong.msg_id);
268
+ const sentRequest = this.#sentRequests.get(pong.msg_id);
269
+ if (sentRequest) {
270
+ sentRequest.promiseWithResolvers.resolve(pong);
271
+ this.#sentRequests.delete(pong.msg_id);
269
272
  }
270
273
  }
271
274
  }
@@ -32,8 +32,8 @@ export declare class NetworkStatisticsManager {
32
32
  };
33
33
  }>;
34
34
  getTransportReadWriteCallback(cdn: boolean): {
35
- read: (count: number) => Promise<void>;
36
- write: (count: number) => Promise<void>;
35
+ read: (count: number) => void;
36
+ write: (count: number) => void;
37
37
  };
38
38
  }
39
39
  //# sourceMappingURL=2_network_statistics_manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"2_network_statistics_manager.d.ts","sourceRoot":"","sources":["../../src/client/2_network_statistics_manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAEtC,qBAAa,wBAAwB;;gBAGvB,CAAC,EAAE,CAAC;IAIV,oBAAoB;;;;;;;;;;IAkB1B,6BAA6B,CAAC,GAAG,EAAE,OAAO;sBAElB,MAAM;uBAIL,MAAM;;CAMhC"}
1
+ {"version":3,"file":"2_network_statistics_manager.d.ts","sourceRoot":"","sources":["../../src/client/2_network_statistics_manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAEtC,qBAAa,wBAAwB;;gBAIvB,CAAC,EAAE,CAAC;IAKV,oBAAoB;;;;;;;;;;IAmB1B,6BAA6B,CAAC,GAAG,EAAE,OAAO;sBAExB,MAAM;uBAKL,MAAM;;CA2B1B"}
@@ -20,10 +20,13 @@
20
20
  */
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
22
  exports.NetworkStatisticsManager = void 0;
23
+ const _1_logger_js_1 = require("../utilities/1_logger.js");
23
24
  class NetworkStatisticsManager {
24
25
  #c;
26
+ #L;
25
27
  constructor(c) {
26
28
  this.#c = c;
29
+ this.#L = (0, _1_logger_js_1.getLogger)("NetworkStatisticsManager");
27
30
  }
28
31
  async getNetworkStatistics() {
29
32
  const [messagesRead, messagesWrite, cdnRead, cdnWrite] = await Promise.all([
@@ -42,17 +45,40 @@ class NetworkStatisticsManager {
42
45
  };
43
46
  return { messages, cdn };
44
47
  }
48
+ #pendingWrites = {};
45
49
  getTransportReadWriteCallback(cdn) {
46
50
  return {
47
- read: async (count) => {
51
+ read: (count) => {
48
52
  const key = cdn ? "netstat_cdn_read" : "netstat_messages_read";
49
- await this.#c.storage.incr([key], count);
53
+ this.#pendingWrites[key] = (this.#pendingWrites[key] ?? 0) + count;
54
+ this.#write();
50
55
  },
51
- write: async (count) => {
56
+ write: (count) => {
52
57
  const key = cdn ? "netstat_cdn_write" : "netstat_messages_write";
53
- await this.#c.storage.incr([key], count);
58
+ this.#pendingWrites[key] = (this.#pendingWrites[key] ?? 0) + count;
59
+ this.#write();
54
60
  },
55
61
  };
56
62
  }
63
+ #writing = false;
64
+ async #write() {
65
+ if (this.#writing) {
66
+ return;
67
+ }
68
+ this.#writing = true;
69
+ for (const [k, v] of Object.entries(this.#pendingWrites)) {
70
+ if (v < 1) {
71
+ continue;
72
+ }
73
+ try {
74
+ await this.#c.messageStorage.incr([k], v);
75
+ this.#pendingWrites[k] -= v;
76
+ }
77
+ catch (err) {
78
+ this.#L.error("write failed:", err);
79
+ }
80
+ }
81
+ this.#writing = false;
82
+ }
57
83
  }
58
84
  exports.NetworkStatisticsManager = NetworkStatisticsManager;
@@ -962,7 +962,7 @@ class UpdateManager {
962
962
  const timeout = await this.#recoverChannelUpdateGap(channelId, "openChat");
963
963
  const dT = Date.now() - Ti;
964
964
  const delay = Math.max(timeout * 1_000 - dT, 0);
965
- logger.debug("timeout=", timeout, "delay=", delay, "dT=", dT);
965
+ logger.debug("timeout =", timeout, "delay =", delay, "dT =", dT);
966
966
  if (delay) {
967
967
  await new Promise((r) => {
968
968
  const resolve = () => {
@@ -853,10 +853,10 @@ class Client extends Composer {
853
853
  return this.#lastGetMe?.isPremium ?? false;
854
854
  }
855
855
  #lastUpdates = new Date();
856
- #updateGapRecoveryLoop = new _0_abortable_loop_js_1.AbortableLoop(async (signal) => {
856
+ #updateGapRecoveryLoop = new _0_abortable_loop_js_1.AbortableLoop(async (loop, signal) => {
857
857
  await (0, _0_deps_js_1.delay)(60 * _0_deps_js_1.SECOND, { signal });
858
858
  if (!this.connected) {
859
- this.#updateGapRecoveryLoop.abort();
859
+ loop.abort();
860
860
  return;
861
861
  }
862
862
  if (Date.now() - this.#lastUpdates.getTime() >= 15 * _0_deps_js_1.MINUTE) {
@@ -864,18 +864,18 @@ class Client extends Composer {
864
864
  this.#lastUpdates = new Date();
865
865
  }));
866
866
  }
867
- }, (err) => {
867
+ }, (loop, err) => {
868
868
  if (!this.connected) {
869
- this.#updateGapRecoveryLoop.abort();
869
+ loop.abort();
870
870
  }
871
871
  else {
872
872
  this.#LupdateGapRecoveryLoop.error(err);
873
873
  }
874
874
  });
875
- #clientDisconnectionLoop = new _0_abortable_loop_js_1.AbortableLoop(async (signal) => {
875
+ #clientDisconnectionLoop = new _0_abortable_loop_js_1.AbortableLoop(async (loop, signal) => {
876
876
  await (0, _0_deps_js_1.delay)(60 * _0_deps_js_1.SECOND, { signal });
877
877
  if (!this.connected) {
878
- this.#clientDisconnectionLoop.abort();
878
+ loop.abort();
879
879
  return;
880
880
  }
881
881
  const now = Date.now();
@@ -885,12 +885,12 @@ class Client extends Composer {
885
885
  client?.disconnect();
886
886
  }
887
887
  }
888
- }, () => {
888
+ }, (loop) => {
889
889
  if (!this.connected) {
890
- this.#clientDisconnectionLoop.abort();
890
+ loop.abort();
891
891
  }
892
892
  });
893
- #storageWriteLoop = new _0_abortable_loop_js_1.AbortableLoop(async (signal) => {
893
+ #storageWriteLoop = new _0_abortable_loop_js_1.AbortableLoop(async (_loop, signal) => {
894
894
  await (0, _0_deps_js_1.delay)(60 * _0_deps_js_1.SECOND, { signal });
895
895
  await this.messageStorage.commit();
896
896
  await this.storage.commit();
@@ -21,6 +21,7 @@ export declare abstract class Session {
21
21
  get dc(): DC;
22
22
  get cdn(): boolean;
23
23
  set serverSalt(serverSalt: bigint);
24
+ get serverSalt(): bigint;
24
25
  get connected(): boolean;
25
26
  connect(): Promise<void>;
26
27
  protected waitUntilConnected(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"1_session.d.ts","sourceRoot":"","sources":["../../src/session/1_session.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAAoD,MAAM,mBAAmB,CAAC;AACtH,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAQpD,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;OAEG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,8BAAsB,OAAO;;IAG3B,SAAS,CAAC,KAAK,EAAE,YAAY,CAAsB;IACnD,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC;gBAMvC,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa;IAc1C,IAAI,uBAAuB,CAAC,uBAAuB,EAAE,UAAU,CAAC,oBAAoB,CAAC,EAEpF;IAED,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,EAExE;IAED,IAAI,EAAE,IAAI,EAAE,CAEX;IAED,IAAI,GAAG,IAAI,OAAO,CAEjB;IAED,IAAI,UAAU,CAAC,UAAU,EAAE,MAAM,EAEhC;IA6BD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAGK,OAAO;cAeG,kBAAkB;IAIlC,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,UAAU;IAOV,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;CACjD"}
1
+ {"version":3,"file":"1_session.d.ts","sourceRoot":"","sources":["../../src/session/1_session.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAAoD,MAAM,mBAAmB,CAAC;AACtH,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAQpD,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;OAEG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,8BAAsB,OAAO;;IAG3B,SAAS,CAAC,KAAK,EAAE,YAAY,CAAsB;IACnD,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC;gBAMvC,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa;IAc1C,IAAI,uBAAuB,CAAC,uBAAuB,EAAE,UAAU,CAAC,oBAAoB,CAAC,EAEpF;IAED,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,EAExE;IAED,IAAI,EAAE,IAAI,EAAE,CAEX;IAED,IAAI,GAAG,IAAI,OAAO,CAEjB;IAED,IAAI,UAAU,CAAC,UAAU,EAAE,MAAM,EAEhC;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IA6BD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAGK,OAAO;cAeG,kBAAkB;IAIlC,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,UAAU;IAOV,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;CACjD"}
@@ -98,6 +98,9 @@ class Session {
98
98
  set serverSalt(serverSalt) {
99
99
  this.state.serverSalt = serverSalt;
100
100
  }
101
+ get serverSalt() {
102
+ return this.state.serverSalt;
103
+ }
101
104
  #lastState;
102
105
  async #stateChangeHandler(connected) {
103
106
  if (this.#lastState !== connected) {
@@ -36,6 +36,6 @@ export declare class SessionEncrypted extends Session implements Session {
36
36
  get authKey(): Uint8Array<ArrayBuffer>;
37
37
  connect(): Promise<void>;
38
38
  disconnect(): void;
39
- send(body: Uint8Array): Promise<bigint>;
39
+ send(body: Uint8Array<ArrayBuffer>): Promise<bigint>;
40
40
  }
41
41
  //# sourceMappingURL=2_session_encrypted.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"2_session_encrypted.d.ts","sourceRoot":"","sources":["../../src/session/2_session_encrypted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAwD,OAAO,EAAuC,MAAM,YAAY,CAAC;AAChI,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAI5C,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAS7D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC;IAC5D,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACxD;AAQD,qBAAa,gBAAiB,SAAQ,OAAQ,YAAW,OAAO;;IAI9D,QAAQ,EAAE,QAAQ,CAAM;gBAUZ,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa;IAMpC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC;IAM7C,IAAI,OAAO,IAAI,UAAU,CAAC,WAAW,CAAC,CAErC;IAEc,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAa9B,UAAU,IAAI,IAAI;IA2ErB,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;CAsT9C"}
1
+ {"version":3,"file":"2_session_encrypted.d.ts","sourceRoot":"","sources":["../../src/session/2_session_encrypted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAwD,OAAO,EAAuC,MAAM,YAAY,CAAC;AAChI,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAI5C,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAa7D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC;IAC5D,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACxD;AAED,qBAAa,gBAAiB,SAAQ,OAAQ,YAAW,OAAO;;IAI9D,QAAQ,EAAE,QAAQ,CAAM;gBAiBZ,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,aAAa;IAQpC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC;IAM7C,IAAI,OAAO,IAAI,UAAU,CAAC,WAAW,CAAC,CAErC;IAEc,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAe9B,UAAU,IAAI,IAAI;IA6ErB,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;CA6W3D"}