markform 0.1.14 → 0.1.16

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 (49) hide show
  1. package/README.md +48 -39
  2. package/dist/ai-sdk.d.mts +3 -2
  3. package/dist/ai-sdk.mjs +3 -2
  4. package/dist/ai-sdk.mjs.map +1 -0
  5. package/dist/{apply-CUH_16RD.mjs → apply-CXsI5N9x.mjs} +639 -9
  6. package/dist/apply-CXsI5N9x.mjs.map +1 -0
  7. package/dist/bin.mjs +3 -2
  8. package/dist/bin.mjs.map +1 -0
  9. package/dist/{cli-ixzNVirs.mjs → cli-BsFessUW.mjs} +713 -120
  10. package/dist/cli-BsFessUW.mjs.map +1 -0
  11. package/dist/cli.d.mts +2 -1
  12. package/dist/cli.mjs +1 -1
  13. package/dist/{coreTypes-CnKsB1H3.d.mts → coreTypes-DE6Giau5.d.mts} +10 -1
  14. package/dist/coreTypes-DiCddBKu.mjs +2 -1
  15. package/dist/coreTypes-DiCddBKu.mjs.map +1 -0
  16. package/dist/index.d.mts +15 -2
  17. package/dist/index.mjs +2 -2
  18. package/dist/session-XDrocA3j.mjs +2 -1
  19. package/dist/session-XDrocA3j.mjs.map +1 -0
  20. package/dist/{shared-D3dNi-Gn.mjs → shared-CCq4haEV.mjs} +9 -1
  21. package/dist/shared-CCq4haEV.mjs.map +1 -0
  22. package/dist/shared-fUKfJ1UA.mjs +4 -0
  23. package/dist/{src-BKRKMdgR.mjs → src-Dv3IZSQU.mjs} +15 -6
  24. package/dist/src-Dv3IZSQU.mjs.map +1 -0
  25. package/docs/markform-reference.md +58 -7
  26. package/docs/markform-spec.md +142 -0
  27. package/examples/movie-research/movie-deep-research-mock-filled.form.md +64 -40
  28. package/examples/movie-research/movie-deep-research.form.md +58 -37
  29. package/examples/movie-research/movie-research-demo.form.md +9 -6
  30. package/examples/rejection-test/rejection-test-mock-filled.form.md +5 -7
  31. package/examples/rejection-test/rejection-test-mock-filled.report.md +4 -2
  32. package/examples/rejection-test/rejection-test-mock-filled.schema.json +1 -1
  33. package/examples/rejection-test/rejection-test.form.md +5 -7
  34. package/examples/rejection-test/rejection-test.session.yaml +10 -10
  35. package/examples/simple/simple-comment-syntax.form.md +79 -0
  36. package/examples/simple/simple-mock-filled.form.md +20 -9
  37. package/examples/simple/simple-mock-filled.report.md +30 -7
  38. package/examples/simple/simple-skipped-filled.form.md +22 -10
  39. package/examples/simple/simple-skipped-filled.report.md +27 -4
  40. package/examples/simple/simple-skipped-filled.yml +1 -1
  41. package/examples/simple/simple-with-skips.session.yaml +35 -19
  42. package/examples/simple/simple.form.md +20 -9
  43. package/examples/simple/simple.raw.md +18 -25
  44. package/examples/simple/simple.session.yaml +35 -19
  45. package/examples/startup-deep-research/startup-deep-research.form.md +126 -103
  46. package/examples/startup-research/startup-research-mock-filled.form.md +19 -10
  47. package/examples/startup-research/startup-research.form.md +36 -29
  48. package/package.json +9 -3
  49. package/dist/shared-CNqwaxUt.mjs +0 -4
package/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Markform
2
2
 
3
- [![CI](https://github.com/jlevy/markform/actions/workflows/ci.yml/badge.svg)](https://github.com/jlevy/markform/actions/workflows/ci.yml)
4
- ![Coverage](./badges/packages/markform/coverage-total.svg) [![X (formerly Twitter)
5
- Follow](https://img.shields.io/twitter/follow/ojoshe)](https://x.com/ojoshe)
3
+ [![CI](https://github.com/jlevy/markform/actions/workflows/ci.yml/badge.svg)](https://github.com/jlevy/markform/actions/runs/21077282678)
4
+ [![Coverage](https://raw.githubusercontent.com/jlevy/markform/main/badges/packages/markform/coverage-total.svg)](https://github.com/jlevy/markform/actions/runs/21077282678)
5
+ [![npm version](https://img.shields.io/npm/v/markform)](https://www.npmjs.com/package/markform)
6
+ [![X Follow](https://img.shields.io/twitter/follow/ojoshe)](https://x.com/ojoshe)
6
7
 
7
8
  **Markform** is a text format for defining structured forms that humans can read,
8
9
  machines can parse, and agents can fill via tool calls.
@@ -33,8 +34,8 @@ in one place.
33
34
 
34
35
  Markform syntax is a good source format: token-efficient text you can read, diff, and
35
36
  version control.
36
- It is built with [Markdoc](https://github.com/markdoc/markdoc), which is
37
- a Markdown extension from Stripe with Jinja-style `{% tag %}` annotations.
37
+ Structure is defined with HTML comment tags (`<!-- field -->`) that render invisibly
38
+ on GitHub, so forms look like regular Markdown.
38
39
 
39
40
  ## Why Do Agents Need Forms?
40
41
 
@@ -53,8 +54,8 @@ or dependent on model whims (changes unpredictably with model updates).
53
54
 
54
55
  Forms solve this. Forms codify operational excellence.
55
56
  They’re easy to read, easy to edit, and enforce standards.
56
- Because LLMs handle Markdown and Jinja-style tags well, agents can also help create and
57
- improve the forms themselves—closing the meta-loop.
57
+ Because LLMs handle Markdown well, agents can also help create and improve the forms
58
+ themselves—closing the meta-loop.
58
59
 
59
60
  It’s time to bring bureaucracy to the agents!
60
61
  See [the FAQ](#faq) for more on the design.
@@ -93,46 +94,44 @@ npm install markform
93
94
 
94
95
  ### Form Definition
95
96
 
96
- A `.form.md` file is simply a Markdoc file.
97
- It combines YAML frontmatter with Markdoc-tagged content.
98
-
97
+ A `.form.md` file combines YAML frontmatter with HTML comment tags that define structure.
99
98
  The text can be any Markdown.
100
99
  The tags define things like fields:
101
100
 
102
- ```jinja
103
- {% field kind="string" id="movie" label="Movie" role="user"
104
- required=true minLength=1 maxLength=300 %}{% /field %}
105
-
106
- {% field kind="single_select" id="mpaa_rating" role="agent" label="MPAA Rating" %}
107
- - [ ] G {% #g %}
108
- - [ ] PG {% #pg %}
109
- - [ ] PG-13 {% #pg_13 %}
110
- - [ ] R {% #r %}
111
- - [ ] NC-17 {% #nc_17 %}
112
- - [ ] NR/Unrated {% #nr %}
113
- {% /field %}
101
+ ```markdown
102
+ <!-- field kind="string" id="movie" label="Movie" role="user"
103
+ required=true minLength=1 maxLength=300 --><!-- /field -->
104
+
105
+ <!-- field kind="single_select" id="mpaa_rating" role="agent" label="MPAA Rating" -->
106
+ - [ ] G <!-- #g -->
107
+ - [ ] PG <!-- #pg -->
108
+ - [ ] PG-13 <!-- #pg_13 -->
109
+ - [ ] R <!-- #r -->
110
+ - [ ] NC-17 <!-- #nc_17 -->
111
+ - [ ] NR/Unrated <!-- #nr -->
112
+ <!-- /field -->
114
113
  ```
115
114
 
116
115
  Fields have types defined by the attributes.
117
116
  Values are filled in incrementally, just like any form.
118
117
  Once filled in, values appear directly inside the tags, in Markdown format:
119
118
 
120
- ````jinja
121
- {% field kind="string" id="movie" label="Movie" role="user"
122
- required=true minLength=1 maxLength=300 %}
119
+ ````markdown
120
+ <!-- field kind="string" id="movie" label="Movie" role="user"
121
+ required=true minLength=1 maxLength=300 -->
123
122
  ```value
124
123
  The Shawshank Redemption
125
124
  ```
126
- {% /field %}
127
-
128
- {% field kind="single_select" id="mpaa_rating" role="agent" label="MPAA Rating" %}
129
- - [ ] G {% #g %}
130
- - [ ] PG {% #pg %}
131
- - [ ] PG-13 {% #pg_13 %}
132
- - [x] R {% #r %}
133
- - [ ] NC-17 {% #nc_17 %}
134
- - [ ] NR/Unrated {% #nr %}
135
- {% /field %}
125
+ <!-- /field -->
126
+
127
+ <!-- field kind="single_select" id="mpaa_rating" role="agent" label="MPAA Rating" -->
128
+ - [ ] G <!-- #g -->
129
+ - [ ] PG <!-- #pg -->
130
+ - [ ] PG-13 <!-- #pg_13 -->
131
+ - [x] R <!-- #r -->
132
+ - [ ] NC-17 <!-- #nc_17 -->
133
+ - [ ] NR/Unrated <!-- #nr -->
134
+ <!-- /field -->
136
135
  ````
137
136
 
138
137
  Note fields can have a `role="user"` to indicate they are filled interactively by the
@@ -144,13 +143,13 @@ grouping of forms.
144
143
  Checkboxes and tables as values are supported!
145
144
  Checkboxes can be single-select or multi-select.
146
145
 
147
- Heres a full example:
146
+ Here's a full example (using the alternative Markdoc tag syntax, which also works):
148
147
 
149
148
  <details>
150
149
 
151
150
  <summary>Markform for Movie Research Demo (click to expand)</summary>
152
151
 
153
- ```jinja
152
+ ```markdown
154
153
  ---
155
154
  markform:
156
155
  spec: MF/0.1
@@ -821,8 +820,18 @@ Or see [markdoc/language-server](https://github.com/markdoc/language-server).
821
820
 
822
821
  ## License
823
822
 
824
- AGPL-3.0-or-later. [Contact me](https://github.com/jlevy) for additional licensing
825
- options.
823
+ This project uses a dual licensing approach:
824
+
825
+ - **Markform Specification** ([`docs/markform-spec.md`](docs/markform-spec.md),
826
+ [`docs/markform-reference.md`](docs/markform-reference.md)):
827
+ [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/).
828
+ You may freely implement this specification in your own software under any license.
829
+
830
+ - **Reference Implementation** (all code in this repository):
831
+ [AGPL-3.0-or-later](./LICENSE).
832
+ [Contact me](https://github.com/jlevy) for commercial licensing options.
833
+
834
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution terms.
826
835
 
827
836
  [markdoc-overview]: https://markdoc.dev/docs/overview
828
837
  [stripe-markdoc]: https://stripe.com/blog/markdoc
package/dist/ai-sdk.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { At as PatchSchema, Dt as ParsedForm, Ot as Patch, Q as Id, V as FieldResponse, dr as ValidatorRegistry, q as FormSchema, r as ApplyResult, rt as InspectResult } from "./coreTypes-CnKsB1H3.mjs";
2
+ import { At as PatchSchema, Dt as ParsedForm, Ot as Patch, Q as Id, V as FieldResponse, fr as ValidatorRegistry, q as FormSchema, r as ApplyResult, rt as InspectResult } from "./coreTypes-DE6Giau5.mjs";
3
3
  import { z } from "zod";
4
4
 
5
5
  //#region src/integrations/toolTypes.d.ts
@@ -126,4 +126,5 @@ interface CreateMarkformToolsOptions {
126
126
  */
127
127
  declare function createMarkformTools(options: CreateMarkformToolsOptions): MarkformToolSet;
128
128
  //#endregion
129
- export { type ApplyToolResult, CreateMarkformToolsOptions, type ExportToolResult, type GetMarkdownToolResult, type InspectToolResult, MarkformSessionStore, type MarkformTool, type MarkformToolSet, PatchSchema, createMarkformTools };
129
+ export { type ApplyToolResult, CreateMarkformToolsOptions, type ExportToolResult, type GetMarkdownToolResult, type InspectToolResult, MarkformSessionStore, type MarkformTool, type MarkformToolSet, PatchSchema, createMarkformTools };
130
+ //# sourceMappingURL=ai-sdk.d.mts.map
package/dist/ai-sdk.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  import { L as PatchSchema } from "./coreTypes-DiCddBKu.mjs";
3
- import { d as serializeForm, i as inspect, t as applyPatches } from "./apply-CUH_16RD.mjs";
3
+ import { d as serializeForm, i as inspect, t as applyPatches } from "./apply-CXsI5N9x.mjs";
4
4
  import { z } from "zod";
5
5
 
6
6
  //#region src/integrations/vercelAiSdkTools.ts
@@ -165,4 +165,5 @@ function createMarkformTools(options) {
165
165
  }
166
166
 
167
167
  //#endregion
168
- export { MarkformSessionStore, PatchSchema, createMarkformTools };
168
+ export { MarkformSessionStore, PatchSchema, createMarkformTools };
169
+ //# sourceMappingURL=ai-sdk.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk.mjs","names":["toolset: MarkformToolSet"],"sources":["../src/integrations/vercelAiSdkTools.ts"],"sourcesContent":["/**\n * AI SDK Integration for Markform.\n *\n * Provides Vercel AI SDK compatible tools for agent-driven form filling.\n * Use createMarkformTools() to create a toolset that wraps the Markform engine.\n *\n * @example\n * ```typescript\n * import { createMarkformTools, MarkformSessionStore } from 'markform/ai-sdk';\n * import { generateText } from 'ai';\n *\n * const store = new MarkformSessionStore(parsedForm);\n * const tools = createMarkformTools({ sessionStore: store });\n *\n * const { text } = await generateText({\n * model: openai('gpt-4'),\n * prompt: 'Fill out this form...',\n * tools,\n * });\n * ```\n */\n\nimport { z } from 'zod';\nimport type { ParsedForm, Patch, ValidatorRegistry } from '../engine/coreTypes.js';\nimport { inspect } from '../engine/inspect.js';\nimport { applyPatches } from '../engine/apply.js';\nimport { serializeForm } from '../engine/serialize.js';\nimport { PatchSchema } from '../engine/coreTypes.js';\n\n// =============================================================================\n// Session Store\n// =============================================================================\n\n/**\n * Session store for managing form state during AI interactions.\n *\n * The AI SDK tools operate on a shared form instance through this store.\n * Create one store per form-filling session.\n */\nexport class MarkformSessionStore {\n private form: ParsedForm;\n private validatorRegistry: ValidatorRegistry;\n\n constructor(form: ParsedForm, validatorRegistry?: ValidatorRegistry) {\n this.form = form;\n this.validatorRegistry = validatorRegistry ?? {};\n }\n\n /**\n * Get the current form.\n */\n getForm(): ParsedForm {\n return this.form;\n }\n\n /**\n * Get the validator registry.\n */\n getValidatorRegistry(): ValidatorRegistry {\n return this.validatorRegistry;\n }\n\n /**\n * Update the form values.\n */\n updateForm(form: ParsedForm): void {\n this.form = form;\n }\n}\n\n// =============================================================================\n// Tool Creation Options\n// =============================================================================\n\n/**\n * Options for creating Markform AI SDK tools.\n */\nexport interface CreateMarkformToolsOptions {\n /**\n * Session store managing the form state.\n */\n sessionStore: MarkformSessionStore;\n\n /**\n * Whether to include the markform_get_markdown tool.\n * Defaults to true.\n */\n includeGetMarkdown?: boolean;\n}\n\n// =============================================================================\n// Tool Types (imported from toolTypes.ts)\n// =============================================================================\n\nimport type {\n ApplyToolResult,\n ExportToolResult,\n GetMarkdownToolResult,\n InspectToolResult,\n MarkformTool,\n MarkformToolSet,\n} from './toolTypes.js';\n\n// Re-export types for backwards compatibility\nexport type {\n ApplyToolResult,\n ExportToolResult,\n GetMarkdownToolResult,\n InspectToolResult,\n MarkformTool,\n MarkformToolSet,\n} from './toolTypes.js';\n\n// =============================================================================\n// Zod Schemas for Tool Inputs\n// =============================================================================\n\n/**\n * Input schema for markform_inspect tool (no parameters).\n */\nconst InspectInputSchema = z\n .object({})\n .describe('No input parameters required. Call this tool to inspect the current form state.');\n\n/**\n * Input schema for markform_apply tool.\n */\nconst ApplyInputSchema = z\n .object({\n patches: z\n .array(PatchSchema)\n .min(1)\n .max(20)\n .describe(\n 'Array of patches to apply to the form. Each patch sets or clears a field value. ' +\n 'Operations: set_string, set_number, set_string_list, set_single_select, set_multi_select, ' +\n 'set_checkboxes, set_url, set_url_list, set_date, set_year, set_table, clear_field, skip_field, abort_field. ' +\n 'Example: [{ \"op\": \"set_string\", \"fieldId\": \"name\", \"value\": \"Alice\" }]',\n ),\n })\n .describe('Apply patches to update form field values.');\n\n/**\n * Input schema for markform_export tool (no parameters).\n */\nconst ExportInputSchema = z\n .object({})\n .describe(\n 'No input parameters required. Call this tool to export the form schema and current values as JSON.',\n );\n\n/**\n * Input schema for markform_get_markdown tool (no parameters).\n */\nconst GetMarkdownInputSchema = z\n .object({})\n .describe(\n 'No input parameters required. Call this tool to get the canonical Markdown representation of the current form.',\n );\n\n// =============================================================================\n// Tool Factory\n// =============================================================================\n\n/**\n * Create Markform AI SDK tools for agent-driven form filling.\n *\n * Returns a toolset compatible with Vercel AI SDK's generateText and streamText.\n *\n * @param options - Tool creation options including session store\n * @returns MarkformToolSet containing all tools\n *\n * @example\n * ```typescript\n * import { parseForm } from 'markform';\n * import { createMarkformTools, MarkformSessionStore } from 'markform/ai-sdk';\n *\n * const form = parseForm(markdownContent);\n * const store = new MarkformSessionStore(form);\n * const tools = createMarkformTools({ sessionStore: store });\n *\n * // Use with AI SDK\n * const result = await generateText({\n * model: yourModel,\n * tools,\n * prompt: 'Fill out this form based on the user information...',\n * });\n * ```\n */\nexport function createMarkformTools(options: CreateMarkformToolsOptions): MarkformToolSet {\n const { sessionStore, includeGetMarkdown = true } = options;\n\n // markform_inspect - Get current form state with issues\n const markform_inspect: MarkformTool<Record<string, never>, InspectToolResult> = {\n description:\n 'Inspect the current form state. Returns structure summary, progress summary, validation issues, ' +\n 'and completion status. Use this to understand what fields need to be filled and what issues exist. ' +\n \"Issues are sorted by priority (1 = highest). Focus on 'required' severity issues first.\",\n inputSchema: InspectInputSchema,\n execute: () => {\n const form = sessionStore.getForm();\n const result = inspect(form);\n\n const requiredCount = result.issues.filter((i) => i.severity === 'required').length;\n const message = result.isComplete\n ? 'Form is complete. All required fields are filled.'\n : `Form has ${requiredCount} required issue(s) to resolve.`;\n\n return Promise.resolve({\n success: true,\n data: result,\n message,\n });\n },\n };\n\n // markform_apply - Apply patches to update form values\n const markform_apply: MarkformTool<{ patches: Patch[] }, ApplyToolResult> = {\n description:\n 'Apply patches to update form field values. Valid patches are applied even if some fail. ' +\n 'Single values are automatically coerced to arrays for list fields. ' +\n 'Returns applied patches, warnings for coerced values, and rejected patches separately. ' +\n 'Patch operations: set_string, set_number, set_string_list, set_single_select, set_multi_select, ' +\n 'set_checkboxes, set_url, set_url_list, set_date, set_year, set_table, clear_field, skip_field, abort_field.',\n inputSchema: ApplyInputSchema,\n execute: ({ patches }) => {\n const form = sessionStore.getForm();\n const result = applyPatches(form, patches);\n\n // Update the store with the modified form\n sessionStore.updateForm(form);\n\n const warningNote = result.warnings.length > 0 ? ` (${result.warnings.length} coerced)` : '';\n const remaining = result.issues.filter((i) => i.severity === 'required').length;\n\n const message =\n result.applyStatus === 'applied'\n ? `Applied ${patches.length} patch(es)${warningNote}. ${\n result.isComplete\n ? 'Form is now complete!'\n : `${remaining} required issue(s) remaining.`\n }`\n : result.applyStatus === 'partial'\n ? `Applied ${result.appliedPatches.length}/${patches.length} patches${warningNote}. ` +\n `${result.rejectedPatches.length} rejected.`\n : `All patches rejected. Check field IDs and value types.`;\n\n return Promise.resolve({\n success: result.applyStatus !== 'rejected',\n data: result,\n message,\n });\n },\n };\n\n // markform_export - Export schema and values as JSON\n const markform_export: MarkformTool<Record<string, never>, ExportToolResult> = {\n description:\n 'Export the form schema and current values as JSON. Use this to get a machine-readable ' +\n 'representation of the form structure and all field values. Useful for processing or analysis.',\n inputSchema: ExportInputSchema,\n execute: () => {\n const form = sessionStore.getForm();\n\n // Count answered fields\n const answeredCount = Object.values(form.responsesByFieldId).filter(\n (response) => response.state === 'answered',\n ).length;\n\n return Promise.resolve({\n success: true,\n data: {\n schema: form.schema,\n values: form.responsesByFieldId,\n },\n message: `Exported form with ${form.schema.groups.length} group(s) and ${answeredCount} answered field(s).`,\n });\n },\n };\n\n // Build the toolset\n const toolset: MarkformToolSet = {\n markform_inspect,\n markform_apply,\n markform_export,\n };\n\n // Optionally include markform_get_markdown\n if (includeGetMarkdown) {\n const markform_get_markdown: MarkformTool<Record<string, never>, GetMarkdownToolResult> = {\n description:\n 'Get the canonical Markdown representation of the current form. ' +\n 'Use this to see the complete form with all current values in Markform format. ' +\n 'The output is deterministic and round-trip safe.',\n inputSchema: GetMarkdownInputSchema,\n execute: () => {\n const form = sessionStore.getForm();\n const markdown = serializeForm(form);\n\n return Promise.resolve({\n success: true,\n data: {\n markdown,\n },\n message: `Generated Markdown (${markdown.length} characters).`,\n });\n },\n };\n\n toolset.markform_get_markdown = markform_get_markdown;\n }\n\n return toolset;\n}\n\n// =============================================================================\n// Convenience Exports\n// =============================================================================\n\nexport { PatchSchema } from '../engine/coreTypes.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,IAAa,uBAAb,MAAkC;CAChC,AAAQ;CACR,AAAQ;CAER,YAAY,MAAkB,mBAAuC;AACnE,OAAK,OAAO;AACZ,OAAK,oBAAoB,qBAAqB,EAAE;;;;;CAMlD,UAAsB;AACpB,SAAO,KAAK;;;;;CAMd,uBAA0C;AACxC,SAAO,KAAK;;;;;CAMd,WAAW,MAAwB;AACjC,OAAK,OAAO;;;;;;AAsDhB,MAAM,qBAAqB,EACxB,OAAO,EAAE,CAAC,CACV,SAAS,kFAAkF;;;;AAK9F,MAAM,mBAAmB,EACtB,OAAO,EACN,SAAS,EACN,MAAM,YAAY,CAClB,IAAI,EAAE,CACN,IAAI,GAAG,CACP,SACC,2WAID,EACJ,CAAC,CACD,SAAS,6CAA6C;;;;AAKzD,MAAM,oBAAoB,EACvB,OAAO,EAAE,CAAC,CACV,SACC,qGACD;;;;AAKH,MAAM,yBAAyB,EAC5B,OAAO,EAAE,CAAC,CACV,SACC,iHACD;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BH,SAAgB,oBAAoB,SAAsD;CACxF,MAAM,EAAE,cAAc,qBAAqB,SAAS;CA2FpD,MAAMA,UAA2B;EAC/B,kBAzF+E;GAC/E,aACE;GAGF,aAAa;GACb,eAAe;IAEb,MAAM,SAAS,QADF,aAAa,SAAS,CACP;IAE5B,MAAM,gBAAgB,OAAO,OAAO,QAAQ,MAAM,EAAE,aAAa,WAAW,CAAC;IAC7E,MAAM,UAAU,OAAO,aACnB,sDACA,YAAY,cAAc;AAE9B,WAAO,QAAQ,QAAQ;KACrB,SAAS;KACT,MAAM;KACN;KACD,CAAC;;GAEL;EAqEC,gBAlE0E;GAC1E,aACE;GAKF,aAAa;GACb,UAAU,EAAE,cAAc;IACxB,MAAM,OAAO,aAAa,SAAS;IACnC,MAAM,SAAS,aAAa,MAAM,QAAQ;AAG1C,iBAAa,WAAW,KAAK;IAE7B,MAAM,cAAc,OAAO,SAAS,SAAS,IAAI,KAAK,OAAO,SAAS,OAAO,aAAa;IAC1F,MAAM,YAAY,OAAO,OAAO,QAAQ,MAAM,EAAE,aAAa,WAAW,CAAC;IAEzE,MAAM,UACJ,OAAO,gBAAgB,YACnB,WAAW,QAAQ,OAAO,YAAY,YAAY,IAChD,OAAO,aACH,0BACA,GAAG,UAAU,mCAEnB,OAAO,gBAAgB,YACrB,WAAW,OAAO,eAAe,OAAO,GAAG,QAAQ,OAAO,UAAU,YAAY,IAC7E,OAAO,gBAAgB,OAAO,cACjC;AAER,WAAO,QAAQ,QAAQ;KACrB,SAAS,OAAO,gBAAgB;KAChC,MAAM;KACN;KACD,CAAC;;GAEL;EA+BC,iBA5B6E;GAC7E,aACE;GAEF,aAAa;GACb,eAAe;IACb,MAAM,OAAO,aAAa,SAAS;IAGnC,MAAM,gBAAgB,OAAO,OAAO,KAAK,mBAAmB,CAAC,QAC1D,aAAa,SAAS,UAAU,WAClC,CAAC;AAEF,WAAO,QAAQ,QAAQ;KACrB,SAAS;KACT,MAAM;MACJ,QAAQ,KAAK;MACb,QAAQ,KAAK;MACd;KACD,SAAS,sBAAsB,KAAK,OAAO,OAAO,OAAO,gBAAgB,cAAc;KACxF,CAAC;;GAEL;EAOA;AAGD,KAAI,mBAqBF,SAAQ,wBApBkF;EACxF,aACE;EAGF,aAAa;EACb,eAAe;GAEb,MAAM,WAAW,cADJ,aAAa,SAAS,CACC;AAEpC,UAAO,QAAQ,QAAQ;IACrB,SAAS;IACT,MAAM,EACJ,UACD;IACD,SAAS,uBAAuB,SAAS,OAAO;IACjD,CAAC;;EAEL;AAKH,QAAO"}