@burdenoff/microfe-mybodyshield 2026.821.2 → 2026.830.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.
Files changed (90) hide show
  1. package/dist/mybodyshield/MyBodyShieldRoot.d.ts.map +1 -1
  2. package/dist/mybodyshield/MyBodyShieldRoot.js +54 -56
  3. package/dist/mybodyshield/MyBodyShieldRoot.js.map +1 -1
  4. package/dist/mybodyshield/MyBodyShieldRoutes.d.ts.map +1 -1
  5. package/dist/mybodyshield/MyBodyShieldRoutes.js +121 -62
  6. package/dist/mybodyshield/MyBodyShieldRoutes.js.map +1 -1
  7. package/dist/mybodyshield/components/EvidenceUpload.d.ts.map +1 -1
  8. package/dist/mybodyshield/components/EvidenceUpload.js +46 -45
  9. package/dist/mybodyshield/components/EvidenceUpload.js.map +1 -1
  10. package/dist/mybodyshield/components/FileLink.d.ts.map +1 -1
  11. package/dist/mybodyshield/components/FileLink.js +27 -18
  12. package/dist/mybodyshield/components/FileLink.js.map +1 -1
  13. package/dist/mybodyshield/components/MybDiscussion.d.ts +1 -1
  14. package/dist/mybodyshield/components/MybDiscussion.d.ts.map +1 -1
  15. package/dist/mybodyshield/components/MybDiscussion.js +59 -58
  16. package/dist/mybodyshield/components/MybDiscussion.js.map +1 -1
  17. package/dist/mybodyshield/components/MybTags.d.ts +1 -1
  18. package/dist/mybodyshield/components/MybTags.d.ts.map +1 -1
  19. package/dist/mybodyshield/components/MybTags.js +83 -74
  20. package/dist/mybodyshield/components/MybTags.js.map +1 -1
  21. package/dist/mybodyshield/components/PageDisabled.d.ts.map +1 -1
  22. package/dist/mybodyshield/components/PageDisabled.js +16 -11
  23. package/dist/mybodyshield/components/PageDisabled.js.map +1 -1
  24. package/dist/mybodyshield/components/Pagination.d.ts.map +1 -1
  25. package/dist/mybodyshield/components/Pagination.js +36 -27
  26. package/dist/mybodyshield/components/Pagination.js.map +1 -1
  27. package/dist/mybodyshield/components/StateViews.d.ts.map +1 -1
  28. package/dist/mybodyshield/components/StateViews.js +42 -34
  29. package/dist/mybodyshield/components/StateViews.js.map +1 -1
  30. package/dist/mybodyshield/components/UserSearchSelect.d.ts.map +1 -1
  31. package/dist/mybodyshield/components/UserSearchSelect.js +66 -68
  32. package/dist/mybodyshield/components/UserSearchSelect.js.map +1 -1
  33. package/dist/mybodyshield/hooks/index.d.ts +1 -0
  34. package/dist/mybodyshield/hooks/index.d.ts.map +1 -1
  35. package/dist/mybodyshield/hooks/index.js +1 -0
  36. package/dist/mybodyshield/hooks/useTr.d.ts +5 -0
  37. package/dist/mybodyshield/hooks/useTr.d.ts.map +1 -0
  38. package/dist/mybodyshield/hooks/useTr.js +12 -0
  39. package/dist/mybodyshield/hooks/useTr.js.map +1 -0
  40. package/dist/mybodyshield/pages/DashboardPage.d.ts.map +1 -1
  41. package/dist/mybodyshield/pages/DashboardPage.js +157 -136
  42. package/dist/mybodyshield/pages/DashboardPage.js.map +1 -1
  43. package/dist/mybodyshield/pages/SettingsPage.d.ts.map +1 -1
  44. package/dist/mybodyshield/pages/SettingsPage.js +50 -59
  45. package/dist/mybodyshield/pages/SettingsPage.js.map +1 -1
  46. package/dist/mybodyshield/pages/_shared/visuals.d.ts +2 -1
  47. package/dist/mybodyshield/pages/_shared/visuals.d.ts.map +1 -1
  48. package/dist/mybodyshield/pages/_shared/visuals.js +91 -81
  49. package/dist/mybodyshield/pages/_shared/visuals.js.map +1 -1
  50. package/dist/mybodyshield/pages/ai/AiControlsPage.d.ts.map +1 -1
  51. package/dist/mybodyshield/pages/ai/AiControlsPage.js +279 -231
  52. package/dist/mybodyshield/pages/ai/AiControlsPage.js.map +1 -1
  53. package/dist/mybodyshield/pages/coaching/CoachingPage.d.ts.map +1 -1
  54. package/dist/mybodyshield/pages/coaching/CoachingPage.js +349 -258
  55. package/dist/mybodyshield/pages/coaching/CoachingPage.js.map +1 -1
  56. package/dist/mybodyshield/pages/goals/GoalsPage.d.ts.map +1 -1
  57. package/dist/mybodyshield/pages/goals/GoalsPage.js +247 -251
  58. package/dist/mybodyshield/pages/goals/GoalsPage.js.map +1 -1
  59. package/dist/mybodyshield/pages/insights/InsightsCharts.d.ts.map +1 -1
  60. package/dist/mybodyshield/pages/insights/InsightsCharts.js +216 -213
  61. package/dist/mybodyshield/pages/insights/InsightsCharts.js.map +1 -1
  62. package/dist/mybodyshield/pages/insights/InsightsPage.d.ts.map +1 -1
  63. package/dist/mybodyshield/pages/insights/InsightsPage.js +327 -220
  64. package/dist/mybodyshield/pages/insights/InsightsPage.js.map +1 -1
  65. package/dist/mybodyshield/pages/nutrition/NutritionPage.d.ts.map +1 -1
  66. package/dist/mybodyshield/pages/nutrition/NutritionPage.js +575 -529
  67. package/dist/mybodyshield/pages/nutrition/NutritionPage.js.map +1 -1
  68. package/dist/mybodyshield/pages/programs/ProgramDetailPage.d.ts.map +1 -1
  69. package/dist/mybodyshield/pages/programs/ProgramDetailPage.js +333 -275
  70. package/dist/mybodyshield/pages/programs/ProgramDetailPage.js.map +1 -1
  71. package/dist/mybodyshield/pages/programs/ProgramsPage.d.ts.map +1 -1
  72. package/dist/mybodyshield/pages/programs/ProgramsPage.js +258 -253
  73. package/dist/mybodyshield/pages/programs/ProgramsPage.js.map +1 -1
  74. package/dist/mybodyshield/pages/progress/ProgressPage.d.ts.map +1 -1
  75. package/dist/mybodyshield/pages/progress/ProgressPage.js +271 -254
  76. package/dist/mybodyshield/pages/progress/ProgressPage.js.map +1 -1
  77. package/dist/mybodyshield/pages/recovery/RecoveryPage.d.ts.map +1 -1
  78. package/dist/mybodyshield/pages/recovery/RecoveryPage.js +206 -200
  79. package/dist/mybodyshield/pages/recovery/RecoveryPage.js.map +1 -1
  80. package/dist/mybodyshield/pages/train/SessionDetailPage.d.ts.map +1 -1
  81. package/dist/mybodyshield/pages/train/SessionDetailPage.js +327 -294
  82. package/dist/mybodyshield/pages/train/SessionDetailPage.js.map +1 -1
  83. package/dist/mybodyshield/pages/train/SessionsPage.d.ts.map +1 -1
  84. package/dist/mybodyshield/pages/train/SessionsPage.js +180 -163
  85. package/dist/mybodyshield/pages/train/SessionsPage.js.map +1 -1
  86. package/dist/mybodyshield/utils/i18n.d.ts +1 -2
  87. package/dist/mybodyshield/utils/i18n.d.ts.map +1 -1
  88. package/dist/mybodyshield/utils/i18n.js +15 -0
  89. package/dist/mybodyshield/utils/i18n.js.map +1 -0
  90. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InsightsCharts.js","names":[],"sources":["../../../../src/mybodyshield/pages/insights/InsightsCharts.tsx"],"sourcesContent":["/**\n * Insights visualisations — recharts-based charts and correlation summary for\n * the MyBodyShield Insights page.\n * @module mybodyshield/pages/insights\n *\n * BOFF-4056: charts are pure presentational components that receive the\n * `MybInsightsDay[]` series already aggregated by the backend. No network\n * calls here.\n */\n\nimport { useMemo, type ReactNode } from 'react';\nimport {\n ResponsiveContainer,\n ComposedChart,\n BarChart,\n Bar,\n Area,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n} from 'recharts';\nimport { Dumbbell, HeartPulse, Moon, Utensils, Scale, Activity } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../../utils/cn';\nimport {\n formatDate,\n formatNumber,\n formatWeight,\n formatGrams,\n formatKcal,\n} from '../../utils/formatters';\nimport { IconChip, MACRO_HUE } from '../_shared/visuals';\nimport type { MybInsightsDay } from '../../types';\n\n// ============================================================================\n// Tokens\n// ============================================================================\n\nconst CHART_COLORS = {\n primary: 'var(--color-action-primary-bg)',\n secondary: 'var(--color-accent-primary)',\n success: 'var(--color-status-success-text)',\n warning: 'var(--color-status-warning-text)',\n error: 'var(--color-status-error-text)',\n chart1: 'var(--color-chart-1)',\n chart2: 'var(--color-chart-2)',\n chart3: 'var(--color-chart-3)',\n chart4: 'var(--color-chart-4)',\n} as const;\n\nconst TOOLTIP_STYLE = {\n background: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-seam)',\n borderRadius: 12,\n color: 'var(--color-text-primary)',\n fontSize: 12,\n};\n\nconst GRID_STYLE = {\n stroke: 'var(--color-border-seam)',\n strokeDasharray: '4 4',\n};\n\nconst AXIS_TICK_STYLE = { fill: 'var(--color-text-tertiary)', fontSize: 12 };\n\n// ============================================================================\n// Chart data shaping\n// ============================================================================\n\ntype ChartRow = {\n label: string;\n date: string;\n sessions: number;\n volumeKg: number;\n readiness: number | null;\n sleepHours: number | null;\n calories: number;\n proteinG: number;\n carbsG: number;\n fatG: number;\n weight: number | null;\n};\n\nfunction useChartData(daily: MybInsightsDay[]): ChartRow[] {\n return useMemo(\n () =>\n [...daily]\n .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime())\n .map((d) => ({\n label: formatDate(d.date),\n date: d.date,\n sessions: d.sessions,\n volumeKg: d.volumeKg,\n readiness: d.readiness ?? null,\n sleepHours: d.sleepHours ?? null,\n calories: d.calories,\n proteinG: d.proteinG,\n carbsG: d.carbsG,\n fatG: d.fatG,\n weight: d.weight ?? null,\n })),\n [daily]\n );\n}\n\nfunction EmptyChart({ message = 'No data for the selected range' }: { message?: string }) {\n return (\n <div className=\"flex h-[240px] flex-col items-center justify-center gap-2 text-center\">\n <Activity className=\"h-8 w-8 text-text-tertiary\" />\n <p className=\"text-sm text-text-secondary\">{message}</p>\n </div>\n );\n}\n\nfunction ChartCard({\n title,\n icon,\n children,\n className,\n}: {\n title: string;\n icon: ReactNode;\n children: ReactNode;\n className?: string;\n}) {\n return (\n <GlassCard treatment=\"plain\" className={cn('overflow-hidden p-5', className)}>\n <div className=\"mb-4 flex items-center gap-2.5\">\n {icon}\n <h3 className=\"text-sm font-semibold text-text-primary\">{title}</h3>\n </div>\n {children}\n </GlassCard>\n );\n}\n\n// ============================================================================\n// Volume + sessions over time\n// ============================================================================\n\nexport function VolumeChart({ daily }: { daily: MybInsightsDay[] }) {\n const data = useChartData(daily);\n\n if (data.length === 0) {\n return (\n <ChartCard\n title=\"Training volume\"\n icon={<IconChip icon={<Dumbbell className=\"h-4 w-4\" />} tint={CHART_COLORS.primary} />}\n >\n <EmptyChart message=\"Log completed sessions to see volume trends.\" />\n </ChartCard>\n );\n }\n\n return (\n <ChartCard\n title=\"Training volume\"\n icon={<IconChip icon={<Dumbbell className=\"h-4 w-4\" />} tint={CHART_COLORS.primary} />}\n >\n <div className=\"h-[260px] w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart data={data} margin={{ top: 4, right: 16, bottom: 4, left: 4 }}>\n <CartesianGrid {...GRID_STYLE} vertical={false} />\n <XAxis\n dataKey=\"label\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n tickMargin={8}\n minTickGap={24}\n />\n <YAxis\n yAxisId=\"left\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={52}\n tickFormatter={(v) => formatWeight(Number(v))}\n />\n <YAxis\n yAxisId=\"right\"\n orientation=\"right\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={36}\n allowDecimals={false}\n />\n <Tooltip\n contentStyle={TOOLTIP_STYLE}\n labelStyle={{ color: 'var(--color-text-tertiary)' }}\n formatter={(value, name) => {\n if (name === 'Volume') return [formatWeight(Number(value)), name];\n return [formatNumber(Number(value)), 'Sessions'];\n }}\n />\n <Legend wrapperStyle={{ fontSize: 12, paddingTop: 8 }} />\n <Bar\n yAxisId=\"left\"\n dataKey=\"volumeKg\"\n name=\"Volume\"\n fill={CHART_COLORS.primary}\n radius={[4, 4, 0, 0]}\n opacity={0.85}\n />\n <Line\n yAxisId=\"right\"\n type=\"monotone\"\n dataKey=\"sessions\"\n name=\"Sessions\"\n stroke={CHART_COLORS.secondary}\n strokeWidth={2.5}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 2, stroke: 'var(--color-bg-surface)' }}\n />\n </ComposedChart>\n </ResponsiveContainer>\n </div>\n </ChartCard>\n );\n}\n\n// ============================================================================\n// Readiness + sleep over time\n// ============================================================================\n\nexport function ReadinessSleepChart({ daily }: { daily: MybInsightsDay[] }) {\n const data = useChartData(daily);\n const hasData = data.some((d) => d.readiness != null || d.sleepHours != null);\n\n if (!hasData) {\n return (\n <ChartCard\n title=\"Recovery & sleep\"\n icon={<IconChip icon={<HeartPulse className=\"h-4 w-4\" />} tint={CHART_COLORS.success} />}\n >\n <EmptyChart message=\"Log recovery entries to see readiness and sleep trends.\" />\n </ChartCard>\n );\n }\n\n return (\n <ChartCard\n title=\"Recovery & sleep\"\n icon={<IconChip icon={<HeartPulse className=\"h-4 w-4\" />} tint={CHART_COLORS.success} />}\n >\n <div className=\"h-[260px] w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart data={data} margin={{ top: 4, right: 16, bottom: 4, left: 4 }}>\n <CartesianGrid {...GRID_STYLE} vertical={false} />\n <XAxis\n dataKey=\"label\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n tickMargin={8}\n minTickGap={24}\n />\n <YAxis\n yAxisId=\"left\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={36}\n domain={[0, 100]}\n hide={!data.some((d) => d.readiness != null)}\n />\n <YAxis\n yAxisId=\"right\"\n orientation=\"right\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={44}\n tickFormatter={(v) => `${formatNumber(Number(v))} h`}\n hide={!data.some((d) => d.sleepHours != null)}\n />\n <Tooltip\n contentStyle={TOOLTIP_STYLE}\n labelStyle={{ color: 'var(--color-text-tertiary)' }}\n formatter={(value, name) => {\n if (name === 'Readiness') return [formatNumber(Number(value)), name];\n return [`${formatNumber(Number(value))} h`, name];\n }}\n />\n <Legend wrapperStyle={{ fontSize: 12, paddingTop: 8 }} />\n <Area\n yAxisId=\"right\"\n type=\"monotone\"\n dataKey=\"sleepHours\"\n name=\"Sleep\"\n stroke={CHART_COLORS.secondary}\n strokeWidth={2}\n fill={CHART_COLORS.secondary}\n fillOpacity={0.12}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 2, stroke: 'var(--color-bg-surface)' }}\n connectNulls\n />\n <Line\n yAxisId=\"left\"\n type=\"monotone\"\n dataKey=\"readiness\"\n name=\"Readiness\"\n stroke={CHART_COLORS.success}\n strokeWidth={2.5}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 2, stroke: 'var(--color-bg-surface)' }}\n connectNulls\n />\n </ComposedChart>\n </ResponsiveContainer>\n </div>\n </ChartCard>\n );\n}\n\n// ============================================================================\n// Macros over time\n// ============================================================================\n\nexport function MacroChart({ daily }: { daily: MybInsightsDay[] }) {\n const data = useChartData(daily);\n\n if (data.length === 0) {\n return (\n <ChartCard\n title=\"Macro adherence\"\n icon={<IconChip icon={<Utensils className=\"h-4 w-4\" />} tint={CHART_COLORS.warning} />}\n >\n <EmptyChart message=\"Log meals to see macro trends.\" />\n </ChartCard>\n );\n }\n\n return (\n <ChartCard\n title=\"Macro adherence\"\n icon={<IconChip icon={<Utensils className=\"h-4 w-4\" />} tint={CHART_COLORS.warning} />}\n >\n <div className=\"h-[260px] w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={data} margin={{ top: 4, right: 16, bottom: 4, left: 4 }}>\n <CartesianGrid {...GRID_STYLE} vertical={false} />\n <XAxis\n dataKey=\"label\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n tickMargin={8}\n minTickGap={24}\n />\n <YAxis\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={44}\n tickFormatter={(v) => formatGrams(Number(v))}\n />\n <Tooltip\n contentStyle={TOOLTIP_STYLE}\n labelStyle={{ color: 'var(--color-text-tertiary)' }}\n formatter={(value, name) => [formatGrams(Number(value)), name as string]}\n />\n <Legend wrapperStyle={{ fontSize: 12, paddingTop: 8 }} />\n <Bar dataKey=\"proteinG\" name=\"Protein\" stackId=\"macros\" fill={MACRO_HUE.protein} />\n <Bar dataKey=\"carbsG\" name=\"Carbs\" stackId=\"macros\" fill={MACRO_HUE.carbs} />\n <Bar dataKey=\"fatG\" name=\"Fat\" stackId=\"macros\" fill={MACRO_HUE.fat} />\n </BarChart>\n </ResponsiveContainer>\n </div>\n </ChartCard>\n );\n}\n\n// ============================================================================\n// Calorie trend\n// ============================================================================\n\nexport function CalorieChart({ daily }: { daily: MybInsightsDay[] }) {\n const data = useChartData(daily);\n\n if (data.length === 0) {\n return (\n <ChartCard\n title=\"Calorie trend\"\n icon={<IconChip icon={<Scale className=\"h-4 w-4\" />} tint={CHART_COLORS.chart1} />}\n >\n <EmptyChart message=\"Log meals to see calorie trends.\" />\n </ChartCard>\n );\n }\n\n return (\n <ChartCard\n title=\"Calorie trend\"\n icon={<IconChip icon={<Scale className=\"h-4 w-4\" />} tint={CHART_COLORS.chart1} />}\n >\n <div className=\"h-[260px] w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart data={data} margin={{ top: 4, right: 16, bottom: 4, left: 4 }}>\n <CartesianGrid {...GRID_STYLE} vertical={false} />\n <XAxis\n dataKey=\"label\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n tickMargin={8}\n minTickGap={24}\n />\n <YAxis\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={52}\n tickFormatter={(v) => formatKcal(Number(v))}\n />\n <Tooltip\n contentStyle={TOOLTIP_STYLE}\n labelStyle={{ color: 'var(--color-text-tertiary)' }}\n formatter={(value) => [formatKcal(Number(value)), 'Calories']}\n />\n <Area\n type=\"monotone\"\n dataKey=\"calories\"\n name=\"Calories\"\n stroke={CHART_COLORS.chart1}\n strokeWidth={2}\n fill={CHART_COLORS.chart1}\n fillOpacity={0.12}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 2, stroke: 'var(--color-bg-surface)' }}\n />\n </ComposedChart>\n </ResponsiveContainer>\n </div>\n </ChartCard>\n );\n}\n\n// ============================================================================\n// Correlation view\n// ============================================================================\n\ntype CorrelationPair = {\n label: string;\n x: string;\n y: string;\n r: number | null;\n n: number;\n};\n\nfunction pearson(xs: (number | null)[], ys: (number | null)[]): { r: number | null; n: number } {\n const pairs = xs\n .map((x, i) => [x, ys[i]] as const)\n .filter(([x, y]) => x != null && y != null) as [number, number][];\n if (pairs.length < 3) return { r: null, n: pairs.length };\n\n const n = pairs.length;\n const sumX = pairs.reduce((a, [x]) => a + x, 0);\n const sumY = pairs.reduce((a, [, y]) => a + y, 0);\n const sumX2 = pairs.reduce((a, [x]) => a + x * x, 0);\n const sumY2 = pairs.reduce((a, [, y]) => a + y * y, 0);\n const sumXY = pairs.reduce((a, [x, y]) => a + x * y, 0);\n\n const denom = Math.sqrt((n * sumX2 - sumX * sumX) * (n * sumY2 - sumY * sumY));\n if (!Number.isFinite(denom) || denom === 0) return { r: null, n };\n\n return { r: (n * sumXY - sumX * sumY) / denom, n };\n}\n\nfunction useCorrelations(daily: MybInsightsDay[]): CorrelationPair[] {\n return useMemo(() => {\n const readiness = daily.map((d) => d.readiness ?? null);\n const sleep = daily.map((d) => d.sleepHours ?? null);\n const volume = daily.map((d) => d.volumeKg);\n const sessions = daily.map((d) => d.sessions);\n const protein = daily.map((d) => d.proteinG);\n const calories = daily.map((d) => d.calories);\n\n const compute = (\n label: string,\n x: string,\n y: string,\n xs: (number | null)[],\n ys: (number | null)[]\n ) => {\n const { r, n } = pearson(xs, ys);\n return { label, x, y, r, n };\n };\n\n return [\n compute('Sleep → Readiness', 'Sleep', 'Readiness', sleep, readiness),\n compute('Volume → Readiness', 'Volume', 'Readiness', volume, readiness),\n compute('Sessions → Sleep', 'Sessions', 'Sleep', sessions, sleep),\n compute('Protein → Readiness', 'Protein', 'Readiness', protein, readiness),\n compute('Calories → Volume', 'Calories', 'Volume', calories, volume),\n ];\n }, [daily]);\n}\n\nfunction correlationLabel(r: number): string {\n const abs = Math.abs(r);\n if (abs >= 0.7) return 'Strong';\n if (abs >= 0.4) return 'Moderate';\n if (abs >= 0.2) return 'Weak';\n return 'None';\n}\n\nfunction correlationColor(r: number): string {\n if (r > 0) return 'var(--color-status-success-text)';\n if (r < 0) return 'var(--color-status-error-text)';\n return 'var(--color-text-tertiary)';\n}\n\nexport function CorrelationView({ daily }: { daily: MybInsightsDay[] }) {\n const correlations = useCorrelations(daily);\n const available = correlations.filter((c) => c.r != null);\n\n if (available.length === 0) {\n return (\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"flex items-center gap-2.5\">\n <IconChip icon={<Moon className=\"h-4 w-4\" />} tint={CHART_COLORS.secondary} />\n <h3 className=\"text-sm font-semibold text-text-primary\">Correlations</h3>\n </div>\n <p className=\"mt-3 text-sm text-text-secondary\">\n Log a few more recovery, training and nutrition days to surface correlations.\n </p>\n </GlassCard>\n );\n }\n\n return (\n <GlassCard treatment=\"plain\" className=\"overflow-hidden p-0\">\n <div className=\"border-b border-border-seam px-5 py-4\">\n <div className=\"flex items-center gap-2.5\">\n <IconChip icon={<Moon className=\"h-4 w-4\" />} tint={CHART_COLORS.secondary} />\n <h3 className=\"text-sm font-semibold text-text-primary\">Correlations</h3>\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n Pearson correlation across the selected range. More data gives more reliable signals.\n </p>\n </div>\n <div className=\"divide-y divide-border-seam/60\">\n {available.map((c) => (\n <div key={c.label} className=\"flex items-center justify-between px-5 py-3\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{c.label}</p>\n <p className=\"text-xs text-text-tertiary\">{c.n} days with both metrics</p>\n </div>\n <div className=\"text-right\">\n <p\n className=\"text-sm font-semibold tabular-nums\"\n style={{ color: correlationColor(c.r ?? 0) }}\n >\n {(c.r ?? 0).toFixed(2)}\n </p>\n <p className=\"text-xs text-text-tertiary\">{correlationLabel(c.r ?? 0)}</p>\n </div>\n </div>\n ))}\n </div>\n </GlassCard>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"InsightsCharts.js","names":[],"sources":["../../../../src/mybodyshield/pages/insights/InsightsCharts.tsx"],"sourcesContent":["/**\n * Insights visualisations — recharts-based charts and correlation summary for\n * the MyBodyShield Insights page.\n * @module mybodyshield/pages/insights\n *\n * BOFF-4056: charts are pure presentational components that receive the\n * `MybInsightsDay[]` series already aggregated by the backend. No network\n * calls here.\n */\n\nimport { useMemo, type ReactNode } from 'react';\nimport {\n ResponsiveContainer,\n ComposedChart,\n BarChart,\n Bar,\n Area,\n Line,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n} from 'recharts';\nimport { Dumbbell, HeartPulse, Moon, Utensils, Scale, Activity } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../../utils/cn';\nimport {\n formatDate,\n formatNumber,\n formatWeight,\n formatGrams,\n formatKcal,\n} from '../../utils/formatters';\nimport { IconChip, MACRO_HUE } from '../_shared/visuals';\nimport { useTr } from '../../hooks';\nimport type { MybInsightsDay } from '../../types';\n\n// ============================================================================\n// Tokens\n// ============================================================================\n\nconst CHART_COLORS = {\n primary: 'var(--color-action-primary-bg)',\n secondary: 'var(--color-accent-primary)',\n success: 'var(--color-status-success-text)',\n warning: 'var(--color-status-warning-text)',\n error: 'var(--color-status-error-text)',\n chart1: 'var(--color-chart-1)',\n chart2: 'var(--color-chart-2)',\n chart3: 'var(--color-chart-3)',\n chart4: 'var(--color-chart-4)',\n} as const;\n\nconst TOOLTIP_STYLE = {\n background: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-seam)',\n borderRadius: 12,\n color: 'var(--color-text-primary)',\n fontSize: 12,\n};\n\nconst GRID_STYLE = {\n stroke: 'var(--color-border-seam)',\n strokeDasharray: '4 4',\n};\n\nconst AXIS_TICK_STYLE = { fill: 'var(--color-text-tertiary)', fontSize: 12 };\n\n// ============================================================================\n// Chart data shaping\n// ============================================================================\n\ntype ChartRow = {\n label: string;\n date: string;\n sessions: number;\n volumeKg: number;\n readiness: number | null;\n sleepHours: number | null;\n calories: number;\n proteinG: number;\n carbsG: number;\n fatG: number;\n weight: number | null;\n};\n\nfunction useChartData(daily: MybInsightsDay[]): ChartRow[] {\n return useMemo(\n () =>\n [...daily]\n .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime())\n .map((d) => ({\n label: formatDate(d.date),\n date: d.date,\n sessions: d.sessions,\n volumeKg: d.volumeKg,\n readiness: d.readiness ?? null,\n sleepHours: d.sleepHours ?? null,\n calories: d.calories,\n proteinG: d.proteinG,\n carbsG: d.carbsG,\n fatG: d.fatG,\n weight: d.weight ?? null,\n })),\n [daily]\n );\n}\n\nfunction EmptyChart({ message = 'No data for the selected range' }: { message?: string }) {\n return (\n <div className=\"flex h-[240px] flex-col items-center justify-center gap-2 text-center\">\n <Activity className=\"h-8 w-8 text-text-tertiary\" />\n <p className=\"text-sm text-text-secondary\">{message}</p>\n </div>\n );\n}\n\nfunction ChartCard({\n title,\n icon,\n children,\n className,\n}: {\n title: string;\n icon: ReactNode;\n children: ReactNode;\n className?: string;\n}) {\n return (\n <GlassCard treatment=\"plain\" className={cn('overflow-hidden p-5', className)}>\n <div className=\"mb-4 flex items-center gap-2.5\">\n {icon}\n <h3 className=\"text-sm font-semibold text-text-primary\">{title}</h3>\n </div>\n {children}\n </GlassCard>\n );\n}\n\n// ============================================================================\n// Volume + sessions over time\n// ============================================================================\n\nexport function VolumeChart({ daily }: { daily: MybInsightsDay[] }) {\n const data = useChartData(daily);\n const t = useTr();\n\n if (data.length === 0) {\n return (\n <ChartCard\n title={t('mybodyshield.pages.insights.volumeChartTitle', 'Training volume')}\n icon={<IconChip icon={<Dumbbell className=\"h-4 w-4\" />} tint={CHART_COLORS.primary} />}\n >\n <EmptyChart\n message={t(\n 'mybodyshield.pages.insights.volumeChartEmpty',\n 'Log completed sessions to see volume trends.'\n )}\n />\n </ChartCard>\n );\n }\n\n return (\n <ChartCard\n title={t('mybodyshield.pages.insights.volumeChartTitle', 'Training volume')}\n icon={<IconChip icon={<Dumbbell className=\"h-4 w-4\" />} tint={CHART_COLORS.primary} />}\n >\n <div className=\"h-[260px] w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart data={data} margin={{ top: 4, right: 16, bottom: 4, left: 4 }}>\n <CartesianGrid {...GRID_STYLE} vertical={false} />\n <XAxis\n dataKey=\"label\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n tickMargin={8}\n minTickGap={24}\n />\n <YAxis\n yAxisId=\"left\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={52}\n tickFormatter={(v) => formatWeight(Number(v))}\n />\n <YAxis\n yAxisId=\"right\"\n orientation=\"right\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={36}\n allowDecimals={false}\n />\n <Tooltip\n contentStyle={TOOLTIP_STYLE}\n labelStyle={{ color: 'var(--color-text-tertiary)' }}\n formatter={(value, name, props) => {\n if (props.dataKey === 'volumeKg') return [formatWeight(Number(value)), name];\n return [formatNumber(Number(value)), name];\n }}\n />\n <Legend wrapperStyle={{ fontSize: 12, paddingTop: 8 }} />\n <Bar\n yAxisId=\"left\"\n dataKey=\"volumeKg\"\n name={t('mybodyshield.common.volume', 'Volume')}\n fill={CHART_COLORS.primary}\n radius={[4, 4, 0, 0]}\n opacity={0.85}\n />\n <Line\n yAxisId=\"right\"\n type=\"monotone\"\n dataKey=\"sessions\"\n name={t('mybodyshield.common.sessions', 'Sessions')}\n stroke={CHART_COLORS.secondary}\n strokeWidth={2.5}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 2, stroke: 'var(--color-bg-surface)' }}\n />\n </ComposedChart>\n </ResponsiveContainer>\n </div>\n </ChartCard>\n );\n}\n\n// ============================================================================\n// Readiness + sleep over time\n// ============================================================================\n\nexport function ReadinessSleepChart({ daily }: { daily: MybInsightsDay[] }) {\n const data = useChartData(daily);\n const t = useTr();\n const hasData = data.some((d) => d.readiness != null || d.sleepHours != null);\n\n if (!hasData) {\n return (\n <ChartCard\n title={t('mybodyshield.pages.insights.readinessSleepChartTitle', 'Recovery & sleep')}\n icon={<IconChip icon={<HeartPulse className=\"h-4 w-4\" />} tint={CHART_COLORS.success} />}\n >\n <EmptyChart\n message={t(\n 'mybodyshield.pages.insights.readinessSleepChartEmpty',\n 'Log recovery entries to see readiness and sleep trends.'\n )}\n />\n </ChartCard>\n );\n }\n\n return (\n <ChartCard\n title={t('mybodyshield.pages.insights.readinessSleepChartTitle', 'Recovery & sleep')}\n icon={<IconChip icon={<HeartPulse className=\"h-4 w-4\" />} tint={CHART_COLORS.success} />}\n >\n <div className=\"h-[260px] w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart data={data} margin={{ top: 4, right: 16, bottom: 4, left: 4 }}>\n <CartesianGrid {...GRID_STYLE} vertical={false} />\n <XAxis\n dataKey=\"label\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n tickMargin={8}\n minTickGap={24}\n />\n <YAxis\n yAxisId=\"left\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={36}\n domain={[0, 100]}\n hide={!data.some((d) => d.readiness != null)}\n />\n <YAxis\n yAxisId=\"right\"\n orientation=\"right\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={44}\n tickFormatter={(v) => `${formatNumber(Number(v))} h`}\n hide={!data.some((d) => d.sleepHours != null)}\n />\n <Tooltip\n contentStyle={TOOLTIP_STYLE}\n labelStyle={{ color: 'var(--color-text-tertiary)' }}\n formatter={(value, name, props) => {\n if (props.dataKey === 'readiness') return [formatNumber(Number(value)), name];\n return [`${formatNumber(Number(value))} h`, name];\n }}\n />\n <Legend wrapperStyle={{ fontSize: 12, paddingTop: 8 }} />\n <Area\n yAxisId=\"right\"\n type=\"monotone\"\n dataKey=\"sleepHours\"\n name={t('mybodyshield.common.sleep', 'Sleep')}\n stroke={CHART_COLORS.secondary}\n strokeWidth={2}\n fill={CHART_COLORS.secondary}\n fillOpacity={0.12}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 2, stroke: 'var(--color-bg-surface)' }}\n connectNulls\n />\n <Line\n yAxisId=\"left\"\n type=\"monotone\"\n dataKey=\"readiness\"\n name={t('mybodyshield.common.readiness', 'Readiness')}\n stroke={CHART_COLORS.success}\n strokeWidth={2.5}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 2, stroke: 'var(--color-bg-surface)' }}\n connectNulls\n />\n </ComposedChart>\n </ResponsiveContainer>\n </div>\n </ChartCard>\n );\n}\n\n// ============================================================================\n// Macros over time\n// ============================================================================\n\nexport function MacroChart({ daily }: { daily: MybInsightsDay[] }) {\n const data = useChartData(daily);\n const t = useTr();\n\n if (data.length === 0) {\n return (\n <ChartCard\n title={t('mybodyshield.pages.insights.macroChartTitle', 'Macro adherence')}\n icon={<IconChip icon={<Utensils className=\"h-4 w-4\" />} tint={CHART_COLORS.warning} />}\n >\n <EmptyChart\n message={t(\n 'mybodyshield.pages.insights.macroChartEmpty',\n 'Log meals to see macro trends.'\n )}\n />\n </ChartCard>\n );\n }\n\n return (\n <ChartCard\n title={t('mybodyshield.pages.insights.macroChartTitle', 'Macro adherence')}\n icon={<IconChip icon={<Utensils className=\"h-4 w-4\" />} tint={CHART_COLORS.warning} />}\n >\n <div className=\"h-[260px] w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={data} margin={{ top: 4, right: 16, bottom: 4, left: 4 }}>\n <CartesianGrid {...GRID_STYLE} vertical={false} />\n <XAxis\n dataKey=\"label\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n tickMargin={8}\n minTickGap={24}\n />\n <YAxis\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={44}\n tickFormatter={(v) => formatGrams(Number(v))}\n />\n <Tooltip\n contentStyle={TOOLTIP_STYLE}\n labelStyle={{ color: 'var(--color-text-tertiary)' }}\n formatter={(value, name) => [formatGrams(Number(value)), name as string]}\n />\n <Legend wrapperStyle={{ fontSize: 12, paddingTop: 8 }} />\n <Bar\n dataKey=\"proteinG\"\n name={t('mybodyshield.common.protein', 'Protein')}\n stackId=\"macros\"\n fill={MACRO_HUE.protein}\n />\n <Bar\n dataKey=\"carbsG\"\n name={t('mybodyshield.common.carbs', 'Carbs')}\n stackId=\"macros\"\n fill={MACRO_HUE.carbs}\n />\n <Bar\n dataKey=\"fatG\"\n name={t('mybodyshield.common.fat', 'Fat')}\n stackId=\"macros\"\n fill={MACRO_HUE.fat}\n />\n </BarChart>\n </ResponsiveContainer>\n </div>\n </ChartCard>\n );\n}\n\n// ============================================================================\n// Calorie trend\n// ============================================================================\n\nexport function CalorieChart({ daily }: { daily: MybInsightsDay[] }) {\n const data = useChartData(daily);\n const t = useTr();\n\n if (data.length === 0) {\n return (\n <ChartCard\n title={t('mybodyshield.pages.insights.calorieChartTitle', 'Calorie trend')}\n icon={<IconChip icon={<Scale className=\"h-4 w-4\" />} tint={CHART_COLORS.chart1} />}\n >\n <EmptyChart\n message={t(\n 'mybodyshield.pages.insights.calorieChartEmpty',\n 'Log meals to see calorie trends.'\n )}\n />\n </ChartCard>\n );\n }\n\n return (\n <ChartCard\n title={t('mybodyshield.pages.insights.calorieChartTitle', 'Calorie trend')}\n icon={<IconChip icon={<Scale className=\"h-4 w-4\" />} tint={CHART_COLORS.chart1} />}\n >\n <div className=\"h-[260px] w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <ComposedChart data={data} margin={{ top: 4, right: 16, bottom: 4, left: 4 }}>\n <CartesianGrid {...GRID_STYLE} vertical={false} />\n <XAxis\n dataKey=\"label\"\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n tickMargin={8}\n minTickGap={24}\n />\n <YAxis\n tickLine={false}\n axisLine={false}\n tick={AXIS_TICK_STYLE}\n width={52}\n tickFormatter={(v) => formatKcal(Number(v))}\n />\n <Tooltip\n contentStyle={TOOLTIP_STYLE}\n labelStyle={{ color: 'var(--color-text-tertiary)' }}\n formatter={(value, name) => [formatKcal(Number(value)), name]}\n />\n <Area\n type=\"monotone\"\n dataKey=\"calories\"\n name={t('mybodyshield.common.calories', 'Calories')}\n stroke={CHART_COLORS.chart1}\n strokeWidth={2}\n fill={CHART_COLORS.chart1}\n fillOpacity={0.12}\n dot={false}\n activeDot={{ r: 4, strokeWidth: 2, stroke: 'var(--color-bg-surface)' }}\n />\n </ComposedChart>\n </ResponsiveContainer>\n </div>\n </ChartCard>\n );\n}\n\n// ============================================================================\n// Correlation view\n// ============================================================================\n\ntype CorrelationPair = {\n labelKey: string;\n labelFallback: string;\n x: string;\n y: string;\n r: number | null;\n n: number;\n};\n\nfunction pearson(xs: (number | null)[], ys: (number | null)[]): { r: number | null; n: number } {\n const pairs = xs\n .map((x, i) => [x, ys[i]] as const)\n .filter(([x, y]) => x != null && y != null) as [number, number][];\n if (pairs.length < 3) return { r: null, n: pairs.length };\n\n const n = pairs.length;\n const sumX = pairs.reduce((a, [x]) => a + x, 0);\n const sumY = pairs.reduce((a, [, y]) => a + y, 0);\n const sumX2 = pairs.reduce((a, [x]) => a + x * x, 0);\n const sumY2 = pairs.reduce((a, [, y]) => a + y * y, 0);\n const sumXY = pairs.reduce((a, [x, y]) => a + x * y, 0);\n\n const denom = Math.sqrt((n * sumX2 - sumX * sumX) * (n * sumY2 - sumY * sumY));\n if (!Number.isFinite(denom) || denom === 0) return { r: null, n };\n\n return { r: (n * sumXY - sumX * sumY) / denom, n };\n}\n\nfunction useCorrelations(daily: MybInsightsDay[]): CorrelationPair[] {\n return useMemo(() => {\n const readiness = daily.map((d) => d.readiness ?? null);\n const sleep = daily.map((d) => d.sleepHours ?? null);\n const volume = daily.map((d) => d.volumeKg);\n const sessions = daily.map((d) => d.sessions);\n const protein = daily.map((d) => d.proteinG);\n const calories = daily.map((d) => d.calories);\n\n const compute = (\n labelKey: string,\n labelFallback: string,\n x: string,\n y: string,\n xs: (number | null)[],\n ys: (number | null)[]\n ) => {\n const { r, n } = pearson(xs, ys);\n return { labelKey, labelFallback, x, y, r, n };\n };\n\n return [\n compute(\n 'mybodyshield.pages.insights.correlationSleepReadiness',\n 'Sleep → Readiness',\n 'Sleep',\n 'Readiness',\n sleep,\n readiness\n ),\n compute(\n 'mybodyshield.pages.insights.correlationVolumeReadiness',\n 'Volume → Readiness',\n 'Volume',\n 'Readiness',\n volume,\n readiness\n ),\n compute(\n 'mybodyshield.pages.insights.correlationSessionsSleep',\n 'Sessions → Sleep',\n 'Sessions',\n 'Sleep',\n sessions,\n sleep\n ),\n compute(\n 'mybodyshield.pages.insights.correlationProteinReadiness',\n 'Protein → Readiness',\n 'Protein',\n 'Readiness',\n protein,\n readiness\n ),\n compute(\n 'mybodyshield.pages.insights.correlationCaloriesVolume',\n 'Calories → Volume',\n 'Calories',\n 'Volume',\n calories,\n volume\n ),\n ];\n }, [daily]);\n}\n\nfunction correlationLabel(r: number, t: ReturnType<typeof useTr>): string {\n const abs = Math.abs(r);\n if (abs >= 0.7) return t('mybodyshield.pages.insights.correlationStrong', 'Strong');\n if (abs >= 0.4) return t('mybodyshield.pages.insights.correlationModerate', 'Moderate');\n if (abs >= 0.2) return t('mybodyshield.pages.insights.correlationWeak', 'Weak');\n return t('mybodyshield.pages.insights.correlationNone', 'None');\n}\n\nfunction correlationColor(r: number): string {\n if (r > 0) return 'var(--color-status-success-text)';\n if (r < 0) return 'var(--color-status-error-text)';\n return 'var(--color-text-tertiary)';\n}\n\nexport function CorrelationView({ daily }: { daily: MybInsightsDay[] }) {\n const t = useTr();\n const correlations = useCorrelations(daily);\n const available = correlations.filter((c) => c.r != null);\n\n if (available.length === 0) {\n return (\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"flex items-center gap-2.5\">\n <IconChip icon={<Moon className=\"h-4 w-4\" />} tint={CHART_COLORS.secondary} />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t('mybodyshield.pages.insights.correlationsTitle', 'Correlations')}\n </h3>\n </div>\n <p className=\"mt-3 text-sm text-text-secondary\">\n {t(\n 'mybodyshield.pages.insights.correlationsEmpty',\n 'Log a few more recovery, training and nutrition days to surface correlations.'\n )}\n </p>\n </GlassCard>\n );\n }\n\n return (\n <GlassCard treatment=\"plain\" className=\"overflow-hidden p-0\">\n <div className=\"border-b border-border-seam px-5 py-4\">\n <div className=\"flex items-center gap-2.5\">\n <IconChip icon={<Moon className=\"h-4 w-4\" />} tint={CHART_COLORS.secondary} />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t('mybodyshield.pages.insights.correlationsTitle', 'Correlations')}\n </h3>\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {t(\n 'mybodyshield.pages.insights.correlationsSubtitle',\n 'Pearson correlation across the selected range. More data gives more reliable signals.'\n )}\n </p>\n </div>\n <div className=\"divide-y divide-border-seam/60\">\n {available.map((c) => (\n <div key={c.labelKey} className=\"flex items-center justify-between px-5 py-3\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {t(c.labelKey, c.labelFallback)}\n </p>\n <p className=\"text-xs text-text-tertiary\">\n {t(\n 'mybodyshield.pages.insights.correlationDaysWithMetrics',\n '{{count}} days with both metrics',\n { count: c.n }\n )}\n </p>\n </div>\n <div className=\"text-right\">\n <p\n className=\"text-sm font-semibold tabular-nums\"\n style={{ color: correlationColor(c.r ?? 0) }}\n >\n {(c.r ?? 0).toFixed(2)}\n </p>\n <p className=\"text-xs text-text-tertiary\">{correlationLabel(c.r ?? 0, t)}</p>\n </div>\n </div>\n ))}\n </div>\n </GlassCard>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"InsightsPage.d.ts","sourceRoot":"","sources":["../../../../src/mybodyshield/pages/insights/InsightsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAqEH,wBAAgB,YAAY,gCAsR3B"}
1
+ {"version":3,"file":"InsightsPage.d.ts","sourceRoot":"","sources":["../../../../src/mybodyshield/pages/insights/InsightsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0LH,wBAAgB,YAAY,gCAgV3B"}