@based/functions 1.0.2 → 1.1.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.
package/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # @based/functions
2
+
3
+ To be used with based cloud functions, adds types and utilities.
4
+
5
+ - Example based function
6
+
7
+ ```typescript
8
+ import { BasedFunction } from '@based/functions'
9
+
10
+ const submitVote: BasedFunction<
11
+ { target: number },
12
+ 'ok' | 'not-ok'
13
+ > = async (based, { target }) => {
14
+ if (target > 10) {
15
+ return 'ok'
16
+ }
17
+ return 'not-ok'
18
+ }
19
+
20
+ export default submitVote
21
+ ```
package/dist/auth.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BasedFunctionClient } from './client';
2
2
  import { HttpRequest } from './uws';
3
3
  import { Context, WebSocketSession, HttpSession } from './context';
4
- export declare type AuthState = {
4
+ export type AuthState = {
5
5
  token?: string;
6
6
  userId?: string;
7
7
  refreshToken?: string;
@@ -9,7 +9,7 @@ export declare type AuthState = {
9
9
  persistent?: boolean;
10
10
  type?: string;
11
11
  };
12
- export declare type Authorize = (based: BasedFunctionClient, context: Context<HttpSession | WebSocketSession>, name: string, // name as generic dope
12
+ export type Authorize = (based: BasedFunctionClient, context: Context<HttpSession | WebSocketSession>, name: string, // name as generic dope
13
13
  payload?: any) => Promise<boolean>;
14
- export declare type VerifyAuthState = (based: BasedFunctionClient, context: Context<HttpSession | WebSocketSession>, authState: AuthState) => true | AuthState;
15
- export declare type AuthorizeConnection = (based: BasedFunctionClient, req: HttpRequest) => Promise<boolean>;
14
+ export type VerifyAuthState = (based: BasedFunctionClient, context: Context<HttpSession | WebSocketSession>, authState: AuthState) => Promise<true | AuthState>;
15
+ export type AuthorizeConnection = (based: BasedFunctionClient, req: HttpRequest) => Promise<boolean>;
@@ -0,0 +1,5 @@
1
+ import { ChannelMessageFunction } from './functions';
2
+ export declare abstract class BasedChannel<K = any> {
3
+ abstract subscribe(onMessage: ChannelMessageFunction<K>, onError?: (err: any) => void): () => void;
4
+ abstract publish(message: K): void;
5
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BasedChannel = void 0;
4
+ class BasedChannel {
5
+ }
6
+ exports.BasedChannel = BasedChannel;
7
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":";;;AAEA,MAAsB,YAAY;CAOjC;AAPD,oCAOC"}
package/dist/client.d.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import { AuthState } from './auth';
2
+ import { BasedChannel } from './channel';
2
3
  import { Context } from './context';
3
4
  import { BasedQuery } from './query';
5
+ import { StreamFunctionOpts } from './stream';
4
6
  export declare abstract class BasedFunctionClient {
5
7
  server: any;
6
8
  abstract call(name: string, payload?: any, ctx?: Context): Promise<any>;
7
9
  abstract query(name: string, payload?: any): BasedQuery;
8
- abstract stream(name: string, stream?: any, ctx?: Context): Promise<any>;
10
+ abstract channel(name: string, payload?: any): BasedChannel;
11
+ abstract stream(name: string, payload: StreamFunctionOpts, ctx?: Context): Promise<any>;
9
12
  abstract sendAuthState(ctx: Context, authState: AuthState): void;
10
- abstract renewAuthState(ctx: Context): void;
13
+ abstract renewAuthState(ctx: Context, authState?: AuthState): Promise<AuthState>;
11
14
  }
package/dist/client.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BasedFunctionClient = void 0;
4
+ // TODO: this is the place where we will add extra specifications
4
5
  class BasedFunctionClient {
5
6
  }
6
7
  exports.BasedFunctionClient = BasedFunctionClient;
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAIA,MAAsB,mBAAmB;CAYxC;AAZD,kDAYC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAMA,iEAAiE;AACjE,MAAsB,mBAAmB;CAqBxC;AArBD,kDAqBC"}
package/dist/context.d.ts CHANGED
@@ -2,7 +2,7 @@ import { AuthState } from './auth';
2
2
  import { WebSocket, HttpRequest, HttpResponse } from './uws';
3
3
  import { parseQuery } from '@saulx/utils';
4
4
  import { BasedFunctionClient } from './client';
5
- export declare type WebSocketSession = {
5
+ export type WebSocketSession = {
6
6
  state?: any;
7
7
  query: string;
8
8
  ua: string;
@@ -11,15 +11,22 @@ export declare type WebSocketSession = {
11
11
  method: string;
12
12
  authState: AuthState;
13
13
  obs: Set<number>;
14
- unauthorizedObs: Set<{
14
+ unauthorizedObs?: Set<{
15
15
  id: number;
16
16
  checksum: number;
17
17
  name: string;
18
18
  payload: any;
19
19
  }>;
20
+ unauthorizedChannels?: Set<{
21
+ id: number;
22
+ name: string;
23
+ payload: any;
24
+ }>;
20
25
  c?: Context<WebSocketSession>;
21
- } & WebSocket;
22
- export declare type HttpSession = {
26
+ ws?: BasedWebSocket;
27
+ };
28
+ export type BasedWebSocket = WebSocket<WebSocketSession>;
29
+ export type HttpSession = {
23
30
  state?: any;
24
31
  res: HttpResponse;
25
32
  req: HttpRequest;
@@ -40,25 +47,34 @@ export declare type HttpSession = {
40
47
  [key: string]: string;
41
48
  };
42
49
  };
43
- export declare type InternalSessionObservable = {
50
+ export type InternalSessionObservable = {
44
51
  id: number;
45
52
  name: string;
46
53
  type: 'query';
47
54
  };
48
- export declare type InternalSessionClient = {
55
+ export type InternalSessionChannel = {
56
+ id: number;
57
+ name: string;
58
+ type: 'channel';
59
+ };
60
+ export type InternalSessionClient = {
49
61
  client: BasedFunctionClient;
50
62
  type: 'client';
51
63
  };
52
- export declare type InternalSession = InternalSessionClient | InternalSessionObservable;
53
- export declare type MinimalExternalSession = {
64
+ export type InternalSession = InternalSessionClient | InternalSessionObservable | InternalSessionChannel;
65
+ export type MinimalExternalSession = {
54
66
  ua: string;
55
67
  ip: string;
56
68
  };
57
- export declare type Session = WebSocketSession | HttpSession | InternalSession | MinimalExternalSession;
58
- export declare type Context<S extends Session = Session> = {
69
+ export type Session = (WebSocketSession | HttpSession | InternalSession | MinimalExternalSession) & {
70
+ /** Only available in Ws and Http contexts */
71
+ authState?: AuthState;
72
+ };
73
+ export type Context<S extends Session = Session> = {
59
74
  session?: S;
60
75
  };
61
76
  export declare const isHttpContext: (ctx: Context<Session>) => ctx is Context<HttpSession>;
62
77
  export declare const isWsContext: (ctx: Context<Session>) => ctx is Context<WebSocketSession>;
63
- export declare const isClientContext: (ctx: Context<Session>) => ctx is Context<WebSocketSession>;
78
+ export declare const isClientContext: (ctx: Context<Session>) => ctx is Context<WebSocketSession | HttpSession>;
79
+ export declare const isHttpSession: (session: Session) => session is HttpSession;
64
80
  export declare const isWsSession: (session: Session) => session is WebSocketSession;
package/dist/context.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isWsSession = exports.isClientContext = exports.isWsContext = exports.isHttpContext = void 0;
3
+ exports.isWsSession = exports.isHttpSession = exports.isClientContext = exports.isWsContext = exports.isHttpContext = void 0;
4
4
  const isHttpContext = (ctx) => {
5
5
  if ('res' in ctx?.session) {
6
6
  return true;
@@ -16,14 +16,21 @@ const isWsContext = (ctx) => {
16
16
  };
17
17
  exports.isWsContext = isWsContext;
18
18
  const isClientContext = (ctx) => {
19
- if (ctx.session && 'authState' in ctx.session) {
19
+ if (ctx.session && ((0, exports.isWsSession)(ctx.session) || (0, exports.isHttpSession)(ctx.session))) {
20
20
  return true;
21
21
  }
22
22
  return false;
23
23
  };
24
24
  exports.isClientContext = isClientContext;
25
+ const isHttpSession = (session) => {
26
+ if ('res' in session) {
27
+ return true;
28
+ }
29
+ return false;
30
+ };
31
+ exports.isHttpSession = isHttpSession;
25
32
  const isWsSession = (session) => {
26
- if (!('res' in session) && 'ip' in session && 'id' in session) {
33
+ if ('send' in session) {
27
34
  return true;
28
35
  }
29
36
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;;AA4EO,MAAM,aAAa,GAAG,CAC3B,GAAqB,EACQ,EAAE;IAC/B,IAAI,KAAK,IAAI,GAAG,EAAE,OAAO,EAAE;QACzB,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAPY,QAAA,aAAa,iBAOzB;AAEM,MAAM,WAAW,GAAG,CACzB,GAAqB,EACa,EAAE;IACpC,IAAI,GAAG,CAAC,OAAO,IAAI,IAAA,mBAAW,EAAC,GAAG,CAAC,OAAO,CAAC,EAAE;QAC3C,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAPY,QAAA,WAAW,eAOvB;AAEM,MAAM,eAAe,GAAG,CAC7B,GAAqB,EACa,EAAE;IACpC,IAAI,GAAG,CAAC,OAAO,IAAI,WAAW,IAAI,GAAG,CAAC,OAAO,EAAE;QAC7C,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAPY,QAAA,eAAe,mBAO3B;AAEM,MAAM,WAAW,GAAG,CAAC,OAAgB,EAA+B,EAAE;IAC3E,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,EAAE;QAC7D,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AALY,QAAA,WAAW,eAKvB"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;;AAiGO,MAAM,aAAa,GAAG,CAC3B,GAAqB,EACQ,EAAE;IAC/B,IAAI,KAAK,IAAI,GAAG,EAAE,OAAO,EAAE;QACzB,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAPY,QAAA,aAAa,iBAOzB;AAEM,MAAM,WAAW,GAAG,CACzB,GAAqB,EACa,EAAE;IACpC,IAAI,GAAG,CAAC,OAAO,IAAI,IAAA,mBAAW,EAAC,GAAG,CAAC,OAAO,CAAC,EAAE;QAC3C,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAPY,QAAA,WAAW,eAOvB;AAEM,MAAM,eAAe,GAAG,CAC7B,GAAqB,EAC2B,EAAE;IAClD,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,IAAA,mBAAW,EAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAA,qBAAa,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE;QAC3E,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAPY,QAAA,eAAe,mBAO3B;AAEM,MAAM,aAAa,GAAG,CAAC,OAAgB,EAA0B,EAAE;IACxE,IAAI,KAAK,IAAI,OAAO,EAAE;QACpB,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AALY,QAAA,aAAa,iBAKzB;AAEM,MAAM,WAAW,GAAG,CAAC,OAAgB,EAA+B,EAAE;IAC3E,IAAI,MAAM,IAAI,OAAO,EAAE;QACrB,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AALY,QAAA,WAAW,eAKvB"}
@@ -1,28 +1,29 @@
1
- /// <reference types="node" />
2
1
  import { Context, HttpSession } from './context';
3
2
  import { BasedFunctionClient } from './client';
4
- import { Duplex } from 'stream';
5
- export declare type ObservableUpdateFunction<K = any> = {
3
+ import { BasedDataStream } from './stream';
4
+ export type ObservableUpdateFunction<K = any> = {
6
5
  (data: K, checksum?: number, diff?: any, fromChecksum?: number, isDeflate?: boolean, rawData?: K, err?: any): void;
7
6
  __internalObs__?: true;
8
7
  };
9
- export declare type ObserveErrorListener = (err: any) => void;
10
- export declare type HttpHeaders = {
8
+ export type ObserveErrorListener = (err: any) => void;
9
+ export type HttpHeaders = {
11
10
  [header: string]: number | string | (string | number)[];
12
11
  };
13
- export declare type SendHttpResponse = (responseData: any, headers?: HttpHeaders, status?: string | number) => void;
14
- export declare type HttpResponse<P = any, K = any> = (based: BasedFunctionClient, payload: P, responseData: K, send: SendHttpResponse, ctx: Context<HttpSession>) => Promise<void>;
15
- export declare type BasedFunction<P = any, K = any> = (based: BasedFunctionClient, payload: P, ctx: Context) => Promise<K>;
16
- export declare type StreamPayload<P = any> = {
12
+ export type SendHttpResponse = (responseData: any, headers?: HttpHeaders, status?: string | number) => void;
13
+ export type HttpResponse<P = any, K = any> = (based: BasedFunctionClient, payload: P, responseData: K, send: SendHttpResponse, ctx: Context<HttpSession>) => Promise<void>;
14
+ export type BasedFunction<P = any, K = any> = (based: BasedFunctionClient, payload: P, ctx: Context) => Promise<K>;
15
+ export type StreamPayload<P = any> = {
17
16
  payload?: P;
18
17
  mimeType: string;
19
18
  size: number;
20
- stream: Duplex & {
21
- size: number;
22
- receivedBytes: number;
23
- };
19
+ stream: BasedDataStream;
24
20
  fileName?: string;
25
21
  extension?: string;
26
22
  };
27
- export declare type BasedStreamFunction<P = any, K = any> = BasedFunction<StreamPayload<P>, K>;
28
- export declare type BasedQueryFunction<P = any, K = any> = ((based: BasedFunctionClient, payload: P, update: ObservableUpdateFunction<K>, error?: ObserveErrorListener) => Promise<() => void>) | ((based: BasedFunctionClient, payload: P, update: ObservableUpdateFunction<K>, error?: ObserveErrorListener) => () => void);
23
+ export type BasedStreamFunction<P = any, K = any> = BasedFunction<StreamPayload<P>, K>;
24
+ export type BasedQueryFunction<P = any, K = any> = ((based: BasedFunctionClient, payload: P, update: ObservableUpdateFunction<K>, error: ObserveErrorListener) => Promise<() => void>) | ((based: BasedFunctionClient, payload: P, update: ObservableUpdateFunction<K>, error: ObserveErrorListener) => () => void);
25
+ export type BasedChannelFunction<P = any, K = any> = (based: BasedFunctionClient, payload: P, id: number, update: ChannelMessageFunction<K>, error: (err?: any) => void) => () => void;
26
+ export type BasedChannelPublishFunction<P = any, K = any> = (based: BasedFunctionClient, payload: P, message: K, id: number, ctx: Context) => void;
27
+ export type ChannelMessageFunction<K = any> = (message: K) => void;
28
+ export type ChannelMessageFunctionInternal<K = any> = (message: K, err?: any) => void;
29
+ export type UninstallFunction = () => Promise<void>;
package/dist/index.d.ts CHANGED
@@ -3,3 +3,5 @@ export * from './auth';
3
3
  export * from './client';
4
4
  export * from './functions';
5
5
  export * from './query';
6
+ export * from './stream';
7
+ export * from './channel';
package/dist/index.js CHANGED
@@ -19,4 +19,6 @@ __exportStar(require("./auth"), exports);
19
19
  __exportStar(require("./client"), exports);
20
20
  __exportStar(require("./functions"), exports);
21
21
  __exportStar(require("./query"), exports);
22
+ __exportStar(require("./stream"), exports);
23
+ __exportStar(require("./channel"), exports);
22
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAAyB;AACzB,yCAAsB;AACtB,2CAAwB;AACxB,8CAA2B;AAC3B,0CAAuB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAAyB;AACzB,yCAAsB;AACtB,2CAAwB;AACxB,8CAA2B;AAC3B,0CAAuB;AACvB,2CAAwB;AACxB,4CAAyB"}
package/dist/query.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ObservableUpdateFunction, ObserveErrorListener } from './functions';
2
- export declare abstract class BasedQuery {
3
- abstract subscribe(onData: ObservableUpdateFunction, onError?: ObserveErrorListener): () => void;
4
- abstract getWhen(condition: (data: any, checksum: number) => boolean): Promise<any>;
5
- abstract get(): Promise<any>;
2
+ export declare abstract class BasedQuery<K = any> {
3
+ abstract subscribe(onData: ObservableUpdateFunction<K>, onError?: ObserveErrorListener): () => void;
4
+ abstract getWhen(condition: (data: K, checksum: number) => boolean): Promise<any>;
5
+ abstract get(): Promise<K>;
6
6
  }
@@ -0,0 +1,39 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ import { Duplex, Readable } from 'stream';
6
+ import util from 'node:util';
7
+ export declare class BasedDataStream extends Duplex {
8
+ size: number;
9
+ receivedBytes: number;
10
+ progessTimer: NodeJS.Timeout;
11
+ constructor(size: number);
12
+ _read(): void;
13
+ _write(chunk: any, encoding: any, callback: any): void;
14
+ _final(): void;
15
+ [util.inspect.custom](): string;
16
+ }
17
+ export type StreamFunctionContents<F = Buffer | ArrayBuffer | string> = {
18
+ contents: F;
19
+ payload?: any;
20
+ mimeType?: string;
21
+ fileName?: string;
22
+ };
23
+ export type StreamFunctionStream = {
24
+ contents: Readable | Duplex;
25
+ payload?: any;
26
+ size: number;
27
+ mimeType?: string;
28
+ fileName?: string;
29
+ extension?: string;
30
+ } | {
31
+ contents: BasedDataStream;
32
+ payload?: any;
33
+ size?: number;
34
+ mimeType?: string;
35
+ fileName?: string;
36
+ extension?: string;
37
+ };
38
+ export type StreamFunctionOpts = StreamFunctionContents | StreamFunctionStream;
39
+ export declare const isStreamFunctionOpts: (opts: StreamFunctionContents | StreamFunctionStream) => opts is StreamFunctionStream;
package/dist/stream.js ADDED
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isStreamFunctionOpts = exports.BasedDataStream = void 0;
7
+ const stream_1 = require("stream");
8
+ const node_util_1 = __importDefault(require("node:util"));
9
+ // prob want to move this to based functions
10
+ class BasedDataStream extends stream_1.Duplex {
11
+ constructor(size) {
12
+ super();
13
+ this.size = 0;
14
+ this.receivedBytes = 0;
15
+ this.size = size;
16
+ this.emit('progress', 0);
17
+ }
18
+ _read() { }
19
+ _write(chunk, encoding, callback) {
20
+ this.receivedBytes += chunk.byteLength;
21
+ if (this.size && this.size > 20000) {
22
+ if (!this.progessTimer) {
23
+ this.progessTimer = setTimeout(() => {
24
+ const progress = this.receivedBytes / this.size;
25
+ this.emit('progress', progress);
26
+ this.progessTimer = null;
27
+ }, 200);
28
+ }
29
+ }
30
+ this.push(Buffer.from(chunk, encoding));
31
+ callback();
32
+ }
33
+ _final() {
34
+ if (!this.size) {
35
+ this.size = this.receivedBytes;
36
+ }
37
+ this.receivedBytes = this.size;
38
+ if (this.progessTimer) {
39
+ clearTimeout(this.progessTimer);
40
+ this.progessTimer = null;
41
+ }
42
+ this.emit('progress', 1);
43
+ this.push(null);
44
+ }
45
+ [node_util_1.default.inspect.custom]() {
46
+ if (this.size) {
47
+ const rb = this.receivedBytes < 1000
48
+ ? Math.round(this.receivedBytes / 1024) + 'kb'
49
+ : Math.round(this.receivedBytes / 1024 / 1024) + 'mb';
50
+ return `[BasedStream ${~~((this.receivedBytes / this.size) *
51
+ 100)}% ${rb}]`;
52
+ }
53
+ else {
54
+ return `[BasedStream]`;
55
+ }
56
+ }
57
+ }
58
+ exports.BasedDataStream = BasedDataStream;
59
+ const isStreamFunctionOpts = (opts) => {
60
+ return opts.contents instanceof stream_1.Duplex || opts.contents instanceof stream_1.Readable;
61
+ };
62
+ exports.isStreamFunctionOpts = isStreamFunctionOpts;
63
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":";;;;;;AAAA,mCAAyC;AACzC,0DAA4B;AAE5B,4CAA4C;AAC5C,MAAa,eAAgB,SAAQ,eAAM;IAKzC,YAAY,IAAY;QACtB,KAAK,EAAE,CAAA;QALF,SAAI,GAAW,CAAC,CAAA;QAChB,kBAAa,GAAW,CAAC,CAAA;QAK9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;IAC1B,CAAC;IAED,KAAK,KAAI,CAAC;IAEV,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ;QAC9B,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC,UAAU,CAAA;QACtC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,EAAE;YAClC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;gBACtB,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;oBAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAA;oBAC/C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;oBAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;gBAC1B,CAAC,EAAE,GAAG,CAAC,CAAA;aACR;SACF;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAA;QACvC,QAAQ,EAAE,CAAA;IACZ,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,aAAa,CAAA;SAC/B;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAA;QAC9B,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;SACzB;QACD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;QACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjB,CAAC;IAED,CAAC,mBAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACnB,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,MAAM,EAAE,GACN,IAAI,CAAC,aAAa,GAAG,IAAI;gBACvB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,IAAI;gBAC9C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;YAEzD,OAAO,gBAAgB,CAAC,CAAC,CACvB,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC;gBAChC,GAAG,CACJ,KAAK,EAAE,GAAG,CAAA;SACZ;aAAM;YACL,OAAO,eAAe,CAAA;SACvB;IACH,CAAC;CACF;AAxDD,0CAwDC;AA8BM,MAAM,oBAAoB,GAAG,CAClC,IAAmD,EACrB,EAAE;IAChC,OAAO,IAAI,CAAC,QAAQ,YAAY,eAAM,IAAI,IAAI,CAAC,QAAQ,YAAY,iBAAQ,CAAA;AAC7E,CAAC,CAAA;AAJY,QAAA,oBAAoB,wBAIhC"}