foldkit 0.16.0 → 0.18.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 (113) hide show
  1. package/README.md +3 -8
  2. package/dist/{fieldValidation.d.ts → fieldValidation/index.d.ts} +9 -9
  3. package/dist/fieldValidation/index.d.ts.map +1 -0
  4. package/dist/{fieldValidation.js → fieldValidation/index.js} +5 -4
  5. package/dist/fieldValidation/public.d.ts +3 -0
  6. package/dist/fieldValidation/public.d.ts.map +1 -0
  7. package/dist/fieldValidation/public.js +1 -0
  8. package/dist/{html.d.ts → html/index.d.ts} +40 -4
  9. package/dist/html/index.d.ts.map +1 -0
  10. package/dist/{html.js → html/index.js} +31 -4
  11. package/dist/html/public.d.ts +3 -0
  12. package/dist/html/public.d.ts.map +1 -0
  13. package/dist/html/public.js +1 -0
  14. package/dist/index.d.ts +9 -8
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +9 -8
  17. package/dist/{navigation.d.ts → navigation/index.d.ts} +1 -1
  18. package/dist/navigation/index.d.ts.map +1 -0
  19. package/dist/navigation/public.d.ts +2 -0
  20. package/dist/navigation/public.d.ts.map +1 -0
  21. package/dist/navigation/public.js +1 -0
  22. package/dist/route/index.d.ts +2 -0
  23. package/dist/route/index.d.ts.map +1 -0
  24. package/dist/{parser.d.ts → route/parser.d.ts} +1 -1
  25. package/dist/route/parser.d.ts.map +1 -0
  26. package/dist/route/public.d.ts +3 -0
  27. package/dist/route/public.d.ts.map +1 -0
  28. package/dist/route/public.js +1 -0
  29. package/dist/runtime/browserListeners.d.ts.map +1 -1
  30. package/dist/runtime/browserListeners.js +2 -2
  31. package/dist/runtime/public.d.ts +5 -0
  32. package/dist/runtime/public.d.ts.map +1 -0
  33. package/dist/runtime/public.js +2 -0
  34. package/dist/runtime/runtime.d.ts +1 -1
  35. package/dist/runtime/runtime.d.ts.map +1 -1
  36. package/dist/runtime/urlRequest.d.ts +4 -4
  37. package/dist/runtime/urlRequest.d.ts.map +1 -1
  38. package/dist/runtime/urlRequest.js +3 -2
  39. package/dist/schema/index.d.ts +26 -0
  40. package/dist/schema/index.d.ts.map +1 -0
  41. package/dist/schema/index.js +14 -0
  42. package/dist/schema/public.d.ts +3 -0
  43. package/dist/schema/public.d.ts.map +1 -0
  44. package/dist/schema/public.js +1 -0
  45. package/dist/{struct.d.ts → struct/index.d.ts} +2 -1
  46. package/dist/struct/index.d.ts.map +1 -0
  47. package/dist/struct/index.js +3 -0
  48. package/dist/struct/public.d.ts +2 -0
  49. package/dist/struct/public.d.ts.map +1 -0
  50. package/dist/struct/public.js +1 -0
  51. package/dist/task/index.d.ts +109 -0
  52. package/dist/task/index.d.ts.map +1 -0
  53. package/dist/task/index.js +168 -0
  54. package/dist/task/public.d.ts +2 -0
  55. package/dist/task/public.d.ts.map +1 -0
  56. package/dist/task/public.js +1 -0
  57. package/dist/ui/dialog/index.d.ts +46 -0
  58. package/dist/ui/dialog/index.d.ts.map +1 -0
  59. package/dist/ui/dialog/index.js +67 -0
  60. package/dist/ui/dialog/public.d.ts +3 -0
  61. package/dist/ui/dialog/public.d.ts.map +1 -0
  62. package/dist/ui/dialog/public.js +1 -0
  63. package/dist/ui/disclosure/index.d.ts +47 -0
  64. package/dist/ui/disclosure/index.d.ts.map +1 -0
  65. package/dist/ui/disclosure/index.js +90 -0
  66. package/dist/ui/disclosure/public.d.ts +3 -0
  67. package/dist/ui/disclosure/public.d.ts.map +1 -0
  68. package/dist/ui/disclosure/public.js +1 -0
  69. package/dist/ui/index.d.ts +4 -1
  70. package/dist/ui/index.d.ts.map +1 -1
  71. package/dist/ui/index.js +4 -1
  72. package/dist/ui/keyboard.d.ts +4 -0
  73. package/dist/ui/keyboard.d.ts.map +1 -0
  74. package/dist/ui/keyboard.js +7 -0
  75. package/dist/ui/menu/index.d.ts +136 -0
  76. package/dist/ui/menu/index.d.ts.map +1 -0
  77. package/dist/ui/menu/index.js +297 -0
  78. package/dist/ui/menu/public.d.ts +3 -0
  79. package/dist/ui/menu/public.d.ts.map +1 -0
  80. package/dist/ui/menu/public.js +1 -0
  81. package/dist/ui/tabs/index.d.ts +76 -0
  82. package/dist/ui/tabs/index.d.ts.map +1 -0
  83. package/dist/ui/{tabs.js → tabs/index.js} +25 -25
  84. package/dist/ui/tabs/public.d.ts +3 -0
  85. package/dist/ui/tabs/public.d.ts.map +1 -0
  86. package/dist/ui/tabs/public.js +1 -0
  87. package/dist/{url.d.ts → url/index.d.ts} +2 -2
  88. package/dist/url/index.d.ts.map +1 -0
  89. package/dist/{url.js → url/index.js} +1 -1
  90. package/dist/url/public.d.ts +2 -0
  91. package/dist/url/public.d.ts.map +1 -0
  92. package/dist/url/public.js +1 -0
  93. package/package.json +32 -19
  94. package/dist/fieldValidation.d.ts.map +0 -1
  95. package/dist/html.d.ts.map +0 -1
  96. package/dist/navigation.d.ts.map +0 -1
  97. package/dist/parser.d.ts.map +0 -1
  98. package/dist/route.d.ts +0 -2
  99. package/dist/route.d.ts.map +0 -1
  100. package/dist/schema.d.ts +0 -20
  101. package/dist/schema.d.ts.map +0 -1
  102. package/dist/schema.js +0 -16
  103. package/dist/struct.d.ts.map +0 -1
  104. package/dist/struct.js +0 -2
  105. package/dist/task.d.ts +0 -64
  106. package/dist/task.d.ts.map +0 -1
  107. package/dist/task.js +0 -87
  108. package/dist/ui/tabs.d.ts +0 -65
  109. package/dist/ui/tabs.d.ts.map +0 -1
  110. package/dist/url.d.ts.map +0 -1
  111. /package/dist/{navigation.js → navigation/index.js} +0 -0
  112. /package/dist/{route.js → route/index.js} +0 -0
  113. /package/dist/{parser.js → route/parser.js} +0 -0
@@ -1,11 +1,12 @@
1
1
  import { Schema as S } from 'effect';
2
+ import { ts } from '../schema';
2
3
  import { Url } from '../url';
3
4
  /** A URL request to a page within the application (same origin). */
4
- export const Internal = S.TaggedStruct('Internal', {
5
+ export const Internal = ts('Internal', {
5
6
  url: Url,
6
7
  });
7
8
  /** A URL request to an external page (different origin). */
8
- export const External = S.TaggedStruct('External', {
9
+ export const External = ts('External', {
9
10
  href: S.String,
10
11
  });
11
12
  /** Union of `Internal` and `External` URL request types. */
@@ -0,0 +1,26 @@
1
+ import { Schema as S } from 'effect';
2
+ /** A `TaggedStruct` schema that can be called directly as a constructor: `Foo({ count: 1 })` instead of `Foo.make({ count: 1 })`. */
3
+ export type CallableTaggedStruct<Tag extends string, Fields extends S.Struct.Fields> = S.TaggedStruct<Tag, Fields> & (keyof Fields extends never ? (value?: Parameters<S.TaggedStruct<Tag, Fields>['make']>[0] | void) => S.Simplify<S.Struct.Type<{
4
+ readonly _tag: S.tag<Tag>;
5
+ } & Fields>> : (value: Parameters<S.TaggedStruct<Tag, Fields>['make']>[0]) => S.Simplify<S.Struct.Type<{
6
+ readonly _tag: S.tag<Tag>;
7
+ } & Fields>>);
8
+ /**
9
+ * A wrapper around Effect Schema.taggedStruct that returns a callable schema.
10
+ *
11
+ * Abbreviated as `ts` because it's used so frequently throughout Foldkit applications.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Simple tag — callable with no args
16
+ * const Reset = ts('Reset')
17
+ * Reset() // { _tag: 'Reset' }
18
+ *
19
+ * // Tag with fields — callable with fields
20
+ * const SetCount = ts('SetCount', { count: S.Number })
21
+ * SetCount({ count: 1 }) // { _tag: 'SetCount', count: 1 }
22
+ * ```
23
+ */
24
+ export declare function ts<Tag extends string>(tag: Tag): CallableTaggedStruct<Tag, {}>;
25
+ export declare function ts<Tag extends string, Fields extends S.Struct.Fields>(tag: Tag, fields: Fields): CallableTaggedStruct<Tag, Fields>;
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAEpC,qIAAqI;AACrI,MAAM,MAAM,oBAAoB,CAC9B,GAAG,SAAS,MAAM,EAClB,MAAM,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,IAC5B,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,GAC7B,CAAC,MAAM,MAAM,SAAS,KAAK,GACvB,CACE,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,KAC9D,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;CAAE,GAAG,MAAM,CAAC,CAAC,GACtE,CACE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KACtD,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;CAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;AAe7E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,EAAE,CAAC,GAAG,SAAS,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,oBAAoB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AAC/E,wBAAgB,EAAE,CAAC,GAAG,SAAS,MAAM,EAAE,MAAM,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,EACnE,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,GACb,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { Schema as S } from 'effect';
2
+ const makeCallable = (schema) =>
3
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
4
+ new Proxy(schema, {
5
+ apply(_target, _thisArg, argumentsList) {
6
+ return schema.make(argumentsList[0]);
7
+ },
8
+ get(target, property, receiver) {
9
+ return Reflect.get(target, property, receiver);
10
+ },
11
+ });
12
+ export function ts(tag, fields = {}) {
13
+ return makeCallable(S.TaggedStruct(tag, fields));
14
+ }
@@ -0,0 +1,3 @@
1
+ export { ts } from './index';
2
+ export type { CallableTaggedStruct } from './index';
3
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/schema/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAC5B,YAAY,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1 @@
1
+ export { ts } from './index';
@@ -7,9 +7,10 @@ type StrictKeys<O, T> = T extends Record<string, any> ? Exclude<keyof T, keyof O
7
7
  type Evolved<O, T> = {
8
8
  [K in keyof O]: K extends keyof T ? T[K] extends (a: any) => infer R ? R : O[K] : O[K];
9
9
  };
10
+ /** Immutably updates fields of a struct by applying transform functions. Wraps Effect's `Struct.evolve` with stricter key checking. */
10
11
  export declare const evo: {
11
12
  <O, const T extends EvolveTransform<O>>(t: StrictKeys<O, T>): (obj: O) => Evolved<O, T>;
12
13
  <O, const T extends EvolveTransform<O>>(obj: O, t: StrictKeys<O, T>): Evolved<O, T>;
13
14
  };
14
15
  export {};
15
- //# sourceMappingURL=struct.d.ts.map
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/struct/index.ts"],"names":[],"mappings":"AAEA,KAAK,eAAe,CAAC,CAAC,IAAI,OAAO,CAAC;KAC/B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;CAClC,CAAC,CAAA;AAEF,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,IAClB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,SAAS,KAAK,GACrC,CAAC,GACD,CAAC,GAAG;KACD,CAAC,IAAI,gBAAgB,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,KAAK;CACnE,GACH,KAAK,CAAA;AAEX,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI;KAClB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAC7B,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,MAAM,CAAC,GAC9B,CAAC,GACD,CAAC,CAAC,CAAC,CAAC,GACN,CAAC,CAAC,CAAC,CAAC;CACT,CAAA;AAED,uIAAuI;AACvI,eAAO,MAAM,GAAG,EAAE;IAChB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,eAAe,CAAC,CAAC,CAAC,EACpC,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAClB,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC5B,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,eAAe,CAAC,CAAC,CAAC,EACpC,GAAG,EAAE,CAAC,EACN,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAClB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CACD,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { Struct } from 'effect';
2
+ /** Immutably updates fields of a struct by applying transform functions. Wraps Effect's `Struct.evolve` with stricter key checking. */
3
+ export const evo = Struct.evolve;
@@ -0,0 +1,2 @@
1
+ export { evo } from './index';
2
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/struct/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1 @@
1
+ export { evo } from './index';
@@ -0,0 +1,109 @@
1
+ import { DateTime, Duration, Effect } from 'effect';
2
+ /**
3
+ * Creates a command that gets the current UTC time and passes it to a message constructor.
4
+ * This is similar to Elm's `Task.perform` with `Time.now`.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * Task.getTime(utc => GotTime({ utc }))
9
+ * ```
10
+ */
11
+ export declare const getTime: <Message>(f: (utc: DateTime.Utc) => Message) => Effect.Effect<Message>;
12
+ /**
13
+ * Creates a command that gets the system timezone and passes it to a message constructor.
14
+ * This is similar to Elm's `Task.perform` with `Time.here`.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * Task.getTimeZone(zone => GotTimeZone({ zone }))
19
+ * ```
20
+ */
21
+ export declare const getTimeZone: <Message>(f: (zone: DateTime.TimeZone) => Message) => Effect.Effect<Message>;
22
+ /**
23
+ * Creates a command that gets the current time in the system timezone and passes it to a message constructor.
24
+ * This combines both time and timezone in a single task.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * Task.getZonedTime(zoned => GotTime({ zoned }))
29
+ * ```
30
+ */
31
+ export declare const getZonedTime: <Message>(f: (zoned: DateTime.Zoned) => Message) => Effect.Effect<Message>;
32
+ /**
33
+ * Creates a command that gets the current time in a specific timezone and passes it to a message constructor.
34
+ * If the timezone is invalid, the effect will fail with an error string.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * Task.getZonedTimeIn('America/New_York', zoned => GotNYTime({ zoned }))
39
+ * ```
40
+ */
41
+ export declare const getZonedTimeIn: <Message>(zoneId: string, f: (zoned: DateTime.Zoned) => Message) => Effect.Effect<Message, string>;
42
+ /**
43
+ * Creates a command that focuses an element by selector and passes the result to a message constructor.
44
+ * Passes true if the element was found and focused, false otherwise.
45
+ * Uses requestAnimationFrame to ensure the DOM tree is updated and nodes exist before attempting to focus.
46
+ * This follows the same approach as Elm's Browser.Dom.focus.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * Task.focus('#email-input', success => InputFocused({ success }))
51
+ * ```
52
+ */
53
+ export declare const focus: <Message>(selector: string, f: (success: boolean) => Message) => Effect.Effect<Message>;
54
+ /**
55
+ * Creates a command that opens a dialog element as a modal using `showModal()`.
56
+ * Passes true if the element was found and opened, false otherwise.
57
+ * Uses requestAnimationFrame to ensure the DOM tree is updated and nodes exist before attempting to show.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * Task.showModal('#my-dialog', success => ModalOpened({ success }))
62
+ * ```
63
+ */
64
+ export declare const showModal: <Message>(selector: string, f: (success: boolean) => Message) => Effect.Effect<Message>;
65
+ /**
66
+ * Creates a command that closes a dialog element using `.close()`.
67
+ * Passes true if the element was found and closed, false otherwise.
68
+ * Uses requestAnimationFrame to ensure the DOM tree is updated and nodes exist before attempting to close.
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * Task.closeModal('#my-dialog', success => ModalClosed({ success }))
73
+ * ```
74
+ */
75
+ export declare const closeModal: <Message>(selector: string, f: (success: boolean) => Message) => Effect.Effect<Message>;
76
+ /**
77
+ * Creates a command that resolves to a message after a delay.
78
+ * Useful for debouncing, such as clearing a typeahead search query.
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * Task.delay(350, () => SearchCleared({ version: model.searchVersion }))
83
+ * Task.delay(Duration.seconds(1), () => TimedOut())
84
+ * ```
85
+ */
86
+ export declare const delay: <Message>(duration: Duration.DurationInput, f: () => Message) => Effect.Effect<Message>;
87
+ /**
88
+ * Creates a command that generates a random integer between min (inclusive) and max (exclusive)
89
+ * and passes it to a message constructor.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * Task.randomInt(0, 100, value => GotRandom({ value }))
94
+ * ```
95
+ */
96
+ /**
97
+ * Creates a command that scrolls an element into view by selector and passes the result to a message constructor.
98
+ * Passes true if the element was found and scrolled, false otherwise.
99
+ * Uses requestAnimationFrame to ensure the DOM tree is updated and nodes exist before attempting to scroll.
100
+ * Uses `{ block: 'nearest' }` to avoid unnecessary scrolling when the element is already visible.
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * Task.scrollIntoView('#active-item', success => ItemScrolled({ success }))
105
+ * ```
106
+ */
107
+ export declare const scrollIntoView: <Message>(selector: string, f: (success: boolean) => Message) => Effect.Effect<Message>;
108
+ export declare const randomInt: <Message>(min: number, max: number, f: (value: number) => Message) => Effect.Effect<Message>;
109
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/task/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,GAAI,OAAO,EAC7B,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,KAAK,OAAO,KAChC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAgC,CAAA;AAExD;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,EACjC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,KAAK,OAAO,KACtC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAmD,CAAA;AAE3E;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,EAClC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,KAAK,OAAO,KACpC,MAAM,CAAC,MAAM,CAAC,OAAO,CAMpB,CAAA;AAEJ;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,EACpC,QAAQ,MAAM,EACd,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,KAAK,OAAO,KACpC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAS5B,CAAA;AAEJ;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,GAAI,OAAO,EAC3B,UAAU,MAAM,EAChB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,KAC/B,MAAM,CAAC,MAAM,CAAC,OAAO,CAWpB,CAAA;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,GAAI,OAAO,EAC/B,UAAU,MAAM,EAChB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,KAC/B,MAAM,CAAC,MAAM,CAAC,OAAO,CAWpB,CAAA;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,EAChC,UAAU,MAAM,EAChB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,KAC/B,MAAM,CAAC,MAAM,CAAC,OAAO,CAWpB,CAAA;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,KAAK,GAAI,OAAO,EAC3B,UAAU,QAAQ,CAAC,aAAa,EAChC,GAAG,MAAM,OAAO,KACf,MAAM,CAAC,MAAM,CAAC,OAAO,CAIpB,CAAA;AAEJ;;;;;;;;GAQG;AACH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,EACpC,UAAU,MAAM,EAChB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,KAC/B,MAAM,CAAC,MAAM,CAAC,OAAO,CAWpB,CAAA;AAEJ,eAAO,MAAM,SAAS,GAAI,OAAO,EAC/B,KAAK,MAAM,EACX,KAAK,MAAM,EACX,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,KAC5B,MAAM,CAAC,MAAM,CAAC,OAAO,CAC6C,CAAA"}
@@ -0,0 +1,168 @@
1
+ import { DateTime, Effect, Option } from 'effect';
2
+ /**
3
+ * Creates a command that gets the current UTC time and passes it to a message constructor.
4
+ * This is similar to Elm's `Task.perform` with `Time.now`.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * Task.getTime(utc => GotTime({ utc }))
9
+ * ```
10
+ */
11
+ export const getTime = (f) => Effect.map(DateTime.now, f);
12
+ /**
13
+ * Creates a command that gets the system timezone and passes it to a message constructor.
14
+ * This is similar to Elm's `Task.perform` with `Time.here`.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * Task.getTimeZone(zone => GotTimeZone({ zone }))
19
+ * ```
20
+ */
21
+ export const getTimeZone = (f) => Effect.sync(() => f(DateTime.zoneMakeLocal()));
22
+ /**
23
+ * Creates a command that gets the current time in the system timezone and passes it to a message constructor.
24
+ * This combines both time and timezone in a single task.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * Task.getZonedTime(zoned => GotTime({ zoned }))
29
+ * ```
30
+ */
31
+ export const getZonedTime = (f) => Effect.gen(function* () {
32
+ const utc = yield* DateTime.now;
33
+ const zone = DateTime.zoneMakeLocal();
34
+ const zoned = DateTime.setZone(utc, zone);
35
+ return f(zoned);
36
+ });
37
+ /**
38
+ * Creates a command that gets the current time in a specific timezone and passes it to a message constructor.
39
+ * If the timezone is invalid, the effect will fail with an error string.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * Task.getZonedTimeIn('America/New_York', zoned => GotNYTime({ zoned }))
44
+ * ```
45
+ */
46
+ export const getZonedTimeIn = (zoneId, f) => Effect.gen(function* () {
47
+ const utc = yield* DateTime.now;
48
+ const maybeZone = DateTime.zoneMakeNamed(zoneId);
49
+ if (Option.isNone(maybeZone)) {
50
+ return yield* Effect.fail(`Invalid timezone: ${zoneId}`);
51
+ }
52
+ const zoned = DateTime.setZone(utc, maybeZone.value);
53
+ return f(zoned);
54
+ });
55
+ /**
56
+ * Creates a command that focuses an element by selector and passes the result to a message constructor.
57
+ * Passes true if the element was found and focused, false otherwise.
58
+ * Uses requestAnimationFrame to ensure the DOM tree is updated and nodes exist before attempting to focus.
59
+ * This follows the same approach as Elm's Browser.Dom.focus.
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * Task.focus('#email-input', success => InputFocused({ success }))
64
+ * ```
65
+ */
66
+ export const focus = (selector, f) => Effect.async((resume) => {
67
+ requestAnimationFrame(() => {
68
+ const element = document.querySelector(selector);
69
+ if (element instanceof HTMLElement) {
70
+ element.focus();
71
+ resume(Effect.succeed(f(true)));
72
+ }
73
+ else {
74
+ resume(Effect.succeed(f(false)));
75
+ }
76
+ });
77
+ });
78
+ /**
79
+ * Creates a command that opens a dialog element as a modal using `showModal()`.
80
+ * Passes true if the element was found and opened, false otherwise.
81
+ * Uses requestAnimationFrame to ensure the DOM tree is updated and nodes exist before attempting to show.
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * Task.showModal('#my-dialog', success => ModalOpened({ success }))
86
+ * ```
87
+ */
88
+ export const showModal = (selector, f) => Effect.async((resume) => {
89
+ requestAnimationFrame(() => {
90
+ const element = document.querySelector(selector);
91
+ if (element instanceof HTMLDialogElement) {
92
+ element.showModal();
93
+ resume(Effect.succeed(f(true)));
94
+ }
95
+ else {
96
+ resume(Effect.succeed(f(false)));
97
+ }
98
+ });
99
+ });
100
+ /**
101
+ * Creates a command that closes a dialog element using `.close()`.
102
+ * Passes true if the element was found and closed, false otherwise.
103
+ * Uses requestAnimationFrame to ensure the DOM tree is updated and nodes exist before attempting to close.
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * Task.closeModal('#my-dialog', success => ModalClosed({ success }))
108
+ * ```
109
+ */
110
+ export const closeModal = (selector, f) => Effect.async((resume) => {
111
+ requestAnimationFrame(() => {
112
+ const element = document.querySelector(selector);
113
+ if (element instanceof HTMLDialogElement) {
114
+ element.close();
115
+ resume(Effect.succeed(f(true)));
116
+ }
117
+ else {
118
+ resume(Effect.succeed(f(false)));
119
+ }
120
+ });
121
+ });
122
+ /**
123
+ * Creates a command that resolves to a message after a delay.
124
+ * Useful for debouncing, such as clearing a typeahead search query.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * Task.delay(350, () => SearchCleared({ version: model.searchVersion }))
129
+ * Task.delay(Duration.seconds(1), () => TimedOut())
130
+ * ```
131
+ */
132
+ export const delay = (duration, f) => Effect.gen(function* () {
133
+ yield* Effect.sleep(duration);
134
+ return f();
135
+ });
136
+ /**
137
+ * Creates a command that generates a random integer between min (inclusive) and max (exclusive)
138
+ * and passes it to a message constructor.
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * Task.randomInt(0, 100, value => GotRandom({ value }))
143
+ * ```
144
+ */
145
+ /**
146
+ * Creates a command that scrolls an element into view by selector and passes the result to a message constructor.
147
+ * Passes true if the element was found and scrolled, false otherwise.
148
+ * Uses requestAnimationFrame to ensure the DOM tree is updated and nodes exist before attempting to scroll.
149
+ * Uses `{ block: 'nearest' }` to avoid unnecessary scrolling when the element is already visible.
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * Task.scrollIntoView('#active-item', success => ItemScrolled({ success }))
154
+ * ```
155
+ */
156
+ export const scrollIntoView = (selector, f) => Effect.async((resume) => {
157
+ requestAnimationFrame(() => {
158
+ const element = document.querySelector(selector);
159
+ if (element instanceof HTMLElement) {
160
+ element.scrollIntoView({ block: 'nearest' });
161
+ resume(Effect.succeed(f(true)));
162
+ }
163
+ else {
164
+ resume(Effect.succeed(f(false)));
165
+ }
166
+ });
167
+ });
168
+ export const randomInt = (min, max, f) => Effect.sync(() => f(Math.floor(Math.random() * (max - min)) + min));
@@ -0,0 +1,2 @@
1
+ export { getTime, getTimeZone, getZonedTime, getZonedTimeIn, focus, showModal, closeModal, delay, scrollIntoView, randomInt, } from './index';
2
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/task/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,WAAW,EACX,YAAY,EACZ,cAAc,EACd,KAAK,EACL,SAAS,EACT,UAAU,EACV,KAAK,EACL,cAAc,EACd,SAAS,GACV,MAAM,SAAS,CAAA"}
@@ -0,0 +1 @@
1
+ export { getTime, getTimeZone, getZonedTime, getZonedTimeIn, focus, showModal, closeModal, delay, scrollIntoView, randomInt, } from './index';
@@ -0,0 +1,46 @@
1
+ import { Schema as S } from 'effect';
2
+ import type { Html } from '../../html';
3
+ import type { Command } from '../../runtime/runtime';
4
+ /** Schema for the dialog component's state, tracking its unique ID and open/closed status. */
5
+ export declare const Model: S.Struct<{
6
+ id: typeof S.String;
7
+ isOpen: typeof S.Boolean;
8
+ }>;
9
+ export type Model = typeof Model.Type;
10
+ /** Sent when the dialog should open. Triggers the showModal command. */
11
+ export declare const Opened: import("../../schema").CallableTaggedStruct<"Opened", {}>;
12
+ /** Sent when the dialog should close (Escape key, backdrop click, or programmatic). Triggers the closeModal command. */
13
+ export declare const Closed: import("../../schema").CallableTaggedStruct<"Closed", {}>;
14
+ /** Placeholder message used when no action is needed, such as after a showModal or closeModal command completes. */
15
+ export declare const NoOp: import("../../schema").CallableTaggedStruct<"NoOp", {}>;
16
+ /** Union of all messages the dialog component can produce. */
17
+ export declare const Message: S.Union<[import("../../schema").CallableTaggedStruct<"Opened", {}>, import("../../schema").CallableTaggedStruct<"Closed", {}>, import("../../schema").CallableTaggedStruct<"NoOp", {}>]>;
18
+ export type Opened = typeof Opened.Type;
19
+ export type Closed = typeof Closed.Type;
20
+ export type NoOp = typeof NoOp.Type;
21
+ export type Message = typeof Message.Type;
22
+ /** Configuration for creating a dialog model with `init`. */
23
+ export type InitConfig = Readonly<{
24
+ id: string;
25
+ isOpen?: boolean;
26
+ }>;
27
+ /** Creates an initial dialog model from a config. Defaults to closed. */
28
+ export declare const init: (config: InitConfig) => Model;
29
+ /** Processes a dialog message and returns the next model and commands. */
30
+ export declare const update: (model: Model, message: Message) => [Model, ReadonlyArray<Command<Message>>];
31
+ /** Returns the ID used for `aria-labelledby` on the dialog. Apply this to your title element. */
32
+ export declare const titleId: (model: Model) => string;
33
+ /** Returns the ID used for `aria-describedby` on the dialog. Apply this to your description element. */
34
+ export declare const descriptionId: (model: Model) => string;
35
+ /** Configuration for rendering a dialog with `view`. */
36
+ export type ViewConfig<Message> = Readonly<{
37
+ model: Model;
38
+ toMessage: (message: Closed | NoOp) => Message;
39
+ panelContent: Html;
40
+ panelClassName: string;
41
+ backdropClassName: string;
42
+ className?: string;
43
+ }>;
44
+ /** Renders a headless dialog component backed by the native `<dialog>` element with `showModal()`. */
45
+ export declare const view: <Message>(config: ViewConfig<Message>) => Html;
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/dialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAGxD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAOpD,8FAA8F;AAC9F,eAAO,MAAM,KAAK;;;EAGhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,wEAAwE;AACxE,eAAO,MAAM,MAAM,2DAAe,CAAA;AAClC,wHAAwH;AACxH,eAAO,MAAM,MAAM,2DAAe,CAAA;AAClC,oHAAoH;AACpH,eAAO,MAAM,IAAI,yDAAa,CAAA;AAE9B,8DAA8D;AAC9D,eAAO,MAAM,OAAO,0LAAgC,CAAA;AAEpD,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAA;AACvC,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAA;AACvC,MAAM,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,CAAA;AAEnC,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,6DAA6D;AAC7D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF,yEAAyE;AACzE,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAGxC,CAAA;AAMF,0EAA0E;AAC1E,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,SAAS,OAAO,KACf,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CA4BvC,CAAA;AAIH,iGAAiG;AACjG,eAAO,MAAM,OAAO,GAAI,OAAO,KAAK,KAAG,MAA6B,CAAA;AAEpE,wGAAwG;AACxG,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,KAAG,MAAmC,CAAA;AAEhF,wDAAwD;AACxD,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,KAAK,EAAE,KAAK,CAAA;IACZ,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAA;IAC9C,YAAY,EAAE,IAAI,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,iBAAiB,EAAE,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAC,CAAA;AAEF,sGAAsG;AACtG,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,QAAQ,UAAU,CAAC,OAAO,CAAC,KAAG,IA6C3D,CAAA"}
@@ -0,0 +1,67 @@
1
+ import { Match as M, Option, Schema as S } from 'effect';
2
+ import { html } from '../../html';
3
+ import { ts } from '../../schema';
4
+ import { evo } from '../../struct';
5
+ import * as Task from '../../task';
6
+ // MODEL
7
+ /** Schema for the dialog component's state, tracking its unique ID and open/closed status. */
8
+ export const Model = S.Struct({
9
+ id: S.String,
10
+ isOpen: S.Boolean,
11
+ });
12
+ // MESSAGE
13
+ /** Sent when the dialog should open. Triggers the showModal command. */
14
+ export const Opened = ts('Opened');
15
+ /** Sent when the dialog should close (Escape key, backdrop click, or programmatic). Triggers the closeModal command. */
16
+ export const Closed = ts('Closed');
17
+ /** Placeholder message used when no action is needed, such as after a showModal or closeModal command completes. */
18
+ export const NoOp = ts('NoOp');
19
+ /** Union of all messages the dialog component can produce. */
20
+ export const Message = S.Union(Opened, Closed, NoOp);
21
+ /** Creates an initial dialog model from a config. Defaults to closed. */
22
+ export const init = (config) => ({
23
+ id: config.id,
24
+ isOpen: config.isOpen ?? false,
25
+ });
26
+ // UPDATE
27
+ const dialogSelector = (id) => `#${id}`;
28
+ /** Processes a dialog message and returns the next model and commands. */
29
+ export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
30
+ Opened: () => {
31
+ const maybeShowCommand = Option.liftPredicate(Task.showModal(dialogSelector(model.id), () => NoOp()), () => !model.isOpen);
32
+ return [
33
+ evo(model, { isOpen: () => true }),
34
+ Option.toArray(maybeShowCommand),
35
+ ];
36
+ },
37
+ Closed: () => {
38
+ const maybeCloseCommand = Option.liftPredicate(Task.closeModal(dialogSelector(model.id), () => NoOp()), () => model.isOpen);
39
+ return [
40
+ evo(model, { isOpen: () => false }),
41
+ Option.toArray(maybeCloseCommand),
42
+ ];
43
+ },
44
+ NoOp: () => [model, []],
45
+ }));
46
+ // VIEW
47
+ /** Returns the ID used for `aria-labelledby` on the dialog. Apply this to your title element. */
48
+ export const titleId = (model) => `${model.id}-title`;
49
+ /** Returns the ID used for `aria-describedby` on the dialog. Apply this to your description element. */
50
+ export const descriptionId = (model) => `${model.id}-description`;
51
+ /** Renders a headless dialog component backed by the native `<dialog>` element with `showModal()`. */
52
+ export const view = (config) => {
53
+ const { AriaDescribedBy, AriaLabelledBy, Class, DataAttribute, Id, OnCancel, OnClick, keyed, } = html();
54
+ const { model: { id, isOpen }, toMessage, panelContent, panelClassName, backdropClassName, className, } = config;
55
+ const dialogAttributes = [
56
+ Id(id),
57
+ AriaLabelledBy(`${id}-title`),
58
+ AriaDescribedBy(`${id}-description`),
59
+ OnCancel(toMessage(Closed())),
60
+ ...(isOpen ? [DataAttribute('open', '')] : []),
61
+ ...(className ? [Class(className)] : []),
62
+ ];
63
+ const backdrop = keyed('div')(`${id}-backdrop`, [Class(backdropClassName), OnClick(toMessage(Closed()))], []);
64
+ const panel = keyed('div')(`${id}-panel`, [Class(panelClassName)], [panelContent]);
65
+ const content = isOpen ? [backdrop, panel] : [];
66
+ return keyed('dialog')(id, dialogAttributes, content);
67
+ };
@@ -0,0 +1,3 @@
1
+ export { init, update, view, titleId, descriptionId, Model, Message, Opened, Closed, NoOp, } from './index';
2
+ export type { InitConfig, ViewConfig } from './index';
3
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/ui/dialog/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,OAAO,EACP,aAAa,EACb,KAAK,EACL,OAAO,EACP,MAAM,EACN,MAAM,EACN,IAAI,GACL,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1 @@
1
+ export { init, update, view, titleId, descriptionId, Model, Message, Opened, Closed, NoOp, } from './index';
@@ -0,0 +1,47 @@
1
+ import { Schema as S } from 'effect';
2
+ import type { Html, TagName } from '../../html';
3
+ import type { Command } from '../../runtime/runtime';
4
+ /** Schema for the disclosure component's state, tracking its unique ID and open/closed status. */
5
+ export declare const Model: S.Struct<{
6
+ id: typeof S.String;
7
+ isOpen: typeof S.Boolean;
8
+ }>;
9
+ export type Model = typeof Model.Type;
10
+ /** Sent when the disclosure button is clicked. Toggles the open/closed state. */
11
+ export declare const Toggled: import("../../schema").CallableTaggedStruct<"Toggled", {}>;
12
+ /** Sent to explicitly close the disclosure, regardless of its current state. */
13
+ export declare const Closed: import("../../schema").CallableTaggedStruct<"Closed", {}>;
14
+ /** Placeholder message used when no action is needed, such as after a focus command completes. */
15
+ export declare const NoOp: import("../../schema").CallableTaggedStruct<"NoOp", {}>;
16
+ /** Union of all messages the disclosure component can produce. */
17
+ export declare const Message: S.Union<[import("../../schema").CallableTaggedStruct<"Toggled", {}>, import("../../schema").CallableTaggedStruct<"Closed", {}>, import("../../schema").CallableTaggedStruct<"NoOp", {}>]>;
18
+ export type Toggled = typeof Toggled.Type;
19
+ export type Closed = typeof Closed.Type;
20
+ export type NoOp = typeof NoOp.Type;
21
+ export type Message = typeof Message.Type;
22
+ /** Configuration for creating a disclosure model with `init`. */
23
+ export type InitConfig = Readonly<{
24
+ id: string;
25
+ isOpen?: boolean;
26
+ }>;
27
+ /** Creates an initial disclosure model from a config. Defaults to closed. */
28
+ export declare const init: (config: InitConfig) => Model;
29
+ /** Processes a disclosure message and returns the next model and commands. */
30
+ export declare const update: (model: Model, message: Message) => [Model, ReadonlyArray<Command<Message>>];
31
+ /** Configuration for rendering a disclosure with `view`. */
32
+ export type ViewConfig<Message> = Readonly<{
33
+ model: Model;
34
+ toMessage: (message: Toggled | Closed | NoOp) => Message;
35
+ buttonClassName: string;
36
+ buttonContent: Html;
37
+ panelClassName: string;
38
+ panelContent: Html;
39
+ isDisabled?: boolean;
40
+ persistPanel?: boolean;
41
+ buttonElement?: TagName;
42
+ panelElement?: TagName;
43
+ className?: string;
44
+ }>;
45
+ /** Renders a headless disclosure component with accessible ARIA attributes and keyboard support. */
46
+ export declare const view: <Message>(config: ViewConfig<Message>) => Html;
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/disclosure/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAGxD,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAOpD,kGAAkG;AAClG,eAAO,MAAM,KAAK;;;EAGhB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,iFAAiF;AACjF,eAAO,MAAM,OAAO,4DAAgB,CAAA;AACpC,gFAAgF;AAChF,eAAO,MAAM,MAAM,2DAAe,CAAA;AAClC,kGAAkG;AAClG,eAAO,MAAM,IAAI,yDAAa,CAAA;AAE9B,kEAAkE;AAClE,eAAO,MAAM,OAAO,2LAAiC,CAAA;AAErD,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AACzC,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,IAAI,CAAA;AACvC,MAAM,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,CAAA;AAEnC,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,iEAAiE;AACjE,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF,6EAA6E;AAC7E,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAGxC,CAAA;AAQF,8EAA8E;AAC9E,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,SAAS,OAAO,KACf,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CA4BvC,CAAA;AAIH,4DAA4D;AAC5D,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,KAAK,EAAE,KAAK,CAAA;IACZ,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,KAAK,OAAO,CAAA;IACxD,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,IAAI,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,IAAI,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAC,CAAA;AAEF,oGAAoG;AACpG,eAAO,MAAM,IAAI,GAAI,OAAO,EAAE,QAAQ,UAAU,CAAC,OAAO,CAAC,KAAG,IAyF3D,CAAA"}