@veloxts/client 0.4.7 → 0.4.9
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/dist/client.d.ts.map +1 -1
- package/dist/client.js +17 -2
- package/dist/client.js.map +1 -1
- package/dist/react/__tests__/hooks.test.js +1 -1
- package/dist/react/__tests__/hooks.test.js.map +1 -1
- package/dist/react/index.d.ts +22 -39
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +25 -40
- package/dist/react/index.js.map +1 -1
- package/dist/react/proxy-hooks.d.ts +88 -0
- package/dist/react/proxy-hooks.d.ts.map +1 -0
- package/dist/react/proxy-hooks.js +396 -0
- package/dist/react/proxy-hooks.js.map +1 -0
- package/dist/react/proxy-types.d.ts +401 -0
- package/dist/react/proxy-types.d.ts.map +1 -0
- package/dist/react/proxy-types.js +10 -0
- package/dist/react/proxy-types.js.map +1 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy-based React hooks for VeloxTS
|
|
3
|
+
*
|
|
4
|
+
* Provides tRPC-style ergonomics with full IDE autocomplete
|
|
5
|
+
* by using TypeScript mapped types and JavaScript Proxy objects.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* // Create hooks once at app level
|
|
10
|
+
* import { createVeloxHooks } from '@veloxts/client/react';
|
|
11
|
+
* import type { AppRouter } from './api-types';
|
|
12
|
+
*
|
|
13
|
+
* export const api = createVeloxHooks<AppRouter>();
|
|
14
|
+
*
|
|
15
|
+
* // Use in components with full autocomplete
|
|
16
|
+
* function UserProfile({ userId }: { userId: string }) {
|
|
17
|
+
* const queryClient = useQueryClient();
|
|
18
|
+
*
|
|
19
|
+
* const { data } = api.users.getUser.useQuery({ id: userId });
|
|
20
|
+
* const { mutate } = api.users.updateUser.useMutation({
|
|
21
|
+
* onSuccess: () => api.users.getUser.invalidate({ id: userId }, queryClient),
|
|
22
|
+
* });
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module @veloxts/client/react/proxy-hooks
|
|
27
|
+
*/
|
|
28
|
+
import { useMutation as useReactMutation, useQuery as useReactQuery, useQueryClient as useReactQueryClient, useSuspenseQuery as useReactSuspenseQuery, } from '@tanstack/react-query';
|
|
29
|
+
import { useVeloxContext } from './provider.js';
|
|
30
|
+
import { buildQueryKey } from './utils.js';
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Query/Mutation Detection
|
|
33
|
+
// ============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Determines if a procedure is a query based on naming convention
|
|
36
|
+
*
|
|
37
|
+
* Matches the logic in @veloxts/router for consistency.
|
|
38
|
+
* Procedures starting with these prefixes are queries:
|
|
39
|
+
* - get* (e.g., getUser, getProfile)
|
|
40
|
+
* - list* (e.g., listUsers, listPosts)
|
|
41
|
+
* - find* (e.g., findUsers, findByEmail)
|
|
42
|
+
*
|
|
43
|
+
* Everything else is considered a mutation.
|
|
44
|
+
*
|
|
45
|
+
* @param procedureName - The procedure name to check
|
|
46
|
+
* @returns true if the procedure is a query, false for mutation
|
|
47
|
+
*/
|
|
48
|
+
function isQueryProcedure(procedureName) {
|
|
49
|
+
const queryPrefixes = ['get', 'list', 'find'];
|
|
50
|
+
return queryPrefixes.some((prefix) => procedureName.startsWith(prefix));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Determines the mutation type from procedure name
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
function getMutationType(procedureName) {
|
|
57
|
+
if (/^(?:create|add)/.test(procedureName))
|
|
58
|
+
return 'create';
|
|
59
|
+
if (/^(?:update|edit|patch)/.test(procedureName))
|
|
60
|
+
return 'update';
|
|
61
|
+
if (/^(?:delete|remove)/.test(procedureName))
|
|
62
|
+
return 'delete';
|
|
63
|
+
return 'unknown';
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Extracts ID from mutation input for targeted invalidation
|
|
67
|
+
*
|
|
68
|
+
* Looks for common patterns:
|
|
69
|
+
* - `{ id }` - Direct id field
|
|
70
|
+
* - `{ userId }`, `{ postId }` - *Id pattern
|
|
71
|
+
* - `{ data: { id } }` - Nested in data object
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
function extractIdFromInput(input) {
|
|
76
|
+
if (!input || typeof input !== 'object')
|
|
77
|
+
return null;
|
|
78
|
+
const obj = input;
|
|
79
|
+
// Direct id field
|
|
80
|
+
if (typeof obj.id === 'string')
|
|
81
|
+
return obj.id;
|
|
82
|
+
if (typeof obj.id === 'number')
|
|
83
|
+
return String(obj.id);
|
|
84
|
+
// *Id pattern (userId, postId, etc.)
|
|
85
|
+
for (const key of Object.keys(obj)) {
|
|
86
|
+
if (key.endsWith('Id') && (typeof obj[key] === 'string' || typeof obj[key] === 'number')) {
|
|
87
|
+
return String(obj[key]);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Nested in data
|
|
91
|
+
if (obj.data && typeof obj.data === 'object') {
|
|
92
|
+
const data = obj.data;
|
|
93
|
+
if (typeof data.id === 'string')
|
|
94
|
+
return data.id;
|
|
95
|
+
if (typeof data.id === 'number')
|
|
96
|
+
return String(data.id);
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Performs convention-based cache invalidation after mutation success
|
|
102
|
+
*
|
|
103
|
+
* Invalidation rules:
|
|
104
|
+
* - `create*`, `add*` → invalidates `list*`, `find*` queries
|
|
105
|
+
* - `update*`, `edit*`, `patch*` → invalidates `get*` (matching ID), `list*`, `find*`
|
|
106
|
+
* - `delete*`, `remove*` → invalidates `get*` (matching ID), `list*`, `find*`
|
|
107
|
+
*
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
async function performAutoInvalidation(queryClient, namespace, procedureName, input, output, config) {
|
|
111
|
+
const mutationType = getMutationType(procedureName);
|
|
112
|
+
const exclude = config?.exclude ?? [];
|
|
113
|
+
// Get all queries in this namespace from the cache
|
|
114
|
+
const queries = queryClient.getQueryCache().findAll({ queryKey: [namespace] });
|
|
115
|
+
for (const query of queries) {
|
|
116
|
+
const queryKey = query.queryKey;
|
|
117
|
+
const queryProcName = queryKey[1];
|
|
118
|
+
// Skip if excluded
|
|
119
|
+
if (exclude.includes(queryProcName))
|
|
120
|
+
continue;
|
|
121
|
+
// Create/Update/Delete all invalidate list/find queries
|
|
122
|
+
if (/^(?:list|find)/.test(queryProcName)) {
|
|
123
|
+
await queryClient.invalidateQueries({ queryKey: [namespace, queryProcName] });
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
// Update/Delete also invalidate matching get queries
|
|
127
|
+
if (mutationType !== 'create' && /^get/.test(queryProcName)) {
|
|
128
|
+
const id = extractIdFromInput(input) ?? extractIdFromInput(output);
|
|
129
|
+
if (id) {
|
|
130
|
+
// Invalidate the specific query if it matches the ID
|
|
131
|
+
const queryInput = queryKey[2];
|
|
132
|
+
const queryId = queryInput ? extractIdFromInput(queryInput) : null;
|
|
133
|
+
if (queryId === id) {
|
|
134
|
+
await queryClient.invalidateQueries({ queryKey: query.queryKey });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Handle additional invalidations from config
|
|
140
|
+
if (config?.additional) {
|
|
141
|
+
for (const [ns, proc, inp] of config.additional) {
|
|
142
|
+
const queryKey = inp !== undefined ? [ns, proc, inp] : [ns, proc];
|
|
143
|
+
await queryClient.invalidateQueries({ queryKey });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Run custom invalidation handler if provided
|
|
147
|
+
if (config?.custom) {
|
|
148
|
+
const context = {
|
|
149
|
+
namespace,
|
|
150
|
+
procedureName,
|
|
151
|
+
input,
|
|
152
|
+
data: output,
|
|
153
|
+
queryClient,
|
|
154
|
+
invalidate: async (proc, inp) => {
|
|
155
|
+
const queryKey = inp !== undefined ? [namespace, proc, inp] : [namespace, proc];
|
|
156
|
+
await queryClient.invalidateQueries({ queryKey });
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
await config.custom(context);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ============================================================================
|
|
163
|
+
// Procedure Proxy Creators
|
|
164
|
+
// ============================================================================
|
|
165
|
+
/**
|
|
166
|
+
* Creates a query procedure proxy with all hook methods
|
|
167
|
+
*
|
|
168
|
+
* @param namespace - The procedure namespace (e.g., 'users')
|
|
169
|
+
* @param procedureName - The procedure name (e.g., 'getUser')
|
|
170
|
+
* @param getClient - Factory function to get the client (called inside hooks)
|
|
171
|
+
*/
|
|
172
|
+
function createQueryProcedureProxy(namespace, procedureName, getClient) {
|
|
173
|
+
return {
|
|
174
|
+
useQuery(input, options) {
|
|
175
|
+
const client = getClient();
|
|
176
|
+
const queryKey = buildQueryKey(namespace, procedureName, input);
|
|
177
|
+
return useReactQuery({
|
|
178
|
+
queryKey,
|
|
179
|
+
queryFn: async () => {
|
|
180
|
+
const namespaceClient = client[namespace];
|
|
181
|
+
const procedure = namespaceClient[procedureName];
|
|
182
|
+
return procedure(input);
|
|
183
|
+
},
|
|
184
|
+
...options,
|
|
185
|
+
});
|
|
186
|
+
},
|
|
187
|
+
useSuspenseQuery(input, options) {
|
|
188
|
+
const client = getClient();
|
|
189
|
+
const queryKey = buildQueryKey(namespace, procedureName, input);
|
|
190
|
+
return useReactSuspenseQuery({
|
|
191
|
+
queryKey,
|
|
192
|
+
queryFn: async () => {
|
|
193
|
+
const namespaceClient = client[namespace];
|
|
194
|
+
const procedure = namespaceClient[procedureName];
|
|
195
|
+
return procedure(input);
|
|
196
|
+
},
|
|
197
|
+
...options,
|
|
198
|
+
});
|
|
199
|
+
},
|
|
200
|
+
getQueryKey(input) {
|
|
201
|
+
return buildQueryKey(namespace, procedureName, input);
|
|
202
|
+
},
|
|
203
|
+
invalidate(input, queryClient) {
|
|
204
|
+
const queryKey = input
|
|
205
|
+
? buildQueryKey(namespace, procedureName, input)
|
|
206
|
+
: [namespace, procedureName];
|
|
207
|
+
return queryClient.invalidateQueries({ queryKey });
|
|
208
|
+
},
|
|
209
|
+
prefetch(input, queryClient) {
|
|
210
|
+
const client = getClient();
|
|
211
|
+
const queryKey = buildQueryKey(namespace, procedureName, input);
|
|
212
|
+
return queryClient.prefetchQuery({
|
|
213
|
+
queryKey,
|
|
214
|
+
queryFn: async () => {
|
|
215
|
+
const namespaceClient = client[namespace];
|
|
216
|
+
const procedure = namespaceClient[procedureName];
|
|
217
|
+
return procedure(input);
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
},
|
|
221
|
+
setData(input, data, queryClient) {
|
|
222
|
+
const queryKey = buildQueryKey(namespace, procedureName, input);
|
|
223
|
+
queryClient.setQueryData(queryKey, data);
|
|
224
|
+
},
|
|
225
|
+
getData(input, queryClient) {
|
|
226
|
+
const queryKey = buildQueryKey(namespace, procedureName, input);
|
|
227
|
+
return queryClient.getQueryData(queryKey);
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Creates a mutation procedure proxy with hook methods and auto-invalidation
|
|
233
|
+
*
|
|
234
|
+
* Auto-invalidation is enabled by default and follows naming conventions:
|
|
235
|
+
* - `create*`, `add*` → invalidates `list*`, `find*` queries
|
|
236
|
+
* - `update*`, `edit*`, `patch*` → invalidates `get*` (matching ID), `list*`, `find*`
|
|
237
|
+
* - `delete*`, `remove*` → invalidates `get*` (matching ID), `list*`, `find*`
|
|
238
|
+
*
|
|
239
|
+
* @param namespace - The procedure namespace (e.g., 'users')
|
|
240
|
+
* @param procedureName - The procedure name (e.g., 'createUser')
|
|
241
|
+
* @param getClient - Factory function to get the client (called inside hooks)
|
|
242
|
+
*/
|
|
243
|
+
function createMutationProcedureProxy(namespace, procedureName, getClient) {
|
|
244
|
+
return {
|
|
245
|
+
useMutation(options) {
|
|
246
|
+
const client = getClient();
|
|
247
|
+
const queryClient = useReactQueryClient();
|
|
248
|
+
// Extract auto-invalidation configuration
|
|
249
|
+
const typedOptions = options;
|
|
250
|
+
const autoInvalidateOption = typedOptions?.autoInvalidate;
|
|
251
|
+
const autoInvalidateEnabled = autoInvalidateOption !== false;
|
|
252
|
+
const autoInvalidateConfig = typeof autoInvalidateOption === 'object' ? autoInvalidateOption : undefined;
|
|
253
|
+
// Store original onSuccess to call after auto-invalidation
|
|
254
|
+
const originalOnSuccess = options?.onSuccess;
|
|
255
|
+
return useReactMutation({
|
|
256
|
+
mutationFn: async (input) => {
|
|
257
|
+
const namespaceClient = client[namespace];
|
|
258
|
+
const procedure = namespaceClient[procedureName];
|
|
259
|
+
return procedure(input);
|
|
260
|
+
},
|
|
261
|
+
...options,
|
|
262
|
+
onSuccess: async (data, variables, context, meta) => {
|
|
263
|
+
// Perform auto-invalidation if enabled
|
|
264
|
+
if (autoInvalidateEnabled) {
|
|
265
|
+
await performAutoInvalidation(queryClient, namespace, procedureName, variables, data, autoInvalidateConfig);
|
|
266
|
+
}
|
|
267
|
+
// Call user's onSuccess callback if provided (React Query v5 signature)
|
|
268
|
+
if (originalOnSuccess) {
|
|
269
|
+
await originalOnSuccess(data, variables, context, meta);
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
// ============================================================================
|
|
277
|
+
// Namespace Proxy
|
|
278
|
+
// ============================================================================
|
|
279
|
+
/**
|
|
280
|
+
* Creates a proxy for a namespace that returns procedure proxies
|
|
281
|
+
*
|
|
282
|
+
* Each property access on the namespace proxy creates a procedure proxy
|
|
283
|
+
* with the appropriate methods (useQuery for queries, useMutation for mutations).
|
|
284
|
+
*
|
|
285
|
+
* @param namespace - The namespace name (e.g., 'users')
|
|
286
|
+
* @param getClient - Factory function to get the client
|
|
287
|
+
*/
|
|
288
|
+
function createNamespaceProxy(namespace, getClient) {
|
|
289
|
+
// Cache procedure proxies to avoid recreating on every access
|
|
290
|
+
const procedureCache = new Map();
|
|
291
|
+
return new Proxy({}, {
|
|
292
|
+
get(_target, procedureName) {
|
|
293
|
+
// Return cached proxy if available
|
|
294
|
+
const cached = procedureCache.get(procedureName);
|
|
295
|
+
if (cached) {
|
|
296
|
+
return cached;
|
|
297
|
+
}
|
|
298
|
+
// Create new procedure proxy based on naming convention
|
|
299
|
+
const procedureProxy = isQueryProcedure(procedureName)
|
|
300
|
+
? createQueryProcedureProxy(namespace, procedureName, getClient)
|
|
301
|
+
: createMutationProcedureProxy(namespace, procedureName, getClient);
|
|
302
|
+
// Cache for future access
|
|
303
|
+
procedureCache.set(procedureName, procedureProxy);
|
|
304
|
+
return procedureProxy;
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
// ============================================================================
|
|
309
|
+
// Main Factory
|
|
310
|
+
// ============================================================================
|
|
311
|
+
/**
|
|
312
|
+
* Creates a typed proxy for accessing VeloxTS procedures as React hooks
|
|
313
|
+
*
|
|
314
|
+
* This is the primary entry point for the tRPC-style API. It returns a proxy
|
|
315
|
+
* that mirrors your router structure and provides hook methods with full
|
|
316
|
+
* IDE autocomplete.
|
|
317
|
+
*
|
|
318
|
+
* @template TRouter - The router type (collection of procedure collections)
|
|
319
|
+
* @param config - Optional configuration
|
|
320
|
+
* @returns Fully typed proxy with autocomplete for namespaces and procedures
|
|
321
|
+
*
|
|
322
|
+
* @example Basic usage
|
|
323
|
+
* ```tsx
|
|
324
|
+
* // api.ts - Create hooks once
|
|
325
|
+
* import { createVeloxHooks } from '@veloxts/client/react';
|
|
326
|
+
* import type { AppRouter } from '../../api/src';
|
|
327
|
+
*
|
|
328
|
+
* export const api = createVeloxHooks<AppRouter>();
|
|
329
|
+
*
|
|
330
|
+
* // UserProfile.tsx - Use with full autocomplete
|
|
331
|
+
* import { api } from '../api';
|
|
332
|
+
*
|
|
333
|
+
* function UserProfile({ userId }: { userId: string }) {
|
|
334
|
+
* const { data: user, isLoading } = api.users.getUser.useQuery({ id: userId });
|
|
335
|
+
*
|
|
336
|
+
* const { mutate: updateUser } = api.users.updateUser.useMutation({
|
|
337
|
+
* onSuccess: () => {
|
|
338
|
+
* api.users.getUser.invalidate({ id: userId });
|
|
339
|
+
* },
|
|
340
|
+
* });
|
|
341
|
+
*
|
|
342
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
343
|
+
* return <div>{user?.name}</div>;
|
|
344
|
+
* }
|
|
345
|
+
* ```
|
|
346
|
+
*
|
|
347
|
+
* @example With Suspense
|
|
348
|
+
* ```tsx
|
|
349
|
+
* function UserProfileSuspense({ userId }: { userId: string }) {
|
|
350
|
+
* // Throws promise for Suspense boundary
|
|
351
|
+
* const { data: user } = api.users.getUser.useSuspenseQuery({ id: userId });
|
|
352
|
+
* return <h1>{user.name}</h1>;
|
|
353
|
+
* }
|
|
354
|
+
*
|
|
355
|
+
* // Wrap with Suspense boundary
|
|
356
|
+
* <Suspense fallback={<Spinner />}>
|
|
357
|
+
* <UserProfileSuspense userId="123" />
|
|
358
|
+
* </Suspense>
|
|
359
|
+
* ```
|
|
360
|
+
*
|
|
361
|
+
* @example SSR with direct client
|
|
362
|
+
* ```tsx
|
|
363
|
+
* import { createClient } from '@veloxts/client';
|
|
364
|
+
*
|
|
365
|
+
* const client = createClient<AppRouter>({ baseUrl: '/api' });
|
|
366
|
+
* const api = createVeloxHooks<AppRouter>({ client });
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
export function createVeloxHooks(config) {
|
|
370
|
+
// Cache namespace proxies to avoid recreating on every access
|
|
371
|
+
const namespaceCache = new Map();
|
|
372
|
+
// Factory function that gets the client
|
|
373
|
+
// If config.client is provided, use it directly (SSR/testing)
|
|
374
|
+
// Otherwise, get from context (must be inside VeloxProvider)
|
|
375
|
+
const getClient = () => {
|
|
376
|
+
// Must always call hook before returning
|
|
377
|
+
const { client: contextClient } = useVeloxContext();
|
|
378
|
+
return config?.client ?? contextClient;
|
|
379
|
+
};
|
|
380
|
+
// Create the root proxy
|
|
381
|
+
return new Proxy({}, {
|
|
382
|
+
get(_target, namespace) {
|
|
383
|
+
// Return cached namespace proxy if available
|
|
384
|
+
const cached = namespaceCache.get(namespace);
|
|
385
|
+
if (cached) {
|
|
386
|
+
return cached;
|
|
387
|
+
}
|
|
388
|
+
// Create new namespace proxy
|
|
389
|
+
const namespaceProxy = createNamespaceProxy(namespace, getClient);
|
|
390
|
+
// Cache for future access
|
|
391
|
+
namespaceCache.set(namespace, namespaceProxy);
|
|
392
|
+
return namespaceProxy;
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
//# sourceMappingURL=proxy-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-hooks.js","sourceRoot":"","sources":["../../src/react/proxy-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EACL,WAAW,IAAI,gBAAgB,EAC/B,QAAQ,IAAI,aAAa,EACzB,cAAc,IAAI,mBAAmB,EACrC,gBAAgB,IAAI,qBAAqB,GAC1C,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAYhD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E;;;;;;;;;;;;;GAaG;AACH,SAAS,gBAAgB,CAAC,aAAqB;IAC7C,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAC1E,CAAC;AAYD;;;GAGG;AACH,SAAS,eAAe,CAAC,aAAqB;IAC5C,IAAI,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC3D,IAAI,wBAAwB,CAAC,IAAI,CAAC,aAAa,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClE,IAAI,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC9D,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAErD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAE7C,kBAAkB;IAClB,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC,EAAE,CAAC;IAC9C,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEtD,qCAAqC;IACrC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YACzF,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,uBAAuB,CACpC,WAAwB,EACxB,SAAiB,EACjB,aAAqB,EACrB,KAAc,EACd,MAAe,EACf,MAA+B;IAE/B,MAAM,YAAY,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;IAEtC,mDAAmD;IACnD,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAE/E,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAsC,CAAC;QAC9D,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAElC,mBAAmB;QACnB,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;YAAE,SAAS;QAE9C,wDAAwD;QACxD,IAAI,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YACzC,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;YAC9E,SAAS;QACX,CAAC;QAED,qDAAqD;QACrD,IAAI,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAC5D,MAAM,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;YACnE,IAAI,EAAE,EAAE,CAAC;gBACP,qDAAqD;gBACrD,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAwC,CAAC;gBACtE,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACnE,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;oBACnB,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACpE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAChD,MAAM,QAAQ,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAClE,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;QACnB,MAAM,OAAO,GAAwB;YACnC,SAAS;YACT,aAAa;YACb,KAAK;YACL,IAAI,EAAE,MAAM;YACZ,WAAW;YACX,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;gBAC9B,MAAM,QAAQ,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBAChF,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;YACpD,CAAC;SACF,CAAC;QACF,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E;;;;;;GAMG;AACH,SAAS,yBAAyB,CAChC,SAAiB,EACjB,aAAqB,EACrB,SAAgC;IAEhC,OAAO;QACL,QAAQ,CAAC,KAAK,EAAE,OAAO;YACrB,MAAM,MAAM,GAAG,SAAS,EAAmB,CAAC;YAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;YAEhE,OAAO,aAAa,CAAC;gBACnB,QAAQ;gBACR,OAAO,EAAE,KAAK,IAAI,EAAE;oBAClB,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;oBAC1C,MAAM,SAAS,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;oBACjD,OAAO,SAAS,CAAC,KAAK,CAAqB,CAAC;gBAC9C,CAAC;gBACD,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;QAED,gBAAgB,CAAC,KAAK,EAAE,OAAO;YAC7B,MAAM,MAAM,GAAG,SAAS,EAAmB,CAAC;YAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;YAEhE,OAAO,qBAAqB,CAAC;gBAC3B,QAAQ;gBACR,OAAO,EAAE,KAAK,IAAI,EAAE;oBAClB,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;oBAC1C,MAAM,SAAS,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;oBACjD,OAAO,SAAS,CAAC,KAAK,CAAqB,CAAC;gBAC9C,CAAC;gBACD,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;QAED,WAAW,CAAC,KAAK;YACf,OAAO,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;QAED,UAAU,CAAC,KAAK,EAAE,WAAW;YAC3B,MAAM,QAAQ,GAAG,KAAK;gBACpB,CAAC,CAAC,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC;gBAChD,CAAC,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;YAC/B,OAAO,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,QAAQ,CAAC,KAAK,EAAE,WAAW;YACzB,MAAM,MAAM,GAAG,SAAS,EAAmB,CAAC;YAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;YAEhE,OAAO,WAAW,CAAC,aAAa,CAAC;gBAC/B,QAAQ;gBACR,OAAO,EAAE,KAAK,IAAI,EAAE;oBAClB,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;oBAC1C,MAAM,SAAS,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;oBACjD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC1B,CAAC;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW;YAC9B,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;YAChE,WAAW,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,CAAC,KAAK,EAAE,WAAW;YACxB,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;YAChE,OAAO,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAwB,CAAC;QACnE,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,4BAA4B,CACnC,SAAiB,EACjB,aAAqB,EACrB,SAAgC;IAEhC,OAAO;QACL,WAAW,CAAC,OAAO;YACjB,MAAM,MAAM,GAAG,SAAS,EAAmB,CAAC;YAC5C,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;YAE1C,0CAA0C;YAC1C,MAAM,YAAY,GAAG,OAA4D,CAAC;YAClF,MAAM,oBAAoB,GAAG,YAAY,EAAE,cAAc,CAAC;YAC1D,MAAM,qBAAqB,GAAG,oBAAoB,KAAK,KAAK,CAAC;YAC7D,MAAM,oBAAoB,GACxB,OAAO,oBAAoB,KAAK,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;YAE9E,2DAA2D;YAC3D,MAAM,iBAAiB,GAAG,OAAO,EAAE,SAAS,CAAC;YAE7C,OAAO,gBAAgB,CAAC;gBACtB,UAAU,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;oBAClC,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;oBAC1C,MAAM,SAAS,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;oBACjD,OAAO,SAAS,CAAC,KAAK,CAAqB,CAAC;gBAC9C,CAAC;gBACD,GAAG,OAAO;gBACV,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;oBAClD,uCAAuC;oBACvC,IAAI,qBAAqB,EAAE,CAAC;wBAC1B,MAAM,uBAAuB,CAC3B,WAAW,EACX,SAAS,EACT,aAAa,EACb,SAAS,EACT,IAAI,EACJ,oBAAoB,CACrB,CAAC;oBACJ,CAAC;oBAED,wEAAwE;oBACxE,IAAI,iBAAiB,EAAE,CAAC;wBACtB,MAAM,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;oBAC1D,CAAC;gBACH,CAAC;aACF,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E;;;;;;;;GAQG;AACH,SAAS,oBAAoB,CAC3B,SAAiB,EACjB,SAAgC;IAKhC,8DAA8D;IAC9D,MAAM,cAAc,GAAG,IAAI,GAAG,EAG3B,CAAC;IAEJ,OAAO,IAAI,KAAK,CACd,EAGC,EACD;QACE,GAAG,CAAC,OAAO,EAAE,aAAqB;YAChC,mCAAmC;YACnC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACjD,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC;YAChB,CAAC;YAED,wDAAwD;YACxD,MAAM,cAAc,GAAG,gBAAgB,CAAC,aAAa,CAAC;gBACpD,CAAC,CAAC,yBAAyB,CAAC,SAAS,EAAE,aAAa,EAAE,SAAkC,CAAC;gBACzF,CAAC,CAAC,4BAA4B,CAC1B,SAAS,EACT,aAAa,EACb,SAAkC,CACnC,CAAC;YAEN,0BAA0B;YAC1B,cAAc,CAAC,GAAG,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;YAElD,OAAO,cAAc,CAAC;QACxB,CAAC;KACF,CACF,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,MAAM,UAAU,gBAAgB,CAAU,MAAkC;IAC1E,8DAA8D;IAC9D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAmD,CAAC;IAElF,wCAAwC;IACxC,8DAA8D;IAC9D,6DAA6D;IAC7D,MAAM,SAAS,GAA0B,GAAG,EAAE;QAC5C,yCAAyC;QACzC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,eAAe,EAAW,CAAC;QAC7D,OAAO,MAAM,EAAE,MAAM,IAAI,aAAa,CAAC;IACzC,CAAC,CAAC;IAEF,wBAAwB;IACxB,OAAO,IAAI,KAAK,CAAC,EAAyB,EAAE;QAC1C,GAAG,CAAC,OAAO,EAAE,SAAiB;YAC5B,6CAA6C;YAC7C,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC7C,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC;YAChB,CAAC;YAED,6BAA6B;YAC7B,MAAM,cAAc,GAAG,oBAAoB,CAAU,SAAS,EAAE,SAAS,CAAC,CAAC;YAE3E,0BAA0B;YAC1B,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAE9C,OAAO,cAAc,CAAC;QACxB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|