diff --git a/maternal-web/app/track/growth/page.tsx b/maternal-web/app/track/growth/page.tsx index 7d206b1..c864280 100644 --- a/maternal-web/app/track/growth/page.tsx +++ b/maternal-web/app/track/growth/page.tsx @@ -45,6 +45,10 @@ import { FormSkeleton, ActivityListSkeleton } from '@/components/common/LoadingS import { motion } from 'framer-motion'; import { useLocalizedDate } from '@/hooks/useLocalizedDate'; import { useTranslation } from '@/hooks/useTranslation'; +import { useDispatch, useSelector } from 'react-redux'; +import { fetchChildren, selectChild, selectSelectedChild, childrenSelectors } from '@/store/slices/childrenSlice'; +import { AppDispatch, RootState } from '@/store/store'; +import ChildSelector from '@/components/common/ChildSelector'; import { UnitInput } from '@/components/forms/UnitInput'; interface GrowthData { @@ -59,8 +63,15 @@ function GrowthTrackPage() { const { user } = useAuth(); const { t } = useTranslation('tracking'); const { formatDistanceToNow } = useLocalizedDate(); - const [children, setChildren] = useState([]); - const [selectedChild, setSelectedChild] = useState(''); + const dispatch = useDispatch(); + + // Redux state + const children = useSelector((state: RootState) => childrenSelectors.selectAll(state)); + const selectedChild = useSelector(selectSelectedChild); + const familyId = useSelector((state: RootState) => state.auth.user?.familyId); + + // Local state + const [selectedChildIds, setSelectedChildIds] = useState([]); // Growth state const [measurementType, setMeasurementType] = useState<'weight' | 'height' | 'head' | 'all'>('weight'); @@ -72,7 +83,6 @@ function GrowthTrackPage() { const [notes, setNotes] = useState(''); const [recentGrowth, setRecentGrowth] = useState([]); const [loading, setLoading] = useState(false); - const [childrenLoading, setChildrenLoading] = useState(true); const [growthLoading, setGrowthLoading] = useState(false); const [error, setError] = useState(null); const [successMessage, setSuccessMessage] = useState(null); @@ -81,46 +91,34 @@ function GrowthTrackPage() { const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [activityToDelete, setActivityToDelete] = useState(null); - const familyId = user?.families?.[0]?.familyId; - - // Load children + // Load children from Redux useEffect(() => { - if (familyId) { - loadChildren(); + if (familyId && children.length === 0) { + dispatch(fetchChildren(familyId)); } - }, [familyId]); + }, [familyId, dispatch, children.length]); - // Load recent growth when child is selected + // Sync selectedChildIds with Redux selectedChild useEffect(() => { - if (selectedChild) { - loadRecentGrowth(); + if (selectedChild?.id) { + setSelectedChildIds([selectedChild.id]); } }, [selectedChild]); - const loadChildren = async () => { - if (!familyId) return; - - try { - setChildrenLoading(true); - const childrenData = await childrenApi.getChildren(familyId); - setChildren(childrenData); - if (childrenData.length > 0) { - setSelectedChild(childrenData[0].id); - } - } catch (err: any) { - console.error('Failed to load children:', err); - setError(err.response?.data?.message || t('common.error.loadChildrenFailed')); - } finally { - setChildrenLoading(false); + // Load recent growth when child is selected + useEffect(() => { + if (selectedChild?.id) { + loadRecentGrowth(); } - }; + }, [selectedChild?.id]); + const loadRecentGrowth = async () => { - if (!selectedChild) return; + if (!selectedChild?.id) return; try { setGrowthLoading(true); - const activities = await trackingApi.getActivities(selectedChild, 'growth'); + const activities = await trackingApi.getActivities(selectedChild.id, 'growth'); const sorted = activities.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime() ).slice(0, 10); @@ -133,7 +131,7 @@ function GrowthTrackPage() { }; const handleSubmit = async () => { - if (!selectedChild) { + if (!selectedChild?.id) { setError(t('common.selectChild')); return; } @@ -167,7 +165,7 @@ function GrowthTrackPage() { ...(measurementType === 'head' || measurementType === 'all' ? { headCircumference } : {}), }; - await trackingApi.createActivity(selectedChild, { + await trackingApi.createActivity(selectedChild.id, { type: 'growth', timestamp: new Date().toISOString(), data, @@ -257,7 +255,9 @@ function GrowthTrackPage() { return details.join(' | '); }; - if (childrenLoading) { + const childrenLoading = useSelector((state: RootState) => state.children.loading); + + if (childrenLoading && children.length === 0) { return ( @@ -338,20 +338,19 @@ function GrowthTrackPage() { {/* Child Selector */} {children.length > 1 && ( - - {t('common.selectChild')} - - + { + setSelectedChildIds(childIds); + if (childIds.length > 0) { + dispatch(selectChild(childIds[0])); + } + }} + mode="single" + label={t('common.selectChild')} + required + /> )} diff --git a/maternal-web/app/track/growth/page.tsx.bak b/maternal-web/app/track/growth/page.tsx.bak new file mode 100644 index 0000000..ce5c8f8 --- /dev/null +++ b/maternal-web/app/track/growth/page.tsx.bak @@ -0,0 +1,562 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { + Box, + Typography, + Button, + Paper, + TextField, + FormControl, + InputLabel, + Select, + MenuItem, + IconButton, + Alert, + CircularProgress, + Card, + CardContent, + Dialog, + DialogTitle, + DialogContent, + DialogContentText, + DialogActions, + Chip, + Snackbar, +} from '@mui/material'; +import { + ArrowBack, + Save, + TrendingUp, + Delete, + Refresh, + ChildCare, + Add, +} from '@mui/icons-material'; +import { useRouter } from 'next/navigation'; +import { AppShell } from '@/components/layouts/AppShell/AppShell'; +import { ProtectedRoute } from '@/components/common/ProtectedRoute'; +import { withErrorBoundary } from '@/components/common/ErrorFallbacks'; +import { useAuth } from '@/lib/auth/AuthContext'; +import { trackingApi, Activity } from '@/lib/api/tracking'; +import { childrenApi, Child } from '@/lib/api/children'; +import { VoiceInputButton } from '@/components/voice/VoiceInputButton'; +import { FormSkeleton, ActivityListSkeleton } from '@/components/common/LoadingSkeletons'; +import { motion } from 'framer-motion'; +import { useLocalizedDate } from '@/hooks/useLocalizedDate'; +import { useTranslation } from '@/hooks/useTranslation'; +import { useDispatch, useSelector } from 'react-redux'; +import { fetchChildren, selectChild, selectSelectedChild, childrenSelectors } from '@/store/slices/childrenSlice'; +import { AppDispatch, RootState } from '@/store/store'; +import ChildSelector from '@/components/common/ChildSelector'; +import { UnitInput } from '@/components/forms/UnitInput'; + +interface GrowthData { + weight?: number; // in kg + height?: number; // in cm + headCircumference?: number; // in cm + measurementType: 'weight' | 'height' | 'head' | 'all'; +} + +function GrowthTrackPage() { + const router = useRouter(); + const { user } = useAuth(); + const { t } = useTranslation('tracking'); + const { formatDistanceToNow } = useLocalizedDate(); + const dispatch = useDispatch(); + + // Redux state + const children = useSelector((state: RootState) => childrenSelectors.selectAll(state)); + const selectedChild = useSelector(selectSelectedChild); + const familyId = useSelector((state: RootState) => state.auth.user?.familyId); + + // Local state + const [selectedChildIds, setSelectedChildIds] = useState([]); + + // Growth state + const [measurementType, setMeasurementType] = useState<'weight' | 'height' | 'head' | 'all'>('weight'); + const [weight, setWeight] = useState(0); + const [height, setHeight] = useState(0); + const [headCircumference, setHeadCircumference] = useState(0); + + // Common state + const [notes, setNotes] = useState(''); + const [recentGrowth, setRecentGrowth] = useState([]); + const [loading, setLoading] = useState(false); + const [childrenLoading, setChildrenLoading] = useState(true); + const [growthLoading, setGrowthLoading] = useState(false); + const [error, setError] = useState(null); + const [successMessage, setSuccessMessage] = useState(null); + + // Delete confirmation dialog + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); + const [activityToDelete, setActivityToDelete] = useState(null); + + const familyId = user?.families?.[0]?.familyId; + + // Load children + useEffect(() => { + if (familyId) { + loadChildren(); + } + }, [familyId]); + + // Load recent growth when child is selected + useEffect(() => { + if (selectedChild) { + loadRecentGrowth(); + } + }, [selectedChild]); + + const loadChildren = async () => { + if (!familyId) return; + + try { + setChildrenLoading(true); + const childrenData = await childrenApi.getChildren(familyId); + setChildren(childrenData); + if (childrenData.length > 0) { + setSelectedChild(childrenData[0].id); + } + } catch (err: any) { + console.error('Failed to load children:', err); + setError(err.response?.data?.message || t('common.error.loadChildrenFailed')); + } finally { + setChildrenLoading(false); + } + }; + + const loadRecentGrowth = async () => { + if (!selectedChild) return; + + try { + setGrowthLoading(true); + const activities = await trackingApi.getActivities(selectedChild, 'growth'); + const sorted = activities.sort((a, b) => + new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime() + ).slice(0, 10); + setRecentGrowth(sorted); + } catch (err: any) { + console.error('Failed to load recent growth:', err); + } finally { + setGrowthLoading(false); + } + }; + + const handleSubmit = async () => { + if (!selectedChild) { + setError(t('common.selectChild')); + return; + } + + // Validation + if (measurementType === 'weight' && weight === 0) { + setError('Please enter weight'); + return; + } + if (measurementType === 'height' && height === 0) { + setError('Please enter height'); + return; + } + if (measurementType === 'head' && headCircumference === 0) { + setError('Please enter head circumference'); + return; + } + if (measurementType === 'all' && (weight === 0 || height === 0 || headCircumference === 0)) { + setError('Please enter all measurements'); + return; + } + + try { + setLoading(true); + setError(null); + + const data: GrowthData = { + measurementType, + ...(measurementType === 'weight' || measurementType === 'all' ? { weight } : {}), + ...(measurementType === 'height' || measurementType === 'all' ? { height } : {}), + ...(measurementType === 'head' || measurementType === 'all' ? { headCircumference } : {}), + }; + + await trackingApi.createActivity(selectedChild, { + type: 'growth', + timestamp: new Date().toISOString(), + data, + notes: notes || undefined, + }); + + setSuccessMessage('Growth measurement logged successfully!'); + + // Reset form + resetForm(); + + // Reload recent growth + await loadRecentGrowth(); + } catch (err: any) { + console.error('Failed to save growth:', err); + setError(err.response?.data?.message || 'Failed to save growth measurement'); + } finally { + setLoading(false); + } + }; + + const resetForm = () => { + setWeight(0); + setHeight(0); + setHeadCircumference(0); + setMeasurementType('weight'); + setNotes(''); + }; + + const handleDeleteClick = (activityId: string) => { + setActivityToDelete(activityId); + setDeleteDialogOpen(true); + }; + + const handleDeleteConfirm = async () => { + if (!activityToDelete) return; + + try { + setLoading(true); + await trackingApi.deleteActivity(activityToDelete); + setSuccessMessage('Growth measurement deleted successfully'); + setDeleteDialogOpen(false); + setActivityToDelete(null); + await loadRecentGrowth(); + } catch (err: any) { + console.error('Failed to delete growth:', err); + setError(err.response?.data?.message || 'Failed to delete growth measurement'); + } finally { + setLoading(false); + } + }; + + const getGrowthDetails = (activity: Activity) => { + const data = activity.data as GrowthData; + const details: string[] = []; + + if (data.weight) { + const measurementSystem = (user?.preferences?.measurementUnit as 'metric' | 'imperial') || 'metric'; + if (measurementSystem === 'imperial') { + const lbs = (data.weight * 2.20462).toFixed(1); + details.push(`Weight: ${lbs} lbs`); + } else { + details.push(`Weight: ${data.weight} kg`); + } + } + + if (data.height) { + const measurementSystem = (user?.preferences?.measurementUnit as 'metric' | 'imperial') || 'metric'; + if (measurementSystem === 'imperial') { + const inches = (data.height * 0.393701).toFixed(1); + details.push(`Height: ${inches} in`); + } else { + details.push(`Height: ${data.height} cm`); + } + } + + if (data.headCircumference) { + const measurementSystem = (user?.preferences?.measurementUnit as 'metric' | 'imperial') || 'metric'; + if (measurementSystem === 'imperial') { + const inches = (data.headCircumference * 0.393701).toFixed(1); + details.push(`Head: ${inches} in`); + } else { + details.push(`Head: ${data.headCircumference} cm`); + } + } + + return details.join(' | '); + }; + + if (childrenLoading) { + return ( + + + + + {t('activities.growth')} + + + + + + + + + ); + } + + if (!familyId || children.length === 0) { + return ( + + + + + + + {t('common.noChildrenAdded')} + + + {t('common.noChildrenMessage')} + + + + + + + ); + } + + return ( + + + + + router.back()} sx={{ mr: 2 }}> + + + + {t('activities.growth')} + + { + console.log('[Growth] Voice transcript:', transcript); + }} + onClassifiedIntent={(result) => { + console.log('[Growth] Intent:', result); + }} + size="medium" + /> + + + {error && ( + setError(null)}> + {error} + + )} + + + {/* Child Selector */} + {children.length > 1 && ( + + + {t('common.selectChild')} + + + + )} + + {/* Main Form */} + + + + + Growth Measurement + + + + + Measurement Type + + + + {(measurementType === 'weight' || measurementType === 'all') && ( + setWeight(metricValue)} + required + sx={{ mb: 3 }} + /> + )} + + {(measurementType === 'height' || measurementType === 'all') && ( + setHeight(metricValue)} + required + sx={{ mb: 3 }} + /> + )} + + {(measurementType === 'head' || measurementType === 'all') && ( + setHeadCircumference(metricValue)} + required + sx={{ mb: 3 }} + /> + )} + + setNotes(e.target.value)} + sx={{ mb: 3 }} + placeholder="Add any notes about this measurement..." + /> + + + + + {/* Recent Growth */} + + + + Recent Growth Measurements + + + + + + + {growthLoading ? ( + + + + ) : recentGrowth.length === 0 ? ( + + + {t('noEntries')} + + + ) : ( + + {recentGrowth.map((activity, index) => ( + + + + + + + + + + + Growth Measurement + + + + + {getGrowthDetails(activity)} + + {activity.notes && ( + + {activity.notes} + + )} + + + handleDeleteClick(activity.id)} + disabled={loading} + > + + + + + + + + ))} + + )} + + + + + {/* Delete Confirmation Dialog */} + setDeleteDialogOpen(false)} + > + {t('deleteEntry')} + + + {t('confirmDelete')} + + + + + + + + + {/* Success Snackbar */} + setSuccessMessage(null)} + message={successMessage} + /> + + + ); +} + +export default withErrorBoundary(GrowthTrackPage, 'form'); diff --git a/maternal-web/app/track/medicine/page.tsx b/maternal-web/app/track/medicine/page.tsx index d2bb7e7..b08b984 100644 --- a/maternal-web/app/track/medicine/page.tsx +++ b/maternal-web/app/track/medicine/page.tsx @@ -53,6 +53,10 @@ import { useTranslation } from '@/hooks/useTranslation'; import { UnitInput } from '@/components/forms/UnitInput'; import { convertVolume, convertTemperature } from '@/lib/utils/unitConversion'; import { MeasurementSystem } from '@/hooks/useLocale'; +import { useDispatch, useSelector } from 'react-redux'; +import { fetchChildren, selectChild, selectSelectedChild, childrenSelectors } from '@/store/slices/childrenSlice'; +import { AppDispatch, RootState } from '@/store/store'; +import ChildSelector from '@/components/common/ChildSelector'; type MedicalActivityType = 'medication' | 'temperature' | 'doctor'; @@ -82,8 +86,15 @@ function MedicalTrackPage() { const { user } = useAuth(); const { t } = useTranslation('tracking'); const { formatDistanceToNow } = useLocalizedDate(); - const [children, setChildren] = useState([]); - const [selectedChild, setSelectedChild] = useState(''); + const dispatch = useDispatch(); + + // Redux state + const children = useSelector((state: RootState) => childrenSelectors.selectAll(state)); + const selectedChild = useSelector(selectSelectedChild); + const familyId = useSelector((state: RootState) => state.auth.user?.familyId); + + // Local state + const [selectedChildIds, setSelectedChildIds] = useState([]); const [activityType, setActivityType] = useState('medication'); // Medication state @@ -109,7 +120,6 @@ function MedicalTrackPage() { const [notes, setNotes] = useState(''); const [recentActivities, setRecentActivities] = useState([]); const [loading, setLoading] = useState(false); - const [childrenLoading, setChildrenLoading] = useState(true); const [activitiesLoading, setActivitiesLoading] = useState(false); const [error, setError] = useState(null); const [successMessage, setSuccessMessage] = useState(null); @@ -118,40 +128,28 @@ function MedicalTrackPage() { const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [activityToDelete, setActivityToDelete] = useState(null); - const familyId = user?.families?.[0]?.familyId; - + // Load children from Redux useEffect(() => { - if (familyId) { - loadChildren(); + if (familyId && children.length === 0) { + dispatch(fetchChildren(familyId)); } - }, [familyId]); + }, [familyId, dispatch, children.length]); + + // Sync selectedChildIds with Redux selectedChild + useEffect(() => { + if (selectedChild?.id) { + setSelectedChildIds([selectedChild.id]); + } + }, [selectedChild]); useEffect(() => { - if (selectedChild) { + if (selectedChild?.id) { loadRecentActivities(); } - }, [selectedChild, activityType]); - - const loadChildren = async () => { - if (!familyId) return; - - try { - setChildrenLoading(true); - const childrenData = await childrenApi.getChildren(familyId); - setChildren(childrenData); - if (childrenData.length > 0) { - setSelectedChild(childrenData[0].id); - } - } catch (err: any) { - console.error('Failed to load children:', err); - setError(err.response?.data?.message || t('common.error.loadChildrenFailed')); - } finally { - setChildrenLoading(false); - } - }; + }, [selectedChild?.id, activityType]); const loadRecentActivities = async () => { - if (!selectedChild) return; + if (!selectedChild?.id) return; try { setActivitiesLoading(true); @@ -159,7 +157,7 @@ function MedicalTrackPage() { const medicalTypes = ['medication', 'temperature', 'doctor', 'medicine']; const allActivities = await Promise.all( medicalTypes.map(type => - trackingApi.getActivities(selectedChild, type as any).catch(() => []) + trackingApi.getActivities(selectedChild.id, type as any).catch(() => []) ) ); @@ -185,7 +183,7 @@ function MedicalTrackPage() { }; const handleSubmit = async () => { - if (!selectedChild) { + if (!selectedChild?.id) { setError(t('common.selectChild')); return; } @@ -242,7 +240,7 @@ function MedicalTrackPage() { }; } - await trackingApi.createActivity(selectedChild, { + await trackingApi.createActivity(selectedChild.id, { type: activityType, timestamp: new Date().toISOString(), data, @@ -369,7 +367,9 @@ function MedicalTrackPage() { return 'Medical Record'; }; - if (childrenLoading) { + const childrenLoading = useSelector((state: RootState) => state.children.loading); + + if (childrenLoading && children.length === 0) { return ( @@ -454,18 +454,21 @@ function MedicalTrackPage() { {/* Child Selector */} - {children.length > 1 && ( + {children.length > 0 && ( - - {t('common.selectChild')} - - + { + setSelectedChildIds(childIds); + if (childIds.length > 0) { + dispatch(selectChild(childIds[0])); + } + }} + mode="single" + label={t('common.selectChild')} + required + /> )} diff --git a/maternal-web/public/sw.js b/maternal-web/public/sw.js index 3403590..90edeca 100644 --- a/maternal-web/public/sw.js +++ b/maternal-web/public/sw.js @@ -1 +1 @@ -if(!self.define){let e,a={};const s=(s,c)=>(s=new URL(s+".js",c).href,a[s]||new Promise(a=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=a,document.head.appendChild(e)}else e=s,importScripts(s),a()}).then(()=>{let e=a[s];if(!e)throw new Error(`Module ${s} didn’t register its module`);return e}));self.define=(c,i)=>{const n=e||("document"in self?document.currentScript.src:"")||location.href;if(a[n])return;let t={};const d=e=>s(e,n),r={module:{uri:n},exports:t,require:d};a[n]=Promise.all(c.map(e=>r[e]||d(e))).then(e=>(i(...e),t))}}define(["./workbox-4d767a27"],function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/app-build-manifest.json",revision:"d82d73aa2009998d3d12c994d8d02285"},{url:"/_next/static/42NBZ0VH8j0-Czsr1zdjy/_buildManifest.js",revision:"003849461a7dd4bad470c5d1d5e5254c"},{url:"/_next/static/42NBZ0VH8j0-Czsr1zdjy/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/1123-1d08a95481112410.js",revision:"1d08a95481112410"},{url:"/_next/static/chunks/1255-b2f7fd83e387a9e1.js",revision:"b2f7fd83e387a9e1"},{url:"/_next/static/chunks/1280-296e0a2b6e9dd9b1.js",revision:"296e0a2b6e9dd9b1"},{url:"/_next/static/chunks/1345-1314f44fc75b1a30.js",revision:"1314f44fc75b1a30"},{url:"/_next/static/chunks/1539-844ad6f5c8b8cb29.js",revision:"844ad6f5c8b8cb29"},{url:"/_next/static/chunks/1543-530e0f57f7af68aa.js",revision:"530e0f57f7af68aa"},{url:"/_next/static/chunks/1746-169ef5faedcd107c.js",revision:"169ef5faedcd107c"},{url:"/_next/static/chunks/1863-7231108310f72246.js",revision:"7231108310f72246"},{url:"/_next/static/chunks/2262-26293d6453fcc927.js",revision:"26293d6453fcc927"},{url:"/_next/static/chunks/2449-b8a41aa6a7d2d3a4.js",revision:"b8a41aa6a7d2d3a4"},{url:"/_next/static/chunks/2619-04bc32f026a0d946.js",revision:"04bc32f026a0d946"},{url:"/_next/static/chunks/3039-0e9bf08230c8ee7b.js",revision:"0e9bf08230c8ee7b"},{url:"/_next/static/chunks/3664-56dedfcaec4aaceb.js",revision:"56dedfcaec4aaceb"},{url:"/_next/static/chunks/3750-c1b23963ed9c2e1f.js",revision:"c1b23963ed9c2e1f"},{url:"/_next/static/chunks/3762-c2c13ecf11b3eabb.js",revision:"c2c13ecf11b3eabb"},{url:"/_next/static/chunks/4409-46ad5ec8e96de263.js",revision:"46ad5ec8e96de263"},{url:"/_next/static/chunks/4546-3be482382b443121.js",revision:"3be482382b443121"},{url:"/_next/static/chunks/4bd1b696-100b9d70ed4e49c1.js",revision:"100b9d70ed4e49c1"},{url:"/_next/static/chunks/5125-c990fc036d2a6ce4.js",revision:"c990fc036d2a6ce4"},{url:"/_next/static/chunks/5380-9004e1ac3565daca.js",revision:"9004e1ac3565daca"},{url:"/_next/static/chunks/5385-7ecda8e4ba984edc.js",revision:"7ecda8e4ba984edc"},{url:"/_next/static/chunks/5482-7535aa0aab02d518.js",revision:"7535aa0aab02d518"},{url:"/_next/static/chunks/6024-09f3a73b85a37fdd.js",revision:"09f3a73b85a37fdd"},{url:"/_next/static/chunks/6088-c165c565edce02be.js",revision:"c165c565edce02be"},{url:"/_next/static/chunks/6107-8fb7b82c50ce5ddd.js",revision:"8fb7b82c50ce5ddd"},{url:"/_next/static/chunks/6191.e178f0fbe1b1be57.js",revision:"e178f0fbe1b1be57"},{url:"/_next/static/chunks/6206-1b3859e1902bcca4.js",revision:"1b3859e1902bcca4"},{url:"/_next/static/chunks/670-a4ca0f366ee779f5.js",revision:"a4ca0f366ee779f5"},{url:"/_next/static/chunks/6847-ce99bc721adda9c4.js",revision:"ce99bc721adda9c4"},{url:"/_next/static/chunks/6873-ff265086321345c8.js",revision:"ff265086321345c8"},{url:"/_next/static/chunks/6886-40f1779ffff00d58.js",revision:"40f1779ffff00d58"},{url:"/_next/static/chunks/6937.f8d44316fed7bc8e.js",revision:"f8d44316fed7bc8e"},{url:"/_next/static/chunks/710-7e96cbf5d461482a.js",revision:"7e96cbf5d461482a"},{url:"/_next/static/chunks/7359-1abfb9f346309354.js",revision:"1abfb9f346309354"},{url:"/_next/static/chunks/7741-0af8b5a61d8e63d3.js",revision:"0af8b5a61d8e63d3"},{url:"/_next/static/chunks/7855-72c79224370eff7b.js",revision:"72c79224370eff7b"},{url:"/_next/static/chunks/787-032067ae978e62a8.js",revision:"032067ae978e62a8"},{url:"/_next/static/chunks/8126-48064e6c5d5794c7.js",revision:"48064e6c5d5794c7"},{url:"/_next/static/chunks/8221-d51102291d5ddaf9.js",revision:"d51102291d5ddaf9"},{url:"/_next/static/chunks/8241-eaf1b9c6054e9ad8.js",revision:"eaf1b9c6054e9ad8"},{url:"/_next/static/chunks/8466-ffa71cea7998f777.js",revision:"ffa71cea7998f777"},{url:"/_next/static/chunks/8544.74f59dd908783038.js",revision:"74f59dd908783038"},{url:"/_next/static/chunks/8746-92ff3ad56eb06d6e.js",revision:"92ff3ad56eb06d6e"},{url:"/_next/static/chunks/8876-26dea77829b2c9a0.js",revision:"26dea77829b2c9a0"},{url:"/_next/static/chunks/9205-f540995b767df00b.js",revision:"f540995b767df00b"},{url:"/_next/static/chunks/9333-b4ce9ef429de942e.js",revision:"b4ce9ef429de942e"},{url:"/_next/static/chunks/9378-4fb7500ab3ba2b2b.js",revision:"4fb7500ab3ba2b2b"},{url:"/_next/static/chunks/9392-2887c5e5703ed90a.js",revision:"2887c5e5703ed90a"},{url:"/_next/static/chunks/9397-40b8ac68e22a4d87.js",revision:"40b8ac68e22a4d87"},{url:"/_next/static/chunks/9515-53e74005e71810bd.js",revision:"53e74005e71810bd"},{url:"/_next/static/chunks/9738-c70b13d86cc3ea77.js",revision:"c70b13d86cc3ea77"},{url:"/_next/static/chunks/9885-e6d3eeda017e8f99.js",revision:"e6d3eeda017e8f99"},{url:"/_next/static/chunks/9958.57780b11643f5bd9.js",revision:"57780b11643f5bd9"},{url:"/_next/static/chunks/app/(auth)/forgot-password/page-fc9fe10cd0da6b8c.js",revision:"fc9fe10cd0da6b8c"},{url:"/_next/static/chunks/app/(auth)/login/page-d9a5d5755d9f403f.js",revision:"d9a5d5755d9f403f"},{url:"/_next/static/chunks/app/(auth)/onboarding/page-e6a3ae4dd1d1c7a1.js",revision:"e6a3ae4dd1d1c7a1"},{url:"/_next/static/chunks/app/(auth)/register/page-7ff36625af4c56d4.js",revision:"7ff36625af4c56d4"},{url:"/_next/static/chunks/app/(auth)/reset-password/page-877e00efc3824f99.js",revision:"877e00efc3824f99"},{url:"/_next/static/chunks/app/_not-found/page-95f11f5fe94340f1.js",revision:"95f11f5fe94340f1"},{url:"/_next/static/chunks/app/ai-assistant/page-48a8ac4a67cba5b6.js",revision:"48a8ac4a67cba5b6"},{url:"/_next/static/chunks/app/analytics/page-c149f1b4d78145ab.js",revision:"c149f1b4d78145ab"},{url:"/_next/static/chunks/app/api/ai/chat/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/auth/login/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/auth/password-reset/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/auth/register/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/health/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/tracking/feeding/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/voice/transcribe/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/children/page-b6fb68596ba09b7a.js",revision:"b6fb68596ba09b7a"},{url:"/_next/static/chunks/app/family/page-3bf65f3ee77dd58f.js",revision:"3bf65f3ee77dd58f"},{url:"/_next/static/chunks/app/history/page-db18505f04d26741.js",revision:"db18505f04d26741"},{url:"/_next/static/chunks/app/insights/page-29f6a4b7950dbea1.js",revision:"29f6a4b7950dbea1"},{url:"/_next/static/chunks/app/layout-87f576c1967238c9.js",revision:"87f576c1967238c9"},{url:"/_next/static/chunks/app/legal/cookies/page-c39a3fa6e27a8806.js",revision:"c39a3fa6e27a8806"},{url:"/_next/static/chunks/app/legal/eula/page-8015f749ab4dd660.js",revision:"8015f749ab4dd660"},{url:"/_next/static/chunks/app/legal/page-3de074f0b9741bc6.js",revision:"3de074f0b9741bc6"},{url:"/_next/static/chunks/app/legal/privacy/page-3cb58024b6fd8e21.js",revision:"3cb58024b6fd8e21"},{url:"/_next/static/chunks/app/legal/terms/page-b5a1c96cae251767.js",revision:"b5a1c96cae251767"},{url:"/_next/static/chunks/app/logout/page-359b0e371fd55c32.js",revision:"359b0e371fd55c32"},{url:"/_next/static/chunks/app/offline/page-28c005360c2b2736.js",revision:"28c005360c2b2736"},{url:"/_next/static/chunks/app/page-ac1ca4d11d13a47e.js",revision:"ac1ca4d11d13a47e"},{url:"/_next/static/chunks/app/settings/page-59fdbbe8a4a0be60.js",revision:"59fdbbe8a4a0be60"},{url:"/_next/static/chunks/app/track/activity/page-4dacb3fe9a9c82b5.js",revision:"4dacb3fe9a9c82b5"},{url:"/_next/static/chunks/app/track/diaper/page-75d581a053150f41.js",revision:"75d581a053150f41"},{url:"/_next/static/chunks/app/track/feeding/page-750011aee5eb8f44.js",revision:"750011aee5eb8f44"},{url:"/_next/static/chunks/app/track/growth/page-a781831c044d3317.js",revision:"a781831c044d3317"},{url:"/_next/static/chunks/app/track/medicine/page-01d9239e3583583e.js",revision:"01d9239e3583583e"},{url:"/_next/static/chunks/app/track/page-dd5ade1eb19ad389.js",revision:"dd5ade1eb19ad389"},{url:"/_next/static/chunks/app/track/sleep/page-b6f274ad52ce293d.js",revision:"b6f274ad52ce293d"},{url:"/_next/static/chunks/framework-bd61ec64032c2de7.js",revision:"bd61ec64032c2de7"},{url:"/_next/static/chunks/main-520e5ec2d671abe7.js",revision:"520e5ec2d671abe7"},{url:"/_next/static/chunks/main-app-02fc3649960ba6c7.js",revision:"02fc3649960ba6c7"},{url:"/_next/static/chunks/pages/_app-4b3fb5e477a0267f.js",revision:"4b3fb5e477a0267f"},{url:"/_next/static/chunks/pages/_error-c970d8b55ace1b48.js",revision:"c970d8b55ace1b48"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-6127c6733c04c605.js",revision:"6127c6733c04c605"},{url:"/_next/static/css/2eb0f1dfbb62d2c0.css",revision:"2eb0f1dfbb62d2c0"},{url:"/_next/static/media/19cfc7226ec3afaa-s.woff2",revision:"9dda5cfc9a46f256d0e131bb535e46f8"},{url:"/_next/static/media/21350d82a1f187e9-s.woff2",revision:"4e2553027f1d60eff32898367dd4d541"},{url:"/_next/static/media/8e9860b6e62d6359-s.woff2",revision:"01ba6c2a184b8cba08b0d57167664d75"},{url:"/_next/static/media/ba9851c3c22cd980-s.woff2",revision:"9e494903d6b0ffec1a1e14d34427d44d"},{url:"/_next/static/media/c5fe6dc8356a8c31-s.woff2",revision:"027a89e9ab733a145db70f09b8a18b42"},{url:"/_next/static/media/df0a9ae256c0569c-s.woff2",revision:"d54db44de5ccb18886ece2fda72bdfe0"},{url:"/_next/static/media/e4af272ccee01ff0-s.p.woff2",revision:"65850a373e258f1c897a2b3d75eb74de"},{url:"/apple-touch-icon.png",revision:"fa2d4d791b90148a18d49bc3bfd7a43a"},{url:"/favicon-16x16.png",revision:"db2da3355c89a6149f6d9ee35ebe6bf3"},{url:"/favicon-32x32.png",revision:"0fd88d56aa584bd0546d05ffc63ef777"},{url:"/icon-192x192.png",revision:"b8ef7f117472c4399cceffea644eb8bd"},{url:"/icons/icon-128x128.png",revision:"96cff3b189d9c1daa1edf470290a90cd"},{url:"/icons/icon-144x144.png",revision:"b627c346c431d7e306005aec5f51baff"},{url:"/icons/icon-152x152.png",revision:"012071830c13d310e51f833baed531af"},{url:"/icons/icon-192x192.png",revision:"dfb20132ddb628237eccd4b0e2ee4aaa"},{url:"/icons/icon-384x384.png",revision:"d032b25376232878a2a29b5688992a8d"},{url:"/icons/icon-512x512.png",revision:"ffda0043571d60956f4e321cba706670"},{url:"/icons/icon-72x72.png",revision:"cc89e74126e7e1109f0186774b3c0d77"},{url:"/icons/icon-96x96.png",revision:"32813cdad5b636fc09eec01c7d705936"},{url:"/manifest.json",revision:"5cbf1ecd33b05c4772688ce7d00c2c23"},{url:"/next.svg",revision:"8e061864f388b47f33a1c3780831193e"},{url:"/vercel.svg",revision:"61c6b19abff40ea7acd577be818f3976"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:a,event:s,state:c})=>a&&"opaqueredirect"===a.type?new Response(a.body,{status:200,statusText:"OK",headers:a.headers}):a}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/api\/.*$/i,new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/.*/i,new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET")}); +if(!self.define){let e,a={};const s=(s,c)=>(s=new URL(s+".js",c).href,a[s]||new Promise(a=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=a,document.head.appendChild(e)}else e=s,importScripts(s),a()}).then(()=>{let e=a[s];if(!e)throw new Error(`Module ${s} didn’t register its module`);return e}));self.define=(c,i)=>{const n=e||("document"in self?document.currentScript.src:"")||location.href;if(a[n])return;let t={};const r=e=>s(e,n),f={module:{uri:n},exports:t,require:r};a[n]=Promise.all(c.map(e=>f[e]||r(e))).then(e=>(i(...e),t))}}define(["./workbox-4d767a27"],function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/app-build-manifest.json",revision:"0b0b2d52af4e48989eab6457b1a9e89d"},{url:"/_next/static/F1dLzW1u8KdxK6TnqB-sB/_buildManifest.js",revision:"003849461a7dd4bad470c5d1d5e5254c"},{url:"/_next/static/F1dLzW1u8KdxK6TnqB-sB/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/1063-f889ee292f8f15b5.js",revision:"f889ee292f8f15b5"},{url:"/_next/static/chunks/1091.c762d795c6885f94.js",revision:"c762d795c6885f94"},{url:"/_next/static/chunks/1255-b2f7fd83e387a9e1.js",revision:"b2f7fd83e387a9e1"},{url:"/_next/static/chunks/1280-296e0a2b6e9dd9b1.js",revision:"296e0a2b6e9dd9b1"},{url:"/_next/static/chunks/1514-a6ed8a01b9885870.js",revision:"a6ed8a01b9885870"},{url:"/_next/static/chunks/1543-530e0f57f7af68aa.js",revision:"530e0f57f7af68aa"},{url:"/_next/static/chunks/1569-55e6fb5a18f58b21.js",revision:"55e6fb5a18f58b21"},{url:"/_next/static/chunks/1863-7231108310f72246.js",revision:"7231108310f72246"},{url:"/_next/static/chunks/2262-26293d6453fcc927.js",revision:"26293d6453fcc927"},{url:"/_next/static/chunks/2506-b6cf4a8108dc7c86.js",revision:"b6cf4a8108dc7c86"},{url:"/_next/static/chunks/2619-04bc32f026a0d946.js",revision:"04bc32f026a0d946"},{url:"/_next/static/chunks/3039-0e9bf08230c8ee7b.js",revision:"0e9bf08230c8ee7b"},{url:"/_next/static/chunks/3127-49a95e7cb556ace3.js",revision:"49a95e7cb556ace3"},{url:"/_next/static/chunks/3183-823e6c5b74284106.js",revision:"823e6c5b74284106"},{url:"/_next/static/chunks/3237-0e9cdda62e9e7c23.js",revision:"0e9cdda62e9e7c23"},{url:"/_next/static/chunks/3664-56dedfcaec4aaceb.js",revision:"56dedfcaec4aaceb"},{url:"/_next/static/chunks/3762-c2c13ecf11b3eabb.js",revision:"c2c13ecf11b3eabb"},{url:"/_next/static/chunks/4232-d460569f72a550dd.js",revision:"d460569f72a550dd"},{url:"/_next/static/chunks/4241-f94f398f62924b88.js",revision:"f94f398f62924b88"},{url:"/_next/static/chunks/4337-7b7eba57ddf5f8f1.js",revision:"7b7eba57ddf5f8f1"},{url:"/_next/static/chunks/4589-ddaaeca1ea084b22.js",revision:"ddaaeca1ea084b22"},{url:"/_next/static/chunks/4bd1b696-100b9d70ed4e49c1.js",revision:"100b9d70ed4e49c1"},{url:"/_next/static/chunks/5125-c990fc036d2a6ce4.js",revision:"c990fc036d2a6ce4"},{url:"/_next/static/chunks/5380-9004e1ac3565daca.js",revision:"9004e1ac3565daca"},{url:"/_next/static/chunks/5385-7ecda8e4ba984edc.js",revision:"7ecda8e4ba984edc"},{url:"/_next/static/chunks/5482-7535aa0aab02d518.js",revision:"7535aa0aab02d518"},{url:"/_next/static/chunks/5761-e5b2862a3b7d7efa.js",revision:"e5b2862a3b7d7efa"},{url:"/_next/static/chunks/6088-c165c565edce02be.js",revision:"c165c565edce02be"},{url:"/_next/static/chunks/670-a4ca0f366ee779f5.js",revision:"a4ca0f366ee779f5"},{url:"/_next/static/chunks/6733-52673e6aade9c963.js",revision:"52673e6aade9c963"},{url:"/_next/static/chunks/6873-ff265086321345c8.js",revision:"ff265086321345c8"},{url:"/_next/static/chunks/6886-40f1779ffff00d58.js",revision:"40f1779ffff00d58"},{url:"/_next/static/chunks/6937.f8d44316fed7bc8e.js",revision:"f8d44316fed7bc8e"},{url:"/_next/static/chunks/710-7e96cbf5d461482a.js",revision:"7e96cbf5d461482a"},{url:"/_next/static/chunks/7359-1abfb9f346309354.js",revision:"1abfb9f346309354"},{url:"/_next/static/chunks/7741-0af8b5a61d8e63d3.js",revision:"0af8b5a61d8e63d3"},{url:"/_next/static/chunks/7855-72c79224370eff7b.js",revision:"72c79224370eff7b"},{url:"/_next/static/chunks/787-032067ae978e62a8.js",revision:"032067ae978e62a8"},{url:"/_next/static/chunks/8077-207d45bccb6d4afe.js",revision:"207d45bccb6d4afe"},{url:"/_next/static/chunks/8221-d51102291d5ddaf9.js",revision:"d51102291d5ddaf9"},{url:"/_next/static/chunks/8241-eaf1b9c6054e9ad8.js",revision:"eaf1b9c6054e9ad8"},{url:"/_next/static/chunks/8412-8ce7440f3599e2d9.js",revision:"8ce7440f3599e2d9"},{url:"/_next/static/chunks/8466-ffa71cea7998f777.js",revision:"ffa71cea7998f777"},{url:"/_next/static/chunks/8544.74f59dd908783038.js",revision:"74f59dd908783038"},{url:"/_next/static/chunks/8746-92ff3ad56eb06d6e.js",revision:"92ff3ad56eb06d6e"},{url:"/_next/static/chunks/8863-7b43165e8b5cae38.js",revision:"7b43165e8b5cae38"},{url:"/_next/static/chunks/9205-f540995b767df00b.js",revision:"f540995b767df00b"},{url:"/_next/static/chunks/9333-b4ce9ef429de942e.js",revision:"b4ce9ef429de942e"},{url:"/_next/static/chunks/9392-2887c5e5703ed90a.js",revision:"2887c5e5703ed90a"},{url:"/_next/static/chunks/9397-40b8ac68e22a4d87.js",revision:"40b8ac68e22a4d87"},{url:"/_next/static/chunks/9515-53e74005e71810bd.js",revision:"53e74005e71810bd"},{url:"/_next/static/chunks/9517-17518b5fffe76114.js",revision:"17518b5fffe76114"},{url:"/_next/static/chunks/9738-c70b13d86cc3ea77.js",revision:"c70b13d86cc3ea77"},{url:"/_next/static/chunks/9958.57780b11643f5bd9.js",revision:"57780b11643f5bd9"},{url:"/_next/static/chunks/app/(auth)/forgot-password/page-294fb4d9f0014755.js",revision:"294fb4d9f0014755"},{url:"/_next/static/chunks/app/(auth)/login/page-d8f5656a139ee55d.js",revision:"d8f5656a139ee55d"},{url:"/_next/static/chunks/app/(auth)/onboarding/page-ea1c1fa93f2bff9a.js",revision:"ea1c1fa93f2bff9a"},{url:"/_next/static/chunks/app/(auth)/register/page-4b000eea571750ea.js",revision:"4b000eea571750ea"},{url:"/_next/static/chunks/app/(auth)/reset-password/page-836751db40b617b5.js",revision:"836751db40b617b5"},{url:"/_next/static/chunks/app/_not-found/page-95f11f5fe94340f1.js",revision:"95f11f5fe94340f1"},{url:"/_next/static/chunks/app/ai-assistant/page-e34646713b4eca94.js",revision:"e34646713b4eca94"},{url:"/_next/static/chunks/app/analytics/page-7a6b08f18da0121a.js",revision:"7a6b08f18da0121a"},{url:"/_next/static/chunks/app/api/ai/chat/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/auth/login/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/auth/password-reset/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/auth/register/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/health/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/tracking/feeding/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/api/voice/transcribe/route-a631d97a33877f8a.js",revision:"a631d97a33877f8a"},{url:"/_next/static/chunks/app/children/page-b6fb68596ba09b7a.js",revision:"b6fb68596ba09b7a"},{url:"/_next/static/chunks/app/family/page-3bf65f3ee77dd58f.js",revision:"3bf65f3ee77dd58f"},{url:"/_next/static/chunks/app/history/page-db18505f04d26741.js",revision:"db18505f04d26741"},{url:"/_next/static/chunks/app/insights/page-d16e2a65278ff204.js",revision:"d16e2a65278ff204"},{url:"/_next/static/chunks/app/layout-aa5009044901debe.js",revision:"aa5009044901debe"},{url:"/_next/static/chunks/app/legal/cookies/page-c39a3fa6e27a8806.js",revision:"c39a3fa6e27a8806"},{url:"/_next/static/chunks/app/legal/eula/page-8015f749ab4dd660.js",revision:"8015f749ab4dd660"},{url:"/_next/static/chunks/app/legal/page-3de074f0b9741bc6.js",revision:"3de074f0b9741bc6"},{url:"/_next/static/chunks/app/legal/privacy/page-3cb58024b6fd8e21.js",revision:"3cb58024b6fd8e21"},{url:"/_next/static/chunks/app/legal/terms/page-b5a1c96cae251767.js",revision:"b5a1c96cae251767"},{url:"/_next/static/chunks/app/logout/page-359b0e371fd55c32.js",revision:"359b0e371fd55c32"},{url:"/_next/static/chunks/app/offline/page-28c005360c2b2736.js",revision:"28c005360c2b2736"},{url:"/_next/static/chunks/app/page-1214f06d5dd3a35e.js",revision:"1214f06d5dd3a35e"},{url:"/_next/static/chunks/app/settings/page-3f8776db67351a35.js",revision:"3f8776db67351a35"},{url:"/_next/static/chunks/app/track/activity/page-50fa2ed16f4a32bf.js",revision:"50fa2ed16f4a32bf"},{url:"/_next/static/chunks/app/track/diaper/page-85088302e7b1c9c7.js",revision:"85088302e7b1c9c7"},{url:"/_next/static/chunks/app/track/feeding/page-42439b02c18559b2.js",revision:"42439b02c18559b2"},{url:"/_next/static/chunks/app/track/growth/page-1bf088f59a517f26.js",revision:"1bf088f59a517f26"},{url:"/_next/static/chunks/app/track/medicine/page-4da694ff59423866.js",revision:"4da694ff59423866"},{url:"/_next/static/chunks/app/track/page-dd5ade1eb19ad389.js",revision:"dd5ade1eb19ad389"},{url:"/_next/static/chunks/app/track/sleep/page-4d919dae273fdc89.js",revision:"4d919dae273fdc89"},{url:"/_next/static/chunks/framework-bd61ec64032c2de7.js",revision:"bd61ec64032c2de7"},{url:"/_next/static/chunks/main-520e5ec2d671abe7.js",revision:"520e5ec2d671abe7"},{url:"/_next/static/chunks/main-app-02fc3649960ba6c7.js",revision:"02fc3649960ba6c7"},{url:"/_next/static/chunks/pages/_app-4b3fb5e477a0267f.js",revision:"4b3fb5e477a0267f"},{url:"/_next/static/chunks/pages/_error-c970d8b55ace1b48.js",revision:"c970d8b55ace1b48"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-1b3d132f0078d9eb.js",revision:"1b3d132f0078d9eb"},{url:"/_next/static/css/2eb0f1dfbb62d2c0.css",revision:"2eb0f1dfbb62d2c0"},{url:"/_next/static/media/19cfc7226ec3afaa-s.woff2",revision:"9dda5cfc9a46f256d0e131bb535e46f8"},{url:"/_next/static/media/21350d82a1f187e9-s.woff2",revision:"4e2553027f1d60eff32898367dd4d541"},{url:"/_next/static/media/8e9860b6e62d6359-s.woff2",revision:"01ba6c2a184b8cba08b0d57167664d75"},{url:"/_next/static/media/ba9851c3c22cd980-s.woff2",revision:"9e494903d6b0ffec1a1e14d34427d44d"},{url:"/_next/static/media/c5fe6dc8356a8c31-s.woff2",revision:"027a89e9ab733a145db70f09b8a18b42"},{url:"/_next/static/media/df0a9ae256c0569c-s.woff2",revision:"d54db44de5ccb18886ece2fda72bdfe0"},{url:"/_next/static/media/e4af272ccee01ff0-s.p.woff2",revision:"65850a373e258f1c897a2b3d75eb74de"},{url:"/apple-touch-icon.png",revision:"fa2d4d791b90148a18d49bc3bfd7a43a"},{url:"/favicon-16x16.png",revision:"db2da3355c89a6149f6d9ee35ebe6bf3"},{url:"/favicon-32x32.png",revision:"0fd88d56aa584bd0546d05ffc63ef777"},{url:"/icon-192x192.png",revision:"b8ef7f117472c4399cceffea644eb8bd"},{url:"/icons/icon-128x128.png",revision:"96cff3b189d9c1daa1edf470290a90cd"},{url:"/icons/icon-144x144.png",revision:"b627c346c431d7e306005aec5f51baff"},{url:"/icons/icon-152x152.png",revision:"012071830c13d310e51f833baed531af"},{url:"/icons/icon-192x192.png",revision:"dfb20132ddb628237eccd4b0e2ee4aaa"},{url:"/icons/icon-384x384.png",revision:"d032b25376232878a2a29b5688992a8d"},{url:"/icons/icon-512x512.png",revision:"ffda0043571d60956f4e321cba706670"},{url:"/icons/icon-72x72.png",revision:"cc89e74126e7e1109f0186774b3c0d77"},{url:"/icons/icon-96x96.png",revision:"32813cdad5b636fc09eec01c7d705936"},{url:"/manifest.json",revision:"5cbf1ecd33b05c4772688ce7d00c2c23"},{url:"/next.svg",revision:"8e061864f388b47f33a1c3780831193e"},{url:"/vercel.svg",revision:"61c6b19abff40ea7acd577be818f3976"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:a,event:s,state:c})=>a&&"opaqueredirect"===a.type?new Response(a.body,{status:200,statusText:"OK",headers:a.headers}):a}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/api\/.*$/i,new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/.*/i,new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET")});