@nimbus-sh/loom 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ashish Kumar Singh and Nimbus contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # @nimbus-sh/loom
2
+
3
+ > Part of [Nimbus](https://github.com/AshishKumar4/Nimbus), my hobby/research
4
+ > cloud OS. This README is edited and maintained with Claude (AI) and
5
+ > presented as-is.
6
+
7
+ An actor framework for Cloudflare Durable Objects. On top it is
8
+ [partyserver](https://github.com/cloudflare/partykit/tree/main/packages/partyserver)'s
9
+ surface, unchanged: `Actor extends Server`, so routing, connections, tags,
10
+ broadcast, and hibernation work exactly as partyserver documents them.
11
+ Underneath it is [`@nimbus-sh/fabric`](https://www.npmjs.com/package/@nimbus-sh/fabric),
12
+ the Durable Object machinery Nimbus runs in production, pre-wired so an
13
+ embedder writes one class instead of the wiring.
14
+
15
+ Cloudflare's own Agents SDK takes the same shape (`Agent extends Server`).
16
+ Where the two overlap, loom keeps the SDK's API and wire protocol so its
17
+ clients are not surprised, and swaps the machinery for fabric's where
18
+ fabric's is measurably stronger. Every such claim below was verified against
19
+ the shipped `agents` 0.20.1 dist, not its docs. partyserver is pinned to an
20
+ exact version (0.5.10); loom extends its prototype surface, and a floating
21
+ prototype dependency is a drift channel.
22
+
23
+ ## One class
24
+
25
+ ```ts
26
+ import { Actor, callable, routeActorRequest } from '@nimbus-sh/loom';
27
+
28
+ interface CounterState {
29
+ count: number;
30
+ }
31
+
32
+ export class Counter extends Actor<Env, CounterState> {
33
+ static options = { hibernate: true };
34
+ initialState: CounterState = { count: 0 };
35
+
36
+ @callable()
37
+ increment(by: number): number {
38
+ this.setState({ count: this.state.count + by });
39
+ return this.state.count;
40
+ }
41
+
42
+ async remind(payload: { what: string }): Promise<void> {
43
+ this.broadcast(`reminder: ${payload.what}`);
44
+ }
45
+
46
+ async onRequest(request: Request): Promise<Response> {
47
+ await this.schedule(60, 'remind', { what: 'tea' });
48
+ return Response.json(this.state);
49
+ }
50
+ }
51
+
52
+ export default {
53
+ async fetch(request: Request, env: Env): Promise<Response> {
54
+ return (await routeActorRequest(request, env))
55
+ ?? new Response('not found', { status: 404 });
56
+ },
57
+ } satisfies ExportedHandler<Env>;
58
+ ```
59
+
60
+ `routeActorRequest` and `getActorByName` are partyserver's router
61
+ re-exported, URL convention included (`/parties/<binding>/<name>`); a
62
+ parallel implementation would drift. Actor classes must be SQLite-backed
63
+ Durable Objects (`new_sqlite_classes`, the default for new classes); state
64
+ and schedules live in the actor's own SQLite.
65
+
66
+ ## The floor you inherit
67
+
68
+ **Nothing async on the init gate.** The constructor is synchronous.
69
+ partyserver's gate runs exactly your `onStart`, and a gate callback still
70
+ pending at ~30 s is cancelled and resets the object, so `onStart` must stay
71
+ short. Work that belongs to a fresh incarnation goes through
72
+ `this.deferToColdStart(task)` and runs on the first turn the actor owns.
73
+ Generation adoption (`this.generation`, fabric's incarnation counter) and
74
+ fenced-work recovery ride the same turn.
75
+
76
+ **One alarm, many reasons.** A Durable Object has one alarm, and a second
77
+ `setAlarm()` silently overwrites the first. `alarm()` therefore dispatches
78
+ fabric's reason map: register a reason with `registerTimerReason` in the
79
+ constructor, arm it with `this.timers.schedule(reason, whenMs)`, re-arm by
80
+ returning `{ rearmAt }` from the handler. The schedule API and every outbox
81
+ are reasons in the same map, so nothing clobbers anything.
82
+
83
+ **Scheduling.** `schedule(when, callback, payload?)` takes a delay in
84
+ seconds, a `Date`, or a cron expression; `scheduleEvery(intervalSeconds,
85
+ ...)` is a fixed interval. `getScheduleById`, `listSchedules`,
86
+ `cancelSchedule` read and cancel. The callback receives
87
+ `(payload, invocation)` where the invocation carries the schedule, the
88
+ attempt number, and the platform's `alarmInfo` (`isRetry`, `retryCount`),
89
+ which the Agents SDK drops. Retries are durable: a failed attempt writes its
90
+ backed-off deadline into the row, so the budget survives an instance reset
91
+ instead of sleeping inside the alarm turn. Times are epoch milliseconds.
92
+
93
+ **State sync.** Declare `initialState`, read `this.state`, write
94
+ `setState(next)`. State persists to SQLite and broadcasts to every
95
+ connection as a `cf_agent_state` frame (the Agents wire protocol, so its
96
+ clients work as-is). A client can send the same frame back;
97
+ `validateStateChange(next, source)` vetoes synchronously before anything
98
+ persists, and `onStateChanged(state, source)` runs after. A refused client
99
+ update earns a `cf_agent_state_error` frame.
100
+
101
+ **Callable RPC.** Mark a method `@callable()` and any connection can invoke
102
+ it by name; everything unmarked is refused. `@callable({ streaming: true })`
103
+ prepends a `StreamingResponse` to the arguments for chunked replies. The
104
+ caller side is `actorClient(socket)` from `@nimbus-sh/loom/client.js` —
105
+ dependency-free and workerd-free, with `call(method, args)` and a typed
106
+ `stub<T>()` proxy.
107
+
108
+ **Per-connection state.** `this.connections(schema)` is fabric's typed,
109
+ validated, hibernation-durable attachment state over partyserver's
110
+ `Connection` surface: `read` validates instead of casting (an attachment
111
+ written by a previous deploy is untrusted input), `write` validates on the
112
+ way in, tags address connections. partyserver owns the accept; tag
113
+ connections in `getConnectionTags`. Hibernating actors only — the state
114
+ rides the hibernatable socket attachment, and a non-hibernating actor is
115
+ refused with an error rather than corrupted later.
116
+
117
+ **Durable messaging.** `this.outbox(name, policy)` is a write-ahead retry
118
+ outbox (dispositions, per-key ordering, dead letters), its drain registered
119
+ as a timer reason the moment you create it. Create outboxes in the
120
+ constructor: a queued row survives an instance reset, but the alarm
121
+ dispatcher drops a fired reason no handler answers, so an outbox first
122
+ created inside a request path is unregistered until that path runs again.
123
+ `this.journal(name)` is an append-only event log with dedupe and
124
+ self-expiring delivery leases.
125
+
126
+ **Processes and facets.** `this.facets` leases DO facets so reclaiming
127
+ storage is the default and leaking it takes an explicit `detach()`.
128
+ `this.processes` is fabric's process fabric over a substrate you declare by
129
+ overriding `processHost()`. `this.derived` / `this.derivedAsync` are the
130
+ watermark memos.
131
+
132
+ **Hibernation, configured.** `static options = { hibernate: true }` opts
133
+ into partyserver's hibernation and also applies fabric's config: `ping`/
134
+ `pong` auto-response (a matched frame no longer wakes the actor) and the 5 s
135
+ hibernatable-event timeout. `this.hibernation` reports what the runtime
136
+ supported. State your fabric composition once, on the class:
137
+ `static options = { fabric: { supervisorEntrypoint: '...' } }`.
138
+
139
+ Define hooks (`onMessage`, `onConnect`, ...) as methods, not instance
140
+ fields. Loom wraps them at construction to pay the floor work and consume
141
+ protocol frames; an instance field assigns over the wiring.
142
+
143
+ ## What this is not
144
+
145
+ There is no chat surface, no MCP, no email routing, no React hooks, and no
146
+ Workflows integration. That is the Agents SDK's product surface; loom stops
147
+ at the framework layer. If you need those today, use `agents` — its `Agent`
148
+ and loom's `Actor` are siblings on the same partyserver base, and they do
149
+ not share a Durable Object.
150
+
151
+ ## Importing it
152
+
153
+ Your Worker must set `compatibility_flags: ["nodejs_compat"]`. Loom dispatches
154
+ timers through fabric, and fabric's dispatcher imports `AsyncLocalStorage`
155
+ from `node:async_hooks`. Without the flag the module fails to load at deploy
156
+ time.
157
+
158
+ The root export pulls `partyserver`, which imports `cloudflare:workers`, so
159
+ `import ... from '@nimbus-sh/loom'` resolves only inside a Worker. Outside
160
+ workerd (unit tests, browsers) import subpaths: `@nimbus-sh/loom/client.js`
161
+ and `@nimbus-sh/loom/protocol.js` are workerd-free by design, and
162
+ `@nimbus-sh/loom/schedules.js` is structurally typed for plain-process
163
+ tests, the same discipline as fabric.
@@ -0,0 +1,222 @@
1
+ /**
2
+ * actor.ts — `Actor`, a partyserver `Server` standing on the fabric floor.
3
+ *
4
+ * partyserver contributes the surface: routing, connections, tags,
5
+ * broadcast, hibernation opt-in, `onStart`/`onConnect`/`onMessage`/
6
+ * `onRequest`/`onClose`/`onError`. Fabric contributes the machinery a
7
+ * Durable Object needs under that surface, and this class wires it so an
8
+ * embedder never does:
9
+ *
10
+ * - ONE ALARM, MANY REASONS. `alarm()` dispatches fabric's reason map;
11
+ * the embedder registers reasons ({@link Actor.registerTimerReason})
12
+ * and arms them (`this.timers`). The schedule API and every outbox are
13
+ * reasons in the same map. The platform's `alarmInfo` rides through to
14
+ * every handler.
15
+ * - NOTHING ASYNC ON THE INIT GATE. The constructor is synchronous.
16
+ * partyserver's own gate runs exactly `onStart` (its `#ensureInitialized`,
17
+ * a `blockConcurrencyWhile`); a gate callback still pending at ~30 s is
18
+ * cancelled and RESETS the object, so `onStart` must stay short.
19
+ * Everything the floor defers — generation adoption, cold-start
20
+ * reconciliation, fenced-work recovery — runs on the first turn the
21
+ * actor already owns: every entry point passes {@link Actor.#enterTurn}
22
+ * after initialization and before embedder code. One platform
23
+ * exception: partyserver's fetch asks `getConnectionTags` during the
24
+ * accept, before the connect turn's floor entry — keep that hook pure.
25
+ * - HIBERNATION CONFIGURED, NOT JUST ENABLED. With
26
+ * `static options = { hibernate: true }`, the constructor also applies
27
+ * fabric's ws-hibernation config: ping/pong auto-response (a matched
28
+ * frame no longer wakes the actor) and the 5 s hibernatable-event
29
+ * timeout. The result is on `this.hibernation` for diagnostics.
30
+ * - COMPOSITION STATED ONCE. `static options = { fabric: {...} }` feeds
31
+ * `composeFabric`, and the constructor captures `ctx.exports` where the
32
+ * platform hands it over. Both are first-write-wins.
33
+ *
34
+ * Protocol frames (state sync, callable RPC — see protocol.ts) are consumed
35
+ * before `onMessage`; everything else reaches the embedder untouched. For
36
+ * that interception to hold, hooks must be prototype METHODS — an instance
37
+ * field (`onMessage = () => {}`) assigns over the wiring.
38
+ *
39
+ * The state and schedule tables live in the actor's own SQLite, so an Actor
40
+ * class must be SQLite-backed (`new_sqlite_classes` — the default for new
41
+ * classes).
42
+ */
43
+ import { Server, type Connection } from 'partyserver';
44
+ import { type TimerAlarmInfo, type TimerHandlerResult, type Timers } from '@nimbus-sh/fabric/timers.js';
45
+ import { type Outbox, type OutboxPolicy } from '@nimbus-sh/fabric/outbox.js';
46
+ import { type Journal } from '@nimbus-sh/fabric/journal.js';
47
+ import { type FacetPool } from '@nimbus-sh/fabric/facet-pool.js';
48
+ import { type Derived, type DerivedAsync, type DerivedAsyncHooks, type DerivedHooks } from '@nimbus-sh/fabric/derived.js';
49
+ import { FencedWork, type FencedWorkHost, type FencedWorkRecord } from '@nimbus-sh/fabric/fenced-work.js';
50
+ import { type FabricComposition } from '@nimbus-sh/fabric/composition.js';
51
+ import { type WsHibernationConfigResult } from '@nimbus-sh/fabric/ws-hibernation-config.js';
52
+ import { ProcessFabric, type ProcessHost } from '@nimbus-sh/fabric/process-fabric.js';
53
+ import type { z } from 'zod/v4';
54
+ import { type Schedule, type ScheduleCriteria, type ScheduleOptions } from './schedules.js';
55
+ /** The timer reason the schedule store dispatches under. */
56
+ export declare const SCHEDULE_TIMER_REASON = "loom:schedule";
57
+ /** Static configuration, inherited through the class chain like partyserver's. */
58
+ export interface ActorOptions {
59
+ /** partyserver's hibernation opt-in; loom also applies fabric's ws config. */
60
+ hibernate?: boolean;
61
+ /**
62
+ * The embedder's fabric composition, stated once on the class. Fed to
63
+ * `composeFabric` (first-write-wins) before anything can need it.
64
+ */
65
+ fabric?: FabricComposition;
66
+ }
67
+ /**
68
+ * Typed, validated per-connection state over partyserver's `Connection`
69
+ * surface — fabric's `connections` machinery with the accept half left to
70
+ * partyserver, which owns the accept.
71
+ */
72
+ export interface TypedConnections<T> {
73
+ /** The open connection holding a tag, or null. */
74
+ get(tag: string): Connection | null;
75
+ /** Every open connection (optionally: holding a tag). */
76
+ list(tag?: string): Connection[];
77
+ /** A connection's tags — its id first, then `getConnectionTags`' additions. */
78
+ tags(connection: Connection): string[];
79
+ /**
80
+ * The attachment, validated. Null when it does not parse — an attachment
81
+ * written by a previous deploy is untrusted input.
82
+ */
83
+ read(connection: Connection): T | null;
84
+ /** Replace the attachment, validated on the way in. */
85
+ write(connection: Connection, attachment: T): void;
86
+ }
87
+ export declare class Actor<Env extends Cloudflare.Env = Cloudflare.Env, State = unknown, Props extends Record<string, unknown> = Record<string, unknown>> extends Server<Env, Props> {
88
+ #private;
89
+ static options: ActorOptions;
90
+ /** fabric `TimerHost`: the chain serializing this instance's timer map. */
91
+ _timerChain?: Promise<unknown>;
92
+ /**
93
+ * Fabric's ws-hibernation configuration result, when
94
+ * `options.hibernate` asked for it; null otherwise. Reports honestly
95
+ * which half the runtime supported.
96
+ */
97
+ readonly hibernation: WsHibernationConfigResult | null;
98
+ /**
99
+ * The state broadcast to (and settable by) connections. Assign it in the
100
+ * subclass; leave it unassigned for a stateless actor.
101
+ */
102
+ initialState: State;
103
+ constructor(ctx: DurableObjectState, env: Env);
104
+ /**
105
+ * The native-RPC entry point (`getActorByName` calls it before any
106
+ * embedder RPC method) pays the turn entry too, after partyserver has
107
+ * initialized.
108
+ */
109
+ setName(name: string, props?: Props): Promise<void>;
110
+ /**
111
+ * partyserver initialization, then the floor, then `onAlarm`, then
112
+ * fabric's dispatcher runs every due reason with the platform's
113
+ * `alarmInfo`. Handlers re-arm through their return value; the map's
114
+ * earliest remaining deadline re-arms the platform alarm.
115
+ * `__unsafe_ensureInitialized` is partyserver's documented escape hatch
116
+ * for frameworks; calling it here (instead of `super.alarm()`) is what
117
+ * lets `onAlarm` run AFTER the floor, like every other embedder hook.
118
+ */
119
+ alarm(alarmInfo?: TimerAlarmInfo): Promise<void>;
120
+ /** partyserver logs "implement onAlarm" per fire; an empty hook is the default here. */
121
+ onAlarm(): void | Promise<void>;
122
+ /**
123
+ * Register the handler for one timer reason. Reasons are the alarm's
124
+ * multiplexing key: register in the constructor, arm with
125
+ * `this.timers.schedule(reason, whenMs)`, re-arm by returning
126
+ * `{ rearmAt }` from the handler. One handler per reason, for the
127
+ * instance's lifetime.
128
+ */
129
+ protected registerTimerReason(reason: string, handler: (now: number, info?: TimerAlarmInfo) => TimerHandlerResult | Promise<TimerHandlerResult>): void;
130
+ /**
131
+ * Schedule a method call: `when` is a delay in seconds, an absolute
132
+ * `Date`, or a cron expression. The callback fires as
133
+ * `this[callback](payload, invocation)`; the invocation carries the
134
+ * schedule, the attempt number, and the platform's `alarmInfo`. Retries
135
+ * are durable rows (see schedules.ts), governed by `options.retry`.
136
+ */
137
+ schedule<T = unknown>(when: number | Date | string, callback: keyof this & string, payload?: T, options?: ScheduleOptions): Promise<Schedule<T>>;
138
+ /** Schedule a method call every `intervalSeconds`, first fire one interval from now. */
139
+ scheduleEvery<T = unknown>(intervalSeconds: number, callback: keyof this & string, payload?: T, options?: ScheduleOptions): Promise<Schedule<T>>;
140
+ getScheduleById<T = unknown>(id: string): Promise<Schedule<T> | undefined>;
141
+ listSchedules<T = unknown>(criteria?: ScheduleCriteria): Promise<Array<Schedule<T>>>;
142
+ /** True when the id existed and is now cancelled. */
143
+ cancelSchedule(id: string): Promise<boolean>;
144
+ /**
145
+ * A schedule's retry budget is spent (or its callback is not a method).
146
+ * The default names the failure; override to route it.
147
+ */
148
+ onScheduleError(schedule: Schedule, error: unknown): void;
149
+ /**
150
+ * The synced state. Loaded from SQLite on first read; `initialState`
151
+ * before anything was ever set; undefined for a stateless actor.
152
+ */
153
+ get state(): State;
154
+ /** Replace the state: validate, persist, broadcast, notify. */
155
+ setState(state: State): void;
156
+ /**
157
+ * Synchronous veto over every state change, the embedder's own and a
158
+ * connection's alike. Runs BEFORE anything persists; throw to refuse.
159
+ * A refused connection update earns the client a
160
+ * `cf_agent_state_error` frame.
161
+ */
162
+ validateStateChange(_next: State, _source: Connection | 'server'): void;
163
+ /** The state changed and is already persisted and broadcast. */
164
+ onStateChanged(_state: State, _source: Connection | 'server'): void | Promise<void>;
165
+ /** This actor's reason map over its ONE platform alarm. */
166
+ get timers(): Timers;
167
+ /** This incarnation's generation. Zero until the first turn adopted it. */
168
+ get generation(): number;
169
+ /**
170
+ * The named durable retry outbox, its drain registered as a timer reason
171
+ * on first call. One instance per name; later calls return the first and
172
+ * ignore their policy argument.
173
+ *
174
+ * Create outboxes in the CONSTRUCTOR. A queued row survives an instance
175
+ * reset, but the dispatcher drops a fired reason no handler answers
176
+ * (rollback forward-compat) — an outbox first created inside a request
177
+ * path is not registered when the next incarnation's alarm fires, and
178
+ * its queued rows sit until some later `queue()` happens to re-arm.
179
+ */
180
+ outbox<M>(name: string, policy: OutboxPolicy<M>): Outbox<M>;
181
+ /** The named append-only event journal. One instance per name. */
182
+ journal<P>(name: string): Journal<P>;
183
+ /** Leased facets: disposal retires (storage wiped), `detach()` keeps it. */
184
+ get facets(): FacetPool;
185
+ /**
186
+ * The process fabric over this actor's substrate. Declare the substrate
187
+ * by overriding {@link processHost}; the fabric is built once, on first
188
+ * use.
189
+ */
190
+ get processes(): ProcessFabric;
191
+ /** The substrate {@link processes} runs on. Override to declare one. */
192
+ protected processHost(): ProcessHost;
193
+ /** A watermark memo: derive a cheap key, compare, rebuild only on change. */
194
+ derived<T, C = void>(watermark: (context: C) => string | number, build: (context: C, key: string | number) => T, hooks?: DerivedHooks): Derived<T, C>;
195
+ /** The async memo; a watermark or build failure serves the last good value. */
196
+ derivedAsync<T, C = void>(watermark: (context: C) => Promise<string | number>, build: (context: C, key: string | number) => Promise<T>, hooks?: DerivedAsyncHooks): DerivedAsync<T, C>;
197
+ /**
198
+ * Typed, validated per-connection state over the WebSocket attachment,
199
+ * hibernation-durable. partyserver owns the accept (tag connections via
200
+ * `getConnectionTags`); this reads, writes, and addresses by tag. To
201
+ * replace-on-reconnect, close the other holders of the identity tag in
202
+ * `onConnect`.
203
+ *
204
+ * Hibernation-only: the state rides the hibernatable socket attachment,
205
+ * and partyserver's non-hibernating connections neither wrap nor persist
206
+ * it — so a non-hibernating actor is refused here, not corrupted later.
207
+ */
208
+ connections<T>(schema: z.ZodType<T>): TypedConnections<T>;
209
+ /**
210
+ * A fenced-work journal whose recovery is pumped on the first turn of
211
+ * every incarnation — reconnects after a reset included. The host defines
212
+ * what a launch is and how to re-drive it; call once, in the constructor.
213
+ */
214
+ protected fenceWork<R extends FencedWorkRecord>(host: FencedWorkHost<R>): FencedWork<R>;
215
+ /**
216
+ * Defer async reconciliation to the first turn of this incarnation —
217
+ * never the init gate. Safe to call from the constructor; that is the
218
+ * point.
219
+ */
220
+ protected deferToColdStart(task: () => Promise<unknown>): void;
221
+ }
222
+ //# sourceMappingURL=actor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../src/actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAA0C,MAAM,aAAa,CAAC;AAQ9F,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,kBAAkB,EAEvB,KAAK,MAAM,EACZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAA0B,KAAK,MAAM,EAAsB,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACzH,OAAO,EAA4B,KAAK,OAAO,EAAuB,MAAM,8BAA8B,CAAC;AAC3G,OAAO,EAAa,KAAK,SAAS,EAAyB,MAAM,iCAAiC,CAAC;AACnG,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAEtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAEL,KAAK,QAAQ,EAEb,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAIxB,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AAErD,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,kDAAkD;IAClD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IACpC,yDAAyD;IACzD,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAAC;IACjC,+EAA+E;IAC/E,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,CAAC;IACvC;;;OAGG;IACH,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC;IACvC,uDAAuD;IACvD,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC;CACpD;AAcD,qBAAa,KAAK,CAChB,GAAG,SAAS,UAAU,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,EAC3C,KAAK,GAAG,OAAO,EACf,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC/D,SAAQ,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC;;IAC1B,OAAe,OAAO,EAAE,YAAY,CAAC;IAErC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,yBAAyB,GAAG,IAAI,CAAQ;IAE9D;;;OAGG;IACK,YAAY,EAAE,KAAK,CAAC;gBAahB,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IAuE7C;;;;OAIG;IACY,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE;;;;;;;;OAQG;IACY,KAAK,CAAC,SAAS,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/D,wFAAwF;IAC/E,OAAO,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAExC;;;;;;OAMG;IACH,SAAS,CAAC,mBAAmB,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,KAAK,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,GAChG,IAAI;IASP;;;;;;OAMG;IACG,QAAQ,CAAC,CAAC,GAAG,OAAO,EACxB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAC5B,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,EAC7B,OAAO,CAAC,EAAE,CAAC,EACX,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAOvB,wFAAwF;IAClF,aAAa,CAAC,CAAC,GAAG,OAAO,EAC7B,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,EAC7B,OAAO,CAAC,EAAE,CAAC,EACX,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAOjB,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAI1E,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAI1F,qDAAqD;IAC/C,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlD;;;OAGG;IACH,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IA0BzD;;;OAGG;IACH,IAAI,KAAK,IAAI,KAAK,CAQjB;IAED,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI5B;;;;;OAKG;IACH,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI;IAEvE,gEAAgE;IAChE,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA2FnF,2DAA2D;IAC3D,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,2EAA2E;IAC3E,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IAS3D,kEAAkE;IAClE,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAQpC,4EAA4E;IAC5E,IAAI,MAAM,IAAI,SAAS,CAEtB;IAED;;;;OAIG;IACH,IAAI,SAAS,IAAI,aAAa,CAE7B;IAED,wEAAwE;IACxE,SAAS,CAAC,WAAW,IAAI,WAAW;IAMpC,6EAA6E;IAC7E,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,EACjB,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,EAC1C,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,CAAC,EAC9C,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAIhB,+EAA+E;IAC/E,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,EACtB,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,EACnD,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACvD,KAAK,CAAC,EAAE,iBAAiB,GACxB,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;IAIrB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC;IA0BzD;;;;OAIG;IACH,SAAS,CAAC,SAAS,CAAC,CAAC,SAAS,gBAAgB,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAMvF;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;CAO/D"}