@awesome-markdown/board-ui 0.0.0-stage → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -2
- package/dist/board/Board.d.ts +24 -0
- package/dist/board/Board.d.ts.map +1 -0
- package/dist/board/Board.js +179 -0
- package/dist/board/Board.js.map +1 -0
- package/dist/board/Cell.d.ts +23 -0
- package/dist/board/Cell.d.ts.map +1 -0
- package/dist/board/Cell.js +150 -0
- package/dist/board/Cell.js.map +1 -0
- package/dist/board/ColumnHeader.d.ts +18 -0
- package/dist/board/ColumnHeader.d.ts.map +1 -0
- package/dist/board/ColumnHeader.js +31 -0
- package/dist/board/ColumnHeader.js.map +1 -0
- package/dist/board/HomelessItemCard.d.ts +15 -0
- package/dist/board/HomelessItemCard.d.ts.map +1 -0
- package/dist/board/HomelessItemCard.js +37 -0
- package/dist/board/HomelessItemCard.js.map +1 -0
- package/dist/board/HomelessPanel.d.ts +17 -0
- package/dist/board/HomelessPanel.d.ts.map +1 -0
- package/dist/board/HomelessPanel.js +26 -0
- package/dist/board/HomelessPanel.js.map +1 -0
- package/dist/board/ItemCard.d.ts +21 -0
- package/dist/board/ItemCard.d.ts.map +1 -0
- package/dist/board/ItemCard.js +97 -0
- package/dist/board/ItemCard.js.map +1 -0
- package/dist/board/SwimlaneRow.d.ts +23 -0
- package/dist/board/SwimlaneRow.d.ts.map +1 -0
- package/dist/board/SwimlaneRow.js +30 -0
- package/dist/board/SwimlaneRow.js.map +1 -0
- package/dist/board/dnd/boardDnd.d.ts +15 -0
- package/dist/board/dnd/boardDnd.d.ts.map +1 -0
- package/dist/board/dnd/boardDnd.js +69 -0
- package/dist/board/dnd/boardDnd.js.map +1 -0
- package/dist/board/dnd/dragTypes.d.ts +24 -0
- package/dist/board/dnd/dragTypes.d.ts.map +1 -0
- package/dist/board/dnd/dragTypes.js +22 -0
- package/dist/board/dnd/dragTypes.js.map +1 -0
- package/dist/board/dnd/mutateDragDrop.d.ts +35 -0
- package/dist/board/dnd/mutateDragDrop.d.ts.map +1 -0
- package/dist/board/dnd/mutateDragDrop.js +97 -0
- package/dist/board/dnd/mutateDragDrop.js.map +1 -0
- package/dist/board/dnd/onDragEnd.d.ts +24 -0
- package/dist/board/dnd/onDragEnd.d.ts.map +1 -0
- package/dist/board/dnd/onDragEnd.js +47 -0
- package/dist/board/dnd/onDragEnd.js.map +1 -0
- package/dist/board/layout/AxisBehavior.d.ts +36 -0
- package/dist/board/layout/AxisBehavior.d.ts.map +1 -0
- package/dist/board/layout/AxisBehavior.js +86 -0
- package/dist/board/layout/AxisBehavior.js.map +1 -0
- package/dist/board/layout/AxisDrawer.d.ts +17 -0
- package/dist/board/layout/AxisDrawer.d.ts.map +1 -0
- package/dist/board/layout/AxisDrawer.js +40 -0
- package/dist/board/layout/AxisDrawer.js.map +1 -0
- package/dist/board/layout/BoardDrawer.d.ts +11 -0
- package/dist/board/layout/BoardDrawer.d.ts.map +1 -0
- package/dist/board/layout/BoardDrawer.js +27 -0
- package/dist/board/layout/BoardDrawer.js.map +1 -0
- package/dist/board/layout/Drawer.d.ts +19 -0
- package/dist/board/layout/Drawer.d.ts.map +1 -0
- package/dist/board/layout/Drawer.js +18 -0
- package/dist/board/layout/Drawer.js.map +1 -0
- package/dist/board/layout/FilterEditor.d.ts +12 -0
- package/dist/board/layout/FilterEditor.d.ts.map +1 -0
- package/dist/board/layout/FilterEditor.js +11 -0
- package/dist/board/layout/FilterEditor.js.map +1 -0
- package/dist/board/layout/InlineControls.d.ts +22 -0
- package/dist/board/layout/InlineControls.d.ts.map +1 -0
- package/dist/board/layout/InlineControls.js +39 -0
- package/dist/board/layout/InlineControls.js.map +1 -0
- package/dist/board/layout/SortableAxis.d.ts +28 -0
- package/dist/board/layout/SortableAxis.d.ts.map +1 -0
- package/dist/board/layout/SortableAxis.js +39 -0
- package/dist/board/layout/SortableAxis.js.map +1 -0
- package/dist/board/layout/axis-defaults.d.ts +22 -0
- package/dist/board/layout/axis-defaults.d.ts.map +1 -0
- package/dist/board/layout/axis-defaults.js +37 -0
- package/dist/board/layout/axis-defaults.js.map +1 -0
- package/dist/board/layout/filter-draft.d.ts +21 -0
- package/dist/board/layout/filter-draft.d.ts.map +1 -0
- package/dist/board/layout/filter-draft.js +112 -0
- package/dist/board/layout/filter-draft.js.map +1 -0
- package/dist/board/layout/useBoardLayout.d.ts +27 -0
- package/dist/board/layout/useBoardLayout.d.ts.map +1 -0
- package/dist/board/layout/useBoardLayout.js +92 -0
- package/dist/board/layout/useBoardLayout.js.map +1 -0
- package/dist/breadcrumb.d.ts +22 -0
- package/dist/breadcrumb.d.ts.map +1 -0
- package/dist/breadcrumb.js +15 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/components/ConflictBanner.d.ts +12 -0
- package/dist/components/ConflictBanner.d.ts.map +1 -0
- package/dist/components/ConflictBanner.js +47 -0
- package/dist/components/ConflictBanner.js.map +1 -0
- package/dist/components/ConflictDiff.d.ts +13 -0
- package/dist/components/ConflictDiff.d.ts.map +1 -0
- package/dist/components/ConflictDiff.js +97 -0
- package/dist/components/ConflictDiff.js.map +1 -0
- package/dist/components/ConflictPanel.d.ts +16 -0
- package/dist/components/ConflictPanel.d.ts.map +1 -0
- package/dist/components/ConflictPanel.js +53 -0
- package/dist/components/ConflictPanel.js.map +1 -0
- package/dist/components/ItemRecovery.d.ts +9 -0
- package/dist/components/ItemRecovery.d.ts.map +1 -0
- package/dist/components/ItemRecovery.js +48 -0
- package/dist/components/ItemRecovery.js.map +1 -0
- package/dist/components/PropertyTree.d.ts +18 -0
- package/dist/components/PropertyTree.d.ts.map +1 -0
- package/dist/components/PropertyTree.js +109 -0
- package/dist/components/PropertyTree.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/derive-summary.d.ts +9 -0
- package/dist/lib/derive-summary.d.ts.map +1 -0
- package/dist/lib/derive-summary.js +27 -0
- package/dist/lib/derive-summary.js.map +1 -0
- package/dist/lib/item-board.d.ts +2 -0
- package/dist/lib/item-board.d.ts.map +1 -0
- package/dist/lib/item-board.js +7 -0
- package/dist/lib/item-board.js.map +1 -0
- package/dist/lib/patch-visible-item.d.ts +4 -0
- package/dist/lib/patch-visible-item.d.ts.map +1 -0
- package/dist/lib/patch-visible-item.js +10 -0
- package/dist/lib/patch-visible-item.js.map +1 -0
- package/dist/lib/property-display.d.ts +17 -0
- package/dist/lib/property-display.d.ts.map +1 -0
- package/dist/lib/property-display.js +86 -0
- package/dist/lib/property-display.js.map +1 -0
- package/dist/lib/property-tree.d.ts +23 -0
- package/dist/lib/property-tree.d.ts.map +1 -0
- package/dist/lib/property-tree.js +109 -0
- package/dist/lib/property-tree.js.map +1 -0
- package/dist/pages/BoardListPage.d.ts +9 -0
- package/dist/pages/BoardListPage.d.ts.map +1 -0
- package/dist/pages/BoardListPage.js +113 -0
- package/dist/pages/BoardListPage.js.map +1 -0
- package/dist/pages/BoardPage.d.ts +7 -0
- package/dist/pages/BoardPage.d.ts.map +1 -0
- package/dist/pages/BoardPage.js +37 -0
- package/dist/pages/BoardPage.js.map +1 -0
- package/dist/pages/ItemEditorPage.d.ts +3 -0
- package/dist/pages/ItemEditorPage.d.ts.map +1 -0
- package/dist/pages/ItemEditorPage.js +236 -0
- package/dist/pages/ItemEditorPage.js.map +1 -0
- package/dist/provider/ProviderContext.d.ts +17 -0
- package/dist/provider/ProviderContext.d.ts.map +1 -0
- package/dist/provider/ProviderContext.js +21 -0
- package/dist/provider/ProviderContext.js.map +1 -0
- package/dist/router/RouterAdapter.d.ts +43 -0
- package/dist/router/RouterAdapter.d.ts.map +1 -0
- package/dist/router/RouterAdapter.js +21 -0
- package/dist/router/RouterAdapter.js.map +1 -0
- package/dist/shell/SyncStatusDot.d.ts +8 -0
- package/dist/shell/SyncStatusDot.d.ts.map +1 -0
- package/dist/shell/SyncStatusDot.js +58 -0
- package/dist/shell/SyncStatusDot.js.map +1 -0
- package/dist/shell/ThemeToggle.d.ts +8 -0
- package/dist/shell/ThemeToggle.d.ts.map +1 -0
- package/dist/shell/ThemeToggle.js +21 -0
- package/dist/shell/ThemeToggle.js.map +1 -0
- package/dist/state/theme-store.d.ts +17 -0
- package/dist/state/theme-store.d.ts.map +1 -0
- package/dist/state/theme-store.js +58 -0
- package/dist/state/theme-store.js.map +1 -0
- package/dist/state/useBoardRender.d.ts +16 -0
- package/dist/state/useBoardRender.d.ts.map +1 -0
- package/dist/state/useBoardRender.js +53 -0
- package/dist/state/useBoardRender.js.map +1 -0
- package/dist/state/useProviderSubscribe.d.ts +22 -0
- package/dist/state/useProviderSubscribe.d.ts.map +1 -0
- package/dist/state/useProviderSubscribe.js +48 -0
- package/dist/state/useProviderSubscribe.js.map +1 -0
- package/dist/sync/conflict-api.d.ts +16 -0
- package/dist/sync/conflict-api.d.ts.map +1 -0
- package/dist/sync/conflict-api.js +35 -0
- package/dist/sync/conflict-api.js.map +1 -0
- package/dist/sync/conflict-store.d.ts +44 -0
- package/dist/sync/conflict-store.d.ts.map +1 -0
- package/dist/sync/conflict-store.js +159 -0
- package/dist/sync/conflict-store.js.map +1 -0
- package/fonts/InterTight-Medium.woff2 +0 -0
- package/fonts/InterTight-Regular.woff2 +0 -0
- package/fonts/JetBrainsMono-Medium.woff2 +0 -0
- package/fonts/JetBrainsMono-Regular.woff2 +0 -0
- package/fonts/LICENSE +14 -0
- package/package.json +59 -3
- package/styles.css +852 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PersistenceProvider } from '@awesome-markdown/contracts';
|
|
3
|
+
interface ProviderContextProviderProps {
|
|
4
|
+
provider: PersistenceProvider;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Injects a PersistenceProvider instance into the React tree.
|
|
9
|
+
* Wrap your root component with this to enable useProvider().
|
|
10
|
+
*/
|
|
11
|
+
export declare function ProviderContextProvider({ provider, children, }: ProviderContextProviderProps): React.ReactElement;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the bound PersistenceProvider. Throws if used outside ProviderContextProvider.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useProvider(): PersistenceProvider;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=ProviderContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderContext.d.ts","sourceRoot":"","sources":["../../src/provider/ProviderContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAIvE,UAAU,4BAA4B;IACpC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,QAAQ,GACT,EAAE,4BAA4B,GAAG,KAAK,CAAC,YAAY,CAMnD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,mBAAmB,CAMjD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { createContext, useContext } from 'react';
|
|
3
|
+
const ProviderContext = createContext(null);
|
|
4
|
+
/**
|
|
5
|
+
* Injects a PersistenceProvider instance into the React tree.
|
|
6
|
+
* Wrap your root component with this to enable useProvider().
|
|
7
|
+
*/
|
|
8
|
+
export function ProviderContextProvider({ provider, children, }) {
|
|
9
|
+
return (_jsx(ProviderContext.Provider, { value: provider, children: children }));
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Returns the bound PersistenceProvider. Throws if used outside ProviderContextProvider.
|
|
13
|
+
*/
|
|
14
|
+
export function useProvider() {
|
|
15
|
+
const ctx = useContext(ProviderContext);
|
|
16
|
+
if (ctx === null) {
|
|
17
|
+
throw new Error('useProvider must be used inside a ProviderContextProvider');
|
|
18
|
+
}
|
|
19
|
+
return ctx;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ProviderContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderContext.js","sourceRoot":"","sources":["../../src/provider/ProviderContext.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGzD,MAAM,eAAe,GAAG,aAAa,CAA6B,IAAI,CAAC,CAAC;AAOxE;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,EACtC,QAAQ,EACR,QAAQ,GACqB;IAC7B,OAAO,CACL,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,QAAQ,YACtC,QAAQ,GACgB,CAC5B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,GAAG,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IACxC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Router-agnostic navigation seam for board-ui.
|
|
4
|
+
*
|
|
5
|
+
* board-ui never imports a router. Every path it produces is *board-relative*
|
|
6
|
+
* (`/`, `/boards/:slug`, `/items/:slug?board=…`); the host app maps those onto
|
|
7
|
+
* its own URL space (e.g. prefixing `/w/:workspace`) inside its adapter.
|
|
8
|
+
*/
|
|
9
|
+
/** Props board-ui passes to `RouterAdapter.Link`. */
|
|
10
|
+
export interface RouterLinkProps {
|
|
11
|
+
/** Board-relative target path, e.g. `/boards/board-all`. */
|
|
12
|
+
to: string;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
className?: string;
|
|
15
|
+
style?: React.CSSProperties;
|
|
16
|
+
title?: string;
|
|
17
|
+
'aria-label'?: string;
|
|
18
|
+
'data-testid'?: string;
|
|
19
|
+
onMouseEnter?: React.MouseEventHandler<HTMLAnchorElement>;
|
|
20
|
+
onMouseLeave?: React.MouseEventHandler<HTMLAnchorElement>;
|
|
21
|
+
}
|
|
22
|
+
export interface RouterAdapter {
|
|
23
|
+
/** Renders an in-app link to a board-relative path. */
|
|
24
|
+
Link: React.ComponentType<RouterLinkProps>;
|
|
25
|
+
/** Navigates to a board-relative path (may include a `?query`). */
|
|
26
|
+
navigate: (to: string) => void;
|
|
27
|
+
/** Hook: path params of the current route (`slug` for board/item pages). */
|
|
28
|
+
useParams: () => Record<string, string | undefined>;
|
|
29
|
+
/** Hook: query-string params of the current location. */
|
|
30
|
+
useSearchParams: () => URLSearchParams;
|
|
31
|
+
}
|
|
32
|
+
interface RouterAdapterProviderProps {
|
|
33
|
+
adapter: RouterAdapter;
|
|
34
|
+
children: React.ReactNode;
|
|
35
|
+
}
|
|
36
|
+
/** Injects the host app's router adapter. Required above any board-ui page. */
|
|
37
|
+
export declare function RouterAdapterProvider({ adapter, children, }: RouterAdapterProviderProps): React.ReactElement;
|
|
38
|
+
/** Returns the bound router adapter. Throws outside `RouterAdapterProvider`. */
|
|
39
|
+
export declare function useRouterAdapter(): RouterAdapter;
|
|
40
|
+
/** Convenience link component that delegates to the adapter's `Link`. */
|
|
41
|
+
export declare function RouterLink(props: RouterLinkProps): React.ReactElement;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=RouterAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouterAdapter.d.ts","sourceRoot":"","sources":["../../src/router/RouterAdapter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAEzD;;;;;;GAMG;AAEH,qDAAqD;AACrD,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAC1D,YAAY,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IAC3C,mEAAmE;IACnE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,4EAA4E;IAC5E,SAAS,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACpD,yDAAyD;IACzD,eAAe,EAAE,MAAM,eAAe,CAAC;CACxC;AAID,UAAU,0BAA0B;IAClC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,QAAQ,GACT,EAAE,0BAA0B,GAAG,KAAK,CAAC,YAAY,CAIjD;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,IAAI,aAAa,CAMhD;AAED,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CAGrE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { createContext, useContext } from 'react';
|
|
3
|
+
const RouterAdapterContext = createContext(null);
|
|
4
|
+
/** Injects the host app's router adapter. Required above any board-ui page. */
|
|
5
|
+
export function RouterAdapterProvider({ adapter, children, }) {
|
|
6
|
+
return (_jsx(RouterAdapterContext.Provider, { value: adapter, children: children }));
|
|
7
|
+
}
|
|
8
|
+
/** Returns the bound router adapter. Throws outside `RouterAdapterProvider`. */
|
|
9
|
+
export function useRouterAdapter() {
|
|
10
|
+
const ctx = useContext(RouterAdapterContext);
|
|
11
|
+
if (ctx === null) {
|
|
12
|
+
throw new Error('useRouterAdapter must be used inside a RouterAdapterProvider');
|
|
13
|
+
}
|
|
14
|
+
return ctx;
|
|
15
|
+
}
|
|
16
|
+
/** Convenience link component that delegates to the adapter's `Link`. */
|
|
17
|
+
export function RouterLink(props) {
|
|
18
|
+
const { Link } = useRouterAdapter();
|
|
19
|
+
return _jsx(Link, { ...props });
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=RouterAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouterAdapter.js","sourceRoot":"","sources":["../../src/router/RouterAdapter.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAmCzD,MAAM,oBAAoB,GAAG,aAAa,CAAuB,IAAI,CAAC,CAAC;AAOvE,+EAA+E;AAC/E,MAAM,UAAU,qBAAqB,CAAC,EACpC,OAAO,EACP,QAAQ,GACmB;IAC3B,OAAO,CACL,KAAC,oBAAoB,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAAG,QAAQ,GAAiC,CAC1F,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAC7C,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,IAAI,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACpC,OAAO,KAAC,IAAI,OAAK,KAAK,GAAI,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* 6 px sync-status circle.
|
|
4
|
+
* No chromatic colors — grayscale tokens only per design spec.
|
|
5
|
+
* pulling state: pulsing animation.
|
|
6
|
+
*/
|
|
7
|
+
export declare function SyncStatusDot(): React.ReactElement;
|
|
8
|
+
//# sourceMappingURL=SyncStatusDot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyncStatusDot.d.ts","sourceRoot":"","sources":["../../src/shell/SyncStatusDot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AA6BnD;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,KAAK,CAAC,YAAY,CAuClD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState, useEffect } from 'react';
|
|
3
|
+
import { useProvider } from '../provider/ProviderContext.js';
|
|
4
|
+
import { isHttpProvider } from '@awesome-markdown/provider-http';
|
|
5
|
+
/**
|
|
6
|
+
* Maps HTTP connection state to the three sync visual states:
|
|
7
|
+
* - clean (idle/online) → static --ink-muted dot
|
|
8
|
+
* - pulling (connecting/reconnecting) → pulsing --ink dot
|
|
9
|
+
* - dirty (offline) → solid --ink dot
|
|
10
|
+
*/
|
|
11
|
+
function stateToSync(s) {
|
|
12
|
+
if (s === 'connecting' || s === 'reconnecting')
|
|
13
|
+
return 'pulling';
|
|
14
|
+
if (s === 'offline')
|
|
15
|
+
return 'dirty';
|
|
16
|
+
return 'clean';
|
|
17
|
+
}
|
|
18
|
+
const SYNC_COLORS = {
|
|
19
|
+
clean: 'var(--ink-muted)',
|
|
20
|
+
pulling: 'var(--ink)',
|
|
21
|
+
dirty: 'var(--ink)',
|
|
22
|
+
};
|
|
23
|
+
const SYNC_LABELS = {
|
|
24
|
+
clean: 'Sync clean',
|
|
25
|
+
pulling: 'Syncing…',
|
|
26
|
+
dirty: 'Sync dirty — changes pending',
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* 6 px sync-status circle.
|
|
30
|
+
* No chromatic colors — grayscale tokens only per design spec.
|
|
31
|
+
* pulling state: pulsing animation.
|
|
32
|
+
*/
|
|
33
|
+
export function SyncStatusDot() {
|
|
34
|
+
const provider = useProvider();
|
|
35
|
+
const isHttp = isHttpProvider(provider);
|
|
36
|
+
const [state, setState] = useState(isHttp ? provider.getConnectionState() : null);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (!isHttpProvider(provider)) {
|
|
39
|
+
setState(null);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
setState(provider.getConnectionState());
|
|
43
|
+
const unsub = provider.onConnectionStateChange((s) => setState(s));
|
|
44
|
+
return unsub;
|
|
45
|
+
}, [provider]);
|
|
46
|
+
const syncState = state !== null ? stateToSync(state) : 'clean';
|
|
47
|
+
const isPulsing = syncState === 'pulling';
|
|
48
|
+
return (_jsx("span", { style: {
|
|
49
|
+
display: 'inline-block',
|
|
50
|
+
width: '6px',
|
|
51
|
+
height: '6px',
|
|
52
|
+
borderRadius: '50%',
|
|
53
|
+
background: SYNC_COLORS[syncState],
|
|
54
|
+
flexShrink: 0,
|
|
55
|
+
animation: isPulsing ? 'pulse 1.5s ease-in-out infinite' : undefined,
|
|
56
|
+
}, "aria-label": SYNC_LABELS[syncState], title: SYNC_LABELS[syncState], "data-testid": "sync-status-dot", "data-sync-state": syncState, "data-connection-state": state ?? 'n/a' }));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=SyncStatusDot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyncStatusDot.js","sourceRoot":"","sources":["../../src/shell/SyncStatusDot.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGjE;;;;;GAKG;AACH,SAAS,WAAW,CAAC,CAAkB;IACrC,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,KAAK,cAAc;QAAE,OAAO,SAAS,CAAC;IACjE,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IACpC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,WAAW,GAAkD;IACjE,KAAK,EAAE,kBAAkB;IACzB,OAAO,EAAE,YAAY;IACrB,KAAK,EAAE,YAAY;CACpB,CAAC;AAEF,MAAM,WAAW,GAAkD;IACjE,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,UAAU;IACnB,KAAK,EAAE,8BAA8B;CACtC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAExC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAChC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAC9C,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QACD,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,SAAS,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,MAAM,SAAS,GAAG,SAAS,KAAK,SAAS,CAAC;IAE1C,OAAO,CACL,eACE,KAAK,EAAE;YACL,OAAO,EAAE,cAAc;YACvB,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,KAAK;YACnB,UAAU,EAAE,WAAW,CAAC,SAAS,CAAC;YAClC,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,SAAS;SACrE,gBACW,WAAW,CAAC,SAAS,CAAC,EAClC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,iBACjB,iBAAiB,qBACZ,SAAS,2BACH,KAAK,IAAI,KAAK,GACrC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Theme toggle button — delegates to useTheme() from theme-store.
|
|
4
|
+
* ☀ = currently light (click to switch to dark)
|
|
5
|
+
* ☾ = currently dark (click to switch to light)
|
|
6
|
+
*/
|
|
7
|
+
export declare function ThemeToggle(): React.ReactElement;
|
|
8
|
+
//# sourceMappingURL=ThemeToggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../src/shell/ThemeToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,KAAK,CAAC,YAAY,CAuBhD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useTheme } from '../state/theme-store.js';
|
|
4
|
+
/**
|
|
5
|
+
* Theme toggle button — delegates to useTheme() from theme-store.
|
|
6
|
+
* ☀ = currently light (click to switch to dark)
|
|
7
|
+
* ☾ = currently dark (click to switch to light)
|
|
8
|
+
*/
|
|
9
|
+
export function ThemeToggle() {
|
|
10
|
+
const { theme, toggle } = useTheme();
|
|
11
|
+
return (_jsx("button", { type: "button", onClick: toggle, "aria-label": theme === 'light' ? 'Switch to dark mode' : 'Switch to light mode', title: theme === 'light' ? 'Switch to dark mode' : 'Switch to light mode', "data-testid": "theme-toggle", style: {
|
|
12
|
+
background: 'none',
|
|
13
|
+
border: 'none',
|
|
14
|
+
cursor: 'pointer',
|
|
15
|
+
color: 'var(--ink-muted)',
|
|
16
|
+
fontSize: '14px',
|
|
17
|
+
padding: '2px 4px',
|
|
18
|
+
lineHeight: 1,
|
|
19
|
+
}, children: theme === 'light' ? '☀' : '☾' }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ThemeToggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeToggle.js","sourceRoot":"","sources":["../../src/shell/ThemeToggle.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;IAErC,OAAO,CACL,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,MAAM,gBACH,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,sBAAsB,EAC9E,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,sBAAsB,iBAC7D,cAAc,EAC1B,KAAK,EAAE;YACL,UAAU,EAAE,MAAM;YAClB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,kBAAkB;YACzB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,SAAS;YAClB,UAAU,EAAE,CAAC;SACd,YAEA,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GACvB,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type Theme = 'light' | 'dark';
|
|
2
|
+
/**
|
|
3
|
+
* React hook for theme management.
|
|
4
|
+
*
|
|
5
|
+
* - Reads initial value from localStorage, falls back to `prefers-color-scheme`.
|
|
6
|
+
* - On change: writes `document.documentElement.dataset.theme` and localStorage.
|
|
7
|
+
* - localStorage unavailable → in-memory only, no error surfaced.
|
|
8
|
+
*
|
|
9
|
+
* UC-6: Theme toggles light↔dark, persists to localStorage, hydrates from OS pref.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useTheme(): {
|
|
12
|
+
theme: Theme;
|
|
13
|
+
toggle(): void;
|
|
14
|
+
set(t: Theme): void;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=theme-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-store.d.ts","sourceRoot":"","sources":["../../src/state/theme-store.ts"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;AAmC9B;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,IAAI;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,IAAI,IAAI,CAAC;IAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAA;CAAE,CAkBhF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
2
|
+
/** Read the persisted theme from localStorage, or null if unavailable. */
|
|
3
|
+
function readStorage() {
|
|
4
|
+
try {
|
|
5
|
+
const stored = localStorage.getItem('theme');
|
|
6
|
+
if (stored === 'light' || stored === 'dark')
|
|
7
|
+
return stored;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// localStorage unavailable (e.g. private browsing, security policy)
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
/** Write theme to localStorage; silently ignores storage errors. */
|
|
15
|
+
function writeStorage(theme) {
|
|
16
|
+
try {
|
|
17
|
+
localStorage.setItem('theme', theme);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// unavailable — in-memory only
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Detect OS colour-scheme preference. */
|
|
24
|
+
function detectOsTheme() {
|
|
25
|
+
if (typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
26
|
+
return 'dark';
|
|
27
|
+
}
|
|
28
|
+
return 'light';
|
|
29
|
+
}
|
|
30
|
+
/** Apply theme to the document root element. */
|
|
31
|
+
function applyTheme(theme) {
|
|
32
|
+
document.documentElement.dataset['theme'] = theme;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* React hook for theme management.
|
|
36
|
+
*
|
|
37
|
+
* - Reads initial value from localStorage, falls back to `prefers-color-scheme`.
|
|
38
|
+
* - On change: writes `document.documentElement.dataset.theme` and localStorage.
|
|
39
|
+
* - localStorage unavailable → in-memory only, no error surfaced.
|
|
40
|
+
*
|
|
41
|
+
* UC-6: Theme toggles light↔dark, persists to localStorage, hydrates from OS pref.
|
|
42
|
+
*/
|
|
43
|
+
export function useTheme() {
|
|
44
|
+
const [theme, setThemeState] = useState(() => readStorage() ?? detectOsTheme());
|
|
45
|
+
// Sync to DOM on mount and whenever theme changes
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
applyTheme(theme);
|
|
48
|
+
writeStorage(theme);
|
|
49
|
+
}, [theme]);
|
|
50
|
+
const toggle = useCallback(() => {
|
|
51
|
+
setThemeState((t) => (t === 'light' ? 'dark' : 'light'));
|
|
52
|
+
}, []);
|
|
53
|
+
const set = useCallback((t) => {
|
|
54
|
+
setThemeState(t);
|
|
55
|
+
}, []);
|
|
56
|
+
return { theme, toggle, set };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=theme-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-store.js","sourceRoot":"","sources":["../../src/state/theme-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAIzD,0EAA0E;AAC1E,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;IACtE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oEAAoE;AACpE,SAAS,YAAY,CAAC,KAAY;IAChC,IAAI,CAAC;QACH,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;IACjC,CAAC;AACH,CAAC;AAED,0CAA0C;AAC1C,SAAS,aAAa;IACpB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,EAAE,CAAC;QAC/F,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gDAAgD;AAChD,SAAS,UAAU,CAAC,KAAY;IAC9B,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;AACpD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAQ,GAAG,EAAE,CAAC,WAAW,EAAE,IAAI,aAAa,EAAE,CAAC,CAAC;IAEvF,kDAAkD;IAClD,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,KAAK,CAAC,CAAC;QAClB,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,MAAM,MAAM,GAAG,WAAW,CAAC,GAAS,EAAE;QACpC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAQ,EAAQ,EAAE;QACzC,aAAa,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BoardRender, Homeless } from '@awesome-markdown/contracts';
|
|
2
|
+
export type BoardRenderStatus = 'loading' | 'ready' | 'error';
|
|
3
|
+
export interface BoardRenderState {
|
|
4
|
+
status: BoardRenderStatus;
|
|
5
|
+
render: BoardRender | null;
|
|
6
|
+
homeless: Homeless | null;
|
|
7
|
+
refetch: () => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Fetches the render envelope and homeless list for a board by slug.
|
|
11
|
+
*
|
|
12
|
+
* Coalesces rapid SSE change events into a single re-fetch per board
|
|
13
|
+
* via `useProviderSubscribe` (debounce ~100 ms).
|
|
14
|
+
*/
|
|
15
|
+
export declare function useBoardRender(slug: string): BoardRenderState;
|
|
16
|
+
//# sourceMappingURL=useBoardRender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBoardRender.d.ts","sourceRoot":"","sources":["../../src/state/useBoardRender.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAIzE,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CA6C7D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
2
|
+
import { useProvider } from '../provider/ProviderContext.js';
|
|
3
|
+
import { useProviderSubscribe } from './useProviderSubscribe.js';
|
|
4
|
+
/**
|
|
5
|
+
* Fetches the render envelope and homeless list for a board by slug.
|
|
6
|
+
*
|
|
7
|
+
* Coalesces rapid SSE change events into a single re-fetch per board
|
|
8
|
+
* via `useProviderSubscribe` (debounce ~100 ms).
|
|
9
|
+
*/
|
|
10
|
+
export function useBoardRender(slug) {
|
|
11
|
+
const provider = useProvider();
|
|
12
|
+
const [render, setRender] = useState(null);
|
|
13
|
+
const [homeless, setHomeless] = useState(null);
|
|
14
|
+
const [status, setStatus] = useState('loading');
|
|
15
|
+
const slugRef = useRef(slug);
|
|
16
|
+
slugRef.current = slug;
|
|
17
|
+
const fetchAll = useCallback(async () => {
|
|
18
|
+
const currentSlug = slugRef.current;
|
|
19
|
+
if (currentSlug === '') {
|
|
20
|
+
setRender(null);
|
|
21
|
+
setHomeless(null);
|
|
22
|
+
setStatus('ready');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const [renderResult, homelessResult] = await Promise.all([
|
|
27
|
+
provider.getBoardRender(currentSlug),
|
|
28
|
+
provider.getHomeless(currentSlug),
|
|
29
|
+
]);
|
|
30
|
+
// Discard if slug changed while inflight
|
|
31
|
+
if (slugRef.current !== currentSlug)
|
|
32
|
+
return;
|
|
33
|
+
setRender(renderResult);
|
|
34
|
+
setHomeless(homelessResult);
|
|
35
|
+
setStatus('ready');
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error('Failed to load board render', currentSlug, err);
|
|
39
|
+
if (slugRef.current === currentSlug) {
|
|
40
|
+
setStatus('error');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}, [provider]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
setRender(null);
|
|
46
|
+
setHomeless(null);
|
|
47
|
+
setStatus('loading');
|
|
48
|
+
void fetchAll();
|
|
49
|
+
}, [provider, slug, fetchAll]);
|
|
50
|
+
useProviderSubscribe(() => void fetchAll());
|
|
51
|
+
return { status, render, homeless, refetch: fetchAll };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=useBoardRender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBoardRender.js","sourceRoot":"","sources":["../../src/state/useBoardRender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAWjE;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IAC/D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAkB,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAoB,SAAS,CAAC,CAAC;IAEnE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAEvB,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAmB,EAAE;QACrD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;QACpC,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;YACvB,SAAS,CAAC,IAAI,CAAC,CAAC;YAChB,WAAW,CAAC,IAAI,CAAC,CAAC;YAClB,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACvD,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC;gBACpC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC;aAClC,CAAC,CAAC;YACH,yCAAyC;YACzC,IAAI,OAAO,CAAC,OAAO,KAAK,WAAW;gBAAE,OAAO;YAC5C,SAAS,CAAC,YAAY,CAAC,CAAC;YACxB,WAAW,CAAC,cAAc,CAAC,CAAC;YAC5B,SAAS,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;YAC/D,IAAI,OAAO,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;gBACpC,SAAS,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,SAAS,CAAC,SAAS,CAAC,CAAC;QACrB,KAAK,QAAQ,EAAE,CAAC;IAClB,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE/B,oBAAoB,CAAC,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;IAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ProviderEvent } from '@awesome-markdown/contracts';
|
|
2
|
+
type ChangeCallback = (event: ProviderEvent | null) => void;
|
|
3
|
+
/**
|
|
4
|
+
* Subscribes to all provider change signals and invokes `callback` on each,
|
|
5
|
+
* debounced by `debounceMs` (default 100 ms).
|
|
6
|
+
*
|
|
7
|
+
* Two signal sources are wired:
|
|
8
|
+
* - `provider.subscribe()` — fires when the http/localstorage provider detects
|
|
9
|
+
* a mutation (local API write or provider-fs file-watcher). The `ProviderEvent`
|
|
10
|
+
* payload is forwarded to the callback.
|
|
11
|
+
* - `window` `sync-engine:change` custom event — fired by `conflict-store` when
|
|
12
|
+
* the sync-engine SSE (port 7402) broadcasts a change (e.g. after a git pull).
|
|
13
|
+
* The callback receives `null` because this path carries no entity metadata.
|
|
14
|
+
*
|
|
15
|
+
* The callback is stabilised via `useRef` so callers do not need to memoize it —
|
|
16
|
+
* the latest closure is always called without re-registering subscriptions.
|
|
17
|
+
*
|
|
18
|
+
* Subscriptions are re-established when `provider` or `debounceMs` change.
|
|
19
|
+
*/
|
|
20
|
+
export declare function useProviderSubscribe(callback: ChangeCallback, debounceMs?: number): void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=useProviderSubscribe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProviderSubscribe.d.ts","sourceRoot":"","sources":["../../src/state/useProviderSubscribe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC;AAE5D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,cAAc,EACxB,UAAU,SAAM,GACf,IAAI,CAgCN"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { useProvider } from '../provider/ProviderContext.js';
|
|
3
|
+
/**
|
|
4
|
+
* Subscribes to all provider change signals and invokes `callback` on each,
|
|
5
|
+
* debounced by `debounceMs` (default 100 ms).
|
|
6
|
+
*
|
|
7
|
+
* Two signal sources are wired:
|
|
8
|
+
* - `provider.subscribe()` — fires when the http/localstorage provider detects
|
|
9
|
+
* a mutation (local API write or provider-fs file-watcher). The `ProviderEvent`
|
|
10
|
+
* payload is forwarded to the callback.
|
|
11
|
+
* - `window` `sync-engine:change` custom event — fired by `conflict-store` when
|
|
12
|
+
* the sync-engine SSE (port 7402) broadcasts a change (e.g. after a git pull).
|
|
13
|
+
* The callback receives `null` because this path carries no entity metadata.
|
|
14
|
+
*
|
|
15
|
+
* The callback is stabilised via `useRef` so callers do not need to memoize it —
|
|
16
|
+
* the latest closure is always called without re-registering subscriptions.
|
|
17
|
+
*
|
|
18
|
+
* Subscriptions are re-established when `provider` or `debounceMs` change.
|
|
19
|
+
*/
|
|
20
|
+
export function useProviderSubscribe(callback, debounceMs = 100) {
|
|
21
|
+
const provider = useProvider();
|
|
22
|
+
// Always holds the latest callback without causing effect re-runs.
|
|
23
|
+
const callbackRef = useRef(callback);
|
|
24
|
+
callbackRef.current = callback;
|
|
25
|
+
const debounceRef = useRef(null);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const schedule = (event) => {
|
|
28
|
+
if (debounceRef.current !== null)
|
|
29
|
+
clearTimeout(debounceRef.current);
|
|
30
|
+
debounceRef.current = setTimeout(() => {
|
|
31
|
+
debounceRef.current = null;
|
|
32
|
+
callbackRef.current(event);
|
|
33
|
+
}, debounceMs);
|
|
34
|
+
};
|
|
35
|
+
const unsubscribe = provider.subscribe((event) => schedule(event));
|
|
36
|
+
const handleWindowChange = () => schedule(null);
|
|
37
|
+
window.addEventListener('sync-engine:change', handleWindowChange);
|
|
38
|
+
return () => {
|
|
39
|
+
unsubscribe();
|
|
40
|
+
window.removeEventListener('sync-engine:change', handleWindowChange);
|
|
41
|
+
if (debounceRef.current !== null) {
|
|
42
|
+
clearTimeout(debounceRef.current);
|
|
43
|
+
debounceRef.current = null;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}, [provider, debounceMs]);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=useProviderSubscribe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProviderSubscribe.js","sourceRoot":"","sources":["../../src/state/useProviderSubscribe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAI7D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAwB,EACxB,UAAU,GAAG,GAAG;IAEhB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,mEAAmE;IACnE,MAAM,WAAW,GAAG,MAAM,CAAiB,QAAQ,CAAC,CAAC;IACrD,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAE/B,MAAM,WAAW,GAAG,MAAM,CAAuC,IAAI,CAAC,CAAC;IAEvE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,CAAC,KAA2B,EAAQ,EAAE;YACrD,IAAI,WAAW,CAAC,OAAO,KAAK,IAAI;gBAAE,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACpE,WAAW,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBACpC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;gBAC3B,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC,EAAE,UAAU,CAAC,CAAC;QACjB,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAEnE,MAAM,kBAAkB,GAAG,GAAS,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;QAElE,OAAO,GAAG,EAAE;YACV,WAAW,EAAE,CAAC;YACd,MAAM,CAAC,mBAAmB,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;YACrE,IAAI,WAAW,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBACjC,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;gBAClC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;YAC7B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ConflictState, ResolveDecision, ResolveResponse } from '@awesome-markdown/contracts';
|
|
2
|
+
/**
|
|
3
|
+
* Fetch the current conflict state from the sync-engine.
|
|
4
|
+
*
|
|
5
|
+
* @param base Base URL of the sync-engine HTTP server (resolved by the host app).
|
|
6
|
+
*/
|
|
7
|
+
export declare function fetchConflictState(base: string): Promise<ConflictState | null>;
|
|
8
|
+
/**
|
|
9
|
+
* Submit resolution decisions to the sync-engine.
|
|
10
|
+
*
|
|
11
|
+
* @param base Base URL of the sync-engine HTTP server.
|
|
12
|
+
* @param mergeId The active mergeId.
|
|
13
|
+
* @param decisions Map of repo-relative path → decision.
|
|
14
|
+
*/
|
|
15
|
+
export declare function submitDecisions(base: string, mergeId: string, decisions: Record<string, ResolveDecision>): Promise<ResolveResponse>;
|
|
16
|
+
//# sourceMappingURL=conflict-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-api.d.ts","sourceRoot":"","sources":["../../src/sync/conflict-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAErC;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAOpF;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GACzC,OAAO,CAAC,eAAe,CAAC,CAe1B"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch the current conflict state from the sync-engine.
|
|
3
|
+
*
|
|
4
|
+
* @param base Base URL of the sync-engine HTTP server (resolved by the host app).
|
|
5
|
+
*/
|
|
6
|
+
export async function fetchConflictState(base) {
|
|
7
|
+
const resp = await fetch(`${base}/sync/conflict/state`, {
|
|
8
|
+
signal: AbortSignal.timeout(5_000),
|
|
9
|
+
});
|
|
10
|
+
if (!resp.ok)
|
|
11
|
+
return null;
|
|
12
|
+
const body = (await resp.json());
|
|
13
|
+
return body.conflict ?? null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Submit resolution decisions to the sync-engine.
|
|
17
|
+
*
|
|
18
|
+
* @param base Base URL of the sync-engine HTTP server.
|
|
19
|
+
* @param mergeId The active mergeId.
|
|
20
|
+
* @param decisions Map of repo-relative path → decision.
|
|
21
|
+
*/
|
|
22
|
+
export async function submitDecisions(base, mergeId, decisions) {
|
|
23
|
+
const resp = await fetch(`${base}/sync/conflict/resolve`, {
|
|
24
|
+
method: 'POST',
|
|
25
|
+
headers: { 'Content-Type': 'application/json' },
|
|
26
|
+
body: JSON.stringify({ mergeId, decisions }),
|
|
27
|
+
signal: AbortSignal.timeout(15_000),
|
|
28
|
+
});
|
|
29
|
+
if (!resp.ok) {
|
|
30
|
+
const err = (await resp.json().catch(() => ({ message: resp.statusText })));
|
|
31
|
+
throw new Error(err.message ?? err.error ?? `HTTP ${resp.status}`);
|
|
32
|
+
}
|
|
33
|
+
return resp.json();
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=conflict-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-api.js","sourceRoot":"","sources":["../../src/sync/conflict-api.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY;IACnD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,sBAAsB,EAAE;QACtD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;KACnC,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAuC,CAAC;IACvE,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY,EACZ,OAAe,EACf,SAA0C;IAE1C,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,wBAAwB,EAAE;QACxD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAC5C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAGzE,CAAC;QACF,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAA8B,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ConflictState, ResolveDecision } from '@awesome-markdown/contracts';
|
|
3
|
+
export interface ConflictStoreState {
|
|
4
|
+
activeConflict: ConflictState | null;
|
|
5
|
+
submitting: boolean;
|
|
6
|
+
error: string | null;
|
|
7
|
+
}
|
|
8
|
+
interface ConflictContextValue extends ConflictStoreState {
|
|
9
|
+
isPathAffected: (filePath: string) => boolean;
|
|
10
|
+
/** Returns true if any conflicted path contains the given item ID. */
|
|
11
|
+
isItemAffected: (itemId: string) => boolean;
|
|
12
|
+
decisionFor: (filePath: string) => ResolveDecision | null;
|
|
13
|
+
resolve: (decisions: Record<string, ResolveDecision>) => Promise<void>;
|
|
14
|
+
dismissError: () => void;
|
|
15
|
+
}
|
|
16
|
+
interface ConflictProviderProps {
|
|
17
|
+
/**
|
|
18
|
+
* Base URL of the sync-engine HTTP server (e.g. `http://localhost:7402` or a
|
|
19
|
+
* same-origin proxy path such as `/sync-engine`). Hosts without a
|
|
20
|
+
* sync-engine simply don't mount `ConflictProvider`.
|
|
21
|
+
*/
|
|
22
|
+
syncEngineUrl: string;
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Provides the conflict store to the component tree.
|
|
27
|
+
*
|
|
28
|
+
* On mount:
|
|
29
|
+
* 1. Fetches GET /sync/conflict/state to hydrate any in-flight conflict.
|
|
30
|
+
* 2. Subscribes to SSE events (conflict / synced) via EventSource.
|
|
31
|
+
*
|
|
32
|
+
* The EventSource is reconnect-safe: duplicate `conflict` events for the same
|
|
33
|
+
* mergeId are coalesced (idempotent set-state).
|
|
34
|
+
*/
|
|
35
|
+
export declare function ConflictProvider({ syncEngineUrl, children, }: ConflictProviderProps): React.ReactElement;
|
|
36
|
+
/** Access the conflict store. Must be used inside <ConflictProvider>. */
|
|
37
|
+
export declare function useConflict(): ConflictContextValue;
|
|
38
|
+
/**
|
|
39
|
+
* Like useConflict but returns null when not inside <ConflictProvider>.
|
|
40
|
+
* Useful for components that are also rendered outside a provider (e.g. tests).
|
|
41
|
+
*/
|
|
42
|
+
export declare function useOptionalConflict(): ConflictContextValue | null;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=conflict-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-store.d.ts","sourceRoot":"","sources":["../../src/sync/conflict-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAOlF,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAwCD,UAAU,oBAAqB,SAAQ,kBAAkB;IACvD,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,sEAAsE;IACtE,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,eAAe,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAQD,UAAU,qBAAqB;IAC7B;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,aAAa,EACb,QAAQ,GACT,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAgI5C;AAED,yEAAyE;AACzE,wBAAgB,WAAW,IAAI,oBAAoB,CAMlD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,oBAAoB,GAAG,IAAI,CAEjE"}
|