@burdenoff/microfe-atheletebridge 2026.705.2 → 2026.706.1
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/dist/atheletebridge/AthleteBridgeRoot.js +55 -39
- package/dist/atheletebridge/AthleteBridgeRoot.js.map +1 -1
- package/dist/atheletebridge/AthleteBridgeRoutes.js +18 -6
- package/dist/atheletebridge/AthleteBridgeRoutes.js.map +1 -1
- package/dist/atheletebridge/components/Crest.js +70 -0
- package/dist/atheletebridge/components/Crest.js.map +1 -0
- package/dist/atheletebridge/components/FixtureCard.js +8 -72
- package/dist/atheletebridge/components/FixtureCard.js.map +1 -1
- package/dist/atheletebridge/components/MatchupRow.js +74 -0
- package/dist/atheletebridge/components/MatchupRow.js.map +1 -0
- package/dist/atheletebridge/components/MetricsCard.js +61 -21
- package/dist/atheletebridge/components/MetricsCard.js.map +1 -1
- package/dist/atheletebridge/components/ProgramCard.js +75 -43
- package/dist/atheletebridge/components/ProgramCard.js.map +1 -1
- package/dist/atheletebridge/components/Scoreboard.js +163 -0
- package/dist/atheletebridge/components/Scoreboard.js.map +1 -0
- package/dist/atheletebridge/components/SessionCard.js +64 -41
- package/dist/atheletebridge/components/SessionCard.js.map +1 -1
- package/dist/atheletebridge/components/SessionStatusTimeline.js +80 -0
- package/dist/atheletebridge/components/SessionStatusTimeline.js.map +1 -0
- package/dist/atheletebridge/components/StatusBadge.js +5 -5
- package/dist/atheletebridge/components/StatusBadge.js.map +1 -1
- package/dist/atheletebridge/components/TeamCard.js +65 -35
- package/dist/atheletebridge/components/TeamCard.js.map +1 -1
- package/dist/atheletebridge/components/UserAvatar.js +33 -0
- package/dist/atheletebridge/components/UserAvatar.js.map +1 -0
- package/dist/atheletebridge/components/domain.js +5 -2
- package/dist/atheletebridge/components/domain.js.map +1 -1
- package/dist/atheletebridge/components/viz/AvatarStack.js +2 -0
- package/dist/atheletebridge/components/viz/BarChart.js +83 -0
- package/dist/atheletebridge/components/viz/BarChart.js.map +1 -0
- package/dist/atheletebridge/components/viz/DonutChart.js +109 -0
- package/dist/atheletebridge/components/viz/DonutChart.js.map +1 -0
- package/dist/atheletebridge/components/viz/LineChart.js +123 -0
- package/dist/atheletebridge/components/viz/LineChart.js.map +1 -0
- package/dist/atheletebridge/components/viz/ProgressRing.js +6 -0
- package/dist/atheletebridge/components/viz/ProgressRing.js.map +1 -0
- package/dist/atheletebridge/components/viz/RatingStars.js +92 -0
- package/dist/atheletebridge/components/viz/RatingStars.js.map +1 -0
- package/dist/atheletebridge/components/viz/Sparkline.js +74 -0
- package/dist/atheletebridge/components/viz/Sparkline.js.map +1 -0
- package/dist/atheletebridge/components/viz/StatCard.js +60 -0
- package/dist/atheletebridge/components/viz/StatCard.js.map +1 -0
- package/dist/atheletebridge/components/viz/StepProgress.js +3 -0
- package/dist/atheletebridge/components/viz/Timeline.js +66 -0
- package/dist/atheletebridge/components/viz/Timeline.js.map +1 -0
- package/dist/atheletebridge/components/viz/index.js +13 -0
- package/dist/atheletebridge/components/viz/lib/Avatar.js +1 -0
- package/dist/atheletebridge/components/viz/lib/CartesianFrame.js +119 -0
- package/dist/atheletebridge/components/viz/lib/CartesianFrame.js.map +1 -0
- package/dist/atheletebridge/components/viz/lib/ResponsiveSvg.js +35 -0
- package/dist/atheletebridge/components/viz/lib/ResponsiveSvg.js.map +1 -0
- package/dist/atheletebridge/components/viz/lib/format.js +17 -0
- package/dist/atheletebridge/components/viz/lib/format.js.map +1 -0
- package/dist/atheletebridge/components/viz/lib/geometry.js +61 -0
- package/dist/atheletebridge/components/viz/lib/geometry.js.map +1 -0
- package/dist/atheletebridge/components/viz/lib/hooks.js +39 -0
- package/dist/atheletebridge/components/viz/lib/hooks.js.map +1 -0
- package/dist/atheletebridge/components/viz/lib/palette.js +27 -0
- package/dist/atheletebridge/components/viz/lib/palette.js.map +1 -0
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +369 -163
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
- package/dist/atheletebridge/pages/DashboardPage.js +182 -117
- package/dist/atheletebridge/pages/DashboardPage.js.map +1 -1
- package/dist/atheletebridge/pages/StandingsPage.js +119 -95
- package/dist/atheletebridge/pages/StandingsPage.js.map +1 -1
- package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js +372 -0
- package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js.map +1 -0
- package/dist/atheletebridge/pages/athletes/AthleteProfilePage.js +511 -0
- package/dist/atheletebridge/pages/athletes/AthleteProfilePage.js.map +1 -0
- package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js +120 -131
- package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/fixtures/FixtureFormPage.js +264 -176
- package/dist/atheletebridge/pages/fixtures/FixtureFormPage.js.map +1 -1
- package/dist/atheletebridge/pages/fixtures/FixturesListPage.js +84 -47
- package/dist/atheletebridge/pages/fixtures/FixturesListPage.js.map +1 -1
- package/dist/atheletebridge/pages/performance/PerformancePage.js +432 -281
- package/dist/atheletebridge/pages/performance/PerformancePage.js.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramDetailPage.js +187 -123
- package/dist/atheletebridge/pages/programs/ProgramDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramsListPage.js +56 -39
- package/dist/atheletebridge/pages/programs/ProgramsListPage.js.map +1 -1
- package/dist/atheletebridge/pages/sessions/SessionDetailPage.js +267 -139
- package/dist/atheletebridge/pages/sessions/SessionDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/sessions/SessionFormPage.js +253 -162
- package/dist/atheletebridge/pages/sessions/SessionFormPage.js.map +1 -1
- package/dist/atheletebridge/pages/sessions/SessionsListPage.js +38 -36
- package/dist/atheletebridge/pages/sessions/SessionsListPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamDetailPage.js +437 -189
- package/dist/atheletebridge/pages/teams/TeamDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamFormPage.js +368 -177
- package/dist/atheletebridge/pages/teams/TeamFormPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamsListPage.js +3 -0
- package/dist/atheletebridge/pages/teams/TeamsListPage.js.map +1 -1
- package/dist/atheletebridge/pages/tournaments/TournamentBracketPage.js +298 -0
- package/dist/atheletebridge/pages/tournaments/TournamentBracketPage.js.map +1 -0
- package/dist/atheletebridge/utils/identity.js +31 -0
- package/dist/atheletebridge/utils/identity.js.map +1 -0
- package/dist/atheletebridge/utils/timeAgo.js +20 -0
- package/dist/atheletebridge/utils/timeAgo.js.map +1 -0
- package/package.json +1 -1
|
@@ -4,102 +4,118 @@ import { useCallback as n, useEffect as r } from "react";
|
|
|
4
4
|
import { QueryClient as i, QueryClientProvider as a } from "@tanstack/react-query";
|
|
5
5
|
import { useI18n as o } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
6
6
|
import { FeatureFlagProvider as s } from "@burdenoff/fe-libs/shared/feature-flags";
|
|
7
|
-
import {
|
|
8
|
-
import { jsx as
|
|
7
|
+
import { BarChart3 as c, CalendarDays as l, ClipboardCheck as u, Dumbbell as d, Gauge as f, LayoutDashboard as p, Swords as m, Trophy as h, Users as g } from "lucide-react";
|
|
8
|
+
import { jsx as _ } from "react/jsx-runtime";
|
|
9
9
|
//#region src/atheletebridge/AthleteBridgeRoot.tsx
|
|
10
|
-
var
|
|
10
|
+
var v = new i({ defaultOptions: { queries: {
|
|
11
11
|
staleTime: 300 * 1e3,
|
|
12
12
|
retry: 1
|
|
13
|
-
} } }),
|
|
14
|
-
let { registerNavItems:
|
|
15
|
-
let n =
|
|
13
|
+
} } }), y = (i) => {
|
|
14
|
+
let { registerNavItems: y, registerFooterItems: b, basePath: x = "/" } = i, { t: S } = o(), C = n((e, t) => {
|
|
15
|
+
let n = S(e);
|
|
16
16
|
return n === e ? t : n;
|
|
17
|
-
}, [
|
|
17
|
+
}, [S]), w = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
|
|
18
18
|
return r(() => {
|
|
19
|
-
if (
|
|
19
|
+
if (y) return y([
|
|
20
20
|
{
|
|
21
21
|
id: "atheletebridge-dashboard",
|
|
22
|
-
label:
|
|
23
|
-
path:
|
|
24
|
-
icon: /* @__PURE__ */
|
|
22
|
+
label: C("atheletebridge.nav.dashboard", "Dashboard"),
|
|
23
|
+
path: w(x, ""),
|
|
24
|
+
icon: /* @__PURE__ */ _(p, { size: 20 }),
|
|
25
25
|
order: 1,
|
|
26
26
|
group: "main"
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
id: "atheletebridge-teams",
|
|
30
|
-
label:
|
|
31
|
-
path:
|
|
32
|
-
icon: /* @__PURE__ */
|
|
30
|
+
label: C("atheletebridge.nav.teams", "Teams"),
|
|
31
|
+
path: w(x, "teams"),
|
|
32
|
+
icon: /* @__PURE__ */ _(g, { size: 20 }),
|
|
33
33
|
order: 10,
|
|
34
34
|
group: "roster"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
id: "atheletebridge-fixtures",
|
|
38
|
-
label:
|
|
39
|
-
path:
|
|
40
|
-
icon: /* @__PURE__ */
|
|
38
|
+
label: C("atheletebridge.nav.fixtures", "Fixtures"),
|
|
39
|
+
path: w(x, "fixtures"),
|
|
40
|
+
icon: /* @__PURE__ */ _(l, { size: 20 }),
|
|
41
41
|
order: 11,
|
|
42
42
|
group: "roster"
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
id: "atheletebridge-standings",
|
|
46
|
-
label:
|
|
47
|
-
path:
|
|
48
|
-
icon: /* @__PURE__ */ h
|
|
46
|
+
label: C("atheletebridge.nav.standings", "Standings"),
|
|
47
|
+
path: w(x, "standings"),
|
|
48
|
+
icon: /* @__PURE__ */ _(h, { size: 20 }),
|
|
49
49
|
order: 12,
|
|
50
50
|
group: "roster"
|
|
51
51
|
},
|
|
52
|
+
{
|
|
53
|
+
id: "atheletebridge-tournaments",
|
|
54
|
+
label: C("atheletebridge.nav.tournaments", "Tournaments"),
|
|
55
|
+
path: w(x, "tournaments"),
|
|
56
|
+
icon: /* @__PURE__ */ _(m, { size: 20 }),
|
|
57
|
+
order: 13,
|
|
58
|
+
group: "roster"
|
|
59
|
+
},
|
|
52
60
|
{
|
|
53
61
|
id: "atheletebridge-programs",
|
|
54
|
-
label:
|
|
55
|
-
path:
|
|
56
|
-
icon: /* @__PURE__ */
|
|
62
|
+
label: C("atheletebridge.nav.programs", "Programs"),
|
|
63
|
+
path: w(x, "programs"),
|
|
64
|
+
icon: /* @__PURE__ */ _(d, { size: 20 }),
|
|
57
65
|
order: 20,
|
|
58
66
|
group: "training"
|
|
59
67
|
},
|
|
60
68
|
{
|
|
61
69
|
id: "atheletebridge-sessions",
|
|
62
|
-
label:
|
|
63
|
-
path:
|
|
64
|
-
icon: /* @__PURE__ */
|
|
70
|
+
label: C("atheletebridge.nav.sessions", "Sessions"),
|
|
71
|
+
path: w(x, "sessions"),
|
|
72
|
+
icon: /* @__PURE__ */ _(u, { size: 20 }),
|
|
65
73
|
order: 21,
|
|
66
74
|
group: "training"
|
|
67
75
|
},
|
|
68
76
|
{
|
|
69
77
|
id: "atheletebridge-performance",
|
|
70
|
-
label:
|
|
71
|
-
path:
|
|
72
|
-
icon: /* @__PURE__ */
|
|
78
|
+
label: C("atheletebridge.nav.performance", "Performance"),
|
|
79
|
+
path: w(x, "performance"),
|
|
80
|
+
icon: /* @__PURE__ */ _(f, { size: 20 }),
|
|
73
81
|
order: 22,
|
|
74
82
|
group: "training"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "atheletebridge-analytics",
|
|
86
|
+
label: C("atheletebridge.nav.analytics", "Analytics"),
|
|
87
|
+
path: w(x, "analytics"),
|
|
88
|
+
icon: /* @__PURE__ */ _(c, { size: 20 }),
|
|
89
|
+
order: 23,
|
|
90
|
+
group: "training"
|
|
75
91
|
}
|
|
76
92
|
]);
|
|
77
93
|
}, [
|
|
78
|
-
_,
|
|
79
94
|
y,
|
|
80
|
-
x
|
|
95
|
+
x,
|
|
96
|
+
C
|
|
81
97
|
]), r(() => {
|
|
82
|
-
if (
|
|
98
|
+
if (b) return b([{
|
|
83
99
|
id: "atheletebridge-status",
|
|
84
|
-
label:
|
|
100
|
+
label: C("atheletebridge.footer.ready", "AthleteBridge Ready"),
|
|
85
101
|
type: "status",
|
|
86
102
|
order: 10,
|
|
87
103
|
section: "left"
|
|
88
104
|
}]);
|
|
89
|
-
}, [
|
|
90
|
-
client:
|
|
91
|
-
children: /* @__PURE__ */
|
|
105
|
+
}, [b, C]), /* @__PURE__ */ _(a, {
|
|
106
|
+
client: v,
|
|
107
|
+
children: /* @__PURE__ */ _(s, {
|
|
92
108
|
workspaceId: null,
|
|
93
109
|
gateway: "global",
|
|
94
110
|
defaultEnabled: !0,
|
|
95
|
-
children: /* @__PURE__ */
|
|
111
|
+
children: /* @__PURE__ */ _(e, {
|
|
96
112
|
...i,
|
|
97
|
-
children: /* @__PURE__ */
|
|
113
|
+
children: /* @__PURE__ */ _(t, {})
|
|
98
114
|
})
|
|
99
115
|
})
|
|
100
116
|
});
|
|
101
117
|
};
|
|
102
118
|
//#endregion
|
|
103
|
-
export {
|
|
119
|
+
export { y as AthleteBridgeRoot };
|
|
104
120
|
|
|
105
121
|
//# sourceMappingURL=AthleteBridgeRoot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AthleteBridgeRoot.js","names":[],"sources":["../../src/atheletebridge/AthleteBridgeRoot.tsx"],"sourcesContent":["/**\n * AthleteBridge Root Component\n * @module atheletebridge\n *\n * The single Root export consumed by the host app shell. The export name and\n * props (AthleteBridgeRootProps) are the host contract and must not change —\n * only the internal nav config, provider tree, and routes are product-specific.\n */\n\nimport type { FC } from 'react';\nimport { useCallback, useEffect } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport {\n LayoutDashboard,\n Users,\n CalendarDays,\n Trophy,\n Dumbbell,\n ClipboardCheck,\n Gauge,\n} from 'lucide-react';\nimport { AthleteBridgeProvider } from './context/AthleteBridgeContext';\nimport { AthleteBridgeRoutes } from './AthleteBridgeRoutes';\nimport type { AthleteBridgeRootProps, NavItem } from './types';\n\n// Create a query client for this microfrontend\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\nexport const AthleteBridgeRoot: FC<AthleteBridgeRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n const { t: translate } = useI18n();\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n\n // Helper to join paths correctly\n const joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n };\n\n // Register navigation items with shell on mount\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'atheletebridge-dashboard',\n label: t('atheletebridge.nav.dashboard', 'Dashboard'),\n path: joinPath(basePath, ''),\n icon: <LayoutDashboard size={20} />,\n order: 1,\n group: 'main',\n },\n {\n id: 'atheletebridge-teams',\n label: t('atheletebridge.nav.teams', 'Teams'),\n path: joinPath(basePath, 'teams'),\n icon: <Users size={20} />,\n order: 10,\n group: 'roster',\n },\n {\n id: 'atheletebridge-fixtures',\n label: t('atheletebridge.nav.fixtures', 'Fixtures'),\n path: joinPath(basePath, 'fixtures'),\n icon: <CalendarDays size={20} />,\n order: 11,\n group: 'roster',\n },\n {\n id: 'atheletebridge-standings',\n label: t('atheletebridge.nav.standings', 'Standings'),\n path: joinPath(basePath, 'standings'),\n icon: <Trophy size={20} />,\n order: 12,\n group: 'roster',\n },\n {\n id: 'atheletebridge-programs',\n label: t('atheletebridge.nav.programs', 'Programs'),\n path: joinPath(basePath, 'programs'),\n icon: <Dumbbell size={20} />,\n order: 20,\n group: 'training',\n },\n {\n id: 'atheletebridge-sessions',\n label: t('atheletebridge.nav.sessions', 'Sessions'),\n path: joinPath(basePath, 'sessions'),\n icon: <ClipboardCheck size={20} />,\n order: 21,\n group: 'training',\n },\n {\n id: 'atheletebridge-performance',\n label: t('atheletebridge.nav.performance', 'Performance'),\n path: joinPath(basePath, 'performance'),\n icon: <Gauge size={20} />,\n order: 22,\n group: 'training',\n },\n ];\n\n const cleanup = registerNavItems(navItems);\n return cleanup;\n }, [registerNavItems, basePath, t]);\n\n // Register footer items\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'atheletebridge-status',\n label: t('atheletebridge.footer.ready', 'AthleteBridge Ready'),\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems, t]);\n\n return (\n <QueryClientProvider client={queryClient}>\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <AthleteBridgeProvider {...props}>\n <AthleteBridgeRoutes />\n </AthleteBridgeProvider>\n </FeatureFlagProvider>\n </QueryClientProvider>\n );\n};\n"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"AthleteBridgeRoot.js","names":[],"sources":["../../src/atheletebridge/AthleteBridgeRoot.tsx"],"sourcesContent":["/**\n * AthleteBridge Root Component\n * @module atheletebridge\n *\n * The single Root export consumed by the host app shell. The export name and\n * props (AthleteBridgeRootProps) are the host contract and must not change —\n * only the internal nav config, provider tree, and routes are product-specific.\n */\n\nimport type { FC } from 'react';\nimport { useCallback, useEffect } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport {\n LayoutDashboard,\n Users,\n CalendarDays,\n Trophy,\n Dumbbell,\n ClipboardCheck,\n Gauge,\n BarChart3,\n Swords,\n} from 'lucide-react';\nimport { AthleteBridgeProvider } from './context/AthleteBridgeContext';\nimport { AthleteBridgeRoutes } from './AthleteBridgeRoutes';\nimport type { AthleteBridgeRootProps, NavItem } from './types';\n\n// Create a query client for this microfrontend\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\nexport const AthleteBridgeRoot: FC<AthleteBridgeRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n const { t: translate } = useI18n();\n const t = useCallback(\n (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n },\n [translate]\n );\n\n // Helper to join paths correctly\n const joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n };\n\n // Register navigation items with shell on mount\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'atheletebridge-dashboard',\n label: t('atheletebridge.nav.dashboard', 'Dashboard'),\n path: joinPath(basePath, ''),\n icon: <LayoutDashboard size={20} />,\n order: 1,\n group: 'main',\n },\n {\n id: 'atheletebridge-teams',\n label: t('atheletebridge.nav.teams', 'Teams'),\n path: joinPath(basePath, 'teams'),\n icon: <Users size={20} />,\n order: 10,\n group: 'roster',\n },\n {\n id: 'atheletebridge-fixtures',\n label: t('atheletebridge.nav.fixtures', 'Fixtures'),\n path: joinPath(basePath, 'fixtures'),\n icon: <CalendarDays size={20} />,\n order: 11,\n group: 'roster',\n },\n {\n id: 'atheletebridge-standings',\n label: t('atheletebridge.nav.standings', 'Standings'),\n path: joinPath(basePath, 'standings'),\n icon: <Trophy size={20} />,\n order: 12,\n group: 'roster',\n },\n {\n id: 'atheletebridge-tournaments',\n label: t('atheletebridge.nav.tournaments', 'Tournaments'),\n path: joinPath(basePath, 'tournaments'),\n icon: <Swords size={20} />,\n order: 13,\n group: 'roster',\n },\n {\n id: 'atheletebridge-programs',\n label: t('atheletebridge.nav.programs', 'Programs'),\n path: joinPath(basePath, 'programs'),\n icon: <Dumbbell size={20} />,\n order: 20,\n group: 'training',\n },\n {\n id: 'atheletebridge-sessions',\n label: t('atheletebridge.nav.sessions', 'Sessions'),\n path: joinPath(basePath, 'sessions'),\n icon: <ClipboardCheck size={20} />,\n order: 21,\n group: 'training',\n },\n {\n id: 'atheletebridge-performance',\n label: t('atheletebridge.nav.performance', 'Performance'),\n path: joinPath(basePath, 'performance'),\n icon: <Gauge size={20} />,\n order: 22,\n group: 'training',\n },\n {\n id: 'atheletebridge-analytics',\n label: t('atheletebridge.nav.analytics', 'Analytics'),\n path: joinPath(basePath, 'analytics'),\n icon: <BarChart3 size={20} />,\n order: 23,\n group: 'training',\n },\n ];\n\n const cleanup = registerNavItems(navItems);\n return cleanup;\n }, [registerNavItems, basePath, t]);\n\n // Register footer items\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'atheletebridge-status',\n label: t('atheletebridge.footer.ready', 'AthleteBridge Ready'),\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems, t]);\n\n return (\n <QueryClientProvider client={queryClient}>\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <AthleteBridgeProvider {...props}>\n <AthleteBridgeRoutes />\n </AthleteBridgeProvider>\n </FeatureFlagProvider>\n </QueryClientProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -5,15 +5,15 @@ import { Loader2 as i } from "lucide-react";
|
|
|
5
5
|
import { Navigate as a, Route as o, Routes as s, useLocation as c } from "react-router-dom";
|
|
6
6
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
7
7
|
//#region src/atheletebridge/AthleteBridgeRoutes.tsx
|
|
8
|
-
var d = r(() => import("./pages/teams/TeamsListPage.js").then((e) => ({ default: e.TeamsListPage }))), f = r(() => import("./pages/teams/TeamDetailPage.js").then((e) => ({ default: e.TeamDetailPage }))), p = r(() => import("./pages/teams/TeamFormPage.js").then((e) => ({ default: e.TeamFormPage }))), m = r(() => import("./pages/fixtures/FixturesListPage.js").then((e) => ({ default: e.FixturesListPage }))), h = r(() => import("./pages/fixtures/FixtureDetailPage.js").then((e) => ({ default: e.FixtureDetailPage }))), g = r(() => import("./pages/fixtures/FixtureFormPage.js").then((e) => ({ default: e.FixtureFormPage }))), _ = r(() => import("./pages/StandingsPage.js").then((e) => ({ default: e.StandingsPage }))), v = r(() => import("./pages/programs/ProgramsListPage.js").then((e) => ({ default: e.ProgramsListPage }))), y = r(() => import("./pages/programs/ProgramDetailPage.js").then((e) => ({ default: e.ProgramDetailPage }))), b = r(() => import("./pages/programs/ProgramFormPage.js").then((e) => ({ default: e.ProgramFormPage }))), x = r(() => import("./pages/sessions/SessionsListPage.js").then((e) => ({ default: e.SessionsListPage }))), S = r(() => import("./pages/sessions/SessionDetailPage.js").then((e) => ({ default: e.SessionDetailPage }))), C = r(() => import("./pages/sessions/SessionFormPage.js").then((e) => ({ default: e.SessionFormPage }))), w = r(() => import("./pages/performance/PerformancePage.js").then((e) => ({ default: e.PerformancePage }))), T = () => /* @__PURE__ */ l("div", {
|
|
8
|
+
var d = r(() => import("./pages/teams/TeamsListPage.js").then((e) => ({ default: e.TeamsListPage }))), f = r(() => import("./pages/teams/TeamDetailPage.js").then((e) => ({ default: e.TeamDetailPage }))), p = r(() => import("./pages/teams/TeamFormPage.js").then((e) => ({ default: e.TeamFormPage }))), m = r(() => import("./pages/fixtures/FixturesListPage.js").then((e) => ({ default: e.FixturesListPage }))), h = r(() => import("./pages/fixtures/FixtureDetailPage.js").then((e) => ({ default: e.FixtureDetailPage }))), g = r(() => import("./pages/fixtures/FixtureFormPage.js").then((e) => ({ default: e.FixtureFormPage }))), _ = r(() => import("./pages/StandingsPage.js").then((e) => ({ default: e.StandingsPage }))), v = r(() => import("./pages/programs/ProgramsListPage.js").then((e) => ({ default: e.ProgramsListPage }))), y = r(() => import("./pages/programs/ProgramDetailPage.js").then((e) => ({ default: e.ProgramDetailPage }))), b = r(() => import("./pages/programs/ProgramFormPage.js").then((e) => ({ default: e.ProgramFormPage }))), x = r(() => import("./pages/sessions/SessionsListPage.js").then((e) => ({ default: e.SessionsListPage }))), S = r(() => import("./pages/sessions/SessionDetailPage.js").then((e) => ({ default: e.SessionDetailPage }))), C = r(() => import("./pages/sessions/SessionFormPage.js").then((e) => ({ default: e.SessionFormPage }))), w = r(() => import("./pages/performance/PerformancePage.js").then((e) => ({ default: e.PerformancePage }))), T = r(() => import("./pages/athletes/AthleteProfilePage.js").then((e) => ({ default: e.AthleteProfilePage }))), E = r(() => import("./pages/analytics/CoachAnalyticsPage.js").then((e) => ({ default: e.CoachAnalyticsPage }))), D = r(() => import("./pages/tournaments/TournamentBracketPage.js").then((e) => ({ default: e.TournamentBracketPage }))), O = () => /* @__PURE__ */ l("div", {
|
|
9
9
|
className: "flex min-h-[400px] items-center justify-center",
|
|
10
10
|
children: /* @__PURE__ */ l(i, { className: "h-8 w-8 animate-spin text-text-secondary" })
|
|
11
|
-
}),
|
|
12
|
-
let { basePath: r, isStandalone: i } = e(),
|
|
13
|
-
return
|
|
11
|
+
}), k = () => {
|
|
12
|
+
let { basePath: r, isStandalone: i } = e(), k = c(), A = r === "/" ? "" : (r ?? "").replace(/\/$/, "");
|
|
13
|
+
return A && !i && !(k.pathname === A || k.pathname.startsWith(A + "/")) ? null : /* @__PURE__ */ l("div", {
|
|
14
14
|
className: "flex min-h-full flex-col",
|
|
15
15
|
children: /* @__PURE__ */ l(n, {
|
|
16
|
-
fallback: /* @__PURE__ */ l(
|
|
16
|
+
fallback: /* @__PURE__ */ l(O, {}),
|
|
17
17
|
children: /* @__PURE__ */ u(s, { children: [
|
|
18
18
|
/* @__PURE__ */ l(o, {
|
|
19
19
|
index: !0,
|
|
@@ -35,6 +35,10 @@ var d = r(() => import("./pages/teams/TeamsListPage.js").then((e) => ({ default:
|
|
|
35
35
|
path: "teams/:id/edit",
|
|
36
36
|
element: /* @__PURE__ */ l(p, {})
|
|
37
37
|
}),
|
|
38
|
+
/* @__PURE__ */ l(o, {
|
|
39
|
+
path: "teams/:teamId/athletes/:memberId",
|
|
40
|
+
element: /* @__PURE__ */ l(T, {})
|
|
41
|
+
}),
|
|
38
42
|
/* @__PURE__ */ l(o, {
|
|
39
43
|
path: "fixtures",
|
|
40
44
|
element: /* @__PURE__ */ l(m, {})
|
|
@@ -83,6 +87,14 @@ var d = r(() => import("./pages/teams/TeamsListPage.js").then((e) => ({ default:
|
|
|
83
87
|
path: "performance",
|
|
84
88
|
element: /* @__PURE__ */ l(w, {})
|
|
85
89
|
}),
|
|
90
|
+
/* @__PURE__ */ l(o, {
|
|
91
|
+
path: "analytics",
|
|
92
|
+
element: /* @__PURE__ */ l(E, {})
|
|
93
|
+
}),
|
|
94
|
+
/* @__PURE__ */ l(o, {
|
|
95
|
+
path: "tournaments",
|
|
96
|
+
element: /* @__PURE__ */ l(D, {})
|
|
97
|
+
}),
|
|
86
98
|
/* @__PURE__ */ l(o, {
|
|
87
99
|
path: "*",
|
|
88
100
|
element: /* @__PURE__ */ l(a, {
|
|
@@ -95,6 +107,6 @@ var d = r(() => import("./pages/teams/TeamsListPage.js").then((e) => ({ default:
|
|
|
95
107
|
});
|
|
96
108
|
};
|
|
97
109
|
//#endregion
|
|
98
|
-
export {
|
|
110
|
+
export { k as AthleteBridgeRoutes };
|
|
99
111
|
|
|
100
112
|
//# sourceMappingURL=AthleteBridgeRoutes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AthleteBridgeRoutes.js","names":[],"sources":["../../src/atheletebridge/AthleteBridgeRoutes.tsx"],"sourcesContent":["/**\n * AthleteBridge Routes\n * @module atheletebridge\n *\n * Real sports-domain routes wired to the deployed `wspace-atheletebridge-svc`\n * GraphQL contract. Dashboard is eager; entity pages are lazy.\n */\n\nimport { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router-dom';\nimport { Loader2 } from 'lucide-react';\nimport { useAthleteBridge } from './context/AthleteBridgeContext';\n\n// Eager — primary landing\nimport { DashboardPage } from './pages/DashboardPage';\n\n// Teams\nconst TeamsListPage = lazy(() =>\n import('./pages/teams/TeamsListPage').then((m) => ({ default: m.TeamsListPage }))\n);\nconst TeamDetailPage = lazy(() =>\n import('./pages/teams/TeamDetailPage').then((m) => ({ default: m.TeamDetailPage }))\n);\nconst TeamFormPage = lazy(() =>\n import('./pages/teams/TeamFormPage').then((m) => ({ default: m.TeamFormPage }))\n);\n\n// Fixtures\nconst FixturesListPage = lazy(() =>\n import('./pages/fixtures/FixturesListPage').then((m) => ({ default: m.FixturesListPage }))\n);\nconst FixtureDetailPage = lazy(() =>\n import('./pages/fixtures/FixtureDetailPage').then((m) => ({ default: m.FixtureDetailPage }))\n);\nconst FixtureFormPage = lazy(() =>\n import('./pages/fixtures/FixtureFormPage').then((m) => ({ default: m.FixtureFormPage }))\n);\n\n// Standings\nconst StandingsPage = lazy(() =>\n import('./pages/StandingsPage').then((m) => ({ default: m.StandingsPage }))\n);\n\n// Programs\nconst ProgramsListPage = lazy(() =>\n import('./pages/programs/ProgramsListPage').then((m) => ({ default: m.ProgramsListPage }))\n);\nconst ProgramDetailPage = lazy(() =>\n import('./pages/programs/ProgramDetailPage').then((m) => ({ default: m.ProgramDetailPage }))\n);\nconst ProgramFormPage = lazy(() =>\n import('./pages/programs/ProgramFormPage').then((m) => ({ default: m.ProgramFormPage }))\n);\n\n// Sessions\nconst SessionsListPage = lazy(() =>\n import('./pages/sessions/SessionsListPage').then((m) => ({ default: m.SessionsListPage }))\n);\nconst SessionDetailPage = lazy(() =>\n import('./pages/sessions/SessionDetailPage').then((m) => ({ default: m.SessionDetailPage }))\n);\nconst SessionFormPage = lazy(() =>\n import('./pages/sessions/SessionFormPage').then((m) => ({ default: m.SessionFormPage }))\n);\n\n// Performance\nconst PerformancePage = lazy(() =>\n import('./pages/performance/PerformancePage').then((m) => ({ default: m.PerformancePage }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n);\n\nexport const AthleteBridgeRoutes: FC = () => {\n const { basePath, isStandalone } = useAthleteBridge();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render when the path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Dashboard */}\n <Route index element={<DashboardPage />} />\n\n {/* Teams */}\n <Route path=\"teams\" element={<TeamsListPage />} />\n <Route path=\"teams/new\" element={<TeamFormPage />} />\n <Route path=\"teams/:id\" element={<TeamDetailPage />} />\n <Route path=\"teams/:id/edit\" element={<TeamFormPage />} />\n\n {/* Fixtures */}\n <Route path=\"fixtures\" element={<FixturesListPage />} />\n <Route path=\"fixtures/new\" element={<FixtureFormPage />} />\n <Route path=\"fixtures/:id\" element={<FixtureDetailPage />} />\n\n {/* Standings */}\n <Route path=\"standings\" element={<StandingsPage />} />\n\n {/* Programs */}\n <Route path=\"programs\" element={<ProgramsListPage />} />\n <Route path=\"programs/new\" element={<ProgramFormPage />} />\n <Route path=\"programs/:id\" element={<ProgramDetailPage />} />\n <Route path=\"programs/:id/edit\" element={<ProgramFormPage />} />\n\n {/* Sessions */}\n <Route path=\"sessions\" element={<SessionsListPage />} />\n <Route path=\"sessions/new\" element={<SessionFormPage />} />\n <Route path=\"sessions/:id\" element={<SessionDetailPage />} />\n\n {/* Performance */}\n <Route path=\"performance\" element={<PerformancePage />} />\n\n {/* Fallback */}\n <Route path=\"*\" element={<Navigate to=\".\" replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AthleteBridgeRoutes.js","names":[],"sources":["../../src/atheletebridge/AthleteBridgeRoutes.tsx"],"sourcesContent":["/**\n * AthleteBridge Routes\n * @module atheletebridge\n *\n * Real sports-domain routes wired to the deployed `wspace-atheletebridge-svc`\n * GraphQL contract. Dashboard is eager; entity pages are lazy.\n */\n\nimport { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router-dom';\nimport { Loader2 } from 'lucide-react';\nimport { useAthleteBridge } from './context/AthleteBridgeContext';\n\n// Eager — primary landing\nimport { DashboardPage } from './pages/DashboardPage';\n\n// Teams\nconst TeamsListPage = lazy(() =>\n import('./pages/teams/TeamsListPage').then((m) => ({ default: m.TeamsListPage }))\n);\nconst TeamDetailPage = lazy(() =>\n import('./pages/teams/TeamDetailPage').then((m) => ({ default: m.TeamDetailPage }))\n);\nconst TeamFormPage = lazy(() =>\n import('./pages/teams/TeamFormPage').then((m) => ({ default: m.TeamFormPage }))\n);\n\n// Fixtures\nconst FixturesListPage = lazy(() =>\n import('./pages/fixtures/FixturesListPage').then((m) => ({ default: m.FixturesListPage }))\n);\nconst FixtureDetailPage = lazy(() =>\n import('./pages/fixtures/FixtureDetailPage').then((m) => ({ default: m.FixtureDetailPage }))\n);\nconst FixtureFormPage = lazy(() =>\n import('./pages/fixtures/FixtureFormPage').then((m) => ({ default: m.FixtureFormPage }))\n);\n\n// Standings\nconst StandingsPage = lazy(() =>\n import('./pages/StandingsPage').then((m) => ({ default: m.StandingsPage }))\n);\n\n// Programs\nconst ProgramsListPage = lazy(() =>\n import('./pages/programs/ProgramsListPage').then((m) => ({ default: m.ProgramsListPage }))\n);\nconst ProgramDetailPage = lazy(() =>\n import('./pages/programs/ProgramDetailPage').then((m) => ({ default: m.ProgramDetailPage }))\n);\nconst ProgramFormPage = lazy(() =>\n import('./pages/programs/ProgramFormPage').then((m) => ({ default: m.ProgramFormPage }))\n);\n\n// Sessions\nconst SessionsListPage = lazy(() =>\n import('./pages/sessions/SessionsListPage').then((m) => ({ default: m.SessionsListPage }))\n);\nconst SessionDetailPage = lazy(() =>\n import('./pages/sessions/SessionDetailPage').then((m) => ({ default: m.SessionDetailPage }))\n);\nconst SessionFormPage = lazy(() =>\n import('./pages/sessions/SessionFormPage').then((m) => ({ default: m.SessionFormPage }))\n);\n\n// Performance\nconst PerformancePage = lazy(() =>\n import('./pages/performance/PerformancePage').then((m) => ({ default: m.PerformancePage }))\n);\n\n// Athlete profile\nconst AthleteProfilePage = lazy(() =>\n import('./pages/athletes/AthleteProfilePage').then((m) => ({ default: m.AthleteProfilePage }))\n);\n\n// Coach analytics\nconst CoachAnalyticsPage = lazy(() =>\n import('./pages/analytics/CoachAnalyticsPage').then((m) => ({ default: m.CoachAnalyticsPage }))\n);\n\n// Tournaments (esports bracket)\nconst TournamentBracketPage = lazy(() =>\n import('./pages/tournaments/TournamentBracketPage').then((m) => ({\n default: m.TournamentBracketPage,\n }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n);\n\nexport const AthleteBridgeRoutes: FC = () => {\n const { basePath, isStandalone } = useAthleteBridge();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render when the path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Dashboard */}\n <Route index element={<DashboardPage />} />\n\n {/* Teams */}\n <Route path=\"teams\" element={<TeamsListPage />} />\n <Route path=\"teams/new\" element={<TeamFormPage />} />\n <Route path=\"teams/:id\" element={<TeamDetailPage />} />\n <Route path=\"teams/:id/edit\" element={<TeamFormPage />} />\n\n {/* Athlete profile (reached from a team roster) */}\n <Route path=\"teams/:teamId/athletes/:memberId\" element={<AthleteProfilePage />} />\n\n {/* Fixtures */}\n <Route path=\"fixtures\" element={<FixturesListPage />} />\n <Route path=\"fixtures/new\" element={<FixtureFormPage />} />\n <Route path=\"fixtures/:id\" element={<FixtureDetailPage />} />\n\n {/* Standings */}\n <Route path=\"standings\" element={<StandingsPage />} />\n\n {/* Programs */}\n <Route path=\"programs\" element={<ProgramsListPage />} />\n <Route path=\"programs/new\" element={<ProgramFormPage />} />\n <Route path=\"programs/:id\" element={<ProgramDetailPage />} />\n <Route path=\"programs/:id/edit\" element={<ProgramFormPage />} />\n\n {/* Sessions */}\n <Route path=\"sessions\" element={<SessionsListPage />} />\n <Route path=\"sessions/new\" element={<SessionFormPage />} />\n <Route path=\"sessions/:id\" element={<SessionDetailPage />} />\n\n {/* Performance */}\n <Route path=\"performance\" element={<PerformancePage />} />\n\n {/* Analytics */}\n <Route path=\"analytics\" element={<CoachAnalyticsPage />} />\n\n {/* Tournaments (esports bracket) */}\n <Route path=\"tournaments\" element={<TournamentBracketPage />} />\n\n {/* Fallback */}\n <Route path=\"*\" element={<Navigate to=\".\" replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { cn as e } from "../utils/cn.js";
|
|
2
|
+
import { gradientForSeed as t, initials as n } from "../utils/identity.js";
|
|
3
|
+
import { SPORT_ICONS as r } from "./domain.js";
|
|
4
|
+
import { useId as i } from "react";
|
|
5
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
6
|
+
//#region src/atheletebridge/components/Crest.tsx
|
|
7
|
+
var s = "M20 1.5 L37 7.5 L37 22 C37 34 29 40.5 20 42.5 C11 40.5 3 34 3 22 L3 7.5 Z", c = ({ name: c, sport: l, size: u = 44, showSportGlyph: d = !0, className: f }) => {
|
|
8
|
+
let [p, m] = t(c || l || "team"), h = n(c, 3), g = `crest-grad-${i().replace(/:/g, "")}`, _ = l ? r[l] : void 0;
|
|
9
|
+
return /* @__PURE__ */ o("span", {
|
|
10
|
+
className: e("relative inline-flex shrink-0 items-center justify-center", f),
|
|
11
|
+
style: {
|
|
12
|
+
width: u,
|
|
13
|
+
height: u * 44 / 40
|
|
14
|
+
},
|
|
15
|
+
role: "img",
|
|
16
|
+
"aria-label": `${c} crest`,
|
|
17
|
+
children: [
|
|
18
|
+
/* @__PURE__ */ o("svg", {
|
|
19
|
+
viewBox: "0 0 40 44",
|
|
20
|
+
width: u,
|
|
21
|
+
height: u * 44 / 40,
|
|
22
|
+
"aria-hidden": "true",
|
|
23
|
+
style: { display: "block" },
|
|
24
|
+
children: [/* @__PURE__ */ a("defs", { children: /* @__PURE__ */ o("linearGradient", {
|
|
25
|
+
id: g,
|
|
26
|
+
x1: "0",
|
|
27
|
+
y1: "0",
|
|
28
|
+
x2: "1",
|
|
29
|
+
y2: "1",
|
|
30
|
+
children: [/* @__PURE__ */ a("stop", {
|
|
31
|
+
offset: "0%",
|
|
32
|
+
style: { stopColor: p }
|
|
33
|
+
}), /* @__PURE__ */ a("stop", {
|
|
34
|
+
offset: "100%",
|
|
35
|
+
style: { stopColor: m }
|
|
36
|
+
})]
|
|
37
|
+
}) }), /* @__PURE__ */ a("path", {
|
|
38
|
+
d: s,
|
|
39
|
+
fill: `url(#${g})`,
|
|
40
|
+
stroke: "var(--color-action-primary-text)",
|
|
41
|
+
strokeOpacity: .22,
|
|
42
|
+
strokeWidth: 1
|
|
43
|
+
})]
|
|
44
|
+
}),
|
|
45
|
+
_ && d ? /* @__PURE__ */ a(_, {
|
|
46
|
+
"aria-hidden": "true",
|
|
47
|
+
className: "pointer-events-none absolute",
|
|
48
|
+
style: {
|
|
49
|
+
width: u * .9,
|
|
50
|
+
height: u * .9,
|
|
51
|
+
color: "var(--color-action-primary-text)",
|
|
52
|
+
opacity: .12
|
|
53
|
+
}
|
|
54
|
+
}) : null,
|
|
55
|
+
/* @__PURE__ */ a("span", {
|
|
56
|
+
"aria-hidden": "true",
|
|
57
|
+
className: "absolute font-bold leading-none tracking-tight text-[var(--color-action-primary-text)]",
|
|
58
|
+
style: {
|
|
59
|
+
fontSize: Math.max(10, u * .34),
|
|
60
|
+
letterSpacing: "-0.02em"
|
|
61
|
+
},
|
|
62
|
+
children: h
|
|
63
|
+
})
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { c as Crest };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=Crest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Crest.js","names":[],"sources":["../../../src/atheletebridge/components/Crest.tsx"],"sourcesContent":["/**\n * Team crest\n * @module atheletebridge/components\n *\n * A deterministic gradient MONOGRAM crest — an honest stand-in for a club logo\n * (the schema has no logo/image field). The gradient + initials are derived\n * stably from the team name, and an optional faint sport glyph reinforces the\n * discipline. Semantic tokens only.\n */\n\nimport { type FC, useId } from 'react';\nimport { cn } from '../utils/cn';\nimport { gradientForSeed, initials } from '../utils/identity';\nimport { SPORT_ICONS } from './domain';\nimport type { AthSport } from '../types';\n\nexport interface CrestProps {\n /** Team name — seeds the gradient and provides the monogram initials. */\n name: string;\n /** Sport — renders a faint watermark glyph and (fallback) seeds the gradient. */\n sport?: AthSport;\n /** Pixel size of the crest (width == height of the shield's bounding box). */\n size?: number;\n /** Show the faint sport glyph watermark (default true when `sport` is set). */\n showSportGlyph?: boolean;\n className?: string;\n}\n\n// Classic shield silhouette in a 40×44 viewBox with a softly-pointed base.\nconst SHIELD_PATH = 'M20 1.5 L37 7.5 L37 22 C37 34 29 40.5 20 42.5 C11 40.5 3 34 3 22 L3 7.5 Z';\n\n/** Deterministic gradient monogram crest for a team (honest logo stand-in). */\nexport const Crest: FC<CrestProps> = ({\n name,\n sport,\n size = 44,\n showSportGlyph = true,\n className,\n}) => {\n const seed = name || sport || 'team';\n const [from, to] = gradientForSeed(seed);\n const mono = initials(name, 3);\n const gradId = `crest-grad-${useId().replace(/:/g, '')}`;\n const SportIcon = sport ? SPORT_ICONS[sport] : undefined;\n\n return (\n <span\n className={cn('relative inline-flex shrink-0 items-center justify-center', className)}\n style={{ width: size, height: (size * 44) / 40 }}\n role=\"img\"\n aria-label={`${name} crest`}\n >\n <svg\n viewBox=\"0 0 40 44\"\n width={size}\n height={(size * 44) / 40}\n aria-hidden=\"true\"\n style={{ display: 'block' }}\n >\n <defs>\n <linearGradient id={gradId} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" style={{ stopColor: from }} />\n <stop offset=\"100%\" style={{ stopColor: to }} />\n </linearGradient>\n </defs>\n <path\n d={SHIELD_PATH}\n fill={`url(#${gradId})`}\n stroke=\"var(--color-action-primary-text)\"\n strokeOpacity={0.22}\n strokeWidth={1}\n />\n </svg>\n\n {SportIcon && showSportGlyph ? (\n <SportIcon\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute\"\n style={{\n width: size * 0.9,\n height: size * 0.9,\n color: 'var(--color-action-primary-text)',\n opacity: 0.12,\n }}\n />\n ) : null}\n\n <span\n aria-hidden=\"true\"\n className=\"absolute font-bold leading-none tracking-tight text-[var(--color-action-primary-text)]\"\n style={{ fontSize: Math.max(10, size * 0.34), letterSpacing: '-0.02em' }}\n >\n {mono}\n </span>\n </span>\n );\n};\n"],"mappings":";;;;;;AA6BA,IAAM,IAAc,6EAGP,KAAyB,EACpC,SACA,UACA,UAAO,IACP,oBAAiB,IACjB,mBACI;CAEJ,IAAM,CAAC,GAAM,KAAM,EADN,KAAQ,KAAS,OACU,EAClC,IAAO,EAAS,GAAM,EAAE,EACxB,IAAS,cAAc,GAAO,CAAC,QAAQ,MAAM,GAAG,IAChD,IAAY,IAAQ,EAAY,KAAS,KAAA;AAE/C,QACE,kBAAC,QAAD;EACE,WAAW,EAAG,6DAA6D,EAAU;EACrF,OAAO;GAAE,OAAO;GAAM,QAAS,IAAO,KAAM;GAAI;EAChD,MAAK;EACL,cAAY,GAAG,EAAK;YAJtB;GAME,kBAAC,OAAD;IACE,SAAQ;IACR,OAAO;IACP,QAAS,IAAO,KAAM;IACtB,eAAY;IACZ,OAAO,EAAE,SAAS,SAAS;cAL7B,CAOE,kBAAC,QAAD,EAAA,UACE,kBAAC,kBAAD;KAAgB,IAAI;KAAQ,IAAG;KAAI,IAAG;KAAI,IAAG;KAAI,IAAG;eAApD,CACE,kBAAC,QAAD;MAAM,QAAO;MAAK,OAAO,EAAE,WAAW,GAAM;MAAI,CAAA,EAChD,kBAAC,QAAD;MAAM,QAAO;MAAO,OAAO,EAAE,WAAW,GAAI;MAAI,CAAA,CACjC;QACZ,CAAA,EACP,kBAAC,QAAD;KACE,GAAG;KACH,MAAM,QAAQ,EAAO;KACrB,QAAO;KACP,eAAe;KACf,aAAa;KACb,CAAA,CACE;;GAEL,KAAa,IACZ,kBAAC,GAAD;IACE,eAAY;IACZ,WAAU;IACV,OAAO;KACL,OAAO,IAAO;KACd,QAAQ,IAAO;KACf,OAAO;KACP,SAAS;KACV;IACD,CAAA,GACA;GAEJ,kBAAC,QAAD;IACE,eAAY;IACZ,WAAU;IACV,OAAO;KAAE,UAAU,KAAK,IAAI,IAAI,IAAO,IAAK;KAAE,eAAe;KAAW;cAEvE;IACI,CAAA;GACF"}
|
|
@@ -1,76 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { FIXTURE_TYPE_LABELS as n } from "./domain.js";
|
|
4
|
-
import { formatDate as r } from "../utils/formatters.js";
|
|
5
|
-
import { CalendarClock as i, MapPin as a } from "lucide-react";
|
|
6
|
-
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
7
|
-
import { GlassCard as c } from "@burdenoff/fe-libs/ui";
|
|
1
|
+
import { Scoreboard as e } from "./Scoreboard.js";
|
|
2
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
8
3
|
//#region src/atheletebridge/components/FixtureCard.tsx
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
tabIndex: 0,
|
|
15
|
-
onClick: u,
|
|
16
|
-
onKeyDown: (e) => {
|
|
17
|
-
(e.key === "Enter" || e.key === " ") && (e.preventDefault(), u?.());
|
|
18
|
-
},
|
|
19
|
-
className: e("cursor-pointer p-5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]"),
|
|
20
|
-
children: [
|
|
21
|
-
/* @__PURE__ */ s("div", {
|
|
22
|
-
className: "flex items-center justify-between gap-3",
|
|
23
|
-
children: [/* @__PURE__ */ o("span", {
|
|
24
|
-
className: "inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
|
|
25
|
-
children: n[l.type]
|
|
26
|
-
}), /* @__PURE__ */ o(t, { status: l.status })]
|
|
27
|
-
}),
|
|
28
|
-
/* @__PURE__ */ s("div", {
|
|
29
|
-
className: "mt-4 flex items-center justify-between gap-3",
|
|
30
|
-
children: [
|
|
31
|
-
/* @__PURE__ */ o("span", {
|
|
32
|
-
className: "flex-1 truncate text-right text-sm font-semibold text-text-primary",
|
|
33
|
-
children: d
|
|
34
|
-
}),
|
|
35
|
-
/* @__PURE__ */ o("span", {
|
|
36
|
-
className: "shrink-0 rounded-lg bg-bg-sunken px-3 py-1 text-sm font-bold tabular-nums text-text-primary",
|
|
37
|
-
children: p ? `${l.homeScore} : ${l.awayScore}` : "vs"
|
|
38
|
-
}),
|
|
39
|
-
/* @__PURE__ */ o("span", {
|
|
40
|
-
className: "flex-1 truncate text-left text-sm font-semibold text-text-primary",
|
|
41
|
-
children: f
|
|
42
|
-
})
|
|
43
|
-
]
|
|
44
|
-
}),
|
|
45
|
-
/* @__PURE__ */ s("div", {
|
|
46
|
-
className: "mt-4 flex flex-wrap items-center gap-x-4 gap-y-1.5 text-xs text-text-secondary",
|
|
47
|
-
children: [
|
|
48
|
-
/* @__PURE__ */ s("span", {
|
|
49
|
-
className: "flex items-center gap-1",
|
|
50
|
-
children: [
|
|
51
|
-
/* @__PURE__ */ o(i, { className: "h-3.5 w-3.5" }),
|
|
52
|
-
" ",
|
|
53
|
-
r(l.scheduledAt)
|
|
54
|
-
]
|
|
55
|
-
}),
|
|
56
|
-
l.venue && /* @__PURE__ */ s("span", {
|
|
57
|
-
className: "flex items-center gap-1 truncate",
|
|
58
|
-
children: [
|
|
59
|
-
/* @__PURE__ */ o(a, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
60
|
-
" ",
|
|
61
|
-
l.venue
|
|
62
|
-
]
|
|
63
|
-
}),
|
|
64
|
-
l.competition && /* @__PURE__ */ o("span", {
|
|
65
|
-
className: "truncate",
|
|
66
|
-
children: l.competition
|
|
67
|
-
})
|
|
68
|
-
]
|
|
69
|
-
})
|
|
70
|
-
]
|
|
71
|
-
});
|
|
72
|
-
};
|
|
4
|
+
var n = ({ fixture: n, onClick: r }) => /* @__PURE__ */ t(e, {
|
|
5
|
+
fixture: n,
|
|
6
|
+
onClick: r,
|
|
7
|
+
variant: "card"
|
|
8
|
+
});
|
|
73
9
|
//#endregion
|
|
74
|
-
export {
|
|
10
|
+
export { n as FixtureCard };
|
|
75
11
|
|
|
76
12
|
//# sourceMappingURL=FixtureCard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FixtureCard.js","names":[],"sources":["../../../src/atheletebridge/components/FixtureCard.tsx"],"sourcesContent":["/**\n * Fixture Card\n * @module atheletebridge/components\n
|
|
1
|
+
{"version":3,"file":"FixtureCard.js","names":[],"sources":["../../../src/atheletebridge/components/FixtureCard.tsx"],"sourcesContent":["/**\n * Fixture Card\n * @module atheletebridge/components\n *\n * A fixture tile rendered as a crest-vs-crest Scoreboard (competition strip →\n * home crest / score-or-vs / away crest → date + venue), replacing the former\n * plain card. Semantic tokens only; winner side tinted from the real score.\n */\n\nimport type { FC } from 'react';\nimport { Scoreboard } from './Scoreboard';\nimport type { AthFixture } from '../types';\n\ninterface FixtureCardProps {\n fixture: AthFixture;\n onClick?: () => void;\n}\n\nexport const FixtureCard: FC<FixtureCardProps> = ({ fixture, onClick }) => (\n <Scoreboard fixture={fixture} onClick={onClick} variant=\"card\" />\n);\n"],"mappings":";;;AAkBA,IAAa,KAAqC,EAAE,YAAS,iBAC3D,kBAAC,GAAD;CAAqB;CAAkB;CAAS,SAAQ;CAAS,CAAA"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { cn as e } from "../utils/cn.js";
|
|
2
|
+
import { StatusBadge as t } from "./StatusBadge.js";
|
|
3
|
+
import { formatDate as n } from "../utils/formatters.js";
|
|
4
|
+
import { MatchupSide as r, ScoreCenter as i, resolveMatchup as a } from "./Scoreboard.js";
|
|
5
|
+
import { CalendarDays as o, ChevronRight as s, Trophy as c } from "lucide-react";
|
|
6
|
+
import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
7
|
+
import { Badge as f } from "@burdenoff/fe-libs/ui";
|
|
8
|
+
//#region src/atheletebridge/components/MatchupRow.tsx
|
|
9
|
+
var p = ({ fixture: e }) => /* @__PURE__ */ d("div", {
|
|
10
|
+
className: "flex flex-col items-end gap-1 text-right",
|
|
11
|
+
children: [/* @__PURE__ */ d("span", {
|
|
12
|
+
className: "flex items-center gap-1 text-xs text-text-secondary",
|
|
13
|
+
children: [/* @__PURE__ */ u(o, {
|
|
14
|
+
className: "h-3.5 w-3.5 shrink-0",
|
|
15
|
+
"aria-hidden": "true"
|
|
16
|
+
}), n(e.scheduledAt)]
|
|
17
|
+
}), /* @__PURE__ */ d("div", {
|
|
18
|
+
className: "flex items-center gap-1.5",
|
|
19
|
+
children: [e.competition ? /* @__PURE__ */ d(f, {
|
|
20
|
+
variant: "secondary",
|
|
21
|
+
className: "gap-1",
|
|
22
|
+
children: [e.type === "CUP" || e.type === "TOURNAMENT" ? /* @__PURE__ */ u(c, {
|
|
23
|
+
className: "h-3 w-3",
|
|
24
|
+
"aria-hidden": "true"
|
|
25
|
+
}) : null, e.competition]
|
|
26
|
+
}) : null, /* @__PURE__ */ u(t, { status: e.status })]
|
|
27
|
+
})]
|
|
28
|
+
}), m = ({ fixture: t, onClick: o, rail: c, className: f }) => {
|
|
29
|
+
let m = a(t), h = !!o, g = c === !1 ? null : c === void 0 ? /* @__PURE__ */ u(p, { fixture: t }) : c, _ = g == null && !m.hasScore ? n(t.scheduledAt) : null, v = /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ d("div", {
|
|
30
|
+
className: "grid flex-1 grid-cols-[1fr_auto_1fr] items-center gap-2 sm:gap-3",
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ u(r, {
|
|
33
|
+
name: m.homeName,
|
|
34
|
+
sport: m.homeSport,
|
|
35
|
+
align: "end",
|
|
36
|
+
won: m.homeWon,
|
|
37
|
+
dimmed: m.awayWon,
|
|
38
|
+
crestSize: 36
|
|
39
|
+
}),
|
|
40
|
+
/* @__PURE__ */ u(i, {
|
|
41
|
+
matchup: m,
|
|
42
|
+
time: _,
|
|
43
|
+
size: "sm"
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ u(r, {
|
|
46
|
+
name: m.awayName,
|
|
47
|
+
sport: m.awaySport,
|
|
48
|
+
align: "start",
|
|
49
|
+
won: m.awayWon,
|
|
50
|
+
dimmed: m.homeWon,
|
|
51
|
+
crestSize: 36
|
|
52
|
+
})
|
|
53
|
+
]
|
|
54
|
+
}), g ? /* @__PURE__ */ d("div", {
|
|
55
|
+
className: "hidden items-center gap-3 border-l border-border-seam pl-3 sm:flex md:pl-4",
|
|
56
|
+
children: [g, h ? /* @__PURE__ */ u(s, {
|
|
57
|
+
className: "h-4 w-4 shrink-0 text-text-muted",
|
|
58
|
+
"aria-hidden": "true"
|
|
59
|
+
}) : null]
|
|
60
|
+
}) : null] });
|
|
61
|
+
return h ? /* @__PURE__ */ u("button", {
|
|
62
|
+
type: "button",
|
|
63
|
+
onClick: o,
|
|
64
|
+
className: e("flex w-full items-center gap-3 rounded-[var(--radius-card)] px-1 py-3 text-left transition-colors hover:bg-bg-sunken focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] md:gap-4", f),
|
|
65
|
+
children: v
|
|
66
|
+
}) : /* @__PURE__ */ u("div", {
|
|
67
|
+
className: e("flex w-full items-center gap-3 py-3 md:gap-4", f),
|
|
68
|
+
children: v
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
export { m as MatchupRow };
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=MatchupRow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MatchupRow.js","names":[],"sources":["../../../src/atheletebridge/components/MatchupRow.tsx"],"sourcesContent":["/**\n * MatchupRow\n * @module atheletebridge/components\n *\n * A compact single-line crest-vs-crest fixture row for the dashboard \"Upcoming\n * fixtures\" feed and team-detail fixture lists. Reuses the Scoreboard building\n * blocks (crest sides + score/vs centerpiece). Semantic tokens only.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { CalendarDays, ChevronRight, Trophy } from 'lucide-react';\nimport { Badge } from '@burdenoff/fe-libs/ui';\nimport { MatchupSide, ScoreCenter, resolveMatchup } from './Scoreboard';\nimport { StatusBadge } from './StatusBadge';\nimport { formatDate } from '../utils/formatters';\nimport { cn } from '../utils/cn';\nimport type { AthFixture } from '../types';\n\nexport interface MatchupRowProps {\n fixture: AthFixture;\n onClick?: () => void;\n /**\n * Right-hand rail content. Defaults to date + competition + status. Pass\n * `false` to hide the rail entirely, or a node to override it.\n */\n rail?: ReactNode | false;\n className?: string;\n}\n\nconst DefaultRail: FC<{ fixture: AthFixture }> = ({ fixture }) => (\n <div className=\"flex flex-col items-end gap-1 text-right\">\n <span className=\"flex items-center gap-1 text-xs text-text-secondary\">\n <CalendarDays className=\"h-3.5 w-3.5 shrink-0\" aria-hidden=\"true\" />\n {formatDate(fixture.scheduledAt)}\n </span>\n <div className=\"flex items-center gap-1.5\">\n {fixture.competition ? (\n <Badge variant=\"secondary\" className=\"gap-1\">\n {fixture.type === 'CUP' || fixture.type === 'TOURNAMENT' ? (\n <Trophy className=\"h-3 w-3\" aria-hidden=\"true\" />\n ) : null}\n {fixture.competition}\n </Badge>\n ) : null}\n <StatusBadge status={fixture.status} />\n </div>\n </div>\n);\n\n/** Compact crest-vs-crest fixture row (dashboard / team-detail feeds). */\nexport const MatchupRow: FC<MatchupRowProps> = ({ fixture, onClick, rail, className }) => {\n const matchup = resolveMatchup(fixture);\n const clickable = Boolean(onClick);\n\n const railNode =\n rail === false ? null : rail !== undefined ? rail : <DefaultRail fixture={fixture} />;\n\n // When there's no rail to carry the date, surface the kickoff under the \"vs\".\n const timeLabel = railNode == null && !matchup.hasScore ? formatDate(fixture.scheduledAt) : null;\n\n const content = (\n <>\n <div className=\"grid flex-1 grid-cols-[1fr_auto_1fr] items-center gap-2 sm:gap-3\">\n <MatchupSide\n name={matchup.homeName}\n sport={matchup.homeSport}\n align=\"end\"\n won={matchup.homeWon}\n dimmed={matchup.awayWon}\n crestSize={36}\n />\n <ScoreCenter matchup={matchup} time={timeLabel} size=\"sm\" />\n <MatchupSide\n name={matchup.awayName}\n sport={matchup.awaySport}\n align=\"start\"\n won={matchup.awayWon}\n dimmed={matchup.homeWon}\n crestSize={36}\n />\n </div>\n {railNode ? (\n <div className=\"hidden items-center gap-3 border-l border-border-seam pl-3 sm:flex md:pl-4\">\n {railNode}\n {clickable ? (\n <ChevronRight className=\"h-4 w-4 shrink-0 text-text-muted\" aria-hidden=\"true\" />\n ) : null}\n </div>\n ) : null}\n </>\n );\n\n if (clickable) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n 'flex w-full items-center gap-3 rounded-[var(--radius-card)] px-1 py-3 text-left transition-colors hover:bg-bg-sunken focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] md:gap-4',\n className\n )}\n >\n {content}\n </button>\n );\n }\n\n return <div className={cn('flex w-full items-center gap-3 py-3 md:gap-4', className)}>{content}</div>;\n};\n"],"mappings":";;;;;;;;AA6BA,IAAM,KAA4C,EAAE,iBAClD,kBAAC,OAAD;CAAK,WAAU;WAAf,CACE,kBAAC,QAAD;EAAM,WAAU;YAAhB,CACE,kBAAC,GAAD;GAAc,WAAU;GAAuB,eAAY;GAAS,CAAA,EACnE,EAAW,EAAQ,YAAY,CAC3B;KACP,kBAAC,OAAD;EAAK,WAAU;YAAf,CACG,EAAQ,cACP,kBAAC,GAAD;GAAO,SAAQ;GAAY,WAAU;aAArC,CACG,EAAQ,SAAS,SAAS,EAAQ,SAAS,eAC1C,kBAAC,GAAD;IAAQ,WAAU;IAAU,eAAY;IAAS,CAAA,GAC/C,MACH,EAAQ,YACH;OACN,MACJ,kBAAC,GAAD,EAAa,QAAQ,EAAQ,QAAU,CAAA,CACnC;IACF;IAIK,KAAmC,EAAE,YAAS,YAAS,SAAM,mBAAgB;CACxF,IAAM,IAAU,EAAe,EAAQ,EACjC,IAAY,EAAQ,GAEpB,IACJ,MAAS,KAAQ,OAAO,MAAS,KAAA,IAAmB,kBAAC,GAAD,EAAsB,YAAW,CAAA,GAAxC,GAGzC,IAAY,KAAY,QAAQ,CAAC,EAAQ,WAAW,EAAW,EAAQ,YAAY,GAAG,MAEtF,IACJ,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD;IACE,MAAM,EAAQ;IACd,OAAO,EAAQ;IACf,OAAM;IACN,KAAK,EAAQ;IACb,QAAQ,EAAQ;IAChB,WAAW;IACX,CAAA;GACF,kBAAC,GAAD;IAAsB;IAAS,MAAM;IAAW,MAAK;IAAO,CAAA;GAC5D,kBAAC,GAAD;IACE,MAAM,EAAQ;IACd,OAAO,EAAQ;IACf,OAAM;IACN,KAAK,EAAQ;IACb,QAAQ,EAAQ;IAChB,WAAW;IACX,CAAA;GACE;KACL,IACC,kBAAC,OAAD;EAAK,WAAU;YAAf,CACG,GACA,IACC,kBAAC,GAAD;GAAc,WAAU;GAAmC,eAAY;GAAS,CAAA,GAC9E,KACA;MACJ,KACH,EAAA,CAAA;AAkBL,QAfI,IAEA,kBAAC,UAAD;EACE,MAAK;EACI;EACT,WAAW,EACT,8NACA,EACD;YAEA;EACM,CAAA,GAIN,kBAAC,OAAD;EAAK,WAAW,EAAG,gDAAgD,EAAU;YAAG;EAAc,CAAA"}
|