@madojs/mado 0.12.0 → 0.13.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.
Files changed (154) hide show
  1. package/AGENTS.md +15 -8
  2. package/CHANGELOG.md +58 -0
  3. package/README.md +25 -3
  4. package/dist/src/component.d.ts +3 -1
  5. package/dist/src/component.d.ts.map +1 -0
  6. package/dist/src/component.js +65 -30
  7. package/dist/src/component.js.map +1 -1
  8. package/dist/src/context.d.ts +13 -32
  9. package/dist/src/context.d.ts.map +1 -0
  10. package/dist/src/context.js +73 -48
  11. package/dist/src/context.js.map +1 -1
  12. package/dist/src/css.d.ts +1 -0
  13. package/dist/src/css.d.ts.map +1 -0
  14. package/dist/src/css.js.map +1 -1
  15. package/dist/src/devtools-hook.d.ts +14 -0
  16. package/dist/src/devtools-hook.d.ts.map +1 -0
  17. package/dist/src/devtools-hook.js +27 -0
  18. package/dist/src/devtools-hook.js.map +1 -0
  19. package/dist/src/devtools.d.ts +24 -22
  20. package/dist/src/devtools.d.ts.map +1 -0
  21. package/dist/src/devtools.js +230 -58
  22. package/dist/src/devtools.js.map +1 -1
  23. package/dist/src/diagnostics.d.ts +12 -0
  24. package/dist/src/diagnostics.d.ts.map +1 -0
  25. package/dist/src/diagnostics.js +68 -8
  26. package/dist/src/diagnostics.js.map +1 -1
  27. package/dist/src/each.d.ts +1 -5
  28. package/dist/src/each.d.ts.map +1 -0
  29. package/dist/src/each.js +0 -8
  30. package/dist/src/each.js.map +1 -1
  31. package/dist/src/forms.d.ts +27 -96
  32. package/dist/src/forms.d.ts.map +1 -0
  33. package/dist/src/forms.js +184 -394
  34. package/dist/src/forms.js.map +1 -1
  35. package/dist/src/head.d.ts +1 -0
  36. package/dist/src/head.d.ts.map +1 -0
  37. package/dist/src/head.js +2 -1
  38. package/dist/src/head.js.map +1 -1
  39. package/dist/src/html/bindings.d.ts +1 -0
  40. package/dist/src/html/bindings.d.ts.map +1 -0
  41. package/dist/src/html/bindings.js.map +1 -1
  42. package/dist/src/html/parser.d.ts +3 -4
  43. package/dist/src/html/parser.d.ts.map +1 -0
  44. package/dist/src/html/parser.js +63 -14
  45. package/dist/src/html/parser.js.map +1 -1
  46. package/dist/src/html/template-types.d.ts +1 -0
  47. package/dist/src/html/template-types.d.ts.map +1 -0
  48. package/dist/src/html/template-types.js.map +1 -1
  49. package/dist/src/html/template.d.ts +5 -1
  50. package/dist/src/html/template.d.ts.map +1 -0
  51. package/dist/src/html/template.js +78 -3
  52. package/dist/src/html/template.js.map +1 -1
  53. package/dist/src/index.d.ts +7 -8
  54. package/dist/src/index.d.ts.map +1 -0
  55. package/dist/src/index.js +5 -7
  56. package/dist/src/index.js.map +1 -1
  57. package/dist/src/json.d.ts +3 -0
  58. package/dist/src/json.d.ts.map +1 -0
  59. package/dist/src/json.js +14 -0
  60. package/dist/src/json.js.map +1 -0
  61. package/dist/src/lifecycle.d.ts +1 -0
  62. package/dist/src/lifecycle.d.ts.map +1 -0
  63. package/dist/src/lifecycle.js +3 -2
  64. package/dist/src/lifecycle.js.map +1 -1
  65. package/dist/src/page.d.ts +1 -0
  66. package/dist/src/page.d.ts.map +1 -0
  67. package/dist/src/page.js.map +1 -1
  68. package/dist/src/persisted.d.ts +6 -1
  69. package/dist/src/persisted.d.ts.map +1 -0
  70. package/dist/src/persisted.js +17 -11
  71. package/dist/src/persisted.js.map +1 -1
  72. package/dist/src/resource.d.ts +2 -1
  73. package/dist/src/resource.d.ts.map +1 -0
  74. package/dist/src/resource.js +126 -49
  75. package/dist/src/resource.js.map +1 -1
  76. package/dist/src/router/base.d.ts +1 -0
  77. package/dist/src/router/base.d.ts.map +1 -0
  78. package/dist/src/router/base.js.map +1 -1
  79. package/dist/src/router/manifest.d.ts +1 -0
  80. package/dist/src/router/manifest.d.ts.map +1 -0
  81. package/dist/src/router/manifest.js +89 -148
  82. package/dist/src/router/manifest.js.map +1 -1
  83. package/dist/src/router/match.d.ts +1 -0
  84. package/dist/src/router/match.d.ts.map +1 -0
  85. package/dist/src/router/match.js +19 -5
  86. package/dist/src/router/match.js.map +1 -1
  87. package/dist/src/router/navigation.d.ts +1 -0
  88. package/dist/src/router/navigation.d.ts.map +1 -0
  89. package/dist/src/router/navigation.js.map +1 -1
  90. package/dist/src/signal.d.ts +1 -0
  91. package/dist/src/signal.d.ts.map +1 -0
  92. package/dist/src/signal.js +46 -17
  93. package/dist/src/signal.js.map +1 -1
  94. package/dist/src/static-runtime.d.ts +1 -0
  95. package/dist/src/static-runtime.d.ts.map +1 -0
  96. package/dist/src/static-runtime.js.map +1 -1
  97. package/dist/src/vite/index.d.ts +1 -0
  98. package/dist/src/vite/index.d.ts.map +1 -0
  99. package/dist/src/vite/index.js +4 -3
  100. package/dist/src/vite/index.js.map +1 -1
  101. package/docs/architecture/v1-roadmap.md +19 -0
  102. package/docs/en/10-pages-and-components.md +9 -1
  103. package/docs/en/13-data.md +8 -6
  104. package/docs/en/14-forms.md +66 -219
  105. package/docs/en/15-static-snapshots.md +4 -4
  106. package/docs/en/16-app-architecture.md +3 -2
  107. package/docs/en/20-deployment.md +21 -8
  108. package/docs/en/21-error-handling.md +9 -6
  109. package/docs/en/24-devtools-and-diagnostics.md +45 -0
  110. package/docs/en/30-api-freeze-map.md +8 -9
  111. package/docs/en/32-v1-stability.md +2 -2
  112. package/docs/en/33-migration-0.12-0.13.md +56 -0
  113. package/docs/en/40-llm-guide.md +7 -9
  114. package/docs/en/41-for-backenders.md +13 -9
  115. package/docs/en/42-why-mado.md +2 -2
  116. package/docs/en/README.md +2 -0
  117. package/docs/recipes/nginx/nginx.conf +2 -2
  118. package/llms.txt +25 -7
  119. package/package.json +37 -16
  120. package/scripts/clean.mjs +8 -0
  121. package/scripts/cli/generate.mjs +11 -14
  122. package/scripts/cli/help.mjs +2 -0
  123. package/scripts/cli/index.mjs +14 -6
  124. package/scripts/cli/init.mjs +13 -18
  125. package/scripts/cli/release.mjs +22 -19
  126. package/scripts/cli/run.mjs +5 -3
  127. package/scripts/logger.mjs +117 -0
  128. package/scripts/output-guard.mjs +128 -0
  129. package/scripts/preview.mjs +11 -19
  130. package/scripts/static/browser.mjs +49 -8
  131. package/scripts/static/discover.mjs +4 -1
  132. package/scripts/static.mjs +21 -7
  133. package/starters/default/package.json +4 -4
  134. package/starters/default/tsconfig.node.json +13 -0
  135. package/starters/default/vite.config.ts +0 -3
  136. package/starters/modular/README.md +4 -4
  137. package/starters/modular/package.json +4 -4
  138. package/starters/modular/src/layouts/app-shell.layout.ts +1 -2
  139. package/starters/modular/src/modules/auth/login.page.ts +5 -12
  140. package/starters/modular/src/modules/billing/pages/invoice-detail.page.ts +3 -4
  141. package/starters/modular/src/modules/billing/pages/invoices-list.page.ts +1 -1
  142. package/starters/modular/src/shared/styles/reset.css +21 -1
  143. package/starters/modular/tsconfig.json +10 -1
  144. package/starters/modular/tsconfig.node.json +13 -0
  145. package/starters/modular/vite.config.ts +6 -5
  146. package/dist/src/lazy.d.ts +0 -38
  147. package/dist/src/lazy.js +0 -73
  148. package/dist/src/lazy.js.map +0 -1
  149. package/scripts/bake.mjs +0 -5
  150. package/scripts/docs-lint.mjs +0 -170
  151. package/scripts/package-smoke.mjs +0 -135
  152. package/scripts/release-notes.mjs +0 -66
  153. package/scripts/size-budget.mjs +0 -95
  154. package/starters/modular/src/shared/ui/x-button.component.ts +0 -49
@@ -32,8 +32,4 @@ export interface EachResult<T = unknown> {
32
32
  }
33
33
  export declare const isEachResult: (v: unknown) => v is EachResult;
34
34
  export declare function each<T>(items: readonly T[], keyOf: (item: T, index: number) => EachKey, render: (item: T, index: number) => TemplateResult): EachResult<T>;
35
- /**
36
- * Sugar: returns a ready TemplateResult with the given list as children.
37
- * Convenient when you need a list without a wrapping parent.
38
- */
39
- export declare function list<T>(items: readonly T[], keyOf: (item: T, index: number) => EachKey, render: (item: T, index: number) => TemplateResult): TemplateResult;
35
+ //# sourceMappingURL=each.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"each.d.ts","sourceRoot":"","sources":["../../src/each.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEtC;;;GAGG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO;IACrC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,cAAc,CAAC;CAC7D;AAED,eAAO,MAAM,YAAY,MAAO,OAAO,KAAG,CAAC,IAAI,UAGT,CAAC;AAEvC,wBAAgB,IAAI,CAAC,CAAC,EACpB,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,EAC1C,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,cAAc,GACjD,UAAU,CAAC,CAAC,CAAC,CAEf"}
package/dist/src/each.js CHANGED
@@ -18,18 +18,10 @@
18
18
  * Template usage:
19
19
  * html`<ul>${() => each(items(), t => t.id, t => html`<li>${t.text}</li>`)}</ul>`
20
20
  */
21
- import { html } from "./html/template.js";
22
21
  export const isEachResult = (v) => typeof v === "object" &&
23
22
  v !== null &&
24
23
  v._madoEach === true;
25
24
  export function each(items, keyOf, render) {
26
25
  return { _madoEach: true, items, keyOf, render };
27
26
  }
28
- /**
29
- * Sugar: returns a ready TemplateResult with the given list as children.
30
- * Convenient when you need a list without a wrapping parent.
31
- */
32
- export function list(items, keyOf, render) {
33
- return html `${each(items, keyOf, render)}`;
34
- }
35
27
  //# sourceMappingURL=each.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"each.js","sourceRoot":"","sources":["../../src/each.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAgB1C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAU,EAAmB,EAAE,CAC1D,OAAO,CAAC,KAAK,QAAQ;IACrB,CAAC,KAAK,IAAI;IACT,CAAgB,CAAC,SAAS,KAAK,IAAI,CAAC;AAEvC,MAAM,UAAU,IAAI,CAClB,KAAmB,EACnB,KAA0C,EAC1C,MAAkD;IAElD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI,CAClB,KAAmB,EACnB,KAA0C,EAC1C,MAAkD;IAElD,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"each.js","sourceRoot":"","sources":["../../src/each.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAiBH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAU,EAAmB,EAAE,CAC1D,OAAO,CAAC,KAAK,QAAQ;IACrB,CAAC,KAAK,IAAI;IACT,CAAgB,CAAC,SAAS,KAAK,IAAI,CAAC;AAEvC,MAAM,UAAU,IAAI,CAClB,KAAmB,EACnB,KAA0C,EAC1C,MAAkD;IAElD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACnD,CAAC","sourcesContent":["/**\n * Keyed list rendering.\n *\n * each() returns a special EachResult descriptor. The html binder recognizes\n * it by the `_madoEach` flag and applies keyed reconciliation: on every\n * update it reuses DOM nodes for the same keys and moves them with\n * insertBefore instead of recreating everything.\n *\n * Key differences from a naive implementation:\n * - state lives in the parent's ChildState, not globally by renderFn, so two\n * each() calls with the same render function do not interfere;\n * - DOM nodes are actually reused, so input focus, animations,\n * IntersectionObserver state and .scrollTop survive reorder.\n *\n * API:\n * each(items, item => item.id, item => html`<li>${item.name}</li>`)\n *\n * Template usage:\n * html`<ul>${() => each(items(), t => t.id, t => html`<li>${t.text}</li>`)}</ul>`\n */\n\nimport type { TemplateResult } from \"./html/template-types.js\";\n\nexport type EachKey = string | number;\n\n/**\n * Marker recognised by the html binder.\n * Do not set `_madoEach` yourself — use each().\n */\nexport interface EachResult<T = unknown> {\n readonly _madoEach: true;\n readonly items: readonly T[];\n readonly keyOf: (item: T, index: number) => EachKey;\n readonly render: (item: T, index: number) => TemplateResult;\n}\n\nexport const isEachResult = (v: unknown): v is EachResult =>\n typeof v === \"object\" &&\n v !== null &&\n (v as EachResult)._madoEach === true;\n\nexport function each<T>(\n items: readonly T[],\n keyOf: (item: T, index: number) => EachKey,\n render: (item: T, index: number) => TemplateResult,\n): EachResult<T> {\n return { _madoEach: true, items, keyOf, render };\n}\n"]}
@@ -1,105 +1,36 @@
1
1
  /**
2
- * Forms without pain. Built on native `<form>` submit/input events plus a
3
- * small schema validator whose rules mirror common HTML constraints.
4
- *
5
- * const f = useForm({
6
- * email: { required: true, type: 'email' },
7
- * age: { min: 18 },
8
- * });
9
- *
10
- * html`
11
- * <form @submit=${f.onSubmit(async values => { await save(values) })}>
12
- * <input name="email" .value=${() => f.values().email ?? ''}
13
- * @input=${f.onInput} />
14
- * ${() => f.errors().email ? html`<err>${f.errors().email}</err>` : null}
15
- *
16
- * <input name="age" type="number" .value=${() => f.values().age ?? ''}
17
- * @input=${f.onInput} />
18
- *
19
- * <button ?disabled=${() => !f.isValid() || f.submitting()}>Save</button>
20
- * </form>
21
- * `;
22
- *
23
- * What's inside:
24
- * - validation rules mirror common HTML constraints
25
- * (required, min, max, pattern, type=email/url/number, etc.);
26
- * - custom rules via a validate(values) function returning
27
- * { field: 'msg' } or null;
28
- * - all fields are automatically "touched" on blur — errors
29
- * are shown only after user interaction;
30
- * - submit() is aborted if the form is invalid.
31
- *
32
- * No Yup/Zod/Formik dependencies. If you really want them —
33
- * pass your own validate(values) and wire it to anything.
2
+ * Typed form state over the browser's native form and constraint-validation
3
+ * model. HTML owns required/type/min/max/pattern; Mado owns reactive state,
4
+ * touched/dirty flags, async validation cancellation and submit state.
34
5
  */
35
- import { type Signal, type Computed } from "./signal.js";
36
- export type FormValue = string | number | boolean | null | undefined | FormValue[] | {
37
- [key: string]: FormValue;
38
- };
39
- export type FormValues = Record<string, FormValue>;
40
- export type FormErrors = Record<string, string | undefined>;
41
- export type FieldValidator<V extends FormValues = FormValues> = (value: FormValue, values: V, path: string) => string | null | undefined;
42
- export type AsyncFieldValidator<V extends FormValues = FormValues> = (value: FormValue, values: V, path: string) => Promise<string | null | undefined>;
43
- /** Field declaration. Rules intentionally match common HTML constraints. */
44
- export interface FieldSchema {
45
- required?: boolean;
46
- type?: "text" | "email" | "url" | "number" | "tel" | "password";
47
- min?: number;
48
- max?: number;
49
- minLength?: number;
50
- maxLength?: number;
51
- pattern?: string;
52
- /** Default value */
53
- default?: FormValue;
54
- /** Synchronous custom validator for this field. */
55
- validate?: FieldValidator;
56
- /** Asynchronous custom validator for this field. */
57
- validateAsync?: AsyncFieldValidator;
6
+ import { type Computed, type Signal } from "./signal.js";
7
+ export type FormValue = unknown;
8
+ export type FormValues = Record<string, unknown>;
9
+ export type FormErrors<V extends FormValues = FormValues> = Partial<Record<string, string>>;
10
+ export type FormTouched<V extends FormValues = FormValues> = Partial<Record<string, boolean>>;
11
+ export interface FormValidationContext {
12
+ signal: AbortSignal;
13
+ form: HTMLFormElement | null;
58
14
  }
59
- export type Schema = Record<string, FieldSchema>;
15
+ export type FormValidator<V extends FormValues> = (values: Readonly<V>, context: FormValidationContext) => FormErrors<V> | null | Promise<FormErrors<V> | null>;
60
16
  export interface UseFormOptions<V extends FormValues> {
61
- /** Custom validator: returns errors or null. */
62
- validate?: (values: V) => FormErrors | null;
63
- /** Async custom validator, usually for server-backed uniqueness checks. */
64
- validateAsync?: (values: V) => Promise<FormErrors | null>;
65
- }
66
- export interface FieldArrayApi<T extends FormValue = FormValue> {
67
- /** Current array value. */
68
- items: () => T[];
69
- /** Field name helper: `items.0.title`. */
70
- path(index: number, field?: string): string;
71
- append(value: T): void;
72
- prepend(value: T): void;
73
- insert(index: number, value: T): void;
74
- remove(index: number): void;
75
- move(from: number, to: number): void;
76
- replace(items: readonly T[]): void;
77
- set(index: number, value: T): void;
17
+ initial: V;
18
+ validate?: FormValidator<V>;
78
19
  }
79
20
  export interface FormApi<V extends FormValues> {
80
21
  values: Signal<V>;
81
- errors: () => FormErrors;
82
- touched: Signal<Record<string, boolean>>;
22
+ errors: Computed<FormErrors<V>>;
23
+ touched: Signal<FormTouched<V>>;
24
+ dirty: Computed<boolean>;
83
25
  submitting: Signal<boolean>;
84
- validating: Computed<boolean>;
85
- validatingFields: Signal<Record<string, boolean>>;
86
- isValid: () => boolean;
87
- /** Binding for @input/@change: automatically picks up name+value+type. */
88
- onInput: (e: Event) => void;
89
- /** Binding for @blur: marks the field as touched. */
90
- onBlur: (e: Event) => void;
91
- /** Submit wrapper: calls handler only if the form is valid. */
92
- onSubmit: (handler: (values: V) => void | Promise<void>) => (e: Event) => void;
93
- /** Set a field value programmatically. */
94
- setField<K extends keyof V & string>(name: K, value: V[K]): void;
95
- setField(name: string, value: FormValue): void;
96
- /** Run async validators for a single field path. */
97
- validateField(name: string): Promise<boolean>;
98
- /** Run all sync + async validators and update errors. */
99
- validate(): Promise<boolean>;
100
- /** Helper for dynamic arrays stored under one form field. */
101
- array<T extends FormValue = FormValue>(name: keyof V & string): FieldArrayApi<T>;
102
- /** Reset to defaults. */
103
- reset(): void;
26
+ validating: Signal<boolean>;
27
+ isValid: Computed<boolean>;
28
+ onInput(event: Event): void;
29
+ onBlur(event: Event): void;
30
+ onSubmit(handler: (values: Readonly<V>, event: SubmitEvent) => void | Promise<void>): (event: SubmitEvent) => void;
31
+ setField<K extends Extract<keyof V, string>>(name: K, value: V[K]): void;
32
+ reset(nextInitial?: V): void;
33
+ validate(form?: HTMLFormElement | null): Promise<boolean>;
104
34
  }
105
- export declare function useForm<V extends FormValues>(schema: Schema, options?: UseFormOptions<V>): FormApi<V>;
35
+ export declare function useForm<V extends FormValues>(options: UseFormOptions<V>): FormApi<V>;
36
+ //# sourceMappingURL=forms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["../../src/forms.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAoB,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAG3E,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC;AAChC,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACjD,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI,OAAO,CACjE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CACvB,CAAC;AACF,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI,OAAO,CAClE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACxB,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,UAAU,IAAI,CAChD,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EACnB,OAAO,EAAE,qBAAqB,KAC3B,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAE1D,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,UAAU;IAClD,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,UAAU;IAC3C,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAClB,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B,QAAQ,CACN,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACzE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAChC,QAAQ,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACzE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAID,wBAAgB,OAAO,CAAC,CAAC,SAAS,UAAU,EAC1C,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAuJZ"}