@mulmoclaude/accounting-plugin 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/server/context.d.ts +45 -3
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/eventPublisher.d.ts +9 -4
- package/dist/server/eventPublisher.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/router.d.ts +27 -3
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/snapshotCache.d.ts +3 -3
- package/dist/server/snapshotCache.d.ts.map +1 -1
- package/dist/server.cjs +149 -80
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +149 -80
- package/dist/server.js.map +1 -1
- package/dist/shared/api.d.ts +12 -0
- package/dist/shared/api.d.ts.map +1 -1
- package/dist/shared/channels.d.ts +22 -2
- package/dist/shared/channels.d.ts.map +1 -1
- package/dist/{shared-BZAAF-I4.js → shared-BccLo0Ux.js} +39 -5
- package/dist/shared-BccLo0Ux.js.map +1 -0
- package/dist/{shared-BpFVwa6Y.cjs → shared-Dgt-i23T.cjs} +50 -4
- package/dist/shared-Dgt-i23T.cjs.map +1 -0
- package/dist/shared.cjs +3 -1
- package/dist/shared.js +2 -2
- package/dist/style.css +19 -10
- package/dist/vue/View.vue.d.ts +5 -0
- package/dist/vue/View.vue.d.ts.map +1 -1
- package/dist/vue/api.d.ts +132 -100
- package/dist/vue/api.d.ts.map +1 -1
- package/dist/vue/components/AccountsModal.vue.d.ts.map +1 -1
- package/dist/vue/components/BalanceSheet.vue.d.ts.map +1 -1
- package/dist/vue/components/BookSettings.vue.d.ts.map +1 -1
- package/dist/vue/components/JournalEntryForm.vue.d.ts.map +1 -1
- package/dist/vue/components/JournalList.vue.d.ts.map +1 -1
- package/dist/vue/components/Ledger.vue.d.ts.map +1 -1
- package/dist/vue/components/NewBookForm.vue.d.ts.map +1 -1
- package/dist/vue/components/OpeningBalancesForm.vue.d.ts.map +1 -1
- package/dist/vue/components/ProfitLoss.vue.d.ts.map +1 -1
- package/dist/vue/hostContext.d.ts +15 -0
- package/dist/vue/hostContext.d.ts.map +1 -1
- package/dist/vue/useAccountingChannel.d.ts +13 -3
- package/dist/vue/useAccountingChannel.d.ts.map +1 -1
- package/dist/vue.cjs +227 -98
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +228 -99
- package/dist/vue.js.map +1 -1
- package/package.json +4 -3
- package/dist/shared-BZAAF-I4.js.map +0 -1
- package/dist/shared-BpFVwa6Y.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -4,6 +4,43 @@ Double-entry accounting plugin for MulmoClaude and MulmoTerminal. Three surfaces
|
|
|
4
4
|
|
|
5
5
|
A plugin for [MulmoClaude](https://github.com/receptron/mulmoclaude) and [MulmoTerminal](https://github.com/receptron/mulmoterminal) — loaded by the host, not run standalone.
|
|
6
6
|
|
|
7
|
+
## Host wiring
|
|
8
|
+
|
|
9
|
+
A single-workspace host (MulmoClaude) wires three calls once at boot:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
configureAccountingServer({ workspaceRoot, logger });
|
|
13
|
+
initAccountingEventPublisher(pubsub);
|
|
14
|
+
app.use(createAccountingRouter());
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
A host that serves one root per project directory (MulmoTerminal) wires the same three
|
|
18
|
+
differently:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
configureAccountingServer({
|
|
22
|
+
workspaceRoot: null, // explicit-root mode: a forgotten root throws
|
|
23
|
+
logger,
|
|
24
|
+
channelScopeForRoot: (root) => projectIdForRoot(root), // opaque id, or null for the default root
|
|
25
|
+
});
|
|
26
|
+
initAccountingEventPublisher(pubsub); // unchanged — the scope comes from the dep above
|
|
27
|
+
app.use(createAccountingRouter({ resolveWorkspaceRoot: (req) => rootForRequest(req) }));
|
|
28
|
+
configureAccountingHost({ apiCall, subscribe, localeTag, projectScope }); // the Vue surface
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Both are opt-in and default to today's behaviour. The invariants behind them:
|
|
32
|
+
|
|
33
|
+
1. **A bookId is unique within a root and nowhere else.** Anything keyed by bookId alone —
|
|
34
|
+
a channel, a rebuild queue, a card — is a cross-project collision waiting to happen.
|
|
35
|
+
2. **`workspaceRoot: null` is the safety net.** With N roots, a forgotten root is not a
|
|
36
|
+
crash but a silent read or write against the wrong project; explicit-root mode turns it
|
|
37
|
+
into a clear throw.
|
|
38
|
+
3. **A project is named by an opaque id, never a path.** Channel names and card envelopes
|
|
39
|
+
reach the browser; an absolute root there publishes the user's home directory.
|
|
40
|
+
4. **The model never picks a project.** `manageAccounting`'s schema has no project
|
|
41
|
+
parameter (pinned by a test), and this package never resolves one off a request body —
|
|
42
|
+
only the host's own `resolveWorkspaceRoot` does.
|
|
43
|
+
|
|
7
44
|
## Dev loop
|
|
8
45
|
|
|
9
46
|
```bash
|
package/dist/server/context.d.ts
CHANGED
|
@@ -9,16 +9,58 @@ export interface IPubSub {
|
|
|
9
9
|
export type AccountingLogger = StructuredLogger;
|
|
10
10
|
export interface AccountingServerDeps {
|
|
11
11
|
/** Absolute path to the workspace root (where `data/` lives). Used as
|
|
12
|
-
* the default when a service/io call doesn't pass an explicit root.
|
|
13
|
-
|
|
12
|
+
* the default when a service/io call doesn't pass an explicit root.
|
|
13
|
+
*
|
|
14
|
+
* `null` declares STRICT mode: this host always passes an explicit
|
|
15
|
+
* root per call, and `defaultWorkspaceRoot()` throws instead of
|
|
16
|
+
* guessing. A multi-root host (MulmoTerminal, one root per project
|
|
17
|
+
* directory) MUST use it — with N roots a forgotten option is not a
|
|
18
|
+
* crash but a silent read/write against the wrong project. Mirrors
|
|
19
|
+
* `CollectionHost.workspaceRoot: string | null` in
|
|
20
|
+
* `@mulmoclaude/core/collection/server`. */
|
|
21
|
+
workspaceRoot: string | null;
|
|
14
22
|
logger: AccountingLogger;
|
|
23
|
+
/** Optional: map an absolute root to the OPAQUE scope id the host uses
|
|
24
|
+
* for that project, used to namespace pub/sub channel names so two
|
|
25
|
+
* roots owning one bookId do not cross-notify. Return `null` for the
|
|
26
|
+
* host's default root, which keeps channel names byte-identical to a
|
|
27
|
+
* single-root host's (`accounting:<bookId>`).
|
|
28
|
+
*
|
|
29
|
+
* It must be an opaque id, NEVER a path: channel names reach the
|
|
30
|
+
* browser, and an absolute root there publishes the user's home
|
|
31
|
+
* directory to the client. Same rule as a collection view token. */
|
|
32
|
+
channelScopeForRoot?: (workspaceRoot: string) => string | null;
|
|
15
33
|
}
|
|
16
34
|
/** Called once by the host before the accounting router is mounted. */
|
|
17
35
|
export declare function configureAccountingServer(context: AccountingServerDeps): void;
|
|
18
36
|
/** Default workspace root for io calls that don't pass one explicitly.
|
|
19
37
|
* Throws if the host never configured the server — a real wiring bug
|
|
20
|
-
* (unit tests always pass an explicit root, so they never hit this)
|
|
38
|
+
* (unit tests always pass an explicit root, so they never hit this) —
|
|
39
|
+
* and also under STRICT mode (`workspaceRoot: null`), where there is no
|
|
40
|
+
* ambient root to fall back to and a missing option is a bug rather
|
|
41
|
+
* than a default. */
|
|
21
42
|
export declare function defaultWorkspaceRoot(): string;
|
|
43
|
+
/** The opaque channel scope for a root, or `null` when the host declared
|
|
44
|
+
* none (single-root hosts, and a multi-root host's default root). Used
|
|
45
|
+
* by the event publisher; never contains a path.
|
|
46
|
+
*
|
|
47
|
+
* A missing root throws under explicit-root mode, exactly as
|
|
48
|
+
* `defaultWorkspaceRoot()` does. Returning `null` there would be worse
|
|
49
|
+
* than the io-path bug it mirrors: the event would go out on the
|
|
50
|
+
* UNSCOPED channel name, which every project's default-scope
|
|
51
|
+
* subscriber receives. The publisher catches it and logs, so a dropped
|
|
52
|
+
* root costs one event and a warning rather than a silent cross-project
|
|
53
|
+
* notification. */
|
|
54
|
+
export declare function channelScopeFor(workspaceRoot?: string): string | null;
|
|
55
|
+
/** Whether the host declared project scoping at all.
|
|
56
|
+
*
|
|
57
|
+
* The difference matters where a card records the project it belongs
|
|
58
|
+
* to: on a scoped host, "no scope" is a REAL answer (the default root)
|
|
59
|
+
* and must be recorded as `null`, not left out — an omitted field means
|
|
60
|
+
* "ask the host what is active now", which is precisely the drift a
|
|
61
|
+
* pinned card exists to prevent. On an unscoped host the field is left
|
|
62
|
+
* out entirely and every payload stays byte-identical to today's. */
|
|
63
|
+
export declare function isProjectScopedHost(): boolean;
|
|
22
64
|
/** Logger proxy — forwards to the injected logger, console fallback
|
|
23
65
|
* before configuration. Lets call sites keep `log.warn("accounting", …)`. */
|
|
24
66
|
export declare const log: AccountingLogger;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;kEAEkE;AAClE,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACtD;AAED,0GAA0G;AAC1G,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;kEAEkE;AAClE,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACtD;AAED,0GAA0G;AAC1G,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;iDAS6C;IAC7C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,gBAAgB,CAAC;IACzB;;;;;;;;yEAQqE;IACrE,mBAAmB,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAChE;AAID,uEAAuE;AACvE,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAE7E;AAED;;;;;sBAKsB;AACtB,wBAAgB,oBAAoB,IAAI,MAAM,CAU7C;AAED;;;;;;;;;;oBAUoB;AACpB,wBAAgB,eAAe,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrE;AAED;;;;;;;sEAOsE;AACtE,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AASD;8EAC8E;AAC9E,eAAO,MAAM,GAAG,EAAE,gBAKjB,CAAC"}
|
|
@@ -3,12 +3,17 @@ import { type IPubSub } from "./context.js";
|
|
|
3
3
|
export declare function initAccountingEventPublisher(instance: IPubSub): void;
|
|
4
4
|
/** Per-book change notification. `period` should be the entry's
|
|
5
5
|
* YYYY-MM bucket (or the earliest invalidated month for snapshot
|
|
6
|
-
* events).
|
|
7
|
-
|
|
6
|
+
* events).
|
|
7
|
+
*
|
|
8
|
+
* `workspaceRoot` is the root the write happened under; the channel
|
|
9
|
+
* name is namespaced by the host's opaque scope for it (see
|
|
10
|
+
* `channelScopeFor`). Omit it — as a single-root host's service calls
|
|
11
|
+
* do — and the name is what it has always been. */
|
|
12
|
+
export declare function publishBookChange(bookId: string, payload: AccountingBookChannelPayload, workspaceRoot?: string): void;
|
|
8
13
|
/** Fired when the *list* of books changes (createBook, deleteBook).
|
|
9
14
|
* Payload is intentionally empty — subscribers refetch from
|
|
10
|
-
* /api/accounting. */
|
|
11
|
-
export declare function publishBooksChanged(): void;
|
|
15
|
+
* /api/accounting. Scoped by root like `publishBookChange`. */
|
|
16
|
+
export declare function publishBooksChanged(workspaceRoot?: string): void;
|
|
12
17
|
/** Test-only — drop the module singleton so each test starts clean. */
|
|
13
18
|
export declare function _resetAccountingEventPublisherForTesting(): void;
|
|
14
19
|
//# sourceMappingURL=eventPublisher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eventPublisher.d.ts","sourceRoot":"","sources":["../../src/server/eventPublisher.ts"],"names":[],"mappings":"AASA,OAAO,
|
|
1
|
+
{"version":3,"file":"eventPublisher.d.ts","sourceRoot":"","sources":["../../src/server/eventPublisher.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,kBAAkB,IAAI,4BAA4B,EACxD,MAAM,WAAW,CAAC;AACnB,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAKlE,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAEpE;AAuBD;;;;;;;oDAOoD;AACpD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,4BAA4B,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAErH;AAED;;gEAEgE;AAChE,wBAAgB,mBAAmB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAEhE;AAED,uEAAuE;AACvE,wBAAgB,wCAAwC,IAAI,IAAI,CAE/D"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createAccountingRouter } from "./router.js";
|
|
2
|
+
export type { AccountingRouterOptions, AccountingDispatchRequest, AccountingActionBody } from "./router.js";
|
|
2
3
|
export { configureAccountingServer } from "./context.js";
|
|
3
4
|
export type { AccountingServerDeps, AccountingLogger, IPubSub } from "./context.js";
|
|
4
5
|
export { initAccountingEventPublisher } from "./eventPublisher.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,YAAY,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC5G,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAKnE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/server/router.d.ts
CHANGED
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
import { Router } from "express";
|
|
1
|
+
import { Router, Request } from "express";
|
|
2
|
+
export interface AccountingActionBody {
|
|
3
|
+
action: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
/** The request shape the dispatch route hands a host resolver — the
|
|
7
|
+
* same one the route itself is typed with, so a host can read headers,
|
|
8
|
+
* query and the parsed body without casting. */
|
|
9
|
+
export type AccountingDispatchRequest = Request<object, unknown, AccountingActionBody>;
|
|
10
|
+
export interface AccountingRouterOptions {
|
|
11
|
+
/** Resolve the workspace root ONE request operates on, for a host
|
|
12
|
+
* that serves more than one (MulmoTerminal: one root per project
|
|
13
|
+
* directory). Return `undefined` to use the host's configured root.
|
|
14
|
+
*
|
|
15
|
+
* The resolver is entirely host-owned and the package never reads a
|
|
16
|
+
* root or a project id off the request body itself. That is what
|
|
17
|
+
* keeps the model out of it: `manageAccounting`'s tool schema has no
|
|
18
|
+
* project parameter, so an LLM cannot name a project even by
|
|
19
|
+
* guessing — the host derives the scope from the session, exactly as
|
|
20
|
+
* `manageCollection` does. A host that DOES accept a project id from
|
|
21
|
+
* a browser must resolve it against its own list of projects and
|
|
22
|
+
* never accept a path (see `AccountingServerDeps.channelScopeForRoot`). */
|
|
23
|
+
resolveWorkspaceRoot?: (req: AccountingDispatchRequest) => string | undefined;
|
|
24
|
+
}
|
|
2
25
|
/** Build the accounting Express router. The host injects its workspace
|
|
3
26
|
* root + logger via `configureAccountingServer(...)` and pub/sub via
|
|
4
27
|
* `initAccountingEventPublisher(...)`, then mounts the returned router
|
|
5
|
-
* with `app.use(...)`.
|
|
6
|
-
|
|
28
|
+
* with `app.use(...)`. Pass `resolveWorkspaceRoot` to serve more than
|
|
29
|
+
* one root; omit it and every request uses the configured one. */
|
|
30
|
+
export declare function createAccountingRouter(options?: AccountingRouterOptions): Router;
|
|
7
31
|
//# sourceMappingURL=router.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAY,MAAM,SAAS,CAAC;AA6BpD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA6WD;;iDAEiD;AACjD,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC;AAEvF,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;;;;gFAW4E;IAC5E,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,yBAAyB,KAAK,MAAM,GAAG,SAAS,CAAC;CAC/E;AAED;;;;mEAImE;AACnE,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,MAAM,CA4CpF"}
|
|
@@ -31,16 +31,16 @@ export declare function scheduleRebuild(bookId: string, fromPeriod: string, work
|
|
|
31
31
|
* `bookId`. Also called by `deleteBook` after `cancelRebuild` to
|
|
32
32
|
* ensure a previously running rebuild has fully stopped before the
|
|
33
33
|
* caller removes the book's directory on disk. */
|
|
34
|
-
export declare function awaitRebuildIdle(bookId: string): Promise<void>;
|
|
34
|
+
export declare function awaitRebuildIdle(bookId: string, workspaceRoot?: string): Promise<void>;
|
|
35
35
|
/** Mark the book's in-flight rebuild as cancelled. The runRebuild
|
|
36
36
|
* loop checks before each write and bails out, so a subsequent
|
|
37
37
|
* `removeBookDir` cannot race with a `writeSnapshot` that would
|
|
38
38
|
* re-create the directory tree. Pair with `awaitRebuildIdle(bookId)`
|
|
39
39
|
* to wait for the in-flight rebuild to finish bailing. */
|
|
40
|
-
export declare function cancelRebuild(bookId: string): void;
|
|
40
|
+
export declare function cancelRebuild(bookId: string, workspaceRoot?: string): void;
|
|
41
41
|
/** Test/diagnostic: snapshot of the per-book queue state. Stable
|
|
42
42
|
* enough to assert against; fields may grow over time. */
|
|
43
|
-
export declare function inspectRebuildQueue(bookId: string): {
|
|
43
|
+
export declare function inspectRebuildQueue(bookId: string, workspaceRoot?: string): {
|
|
44
44
|
running: boolean;
|
|
45
45
|
runningFromPeriod: string | null;
|
|
46
46
|
pendingFromPeriod: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshotCache.d.ts","sourceRoot":"","sources":["../../src/server/snapshotCache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"snapshotCache.d.ts","sourceRoot":"","sources":["../../src/server/snapshotCache.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,oBAAoB,CAAC;AA2BvE;;;oEAGoE;AACpE,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8BvH;AAED;;;6BAG6B;AAC7B,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CASvH;AAED;;sDAEsD;AACtD,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAExI;AAED;;eAEe;AACf,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAOhH;AA2JD;;;uEAGuE;AACvE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAUhG;AAED;;;mDAGmD;AACnD,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5F;AAED;;;;2DAI2D;AAC3D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAO1E;AAED;2DAC2D;AAC3D,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GACrB;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CAWA;AAED;;mEAEmE;AACnE,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,IAAI,CAAC,CAUlE"}
|