effect-zero 0.5.0 → 0.6.0-beta.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 (76) hide show
  1. package/README.md +56 -38
  2. package/dist/client-transaction.d.ts +11 -9
  3. package/dist/client-transaction.d.ts.map +1 -1
  4. package/dist/client-transaction.js +4 -1
  5. package/dist/client-transaction.js.map +1 -1
  6. package/dist/client.d.ts +68 -66
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +7 -10
  9. package/dist/client.js.map +1 -1
  10. package/dist/client.test.d.ts +2 -0
  11. package/dist/client.test.d.ts.map +1 -0
  12. package/dist/client.test.js +19 -0
  13. package/dist/client.test.js.map +1 -0
  14. package/dist/internal/server-synchronization-context.d.ts.map +1 -1
  15. package/dist/internal/server-synchronization-context.js +2 -2
  16. package/dist/internal/server-synchronization-context.js.map +1 -1
  17. package/dist/internal/server.d.ts +13 -28
  18. package/dist/internal/server.d.ts.map +1 -1
  19. package/dist/internal/server.js +5 -19
  20. package/dist/internal/server.js.map +1 -1
  21. package/dist/internal/server.test.js +5 -3
  22. package/dist/internal/server.test.js.map +1 -1
  23. package/dist/server-transaction.d.ts +82 -109
  24. package/dist/server-transaction.d.ts.map +1 -1
  25. package/dist/server-transaction.js +26 -74
  26. package/dist/server-transaction.js.map +1 -1
  27. package/dist/server.d.ts +207 -354
  28. package/dist/server.d.ts.map +1 -1
  29. package/dist/server.js +60 -80
  30. package/dist/server.js.map +1 -1
  31. package/dist/types/ast.d.ts +4 -0
  32. package/dist/types/ast.d.ts.map +1 -0
  33. package/dist/types/ast.js +4 -0
  34. package/dist/types/ast.js.map +1 -0
  35. package/dist/types/{queries.d.ts → custom-queries.d.ts} +19 -1
  36. package/dist/types/custom-queries.d.ts.map +1 -0
  37. package/dist/types/{queries.js → custom-queries.js} +5 -6
  38. package/dist/types/custom-queries.js.map +1 -0
  39. package/dist/types/mutate-server.d.ts +160 -0
  40. package/dist/types/mutate-server.d.ts.map +1 -0
  41. package/dist/types/mutate-server.js +29 -0
  42. package/dist/types/mutate-server.js.map +1 -0
  43. package/dist/types/mutation-id.d.ts +7 -0
  44. package/dist/types/mutation-id.d.ts.map +1 -0
  45. package/dist/types/mutation-id.js +8 -0
  46. package/dist/types/mutation-id.js.map +1 -0
  47. package/dist/types/mutation.d.ts +79 -0
  48. package/dist/types/mutation.d.ts.map +1 -0
  49. package/dist/types/mutation.js +125 -0
  50. package/dist/types/mutation.js.map +1 -0
  51. package/dist/types/push.d.ts +100 -85
  52. package/dist/types/push.d.ts.map +1 -1
  53. package/dist/types/push.js +7 -134
  54. package/dist/types/push.js.map +1 -1
  55. package/dist/types/query-server.d.ts +144 -0
  56. package/dist/types/query-server.d.ts.map +1 -0
  57. package/dist/types/query-server.js +19 -0
  58. package/dist/types/query-server.js.map +1 -0
  59. package/dist/types.test.js +4 -4
  60. package/dist/types.test.js.map +1 -1
  61. package/package.json +35 -5
  62. package/src/client-transaction.ts +5 -1
  63. package/src/client.ts +14 -15
  64. package/src/internal/server-synchronization-context.ts +37 -39
  65. package/src/internal/server.ts +8 -31
  66. package/src/server-transaction.ts +55 -101
  67. package/src/server.ts +147 -151
  68. package/src/types/ast.ts +4 -0
  69. package/src/types/{queries.ts → custom-queries.ts} +4 -6
  70. package/src/types/mutate-server.ts +37 -0
  71. package/src/types/mutation-id.ts +10 -0
  72. package/src/types/mutation.ts +155 -0
  73. package/src/types/push.ts +7 -167
  74. package/src/types/query-server.ts +27 -0
  75. package/dist/types/queries.d.ts.map +0 -1
  76. package/dist/types/queries.js.map +0 -1
@@ -0,0 +1,155 @@
1
+ import * as Schema from "effect/Schema";
2
+ import { JsonSchema } from "./common.js";
3
+ import { MutationId } from "./mutation-id.js";
4
+
5
+ // The code below was converted to Effect Schema from:
6
+ // https://github.com/rocicorp/mono/blob/74273167af5d15ed07045e04165cb04d3983d44f/packages/zero-protocol/src/mutation.ts
7
+
8
+ const PrimaryKey = Schema.NonEmptyArray(Schema.String);
9
+
10
+ const PrimaryKeyValue = Schema.Union([Schema.String, Schema.Number, Schema.Boolean]);
11
+
12
+ const PrimaryKeyValueRecord = Schema.Record(Schema.String, PrimaryKeyValue);
13
+
14
+ const Value = Schema.Union([JsonSchema, Schema.Undefined]);
15
+ const Row = Schema.Record(Schema.String, Value);
16
+
17
+ const CRUD_MUTATION_NAME = "_zero_crud";
18
+
19
+ // biome-ignore lint/correctness/noUnusedVariables: borrowed code
20
+ const CLEANUP_RESULTS_MUTATION_NAME = "_zero_cleanupResults";
21
+
22
+ // biome-ignore lint/correctness/noUnusedVariables: borrowed code
23
+ const CleanupResultsArg = Schema.Union([
24
+ // Legacy format (no type field) - treat as single
25
+ Schema.Struct({
26
+ clientGroupID: Schema.String,
27
+ clientID: Schema.String,
28
+ upToMutationID: Schema.Number,
29
+ }),
30
+ // Explicit single: delete up to a specific mutation ID for one client
31
+ Schema.Struct({
32
+ type: Schema.Literal("single"),
33
+ clientGroupID: Schema.String,
34
+ clientID: Schema.String,
35
+ upToMutationID: Schema.Number,
36
+ }),
37
+ // Bulk: delete all mutations for multiple clients
38
+ Schema.Struct({
39
+ type: Schema.Literal("bulk"),
40
+ clientGroupID: Schema.String,
41
+ clientIDs: Schema.NonEmptyArray(Schema.String),
42
+ }),
43
+ ]);
44
+
45
+ /**
46
+ * Inserts if entity with id does not already exist.
47
+ */
48
+ const InsertOp = Schema.Struct({
49
+ op: Schema.Literal("insert"),
50
+ tableName: Schema.String,
51
+ primaryKey: PrimaryKey,
52
+ value: Row,
53
+ });
54
+
55
+ /**
56
+ * Upsert semantics. Inserts if entity with id does not already exist,
57
+ * otherwise updates existing entity with id.
58
+ */
59
+ const UpsertOp = Schema.Struct({
60
+ op: Schema.Literal("upsert"),
61
+ tableName: Schema.String,
62
+ primaryKey: PrimaryKey,
63
+ value: Row,
64
+ });
65
+
66
+ /**
67
+ * Updates if entity with id exists, otherwise does nothing.
68
+ */
69
+ const UpdateOp = Schema.Struct({
70
+ op: Schema.Literal("update"),
71
+ tableName: Schema.String,
72
+ primaryKey: PrimaryKey,
73
+ // Partial value with at least the primary key fields
74
+ value: Row,
75
+ });
76
+
77
+ /**
78
+ * Deletes entity with id if it exists, otherwise does nothing.
79
+ */
80
+ const DeleteOp = Schema.Struct({
81
+ op: Schema.Literal("delete"),
82
+ tableName: Schema.String,
83
+ primaryKey: PrimaryKey,
84
+ // Partial value representing the primary key
85
+ value: PrimaryKeyValueRecord,
86
+ });
87
+
88
+ const CrudOp = Schema.Union([InsertOp, UpsertOp, UpdateOp, DeleteOp]);
89
+
90
+ const CrudArg = Schema.Struct({
91
+ ops: Schema.Array(CrudOp),
92
+ });
93
+
94
+ const CrudArgs = Schema.Tuple([CrudArg]);
95
+
96
+ const CrudMutation = Schema.Struct({
97
+ type: Schema.Literal("crud"),
98
+ id: Schema.Number,
99
+ clientID: Schema.String,
100
+ name: Schema.Literal(CRUD_MUTATION_NAME),
101
+ args: CrudArgs,
102
+ timestamp: Schema.Number,
103
+ });
104
+
105
+ const CustomMutation = Schema.Struct({
106
+ type: Schema.Literal("custom"),
107
+ id: Schema.Number,
108
+ clientID: Schema.String,
109
+ name: Schema.String,
110
+ args: Schema.Array(JsonSchema),
111
+ timestamp: Schema.Number,
112
+ });
113
+
114
+ export const Mutation = Schema.Union([CrudMutation, CustomMutation]);
115
+ export type Mutation = typeof Mutation.Type;
116
+
117
+ export const AppError = Schema.Struct({
118
+ error: Schema.Literal("app"),
119
+ // The user can return any additional data here
120
+ message: Schema.optional(Schema.String),
121
+ details: Schema.optional(JsonSchema),
122
+ });
123
+
124
+ export type AppError = typeof AppError.Type;
125
+
126
+ export const ZeroError = Schema.Struct({
127
+ error: Schema.Literals([
128
+ /** @deprecated push oooMutation errors are now represented as ['error', { ... }] messages */
129
+ "oooMutation",
130
+ "alreadyProcessed",
131
+ ]),
132
+ details: Schema.optional(JsonSchema),
133
+ });
134
+
135
+ export type ZeroError = typeof ZeroError.Type;
136
+
137
+ const MutationOk = Schema.Struct({
138
+ // The user can return any additional data here
139
+ data: Schema.optional(JsonSchema),
140
+ });
141
+
142
+ const MutationError = Schema.Union([AppError, ZeroError]);
143
+
144
+ export const MutationResult = Schema.Union([
145
+ // We flip the original order here as otherwise values of type MutationError would get parsed as MutationOk with empty `data`
146
+ MutationError,
147
+ MutationOk,
148
+ ]);
149
+ export type MutationResult = typeof MutationResult.Type;
150
+
151
+ export const MutationResponse = Schema.Struct({
152
+ id: MutationId,
153
+ result: MutationResult,
154
+ });
155
+ export type MutationResponse = typeof MutationResponse.Type;
package/src/types/push.ts CHANGED
@@ -1,118 +1,10 @@
1
1
  import * as Schema from "effect/Schema";
2
- import { JsonSchema } from "./common.js";
3
2
  import { PushFailedBody } from "./error.js";
3
+ import { Mutation, MutationResponse } from "./mutation.js";
4
+ import { MutationId } from "./mutation-id.js";
4
5
 
5
6
  // The code below was converted to Effect Schema from:
6
- // https://github.com/rocicorp/mono/blob/8e0f600fb3a9185facf60cfd4971d260b266690e/packages/zero-protocol/src/push.ts
7
-
8
- const PrimaryKey = Schema.Array(Schema.String);
9
-
10
- const PrimaryKeyValue = Schema.Union([Schema.String, Schema.Number, Schema.Boolean]);
11
-
12
- const PrimaryKeyValueRecord = Schema.Record(Schema.String, PrimaryKeyValue);
13
-
14
- const Value = Schema.Union([JsonSchema, Schema.Undefined]);
15
- const Row = Schema.Record(Schema.String, Value);
16
-
17
- const CRUD_MUTATION_NAME = "_zero_crud";
18
-
19
- // biome-ignore lint/correctness/noUnusedVariables: borrowed code
20
- const CLEANUP_RESULTS_MUTATION_NAME = "_zero_cleanupResults";
21
-
22
- // biome-ignore lint/correctness/noUnusedVariables: borrowed code
23
- const CleanupResultsArg = Schema.Union([
24
- // Legacy format (no type field) - treat as single
25
- Schema.Struct({
26
- clientGroupID: Schema.String,
27
- clientID: Schema.String,
28
- upToMutationID: Schema.Number,
29
- }),
30
- // Explicit single: delete up to a specific mutation ID for one client
31
- Schema.Struct({
32
- type: Schema.Literal("single"),
33
- clientGroupID: Schema.String,
34
- clientID: Schema.String,
35
- upToMutationID: Schema.Number,
36
- }),
37
- // Bulk: delete all mutations for multiple clients
38
- Schema.Struct({
39
- type: Schema.Literal("bulk"),
40
- clientGroupID: Schema.String,
41
- clientIDs: Schema.NonEmptyArray(Schema.String),
42
- }),
43
- ]);
44
-
45
- /**
46
- * Inserts if entity with id does not already exist.
47
- */
48
- const InsertOp = Schema.Struct({
49
- op: Schema.Literal("insert"),
50
- tableName: Schema.String,
51
- primaryKey: PrimaryKey,
52
- value: Row,
53
- });
54
-
55
- /**
56
- * Upsert semantics. Inserts if entity with id does not already exist,
57
- * otherwise updates existing entity with id.
58
- */
59
- const UpsertOp = Schema.Struct({
60
- op: Schema.Literal("upsert"),
61
- tableName: Schema.String,
62
- primaryKey: PrimaryKey,
63
- value: Row,
64
- });
65
-
66
- /**
67
- * Updates if entity with id exists, otherwise does nothing.
68
- */
69
- const UpdateOp = Schema.Struct({
70
- op: Schema.Literal("update"),
71
- tableName: Schema.String,
72
- primaryKey: PrimaryKey,
73
- // Partial value with at least the primary key fields
74
- value: Row,
75
- });
76
-
77
- /**
78
- * Deletes entity with id if it exists, otherwise does nothing.
79
- */
80
- const DeleteOp = Schema.Struct({
81
- op: Schema.Literal("delete"),
82
- tableName: Schema.String,
83
- primaryKey: PrimaryKey,
84
- // Partial value representing the primary key
85
- value: PrimaryKeyValueRecord,
86
- });
87
-
88
- const CrudOp = Schema.Union([InsertOp, UpsertOp, UpdateOp, DeleteOp]);
89
-
90
- const CrudArg = Schema.Struct({
91
- ops: Schema.Array(CrudOp),
92
- });
93
-
94
- const CrudArgs = Schema.Tuple([CrudArg]);
95
-
96
- const CrudMutation = Schema.Struct({
97
- type: Schema.Literal("crud"),
98
- id: Schema.Number,
99
- clientID: Schema.String,
100
- name: Schema.Literal(CRUD_MUTATION_NAME),
101
- args: CrudArgs,
102
- timestamp: Schema.Number,
103
- });
104
-
105
- const CustomMutation = Schema.Struct({
106
- type: Schema.Literal("custom"),
107
- id: Schema.Number,
108
- clientID: Schema.String,
109
- name: Schema.String,
110
- args: Schema.Array(JsonSchema),
111
- timestamp: Schema.Number,
112
- });
113
-
114
- export const Mutation = Schema.Union([CrudMutation, CustomMutation]);
115
- export type Mutation = typeof Mutation.Type;
7
+ // https://github.com/rocicorp/mono/blob/74273167af5d15ed07045e04165cb04d3983d44f/packages/zero-protocol/src/push.ts
116
8
 
117
9
  export const PushBody = Schema.Struct({
118
10
  clientGroupID: Schema.String,
@@ -129,57 +21,14 @@ export const PushBody = Schema.Struct({
129
21
  * and should not be included in push messages.
130
22
  */
131
23
  auth: Schema.optional(Schema.String),
24
+ /** W3C traceparent header for distributed tracing. */
25
+ traceparent: Schema.optional(Schema.String),
132
26
  });
133
27
  export type PushBody = typeof PushBody.Type;
134
28
 
135
29
  // biome-ignore lint/correctness/noUnusedVariables: borrowed code
136
30
  const PushMessage = Schema.Tuple([Schema.Literal("push"), PushBody]);
137
31
 
138
- const MutationId = Schema.Struct({
139
- id: Schema.Number,
140
- clientID: Schema.String,
141
- });
142
-
143
- export const AppError = Schema.Struct({
144
- error: Schema.Literal("app"),
145
- // The user can return any additional data here
146
- message: Schema.optional(Schema.String),
147
- details: Schema.optional(JsonSchema),
148
- });
149
-
150
- export type AppError = typeof AppError.Type;
151
-
152
- export const ZeroError = Schema.Struct({
153
- error: Schema.Literals([
154
- /** @deprecated push oooMutation errors are now represented as ['error', { ... }] messages */
155
- "oooMutation",
156
- "alreadyProcessed",
157
- ]),
158
- details: Schema.optional(JsonSchema),
159
- });
160
-
161
- export type ZeroError = typeof ZeroError.Type;
162
-
163
- const MutationOk = Schema.Struct({
164
- // The user can return any additional data here
165
- data: Schema.optional(JsonSchema),
166
- });
167
-
168
- const MutationError = Schema.Union([AppError, ZeroError]);
169
-
170
- export const MutationResult = Schema.Union([
171
- // We flip the original order here as otherwise values of type MutationError would get parsed as MutationOk with empty `data`
172
- MutationError,
173
- MutationOk,
174
- ]);
175
- export type MutationResult = typeof MutationResult.Type;
176
-
177
- export const MutationResponse = Schema.Struct({
178
- id: MutationId,
179
- result: MutationResult,
180
- });
181
- export type MutationResponse = typeof MutationResponse.Type;
182
-
183
32
  const PushOk = Schema.Struct({
184
33
  mutations: Schema.Array(MutationResponse),
185
34
  });
@@ -233,9 +82,9 @@ const ZeroPusherError = Schema.Struct({
233
82
  /**
234
83
  * @deprecated push errors are now represented as ['error', { ... }] messages
235
84
  */
236
- const PushError = Schema.Union([UnsupportedPushVersion, UnsupportedSchemaVersion, HttpError, ZeroPusherError]);
85
+ export const PushError = Schema.Union([UnsupportedPushVersion, UnsupportedSchemaVersion, HttpError, ZeroPusherError]);
237
86
 
238
- const PushResponseBody = Schema.Union([PushOk, PushError]);
87
+ export const PushResponseBody = Schema.Union([PushOk, PushError]);
239
88
 
240
89
  export const PushResponse = Schema.Union([PushResponseBody, PushFailedBody]);
241
90
  export type PushResponse = typeof PushResponse.Type;
@@ -245,12 +94,3 @@ const PushResponseMessage = Schema.Tuple([Schema.Literal("pushResponse"), PushRe
245
94
 
246
95
  // biome-ignore lint/correctness/noUnusedVariables: borrowed code
247
96
  const AckMutationResponsesMessage = Schema.Tuple([Schema.Literal("ackMutationResponses"), MutationId]);
248
-
249
- /**
250
- * The schema for the querystring parameters of the custom push endpoint.
251
- */
252
- export const PushParams = Schema.Struct({
253
- schema: Schema.String,
254
- appID: Schema.String,
255
- });
256
- export type PushParams = typeof PushParams.Type;
@@ -0,0 +1,27 @@
1
+ import * as Schema from "effect/Schema";
2
+ import { ErroredQuery, TransformedQuery, TransformResponseMessage } from "./custom-queries.js";
3
+ import { TransformFailedBody } from "./error.js";
4
+
5
+ // The code below was converted to Effect Schema from:
6
+ // https://github.com/rocicorp/mono/blob/74273167af5d15ed07045e04165cb04d3983d44f/packages/zero-protocol/src/query-server.ts
7
+
8
+ export const QueryResult = Schema.Union([TransformedQuery, ErroredQuery]);
9
+ export type QueryResult = typeof QueryResult.Type;
10
+
11
+ export const QueryResponseBody = Schema.Array(QueryResult);
12
+ export type QueryResponseBody = typeof QueryResponseBody.Type;
13
+
14
+ export const QuerySuccess = Schema.Struct({
15
+ kind: Schema.Literal("QueryResponse"),
16
+ userID: Schema.optional(Schema.NullOr(Schema.String)),
17
+ queries: QueryResponseBody,
18
+ });
19
+ export type QuerySuccess = typeof QuerySuccess.Type;
20
+
21
+ export const QueryResponse = Schema.Union([
22
+ QuerySuccess,
23
+ TransformFailedBody,
24
+ // for backwards compatibility
25
+ TransformResponseMessage,
26
+ ]);
27
+ export type QueryResponse = typeof QueryResponse.Type;
@@ -1 +0,0 @@
1
- {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/types/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AA6CxC,eAAO,MAAM,uBAAuB;;;;KAAoE,CAAC;AACzG,MAAM,MAAM,uBAAuB,GAAG,OAAO,uBAAuB,CAAC,IAAI,CAAC;AAS1E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAA6D,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/types/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,sDAAsD;AACtD,8HAA8H;AAE9H,uCAAuC;AACvC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;AAE3B,MAAM,oBAAoB,GAAG,MAAM,CAAC,KAAK,CACvC,MAAM,CAAC,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;CAC/B,CAAC,CACH,CAAC;AAEF,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,GAAG,EAAE,GAAG;CACT,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;IAC9B,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAExE,MAAM,qBAAqB,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AAE3F,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAGzG,iEAAiE;AACjE,MAAM,qBAAqB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAE3G,MAAM,sBAAsB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAEtG,MAAM,kBAAkB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC;AAEhG,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC,CAAC"}