@legioncodeinc/hive 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 +661 -0
- package/README.md +262 -0
- package/dist/cli-commands.d.ts +41 -0
- package/dist/cli-commands.js +76 -0
- package/dist/cli-commands.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +46 -0
- package/dist/cli.js.map +1 -0
- package/dist/daemon/dashboard/app.js +118 -0
- package/dist/daemon/dashboard/host.d.ts +90 -0
- package/dist/daemon/dashboard/host.js +172 -0
- package/dist/daemon/dashboard/host.js.map +1 -0
- package/dist/daemon/dashboard/web-assets.d.ts +88 -0
- package/dist/daemon/dashboard/web-assets.js +195 -0
- package/dist/daemon/dashboard/web-assets.js.map +1 -0
- package/dist/daemon/fleet-status.d.ts +15 -0
- package/dist/daemon/fleet-status.js +56 -0
- package/dist/daemon/fleet-status.js.map +1 -0
- package/dist/daemon/gate.d.ts +55 -0
- package/dist/daemon/gate.js +128 -0
- package/dist/daemon/gate.js.map +1 -0
- package/dist/daemon/proxy.d.ts +38 -0
- package/dist/daemon/proxy.js +126 -0
- package/dist/daemon/proxy.js.map +1 -0
- package/dist/daemon/registry.d.ts +31 -0
- package/dist/daemon/registry.js +120 -0
- package/dist/daemon/registry.js.map +1 -0
- package/dist/daemon/server.d.ts +41 -0
- package/dist/daemon/server.js +126 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/setup-auth.d.ts +37 -0
- package/dist/daemon/setup-auth.js +51 -0
- package/dist/daemon/setup-auth.js.map +1 -0
- package/dist/daemon/telemetry-proxy.d.ts +47 -0
- package/dist/daemon/telemetry-proxy.js +63 -0
- package/dist/daemon/telemetry-proxy.js.map +1 -0
- package/dist/dashboard/contracts.d.ts +235 -0
- package/dist/dashboard/contracts.js +43 -0
- package/dist/dashboard/contracts.js.map +1 -0
- package/dist/dashboard/web/app.d.ts +44 -0
- package/dist/dashboard/web/app.js +179 -0
- package/dist/dashboard/web/app.js.map +1 -0
- package/dist/dashboard/web/boot-route.d.ts +23 -0
- package/dist/dashboard/web/boot-route.js +29 -0
- package/dist/dashboard/web/boot-route.js.map +1 -0
- package/dist/dashboard/web/build-graph-button.d.ts +46 -0
- package/dist/dashboard/web/build-graph-button.js +81 -0
- package/dist/dashboard/web/build-graph-button.js.map +1 -0
- package/dist/dashboard/web/buzzing-screen.d.ts +30 -0
- package/dist/dashboard/web/buzzing-screen.js +135 -0
- package/dist/dashboard/web/buzzing-screen.js.map +1 -0
- package/dist/dashboard/web/folder-picker.d.ts +54 -0
- package/dist/dashboard/web/folder-picker.js +125 -0
- package/dist/dashboard/web/folder-picker.js.map +1 -0
- package/dist/dashboard/web/graph-layout.d.ts +101 -0
- package/dist/dashboard/web/graph-layout.js +0 -0
- package/dist/dashboard/web/graph-layout.js.map +1 -0
- package/dist/dashboard/web/harness-strip.d.ts +38 -0
- package/dist/dashboard/web/harness-strip.js +65 -0
- package/dist/dashboard/web/harness-strip.js.map +1 -0
- package/dist/dashboard/web/health-rail.d.ts +26 -0
- package/dist/dashboard/web/health-rail.js +61 -0
- package/dist/dashboard/web/health-rail.js.map +1 -0
- package/dist/dashboard/web/main.d.ts +22 -0
- package/dist/dashboard/web/main.js +51 -0
- package/dist/dashboard/web/main.js.map +1 -0
- package/dist/dashboard/web/needs-project.d.ts +51 -0
- package/dist/dashboard/web/needs-project.js +69 -0
- package/dist/dashboard/web/needs-project.js.map +1 -0
- package/dist/dashboard/web/page-frame.d.ts +95 -0
- package/dist/dashboard/web/page-frame.js +98 -0
- package/dist/dashboard/web/page-frame.js.map +1 -0
- package/dist/dashboard/web/pages/coming-soon.d.ts +23 -0
- package/dist/dashboard/web/pages/coming-soon.js +19 -0
- package/dist/dashboard/web/pages/coming-soon.js.map +1 -0
- package/dist/dashboard/web/pages/dashboard.d.ts +32 -0
- package/dist/dashboard/web/pages/dashboard.js +205 -0
- package/dist/dashboard/web/pages/dashboard.js.map +1 -0
- package/dist/dashboard/web/pages/graph.d.ts +72 -0
- package/dist/dashboard/web/pages/graph.js +362 -0
- package/dist/dashboard/web/pages/graph.js.map +1 -0
- package/dist/dashboard/web/pages/harnesses.d.ts +65 -0
- package/dist/dashboard/web/pages/harnesses.js +210 -0
- package/dist/dashboard/web/pages/harnesses.js.map +1 -0
- package/dist/dashboard/web/pages/health.d.ts +22 -0
- package/dist/dashboard/web/pages/health.js +91 -0
- package/dist/dashboard/web/pages/health.js.map +1 -0
- package/dist/dashboard/web/pages/lifecycle-panel.d.ts +60 -0
- package/dist/dashboard/web/pages/lifecycle-panel.js +187 -0
- package/dist/dashboard/web/pages/lifecycle-panel.js.map +1 -0
- package/dist/dashboard/web/pages/logs.d.ts +55 -0
- package/dist/dashboard/web/pages/logs.js +311 -0
- package/dist/dashboard/web/pages/logs.js.map +1 -0
- package/dist/dashboard/web/pages/memories.d.ts +35 -0
- package/dist/dashboard/web/pages/memories.js +439 -0
- package/dist/dashboard/web/pages/memories.js.map +1 -0
- package/dist/dashboard/web/pages/projects.d.ts +38 -0
- package/dist/dashboard/web/pages/projects.js +325 -0
- package/dist/dashboard/web/pages/projects.js.map +1 -0
- package/dist/dashboard/web/pages/roi-chart.d.ts +52 -0
- package/dist/dashboard/web/pages/roi-chart.js +133 -0
- package/dist/dashboard/web/pages/roi-chart.js.map +1 -0
- package/dist/dashboard/web/pages/roi.d.ts +93 -0
- package/dist/dashboard/web/pages/roi.js +375 -0
- package/dist/dashboard/web/pages/roi.js.map +1 -0
- package/dist/dashboard/web/pages/settings.d.ts +103 -0
- package/dist/dashboard/web/pages/settings.js +420 -0
- package/dist/dashboard/web/pages/settings.js.map +1 -0
- package/dist/dashboard/web/pages/sync.d.ts +59 -0
- package/dist/dashboard/web/pages/sync.js +280 -0
- package/dist/dashboard/web/pages/sync.js.map +1 -0
- package/dist/dashboard/web/panels.d.ts +178 -0
- package/dist/dashboard/web/panels.js +471 -0
- package/dist/dashboard/web/panels.js.map +1 -0
- package/dist/dashboard/web/primitives.d.ts +80 -0
- package/dist/dashboard/web/primitives.js +208 -0
- package/dist/dashboard/web/primitives.js.map +1 -0
- package/dist/dashboard/web/readiness-splash.d.ts +39 -0
- package/dist/dashboard/web/readiness-splash.js +201 -0
- package/dist/dashboard/web/readiness-splash.js.map +1 -0
- package/dist/dashboard/web/registry.d.ts +96 -0
- package/dist/dashboard/web/registry.js +99 -0
- package/dist/dashboard/web/registry.js.map +1 -0
- package/dist/dashboard/web/router.d.ts +48 -0
- package/dist/dashboard/web/router.js +76 -0
- package/dist/dashboard/web/router.js.map +1 -0
- package/dist/dashboard/web/scope-context.d.ts +155 -0
- package/dist/dashboard/web/scope-context.js +266 -0
- package/dist/dashboard/web/scope-context.js.map +1 -0
- package/dist/dashboard/web/service-icons.d.ts +33 -0
- package/dist/dashboard/web/service-icons.js +80 -0
- package/dist/dashboard/web/service-icons.js.map +1 -0
- package/dist/dashboard/web/setup-gate.d.ts +116 -0
- package/dist/dashboard/web/setup-gate.js +272 -0
- package/dist/dashboard/web/setup-gate.js.map +1 -0
- package/dist/dashboard/web/sidebar.d.ts +63 -0
- package/dist/dashboard/web/sidebar.js +91 -0
- package/dist/dashboard/web/sidebar.js.map +1 -0
- package/dist/dashboard/web/use-fleet-telemetry.d.ts +111 -0
- package/dist/dashboard/web/use-fleet-telemetry.js +278 -0
- package/dist/dashboard/web/use-fleet-telemetry.js.map +1 -0
- package/dist/dashboard/web/wire.d.ts +1937 -0
- package/dist/dashboard/web/wire.js +1837 -0
- package/dist/dashboard/web/wire.js.map +1 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +11 -0
- package/dist/errors.js.map +1 -0
- package/dist/install/registry.d.ts +35 -0
- package/dist/install/registry.js +110 -0
- package/dist/install/registry.js.map +1 -0
- package/dist/lock.d.ts +10 -0
- package/dist/lock.js +87 -0
- package/dist/lock.js.map +1 -0
- package/dist/service/commands.d.ts +15 -0
- package/dist/service/commands.js +49 -0
- package/dist/service/commands.js.map +1 -0
- package/dist/service/index.d.ts +38 -0
- package/dist/service/index.js +174 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/platform.d.ts +37 -0
- package/dist/service/platform.js +67 -0
- package/dist/service/platform.js.map +1 -0
- package/dist/service/templates.d.ts +10 -0
- package/dist/service/templates.js +120 -0
- package/dist/service/templates.js.map +1 -0
- package/dist/shared/constants.d.ts +15 -0
- package/dist/shared/constants.js +19 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/daemon-routing.d.ts +11 -0
- package/dist/shared/daemon-routing.js +38 -0
- package/dist/shared/daemon-routing.js.map +1 -0
- package/dist/shared/fleet-readiness.d.ts +18 -0
- package/dist/shared/fleet-readiness.js +9 -0
- package/dist/shared/fleet-readiness.js.map +1 -0
- package/dist/shared/fleet-telemetry.d.ts +68 -0
- package/dist/shared/fleet-telemetry.js +61 -0
- package/dist/shared/fleet-telemetry.js.map +1 -0
- package/dist/shared/lifecycle-flags.d.ts +34 -0
- package/dist/shared/lifecycle-flags.js +39 -0
- package/dist/shared/lifecycle-flags.js.map +1 -0
- package/dist/shared/memory-types.d.ts +55 -0
- package/dist/shared/memory-types.js +75 -0
- package/dist/shared/memory-types.js.map +1 -0
- package/dist/shared/service-status.d.ts +82 -0
- package/dist/shared/service-status.js +97 -0
- package/dist/shared/service-status.js.map +1 -0
- package/dist/telemetry/emit.d.ts +197 -0
- package/dist/telemetry/emit.js +196 -0
- package/dist/telemetry/emit.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ROI page — PRD-060e (the `/roi` Net-ROI ledger surface).
|
|
3
|
+
*
|
|
4
|
+
* Mounted at a PRD-037 registry slot (ONE entry in `registry.tsx` + this one component —
|
|
5
|
+
* `library/knowledge/private/dashboard/adding-a-page.md`). The page is a PURE FUNCTION of the
|
|
6
|
+
* {@link RoiView} the daemon assembles (e-AC-2): it switches each section on its `status` discriminant
|
|
7
|
+
* and does NO fetching/compute beyond two `usePoll` hydrations (billing ~60s, token per-session) +
|
|
8
|
+
* one explicit fetch-on-range-change for the trend (e-AC-10). It composes 060b savings, 060c infra,
|
|
9
|
+
* 060d pollination into the Net-ROI ledger and degrades section-by-section.
|
|
10
|
+
*
|
|
11
|
+
* ── The honesty language (folded-in UX brief) ─────────────────────────────────
|
|
12
|
+
* - Measured vs modeled is solved with FOUR reinforcing existing signals (e-AC-3): (1) Badge tone —
|
|
13
|
+
* `verified` (green) measured / `warning` (amber) modeled; (2) numeric weight — `--text-primary`
|
|
14
|
+
* measured / `--text-secondary` modeled (subordinate, indented); (3) a literal `est.` marker + a
|
|
15
|
+
* leading `~` on every modeled figure; (4) dashed-vs-solid chart strokes (in `roi-chart.tsx`). The
|
|
16
|
+
* SAME four distinguish an `allocated` cost from a `measured` one (e-AC-15). The net hero inherits
|
|
17
|
+
* `est.` because it folds a modeled term.
|
|
18
|
+
* - Honey is brand-frame ONLY and never encodes sign (e-AC-4): a positive net renders `var(--verified)`,
|
|
19
|
+
* a negative net `var(--severity-critical)` — never honey.
|
|
20
|
+
* - Degraded states (e-AC-5/6/7): first-run/empty → a DASH glyph (not `$0.00`); token-absent → the
|
|
21
|
+
* `absent` treatment; Claude-Code-only → an info "Claude Code only" badge; billing-unreachable → a
|
|
22
|
+
* dash for the line AND the net + a scoped Retry; not-authenticated → the ledger is gated behind a
|
|
23
|
+
* Settings CTA and ONLY redacted status renders (no token/secret reaches the page — e-AC-7).
|
|
24
|
+
* - Cost-rising is NOT green (e-AC-9): a rising cost KPI delta inverts the usual sense.
|
|
25
|
+
*
|
|
26
|
+
* Money is INTEGER cents in the view-model; dollars are formatted ONLY at the render edge here
|
|
27
|
+
* (e-AC-11). The assumption behind the modeled estimate is disclosed via an ⓘ popover + a persistent
|
|
28
|
+
* page-foot footnote, BOTH sourced from `savings.assumption.assumptionText` (one source — e-AC-8).
|
|
29
|
+
*
|
|
30
|
+
* Security (e-AC-7): the page reads ONLY the loopback `roi`/`roiTrend` endpoints through the injected
|
|
31
|
+
* `wire` (never `createWireClient`); it adds no token/secret and renders subsystem state only. Every
|
|
32
|
+
* visual value is an existing `var(--…)` DS token; no new token, no new dependency. React 18 patterns.
|
|
33
|
+
*/
|
|
34
|
+
import React from "react";
|
|
35
|
+
import type { RoiCostBasisTag, RoiSectionStatus } from "../../contracts.js";
|
|
36
|
+
import { type BadgeTone } from "../primitives.js";
|
|
37
|
+
import type { PageProps } from "../page-frame.js";
|
|
38
|
+
/** The dash glyph the page shows for an absent/unreachable figure — NOT `$0.00` (e-AC-5/e-AC-6). */
|
|
39
|
+
export declare const DASH: "\u2014";
|
|
40
|
+
/**
|
|
41
|
+
* Format INTEGER cents as a dollar string at the render edge (e-AC-11). `~` is the leading modeled
|
|
42
|
+
* marker (the third measured-vs-modeled signal) — present iff `modeled`. NEVER call this for an
|
|
43
|
+
* absent/unreachable figure; those render {@link DASH} instead (a measured `$0.00` is distinct from
|
|
44
|
+
* unknown — e-AC-5).
|
|
45
|
+
*/
|
|
46
|
+
export declare function formatCents(cents: number, modeled?: boolean): string;
|
|
47
|
+
/** Format a token count k/M at the render edge (e-AC-11). */
|
|
48
|
+
export declare function formatTokens(tokens: number): string;
|
|
49
|
+
/**
|
|
50
|
+
* Format the blended `$/Mtok` rate (e-AC-11). `blendedCentsPerMtok` is `null` until token capture is
|
|
51
|
+
* live → render {@link DASH}, NEVER a fabricated `$0.00/Mtok`. When present it is INTEGER cents-per-Mtok.
|
|
52
|
+
*/
|
|
53
|
+
export declare function formatBlendedRate(centsPerMtok: number | null): string;
|
|
54
|
+
/**
|
|
55
|
+
* Signal #1 — Badge tone: `verified` (green) for a MEASURED figure, `warning` (amber) for a MODELED one
|
|
56
|
+
* (e-AC-3). The same maps an `allocated` cost (treated as modeled/`est.`) vs a `measured` one (e-AC-15).
|
|
57
|
+
*/
|
|
58
|
+
export declare function measuredTone(modeled: boolean): BadgeTone;
|
|
59
|
+
/**
|
|
60
|
+
* Signal #2 — numeric weight color: `--text-primary` for a MEASURED figure (the defensible headline),
|
|
61
|
+
* `--text-secondary` for a MODELED one (subordinate). A test asserts a modeled term NEVER renders with
|
|
62
|
+
* the measured (`--text-primary`) treatment (e-AC-3/e-AC-15).
|
|
63
|
+
*/
|
|
64
|
+
export declare function measuredWeightColor(modeled: boolean): string;
|
|
65
|
+
/**
|
|
66
|
+
* The honey-never-encodes-sign rule (e-AC-4): a positive (or zero) net renders `var(--verified)`, a
|
|
67
|
+
* negative net `var(--severity-critical)`. Honey is brand-frame only and is NEVER returned here.
|
|
68
|
+
*/
|
|
69
|
+
export declare function netSignColor(netCents: number): string;
|
|
70
|
+
/**
|
|
71
|
+
* A `cost_basis` is rendered as modeled/`est.` iff it is `allocated` (e-AC-15) — an allocated infra
|
|
72
|
+
* share is an estimate, never a measured fact. `measured`/`none` are not subordinated.
|
|
73
|
+
*/
|
|
74
|
+
export declare function basisIsModeled(basis: RoiCostBasisTag): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Cost-rising-not-green (e-AC-9): for a COST KPI the usual delta sense is INVERTED. A rising cost
|
|
77
|
+
* (delta > 0) is BAD → `var(--severity-critical)`; a falling cost (delta < 0) is good → `var(--verified)`;
|
|
78
|
+
* flat is neutral. A test asserts a cost increase does NOT render green.
|
|
79
|
+
*/
|
|
80
|
+
export declare function costDeltaColor(deltaCents: number): string;
|
|
81
|
+
/** A figure is shown as a DASH (not a number) when its section has no confident value (e-AC-5/e-AC-6). */
|
|
82
|
+
export declare function isDashStatus(status: RoiSectionStatus): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* The ROI page (PRD-060e). Hydrates the composite {@link RoiView} (two `usePoll` loops — billing ~60s,
|
|
85
|
+
* token per-session) + the {@link RoiTrendView} (fetch-on-mount + explicit refetch on a range change,
|
|
86
|
+
* since `usePoll` only re-arms on `ms`). It is a PURE function of those two view-models: it switches each
|
|
87
|
+
* section on its `status` and renders the four-signal measured-vs-modeled language, the honey-frame net,
|
|
88
|
+
* the dimension rollups, and the degraded states — never fetching/computing beyond these hydrations.
|
|
89
|
+
*
|
|
90
|
+
* The whole page is gated behind a Settings CTA when the ROI read is `unauthenticated` (e-AC-7): only a
|
|
91
|
+
* redacted status renders, no ledger.
|
|
92
|
+
*/
|
|
93
|
+
export declare function RoiPage({ wire }: PageProps): React.JSX.Element;
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The ROI page — PRD-060e (the `/roi` Net-ROI ledger surface).
|
|
4
|
+
*
|
|
5
|
+
* Mounted at a PRD-037 registry slot (ONE entry in `registry.tsx` + this one component —
|
|
6
|
+
* `library/knowledge/private/dashboard/adding-a-page.md`). The page is a PURE FUNCTION of the
|
|
7
|
+
* {@link RoiView} the daemon assembles (e-AC-2): it switches each section on its `status` discriminant
|
|
8
|
+
* and does NO fetching/compute beyond two `usePoll` hydrations (billing ~60s, token per-session) +
|
|
9
|
+
* one explicit fetch-on-range-change for the trend (e-AC-10). It composes 060b savings, 060c infra,
|
|
10
|
+
* 060d pollination into the Net-ROI ledger and degrades section-by-section.
|
|
11
|
+
*
|
|
12
|
+
* ── The honesty language (folded-in UX brief) ─────────────────────────────────
|
|
13
|
+
* - Measured vs modeled is solved with FOUR reinforcing existing signals (e-AC-3): (1) Badge tone —
|
|
14
|
+
* `verified` (green) measured / `warning` (amber) modeled; (2) numeric weight — `--text-primary`
|
|
15
|
+
* measured / `--text-secondary` modeled (subordinate, indented); (3) a literal `est.` marker + a
|
|
16
|
+
* leading `~` on every modeled figure; (4) dashed-vs-solid chart strokes (in `roi-chart.tsx`). The
|
|
17
|
+
* SAME four distinguish an `allocated` cost from a `measured` one (e-AC-15). The net hero inherits
|
|
18
|
+
* `est.` because it folds a modeled term.
|
|
19
|
+
* - Honey is brand-frame ONLY and never encodes sign (e-AC-4): a positive net renders `var(--verified)`,
|
|
20
|
+
* a negative net `var(--severity-critical)` — never honey.
|
|
21
|
+
* - Degraded states (e-AC-5/6/7): first-run/empty → a DASH glyph (not `$0.00`); token-absent → the
|
|
22
|
+
* `absent` treatment; Claude-Code-only → an info "Claude Code only" badge; billing-unreachable → a
|
|
23
|
+
* dash for the line AND the net + a scoped Retry; not-authenticated → the ledger is gated behind a
|
|
24
|
+
* Settings CTA and ONLY redacted status renders (no token/secret reaches the page — e-AC-7).
|
|
25
|
+
* - Cost-rising is NOT green (e-AC-9): a rising cost KPI delta inverts the usual sense.
|
|
26
|
+
*
|
|
27
|
+
* Money is INTEGER cents in the view-model; dollars are formatted ONLY at the render edge here
|
|
28
|
+
* (e-AC-11). The assumption behind the modeled estimate is disclosed via an ⓘ popover + a persistent
|
|
29
|
+
* page-foot footnote, BOTH sourced from `savings.assumption.assumptionText` (one source — e-AC-8).
|
|
30
|
+
*
|
|
31
|
+
* Security (e-AC-7): the page reads ONLY the loopback `roi`/`roiTrend` endpoints through the injected
|
|
32
|
+
* `wire` (never `createWireClient`); it adds no token/secret and renders subsystem state only. Every
|
|
33
|
+
* visual value is an existing `var(--…)` DS token; no new token, no new dependency. React 18 patterns.
|
|
34
|
+
*/
|
|
35
|
+
import React from "react";
|
|
36
|
+
import { EMPTY_ROI_TREND, EMPTY_ROI_VIEW } from "../../contracts.js";
|
|
37
|
+
import { Badge, Button } from "../primitives.js";
|
|
38
|
+
import { Panel } from "../panels.js";
|
|
39
|
+
import { PageFrame, usePoll } from "../page-frame.js";
|
|
40
|
+
import { useScope } from "../scope-context.js";
|
|
41
|
+
import { RoiTrendChart } from "./roi-chart.js";
|
|
42
|
+
/** The Settings hash route the not-authenticated gate sends the operator to (e-AC-7). */
|
|
43
|
+
const SETTINGS_ROUTE = "#/settings";
|
|
44
|
+
/** Billing poll cadence (~60s) — the slow loop for the billing-backed sections (infra/pollination/net). */
|
|
45
|
+
const BILLING_POLL_MS = 60_000;
|
|
46
|
+
/** Token poll cadence — the faster per-session loop for the token-derived savings section. */
|
|
47
|
+
const TOKEN_POLL_MS = 15_000;
|
|
48
|
+
/** The default trend window the chart requests; a range change triggers an explicit refetch (e-AC-10). */
|
|
49
|
+
const DEFAULT_RANGE = "30d";
|
|
50
|
+
/** The selectable trend ranges (the dimension-style switch the chart's range control offers). */
|
|
51
|
+
const TREND_RANGES = ["7d", "30d", "90d"];
|
|
52
|
+
/** The dash glyph the page shows for an absent/unreachable figure — NOT `$0.00` (e-AC-5/e-AC-6). */
|
|
53
|
+
export const DASH = "—";
|
|
54
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
55
|
+
// The render edge (e-AC-11) — INTEGER cents → presentation. Cents never leave the
|
|
56
|
+
// view-model as a float; these are the ONLY place dollars/`$/Mtok`/k·M are formed.
|
|
57
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
58
|
+
/**
|
|
59
|
+
* Format INTEGER cents as a dollar string at the render edge (e-AC-11). `~` is the leading modeled
|
|
60
|
+
* marker (the third measured-vs-modeled signal) — present iff `modeled`. NEVER call this for an
|
|
61
|
+
* absent/unreachable figure; those render {@link DASH} instead (a measured `$0.00` is distinct from
|
|
62
|
+
* unknown — e-AC-5).
|
|
63
|
+
*/
|
|
64
|
+
export function formatCents(cents, modeled = false) {
|
|
65
|
+
const sign = cents < 0 ? "-" : "";
|
|
66
|
+
const dollars = Math.abs(cents) / 100;
|
|
67
|
+
const body = `${sign}$${dollars.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
68
|
+
return modeled ? `~${body} est.` : body;
|
|
69
|
+
}
|
|
70
|
+
/** Format a token count k/M at the render edge (e-AC-11). */
|
|
71
|
+
export function formatTokens(tokens) {
|
|
72
|
+
if (tokens >= 1_000_000)
|
|
73
|
+
return `${(tokens / 1_000_000).toFixed(1)}M`;
|
|
74
|
+
if (tokens >= 1_000)
|
|
75
|
+
return `${(tokens / 1_000).toFixed(1)}k`;
|
|
76
|
+
return String(tokens);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Format the blended `$/Mtok` rate (e-AC-11). `blendedCentsPerMtok` is `null` until token capture is
|
|
80
|
+
* live → render {@link DASH}, NEVER a fabricated `$0.00/Mtok`. When present it is INTEGER cents-per-Mtok.
|
|
81
|
+
*/
|
|
82
|
+
export function formatBlendedRate(centsPerMtok) {
|
|
83
|
+
if (centsPerMtok === null)
|
|
84
|
+
return DASH;
|
|
85
|
+
return `$${(centsPerMtok / 100).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}/Mtok`;
|
|
86
|
+
}
|
|
87
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
88
|
+
// The four measured-vs-modeled signals + the honey-never-encodes-sign rule.
|
|
89
|
+
// Pure, exported so the page test asserts the mapping directly (e-AC-3/e-AC-4/e-AC-9/e-AC-15).
|
|
90
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
91
|
+
/**
|
|
92
|
+
* Signal #1 — Badge tone: `verified` (green) for a MEASURED figure, `warning` (amber) for a MODELED one
|
|
93
|
+
* (e-AC-3). The same maps an `allocated` cost (treated as modeled/`est.`) vs a `measured` one (e-AC-15).
|
|
94
|
+
*/
|
|
95
|
+
export function measuredTone(modeled) {
|
|
96
|
+
return modeled ? "warning" : "verified";
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Signal #2 — numeric weight color: `--text-primary` for a MEASURED figure (the defensible headline),
|
|
100
|
+
* `--text-secondary` for a MODELED one (subordinate). A test asserts a modeled term NEVER renders with
|
|
101
|
+
* the measured (`--text-primary`) treatment (e-AC-3/e-AC-15).
|
|
102
|
+
*/
|
|
103
|
+
export function measuredWeightColor(modeled) {
|
|
104
|
+
return modeled ? "var(--text-secondary)" : "var(--text-primary)";
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The honey-never-encodes-sign rule (e-AC-4): a positive (or zero) net renders `var(--verified)`, a
|
|
108
|
+
* negative net `var(--severity-critical)`. Honey is brand-frame only and is NEVER returned here.
|
|
109
|
+
*/
|
|
110
|
+
export function netSignColor(netCents) {
|
|
111
|
+
return netCents < 0 ? "var(--severity-critical)" : "var(--verified)";
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A `cost_basis` is rendered as modeled/`est.` iff it is `allocated` (e-AC-15) — an allocated infra
|
|
115
|
+
* share is an estimate, never a measured fact. `measured`/`none` are not subordinated.
|
|
116
|
+
*/
|
|
117
|
+
export function basisIsModeled(basis) {
|
|
118
|
+
return basis === "allocated";
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Cost-rising-not-green (e-AC-9): for a COST KPI the usual delta sense is INVERTED. A rising cost
|
|
122
|
+
* (delta > 0) is BAD → `var(--severity-critical)`; a falling cost (delta < 0) is good → `var(--verified)`;
|
|
123
|
+
* flat is neutral. A test asserts a cost increase does NOT render green.
|
|
124
|
+
*/
|
|
125
|
+
export function costDeltaColor(deltaCents) {
|
|
126
|
+
if (deltaCents > 0)
|
|
127
|
+
return "var(--severity-critical)";
|
|
128
|
+
if (deltaCents < 0)
|
|
129
|
+
return "var(--verified)";
|
|
130
|
+
return "var(--text-tertiary)";
|
|
131
|
+
}
|
|
132
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
133
|
+
// Small presentation atoms (DS tokens only).
|
|
134
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
135
|
+
/** A mono caption row label. */
|
|
136
|
+
function Caption({ children, color = "var(--text-tertiary)" }) {
|
|
137
|
+
return _jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 11, color }, children: children });
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The ⓘ assumption popover (e-AC-8) — a hover/focus disclosure sourced from `assumption.assumptionText`
|
|
141
|
+
* (the ONE source the page-foot footnote also reads). Pure markup + a local open state; no copy is
|
|
142
|
+
* hardcoded here.
|
|
143
|
+
*/
|
|
144
|
+
function AssumptionInfo({ assumption }) {
|
|
145
|
+
const [open, setOpen] = React.useState(false);
|
|
146
|
+
const text = assumption.assumptionText !== "" ? assumption.assumptionText : "Assumption not yet provided.";
|
|
147
|
+
return (_jsxs("span", { style: { position: "relative", display: "inline-flex" }, children: [_jsx("button", { type: "button", "data-testid": "assumption-info", "aria-label": "modeled assumption", "aria-expanded": open, onClick: () => setOpen((o) => !o), onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false), onFocus: () => setOpen(true), onBlur: () => setOpen(false), style: {
|
|
148
|
+
width: 16,
|
|
149
|
+
height: 16,
|
|
150
|
+
padding: 0,
|
|
151
|
+
borderRadius: "var(--radius-full)",
|
|
152
|
+
border: "1px solid var(--border-strong)",
|
|
153
|
+
background: "transparent",
|
|
154
|
+
color: "var(--text-tertiary)",
|
|
155
|
+
fontFamily: "var(--font-mono)",
|
|
156
|
+
fontSize: 10,
|
|
157
|
+
lineHeight: 1,
|
|
158
|
+
cursor: "pointer",
|
|
159
|
+
}, children: "i" }), open && (_jsxs("span", { role: "tooltip", "data-testid": "assumption-popover", style: {
|
|
160
|
+
position: "absolute",
|
|
161
|
+
top: 22,
|
|
162
|
+
left: 0,
|
|
163
|
+
zIndex: 5,
|
|
164
|
+
width: 260,
|
|
165
|
+
padding: "8px 10px",
|
|
166
|
+
background: "var(--bg-elevated)",
|
|
167
|
+
border: "1px solid var(--border-default)",
|
|
168
|
+
borderRadius: "var(--radius-md)",
|
|
169
|
+
boxShadow: "var(--shadow-md)",
|
|
170
|
+
fontSize: 12,
|
|
171
|
+
lineHeight: "16px",
|
|
172
|
+
color: "var(--text-secondary)",
|
|
173
|
+
}, children: [text, !assumption.signedOff && (_jsx("span", { style: { display: "block", marginTop: 4, fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--text-tertiary)" }, children: "provisional \u2014 not yet signed off" }))] }))] }));
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* One ledger figure row: a label, the figure (a DASH for absent/unreachable, else the formatted cents
|
|
177
|
+
* with the measured/modeled weight + `~`/`est.` markers), a measured/modeled tone Badge, and an optional
|
|
178
|
+
* trailing slot (the ⓘ, a basis caption). `modeled` drives the third+second signals; `dash` forces the
|
|
179
|
+
* DASH glyph regardless of the number (so a measured `$0.00` is distinct from unknown — e-AC-5).
|
|
180
|
+
*/
|
|
181
|
+
function LedgerRow({ label, cents, modeled, dash, indent, tone, toneLabel, trailing, testid, }) {
|
|
182
|
+
return (_jsxs("div", { "data-testid": testid, style: {
|
|
183
|
+
display: "flex",
|
|
184
|
+
alignItems: "center",
|
|
185
|
+
gap: 10,
|
|
186
|
+
padding: "10px 6px",
|
|
187
|
+
paddingLeft: indent ? 22 : 6,
|
|
188
|
+
borderTop: "1px solid var(--border-subtle)",
|
|
189
|
+
}, children: [_jsx("span", { style: { fontSize: 14, color: indent ? "var(--text-secondary)" : "var(--text-primary)" }, children: label }), _jsx(Badge, { tone: tone, mono: true, children: toneLabel }), trailing, _jsx("span", { style: { flex: 1 } }), _jsx("span", { "data-testid": `${testid}-figure`, "data-modeled": modeled ? "true" : "false", style: {
|
|
190
|
+
fontFamily: "var(--font-mono)",
|
|
191
|
+
fontSize: indent ? 15 : 17,
|
|
192
|
+
fontWeight: 700,
|
|
193
|
+
// Signal #2: an absent/unreachable DASH is tertiary; a present figure carries the measured/modeled weight.
|
|
194
|
+
color: dash ? "var(--text-tertiary)" : measuredWeightColor(modeled),
|
|
195
|
+
}, children: dash ? DASH : formatCents(cents, modeled) })] }));
|
|
196
|
+
}
|
|
197
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
198
|
+
// Section status helpers (e-AC-2/e-AC-5/e-AC-6/e-AC-7).
|
|
199
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
200
|
+
/** A figure is shown as a DASH (not a number) when its section has no confident value (e-AC-5/e-AC-6). */
|
|
201
|
+
export function isDashStatus(status) {
|
|
202
|
+
return status === "absent" || status === "unreachable" || status === "unauthenticated";
|
|
203
|
+
}
|
|
204
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
205
|
+
// The NET-ROI hero (e-AC-3/e-AC-4/e-AC-6).
|
|
206
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
207
|
+
/**
|
|
208
|
+
* The Net-ROI hero. The net is rendered ONLY when `net.computed` is true (e-AC-6) — otherwise a DASH
|
|
209
|
+
* glyph + a scoped Retry, never a number fabricated from incomplete inputs. When computed it inherits
|
|
210
|
+
* `est.` (the net folds a modeled term, e-AC-3) and its color obeys the honey-never-encodes-sign rule
|
|
211
|
+
* (e-AC-4): positive `var(--verified)`, negative `var(--severity-critical)`.
|
|
212
|
+
*/
|
|
213
|
+
function NetHero({ net, onRetry, retrying }) {
|
|
214
|
+
const computed = net.computed && net.status === "ok";
|
|
215
|
+
const allocated = basisIsModeled(net.costBasis);
|
|
216
|
+
return (_jsx(Panel, { title: "Net ROI", eyebrow: net.modeled ? "saved − (infra + pollination) · est." : "saved − (infra + pollination)", children: _jsxs("div", { "data-testid": "net-hero", style: { display: "flex", alignItems: "center", gap: 16, padding: "14px 6px", flexWrap: "wrap" }, children: [_jsx("span", { "data-testid": "net-figure", "data-computed": computed ? "true" : "false", style: {
|
|
217
|
+
fontFamily: "var(--font-mono)",
|
|
218
|
+
fontSize: 40,
|
|
219
|
+
fontWeight: 800,
|
|
220
|
+
lineHeight: 1,
|
|
221
|
+
letterSpacing: "-0.02em",
|
|
222
|
+
// e-AC-4: honey NEVER encodes sign — verified (positive) / critical (negative). A non-computed
|
|
223
|
+
// net is a neutral tertiary DASH (no sign to encode).
|
|
224
|
+
color: computed ? netSignColor(net.netCents) : "var(--text-tertiary)",
|
|
225
|
+
}, children: computed ? formatCents(net.netCents, true) : DASH }), computed ? (_jsx(Badge, { tone: "warning", mono: true, children: "est." })) : net.status === "unreachable" ? (_jsxs(_Fragment, { children: [_jsx(Caption, { children: "net not computed - billing is unreachable" }), _jsx(Button, { variant: "ghost", size: "sm", "data-testid": "net-retry", disabled: retrying, onClick: onRetry, children: retrying ? "retrying..." : "Retry" })] })) : (_jsx(Caption, { children: "net not computed yet" })), computed && allocated && (_jsx(Caption, { children: "includes an allocated (estimated) infra share" }))] }) }));
|
|
226
|
+
}
|
|
227
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
228
|
+
// The SAVINGS section (e-AC-3) — measured headline + subordinate modeled est. line.
|
|
229
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
230
|
+
/** The Claude-Code-only partial badge (e-AC-5) — info, not error. */
|
|
231
|
+
function PartialBadge() {
|
|
232
|
+
return (_jsx("span", { "data-testid": "claude-code-only", style: { marginLeft: 4, display: "inline-flex" }, children: _jsx(Badge, { tone: "info", children: "Claude Code only" }) }));
|
|
233
|
+
}
|
|
234
|
+
function SavingsSection({ savings }) {
|
|
235
|
+
const dash = isDashStatus(savings.status);
|
|
236
|
+
return (_jsx(Panel, { title: "Savings", eyebrow: "measured cache \u00B7 modeled memory injection", right: savings.status === "partial" ? _jsx(PartialBadge, {}) : undefined, children: _jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [_jsx(LedgerRow, { testid: "savings-measured", label: "Measured cache savings", cents: savings.measuredCents, modeled: false, dash: dash, tone: measuredTone(false), toneLabel: "measured" }), _jsx(LedgerRow, { testid: "savings-modeled", label: "Modeled memory-injection savings", cents: savings.modeledCents, modeled: true, dash: dash, indent: true, tone: measuredTone(true), toneLabel: "modeled", trailing: _jsx(AssumptionInfo, { assumption: savings.assumption }) }), _jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "8px 6px", borderTop: "1px solid var(--border-subtle)" }, children: [_jsx(Caption, { children: "blended rate" }), _jsx("span", { style: { flex: 1 } }), _jsx("span", { "data-testid": "blended-rate", style: { fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--text-secondary)" }, children: formatBlendedRate(savings.blendedCentsPerMtok) })] })] }) }));
|
|
237
|
+
}
|
|
238
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
239
|
+
// The COST sections (e-AC-6/e-AC-9) — infra + itemized pollination.
|
|
240
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
241
|
+
/**
|
|
242
|
+
* A cost KPI tile with the INVERTED delta sense (e-AC-9). A rising cost (delta > 0) renders the
|
|
243
|
+
* `var(--severity-critical)` (NOT green) treatment; a falling cost renders green. Implemented inline so
|
|
244
|
+
* the shared `Kpi` component is not restructured (per the e-AC-9 directive — keep it additive/inline).
|
|
245
|
+
*/
|
|
246
|
+
function CostKpi({ label, cents, deltaCents, dash, testid }) {
|
|
247
|
+
return (_jsxs("div", { "data-testid": testid, style: {
|
|
248
|
+
display: "flex",
|
|
249
|
+
flexDirection: "column",
|
|
250
|
+
gap: 8,
|
|
251
|
+
padding: 18,
|
|
252
|
+
background: "var(--bg-elevated)",
|
|
253
|
+
border: "1px solid var(--border-default)",
|
|
254
|
+
borderRadius: "var(--radius-lg)",
|
|
255
|
+
}, children: [_jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: "var(--text-xs)", textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--text-tertiary)" }, children: label }), _jsx("span", { "data-testid": `${testid}-figure`, style: { fontFamily: "var(--font-mono)", fontSize: 30, fontWeight: 700, lineHeight: 1, color: dash ? "var(--text-tertiary)" : "var(--text-primary)", letterSpacing: "-0.01em" }, children: dash ? DASH : formatCents(cents) }), !dash && deltaCents !== undefined && deltaCents !== 0 && (_jsxs("span", { "data-testid": `${testid}-delta`, style: { fontFamily: "var(--font-mono)", fontSize: 12, color: costDeltaColor(deltaCents) }, children: [deltaCents > 0 ? "▲" : "▼", " ", formatCents(Math.abs(deltaCents)), " vs prior period"] }))] }));
|
|
256
|
+
}
|
|
257
|
+
function CostSection({ infraCents, infraDash, infraBasis, pollinationCents, pollinationDash, pollinationLines, infraDeltaCents, }) {
|
|
258
|
+
return (_jsxs(Panel, { title: "Cost", eyebrow: "infra \u00B7 pollination", children: [_jsxs("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: 12, marginBottom: 6 }, children: [_jsx(CostKpi, { testid: "infra-kpi", label: basisIsModeled(infraBasis) ? "Infra (allocated, est.)" : "Infra cost", cents: infraCents, deltaCents: infraDeltaCents, dash: infraDash }), _jsx(CostKpi, { testid: "pollination-kpi", label: "Pollination cost", cents: pollinationCents, dash: pollinationDash })] }), _jsx("div", { "data-testid": "pollination-lines", children: pollinationDash || pollinationLines.length === 0 ? (_jsx("div", { style: { padding: "10px 6px", fontSize: 13, color: "var(--text-tertiary)" }, children: pollinationDash ? "Pollination cost unavailable." : "No pollination contributors yet." })) : (pollinationLines.map((l, i) => (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10, padding: "8px 6px", borderTop: "1px solid var(--border-subtle)" }, children: [_jsx(Caption, { children: l.label }), _jsx("span", { style: { flex: 1 } }), _jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--text-secondary)" }, children: formatCents(l.cents) })] }, l.label || i)))) })] }));
|
|
259
|
+
}
|
|
260
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
261
|
+
// The ROLLUPS section (e-AC-13/e-AC-14/e-AC-15) — a dimension switch over view.rollups.
|
|
262
|
+
// The component does NO grouping; the daemon already grouped each dimension (read-time GROUP BY).
|
|
263
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
264
|
+
/** The dimension switch tab (mono pill, honey when active — mirrors the Logs/Sync tabs). */
|
|
265
|
+
function DimTab({ label, active, onClick, testid }) {
|
|
266
|
+
return (_jsx("button", { type: "button", "data-testid": testid, "aria-pressed": active, onClick: onClick, style: {
|
|
267
|
+
height: 30,
|
|
268
|
+
padding: "0 12px",
|
|
269
|
+
background: active ? "var(--honey-subtle)" : "var(--bg-elevated)",
|
|
270
|
+
border: `1px solid ${active ? "var(--honey-border)" : "var(--border-default)"}`,
|
|
271
|
+
borderRadius: "var(--radius-full)",
|
|
272
|
+
color: active ? "var(--honey)" : "var(--text-secondary)",
|
|
273
|
+
fontFamily: "var(--font-sans)",
|
|
274
|
+
fontSize: 12,
|
|
275
|
+
fontWeight: 600,
|
|
276
|
+
cursor: "pointer",
|
|
277
|
+
}, children: label }));
|
|
278
|
+
}
|
|
279
|
+
/** All dimensions in display order; the page only offers those the daemon actually shipped a rollup for. */
|
|
280
|
+
const DIMENSIONS = ["org", "team", "agent", "project"];
|
|
281
|
+
function RollupTable({ rollup, perUserAvailable }) {
|
|
282
|
+
// Finding (peruser-leak / e-AC-14): the per-user gate MUST short-circuit BEFORE any agent row renders.
|
|
283
|
+
// When the dimension is `agent` and per-user is NOT available, render ONLY the "per-user requires
|
|
284
|
+
// verified login" empty state -- NEVER a `rollup-row-agent-*` row or agent label/figure (the prior
|
|
285
|
+
// code rendered the rows first and showed the gate AFTER, leaking per-user data and breaking e-AC-14).
|
|
286
|
+
if (rollup.dimension === "agent" && !perUserAvailable) {
|
|
287
|
+
return (_jsx("div", { "data-testid": `rollup-${rollup.dimension}`, children: _jsx("div", { "data-testid": "per-user-empty", style: { marginTop: 10, padding: "10px 12px", background: "var(--severity-info-bg)", border: "1px solid var(--severity-info)", borderRadius: "var(--radius-md)" }, children: _jsx(Caption, { color: "var(--severity-info)", children: "Per-user requires verified login - sign in to attribute ROI per person." }) }) }));
|
|
288
|
+
}
|
|
289
|
+
return (_jsxs("div", { "data-testid": `rollup-${rollup.dimension}`, children: [rollup.mixedBasis && (_jsx("div", { "data-testid": "mixed-basis-caption", style: { padding: "8px 6px", marginBottom: 4, fontSize: 12, color: "var(--severity-warning)", fontFamily: "var(--font-mono)" }, children: "mixed measured + allocated \u2014 rows are not summed into one net" })), rollup.rows.length === 0 ? (_jsxs("div", { style: { padding: "12px 6px", fontSize: 13, color: "var(--text-tertiary)" }, children: ["No ", rollup.dimension, " rows yet."] })) : (_jsxs(_Fragment, { children: [_jsx("div", { style: { display: "grid", gridTemplateColumns: "1fr auto auto auto", gap: 12, padding: "4px 6px 8px" }, children: ["", "saved", "infra", "net"].map((h, i) => (_jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 10, textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--text-tertiary)", textAlign: i === 0 ? "left" : "right" }, children: h }, i))) }), rollup.rows.map((row, i) => {
|
|
290
|
+
const allocated = basisIsModeled(row.costBasis);
|
|
291
|
+
return (_jsxs("div", { "data-testid": `rollup-row-${rollup.dimension}-${row.key}`, style: { display: "grid", gridTemplateColumns: "1fr auto auto auto", gap: 12, alignItems: "center", padding: "9px 6px", borderTop: "1px solid var(--border-subtle)" }, children: [_jsxs("span", { style: { display: "flex", alignItems: "center", gap: 8, minWidth: 0 }, children: [_jsx("span", { style: { fontSize: 13, color: "var(--text-primary)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, children: row.label || row.key }), allocated && (_jsx("span", { "data-testid": `rollup-allocated-${row.key}`, style: { display: "inline-flex" }, children: _jsx(Badge, { tone: "warning", mono: true, children: "allocated est." }) }))] }), _jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-primary)", textAlign: "right" }, children: formatCents(row.measuredSavingsCents) }), _jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 12, color: allocated ? "var(--text-secondary)" : "var(--text-primary)", textAlign: "right" }, children: allocated ? formatCents(row.infraCostCents, true) : formatCents(row.infraCostCents) }), _jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 12, fontWeight: 600, color: netSignColor(row.netCents), textAlign: "right" }, children: allocated ? formatCents(row.netCents, true) : formatCents(row.netCents) })] }, row.key || i));
|
|
292
|
+
})] }))] }));
|
|
293
|
+
}
|
|
294
|
+
function RollupsSection({ rollups, perUserAvailable }) {
|
|
295
|
+
// The dimensions the daemon actually shipped, in display order (the component does NO grouping).
|
|
296
|
+
const available = DIMENSIONS.filter((d) => rollups.some((r) => r.dimension === d));
|
|
297
|
+
const [dim, setDim] = React.useState(available[0] ?? "org");
|
|
298
|
+
// Keep the active dimension valid if the available set changes between hydrations.
|
|
299
|
+
const activeDim = available.includes(dim) ? dim : (available[0] ?? "org");
|
|
300
|
+
const active = rollups.find((r) => r.dimension === activeDim);
|
|
301
|
+
return (_jsx(Panel, { title: "Rollups", eyebrow: "org \u00B7 team \u00B7 agent \u00B7 project", right: _jsx("div", { style: { display: "flex", gap: 6 }, children: available.map((d) => (_jsx(DimTab, { testid: `rollup-tab-${d}`, label: d, active: d === activeDim, onClick: () => setDim(d) }, d))) }), children: available.length === 0 || active === undefined ? (_jsx("div", { style: { padding: "12px 6px", fontSize: 13, color: "var(--text-tertiary)" }, children: "No rollups yet." })) : (_jsx(RollupTable, { rollup: active, perUserAvailable: perUserAvailable })) }));
|
|
302
|
+
}
|
|
303
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
304
|
+
// The not-authenticated gate (e-AC-7) — redacted status + a Settings CTA. NO secret.
|
|
305
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
306
|
+
/**
|
|
307
|
+
* The ledger gate the page shows when the ROI read is `unauthenticated` (e-AC-7). It renders ONLY a
|
|
308
|
+
* redacted status line ("not connected") + a Settings CTA — NO token/secret/credential value reaches the
|
|
309
|
+
* page (the view-model carries none by construction; this gate renders no credential field at all).
|
|
310
|
+
*/
|
|
311
|
+
function AuthGate() {
|
|
312
|
+
return (_jsx(Panel, { title: "ROI ledger", eyebrow: "locked", children: _jsxs("div", { "data-testid": "auth-gate", style: { display: "flex", flexDirection: "column", alignItems: "flex-start", gap: 12, padding: "20px 8px" }, children: [_jsx("span", { "data-testid": "auth-redacted-status", style: { display: "inline-flex" }, children: _jsx(Badge, { tone: "neutral", mono: true, dot: true, children: "not connected" }) }), _jsx("span", { style: { fontSize: 14, color: "var(--text-secondary)", maxWidth: 460 }, children: "Connect Honeycomb to read the shared ROI ledger. The dashboard never holds your credentials \u2014 the daemon is the sole egress." }), _jsx(Button, { variant: "primary", size: "sm", "data-testid": "auth-settings-cta", onClick: () => { window.location.hash = SETTINGS_ROUTE; }, children: "Open Settings" })] }) }));
|
|
313
|
+
}
|
|
314
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
315
|
+
// The routed page.
|
|
316
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
317
|
+
/**
|
|
318
|
+
* The ROI page (PRD-060e). Hydrates the composite {@link RoiView} (two `usePoll` loops — billing ~60s,
|
|
319
|
+
* token per-session) + the {@link RoiTrendView} (fetch-on-mount + explicit refetch on a range change,
|
|
320
|
+
* since `usePoll` only re-arms on `ms`). It is a PURE function of those two view-models: it switches each
|
|
321
|
+
* section on its `status` and renders the four-signal measured-vs-modeled language, the honey-frame net,
|
|
322
|
+
* the dimension rollups, and the degraded states — never fetching/computing beyond these hydrations.
|
|
323
|
+
*
|
|
324
|
+
* The whole page is gated behind a Settings CTA when the ROI read is `unauthenticated` (e-AC-7): only a
|
|
325
|
+
* redacted status renders, no ledger.
|
|
326
|
+
*/
|
|
327
|
+
export function RoiPage({ wire }) {
|
|
328
|
+
const { scope } = useScope();
|
|
329
|
+
const projectId = scope.project;
|
|
330
|
+
const [view, setView] = React.useState(EMPTY_ROI_VIEW);
|
|
331
|
+
const [trend, setTrend] = React.useState(EMPTY_ROI_TREND);
|
|
332
|
+
const [range, setRange] = React.useState(DEFAULT_RANGE);
|
|
333
|
+
const [retrying, setRetrying] = React.useState(false);
|
|
334
|
+
// Hydrate the composite view. Both poll loops call the SAME read (the daemon assembles billing +
|
|
335
|
+
// token into one view-model); the two cadences exist per the page-frame idiom — a slow billing loop
|
|
336
|
+
// and a faster token loop — so a token change surfaces sooner than the ~60s billing refresh.
|
|
337
|
+
const loadView = React.useCallback(async () => {
|
|
338
|
+
const next = await wire.roi(projectId);
|
|
339
|
+
setView(next);
|
|
340
|
+
}, [wire, projectId]);
|
|
341
|
+
// Two usePoll loops (e-AC: page-frame idiom): billing (~60s) + token (per-session/faster).
|
|
342
|
+
usePoll(loadView, BILLING_POLL_MS);
|
|
343
|
+
usePoll(loadView, TOKEN_POLL_MS);
|
|
344
|
+
// The trend needs an EXPLICIT fetch-on-change effect: usePoll only re-arms on `ms`, so a range change
|
|
345
|
+
// would not refetch under it. This effect refetches whenever the range (or scope/project) changes.
|
|
346
|
+
React.useEffect(() => {
|
|
347
|
+
let alive = true;
|
|
348
|
+
void (async () => {
|
|
349
|
+
const next = await wire.roiTrend(range, projectId);
|
|
350
|
+
if (alive)
|
|
351
|
+
setTrend(next);
|
|
352
|
+
})();
|
|
353
|
+
return () => {
|
|
354
|
+
alive = false;
|
|
355
|
+
};
|
|
356
|
+
}, [wire, range, projectId]);
|
|
357
|
+
// The scoped Retry (e-AC-6): re-read the view (and the trend) when billing was unreachable.
|
|
358
|
+
const onRetry = React.useCallback(async () => {
|
|
359
|
+
setRetrying(true);
|
|
360
|
+
try {
|
|
361
|
+
await loadView();
|
|
362
|
+
const t = await wire.roiTrend(range, projectId);
|
|
363
|
+
setTrend(t);
|
|
364
|
+
}
|
|
365
|
+
finally {
|
|
366
|
+
setRetrying(false);
|
|
367
|
+
}
|
|
368
|
+
}, [loadView, wire, range, projectId]);
|
|
369
|
+
// e-AC-7: the entire ledger is gated when the savings read is unauthenticated (no credentials). Only a
|
|
370
|
+
// redacted status renders — no figure, no token, no secret.
|
|
371
|
+
const unauthenticated = view.savings.status === "unauthenticated" || view.net.status === "unauthenticated";
|
|
372
|
+
const scopeEyebrow = view.scopedAcrossDevices ? "across devices" : "this device";
|
|
373
|
+
return (_jsx(PageFrame, { title: "ROI", eyebrow: `net-roi ledger · ${scopeEyebrow}`, children: unauthenticated ? (_jsx(AuthGate, {})) : (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: [_jsx(NetHero, { net: view.net, onRetry: () => void onRetry(), retrying: retrying }), _jsx(SavingsSection, { savings: view.savings }), _jsx(CostSection, { infraCents: view.infra.cents, infraDash: isDashStatus(view.infra.status), infraBasis: view.infra.costBasis, pollinationCents: view.pollination.cents, pollinationDash: isDashStatus(view.pollination.status), pollinationLines: view.pollination.lines }), _jsx(Panel, { title: "Trend", eyebrow: "measured (solid) \u00B7 modeled (dashed)", right: _jsx("div", { style: { display: "flex", gap: 6 }, children: TREND_RANGES.map((r) => (_jsx(DimTab, { testid: `trend-range-${r}`, label: r, active: r === range, onClick: () => setRange(r) }, r))) }), children: _jsx(RoiTrendChart, { trend: trend }) }), _jsx(RollupsSection, { rollups: view.rollups, perUserAvailable: view.perUserAvailable }), _jsxs("div", { "data-testid": "assumption-footnote", style: { marginTop: 4, padding: "12px 6px", borderTop: "1px solid var(--border-subtle)", fontSize: 12, lineHeight: "18px", color: "var(--text-tertiary)" }, children: [_jsx("span", { style: { fontWeight: 600, color: "var(--text-secondary)" }, children: "Modeled estimate assumption: " }), view.savings.assumption.assumptionText !== "" ? view.savings.assumption.assumptionText : "Assumption not yet provided.", view.ratesAsOf !== "" && _jsxs("span", { style: { marginLeft: 8, fontFamily: "var(--font-mono)" }, children: ["\u00B7 rates as of ", view.ratesAsOf] })] })] })) }));
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=roi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roi.js","sourceRoot":"","sources":["../../../../src/dashboard/web/pages/roi.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAkB,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,yFAAyF;AACzF,MAAM,cAAc,GAAG,YAAqB,CAAC;AAE7C,2GAA2G;AAC3G,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,8FAA8F;AAC9F,MAAM,aAAa,GAAG,MAAM,CAAC;AAC7B,0GAA0G;AAC1G,MAAM,aAAa,GAAG,KAAc,CAAC;AACrC,iGAAiG;AACjG,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAEnD,oGAAoG;AACpG,MAAM,CAAC,MAAM,IAAI,GAAG,GAAY,CAAC;AAEjC,gFAAgF;AAChF,kFAAkF;AAClF,mFAAmF;AACnF,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,OAAO,GAAG,KAAK;IACzD,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;IACtC,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACpH,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,YAAY,CAAC,MAAc;IAC1C,IAAI,MAAM,IAAI,SAAS;QAAE,OAAO,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACtE,IAAI,MAAM,IAAI,KAAK;QAAE,OAAO,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAC9D,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAA2B;IAC5D,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AAC1H,CAAC;AAED,gFAAgF;AAChF,4EAA4E;AAC5E,+FAA+F;AAC/F,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC5C,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IACnD,OAAO,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC5C,OAAO,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,iBAAiB,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAsB;IACpD,OAAO,KAAK,KAAK,WAAW,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB;IAChD,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,0BAA0B,CAAC;IACtD,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAC7C,OAAO,sBAAsB,CAAC;AAC/B,CAAC;AAED,gFAAgF;AAChF,6CAA6C;AAC7C,gFAAgF;AAEhF,gCAAgC;AAChC,SAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,sBAAsB,EAAiD;IAC3G,OAAO,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,YAAG,QAAQ,GAAQ,CAAC;AAChG,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,EAAE,UAAU,EAAiC;IACpE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,UAAU,CAAC,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,8BAA8B,CAAC;IAC3G,OAAO,CACN,gBAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,aAC5D,iBACC,IAAI,EAAC,QAAQ,iBACD,iBAAiB,gBAClB,oBAAoB,mBAChB,IAAI,EACnB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EACjC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EACjC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAClC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAC5B,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAC5B,KAAK,EAAE;oBACN,KAAK,EAAE,EAAE;oBACT,MAAM,EAAE,EAAE;oBACV,OAAO,EAAE,CAAC;oBACV,YAAY,EAAE,oBAAoB;oBAClC,MAAM,EAAE,gCAAgC;oBACxC,UAAU,EAAE,aAAa;oBACzB,KAAK,EAAE,sBAAsB;oBAC7B,UAAU,EAAE,kBAAkB;oBAC9B,QAAQ,EAAE,EAAE;oBACZ,UAAU,EAAE,CAAC;oBACb,MAAM,EAAE,SAAS;iBACjB,kBAGO,EACR,IAAI,IAAI,CACR,gBACC,IAAI,EAAC,SAAS,iBACF,oBAAoB,EAChC,KAAK,EAAE;oBACN,QAAQ,EAAE,UAAU;oBACpB,GAAG,EAAE,EAAE;oBACP,IAAI,EAAE,CAAC;oBACP,MAAM,EAAE,CAAC;oBACT,KAAK,EAAE,GAAG;oBACV,OAAO,EAAE,UAAU;oBACnB,UAAU,EAAE,oBAAoB;oBAChC,MAAM,EAAE,iCAAiC;oBACzC,YAAY,EAAE,kBAAkB;oBAChC,SAAS,EAAE,kBAAkB;oBAC7B,QAAQ,EAAE,EAAE;oBACZ,UAAU,EAAE,MAAM;oBAClB,KAAK,EAAE,uBAAuB;iBAC9B,aAEA,IAAI,EACJ,CAAC,UAAU,CAAC,SAAS,IAAI,CACzB,eAAM,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,sDAErH,CACP,IACK,CACP,IACK,CACP,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,EAClB,KAAK,EACL,KAAK,EACL,OAAO,EACP,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,MAAM,GAWN;IACA,OAAO,CACN,8BACc,MAAM,EACnB,KAAK,EAAE;YACN,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,EAAE;YACP,OAAO,EAAE,UAAU;YACnB,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5B,SAAS,EAAE,gCAAgC;SAC3C,aAED,eAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,EAAE,YAAG,KAAK,GAAQ,EAC9G,KAAC,KAAK,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,kBACrB,SAAS,GACH,EACP,QAAQ,EACT,eAAM,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAI,EAC5B,8BACc,GAAG,MAAM,SAAS,kBACjB,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EACxC,KAAK,EAAE;oBACN,UAAU,EAAE,kBAAkB;oBAC9B,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;oBAC1B,UAAU,EAAE,GAAG;oBACf,2GAA2G;oBAC3G,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC;iBACnE,YAEA,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,GACpC,IACF,CACN,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,wDAAwD;AACxD,gFAAgF;AAEhF,0GAA0G;AAC1G,MAAM,UAAU,YAAY,CAAC,MAAwB;IACpD,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,aAAa,IAAI,MAAM,KAAK,iBAAiB,CAAC;AACxF,CAAC;AAED,gFAAgF;AAChF,2CAA2C;AAC3C,gFAAgF;AAEhF;;;;;GAKG;AACH,SAAS,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAkE;IAC1G,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC;IACrD,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAChD,OAAO,CACN,KAAC,KAAK,IAAC,KAAK,EAAC,SAAS,EAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,+BAA+B,YACrH,8BAAiB,UAAU,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,aAC3H,8BACa,YAAY,mBACT,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAC1C,KAAK,EAAE;wBACN,UAAU,EAAE,kBAAkB;wBAC9B,QAAQ,EAAE,EAAE;wBACZ,UAAU,EAAE,GAAG;wBACf,UAAU,EAAE,CAAC;wBACb,aAAa,EAAE,SAAS;wBACxB,+FAA+F;wBAC/F,sDAAsD;wBACtD,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,sBAAsB;qBACrE,YAEA,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAC5C,EACN,QAAQ,CAAC,CAAC,CAAC,CACX,KAAC,KAAK,IAAC,IAAI,EAAC,SAAS,EAAC,IAAI,2BAElB,CACR,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,CAIlC,8BACC,KAAC,OAAO,4DAAoD,EAC5D,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,iBAAa,WAAW,EAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,YAC5F,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,GAC3B,IACP,CACH,CAAC,CAAC,CAAC,CACH,KAAC,OAAO,uCAA+B,CACvC,EACA,QAAQ,IAAI,SAAS,IAAI,CACzB,KAAC,OAAO,gEAAwD,CAChE,IACI,GACC,CACR,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,oFAAoF;AACpF,gFAAgF;AAEhF,qEAAqE;AACrE,SAAS,YAAY;IACpB,OAAO,CACN,8BAAkB,kBAAkB,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,YACpF,KAAC,KAAK,IAAC,IAAI,EAAC,MAAM,iCAAyB,GACrC,CACP,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,EAAE,OAAO,EAAkC;IAClE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,CACN,KAAC,KAAK,IACL,KAAK,EAAC,SAAS,EACf,OAAO,EAAC,gDAA2C,EACnD,KAAK,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,KAAC,YAAY,KAAG,CAAC,CAAC,CAAC,SAAS,YAElE,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,aAEvD,KAAC,SAAS,IACT,MAAM,EAAC,kBAAkB,EACzB,KAAK,EAAC,wBAAwB,EAC9B,KAAK,EAAE,OAAO,CAAC,aAAa,EAC5B,OAAO,EAAE,KAAK,EACd,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,EACzB,SAAS,EAAC,UAAU,GACnB,EAEF,KAAC,SAAS,IACT,MAAM,EAAC,iBAAiB,EACxB,KAAK,EAAC,kCAAkC,EACxC,KAAK,EAAE,OAAO,CAAC,YAAY,EAC3B,OAAO,QACP,IAAI,EAAE,IAAI,EACV,MAAM,QACN,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,EACxB,SAAS,EAAC,SAAS,EACnB,QAAQ,EAAE,KAAC,cAAc,IAAC,UAAU,EAAE,OAAO,CAAC,UAAU,GAAI,GAC3D,EACF,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,gCAAgC,EAAE,aAC7H,KAAC,OAAO,+BAAuB,EAC/B,eAAM,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAI,EAC5B,8BAAkB,cAAc,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,YACtH,iBAAiB,CAAC,OAAO,CAAC,mBAAmB,CAAC,GACzC,IACF,IACD,GACC,CACR,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,oEAAoE;AACpE,gFAAgF;AAEhF;;;;GAIG;AACH,SAAS,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAwF;IAChJ,OAAO,CACN,8BACc,MAAM,EACnB,KAAK,EAAE;YACN,OAAO,EAAE,MAAM;YACf,aAAa,EAAE,QAAQ;YACvB,GAAG,EAAE,CAAC;YACN,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,oBAAoB;YAChC,MAAM,EAAE,iCAAiC;YACzC,YAAY,EAAE,kBAAkB;SAChC,aAED,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,sBAAsB,EAAE,YAC7J,KAAK,GACA,EACP,8BACc,GAAG,MAAM,SAAS,EAC/B,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,YAE9K,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,GAC3B,EACN,CAAC,IAAI,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,CAAC,IAAI,CACzD,+BAAmB,GAAG,MAAM,QAAQ,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,aAE9H,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,OAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,wBACzD,CACP,IACI,CACN,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,EACpB,UAAU,EACV,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,GASf;IACA,OAAO,CACN,MAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,0BAAqB,aAChD,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,sCAAsC,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,aACrH,KAAC,OAAO,IAAC,MAAM,EAAC,WAAW,EAAC,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,GAAI,EAC7K,KAAC,OAAO,IAAC,MAAM,EAAC,iBAAiB,EAAC,KAAK,EAAC,kBAAkB,EAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,GAAI,IACxG,EAEN,6BAAiB,mBAAmB,YAClC,eAAe,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACnD,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,YAC9E,eAAe,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,kCAAkC,GAClF,CACN,CAAC,CAAC,CAAC,CACH,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAC9B,eAAwB,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,gCAAgC,EAAE,aACjJ,KAAC,OAAO,cAAE,CAAC,CAAC,KAAK,GAAW,EAC5B,eAAM,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAI,EAC5B,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,YAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,GAAQ,KAHnH,CAAC,CAAC,KAAK,IAAI,CAAC,CAIhB,CACN,CAAC,CACF,GACI,IACC,CACR,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,wFAAwF;AACxF,kGAAkG;AAClG,gFAAgF;AAEhF,4FAA4F;AAC5F,SAAS,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAA2E;IAC1H,OAAO,CACN,iBACC,IAAI,EAAC,QAAQ,iBACA,MAAM,kBACL,MAAM,EACpB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE;YACN,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,QAAQ;YACjB,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,oBAAoB;YACjE,MAAM,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,uBAAuB,EAAE;YAC/E,YAAY,EAAE,oBAAoB;YAClC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,uBAAuB;YACxD,UAAU,EAAE,kBAAkB;YAC9B,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,GAAG;YACf,MAAM,EAAE,SAAS;SACjB,YAEA,KAAK,GACE,CACT,CAAC;AACH,CAAC;AAED,4GAA4G;AAC5G,MAAM,UAAU,GAAkC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AAEtF,SAAS,WAAW,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAoD;IAClG,uGAAuG;IACvG,kGAAkG;IAClG,mGAAmG;IACnG,uGAAuG;IACvG,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvD,OAAO,CACN,6BAAkB,UAAU,MAAM,CAAC,SAAS,EAAE,YAC7C,6BAAiB,gBAAgB,EAAC,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,yBAAyB,EAAE,MAAM,EAAE,gCAAgC,EAAE,YAAY,EAAE,kBAAkB,EAAE,YAClM,KAAC,OAAO,IAAC,KAAK,EAAC,sBAAsB,wFAAkF,GAClH,GACD,CACN,CAAC;IACH,CAAC;IACD,OAAO,CACN,8BAAkB,UAAU,MAAM,CAAC,SAAS,EAAE,aAE5C,MAAM,CAAC,UAAU,IAAI,CACrB,6BAAiB,qBAAqB,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,UAAU,EAAE,kBAAkB,EAAE,mFAE/J,CACN,EACA,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC3B,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,oBAAM,MAAM,CAAC,SAAS,kBAAiB,CACvH,CAAC,CAAC,CAAC,CACH,8BACC,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,YACzG,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAC5C,eAAc,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,sBAAsB,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,YAC9L,CAAC,IADQ,CAAC,CAEL,CACP,CAAC,GACG,EACL,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;wBAC3B,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;wBAChD,OAAO,CACN,8BAAqC,cAAc,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,GAAG,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,gCAAgC,EAAE,aACtP,gBAAM,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,aAC1E,eAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,YAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,GAAQ,EAC7J,SAAS,IAAI,CACb,8BAAmB,oBAAoB,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,YAClF,KAAC,KAAK,IAAC,IAAI,EAAC,SAAS,EAAC,IAAI,qCAElB,GACF,CACP,IACK,EACP,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,OAAO,EAAE,YAAG,WAAW,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAQ,EAC/J,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,EAAE,SAAS,EAAE,OAAO,EAAE,YACnJ,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,GAC9E,EACP,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,YAEnI,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,GAClE,KAlBE,GAAG,CAAC,GAAG,IAAI,CAAC,CAmBhB,CACN,CAAC;oBACH,CAAC,CAAC,IACA,CACH,IACI,CACN,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAgE;IAClH,iGAAiG;IACjG,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAqB,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;IAChF,mFAAmF;IACnF,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;IAE9D,OAAO,CACN,KAAC,KAAK,IACL,KAAK,EAAC,SAAS,EACf,OAAO,EAAC,6CAA8B,EACtC,KAAK,EACJ,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,YACrC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACrB,KAAC,MAAM,IAAS,MAAM,EAAE,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAzF,CAAC,CAA4F,CAC1G,CAAC,GACG,YAGN,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CACjD,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,gCAAuB,CACvG,CAAC,CAAC,CAAC,CACH,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,GAAI,CACnE,GACM,CACR,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,qFAAqF;AACrF,gFAAgF;AAEhF;;;;GAIG;AACH,SAAS,QAAQ;IAChB,OAAO,CACN,KAAC,KAAK,IAAC,KAAK,EAAC,YAAY,EAAC,OAAO,EAAC,QAAQ,YACzC,8BAAiB,WAAW,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,aACvI,8BAAkB,sBAAsB,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,YACzE,KAAC,KAAK,IAAC,IAAI,EAAC,SAAS,EAAC,IAAI,QAAC,GAAG,oCAEtB,GACF,EACP,eAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,GAAG,EAAE,kJAErE,EACP,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,iBAAa,mBAAmB,EAAC,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,8BAEpH,IACJ,GACC,CACR,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;;;;;;;GASG;AACH,MAAM,UAAU,OAAO,CAAC,EAAE,IAAI,EAAa;IAC1C,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC;IAEhC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAU,cAAc,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAe,eAAe,CAAC,CAAC;IACxE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAS,aAAa,CAAC,CAAC;IAChE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEtD,iGAAiG;IACjG,oGAAoG;IACpG,6FAA6F;IAC7F,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAmB,EAAE;QAC5D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IAEtB,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACnC,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEjC,sGAAsG;IACtG,mGAAmG;IACnG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,KAAK,CAAC,KAAK,IAAI,EAAE;YAChB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YACnD,IAAI,KAAK;gBAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,GAAG,EAAE;YACX,KAAK,GAAG,KAAK,CAAC;QACf,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAE7B,4FAA4F;IAC5F,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,IAAmB,EAAE;QAC3D,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,CAAC;YACJ,MAAM,QAAQ,EAAE,CAAC;YACjB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAChD,QAAQ,CAAC,CAAC,CAAC,CAAC;QACb,CAAC;gBAAS,CAAC;YACV,WAAW,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACF,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAEvC,uGAAuG;IACvG,4DAA4D;IAC5D,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,iBAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,iBAAiB,CAAC;IAE3G,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC;IAEjF,OAAO,CACN,KAAC,SAAS,IAAC,KAAK,EAAC,KAAK,EAAC,OAAO,EAAE,oBAAoB,YAAY,EAAE,YAChE,eAAe,CAAC,CAAC,CAAC,CAClB,KAAC,QAAQ,KAAG,CACZ,CAAC,CAAC,CAAC,CACH,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,aAChE,KAAC,OAAO,IAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAI,EAC7E,KAAC,cAAc,IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAI,EACzC,KAAC,WAAW,IACX,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAC5B,SAAS,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAC1C,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAChC,gBAAgB,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,EACxC,eAAe,EAAE,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EACtD,gBAAgB,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,GACvC,EACF,KAAC,KAAK,IACL,KAAK,EAAC,OAAO,EACb,OAAO,EAAC,0CAAqC,EAC7C,KAAK,EACJ,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,YACrC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACxB,KAAC,MAAM,IAAS,MAAM,EAAE,eAAe,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAxF,CAAC,CAA2F,CACzG,CAAC,GACG,YAGP,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,GAAI,GACxB,EACR,KAAC,cAAc,IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,GAAI,EAIlF,8BACa,qBAAqB,EACjC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,gCAAgC,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,EAAE,aAE1J,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,uBAAuB,EAAE,8CAAsC,EACrG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,8BAA8B,EACvH,IAAI,CAAC,SAAS,KAAK,EAAE,IAAI,gBAAM,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,oCAAiB,IAAI,CAAC,SAAS,IAAQ,IAC1H,IACD,CACN,GACU,CACZ,CAAC;AACH,CAAC"}
|