@aeye/core 0.1.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 ADDED
@@ -0,0 +1,568 @@
1
+ # @aeye/core
2
+
3
+ Core primitives for building AI agents, tools, and prompts with TypeScript. Provides a type-safe, composable framework for creating sophisticated AI applications with structured inputs/outputs, tool calling, and context management.
4
+
5
+ ## Features
6
+
7
+ - **🎯 Type-Safe Components** - Prompts, Tools, and Agents with full TypeScript support
8
+ - **🔧 Tool Calling** - Native support for function/tool calling with schema validation
9
+ - **📝 Template-Based Prompts** - Handlebars templates for dynamic prompt generation
10
+ - **✅ Schema Validation** - Zod integration for structured inputs and outputs
11
+ - **🌊 Streaming Support** - First-class streaming for real-time AI responses
12
+ - **🔄 Composable Architecture** - Tools can use other tools, prompts can use tools, agents orchestrate everything
13
+ - **📊 Context Management** - Type-safe context threading and automatic token window management
14
+ - **🎛️ Flexible Execution** - Sequential, parallel, or immediate tool execution modes
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @aeye/core zod handlebars
20
+ ```
21
+
22
+ ## Core Concepts
23
+
24
+ ### Components
25
+
26
+ All AI primitives implement the `Component` interface:
27
+
28
+ - **Prompt** - Generates AI responses with optional tool usage and structured outputs
29
+ - **Tool** - Extends AI capabilities with custom functions and external integrations
30
+ - **Agent** - Orchestrates complex workflows combining prompts and tools
31
+
32
+ ### Context & Metadata
33
+
34
+ - **Context (`TContext`)** - Application-specific data threaded through operations (user, db, etc.)
35
+ - **Metadata (`TMetadata`)** - Execution settings for AI requests (model, temperature, etc.)
36
+
37
+ ## Quick Start
38
+
39
+ ### Basic Prompt
40
+
41
+ ```typescript
42
+ import { Prompt } from '@aeye/core';
43
+ import z from 'zod';
44
+
45
+ const summarizer = new Prompt({
46
+ name: 'summarize',
47
+ description: 'Summarizes text concisely',
48
+ content: 'Summarize the following text:\n\n{{text}}',
49
+
50
+ // Transform input
51
+ input: (input: { text: string }) => ({ text: input.text }),
52
+
53
+ // Define output schema
54
+ schema: z.object({
55
+ summary: z.string().describe('A concise summary'),
56
+ keyPoints: z.array(z.string()).describe('Main points')
57
+ })
58
+ });
59
+
60
+ // Execute with a context that has an executor
61
+ const result = await summarizer.get(
62
+ 'result',
63
+ { text: 'Long article text...' },
64
+ {
65
+ execute: yourAIExecutor, // Executor function from a provider
66
+ messages: []
67
+ }
68
+ );
69
+
70
+ console.log(result.summary);
71
+ console.log(result.keyPoints);
72
+ ```
73
+
74
+ ### Creating Tools
75
+
76
+ ```typescript
77
+ import { Tool } from '@aeye/core';
78
+ import z from 'zod';
79
+
80
+ const weatherTool = new Tool({
81
+ name: 'getWeather',
82
+ description: 'Get current weather for a location',
83
+ instructions: 'Use this tool to get weather data',
84
+
85
+ schema: z.object({
86
+ location: z.string().describe('City name or coordinates'),
87
+ units: z.enum(['celsius', 'fahrenheit']).default('celsius')
88
+ }),
89
+
90
+ call: async (input, refs, ctx) => {
91
+ const response = await fetch(
92
+ `https://api.weather.com/v1/${input.location}`
93
+ );
94
+ const data = await response.json();
95
+
96
+ return {
97
+ temperature: data.temp,
98
+ condition: data.condition,
99
+ humidity: data.humidity
100
+ };
101
+ }
102
+ });
103
+ ```
104
+
105
+ ### Prompts with Tools
106
+
107
+ ```typescript
108
+ const travelAdvisor = new Prompt({
109
+ name: 'travelAdvisor',
110
+ description: 'Provides travel advice based on weather',
111
+ content: `You are a travel advisor. Help plan a trip to {{destination}}.
112
+
113
+ Use the weather tool to check current conditions, then provide:
114
+ - What to pack
115
+ - Activities to do
116
+ - Best times to visit`,
117
+
118
+ input: (input: { destination: string }) => ({
119
+ destination: input.destination
120
+ }),
121
+
122
+ tools: [weatherTool],
123
+
124
+ schema: z.object({
125
+ recommendations: z.array(z.string()),
126
+ packingList: z.array(z.string()),
127
+ weatherNotes: z.string()
128
+ })
129
+ });
130
+
131
+ // The AI will automatically call weatherTool if needed
132
+ const advice = await travelAdvisor.get(
133
+ 'result',
134
+ { destination: 'Paris' },
135
+ { execute: yourAIExecutor, messages: [] }
136
+ );
137
+ ```
138
+
139
+ ### Streaming Responses
140
+
141
+ ```typescript
142
+ // Stream content only
143
+ for await (const chunk of summarizer.get(
144
+ 'streamContent',
145
+ { text: 'Long text...' },
146
+ { stream: yourAIStreamer, messages: [] }
147
+ )) {
148
+ process.stdout.write(chunk);
149
+ }
150
+
151
+ // Stream all events (including tool calls)
152
+ for await (const event of summarizer.get(
153
+ 'stream',
154
+ { text: 'Long text...' },
155
+ { stream: yourAIStreamer, messages: [] }
156
+ )) {
157
+ if (event.type === 'textPartial') {
158
+ console.log('Text:', event.content);
159
+ } else if (event.type === 'toolStart') {
160
+ console.log('Tool started:', event.tool.name);
161
+ } else if (event.type === 'toolOutput') {
162
+ console.log('Tool result:', event.result);
163
+ }
164
+ }
165
+ ```
166
+
167
+ ### Building Agents
168
+
169
+ ```typescript
170
+ import { Agent } from '@aeye/core';
171
+
172
+ const researchAgent = new Agent({
173
+ name: 'researcher',
174
+ description: 'Conducts research on topics',
175
+
176
+ refs: [searchTool, summarizeTool, analyzeTool],
177
+
178
+ call: async (input: { topic: string }, [search, summarize, analyze], ctx) => {
179
+ // Step 1: Search for information
180
+ const searchResults = await search.run(
181
+ { query: input.topic, limit: 5 },
182
+ ctx
183
+ );
184
+
185
+ // Step 2: Summarize findings
186
+ const summaries = [];
187
+ for (const result of searchResults) {
188
+ const summary = await summarize.get(
189
+ 'result',
190
+ { text: result.content },
191
+ ctx
192
+ );
193
+ summaries.push(summary);
194
+ }
195
+
196
+ // Step 3: Analyze and synthesize
197
+ const analysis = await analyze.get(
198
+ 'result',
199
+ { topic: input.topic, sources: summaries },
200
+ ctx
201
+ );
202
+
203
+ return analysis;
204
+ }
205
+ });
206
+
207
+ const research = await researchAgent.run(
208
+ { topic: 'Quantum Computing' },
209
+ { execute: yourAIExecutor, messages: [] }
210
+ );
211
+ ```
212
+
213
+ ## Prompt Modes
214
+
215
+ The `get` method supports different execution modes:
216
+
217
+ | Mode | Description | Returns |
218
+ |------|-------------|---------|
219
+ | `'result'` | Get final structured output | `TOutput` |
220
+ | `'tools'` | Get tool call results | `PromptToolOutput[]` |
221
+ | `'stream'` | Stream all events | `AsyncGenerator<PromptEvent>` |
222
+ | `'streamTools'` | Stream tool outputs | `AsyncGenerator<PromptToolOutput>` |
223
+ | `'streamContent'` | Stream text content only | `AsyncGenerator<string>` |
224
+
225
+ ```typescript
226
+ // Get structured result
227
+ const result = await prompt.get('result', input, ctx);
228
+
229
+ // Get tool outputs only
230
+ const tools = await prompt.get('tools', input, ctx);
231
+
232
+ // Stream everything
233
+ for await (const event of prompt.get('stream', input, ctx)) {
234
+ // Handle different event types
235
+ }
236
+ ```
237
+
238
+ ## Tool Execution Modes
239
+
240
+ Control how tools are executed:
241
+
242
+ ```typescript
243
+ const prompt = new Prompt({
244
+ name: 'multi-tool',
245
+ description: 'Uses multiple tools',
246
+ content: 'Analyze the data',
247
+ tools: [tool1, tool2, tool3],
248
+
249
+ // Tool execution mode
250
+ toolExecution: 'parallel', // 'sequential' | 'parallel' | 'immediate'
251
+
252
+ // Retry configuration
253
+ toolRetries: 2, // Retry failed tools
254
+ toolIterations: 3, // Max iterations for tool calls
255
+ toolsMax: 5, // Max total tool calls
256
+ });
257
+ ```
258
+
259
+ - **`sequential`** - Wait for each tool to finish before continuing
260
+ - **`parallel`** - Start all tools at once, wait for all to complete
261
+ - **`immediate`** - Start tools immediately as they're available
262
+
263
+ ## Advanced Features
264
+
265
+ ### Context-Aware Tools
266
+
267
+ ```typescript
268
+ const contextTool = new Tool({
269
+ name: 'contextAware',
270
+ description: 'A context-aware tool',
271
+ instructions: 'Use this tool...',
272
+
273
+ // Schema can depend on context
274
+ schema: (ctx) => {
275
+ if (ctx.userRole === 'admin') {
276
+ return z.object({
277
+ action: z.enum(['read', 'write', 'delete'])
278
+ });
279
+ }
280
+ return z.object({
281
+ action: z.enum(['read'])
282
+ });
283
+ },
284
+
285
+ // Check if tool is applicable
286
+ applicable: (ctx) => {
287
+ return ctx.isAuthenticated === true;
288
+ },
289
+
290
+ call: async (input, refs, ctx) => {
291
+ // Implementation with context access
292
+ }
293
+ });
294
+ ```
295
+
296
+ ### Custom Validation
297
+
298
+ ```typescript
299
+ const validatedTool = new Tool({
300
+ name: 'placeOrder',
301
+ description: 'Place an order',
302
+
303
+ schema: z.object({
304
+ itemId: z.string(),
305
+ quantity: z.number().min(1)
306
+ }),
307
+
308
+ // Additional validation beyond schema
309
+ validate: async (input, ctx) => {
310
+ const inventory = await checkInventory(input.itemId);
311
+ if (inventory < input.quantity) {
312
+ throw new Error(`Only ${inventory} items available`);
313
+ }
314
+ },
315
+
316
+ call: async (input, refs, ctx) => {
317
+ // Place order
318
+ }
319
+ });
320
+ ```
321
+
322
+ ### Event Tracking
323
+
324
+ ```typescript
325
+ import { withEvents } from '@aeye/core';
326
+
327
+ const runner = withEvents({
328
+ onStatus: (instance) => {
329
+ console.log(`${instance.component.name}: ${instance.status}`);
330
+ if (instance.status === 'completed') {
331
+ const duration = instance.completed - instance.started;
332
+ console.log(`Took ${duration}ms`);
333
+ }
334
+ },
335
+
336
+ onPromptEvent: (instance, event) => {
337
+ if (event.type === 'usage') {
338
+ console.log('Tokens used:', event.usage);
339
+ }
340
+ }
341
+ });
342
+
343
+ const result = await prompt.get(
344
+ 'result',
345
+ { text: 'Hello' },
346
+ {
347
+ execute: yourAIExecutor,
348
+ messages: [],
349
+ runner
350
+ }
351
+ );
352
+ ```
353
+
354
+ ### Token Management
355
+
356
+ Automatic conversation trimming when token limits are reached:
357
+
358
+ ```typescript
359
+ const context = {
360
+ execute: yourAIExecutor,
361
+ messages: conversationHistory,
362
+
363
+ // Token configuration
364
+ defaultCompletionTokens: 2048,
365
+
366
+ // Custom token estimation
367
+ estimateTokens: (message) => {
368
+ return message.content.length / 4; // Rough estimate
369
+ }
370
+ };
371
+
372
+ // Prompt will automatically trim messages if needed
373
+ const result = await prompt.get('result', { text: 'Query' }, context);
374
+ ```
375
+
376
+ ### Dynamic Reconfiguration
377
+
378
+ ```typescript
379
+ const adaptivePrompt = new Prompt({
380
+ name: 'adaptive',
381
+ description: 'Adapts based on execution stats',
382
+ content: 'Solve: {{problem}}',
383
+ schema: z.object({ solution: z.string() }),
384
+
385
+ // Adjust configuration during execution
386
+ reconfig: (stats, ctx) => {
387
+ // If tools are failing, change strategy
388
+ if (stats.toolCallErrors > 3) {
389
+ return {
390
+ config: { toolsOneAtATime: true },
391
+ maxIterations: 2
392
+ };
393
+ }
394
+ return {};
395
+ }
396
+ });
397
+ ```
398
+
399
+ ## API Reference
400
+
401
+ ### Prompt
402
+
403
+ ```typescript
404
+ class Prompt<TContext, TMetadata, TName, TInput, TOutput, TTools>
405
+ ```
406
+
407
+ **Constructor Options:**
408
+ - `name: string` - Unique identifier
409
+ - `description: string` - Purpose description
410
+ - `content: string` - Handlebars template
411
+ - `input?: Function` - Transform input for template
412
+ - `schema?: ZodType | Function` - Output schema
413
+ - `config?: Partial<Request> | Function` - AI request config
414
+ - `tools?: Tool[]` - Available tools
415
+ - `toolExecution?: 'sequential' | 'parallel' | 'immediate'`
416
+ - `toolRetries?: number` - Retry failed tools
417
+ - `toolIterations?: number` - Max tool call iterations
418
+ - `outputRetries?: number` - Retry invalid outputs
419
+ - `metadata?: TMetadata` - Execution metadata
420
+ - `validate?: Function` - Post-validation hook
421
+ - `applicable?: Function` - Applicability check
422
+
423
+ **Methods:**
424
+ - `get(input, mode, ctx)` - Execute and retrieve output
425
+ - `run(input, ctx)` - Execute with full streaming
426
+ - `applicable(ctx)` - Check if prompt can run
427
+
428
+ ### Tool
429
+
430
+ ```typescript
431
+ class Tool<TContext, TMetadata, TName, TParams, TOutput, TRefs>
432
+ ```
433
+
434
+ **Constructor Options:**
435
+ - `name: string` - Unique identifier
436
+ - `description: string` - Purpose description
437
+ - `instructions?: string` - Handlebars usage instructions
438
+ - `schema: ZodType | Function` - Input schema
439
+ - `refs?: Component[]` - Referenced components
440
+ - `call: Function` - Implementation
441
+ - `validate?: Function` - Post-validation hook
442
+ - `applicable?: Function` - Applicability check
443
+
444
+ **Methods:**
445
+ - `run(input, ctx)` - Execute the tool
446
+ - `compile(ctx)` - Generate tool definition for AI
447
+ - `parse(ctx, args)` - Parse and validate arguments
448
+ - `applicable(ctx)` - Check if tool can run
449
+
450
+ ### Agent
451
+
452
+ ```typescript
453
+ class Agent<TContext, TMetadata, TName, TInput, TOutput, TRefs>
454
+ ```
455
+
456
+ **Constructor Options:**
457
+ - `name: string` - Unique identifier
458
+ - `description: string` - Purpose description
459
+ - `refs?: Component[]` - Referenced components
460
+ - `call: Function` - Implementation with refs
461
+ - `applicable?: Function` - Applicability check
462
+
463
+ **Methods:**
464
+ - `run(input, ctx)` - Execute the agent
465
+ - `applicable(ctx)` - Check if agent can run
466
+
467
+ ## Context Structure
468
+
469
+ ```typescript
470
+ interface Context<TContext, TMetadata> {
471
+ // Required: AI execution
472
+ execute?: Executor<TContext, TMetadata>;
473
+ stream?: Streamer<TContext, TMetadata>;
474
+
475
+ // Messages
476
+ messages: Message[];
477
+
478
+ // Token management
479
+ defaultCompletionTokens?: number;
480
+ estimateTokens?: (message: Message) => number;
481
+
482
+ // Execution control
483
+ signal?: AbortSignal;
484
+ runner?: Events;
485
+
486
+ // User context (TContext) spreads here
487
+ [key: string]: any;
488
+ }
489
+ ```
490
+
491
+ ## Request Configuration
492
+
493
+ ```typescript
494
+ interface Request {
495
+ messages: Message[];
496
+ temperature?: number; // 0-2
497
+ topP?: number; // 0-1
498
+ maxTokens?: number;
499
+ stop?: string | string[];
500
+ tools?: ToolDefinition[];
501
+ toolChoice?: 'auto' | 'required' | 'none' | { tool: string };
502
+ responseFormat?: 'text' | 'json' | ResponseFormat;
503
+ // ... more options
504
+ }
505
+ ```
506
+
507
+ ## Best Practices
508
+
509
+ 1. **Type Safety** - Use TypeScript generics for context and metadata
510
+ 2. **Schema Validation** - Use Zod for robust input/output validation
511
+ 3. **Error Handling** - Wrap component execution in try-catch blocks
512
+ 4. **Token Management** - Provide `estimateTokens` for accurate trimming
513
+ 5. **Tool Organization** - Group related tools in agents
514
+ 6. **Testing** - Unit test tools and prompts independently
515
+ 7. **Documentation** - Document template variables and schemas
516
+ 8. **Context Minimization** - Pass only necessary data in context
517
+ 9. **Streaming** - Use streaming for better UX with long responses
518
+ 10. **Validation** - Use `validate` hooks for business logic validation
519
+
520
+ ## Examples
521
+
522
+ See the `src/__tests__` directory for comprehensive examples:
523
+
524
+ - **prompt-core-features.test.ts** - Basic prompt usage
525
+ - **prompt-streaming-tool-events.test.ts** - Streaming and events
526
+ - **tool.test.ts** - Tool creation and usage
527
+ - **agent.test.ts** - Agent orchestration
528
+ - **context-propagation.test.ts** - Context handling
529
+
530
+ ## TypeScript Support
531
+
532
+ Full type inference across component hierarchies:
533
+
534
+ ```typescript
535
+ // Types are automatically inferred
536
+ const prompt = new Prompt({
537
+ name: 'example',
538
+ schema: z.object({ result: z.string() })
539
+ // ...
540
+ });
541
+
542
+ // TypeScript knows the output type
543
+ const output = await prompt.get({}); // { result: string }
544
+
545
+ // Tool parameters are type-safe
546
+ const tool = new Tool({
547
+ name: 'math',
548
+ schema: z.object({ a: z.number(), b: z.number() }),
549
+ call: (input, refs, ctx) => {
550
+ // input is typed as { a: number, b: number }
551
+ return input.a + input.b;
552
+ }
553
+ });
554
+ ```
555
+
556
+ ## Contributing
557
+
558
+ Contributions are welcome! See the main [@aeye repository](https://github.com/ClickerMonkey/aeye) for contribution guidelines.
559
+
560
+ ## License
561
+
562
+ MIT © [ClickerMonkey](https://github.com/ClickerMonkey)
563
+
564
+ ## Links
565
+
566
+ - [GitHub Repository](https://github.com/ClickerMonkey/aeye)
567
+ - [Documentation](https://github.com/ClickerMonkey/aeye/tree/main/packages/core)
568
+ - [Issue Tracker](https://github.com/ClickerMonkey/aeye/issues)
@@ -0,0 +1,85 @@
1
+ import { AnyComponent, Component, ComponentCompatible, Context, OptionalParams, Tuple } from "./types";
2
+ /**
3
+ * Configuration for creating an Agent component.
4
+ * Agents orchestrate complex workflows by composing other components (tools, prompts, and agents).
5
+ *
6
+ * @template TContext - The context type needed for the agent's operation.
7
+ * @template TMetadata - The metadata type needed during execution/streaming.
8
+ * @template TName - The name of the agent, typed for inference in parent components.
9
+ * @template TInput - The input parameters type for the agent.
10
+ * @template TOutput - The output type for the agent.
11
+ * @template TRefs - References to other components that this agent depends on.
12
+ */
13
+ export interface AgentInput<TContext = {}, TMetadata = {}, TName extends string = string, TInput extends object = {}, TOutput = string, TRefs extends Tuple<AnyComponent> = []> {
14
+ /** The unique name of the agent */
15
+ name: TName;
16
+ /** Brief description of the agent's purpose (informational only) */
17
+ description: string;
18
+ /** References to other components (tools, prompts, agents) that this agent utilizes */
19
+ refs: TRefs;
20
+ /** The function that implements the agent's behavior */
21
+ call: (input: TInput, refs: TRefs, ctx: Context<TContext, TMetadata>) => TOutput;
22
+ /** Optional function to determine if the component is applicable in the given context */
23
+ applicable?: (ctx: Context<TContext, TMetadata>) => boolean | Promise<boolean>;
24
+ /** Optional way to explicitly declare the types used in this component */
25
+ types?: {
26
+ input?: TInput;
27
+ output?: TOutput;
28
+ context?: TContext;
29
+ metadata?: TMetadata;
30
+ };
31
+ }
32
+ /**
33
+ * An Agent component that orchestrates complex workflows by composing other AI components.
34
+ * Agents can utilize tools, prompts, and other agents to accomplish sophisticated tasks.
35
+ *
36
+ * @template TContext - The context type needed for the agent's operation.
37
+ * @template TMetadata - The metadata type needed during execution/streaming.
38
+ * @template TName - The name of the agent, typed for inference in parent components.
39
+ * @template TInput - The input parameters type for the agent.
40
+ * @template TOutput - The output type for the agent.
41
+ * @template TRefs - References to other components that this agent depends on.
42
+ *
43
+ * @example
44
+ * const researchAgent = new Agent({
45
+ * name: 'researcher',
46
+ * description: 'Conducts research using multiple tools',
47
+ * refs: [searchTool, summarizeTool, analyzePrompt],
48
+ * call: async (input, [search, summarize, analyze], ctx) => {
49
+ * const results = await search.run({ query: input.topic }, ctx);
50
+ * const summary = await summarize.get({ text: results });
51
+ * return analyze.get({ summary, topic: input.topic });
52
+ * }
53
+ * });
54
+ */
55
+ export declare class Agent<TContext = {}, TMetadata = {}, TName extends string = string, TInput extends object = {}, TOutput = string, TRefs extends Tuple<ComponentCompatible<TContext, TMetadata>> = []> implements Component<TContext, TMetadata, TName, TInput, TOutput, TRefs> {
56
+ input: AgentInput<TContext, TMetadata, TName, TInput, TOutput, TRefs>;
57
+ /**
58
+ * Creates a new Agent instance.
59
+ *
60
+ * @param input - The agent input configuration.
61
+ */
62
+ constructor(input: AgentInput<TContext, TMetadata, TName, TInput, TOutput, TRefs>);
63
+ get kind(): 'agent';
64
+ get name(): TName;
65
+ get description(): string;
66
+ get refs(): TRefs;
67
+ /**
68
+ * Executes the agent with the provided context and input.
69
+ * If a custom runner is provided in the context, it will be used instead of direct execution.
70
+ *
71
+ * @param input - The input parameters for the agent.
72
+ * @param ctx - The execution context.
73
+ * @returns The output of the agent's operation.
74
+ */
75
+ run<TRuntimeContext extends TContext, TRuntimeMetadata extends TMetadata, TCoreContext extends Context<TRuntimeContext, TRuntimeMetadata>>(...[inputMaybe, contextMaybe]: OptionalParams<[TInput, TCoreContext]>): TOutput;
76
+ /**
77
+ * Determines whether the agent is applicable in the given context.
78
+ * By default, checks if any of its referenced components are applicable.
79
+ *
80
+ * @param ctx - The context to check applicability against.
81
+ * @returns A promise that resolves to true if the agent is applicable, false otherwise.
82
+ */
83
+ applicable<TRuntimeContext extends TContext, TRuntimeMetadata extends TMetadata, TCoreContext extends Context<TRuntimeContext, TRuntimeMetadata>>(...[contextMaybe]: OptionalParams<[TCoreContext]>): Promise<boolean>;
84
+ }
85
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEvG;;;;;;;;;;GAUG;AACH,MAAM,WAAW,UAAU,CACzB,QAAQ,GAAG,EAAE,EACb,SAAS,GAAG,EAAE,EACd,KAAK,SAAS,MAAM,GAAG,MAAM,EAC7B,MAAM,SAAS,MAAM,GAAG,EAAE,EAC1B,OAAO,GAAG,MAAM,EAChB,KAAK,SAAS,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE;IAEtC,mCAAmC;IACnC,IAAI,EAAE,KAAK,CAAC;IACZ,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,IAAI,EAAE,KAAK,CAAC;IACZ,wDAAwD;IACxD,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,OAAO,CAAC;IACjF,yFAAyF;IACzF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/E,0EAA0E;IAC1E,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;QACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;KACtB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,KAAK,CAChB,QAAQ,GAAG,EAAE,EACb,SAAS,GAAG,EAAE,EACd,KAAK,SAAS,MAAM,GAAG,MAAM,EAC7B,MAAM,SAAS,MAAM,GAAG,EAAE,EAC1B,OAAO,GAAG,MAAM,EAChB,KAAK,SAAS,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAClE,YAAW,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IAQ/D,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IAN9E;;;;OAIG;gBAEM,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IAG9E,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,IAAI,IAAI,IAAI,KAAK,CAEhB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,IAAI,IAAI,KAAK,CAEhB;IAED;;;;;;;OAOG;IACH,GAAG,CACD,eAAe,SAAS,QAAQ,EAChC,gBAAgB,SAAS,SAAS,EAClC,YAAY,SAAS,OAAO,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAC/D,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,cAAc,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,GAAG,OAAO;IAUjF;;;;;;OAMG;IACG,UAAU,CACd,eAAe,SAAS,QAAQ,EAChC,gBAAgB,SAAS,SAAS,EAClC,YAAY,SAAS,OAAO,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAC/D,GAAG,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAevE"}