@happyvertical/smrt-svelte 0.55.18 → 0.55.20
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/agents/cookbook-shell.md +26 -2
- package/agents/overview-surfaces.md +13 -3
- package/agents/workspace.md +46 -0
- package/dist/components/app/AppShell.svelte +29 -7
- package/dist/components/app/AppShell.svelte.d.ts +13 -5
- package/dist/components/app/AppShell.svelte.d.ts.map +1 -1
- package/dist/components/app/DockToggles.svelte +89 -47
- package/dist/components/app/DockToggles.svelte.d.ts +1 -1
- package/dist/components/app/DockToggles.svelte.d.ts.map +1 -1
- package/dist/components/app/PhoneTabBar.svelte +37 -12
- package/dist/components/app/PhoneTabBar.svelte.d.ts +1 -1
- package/dist/components/app/PhoneTabBar.svelte.d.ts.map +1 -1
- package/dist/components/app/ShellSettingsPage.svelte +2 -2
- package/dist/components/app/ShellSettingsPage.svelte.d.ts +2 -2
- package/dist/components/app/ShellSettingsPage.svelte.d.ts.map +1 -1
- package/dist/components/app/dock-toggle.d.ts +45 -0
- package/dist/components/app/dock-toggle.d.ts.map +1 -1
- package/dist/components/app/dock-toggle.js +26 -1
- package/dist/components/app/index.d.ts +1 -0
- package/dist/components/app/index.d.ts.map +1 -1
- package/dist/components/app/shell-user.d.ts +14 -0
- package/dist/components/app/shell-user.d.ts.map +1 -0
- package/dist/components/app/shell-user.js +1 -0
- package/dist/components/cookbook/CookbookSectionOverview.svelte +22 -3
- package/dist/components/cookbook/CookbookSectionOverview.svelte.d.ts +11 -2
- package/dist/components/cookbook/CookbookSectionOverview.svelte.d.ts.map +1 -1
- package/dist/components/cookbook/CookbookSectionPage.svelte +27 -9
- package/dist/components/cookbook/CookbookSectionPage.svelte.d.ts.map +1 -1
- package/dist/components/cookbook/index.d.ts +3 -1
- package/dist/components/cookbook/index.d.ts.map +1 -1
- package/dist/components/cookbook/index.js +2 -1
- package/dist/components/cookbook/registry.d.ts +18 -4
- package/dist/components/cookbook/registry.d.ts.map +1 -1
- package/dist/components/cookbook/registry.js +40 -2
- package/dist/components/cookbook/types.d.ts +39 -4
- package/dist/components/cookbook/types.d.ts.map +1 -1
- package/dist/components/overview/OverviewGrid.svelte +1 -0
- package/dist/components/overview/index.d.ts +1 -1
- package/dist/components/overview/index.d.ts.map +1 -1
- package/dist/components/overview/types.d.ts +6 -0
- package/dist/components/overview/types.d.ts.map +1 -1
- package/dist/components/overview/widgets/ChartWidget.svelte +158 -18
- package/dist/components/overview/widgets/ChartWidget.svelte.d.ts.map +1 -1
- package/dist/components/overview/widgets/ShortcutsWidget.svelte +32 -3
- package/dist/components/overview/widgets/ShortcutsWidget.svelte.d.ts.map +1 -1
- package/dist/components/overview/widgets/core.d.ts +9 -1
- package/dist/components/overview/widgets/core.d.ts.map +1 -1
- package/dist/components/overview/widgets/core.js +20 -1
- package/dist/components/overview/widgets/data.d.ts +16 -6
- package/dist/components/overview/widgets/data.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/AdminShell.svelte +13 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte +52 -7
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte.d.ts +6 -2
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte +54 -5
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte.d.ts +7 -2
- package/dist/components/workspace/admin-shell/WorkspaceAccountMenu.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/mobile-shell.d.ts +1 -1
- package/dist/components/workspace/admin-shell/mobile-shell.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/state.svelte.d.ts +9 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/state.svelte.js +14 -0
- package/dist/i18n/strings.overview.d.ts +5 -0
- package/dist/i18n/strings.overview.d.ts.map +1 -1
- package/dist/i18n/strings.overview.js +5 -0
- package/dist/i18n/strings.workspace.d.ts +2 -0
- package/dist/i18n/strings.workspace.d.ts.map +1 -1
- package/dist/i18n/strings.workspace.js +3 -0
- package/package.json +16 -16
package/agents/cookbook-shell.md
CHANGED
|
@@ -18,7 +18,7 @@ sample data source are not part of it.
|
|
|
18
18
|
| Entry | Contents |
|
|
19
19
|
|---|---|
|
|
20
20
|
| `./cookbook/server` | Svelte-free and Node-safe. `loadCookbookApp` (file + manifests + validation), `readInstalledManifests`, `hasCookbook`, and the pure builder/catalog/theme functions and types. Use it in `+layout.server.ts`. |
|
|
21
|
-
| `./cookbook` | Everything above that is browser-safe, plus `CookbookApp`, `CookbookSectionPage`, `applyCookbookTheme`, `createCookbookRegistry`, `createSectionOverview`. |
|
|
21
|
+
| `./cookbook` | Everything above that is browser-safe, plus `CookbookApp`, `CookbookSectionPage`, `CookbookSectionOverview`, `applyCookbookTheme`, `createCookbookRegistry`, `createSectionOverview`. |
|
|
22
22
|
|
|
23
23
|
## Pure core (no DOM, Node-testable)
|
|
24
24
|
|
|
@@ -84,7 +84,8 @@ sample data source are not part of it.
|
|
|
84
84
|
`slotItems`, `settingsHref`, ...), and:
|
|
85
85
|
|
|
86
86
|
- `loaders` (`metric` / `records` / `chart` data loaders; with `metric` and
|
|
87
|
-
`records` the section pages add the count and latest records
|
|
87
|
+
`records` the section pages add the count and latest records; `shortcuts`
|
|
88
|
+
is a `CookbookShortcutsLoader`, below),
|
|
88
89
|
- `widgetContext` (host capabilities for browser-side widget loads),
|
|
89
90
|
- `resolveExport` (a static map of dynamic imports; turns a recipe export
|
|
90
91
|
reference into a component, used for `shell-widget` slot items and recipe
|
|
@@ -107,6 +108,19 @@ registry, recipe widgets and slot items are resolved in effects (a bundled
|
|
|
107
108
|
`resolveExport` is async), so a section page's overview appears after hydration,
|
|
108
109
|
not in the server HTML.
|
|
109
110
|
|
|
111
|
+
## Host shortcuts loader (#3888)
|
|
112
|
+
|
|
113
|
+
`CookbookApp loaders.shortcuts` is `(ctx, defaults: ShortcutEntry[]) =>
|
|
114
|
+
Promise<ShortcutEntry[]>` (`ShortcutEntry = { href, label, icon?, description?,
|
|
115
|
+
count? }`, exported from `./cookbook` and `./overview`).
|
|
116
|
+
`createCookbookRegistry` computes the default entries from the shell's resolved
|
|
117
|
+
sections, then, when the host supplies `shortcuts`, passes them through it
|
|
118
|
+
(`composeShortcutsLoader`); with no host loader the registry's loader is
|
|
119
|
+
unchanged. The host returns the entries to show (add `count`, reorder, add or
|
|
120
|
+
drop). If it throws, that load keeps the defaults (the page never empties
|
|
121
|
+
because a count query failed) unless the load itself was aborted. The shortcuts
|
|
122
|
+
widget renders `count` as "N records" (plural-aware i18n, tabular figures).
|
|
123
|
+
|
|
110
124
|
## `CookbookSectionPage`
|
|
111
125
|
|
|
112
126
|
A section's own page: title, icon and description (the user's renames win over
|
|
@@ -117,6 +131,16 @@ route: `s/[slug]/+page.svelte` renders
|
|
|
117
131
|
`<CookbookSectionPage slug={page.params.slug} />`. It must be inside
|
|
118
132
|
`CookbookApp`.
|
|
119
133
|
|
|
134
|
+
Props (also on `CookbookSectionOverview`, #3888): `presentation?: 'plain' | 'card'`
|
|
135
|
+
(default `'plain'`) is passed to `OverviewGrid`, so the default section body
|
|
136
|
+
lists shortcut entries as unframed rows on the panel surface (the shortcuts
|
|
137
|
+
widget receives the grid's `presentation` and drops its per-entry frame); `'card'`
|
|
138
|
+
keeps the framed look, and editing always keeps its frame.
|
|
139
|
+
`heading?: Snippet<[{ section: CookbookSectionHeadingInfo }]>` replaces the
|
|
140
|
+
default title block (`{ id, title, description?, icon }`) on the page; on a
|
|
141
|
+
standalone `CookbookSectionOverview` it renders above the grid and needs the
|
|
142
|
+
`section` prop.
|
|
143
|
+
|
|
120
144
|
## Using it in an app
|
|
121
145
|
|
|
122
146
|
```ts
|
|
@@ -198,16 +198,26 @@ shape. Data shapes are in `widgets/data.ts`.
|
|
|
198
198
|
| Type | Options | Data |
|
|
199
199
|
|---|---|---|
|
|
200
200
|
| `metric` | `title`, `model`*, `measure`, `field`, `filter` | `{ value, format?, currency?, label?, change?, href? }` (money = integer minor units) |
|
|
201
|
-
| `chart` | `title`, `model`*, `groupBy`, `measure`, `field`, `period`, `style` (bar/line), `filter` | `{ points: [{ label, value }], format?, currency?, href? }`, one measure of a runtime report |
|
|
201
|
+
| `chart` | `title`, `model`*, `groupBy`, `measure`, `field`, `period`, `style` (bar/line/table/pie/stat), `filter` | `{ points: [{ label, value }], format?, currency?, href?, delta? }`, one measure of a runtime report |
|
|
202
202
|
| `records` | `title`, `model`*, `sort`, `direction`, `limit`, `filter` | `{ rows: [{ id, title, subtitle?, meta?, href? }], total?, href? }`; the loader chooses the title field and the visible records |
|
|
203
|
-
| `shortcuts` | `title`, `section` | `{ items: [{ id, label, href, icon?, description? }] }
|
|
203
|
+
| `shortcuts` | `title`, `section` | `{ items: [{ id, label, href, icon?, description?, count? }] }` (`count` draws as "N records"; widgets also receive the grid's `presentation` and the shortcuts widget drops its entry frame under `plain`); `shortcutsFromNav(sections, sectionId)` maps `resolveShellNavModel` / `useShellLayout().sections` (visible entries, user renames) |
|
|
204
204
|
| `note` | `title`, `body` (Markdown) | none |
|
|
205
205
|
|
|
206
206
|
`note` renders `parseMarkdown` output as elements (headings, paragraphs, lists,
|
|
207
207
|
quotes, fenced code, bold/italic/code/links). There is no `{@html}`; raw HTML is
|
|
208
208
|
literal text and `safeHref` limits links to http(s), mailto, same-site paths and
|
|
209
209
|
fragments. Record and shortcut hrefs pass `safeHref` too. Charts carry their
|
|
210
|
-
numbers as text (inline for bars, a visually hidden table for the line
|
|
210
|
+
numbers as text (inline for bars, a visually hidden table for the line and the
|
|
211
|
+
donut, a visible table for `table`, the value itself for `stat`).
|
|
212
|
+
|
|
213
|
+
Chart styles (#3888, the renderer half of #3878's runtime-report chart hints):
|
|
214
|
+
`table` is a plain table of the series (tabular figures); `pie` is an SVG donut
|
|
215
|
+
with a legend (value and share) and a visually hidden data table, slices cycling
|
|
216
|
+
through the primary/secondary/tertiary/info tokens then their containers;
|
|
217
|
+
`stat` is the last point as a headline value with its change (`delta`, percent,
|
|
218
|
+
else derived from the last two points). Motion honours `prefers-reduced-motion`.
|
|
219
|
+
The chart option schema is **version 2**: v1 (`style` bar or line, or no version)
|
|
220
|
+
migrates by identity (`migrateChartOptions`), so saved overviews keep validating.
|
|
211
221
|
|
|
212
222
|
## Recipe widgets (`recipe-widgets.ts`)
|
|
213
223
|
|
package/agents/workspace.md
CHANGED
|
@@ -226,6 +226,52 @@ dialog and the global shortcut, so it mounts once. Planner-style hosts that
|
|
|
226
226
|
rendered their own `header.end` assistant toggle should pass `dockToggles`
|
|
227
227
|
(`dock:assistant`) and `user` instead.
|
|
228
228
|
|
|
229
|
+
Async sign-out (#3860): `onSignOut?: () => void | Promise<void>` (AppShell,
|
|
230
|
+
`WorkspaceAccountMenu`, `ShellSettingsPage`/`ShellSettingsPanel`) is awaited.
|
|
231
|
+
While pending the control is busy (`aria-busy`) and disabled, so a second
|
|
232
|
+
activation never fires the callback again; on success the account menu closes;
|
|
233
|
+
on rejection the menu (or Account section) stays as it was and shows an inline
|
|
234
|
+
`role="alert"` "Couldn't sign out. Try again." (`ui.shell_settings.sign_out_failed`).
|
|
235
|
+
A rejection is caught, never an unhandled rejection; the control is usable again
|
|
236
|
+
for a retry. `signOutHref` links are unchanged.
|
|
237
|
+
|
|
238
|
+
Unrendered regions in settings (#3860): `ShellState.regionsRendered:
|
|
239
|
+
Record<PanelEdge, boolean>` (read-only for consumers; `AdminShell` writes it
|
|
240
|
+
from the same `topRendered`/`bottomRendered`/`rightRendered`/`isEdgeShown('left')`
|
|
241
|
+
logic that collapses empty bands and edges, default all `true`) says whether a
|
|
242
|
+
region is actually on screen, distinct from the user's visibility choice. The
|
|
243
|
+
Layout rows in `ShellSettingsPanel` list a region when it is rendered, or when
|
|
244
|
+
the user hid it (so Show can always restore it); a shown region that is not
|
|
245
|
+
rendered (empty band, edge not presented at this width) has no row. The
|
|
246
|
+
"cannot hide the last region" guard still counts every shown region. In edit
|
|
247
|
+
mode every band renders, so every available region is listed.
|
|
248
|
+
|
|
249
|
+
`user` prop type (#3860): `AppShell`'s `user` is `ShellUser` (exported from
|
|
250
|
+
`./app`): `null` or `{ id: string | null | undefined; email?; name?; avatarUrl?
|
|
251
|
+
(string | null) }`, all readonly. The runtime's `SessionLayoutUser`
|
|
252
|
+
(`data.session.user`) and a full `User` both assign without a cast
|
|
253
|
+
(`__tests__/shell-user.test.ts` proves it with `expectTypeOf`). `id` stays
|
|
254
|
+
required but accepts `null`/`undefined` because an unsaved `User` carries
|
|
255
|
+
that. The shell reads `name`, `email` and `avatarUrl` for the account menu
|
|
256
|
+
(the avatar now shows) and forwards the same object to `Provider` untouched
|
|
257
|
+
(one internal cast; the Provider is typed for the full `User`), so nothing is
|
|
258
|
+
added or invented on the way.
|
|
259
|
+
|
|
260
|
+
DockToggle fallback (#3860): a `dockToggles` entry also takes `href?`, `ready?`
|
|
261
|
+
(reactive, default `true`), `labelNotReady?` and `onpress?(event, { registered,
|
|
262
|
+
ready }) => boolean | void`. Precedence on activation: (1) `onpress` runs first;
|
|
263
|
+
returning `false` or calling `event.preventDefault()` stops everything (no
|
|
264
|
+
toggle, no navigation). (2) If the tool is registered with `useShellDock()`
|
|
265
|
+
(and the dock is available) and `ready !== false`, the dock toggles as before.
|
|
266
|
+
(3) Otherwise `href` is followed, else nothing happens (the inert
|
|
267
|
+
`aria-disabled` button, unchanged). With an `href` in state 3 the toggle renders
|
|
268
|
+
as an `<a>` (middle-click and open-in-new-tab work) with no `aria-pressed` /
|
|
269
|
+
`aria-expanded`. Its name and tooltip are `labelNotReady`, else "Set up {label}"
|
|
270
|
+
(`ui.dock_toggles.set_up`), whenever it is not ready or links. The phone tab
|
|
271
|
+
bar's dock tab (the first toggle) follows the same resolution through the shared
|
|
272
|
+
`resolveDockToggle` / `runDockTogglePress` helpers in `dock-toggle.ts`; that tab
|
|
273
|
+
becomes a link entry. `PhoneBottomBarItem.onclick` now receives the click event.
|
|
274
|
+
|
|
229
275
|
`ShellLayout.placements?: Record<itemId, ShellSlot>` (additive, still version
|
|
230
276
|
1) overrides default slots. Pure helpers in `layout.ts` (also `./workspace/layout`):
|
|
231
277
|
`placeShellItem(layout, id, slot, defaultSlot?)` (passing the default drops a
|
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
resolvePhoneTabBar,
|
|
71
71
|
} from './phone-tabs.js';
|
|
72
72
|
import RuntimeDiagnosticsWebMcp from './RuntimeDiagnosticsWebMcp.svelte';
|
|
73
|
+
import type { ShellUser } from './shell-user.js';
|
|
73
74
|
import type {
|
|
74
75
|
AppShellAccountMenu,
|
|
75
76
|
AppShellCommandPalette,
|
|
@@ -112,8 +113,12 @@ interface Props {
|
|
|
112
113
|
* default slot (users can still move it in the layout editor).
|
|
113
114
|
*/
|
|
114
115
|
accountMenu?: AppShellAccountMenu;
|
|
115
|
-
/**
|
|
116
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Called when the account menu's Sign out is chosen (wins over
|
|
118
|
+
* `signOutHref`). May be async: the menu awaits it, shows a busy state, and
|
|
119
|
+
* on rejection stays open with an inline error.
|
|
120
|
+
*/
|
|
121
|
+
onSignOut?: () => unknown;
|
|
117
122
|
/**
|
|
118
123
|
* Where the account menu's Sign out link goes when there is no `onSignOut`.
|
|
119
124
|
* A link is a GET: never point it at the runtime's POST-only `/sign-out`
|
|
@@ -136,8 +141,12 @@ interface Props {
|
|
|
136
141
|
commandPalette?: AppShellCommandPalette;
|
|
137
142
|
/** Options for the Provider's WebMCP integration; passed through unchanged. */
|
|
138
143
|
webmcp?: boolean | WebMcpProviderConfig;
|
|
139
|
-
/**
|
|
140
|
-
|
|
144
|
+
/**
|
|
145
|
+
* The signed-in identity (`ShellUser`): the runtime's `SessionLayoutUser`
|
|
146
|
+
* (`data.session.user`) or a full `User` both fit without a cast. It is
|
|
147
|
+
* forwarded to the Provider unchanged; `null` renders the shell signed out.
|
|
148
|
+
*/
|
|
149
|
+
user?: ShellUser;
|
|
141
150
|
/** The user's resolved permission slugs, forwarded to the Provider for permission-gated UI. */
|
|
142
151
|
permissions?: string[];
|
|
143
152
|
/** Register the read-only runtime diagnostics WebMCP tool. */
|
|
@@ -571,11 +580,23 @@ function accountPlacement(
|
|
|
571
580
|
return alignStart ? 'bottom-start' : 'bottom-end';
|
|
572
581
|
}
|
|
573
582
|
const accountIdentity = $derived.by(() => {
|
|
574
|
-
const record = (user ?? {}) as {
|
|
583
|
+
const record = (user ?? {}) as {
|
|
584
|
+
name?: unknown;
|
|
585
|
+
email?: unknown;
|
|
586
|
+
avatarUrl?: unknown;
|
|
587
|
+
};
|
|
575
588
|
const name = typeof record.name === 'string' ? record.name.trim() : '';
|
|
576
589
|
const email = typeof record.email === 'string' ? record.email.trim() : '';
|
|
577
|
-
|
|
590
|
+
const avatarUrl =
|
|
591
|
+
typeof record.avatarUrl === 'string' && record.avatarUrl
|
|
592
|
+
? record.avatarUrl
|
|
593
|
+
: undefined;
|
|
594
|
+
return { name, email, avatarUrl };
|
|
578
595
|
});
|
|
596
|
+
// The Provider is typed for the full `User`. The shell hands it exactly the
|
|
597
|
+
// object the host passed (no fields added or invented), so a minimal session
|
|
598
|
+
// projection reaches it just as it did when the prop was typed as `User`.
|
|
599
|
+
const providerUser = $derived(user as unknown as User | null);
|
|
579
600
|
// The floating toggle sits over the header's end (header visible), the top of
|
|
580
601
|
// the right sidebar (header hidden) or the top of main (neither); reserve that room so it covers no
|
|
581
602
|
// control. AdminShell reads these custom properties.
|
|
@@ -867,6 +888,7 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
867
888
|
<WorkspaceAccountMenu
|
|
868
889
|
userName={accountIdentity.name || accountIdentity.email}
|
|
869
890
|
email={accountIdentity.email}
|
|
891
|
+
avatarUrl={accountIdentity.avatarUrl}
|
|
870
892
|
{compact}
|
|
871
893
|
{tenantLabel}
|
|
872
894
|
{onSignOut}
|
|
@@ -949,7 +971,7 @@ const EDGE_OF_REGION: Record<ShellRegion, PanelEdge> = {
|
|
|
949
971
|
/>
|
|
950
972
|
{/snippet}
|
|
951
973
|
|
|
952
|
-
<Provider {webmcp} {
|
|
974
|
+
<Provider {webmcp} user={providerUser} {permissions}>
|
|
953
975
|
<RuntimeDiagnosticsWebMcp enabled={runtimeDiagnostics} />
|
|
954
976
|
<ThemeProvider {preset} {colorScheme} persist={true}>
|
|
955
977
|
{#if !chrome}
|
|
@@ -4,13 +4,13 @@ import '@happyvertical/smrt-ui/themes/styles/base.css';
|
|
|
4
4
|
import '@happyvertical/smrt-ui/themes/styles/fonts.css';
|
|
5
5
|
import type { DataSurfaceRegistry } from '@happyvertical/smrt-ui/data';
|
|
6
6
|
import { type Component, type Snippet } from 'svelte';
|
|
7
|
-
import type { User } from '../../state/app-state.js';
|
|
8
7
|
import type { WebMcpProviderConfig } from '../../web/webmcp-provider.js';
|
|
9
8
|
import { type ShellLayout } from '../workspace/admin-shell/layout.js';
|
|
10
9
|
import { type ShellSlot } from '../workspace/admin-shell/slots.js';
|
|
11
10
|
import { type AdminShellProps, type ShellNavGroup, type ShellNavItem, type ShellPanelDefaults, type ShellSectionActionsContext } from '../workspace/admin-shell/types.js';
|
|
12
11
|
import type { DockToggle } from './dock-toggle.js';
|
|
13
12
|
import { type PhoneTabBarOptions } from './phone-tabs.js';
|
|
13
|
+
import type { ShellUser } from './shell-user.js';
|
|
14
14
|
import type { AppShellAccountMenu, AppShellCommandPalette, ShellSlotItem } from './slot-item.js';
|
|
15
15
|
interface Props {
|
|
16
16
|
/** Application name shown in the shell brand and app panel. */
|
|
@@ -47,8 +47,12 @@ interface Props {
|
|
|
47
47
|
* default slot (users can still move it in the layout editor).
|
|
48
48
|
*/
|
|
49
49
|
accountMenu?: AppShellAccountMenu;
|
|
50
|
-
/**
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Called when the account menu's Sign out is chosen (wins over
|
|
52
|
+
* `signOutHref`). May be async: the menu awaits it, shows a busy state, and
|
|
53
|
+
* on rejection stays open with an inline error.
|
|
54
|
+
*/
|
|
55
|
+
onSignOut?: () => unknown;
|
|
52
56
|
/**
|
|
53
57
|
* Where the account menu's Sign out link goes when there is no `onSignOut`.
|
|
54
58
|
* A link is a GET: never point it at the runtime's POST-only `/sign-out`
|
|
@@ -73,8 +77,12 @@ interface Props {
|
|
|
73
77
|
commandPalette?: AppShellCommandPalette;
|
|
74
78
|
/** Options for the Provider's WebMCP integration; passed through unchanged. */
|
|
75
79
|
webmcp?: boolean | WebMcpProviderConfig;
|
|
76
|
-
/**
|
|
77
|
-
|
|
80
|
+
/**
|
|
81
|
+
* The signed-in identity (`ShellUser`): the runtime's `SessionLayoutUser`
|
|
82
|
+
* (`data.session.user`) or a full `User` both fit without a cast. It is
|
|
83
|
+
* forwarded to the Provider unchanged; `null` renders the shell signed out.
|
|
84
|
+
*/
|
|
85
|
+
user?: ShellUser;
|
|
78
86
|
/** The user's resolved permission slugs, forwarded to the Provider for permission-gated UI. */
|
|
79
87
|
permissions?: string[];
|
|
80
88
|
/** Register the read-only runtime diagnostics WebMCP tool. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/AppShell.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,WAAW,EAEjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,8CAA8C,CAAC;AACtD,OAAO,+CAA+C,CAAC;AACvD,OAAO,gDAAgD,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO,EAAiB,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"AppShell.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/AppShell.svelte.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
3
|
+
import { M } from '../../i18n/strings.workspace.js';
|
|
2
4
|
import { useShellDock } from '../workspace/admin-shell/dock.js';
|
|
3
5
|
import {
|
|
4
6
|
isShellIconName,
|
|
5
7
|
SHELL_DEFAULT_TOOL_ICON,
|
|
6
8
|
SHELL_ICON_PATHS,
|
|
7
9
|
} from '../workspace/admin-shell/shell-icons.js';
|
|
8
|
-
import
|
|
10
|
+
import {
|
|
11
|
+
type DockToggle,
|
|
12
|
+
type DockToggleResolution,
|
|
13
|
+
resolveDockToggle,
|
|
14
|
+
runDockTogglePress,
|
|
15
|
+
} from './dock-toggle.js';
|
|
9
16
|
|
|
10
17
|
interface Props {
|
|
11
18
|
toggles: DockToggle[];
|
|
@@ -13,67 +20,101 @@ interface Props {
|
|
|
13
20
|
|
|
14
21
|
let { toggles }: Props = $props();
|
|
15
22
|
const dock = useShellDock();
|
|
23
|
+
const { t } = useI18n();
|
|
16
24
|
|
|
17
25
|
function iconFor(toggle: DockToggle): string | undefined {
|
|
18
26
|
return toggle.icon ?? (toggle.tool === 'assistant' ? 'chat' : undefined);
|
|
19
27
|
}
|
|
20
28
|
|
|
29
|
+
function resolve(toggle: DockToggle): DockToggleResolution {
|
|
30
|
+
return resolveDockToggle(toggle, dock.has(toggle.tool) && dock.available);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function nameFor(toggle: DockToggle, notReady: boolean): string {
|
|
34
|
+
if (!notReady) return toggle.label;
|
|
35
|
+
return (
|
|
36
|
+
toggle.labelNotReady ??
|
|
37
|
+
t(M['ui.dock_toggles.set_up'], { label: toggle.label })
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
21
41
|
function press(event: MouseEvent, toggle: DockToggle): void {
|
|
22
|
-
|
|
42
|
+
const resolution = resolve(toggle);
|
|
43
|
+
if (!runDockTogglePress(toggle, event, resolution)) return;
|
|
44
|
+
if (resolution.mode !== 'toggle') return;
|
|
23
45
|
dock.toggle(toggle.tool, {
|
|
24
46
|
returnFocus: event.currentTarget as HTMLElement,
|
|
25
47
|
});
|
|
26
48
|
}
|
|
27
49
|
</script>
|
|
28
50
|
|
|
51
|
+
{#snippet glyph(icon: string | undefined)}
|
|
52
|
+
{#if icon === 'chat'}
|
|
53
|
+
<svg
|
|
54
|
+
viewBox="0 0 24 24"
|
|
55
|
+
width="20"
|
|
56
|
+
height="20"
|
|
57
|
+
fill="none"
|
|
58
|
+
stroke="currentColor"
|
|
59
|
+
stroke-width="2"
|
|
60
|
+
stroke-linecap="round"
|
|
61
|
+
stroke-linejoin="round"
|
|
62
|
+
aria-hidden="true"
|
|
63
|
+
>
|
|
64
|
+
<path d="M21 11.5a8.5 8.5 0 0 1-12.4 7.5L3 20.5l1.6-5A8.5 8.5 0 1 1 21 11.5z" />
|
|
65
|
+
</svg>
|
|
66
|
+
{:else if icon === undefined || isShellIconName(icon)}
|
|
67
|
+
<svg
|
|
68
|
+
viewBox="0 0 24 24"
|
|
69
|
+
width="20"
|
|
70
|
+
height="20"
|
|
71
|
+
fill="currentColor"
|
|
72
|
+
aria-hidden="true"
|
|
73
|
+
focusable="false"
|
|
74
|
+
>
|
|
75
|
+
<path d={SHELL_ICON_PATHS[icon === undefined ? SHELL_DEFAULT_TOOL_ICON : icon]} />
|
|
76
|
+
</svg>
|
|
77
|
+
{:else}
|
|
78
|
+
<span aria-hidden="true">{icon}</span>
|
|
79
|
+
{/if}
|
|
80
|
+
{/snippet}
|
|
81
|
+
|
|
29
82
|
<div class="smrt-dock-toggles" data-testid="dock-toggles">
|
|
30
83
|
{#each toggles as toggle (toggle.tool)}
|
|
31
|
-
{@const
|
|
32
|
-
{@const
|
|
84
|
+
{@const resolution = resolve(toggle)}
|
|
85
|
+
{@const registered = resolution.mode === 'toggle'}
|
|
86
|
+
{@const open = registered && dock.isOpen(toggle.tool)}
|
|
33
87
|
{@const icon = iconFor(toggle)}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
viewBox="0 0 24 24"
|
|
65
|
-
width="20"
|
|
66
|
-
height="20"
|
|
67
|
-
fill="currentColor"
|
|
68
|
-
aria-hidden="true"
|
|
69
|
-
focusable="false"
|
|
70
|
-
>
|
|
71
|
-
<path d={SHELL_ICON_PATHS[icon === undefined ? SHELL_DEFAULT_TOOL_ICON : icon]} />
|
|
72
|
-
</svg>
|
|
73
|
-
{:else}
|
|
74
|
-
<span aria-hidden="true">{icon}</span>
|
|
75
|
-
{/if}
|
|
76
|
-
</button>
|
|
88
|
+
{@const name = nameFor(toggle, resolution.notReady)}
|
|
89
|
+
{#if resolution.mode === 'link'}
|
|
90
|
+
<a
|
|
91
|
+
class="smrt-dock-toggles__button"
|
|
92
|
+
href={toggle.href}
|
|
93
|
+
data-dock-tool={toggle.tool}
|
|
94
|
+
aria-label={name}
|
|
95
|
+
title={name}
|
|
96
|
+
onclick={(event) => press(event, toggle)}
|
|
97
|
+
>
|
|
98
|
+
{@render glyph(icon)}
|
|
99
|
+
</a>
|
|
100
|
+
{:else}
|
|
101
|
+
<!-- raw-primitive-allow: shell chrome toggle, not a content button -->
|
|
102
|
+
<button
|
|
103
|
+
type="button"
|
|
104
|
+
class="smrt-dock-toggles__button"
|
|
105
|
+
class:active={open}
|
|
106
|
+
data-dock-tool={toggle.tool}
|
|
107
|
+
aria-label={name}
|
|
108
|
+
title={name}
|
|
109
|
+
aria-pressed={open}
|
|
110
|
+
aria-expanded={open}
|
|
111
|
+
aria-controls="smrt-admin-shell-right-panel"
|
|
112
|
+
aria-disabled={registered ? undefined : true}
|
|
113
|
+
onclick={(event) => press(event, toggle)}
|
|
114
|
+
>
|
|
115
|
+
{@render glyph(icon)}
|
|
116
|
+
</button>
|
|
117
|
+
{/if}
|
|
77
118
|
{/each}
|
|
78
119
|
</div>
|
|
79
120
|
|
|
@@ -88,6 +129,7 @@ function press(event: MouseEvent, toggle: DockToggle): void {
|
|
|
88
129
|
|
|
89
130
|
.smrt-dock-toggles__button {
|
|
90
131
|
display: inline-grid;
|
|
132
|
+
text-decoration: none;
|
|
91
133
|
place-items: center;
|
|
92
134
|
position: relative;
|
|
93
135
|
inline-size: var(--smrt-control-height-small);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DockToggles.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/DockToggles.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DockToggles.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/DockToggles.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,KAAK,UAAU,EAIhB,MAAM,kBAAkB,CAAC;AAG1B,UAAU,KAAK;IACb,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AA6ED,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -18,7 +18,11 @@ import {
|
|
|
18
18
|
SHELL_PLACEHOLDER_ICON,
|
|
19
19
|
} from '../workspace/admin-shell/shell-icons.js';
|
|
20
20
|
import type { PhoneBottomBarEntry } from '../workspace/admin-shell/types.js';
|
|
21
|
-
import
|
|
21
|
+
import {
|
|
22
|
+
type DockToggle,
|
|
23
|
+
resolveDockToggle,
|
|
24
|
+
runDockTogglePress,
|
|
25
|
+
} from './dock-toggle.js';
|
|
22
26
|
import {
|
|
23
27
|
isTabCurrent,
|
|
24
28
|
type PhoneTabNavEntry,
|
|
@@ -93,17 +97,38 @@ const items = $derived.by(() => {
|
|
|
93
97
|
}));
|
|
94
98
|
if (dockToggle) {
|
|
95
99
|
const tool = dockToggle.tool;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
const resolution = resolveDockToggle(
|
|
101
|
+
dockToggle,
|
|
102
|
+
dock.has(tool) && dock.available,
|
|
103
|
+
);
|
|
104
|
+
const toggling = resolution.mode === 'toggle';
|
|
105
|
+
const label = resolution.notReady
|
|
106
|
+
? (dockToggle.labelNotReady ??
|
|
107
|
+
t(M['ui.dock_toggles.set_up'], { label: dockToggle.label }))
|
|
108
|
+
: dockToggle.label;
|
|
109
|
+
const press = (event: MouseEvent) => {
|
|
110
|
+
if (!runDockTogglePress(dockToggle, event, resolution)) return;
|
|
111
|
+
if (toggling) dock.toggle(tool);
|
|
112
|
+
};
|
|
113
|
+
out.push(
|
|
114
|
+
resolution.mode === 'link'
|
|
115
|
+
? {
|
|
116
|
+
id: `dock:${tool}`,
|
|
117
|
+
label,
|
|
118
|
+
iconName: dockIcon(dockToggle),
|
|
119
|
+
href: dockToggle.href,
|
|
120
|
+
onclick: press,
|
|
121
|
+
}
|
|
122
|
+
: {
|
|
123
|
+
id: `dock:${tool}`,
|
|
124
|
+
label,
|
|
125
|
+
iconName: dockIcon(dockToggle),
|
|
126
|
+
active: toggling && dock.isOpen(tool),
|
|
127
|
+
expanded: toggling ? dock.isOpen(tool) : undefined,
|
|
128
|
+
controls: toggling ? 'smrt-admin-shell-right-panel' : undefined,
|
|
129
|
+
onclick: press,
|
|
130
|
+
},
|
|
131
|
+
);
|
|
107
132
|
} else if (toolsTab) {
|
|
108
133
|
out.push({
|
|
109
134
|
id: 'tools',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Component } from 'svelte';
|
|
2
|
-
import type
|
|
2
|
+
import { type DockToggle } from './dock-toggle.js';
|
|
3
3
|
import { type PhoneTabNavEntry } from './phone-tabs.js';
|
|
4
4
|
interface Props {
|
|
5
5
|
/** Navigation destinations in order (see `phoneTabNavEntries`). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhoneTabBar.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/PhoneTabBar.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAWxC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"PhoneTabBar.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/PhoneTabBar.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAWxC,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AAGzB,UAAU,KAAK;IACb,mEAAmE;IACnE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,yGAAyG;IACzG,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,SAAS,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5D;AAmID,QAAA,MAAM,WAAW,0BAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -10,8 +10,8 @@ interface Props {
|
|
|
10
10
|
* `onSignOut` for that.
|
|
11
11
|
*/
|
|
12
12
|
signOutHref?: string;
|
|
13
|
-
/** Called by the sign-out control instead of following `signOutHref
|
|
14
|
-
onSignOut?: () =>
|
|
13
|
+
/** Called by the sign-out control instead of following `signOutHref`; may be async (busy while pending, inline error on rejection). */
|
|
14
|
+
onSignOut?: () => unknown;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const { signOutHref, onSignOut }: Props = $props();
|
|
@@ -5,8 +5,8 @@ interface Props {
|
|
|
5
5
|
* `onSignOut` for that.
|
|
6
6
|
*/
|
|
7
7
|
signOutHref?: string;
|
|
8
|
-
/** Called by the sign-out control instead of following `signOutHref
|
|
9
|
-
onSignOut?: () =>
|
|
8
|
+
/** Called by the sign-out control instead of following `signOutHref`; may be async (busy while pending, inline error on rejection). */
|
|
9
|
+
onSignOut?: () => unknown;
|
|
10
10
|
}
|
|
11
11
|
declare const ShellSettingsPage: import("svelte").Component<Props, {}, "">;
|
|
12
12
|
type ShellSettingsPage = ReturnType<typeof ShellSettingsPage>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShellSettingsPage.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/ShellSettingsPage.svelte.ts"],"names":[],"mappings":"AAQA,UAAU,KAAK;IACb;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,
|
|
1
|
+
{"version":3,"file":"ShellSettingsPage.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/app/ShellSettingsPage.svelte.ts"],"names":[],"mappings":"AAQA,UAAU,KAAK;IACb;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uIAAuI;IACvI,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;CAC3B;AAuBD,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
|
|
@@ -17,5 +17,50 @@ export interface DockToggle {
|
|
|
17
17
|
* region is hidden the shell moves it along the slot fallback chain.
|
|
18
18
|
*/
|
|
19
19
|
slot?: ShellSlot;
|
|
20
|
+
/**
|
|
21
|
+
* Where to go when the toggle cannot toggle the dock: the tool is not
|
|
22
|
+
* registered with `useShellDock()`, or `ready` is `false`. The button then
|
|
23
|
+
* renders as a link (so middle-click and open-in-new-tab work) and drops
|
|
24
|
+
* `aria-pressed` / `aria-expanded`. Without it that state stays inert.
|
|
25
|
+
*/
|
|
26
|
+
href?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Whether the tool is usable right now (default `true`). Reactive: a host
|
|
29
|
+
* passes e.g. `aiState.assistantReady`. While `false` the toggle behaves as
|
|
30
|
+
* the unregistered state: `href` if given, else inert.
|
|
31
|
+
*/
|
|
32
|
+
ready?: boolean;
|
|
33
|
+
/** Accessible name and tooltip in the not-ready state. Default "Set up {label}". */
|
|
34
|
+
labelNotReady?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Called first on activation with the click event and the resolved state.
|
|
37
|
+
* Returning `false`, or calling `event.preventDefault()`, stops everything
|
|
38
|
+
* else (no dock toggle, no navigation).
|
|
39
|
+
*/
|
|
40
|
+
onpress?: (event: MouseEvent, state: {
|
|
41
|
+
registered: boolean;
|
|
42
|
+
ready: boolean;
|
|
43
|
+
}) => boolean | void;
|
|
44
|
+
}
|
|
45
|
+
/** What activating a `DockToggle` does, from the live dock and `ready`. */
|
|
46
|
+
export type DockToggleMode = 'toggle' | 'link' | 'inert';
|
|
47
|
+
export interface DockToggleResolution {
|
|
48
|
+
mode: DockToggleMode;
|
|
49
|
+
registered: boolean;
|
|
50
|
+
ready: boolean;
|
|
51
|
+
/** True in the not-ready state (unregistered with an `href`, or `ready === false`). */
|
|
52
|
+
notReady: boolean;
|
|
20
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Precedence: `onpress` runs first and can cancel. Then, when the tool is
|
|
56
|
+
* registered and `ready !== false`, the dock toggles. Otherwise `href` is
|
|
57
|
+
* followed when given, else nothing happens.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolveDockToggle(toggle: DockToggle, registered: boolean): DockToggleResolution;
|
|
60
|
+
/**
|
|
61
|
+
* Run `onpress` for a click. Returns `true` when the rest of the press (dock
|
|
62
|
+
* toggle or navigation) should go ahead. Stopping also calls
|
|
63
|
+
* `event.preventDefault()` so a link does not navigate.
|
|
64
|
+
*/
|
|
65
|
+
export declare function runDockTogglePress(toggle: DockToggle, event: MouseEvent, resolution: DockToggleResolution): boolean;
|
|
21
66
|
//# sourceMappingURL=dock-toggle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dock-toggle.d.ts","sourceRoot":"","sources":["../../../src/components/app/dock-toggle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"dock-toggle.d.ts","sourceRoot":"","sources":["../../../src/components/app/dock-toggle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAEnE,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,KAC3C,OAAO,GAAG,IAAI,CAAC;CACrB;AAED,2EAA2E;AAC3E,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,uFAAuF;IACvF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,OAAO,GAClB,oBAAoB,CAKtB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAUT"}
|