]*\ssrc\s*=\s*["\']([^"\']+)["\']#i', $raw, $m)) { $u = html_entity_decode($m[1], ENT_QUOTES | ENT_HTML5, 'UTF-8'); return $allowed($u) ? $u : null; } return null; } $embedUrl = familyHub_google_calendar_embed_url($rawEmbed); $fromIdOnly = false; if ($embedUrl === null && $calId !== '' && $calId !== 'your_calendar_id_here') { $embedUrl = 'https://calendar.google.com/calendar/embed?src=' . rawurlencode($calId); $fromIdOnly = true; } [$rangeStart, $rangeEnd] = hubCalendarDefaultAgendaRange($familySettings); $events = hubCalendarAgendaEvents($rangeStart, $rangeEnd, $people, $familySettings); [, $tzLocal] = familyHubCalendarContext($familySettings); $todayYmd = familyHubTodayYmdInTz($tzLocal); $twoWayMerge = !empty($familySettings['calendar_two_way_google']); $eventsByDate = []; foreach ($events as $ev) { $d = (string) ($ev['date'] ?? ''); if ($d === '') { continue; } if (!isset($eventsByDate[$d])) { $eventsByDate[$d] = []; } $eventsByDate[$d][] = $ev; } ksort($eventsByDate); $iconByType = [ 'chore' => 'fa-tasks', 'meal' => 'fa-utensils', 'grocery_due' => 'fa-cart-shopping', 'expense' => 'fa-coins', 'bill_day' => 'fa-file-invoice-dollar', ]; ?>