@stratasync/client 0.2.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.
- package/README.md +76 -0
- package/dist/client.d.ts +11 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +759 -0
- package/dist/client.js.map +1 -0
- package/dist/history-manager.d.ts +45 -0
- package/dist/history-manager.d.ts.map +1 -0
- package/dist/history-manager.js +266 -0
- package/dist/history-manager.js.map +1 -0
- package/dist/identity-map.d.ts +127 -0
- package/dist/identity-map.d.ts.map +1 -0
- package/dist/identity-map.js +295 -0
- package/dist/identity-map.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/outbox-manager.d.ts +122 -0
- package/dist/outbox-manager.d.ts.map +1 -0
- package/dist/outbox-manager.js +373 -0
- package/dist/outbox-manager.js.map +1 -0
- package/dist/query.d.ts +7 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +36 -0
- package/dist/query.js.map +1 -0
- package/dist/sync-orchestrator.d.ts +208 -0
- package/dist/sync-orchestrator.d.ts.map +1 -0
- package/dist/sync-orchestrator.js +1287 -0
- package/dist/sync-orchestrator.js.map +1 -0
- package/dist/types.d.ts +309 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +14 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +26 -0
- package/dist/utils.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
const DEFAULT_IDENTITY_MAP_MAX_SIZE = 10_000;
|
|
2
|
+
const isModelInstanceLike = (value) => {
|
|
3
|
+
if (!value || typeof value !== "object") {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
const record = value;
|
|
7
|
+
return (typeof record._applyUpdate === "function" ||
|
|
8
|
+
typeof record.makeObservable === "function");
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Identity map for managing model instances
|
|
12
|
+
* Ensures only one instance exists per model+id combination
|
|
13
|
+
*/
|
|
14
|
+
export class IdentityMap {
|
|
15
|
+
map;
|
|
16
|
+
modelName;
|
|
17
|
+
reactivity;
|
|
18
|
+
maxSize;
|
|
19
|
+
accessOrder = new Map();
|
|
20
|
+
accessTick = 0;
|
|
21
|
+
modelFactory;
|
|
22
|
+
constructor(modelName, reactivity, modelFactory, maxSize = DEFAULT_IDENTITY_MAP_MAX_SIZE) {
|
|
23
|
+
this.modelName = modelName;
|
|
24
|
+
this.reactivity = reactivity;
|
|
25
|
+
this.modelFactory = modelFactory;
|
|
26
|
+
this.maxSize = maxSize;
|
|
27
|
+
this.map = reactivity.createMap(undefined, {
|
|
28
|
+
name: `IdentityMap:${modelName}`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
setModelFactory(modelFactory) {
|
|
32
|
+
this.modelFactory = modelFactory;
|
|
33
|
+
}
|
|
34
|
+
// eslint-disable-next-line class-methods-use-this -- references generic type T
|
|
35
|
+
ensureObservable(instance) {
|
|
36
|
+
if (isModelInstanceLike(instance) &&
|
|
37
|
+
typeof instance.makeObservable === "function") {
|
|
38
|
+
instance.makeObservable();
|
|
39
|
+
}
|
|
40
|
+
return instance;
|
|
41
|
+
}
|
|
42
|
+
toInstance(data) {
|
|
43
|
+
if (!this.modelFactory || isModelInstanceLike(data)) {
|
|
44
|
+
return this.ensureObservable(data);
|
|
45
|
+
}
|
|
46
|
+
const instance = this.modelFactory(this.modelName, data);
|
|
47
|
+
return this.ensureObservable(instance);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Gets a model instance by ID
|
|
51
|
+
*/
|
|
52
|
+
get(id) {
|
|
53
|
+
const value = this.map.get(id);
|
|
54
|
+
if (value) {
|
|
55
|
+
this.touch(id);
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Checks if a model instance exists
|
|
61
|
+
*/
|
|
62
|
+
has(id) {
|
|
63
|
+
return this.map.has(id);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Sets a model instance, replacing any existing instance
|
|
67
|
+
*/
|
|
68
|
+
set(id, instance) {
|
|
69
|
+
this.reactivity.runInAction(() => {
|
|
70
|
+
this.map.set(id, this.toInstance(instance));
|
|
71
|
+
this.touch(id);
|
|
72
|
+
this.evictIfNeeded();
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Updates an existing model instance in place
|
|
77
|
+
*/
|
|
78
|
+
update(id, changes) {
|
|
79
|
+
const existing = this.map.get(id);
|
|
80
|
+
if (!existing) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
this.reactivity.runInAction(() => {
|
|
84
|
+
this.applyChanges(existing, changes);
|
|
85
|
+
this.touch(id);
|
|
86
|
+
});
|
|
87
|
+
return existing;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Merges data into an existing instance or creates a new one
|
|
91
|
+
*/
|
|
92
|
+
merge(id, data) {
|
|
93
|
+
return this.reactivity.runInAction(() => {
|
|
94
|
+
const existing = this.map.get(id);
|
|
95
|
+
if (existing) {
|
|
96
|
+
this.applyChanges(existing, data);
|
|
97
|
+
this.touch(id);
|
|
98
|
+
return existing;
|
|
99
|
+
}
|
|
100
|
+
const merged = this.toInstance(data);
|
|
101
|
+
this.map.set(id, merged);
|
|
102
|
+
this.touch(id);
|
|
103
|
+
this.evictIfNeeded();
|
|
104
|
+
return merged;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Deletes a model instance
|
|
109
|
+
*/
|
|
110
|
+
delete(id) {
|
|
111
|
+
return this.reactivity.runInAction(() => {
|
|
112
|
+
this.accessOrder.delete(id);
|
|
113
|
+
return this.map.delete(id);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Clears all model instances
|
|
118
|
+
*/
|
|
119
|
+
clear() {
|
|
120
|
+
this.reactivity.runInAction(() => {
|
|
121
|
+
this.map.clear();
|
|
122
|
+
this.accessOrder.clear();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Gets all model instances
|
|
127
|
+
*/
|
|
128
|
+
values() {
|
|
129
|
+
return [...this.map.values()];
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Gets all model IDs
|
|
133
|
+
*/
|
|
134
|
+
keys() {
|
|
135
|
+
return [...this.map.keys()];
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Gets all entries
|
|
139
|
+
*/
|
|
140
|
+
entries() {
|
|
141
|
+
return [...this.map.entries()];
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Gets the number of instances
|
|
145
|
+
*/
|
|
146
|
+
get size() {
|
|
147
|
+
return this.map.size;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Iterates over all instances
|
|
151
|
+
*/
|
|
152
|
+
// oxlint-disable-next-line prefer-await-to-callbacks -- event listener registration
|
|
153
|
+
forEach(callback) {
|
|
154
|
+
// oxlint-disable-next-line no-array-for-each
|
|
155
|
+
this.map.forEach(callback);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Finds an instance matching a predicate
|
|
159
|
+
*/
|
|
160
|
+
find(predicate) {
|
|
161
|
+
for (const value of this.map.values()) {
|
|
162
|
+
if (predicate(value)) {
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Filters instances matching a predicate
|
|
170
|
+
*/
|
|
171
|
+
filter(predicate) {
|
|
172
|
+
return this.values().filter(predicate);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Gets the model name
|
|
176
|
+
*/
|
|
177
|
+
getModelName() {
|
|
178
|
+
return this.modelName;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Gets the underlying map (for advanced usage)
|
|
182
|
+
*/
|
|
183
|
+
getRawMap() {
|
|
184
|
+
return new Map(this.map.entries());
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Applies changes to an existing instance, preserving identity
|
|
188
|
+
*/
|
|
189
|
+
// eslint-disable-next-line class-methods-use-this -- references generic type T
|
|
190
|
+
applyChanges(target, changes) {
|
|
191
|
+
const candidate = target;
|
|
192
|
+
if (typeof candidate._applyUpdate === "function") {
|
|
193
|
+
candidate._applyUpdate(changes);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
for (const key of Object.keys(changes)) {
|
|
197
|
+
const newVal = changes[key];
|
|
198
|
+
const oldVal = target[key];
|
|
199
|
+
if (!Object.is(oldVal, newVal)) {
|
|
200
|
+
target[key] = newVal;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
touch(id) {
|
|
205
|
+
this.accessTick += 1;
|
|
206
|
+
this.accessOrder.set(id, this.accessTick);
|
|
207
|
+
}
|
|
208
|
+
evictIfNeeded() {
|
|
209
|
+
if (!Number.isFinite(this.maxSize) || this.maxSize <= 0) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
while (this.map.size > this.maxSize) {
|
|
213
|
+
let oldestKey = null;
|
|
214
|
+
let oldestAccess = Number.POSITIVE_INFINITY;
|
|
215
|
+
for (const [key, accessTick] of this.accessOrder.entries()) {
|
|
216
|
+
if (accessTick >= oldestAccess) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
oldestKey = key;
|
|
220
|
+
oldestAccess = accessTick;
|
|
221
|
+
}
|
|
222
|
+
if (!oldestKey) {
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
this.accessOrder.delete(oldestKey);
|
|
226
|
+
this.map.delete(oldestKey);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Manages identity maps for all model types
|
|
232
|
+
*/
|
|
233
|
+
export class IdentityMapRegistry {
|
|
234
|
+
maps = new Map();
|
|
235
|
+
reactivity;
|
|
236
|
+
maxSize;
|
|
237
|
+
modelFactory;
|
|
238
|
+
constructor(reactivity, modelFactory, maxSize = DEFAULT_IDENTITY_MAP_MAX_SIZE) {
|
|
239
|
+
this.reactivity = reactivity;
|
|
240
|
+
this.modelFactory = modelFactory;
|
|
241
|
+
this.maxSize = maxSize;
|
|
242
|
+
}
|
|
243
|
+
setModelFactory(modelFactory) {
|
|
244
|
+
this.modelFactory = modelFactory;
|
|
245
|
+
for (const map of this.maps.values()) {
|
|
246
|
+
map.setModelFactory(modelFactory);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Gets or creates an identity map for a model type
|
|
251
|
+
*/
|
|
252
|
+
getMap(modelName) {
|
|
253
|
+
let map = this.maps.get(modelName);
|
|
254
|
+
if (!map) {
|
|
255
|
+
map = new IdentityMap(modelName, this.reactivity, this.modelFactory, this.maxSize);
|
|
256
|
+
this.maps.set(modelName, map);
|
|
257
|
+
}
|
|
258
|
+
return map;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Checks if a map exists for a model type
|
|
262
|
+
*/
|
|
263
|
+
hasMap(modelName) {
|
|
264
|
+
return this.maps.has(modelName);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Clears all identity maps
|
|
268
|
+
*/
|
|
269
|
+
clearAll() {
|
|
270
|
+
for (const map of this.maps.values()) {
|
|
271
|
+
map.clear();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Clears a specific identity map
|
|
276
|
+
*/
|
|
277
|
+
clear(modelName) {
|
|
278
|
+
this.maps.get(modelName)?.clear();
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Gets all model names with identity maps
|
|
282
|
+
*/
|
|
283
|
+
getModelNames() {
|
|
284
|
+
return [...this.maps.keys()];
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Executes a callback inside a single reactivity action.
|
|
288
|
+
* All identity map mutations within the callback are batched —
|
|
289
|
+
* observers only see the final state after the callback returns.
|
|
290
|
+
*/
|
|
291
|
+
batch(fn) {
|
|
292
|
+
return this.reactivity.runInAction(fn);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=identity-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-map.js","sourceRoot":"","sources":["../src/identity-map.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { createSyncClient } from "./client.js";
|
|
2
|
+
export type { BatchOperation, ModelPersistenceMeta, QueryOptions, QueryResult, StorageAdapter, StorageMeta, StorageOptions, SyncClient, SyncClientEvent, TransportAdapter, } from "./types.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { ArchiveTransactionOptions, SyncId, Transaction, UnarchiveTransactionOptions } from "@stratasync/core";
|
|
2
|
+
import type { StorageAdapter, TransportAdapter } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for the outbox manager
|
|
5
|
+
*/
|
|
6
|
+
export interface OutboxManagerOptions {
|
|
7
|
+
/** Storage adapter for persisting transactions */
|
|
8
|
+
storage: StorageAdapter;
|
|
9
|
+
/** Transport adapter for sending transactions */
|
|
10
|
+
transport: TransportAdapter;
|
|
11
|
+
/** Client ID */
|
|
12
|
+
clientId: string;
|
|
13
|
+
/** Batch mutations together */
|
|
14
|
+
batchMutations?: boolean;
|
|
15
|
+
/** Delay before sending batch (ms) */
|
|
16
|
+
batchDelay?: number;
|
|
17
|
+
/** Maximum batch size */
|
|
18
|
+
maxBatchSize?: number;
|
|
19
|
+
/** Callback when transaction state changes */
|
|
20
|
+
onTransactionStateChange?: (tx: Transaction) => void;
|
|
21
|
+
/** Callback when transaction is rejected by server */
|
|
22
|
+
onTransactionRejected?: (tx: Transaction) => void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Manages the outbox queue of pending transactions
|
|
26
|
+
*/
|
|
27
|
+
export declare class OutboxManager {
|
|
28
|
+
private readonly storage;
|
|
29
|
+
private readonly transport;
|
|
30
|
+
private readonly clientId;
|
|
31
|
+
private readonly batchMutations;
|
|
32
|
+
private readonly batchDelay;
|
|
33
|
+
private readonly maxBatchSize;
|
|
34
|
+
private readonly onTransactionStateChange?;
|
|
35
|
+
private readonly onTransactionRejected?;
|
|
36
|
+
private pendingBatch;
|
|
37
|
+
private batchTimer;
|
|
38
|
+
private processing;
|
|
39
|
+
private processingPromise;
|
|
40
|
+
private sendQueue;
|
|
41
|
+
private lifecycleVersion;
|
|
42
|
+
/**
|
|
43
|
+
* Tracks clientTxIds created by THIS runtime instance only.
|
|
44
|
+
* Used for echo suppression so cross-tab transactions (which share
|
|
45
|
+
* IndexedDB but not this in-memory set) are not incorrectly skipped.
|
|
46
|
+
*/
|
|
47
|
+
private readonly localClientTxIds;
|
|
48
|
+
constructor(options: OutboxManagerOptions);
|
|
49
|
+
/**
|
|
50
|
+
* Queues an INSERT transaction
|
|
51
|
+
*/
|
|
52
|
+
insert(modelName: string, modelId: string, data: Record<string, unknown>): Promise<Transaction>;
|
|
53
|
+
/**
|
|
54
|
+
* Queues an UPDATE transaction
|
|
55
|
+
*/
|
|
56
|
+
update(modelName: string, modelId: string, changes: Record<string, unknown>, original: Record<string, unknown>): Promise<Transaction>;
|
|
57
|
+
/**
|
|
58
|
+
* Queues a DELETE transaction
|
|
59
|
+
*/
|
|
60
|
+
delete(modelName: string, modelId: string, original: Record<string, unknown>): Promise<Transaction>;
|
|
61
|
+
/**
|
|
62
|
+
* Queues an ARCHIVE transaction
|
|
63
|
+
*/
|
|
64
|
+
archive(modelName: string, modelId: string, options?: ArchiveTransactionOptions): Promise<Transaction>;
|
|
65
|
+
/**
|
|
66
|
+
* Queues an UNARCHIVE transaction
|
|
67
|
+
*/
|
|
68
|
+
unarchive(modelName: string, modelId: string, options?: UnarchiveTransactionOptions): Promise<Transaction>;
|
|
69
|
+
/**
|
|
70
|
+
* Queues a transaction for sending
|
|
71
|
+
*/
|
|
72
|
+
private queueTransaction;
|
|
73
|
+
/**
|
|
74
|
+
* Schedules sending the pending batch
|
|
75
|
+
*/
|
|
76
|
+
private scheduleBatchSend;
|
|
77
|
+
/**
|
|
78
|
+
* Flushes the pending batch
|
|
79
|
+
*/
|
|
80
|
+
private flushBatch;
|
|
81
|
+
private dispatchBatch;
|
|
82
|
+
private isLifecycleCurrent;
|
|
83
|
+
private waitForInflightSends;
|
|
84
|
+
/**
|
|
85
|
+
* Sends a batch of transactions
|
|
86
|
+
*/
|
|
87
|
+
private sendBatch;
|
|
88
|
+
private markTransactionsSent;
|
|
89
|
+
private handleTransportFailure;
|
|
90
|
+
/**
|
|
91
|
+
* Handles the result of a mutation batch
|
|
92
|
+
*/
|
|
93
|
+
private handleMutateResult;
|
|
94
|
+
/**
|
|
95
|
+
* Processes any pending transactions from storage (e.g., after reconnect)
|
|
96
|
+
*/
|
|
97
|
+
processPendingTransactions(): Promise<void>;
|
|
98
|
+
private doProcessPending;
|
|
99
|
+
private flushPendingBatchNow;
|
|
100
|
+
/**
|
|
101
|
+
* Gets the count of pending transactions
|
|
102
|
+
*/
|
|
103
|
+
getPendingCount(): Promise<number>;
|
|
104
|
+
/**
|
|
105
|
+
* Returns the set of clientTxIds created by this runtime instance.
|
|
106
|
+
*/
|
|
107
|
+
getLocalClientTxIds(): ReadonlySet<string>;
|
|
108
|
+
/**
|
|
109
|
+
* Completes any awaiting transactions up to the given sync ID
|
|
110
|
+
*/
|
|
111
|
+
completeUpToSyncId(lastSyncId: SyncId): Promise<number>;
|
|
112
|
+
/**
|
|
113
|
+
* Forces an immediate flush of pending batches
|
|
114
|
+
*/
|
|
115
|
+
flush(): Promise<void>;
|
|
116
|
+
dispose(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Clears all pending transactions
|
|
119
|
+
*/
|
|
120
|
+
clear(): Promise<void>;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=outbox-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox-manager.d.ts","sourceRoot":"","sources":["../src/outbox-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EAEzB,MAAM,EACN,WAAW,EACX,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAa1B,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kDAAkD;IAClD,OAAO,EAAE,cAAc,CAAC;IACxB,iDAAiD;IACjD,SAAS,EAAE,gBAAgB,CAAC;IAC5B,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IACrD,sDAAsD;IACtD,qBAAqB,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;CACnD;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAA4B;IACtE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAA4B;IAEnE,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,iBAAiB,CAA8B;IAEvD,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,gBAAgB,CAAK;IAE7B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;gBAE1C,OAAO,EAAE,oBAAoB;IAWzC;;OAEG;IACG,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,WAAW,CAAC;IAMvB;;OAEG;IACG,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,WAAW,CAAC;IAYvB;;OAEG;IACG,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,WAAW,CAAC;IAWvB;;OAEG;IACG,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,WAAW,CAAC;IAWvB;;OAEG;IACG,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,WAAW,CAAC;IAWvB;;OAEG;YACW,gBAAgB;IAc9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;OAEG;IACH,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,oBAAoB;IAI5B;;OAEG;YACW,SAAS;YA2BT,oBAAoB;YAqBpB,sBAAsB;IA6BpC;;OAEG;YACW,kBAAkB;IAmDhC;;OAEG;IACG,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;YAiBnC,gBAAgB;YAiChB,oBAAoB;IAelC;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAUxC;;OAEG;IACH,mBAAmB,IAAI,WAAW,CAAC,MAAM,CAAC;IAI1C;;OAEG;IACG,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB7D;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,OAAO,IAAI,IAAI;IAYf;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
|