@sonordev/site-kit 3.0.5 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +107 -0
- package/agent-manifest.json +377 -0
- package/dist/AnalyticsProvider-CD635CHQ.mjs +8 -0
- package/dist/{AnalyticsProvider-MLT26JRP.mjs.map → AnalyticsProvider-CD635CHQ.mjs.map} +1 -1
- package/dist/AnalyticsProvider-WK2Z6AIN.js +29 -0
- package/dist/{AnalyticsProvider-WTOGN7LV.js.map → AnalyticsProvider-WK2Z6AIN.js.map} +1 -1
- package/dist/BlogPostFaqSection-4AD2NIGG.js +13 -0
- package/dist/{BlogPostFaqSection-H556RV62.js.map → BlogPostFaqSection-4AD2NIGG.js.map} +1 -1
- package/dist/{BlogPostFaqSection-VSHOKKUD.mjs → BlogPostFaqSection-TU6YEC7P.mjs} +3 -3
- package/dist/{BlogPostFaqSection-VSHOKKUD.mjs.map → BlogPostFaqSection-TU6YEC7P.mjs.map} +1 -1
- package/dist/ChatWidget-AIOOZY6H.js +17 -0
- package/dist/{ChatWidget-MAL7FB4M.js.map → ChatWidget-AIOOZY6H.js.map} +1 -1
- package/dist/ChatWidget-UAAWDBNS.mjs +8 -0
- package/dist/{ChatWidget-QPZTPSPE.mjs.map → ChatWidget-UAAWDBNS.mjs.map} +1 -1
- package/dist/EngageWidget-EZ5T6H3K.mjs +7 -0
- package/dist/{EngageWidget-IPBUA4DW.mjs.map → EngageWidget-EZ5T6H3K.mjs.map} +1 -1
- package/dist/EngageWidget-RWVWW56C.js +16 -0
- package/dist/{EngageWidget-N3CABK3L.js.map → EngageWidget-RWVWW56C.js.map} +1 -1
- package/dist/{SignalCore-4MDIJUAP.mjs → SignalCore-4B4RNYLV.mjs} +60 -47
- package/dist/SignalCore-4B4RNYLV.mjs.map +1 -0
- package/dist/{SignalCore-ZMFUE3N4.js → SignalCore-AECW2JFP.js} +60 -47
- package/dist/SignalCore-AECW2JFP.js.map +1 -0
- package/dist/SitemapSync-AICU4SSV.js +15 -0
- package/dist/{SitemapSync-FUCH6Y6J.js.map → SitemapSync-AICU4SSV.js.map} +1 -1
- package/dist/SitemapSync-CIZCAZXK.mjs +6 -0
- package/dist/{SitemapSync-LCSPRAWU.mjs.map → SitemapSync-CIZCAZXK.mjs.map} +1 -1
- package/dist/analytics/index.js +11 -9
- package/dist/analytics/index.mjs +4 -2
- package/dist/blog/index.js +12 -12
- package/dist/blog/index.mjs +2 -2
- package/dist/blog/server-ui.js +5 -5
- package/dist/blog/server-ui.mjs +1 -1
- package/dist/brand.css +8 -3
- package/dist/{chunk-QTWA44S3.mjs → chunk-2WYEJOGA.mjs} +7 -8
- package/dist/chunk-2WYEJOGA.mjs.map +1 -0
- package/dist/{chunk-AN4ATCYQ.mjs → chunk-45QHDA7Q.mjs} +3 -3
- package/dist/{chunk-AN4ATCYQ.mjs.map → chunk-45QHDA7Q.mjs.map} +1 -1
- package/dist/{chunk-RI6JZUAE.js → chunk-4FBV5BJW.js} +7 -8
- package/dist/chunk-4FBV5BJW.js.map +1 -0
- package/dist/{chunk-YJWKHCOB.js → chunk-4NTMIU6V.js} +13 -11
- package/dist/chunk-4NTMIU6V.js.map +1 -0
- package/dist/{chunk-YFGKIKXA.mjs → chunk-57QV6NIY.mjs} +3 -3
- package/dist/{chunk-YFGKIKXA.mjs.map → chunk-57QV6NIY.mjs.map} +1 -1
- package/dist/chunk-5OWZUNNE.js +102 -0
- package/dist/chunk-5OWZUNNE.js.map +1 -0
- package/dist/{chunk-EUDTPXUI.mjs → chunk-6HPNFWSC.mjs} +3 -3
- package/dist/{chunk-EUDTPXUI.mjs.map → chunk-6HPNFWSC.mjs.map} +1 -1
- package/dist/{chunk-FT5JNCD4.mjs → chunk-AB2VYIYU.mjs} +11 -11
- package/dist/{chunk-FT5JNCD4.mjs.map → chunk-AB2VYIYU.mjs.map} +1 -1
- package/dist/{chunk-I5TJIESQ.js → chunk-BMKZHXWQ.js} +11 -11
- package/dist/{chunk-I5TJIESQ.js.map → chunk-BMKZHXWQ.js.map} +1 -1
- package/dist/{chunk-KHFNPPOX.mjs → chunk-DSRPKUQI.mjs} +6 -6
- package/dist/{chunk-KHFNPPOX.mjs.map → chunk-DSRPKUQI.mjs.map} +1 -1
- package/dist/chunk-EAASMIWX.js +258 -0
- package/dist/chunk-EAASMIWX.js.map +1 -0
- package/dist/{chunk-T4QBSRA4.mjs → chunk-EIWRPGOK.mjs} +37 -60
- package/dist/chunk-EIWRPGOK.mjs.map +1 -0
- package/dist/{chunk-O7E6QVK3.js → chunk-GCDVKOSM.js} +3 -3
- package/dist/{chunk-O7E6QVK3.js.map → chunk-GCDVKOSM.js.map} +1 -1
- package/dist/{chunk-KMZ527EM.mjs → chunk-GN62H6EG.mjs} +34 -8
- package/dist/chunk-GN62H6EG.mjs.map +1 -0
- package/dist/{chunk-UJQYSVYV.js → chunk-GQF6QAQS.js} +4 -4
- package/dist/{chunk-UJQYSVYV.js.map → chunk-GQF6QAQS.js.map} +1 -1
- package/dist/{chunk-MLJXELPA.js → chunk-HAZN43I6.js} +60 -94
- package/dist/chunk-HAZN43I6.js.map +1 -0
- package/dist/chunk-LZSCCJ4O.mjs +253 -0
- package/dist/chunk-LZSCCJ4O.mjs.map +1 -0
- package/dist/{chunk-TCVHI3JP.mjs → chunk-N2HR2E4Z.mjs} +60 -92
- package/dist/chunk-N2HR2E4Z.mjs.map +1 -0
- package/dist/{chunk-VCWSSGCU.js → chunk-NAVDN4AE.js} +7 -7
- package/dist/{chunk-VCWSSGCU.js.map → chunk-NAVDN4AE.js.map} +1 -1
- package/dist/chunk-NDHFU4HV.mjs +97 -0
- package/dist/chunk-NDHFU4HV.mjs.map +1 -0
- package/dist/{chunk-PST3NOEM.mjs → chunk-O237KKCX.mjs} +4 -4
- package/dist/{chunk-PST3NOEM.mjs.map → chunk-O237KKCX.mjs.map} +1 -1
- package/dist/{chunk-5AESOLXS.mjs → chunk-OTY7EWET.mjs} +13 -11
- package/dist/chunk-OTY7EWET.mjs.map +1 -0
- package/dist/chunk-Q2NBD54V.js +69 -0
- package/dist/chunk-Q2NBD54V.js.map +1 -0
- package/dist/{chunk-DGHPOWLU.js → chunk-R5A64DCX.js} +8 -8
- package/dist/{chunk-DGHPOWLU.js.map → chunk-R5A64DCX.js.map} +1 -1
- package/dist/{chunk-3YQCPLGP.mjs → chunk-RFIWVH3D.mjs} +41 -79
- package/dist/chunk-RFIWVH3D.mjs.map +1 -0
- package/dist/{chunk-NNZDHLXN.js → chunk-S3YQGTBF.js} +35 -9
- package/dist/chunk-S3YQGTBF.js.map +1 -0
- package/dist/{chunk-IBDVZ6BF.js → chunk-SLWTG2LJ.js} +69 -74
- package/dist/chunk-SLWTG2LJ.js.map +1 -0
- package/dist/chunk-SN2O72UF.mjs +6 -0
- package/dist/chunk-SN2O72UF.mjs.map +1 -0
- package/dist/{chunk-65SMJBHW.mjs → chunk-T2DEEKVQ.mjs} +69 -74
- package/dist/chunk-T2DEEKVQ.mjs.map +1 -0
- package/dist/{chunk-3GCEFS73.js → chunk-TE3W5REY.js} +39 -62
- package/dist/chunk-TE3W5REY.js.map +1 -0
- package/dist/{chunk-IFVMZFNT.js → chunk-TVCCZ7NR.js} +41 -79
- package/dist/chunk-TVCCZ7NR.js.map +1 -0
- package/dist/{chunk-EBJ4S5DU.js → chunk-UT2CF4FC.js} +4 -4
- package/dist/{chunk-EBJ4S5DU.js.map → chunk-UT2CF4FC.js.map} +1 -1
- package/dist/chunk-V6NVBFEP.js +54 -0
- package/dist/chunk-V6NVBFEP.js.map +1 -0
- package/dist/chunk-WRZQS7O4.js +8 -0
- package/dist/chunk-WRZQS7O4.js.map +1 -0
- package/dist/chunk-WZHWWOUC.js +51 -0
- package/dist/chunk-WZHWWOUC.js.map +1 -0
- package/dist/chunk-X3S6KXAP.mjs +47 -0
- package/dist/chunk-X3S6KXAP.mjs.map +1 -0
- package/dist/chunk-X4OPM3SK.mjs +43 -0
- package/dist/chunk-X4OPM3SK.mjs.map +1 -0
- package/dist/chunk-ZPLN537Q.mjs +57 -0
- package/dist/chunk-ZPLN537Q.mjs.map +1 -0
- package/dist/cli/index.js +8986 -1276
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +8972 -1280
- package/dist/cli/index.mjs.map +1 -1
- package/dist/commerce/index.js +50 -48
- package/dist/commerce/index.mjs +5 -3
- package/dist/engage/index.js +11 -8
- package/dist/engage/index.js.map +1 -1
- package/dist/engage/index.mjs +8 -5
- package/dist/engage/index.mjs.map +1 -1
- package/dist/fleet/contract.d.mts +99 -0
- package/dist/fleet/contract.d.ts +99 -0
- package/dist/fleet/contract.js +53 -0
- package/dist/fleet/contract.js.map +1 -0
- package/dist/fleet/contract.mjs +4 -0
- package/dist/fleet/contract.mjs.map +1 -0
- package/dist/fleet/index.d.mts +89 -0
- package/dist/fleet/index.d.ts +89 -0
- package/dist/fleet/index.js +74 -0
- package/dist/fleet/index.js.map +1 -0
- package/dist/fleet/index.mjs +9 -0
- package/dist/fleet/index.mjs.map +1 -0
- package/dist/forms/contract.d.mts +69 -0
- package/dist/forms/contract.d.ts +69 -0
- package/dist/forms/contract.js +33 -0
- package/dist/forms/contract.js.map +1 -0
- package/dist/forms/contract.mjs +4 -0
- package/dist/forms/contract.mjs.map +1 -0
- package/dist/forms/index.js +21 -17
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/index.mjs +14 -10
- package/dist/forms/index.mjs.map +1 -1
- package/dist/forms/styles.css +10 -8
- package/dist/images/index.js +10 -8
- package/dist/images/index.mjs +3 -1
- package/dist/index.js +98 -96
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9 -7
- package/dist/index.mjs.map +1 -1
- package/dist/layout/client.d.mts +8 -1
- package/dist/layout/client.d.ts +8 -1
- package/dist/layout/client.js +8 -3
- package/dist/layout/client.mjs +7 -2
- package/dist/layout/index.d.mts +7 -1
- package/dist/layout/index.d.ts +7 -1
- package/dist/layout/index.js +57 -4
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/index.mjs +56 -3
- package/dist/layout/index.mjs.map +1 -1
- package/dist/maps/index.js +9 -18
- package/dist/maps/index.js.map +1 -1
- package/dist/maps/index.mjs +9 -18
- package/dist/maps/index.mjs.map +1 -1
- package/dist/portfolio/contract.d.mts +61 -0
- package/dist/portfolio/contract.d.ts +61 -0
- package/dist/portfolio/contract.js +43 -0
- package/dist/portfolio/contract.js.map +1 -0
- package/dist/portfolio/contract.mjs +38 -0
- package/dist/portfolio/contract.mjs.map +1 -0
- package/dist/seo/client.js +4 -2
- package/dist/seo/client.mjs +3 -1
- package/dist/seo/index.js +4 -2
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +3 -1
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo-pages/contract.d.mts +62 -0
- package/dist/seo-pages/contract.d.ts +62 -0
- package/dist/seo-pages/contract.js +48 -0
- package/dist/seo-pages/contract.js.map +1 -0
- package/dist/seo-pages/contract.mjs +44 -0
- package/dist/seo-pages/contract.mjs.map +1 -0
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sites/contract.d.mts +57 -0
- package/dist/sites/contract.d.ts +57 -0
- package/dist/sites/contract.js +37 -0
- package/dist/sites/contract.js.map +1 -0
- package/dist/sites/contract.mjs +4 -0
- package/dist/sites/contract.mjs.map +1 -0
- package/package.json +44 -4
- package/skills/site-kit/SKILL.md +66 -0
- package/dist/AnalyticsProvider-MLT26JRP.mjs +0 -6
- package/dist/AnalyticsProvider-WTOGN7LV.js +0 -27
- package/dist/BlogPostFaqSection-H556RV62.js +0 -13
- package/dist/ChatWidget-MAL7FB4M.js +0 -14
- package/dist/ChatWidget-QPZTPSPE.mjs +0 -5
- package/dist/EngageWidget-IPBUA4DW.mjs +0 -5
- package/dist/EngageWidget-N3CABK3L.js +0 -14
- package/dist/SignalCore-4MDIJUAP.mjs.map +0 -1
- package/dist/SignalCore-ZMFUE3N4.js.map +0 -1
- package/dist/SitemapSync-FUCH6Y6J.js +0 -13
- package/dist/SitemapSync-LCSPRAWU.mjs +0 -4
- package/dist/chunk-3GCEFS73.js.map +0 -1
- package/dist/chunk-3YQCPLGP.mjs.map +0 -1
- package/dist/chunk-5AESOLXS.mjs.map +0 -1
- package/dist/chunk-65SMJBHW.mjs.map +0 -1
- package/dist/chunk-IBDVZ6BF.js.map +0 -1
- package/dist/chunk-IFVMZFNT.js.map +0 -1
- package/dist/chunk-KMZ527EM.mjs.map +0 -1
- package/dist/chunk-MLJXELPA.js.map +0 -1
- package/dist/chunk-NNZDHLXN.js.map +0 -1
- package/dist/chunk-QTWA44S3.mjs.map +0 -1
- package/dist/chunk-RI6JZUAE.js.map +0 -1
- package/dist/chunk-T4QBSRA4.mjs.map +0 -1
- package/dist/chunk-TCVHI3JP.mjs.map +0 -1
- package/dist/chunk-YJWKHCOB.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/analytics/WebVitals.tsx","../src/analytics/AnalyticsProvider.tsx"],"names":["usePathname","useRef","useEffect","propApiUrl","propApiKey","propSite","debug","createContext","wordCount","getApiConfig","useState","getOrCreateVisitorId","getOrCreateSessionId","useCallback","registerAnalyticsDispatcher","useMemo","jsxs","jsx","useContext"],"mappings":"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","file":"chunk-IBDVZ6BF.js","sourcesContent":["/**\n * @sonordev/site-kit/analytics - Web Vitals Component\n * \n * Automatically reports Core Web Vitals via Portal API\n */\n\n'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { usePathname } from 'next/navigation'\nimport type { Metric } from 'web-vitals'\n\ninterface WebVitalsProps {\n apiUrl?: string\n apiKey?: string\n /** Sub-site identifier (matches AnalyticsConfig.site). Tagged on every Web Vital event. */\n site?: string\n debug?: boolean\n}\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__\n : undefined\n return { apiUrl, apiKey }\n}\n\nexport function WebVitals({ apiUrl: propApiUrl, apiKey: propApiKey, site: propSite, debug = false }: WebVitalsProps) {\n const pathname = usePathname()\n\n // Core Web Vitals are per-PAGELOAD, not per-route: LCP/TTFB/FCP finalize\n // once for the initial document and never re-fire on SPA navigations. The\n // observers are therefore registered exactly once (mount), and metrics are\n // attributed to the landing pathname. Re-registering per pathname (the old\n // behavior) leaked listeners on every navigation and re-reported the\n // landing page's LCP under later routes.\n const landingPathRef = useRef<string>(pathname || '/')\n const propsRef = useRef({ propApiUrl, propApiKey, propSite, debug })\n propsRef.current = { propApiUrl, propApiKey, propSite, debug }\n\n useEffect(() => {\n let cancelled = false\n let teardown: (() => void) | undefined\n\n // Dynamic import to avoid SSR issues; catch ChunkLoadError (e.g. Turbopack dev)\n import('web-vitals').then(({ onCLS, onLCP, onTTFB, onINP, onFCP }) => {\n if (cancelled) return\n const { propApiUrl, propApiKey, propSite, debug } = propsRef.current\n const vitals: Record<string, number> = {}\n let reported = false\n\n const reportVitals = async () => {\n if (reported) return\n if (Object.keys(vitals).length === 0) return\n \n reported = true\n \n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n const site =\n propSite ||\n (typeof window !== 'undefined'\n ? (window as { __SITE_KIT_SITE__?: string }).__SITE_KIT_SITE__ ||\n window.location.host\n : '')\n\n if (!apiKey) {\n if (debug) console.warn('[Analytics] No API key configured for Web Vitals')\n return\n }\n\n // Report each metric individually\n for (const [name, value] of Object.entries(vitals)) {\n const data = {\n site,\n pagePath: landingPathRef.current,\n metricName: name,\n metricValue: value,\n metricRating: getRating(name, value),\n }\n \n if (debug) {\n console.log('[Analytics] Web Vital:', data)\n }\n \n try {\n await fetch(`${apiUrl}/api/public/analytics/web-vitals`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(data),\n })\n } catch (error) {\n if (debug) console.error('[Analytics] Error reporting Web Vital:', error)\n }\n }\n }\n \n // Collect vitals\n onLCP((metric: Metric) => {\n vitals.LCP = metric.value\n if (debug) console.log('[Analytics] LCP:', metric.value)\n })\n \n onCLS((metric: Metric) => {\n vitals.CLS = metric.value\n if (debug) console.log('[Analytics] CLS:', metric.value)\n })\n \n onTTFB((metric: Metric) => {\n vitals.TTFB = metric.value\n if (debug) console.log('[Analytics] TTFB:', metric.value)\n })\n \n onINP((metric: Metric) => {\n vitals.INP = metric.value\n if (debug) console.log('[Analytics] INP:', metric.value)\n })\n \n onFCP((metric: Metric) => {\n vitals.FCP = metric.value\n if (debug) console.log('[Analytics] FCP:', metric.value)\n })\n \n // Report on page hide (user leaving)\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'hidden') {\n reportVitals()\n }\n }\n\n document.addEventListener('visibilitychange', handleVisibilityChange)\n\n // Also report after a delay as fallback\n const timeout = setTimeout(reportVitals, 10000)\n\n // The old code returned this cleanup from the promise callback, where\n // React never saw it — listeners and observers piled up per navigation.\n teardown = () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange)\n clearTimeout(timeout)\n }\n }).catch((err) => {\n // ChunkLoadError in Turbopack/dev - Web Vitals are optional\n if (propsRef.current.debug) console.warn('[Analytics] Web Vitals import failed:', err)\n })\n\n return () => {\n cancelled = true\n teardown?.()\n }\n // Mount-once by design — see comment above. Props are read via propsRef.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n return null\n}\n\nfunction getRating(name: string, value: number): 'good' | 'needs-improvement' | 'poor' {\n const thresholds: Record<string, [number, number]> = {\n LCP: [2500, 4000],\n CLS: [0.1, 0.25],\n TTFB: [800, 1800],\n INP: [200, 500],\n FCP: [1800, 3000],\n }\n \n const [good, poor] = thresholds[name] || [0, 0]\n if (value <= good) return 'good'\n if (value <= poor) return 'needs-improvement'\n return 'poor'\n}\n","/**\n * @sonordev/site-kit/analytics - Analytics Provider\n * \n * Provides analytics context and automatic page view tracking.\n * All data goes through Portal API with API key auth - never Supabase directly.\n */\n\n'use client'\n\nimport React, { createContext, useContext, useEffect, useRef, useCallback, useMemo, useState } from 'react'\nimport { usePathname } from 'next/navigation'\nimport type { AnalyticsContextValue, TrackEventOptions, TrackConversionOptions } from './types'\nimport { registerAnalyticsDispatcher } from './dispatch'\nimport { WebVitals } from './WebVitals'\n// Single source of truth for visitor/session IDs (storage keys _sk_vid/_sk_sid)\n// — shared with SignalBridge and EngageWidget. Includes the crypto.randomUUID\n// fallback for older browsers; do NOT re-fork ID logic into this module.\nimport { getOrCreateVisitorId, getOrCreateSessionId } from '../shared/identity'\n\nconst AnalyticsContext = createContext<AnalyticsContextValue | null>(null)\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Schedule a callback to run during browser idle time.\n * Safari has no requestIdleCallback — use a short real delay there so the\n * work lands after the post-hydration burst instead of right inside it.\n */\nfunction scheduleIdleTask(callback: () => void, timeout = 2000): void {\n if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {\n ;(window as typeof window & { requestIdleCallback: (cb: () => void, opts?: { timeout: number }) => number }).requestIdleCallback(\n callback,\n { timeout }\n )\n } else {\n setTimeout(callback, 300)\n }\n}\n\nfunction getDeviceType(): 'desktop' | 'mobile' | 'tablet' {\n if (typeof window === 'undefined') return 'desktop'\n \n const ua = navigator.userAgent\n if (/tablet|ipad|playbook|silk/i.test(ua)) return 'tablet'\n if (/mobile|iphone|ipod|android|blackberry|opera mini|iemobile/i.test(ua)) return 'mobile'\n return 'desktop'\n}\n\nfunction getBrowser(): string {\n if (typeof window === 'undefined') return 'unknown'\n \n const ua = navigator.userAgent\n if (ua.includes('Firefox')) return 'Firefox'\n if (ua.includes('Edg')) return 'Edge'\n if (ua.includes('Chrome')) return 'Chrome'\n if (ua.includes('Safari')) return 'Safari'\n if (ua.includes('Opera') || ua.includes('OPR')) return 'Opera'\n return 'Other'\n}\n\nfunction getOS(): string {\n if (typeof window === 'undefined') return 'unknown'\n \n const ua = navigator.userAgent\n if (ua.includes('Windows')) return 'Windows'\n if (ua.includes('Mac OS X') || ua.includes('Macintosh')) return 'macOS'\n if (ua.includes('iPhone') || ua.includes('iPad')) return 'iOS'\n if (ua.includes('Android')) return 'Android'\n if (ua.includes('Linux')) return 'Linux'\n if (ua.includes('CrOS')) return 'ChromeOS'\n return 'Other'\n}\n\nfunction getUserAgent(): string {\n if (typeof window === 'undefined') return ''\n return navigator.userAgent\n}\n\nfunction getUTMParams(): Record<string, string> {\n if (typeof window === 'undefined') return {}\n \n const params = new URLSearchParams(window.location.search)\n const utmParams: Record<string, string> = {}\n \n for (const key of ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']) {\n const value = params.get(key)\n if (value) utmParams[key] = value\n }\n \n return utmParams\n}\n\n/**\n * Promise wrapper around scheduleIdleTask so the metadata scrape can yield\n * back to the main thread between slices.\n */\nfunction nextIdleSlice(timeout = 1500): Promise<void> {\n return new Promise(resolve => scheduleIdleTask(resolve, timeout))\n}\n\n/**\n * Extract SEO metadata from the current page.\n * This enriches seo_pages with live data from the actual page.\n *\n * Split into three slices so no single idle callback runs the whole scrape as\n * one long task on throttled mobile CPUs (full-tree clones + textContent reads\n * are the expensive part):\n * 1. getLightPageMetadata — meta tags, canonical, H1 (cheap queries)\n * 2. getLinkPageMetadata — word count + link graph (whole-tree text + anchors)\n * 3. getHeavyPageMetadata — images w/ context, content clone, sections, FAQs\n * Callers yield via nextIdleSlice() between them and merge the results; the\n * merged payload shape is identical to the old monolithic getPageMetadata().\n */\nfunction getLightPageMetadata(): Record<string, any> {\n if (typeof document === 'undefined') return {}\n\n const getMeta = (name: string): string | null => {\n const el = document.querySelector(`meta[name=\"${name}\"], meta[property=\"${name}\"]`)\n return el?.getAttribute('content') || null\n }\n \n const getCanonical = (): string | null => {\n const el = document.querySelector('link[rel=\"canonical\"]')\n return el?.getAttribute('href') || null\n }\n \n const getRobots = (): string | null => {\n return getMeta('robots')\n }\n \n const getH1 = (): string | null => {\n const h1 = document.querySelector('h1')\n return h1?.textContent?.trim() || null\n }\n \n const getH1Count = (): number => {\n return document.querySelectorAll('h1').length\n }\n \n return {\n metaDescription: getMeta('description'),\n canonical: getCanonical(),\n robots: getRobots(),\n ogTitle: getMeta('og:title'),\n ogDescription: getMeta('og:description'),\n ogImage: getMeta('og:image'),\n h1: getH1(),\n h1Count: getH1Count(),\n }\n}\n\n/** Slice 2: image inventory — per-image ancestor walks + surrounding text. */\nfunction getMediaPageMetadata(): Record<string, any> {\n if (typeof document === 'undefined') return {}\n\n interface PageImageReport {\n src: string\n alt: string | null\n elementType: 'img' | 'Image' | 'ManagedImage' | 'picture' | 'background'\n slotId?: string\n position: 'hero' | 'content' | 'sidebar' | 'footer' | 'header' | 'unknown'\n width?: number\n height?: number\n surroundingText?: string\n }\n\n // Helper to determine element position in page\n const getElementPosition = (el: Element): PageImageReport['position'] => {\n let current: Element | null = el\n while (current) {\n const tag = current.tagName?.toLowerCase()\n const role = current.getAttribute('role')\n const className = current.className?.toString?.() || ''\n \n // Check for hero sections\n if (className.includes('hero') || current.id?.includes('hero')) return 'hero'\n if (tag === 'header' || role === 'banner') return 'header'\n if (tag === 'nav' || role === 'navigation') return 'header'\n if (tag === 'footer' || role === 'contentinfo') return 'footer'\n if (tag === 'aside' || role === 'complementary') return 'sidebar'\n if (tag === 'main' || tag === 'article' || role === 'main') return 'content'\n \n current = current.parentElement\n }\n return 'unknown'\n }\n\n // Get surrounding text context for an image\n const getSurroundingText = (el: Element): string => {\n // Find closest paragraph, figcaption, or container\n const container = el.closest('figure, p, div, section, article')\n if (!container) return ''\n \n // Get text excluding script/style content\n const text = container.textContent?.replace(/\\s+/g, ' ').trim() || ''\n return text.slice(0, 300) // Limit to 300 chars\n }\n\n const getImageDetails = (): PageImageReport[] => {\n const images = document.querySelectorAll('img, [data-managed-image]')\n const seen = new Set<string>()\n const results: PageImageReport[] = []\n \n images.forEach(el => {\n const img = el as HTMLImageElement\n const src = img.getAttribute('src') || img.getAttribute('data-src') || ''\n \n // Skip duplicates, data URIs, and empty src\n if (!src || src.startsWith('data:') || seen.has(src)) return\n seen.add(src)\n \n // Detect if it's a ManagedImage\n const slotId = img.getAttribute('data-slot-id') || undefined\n const isManagedImage = img.hasAttribute('data-managed-image') || !!slotId\n \n results.push({\n src,\n alt: img.alt || null,\n elementType: isManagedImage ? 'ManagedImage' : 'img',\n slotId,\n position: getElementPosition(img),\n width: img.naturalWidth || parseInt(img.getAttribute('width') || '0') || undefined,\n height: img.naturalHeight || parseInt(img.getAttribute('height') || '0') || undefined,\n surroundingText: getSurroundingText(img),\n })\n })\n \n return results\n }\n\n const getImageStats = (): { count: number; withoutAlt: number; images: PageImageReport[] } => {\n const images = getImageDetails()\n let withoutAlt = 0\n images.forEach(img => {\n if (!img.alt || img.alt.trim() === '') withoutAlt++\n })\n return { count: images.length, withoutAlt, images }\n }\n\n const imageStats = getImageStats()\n return {\n imagesCount: imageStats.count,\n imagesWithoutAlt: imageStats.withoutAlt,\n images: imageStats.images, // Full image details for SEO optimization\n }\n}\n\n/** Slice 3: word count, link graph, and content extraction for Signal AI. */\nfunction getContentPageMetadata(): Record<string, any> {\n if (typeof document === 'undefined') return {}\n\n const getWordCount = (): number => {\n // Get main content, fallback to body\n const main = document.querySelector('main, article, [role=\"main\"]') || document.body\n const text = main.textContent || ''\n return text.split(/\\s+/).filter(w => w.length > 0).length\n }\n\n interface InternalLink {\n targetPath: string\n anchorText: string\n position: 'header' | 'nav' | 'content' | 'footer' | 'sidebar' | 'unknown'\n isNofollow: boolean\n }\n \n const getLinkStats = (): { \n internal: number\n external: number\n internalLinks: InternalLink[]\n } => {\n const links = document.querySelectorAll('a[href]')\n const currentHost = window.location.host\n let internal = 0\n let external = 0\n const internalLinks: InternalLink[] = []\n \n // Helper to determine link position in page\n const getLinkPosition = (el: Element): InternalLink['position'] => {\n let current: Element | null = el\n while (current) {\n const tag = current.tagName?.toLowerCase()\n const role = current.getAttribute('role')\n \n if (tag === 'header' || role === 'banner') return 'header'\n if (tag === 'nav' || role === 'navigation') return 'nav'\n if (tag === 'footer' || role === 'contentinfo') return 'footer'\n if (tag === 'aside' || role === 'complementary') return 'sidebar'\n if (tag === 'main' || tag === 'article' || role === 'main') return 'content'\n \n current = current.parentElement\n }\n return 'unknown'\n }\n \n links.forEach(link => {\n const href = link.getAttribute('href') || ''\n const rel = link.getAttribute('rel') || ''\n const isNofollow = rel.includes('nofollow')\n \n let isInternal = false\n let targetPath = ''\n \n if (href.startsWith('/') && !href.startsWith('//')) {\n isInternal = true\n targetPath = href.split('?')[0].split('#')[0] // Remove query/hash\n } else if (href.startsWith('#')) {\n // Same page anchor - skip\n internal++\n return\n } else if (href.startsWith('http')) {\n try {\n const url = new URL(href)\n if (url.host === currentHost) {\n isInternal = true\n targetPath = url.pathname\n } else {\n external++\n }\n } catch {\n // Invalid URL\n }\n }\n \n if (isInternal && targetPath) {\n internal++\n // Normalize path\n if (!targetPath.startsWith('/')) targetPath = '/' + targetPath\n if (targetPath !== '/' && targetPath.endsWith('/')) {\n targetPath = targetPath.slice(0, -1)\n }\n \n internalLinks.push({\n targetPath,\n anchorText: (link.textContent || '').trim().slice(0, 200),\n position: getLinkPosition(link),\n isNofollow,\n })\n }\n })\n \n return { internal, external, internalLinks }\n }\n\n // ============================================\n // Content Extraction for Signal AI Analysis\n // ============================================\n \n interface HeadingInfo {\n level: number\n text: string\n id?: string\n }\n\n interface ContentSection {\n heading?: string\n headingLevel?: number\n text: string\n wordCount: number\n }\n\n interface FAQItem {\n question: string\n answer: string\n }\n\n const getHeadingStructure = (): HeadingInfo[] => {\n const headings: HeadingInfo[] = []\n const elements = document.querySelectorAll('h1, h2, h3, h4, h5, h6')\n \n elements.forEach(el => {\n const level = parseInt(el.tagName[1])\n const text = el.textContent?.trim() || ''\n if (text) {\n headings.push({\n level,\n text: text.slice(0, 200), // Limit length\n id: el.id || undefined\n })\n }\n })\n \n return headings\n }\n\n const getContentText = (): { text: string; hash: string } => {\n // Get main content area\n const main = document.querySelector('main, article, [role=\"main\"]') || document.body\n \n // Clone to avoid modifying the page\n const clone = main.cloneNode(true) as Element\n \n // Remove script, style, nav, header, footer from clone\n clone.querySelectorAll('script, style, nav, header, footer, [role=\"navigation\"], [role=\"banner\"], [role=\"contentinfo\"]').forEach(el => el.remove())\n \n // Get clean text\n let text = clone.textContent || ''\n text = text.replace(/\\s+/g, ' ').trim()\n \n // Limit to 10KB for storage\n text = text.slice(0, 10000)\n \n // Simple hash for change detection\n let hash = 0\n for (let i = 0; i < text.length; i++) {\n const chr = text.charCodeAt(i)\n hash = ((hash << 5) - hash) + chr\n hash |= 0\n }\n \n return { text, hash: hash.toString(16) }\n }\n\n const getContentSections = (): ContentSection[] => {\n const sections: ContentSection[] = []\n const main = document.querySelector('main, article, [role=\"main\"]') || document.body\n \n // Find all heading + content pairs\n const headings = main.querySelectorAll('h1, h2, h3')\n \n headings.forEach((heading, idx) => {\n const headingText = heading.textContent?.trim() || ''\n const level = parseInt(heading.tagName[1])\n \n // Get content between this heading and the next\n let content = ''\n let sibling = heading.nextElementSibling\n \n while (sibling && !['H1', 'H2', 'H3'].includes(sibling.tagName)) {\n if (sibling.tagName === 'P' || sibling.tagName === 'UL' || sibling.tagName === 'OL' || sibling.tagName === 'DIV') {\n content += (sibling.textContent || '') + ' '\n }\n sibling = sibling.nextElementSibling\n }\n \n content = content.replace(/\\s+/g, ' ').trim().slice(0, 1000)\n const wordCount = content.split(/\\s+/).filter(w => w.length > 0).length\n \n if (content && wordCount > 10) {\n sections.push({\n heading: headingText.slice(0, 200),\n headingLevel: level,\n text: content,\n wordCount\n })\n }\n })\n \n return sections.slice(0, 20) // Limit to 20 sections\n }\n\n const detectFAQContent = (): FAQItem[] => {\n const faqs: FAQItem[] = []\n \n // Look for FAQ schema\n const scripts = document.querySelectorAll('script[type=\"application/ld+json\"]')\n scripts.forEach(script => {\n try {\n const data = JSON.parse(script.textContent || '')\n if (data['@type'] === 'FAQPage' && data.mainEntity) {\n data.mainEntity.forEach((item: any) => {\n if (item['@type'] === 'Question') {\n faqs.push({\n question: item.name?.slice(0, 200) || '',\n answer: (item.acceptedAnswer?.text || '').slice(0, 500)\n })\n }\n })\n }\n } catch { /* ignore parse errors */ }\n })\n \n // Look for common FAQ patterns in HTML\n if (faqs.length === 0) {\n // details/summary pattern\n const details = document.querySelectorAll('details')\n details.forEach(detail => {\n const summary = detail.querySelector('summary')\n if (summary) {\n const question = summary.textContent?.trim() || ''\n const answer = detail.textContent?.replace(question, '').trim().slice(0, 500) || ''\n if (question && answer) {\n faqs.push({ question: question.slice(0, 200), answer })\n }\n }\n })\n \n // Accordion pattern (common class names)\n const accordionItems = document.querySelectorAll('[class*=\"accordion\"], [class*=\"faq\"], [data-faq]')\n accordionItems.forEach(item => {\n const questionEl = item.querySelector('[class*=\"question\"], [class*=\"title\"], button, h3, h4')\n const answerEl = item.querySelector('[class*=\"answer\"], [class*=\"content\"], [class*=\"panel\"], p')\n if (questionEl && answerEl) {\n const question = questionEl.textContent?.trim() || ''\n const answer = answerEl.textContent?.trim().slice(0, 500) || ''\n if (question && answer && question.includes('?')) {\n faqs.push({ question: question.slice(0, 200), answer })\n }\n }\n })\n }\n \n return faqs.slice(0, 20) // Limit to 20 FAQs\n }\n\n const detectLists = (): { type: 'ul' | 'ol'; items: string[] }[] => {\n const lists: { type: 'ul' | 'ol'; items: string[] }[] = []\n const main = document.querySelector('main, article, [role=\"main\"]') || document.body\n \n main.querySelectorAll('ul, ol').forEach(list => {\n const type = list.tagName.toLowerCase() as 'ul' | 'ol'\n const items: string[] = []\n \n list.querySelectorAll(':scope > li').forEach(li => {\n const text = li.textContent?.trim().slice(0, 200) || ''\n if (text) items.push(text)\n })\n \n // Only include substantial lists (3+ items)\n if (items.length >= 3) {\n lists.push({ type, items: items.slice(0, 10) })\n }\n })\n \n return lists.slice(0, 10) // Limit to 10 lists\n }\n\n const estimateReadingTime = (wordCount: number): number => {\n // Average reading speed: 200-250 words per minute\n return Math.ceil(wordCount / 225)\n }\n \n const linkStats = getLinkStats()\n const headingStructure = getHeadingStructure()\n const contentData = getContentText()\n const contentSections = getContentSections()\n const faqContent = detectFAQContent()\n const listContent = detectLists()\n const wordCount = getWordCount()\n\n return {\n wordCount,\n internalLinks: linkStats.internal,\n internalLinkTargets: linkStats.internalLinks, // Full link graph data\n externalLinks: linkStats.external,\n // Content analysis data\n content: {\n text: contentData.text,\n hash: contentData.hash,\n headings: headingStructure,\n sections: contentSections,\n faqs: faqContent.length > 0 ? faqContent : undefined,\n lists: listContent.length > 0 ? listContent : undefined,\n readingTime: estimateReadingTime(wordCount),\n },\n }\n}\n\n/**\n * Collect full page metadata across three idle slices so the scrape never\n * runs as one long main-thread task. `isStale` is checked between slices —\n * if the user SPA-navigates mid-scrape, later slices would read the NEW\n * page's DOM under the old path, so we stop and return only the slices\n * scraped while the page was still current (partial metadata beats corrupt\n * metadata, and the page view itself is still recorded).\n */\nasync function collectPageMetadata(isStale: () => boolean): Promise<Record<string, any>> {\n const light = getLightPageMetadata()\n await nextIdleSlice()\n if (isStale()) return light\n const media = getMediaPageMetadata()\n await nextIdleSlice()\n if (isStale()) return { ...light, ...media }\n const content = getContentPageMetadata()\n return { ...light, ...media, ...content }\n}\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__\n : undefined\n return { apiUrl, apiKey }\n}\n\n// ============================================\n// Provider Component\n// ============================================\n\ninterface AnalyticsProviderProps {\n /**\n * Optional. AnalyticsProvider is normally mounted as a CHILDLESS sibling of\n * page content (see SiteKitClientProviders) — it tracks via effects and a\n * metadata ref, it does not need to enclose the page. When rendered\n * childless, the AnalyticsContext simply has no consumers; components that\n * need it should use `useAnalyticsOptional()`.\n */\n children?: React.ReactNode\n apiUrl?: string\n apiKey?: string\n trackPageViews?: boolean\n trackWebVitals?: boolean\n trackScrollDepth?: boolean\n trackClicks?: boolean\n trackJourneys?: boolean // NEW: Track user journey paths\n sessionTimeout?: number\n excludePaths?: string[]\n validateAgainstSitemap?: boolean // Log debug warnings for paths not in sitemap (informational only, never blocks tracking)\n debug?: boolean\n /** External visitor ID from shared identity (used by SiteKitLayout) */\n externalVisitorId?: string\n /** External session ID from shared identity (used by SiteKitLayout) */\n externalSessionId?: string\n /** Callback invoked with page metadata after each page view (used by Signal bridge) */\n onPageMetadata?: (metadata: Record<string, unknown>) => void\n /**\n * Sub-site identifier (e.g. `ohiopowerstudies.com`). Every event tagged with\n * this string so a single Sonor project can host many sites and the\n * dashboard can filter / roll up per site. Normally passed in by\n * SiteKitClientProviders; if omitted, falls back to\n * `window.__SITE_KIT_SITE__` then `window.location.host`.\n */\n site?: string\n}\n\nexport function AnalyticsProvider({\n children,\n apiUrl: propApiUrl,\n apiKey: propApiKey,\n trackPageViews = true,\n trackWebVitals = true,\n trackScrollDepth = true,\n trackClicks = true,\n trackJourneys = true, // NEW: Enable journey tracking by default\n sessionTimeout = 30,\n excludePaths = [],\n validateAgainstSitemap = false,\n debug = false,\n externalVisitorId,\n externalSessionId,\n onPageMetadata,\n site: propSite,\n}: AnalyticsProviderProps) {\n const pathname = usePathname()\n // Use state to track query string changes instead of useSearchParams (avoids Suspense requirement)\n const [queryString, setQueryString] = useState('')\n\n // Sub-site identifier — every event body below carries this so a single\n // Sonor project can host many sites and the dashboard can filter / roll up\n // per site. Resolution: prop > window global (set by SiteKitClientProviders)\n // > window.location.host. Empty string is acceptable (older clients).\n const site =\n propSite ||\n (typeof window !== 'undefined'\n ? (window as { __SITE_KIT_SITE__?: string }).__SITE_KIT_SITE__ ||\n window.location.host\n : '')\n \n // Listen for URL changes including query string\n useEffect(() => {\n if (typeof window === 'undefined') return\n \n // Set initial query string\n setQueryString(window.location.search)\n \n // Listen for popstate (back/forward navigation)\n const handlePopState = () => {\n setQueryString(window.location.search)\n }\n \n window.addEventListener('popstate', handlePopState)\n return () => window.removeEventListener('popstate', handlePopState)\n }, [pathname]) // Re-check when pathname changes\n \n const visitorIdRef = useRef<string>('')\n const sessionIdRef = useRef<string>('')\n const lastPathRef = useRef<string>('')\n const validPathsRef = useRef<Set<string> | null>(null)\n const sitemapLoadedRef = useRef<boolean>(false)\n \n // Journey tracking state\n const journeyStartTimeRef = useRef<number>(0)\n const pageEnterTimeRef = useRef<number>(0)\n const currentScrollDepthRef = useRef<number>(0)\n \n // Initialize IDs — use external (shared) IDs when provided by SiteKitLayout\n useEffect(() => {\n visitorIdRef.current = externalVisitorId || getOrCreateVisitorId()\n sessionIdRef.current = externalSessionId || getOrCreateSessionId(sessionTimeout)\n }, [sessionTimeout, externalVisitorId, externalSessionId])\n \n // Fetch valid pages from seo_pages (populated by SitemapSync from SEO module)\n useEffect(() => {\n if (!validateAgainstSitemap) {\n if (debug) console.log('[Analytics] Page validation disabled')\n return\n }\n \n const fetchValidPages = async () => {\n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n \n if (!apiKey) {\n if (debug) console.warn('[Analytics] No API key for page validation')\n return\n }\n \n try {\n // Fetch seo_pages which is the canonical source of truth\n // (populated by SitemapSync component from the SEO module)\n const response = await fetch(`${apiUrl}/api/public/seo/pages`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n })\n \n if (response.ok) {\n const data = await response.json()\n const pages = data?.pages || []\n validPathsRef.current = new Set(\n pages.map((p: any) => p.path).filter(Boolean)\n )\n sitemapLoadedRef.current = true\n\n if (debug) {\n console.log('[Analytics] Loaded', validPathsRef.current.size, 'valid pages from seo_pages')\n }\n } else {\n sitemapLoadedRef.current = true // Mark as loaded even on failure so we don't block\n if (debug) {\n console.error('[Analytics] Pages fetch failed:', response.statusText)\n }\n }\n } catch (error) {\n sitemapLoadedRef.current = true // Mark as loaded even on error so we don't block\n if (debug) console.error('[Analytics] Error fetching valid pages:', error)\n }\n }\n \n fetchValidPages()\n }, [propApiUrl, propApiKey, validateAgainstSitemap, debug])\n \n // Track page views\n useEffect(() => {\n if (!trackPageViews) return\n if (!pathname) return\n\n // Normalize path: strip trailing slashes (except root)\n const normalizedPath = pathname === '/' ? '/' : pathname.replace(/\\/+$/, '')\n\n if (excludePaths.some(p => normalizedPath.startsWith(p))) return\n if (normalizedPath === lastPathRef.current) return\n\n lastPathRef.current = normalizedPath\n \n const trackPageView = async () => {\n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n \n if (!apiKey) {\n if (debug) console.warn('[Analytics] No API key configured')\n return\n }\n \n const utmParams = getUTMParams()\n // Captured before the sliced scrape yields — the title must belong to\n // THIS page even if the user navigates while slices are pending.\n const pageTitle = document.title\n // Sliced scrape: yields to the main thread between phases; on SPA\n // navigation mid-scrape it returns only the slices read from this\n // page's DOM (the page view still records, with partial metadata).\n const pageMetadata = await collectPageMetadata(\n () => lastPathRef.current !== normalizedPath,\n )\n\n // Share page metadata with Signal bridge via callback\n if (onPageMetadata) {\n onPageMetadata(pageMetadata)\n }\n\n const pageView = {\n sessionId: sessionIdRef.current,\n visitorId: visitorIdRef.current,\n site,\n pagePath: normalizedPath,\n pageTitle,\n referrer: document.referrer || null,\n deviceType: getDeviceType(),\n browser: getBrowser(),\n os: getOS(),\n userAgent: getUserAgent(),\n utmSource: utmParams.utm_source,\n utmMedium: utmParams.utm_medium,\n utmCampaign: utmParams.utm_campaign,\n utmTerm: utmParams.utm_term,\n utmContent: utmParams.utm_content,\n // SEO enrichment data - updates seo_pages\n seo: pageMetadata,\n }\n\n if (debug) {\n console.log('[Analytics] Page view:', pageView)\n }\n\n try {\n const response = await fetch(`${apiUrl}/api/public/analytics/page-view`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(pageView),\n })\n\n if (debug) {\n console.log('[Analytics] Page view response:', response.status, response.statusText, 'url:', `${apiUrl}/api/public/analytics/page-view`)\n }\n if (!response.ok && debug) {\n const text = await response.text().catch(() => '')\n console.error('[Analytics] Error tracking page view:', response.status, response.statusText, text)\n }\n } catch (error) {\n if (debug) console.error('[Analytics] Error tracking page view (fetch failed):', error)\n }\n\n // Informational sitemap validation (never blocks tracking)\n if (validateAgainstSitemap && debug) {\n if (sitemapLoadedRef.current && validPathsRef.current && validPathsRef.current.size > 0) {\n if (!validPathsRef.current.has(normalizedPath)) {\n console.log('[Analytics] Note: path not found in sitemap (tracked anyway):', normalizedPath)\n }\n } else if (!sitemapLoadedRef.current) {\n console.log('[Analytics] Sitemap not yet loaded, tracked anyway:', normalizedPath)\n }\n }\n }\n \n // Use requestIdleCallback to defer tracking until browser is idle\n scheduleIdleTask(() => trackPageView())\n }, [pathname, queryString, propApiUrl, propApiKey, trackPageViews, excludePaths, debug, validateAgainstSitemap])\n\n // ============================================\n // Journey Path Tracking\n // ============================================\n useEffect(() => {\n if (!trackJourneys) return\n if (!pathname) return\n if (typeof window === 'undefined') return\n\n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n \n if (!apiKey) return\n \n const now = Date.now()\n const previousPath = lastPathRef.current\n const previousDuration = pageEnterTimeRef.current > 0 \n ? Math.round((now - pageEnterTimeRef.current) / 1000) \n : 0\n const previousScrollDepth = currentScrollDepthRef.current\n\n // Update tracking refs for next navigation\n pageEnterTimeRef.current = now\n currentScrollDepthRef.current = 0\n\n // Determine if this is a new session or continuation\n const isNewSession = !previousPath || journeyStartTimeRef.current === 0\n \n if (isNewSession) {\n journeyStartTimeRef.current = now\n }\n\n const trackJourneyStep = async () => {\n const sessionData: Record<string, any> = {\n sessionId: sessionIdRef.current,\n visitorId: visitorIdRef.current,\n site,\n action: isNewSession ? 'start' : 'update',\n lastPage: pathname,\n userAgent: getUserAgent(),\n // Journey step data\n journeyStep: {\n page: pathname,\n timestamp: new Date().toISOString(),\n },\n }\n\n // Include previous page duration when navigating\n if (!isNewSession && previousDuration > 0) {\n sessionData.previousPageDuration = previousDuration\n sessionData.previousPageScrollDepth = previousScrollDepth\n }\n\n // Include first page for new sessions\n if (isNewSession) {\n sessionData.firstPage = pathname\n const utmParams = getUTMParams()\n sessionData.referrer = document.referrer || null\n sessionData.utmSource = utmParams.utm_source\n sessionData.utmMedium = utmParams.utm_medium\n sessionData.utmCampaign = utmParams.utm_campaign\n sessionData.utmTerm = utmParams.utm_term\n sessionData.utmContent = utmParams.utm_content\n sessionData.screenWidth = window.screen.width\n sessionData.screenHeight = window.screen.height\n }\n\n if (debug) {\n console.log('[Analytics] Journey step:', sessionData)\n }\n\n try {\n await fetch(`${apiUrl}/api/public/analytics/session`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(sessionData),\n })\n } catch (error) {\n if (debug) console.error('[Analytics] Error tracking journey:', error)\n }\n }\n\n scheduleIdleTask(() => trackJourneyStep())\n\n // Track session end when the page is being hidden/unloaded. `pagehide`\n // (not `beforeunload`): beforeunload never fires on iOS Safari and makes\n // pages ineligible for the back/forward cache in Firefox.\n const handleUnload = () => {\n const duration = Math.round((Date.now() - journeyStartTimeRef.current) / 1000)\n const payload = JSON.stringify({\n sessionId: sessionIdRef.current,\n site,\n action: 'end',\n duration,\n lastPage: pathname,\n previousPageDuration: Math.round((Date.now() - pageEnterTimeRef.current) / 1000),\n previousPageScrollDepth: currentScrollDepthRef.current,\n })\n\n // Use sendBeacon for reliability\n if (navigator.sendBeacon) {\n const blob = new Blob([payload], { type: 'application/json' })\n navigator.sendBeacon(\n `${apiUrl}/api/public/analytics/session?key=${encodeURIComponent(apiKey)}`,\n blob\n )\n }\n }\n\n window.addEventListener('pagehide', handleUnload)\n\n return () => {\n window.removeEventListener('pagehide', handleUnload)\n }\n }, [pathname, propApiUrl, propApiKey, trackJourneys, debug])\n\n // ============================================\n // Scroll Depth Tracking\n // ============================================\n useEffect(() => {\n if (typeof window === 'undefined') return\n \n if (debug) console.log('[Analytics] Scroll tracking setup:', { trackScrollDepth, hasApiKey: !!propApiKey })\n \n if (!trackScrollDepth) return\n\n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n \n if (!apiKey) {\n if (debug) console.warn('[Analytics] Scroll tracking disabled - no API key')\n return\n }\n \n if (debug) console.log('[Analytics] Scroll tracking enabled for:', pathname)\n\n let maxDepth = 0\n let startTime = Date.now()\n let milestone25: number | null = null\n let milestone50: number | null = null\n let milestone75: number | null = null\n let milestone100: number | null = null\n let hasTracked = false\n\n const calculateScrollDepth = () => {\n const scrollTop = window.scrollY\n const docHeight = document.documentElement.scrollHeight\n const winHeight = window.innerHeight\n const scrollableHeight = docHeight - winHeight\n \n if (scrollableHeight <= 0) return 100\n return Math.min(100, Math.round((scrollTop / scrollableHeight) * 100))\n }\n\n const handleScroll = () => {\n const depth = calculateScrollDepth()\n const elapsed = (Date.now() - startTime) / 1000\n\n if (depth > maxDepth) {\n maxDepth = depth\n currentScrollDepthRef.current = depth // Update ref for journey tracking\n if (debug && depth % 25 === 0) console.log('[Analytics] Scroll milestone:', depth + '%')\n \n if (depth >= 25 && milestone25 === null) milestone25 = elapsed\n if (depth >= 50 && milestone50 === null) milestone50 = elapsed\n if (depth >= 75 && milestone75 === null) milestone75 = elapsed\n if (depth >= 100 && milestone100 === null) milestone100 = elapsed\n }\n }\n\n const sendScrollData = async (useBeacon = false) => {\n if (hasTracked || maxDepth === 0) return\n hasTracked = true\n\n const totalTime = (Date.now() - startTime) / 1000\n \n const payload = JSON.stringify({\n sessionId: sessionIdRef.current,\n visitorId: visitorIdRef.current,\n site,\n pagePath: pathname,\n maxDepthPercent: maxDepth,\n timeTo25: milestone25,\n timeTo50: milestone50,\n timeTo75: milestone75,\n timeTo100: milestone100,\n totalTimeSeconds: totalTime,\n deviceType: getDeviceType(),\n })\n\n // Use sendBeacon for page unload (more reliable) or fetch for regular sends\n if (useBeacon && navigator.sendBeacon) {\n const blob = new Blob([payload], { type: 'application/json' })\n const headers = new Headers({ 'x-api-key': apiKey })\n // sendBeacon doesn't support custom headers, so we need to include key in URL\n navigator.sendBeacon(\n `${apiUrl}/api/public/analytics/scroll-depth?key=${encodeURIComponent(apiKey)}`,\n blob\n )\n if (debug) console.log('[Analytics] Scroll depth (beacon):', { maxDepth, totalTime })\n } else {\n try {\n await fetch(`${apiUrl}/api/public/analytics/scroll-depth`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: payload,\n keepalive: true, // Allows request to outlive the page\n })\n \n if (debug) console.log('[Analytics] Scroll depth:', { maxDepth, totalTime })\n } catch (error) {\n if (debug) console.error('[Analytics] Error tracking scroll depth:', error)\n }\n }\n }\n\n // Reset on page change\n maxDepth = 0\n startTime = Date.now()\n milestone25 = null\n milestone50 = null\n milestone75 = null\n milestone100 = null\n hasTracked = false\n\n window.addEventListener('scroll', handleScroll, { passive: true })\n\n // Capture the current position immediately — the provider mounts deferred\n // (idle/first-interaction), so the user may have already scrolled.\n handleScroll()\n\n // Send on page hide/unload - use beacon for reliability. `pagehide` (not\n // `beforeunload`) — it fires on iOS Safari and is bfcache-safe.\n const handlePageHide = () => sendScrollData(true)\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'hidden') sendScrollData(true)\n }\n\n window.addEventListener('pagehide', handlePageHide)\n document.addEventListener('visibilitychange', handleVisibilityChange)\n\n return () => {\n window.removeEventListener('scroll', handleScroll)\n window.removeEventListener('pagehide', handlePageHide)\n document.removeEventListener('visibilitychange', handleVisibilityChange)\n sendScrollData(false) // Send when component unmounts (navigation) - can use fetch here\n }\n }, [pathname, propApiUrl, propApiKey, trackScrollDepth, debug])\n\n // ============================================\n // Click/Heatmap Tracking\n // ============================================\n useEffect(() => {\n if (!trackClicks) return\n if (typeof window === 'undefined') return\n\n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n if (!apiKey) return\n\n const handleClick = async (e: MouseEvent) => {\n const target = e.target as HTMLElement\n if (!target) return\n\n const docHeight = document.documentElement.scrollHeight\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n\n // Calculate click position as percentage\n const xPercent = Math.round((e.pageX / viewportWidth) * 100)\n const yPercent = Math.round(((e.pageY) / docHeight) * 100)\n\n // Get element info\n const elementTag = target.tagName.toLowerCase()\n const elementId = target.id || null\n const elementClass = target.className && typeof target.className === 'string' \n ? target.className.split(' ').slice(0, 3).join(' ') \n : null\n const elementText = target.textContent?.slice(0, 50) || null\n\n const clickData = {\n sessionId: sessionIdRef.current,\n site,\n pagePath: pathname,\n xPercent,\n yPercent,\n xAbsolute: e.pageX,\n yAbsolute: e.pageY,\n viewportWidth,\n viewportHeight,\n pageHeight: docHeight,\n elementTag,\n elementId,\n elementClass,\n elementText,\n }\n\n if (debug) console.log('[Analytics] Click:', clickData)\n\n scheduleIdleTask(async () => {\n try {\n await fetch(`${apiUrl}/api/public/analytics/heatmap-click`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(clickData),\n })\n } catch (error) {\n if (debug) console.error('[Analytics] Error tracking click:', error)\n }\n }, 500)\n }\n\n document.addEventListener('click', handleClick, { passive: true })\n\n return () => {\n document.removeEventListener('click', handleClick)\n }\n }, [pathname, propApiUrl, propApiKey, trackClicks, debug])\n \n // Track event function - uses idle callback for non-critical events\n const trackEvent = useCallback((options: TrackEventOptions) => {\n const doTrack = async () => {\n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n \n if (!apiKey) {\n if (debug) console.warn('[Analytics] No API key configured')\n return\n }\n \n const event = {\n sessionId: sessionIdRef.current,\n visitorId: visitorIdRef.current,\n site,\n eventName: options.name,\n eventCategory: options.category,\n eventLabel: options.label,\n eventValue: options.value,\n properties: options.properties,\n pagePath: pathname,\n }\n \n if (debug) {\n console.log('[Analytics] Event:', event)\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/analytics/event`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(event),\n })\n \n if (!response.ok && debug) {\n console.error('[Analytics] Error tracking event:', response.statusText)\n }\n } catch (error) {\n if (debug) console.error('[Analytics] Error tracking event:', error)\n }\n }\n \n // Defer event tracking to idle time\n scheduleIdleTask(doTrack, 1000)\n }, [propApiUrl, propApiKey, pathname, debug])\n \n // Track conversion function - runs immediately (conversions are high priority)\n const trackConversion = useCallback((options: TrackConversionOptions) => {\n const doTrack = async () => {\n const { apiUrl: globalApiUrl, apiKey: globalApiKey } = getApiConfig()\n const apiUrl = propApiUrl || globalApiUrl\n const apiKey = propApiKey || globalApiKey\n \n if (!apiKey) {\n if (debug) console.warn('[Analytics] No API key configured')\n return\n }\n \n const conversion = {\n sessionId: sessionIdRef.current,\n visitorId: visitorIdRef.current,\n site,\n conversionType: options.type,\n value: options.value,\n currency: options.currency,\n metadata: options.metadata,\n pagePath: pathname,\n referrer: document.referrer || null,\n deviceType: getDeviceType(),\n }\n \n if (debug) {\n console.log('[Analytics] Conversion:', conversion)\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/analytics/conversion`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(conversion),\n })\n \n if (!response.ok && debug) {\n console.error('[Analytics] Error tracking conversion:', response.statusText)\n }\n } catch (error) {\n if (debug) console.error('[Analytics] Error tracking conversion:', error)\n }\n }\n \n // Conversions run immediately (not deferred) since they're high-value events\n doTrack()\n }, [propApiUrl, propApiKey, pathname, debug])\n \n // Bridge for code outside this provider's tree (the childless-sibling\n // mount pattern leaves the whole page un-provided): register the REAL\n // track functions with the standalone dispatch module, which queues any\n // calls made before this (idle-deferred) provider mounted.\n useEffect(() => {\n registerAnalyticsDispatcher({ trackEvent, trackConversion })\n return () => registerAnalyticsDispatcher(null)\n }, [trackEvent, trackConversion])\n\n const contextValue = useMemo<AnalyticsContextValue>(() => ({\n trackEvent,\n trackConversion,\n sessionId: sessionIdRef.current,\n visitorId: visitorIdRef.current,\n }), [trackEvent, trackConversion])\n \n return (\n <AnalyticsContext.Provider value={contextValue}>\n {trackWebVitals && (\n <WebVitals\n apiUrl={propApiUrl}\n apiKey={propApiKey}\n site={site}\n debug={debug}\n />\n )}\n {children}\n </AnalyticsContext.Provider>\n )\n}\n\n// ============================================\n// Hooks\n// ============================================\n\nexport function useAnalytics(): AnalyticsContextValue {\n const context = useContext(AnalyticsContext)\n if (!context) {\n throw new Error('useAnalytics must be used within an AnalyticsProvider')\n }\n return context\n}\n\n/**\n * Safe version of useAnalytics that returns null when used outside of AnalyticsProvider.\n * Use this in components that may be rendered without an AnalyticsProvider in the tree.\n */\nexport function useAnalyticsOptional(): AnalyticsContextValue | null {\n return useContext(AnalyticsContext)\n}\n\nexport function useTrackEvent() {\n const { trackEvent, trackConversion } = useAnalytics()\n return { trackEvent, trackConversion }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":["useState","useCallback","useEffect","jsx","jsxs"],"mappings":"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","file":"chunk-IFVMZFNT.js","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await fetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n console.error('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/files?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.error('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n }\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.error('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n const res = await fetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n headers: {\n 'x-api-key': config.apiKey,\n },\n body: formData,\n })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.error('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n method: 'DELETE',\n headers: {\n 'x-api-key': config.apiKey,\n },\n }\n )\n onSelect()\n } catch (err) {\n console.error('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await fetch(\n `${config.apiUrl}/public/images?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/files?${params}`,\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n const res = await fetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n headers: {\n 'x-api-key': config.apiKey,\n },\n body: formData,\n })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': config.apiKey,\n },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await fetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n {\n method: 'DELETE',\n headers: {\n 'x-api-key': config.apiKey,\n },\n }\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":"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","file":"chunk-KMZ527EM.mjs","sourcesContent":["'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) via\n * SiteKitIdentityProvider, ensuring consistent tracking across Analytics,\n * Signal, and Engage.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n SiteKitIdentityProvider,\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\n// Defer non-critical module mounting until the page is quiet: the lazy\n// modules below are dynamic(ssr:false) and never render on the server, but\n// rendering them during hydration still kicks off their chunk downloads +\n// mount effects inside the critical startup window. useDeferredActivation\n// holds them until window.load + idle or first interaction — the same\n// strategy as the hand-rolled per-site deferrals this replaces (upforge\n// `deferred-analytics.tsx`, TPS `DeferredAnalytics.tsx`). The hook is public\n// (`@sonordev/site-kit/client`) so sites can reuse it for their own scripts.\nimport { useDeferredActivation } from '../shared/defer'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n// SignalBridge is imported STATICALLY, not via dynamic(ssr:false): it is a\n// tiny SSR-safe context shell that renders children immediately and\n// lazy-loads its machinery (SignalCore) as a childless sibling internally.\n// Wrapping children in a dynamic(ssr:false) component was the old SSR-bailout\n// failure mode — do not reintroduce it.\nimport { SignalBridge } from '../signal/SignalBridge'\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n sitemapSync?: boolean\n /**\n * Defer Analytics / Engage / SitemapSync until window load + idle or first\n * interaction (default true). Pass false to restore legacy eager mounting\n * on hydration. SignalBridge is never deferred — it must apply experiment\n * variants as early as possible.\n */\n defer?: boolean\n debug?: boolean\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n defer = true,\n debug = false,\n}: SiteKitClientProvidersProps) {\n // One shared activation gate for all deferred siblings, so they mount in a\n // single commit instead of staggered re-renders.\n const modulesReady = useDeferredActivation(defer)\n // Hoist analytics config so the `site` dimension is resolvable up here.\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n\n // Resolve the sub-site identifier — the dimension that lets one Sonor project\n // host many sites (e.g. truepowersystems.com + ohiopowerstudies.com under one\n // TPS project). Precedence: explicit `analytics.site` > NEXT_PUBLIC_SITE_URL\n // host > window.location.host. Always a string (possibly empty).\n const explicitSite = analyticsConfig.site\n const envSiteUrl =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_SITE_URL\n : undefined\n let resolvedSite = explicitSite ?? ''\n if (!resolvedSite && envSiteUrl) {\n try {\n resolvedSite = new URL(envSiteUrl).host\n } catch {\n /* malformed URL — fall through to client-side host */\n }\n }\n if (!resolvedSite && typeof window !== 'undefined') {\n resolvedSite = window.location.host\n }\n const site = resolvedSite\n\n // Set window globals for modules that still read from them.\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n ;(window as any).__SITE_KIT_SITE__ = site\n }\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled. Safe to wrap: the shell is SSR-safe\n // and renders children straight through — the heavy machinery mounts as a\n // childless sibling inside it. Not gated on modulesReady: experiment\n // variants must apply as early as possible.\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n content = (\n <SignalBridge\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n >\n {content}\n </SignalBridge>\n )\n }\n\n // Add Analytics if enabled (renders alongside, doesn't wrap).\n //\n // CRITICAL: LazyAnalyticsProvider is dynamic(..., { ssr: false }). Wrapping\n // {content} inside an ssr:false component makes the entire page tree skip\n // server rendering — the route de-opts to 100% client rendering and the\n // hero / LCP element only paints after hydration (mobile LCP ~4s, Lighthouse\n // ~85). Analytics tracks via effects + a metadata ref, so it never needs to\n // wrap page content — mount it as a childless sibling, exactly like Engage.\n // Each deferred sibling is appended as `{modulesReady && <Module/>}` so the\n // children slot never moves in the tree — flipping ready only mounts the\n // sibling, it never remounts page content.\n if (analytics) {\n content = (\n <>\n {content}\n {modulesReady && (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n sessionTimeout={analyticsConfig.sessionDuration}\n excludePaths={analyticsConfig.excludePaths}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n />\n </Suspense>\n )}\n </>\n )\n }\n\n // Add Engage widget if enabled (renders alongside, doesn't wrap)\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n content = (\n <>\n {content}\n {modulesReady && (\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n zIndex={engageConfig.zIndex}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n )}\n </>\n )\n }\n\n // Add SitemapSync if enabled\n if (sitemapSync) {\n content = (\n <>\n {content}\n {modulesReady && <LazySitemapSync debug={debug} />}\n </>\n )\n }\n\n return (\n <SiteKitIdentityProvider visitorId={visitorId} sessionId={sessionId}>\n {content}\n </SiteKitIdentityProvider>\n )\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/forms/useFormTracking.ts","../src/forms/defaultSuccessMessage.ts","../src/forms/fetchWithRetry.ts","../src/forms/recaptcha.ts","../src/forms/submitForm.ts","../src/forms/useForm.ts"],"names":["useRef","useEffect","useCallback","useState","useMemo"],"mappings":";;;;;AAuBO,SAAS,eAAA,CAAgB;AAAA,EAC9B,MAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA,GAAU,IAAA;AAAA,EACV,KAAA,GAAQ;AACV,CAAA,EAA+C;AAC7C,EAAA,MAAM,YAAA,GAAeA,aAAe,EAAE,CAAA;AACtC,EAAA,MAAM,YAAA,GAAeA,aAAe,CAAC,CAAA;AACrC,EAAA,MAAM,gBAAA,GAAmBA,aAAe,CAAC,CAAA;AACzC,EAAA,MAAM,YAAA,GAAeA,YAAA,CAA+B,EAAE,CAAA;AACtD,EAAA,MAAM,cAAA,GAAiBA,aAAe,CAAC,CAAA;AACvC,EAAA,MAAM,UAAA,GAAaA,aAAe,CAAC,CAAA;AACnC,EAAA,MAAM,cAAA,GAAiBA,aAAsB,IAAI,CAAA;AAGjD,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,2CAA2C,CAAA;AACnE,MAAA;AAAA,IACF;AAGA,IAAA,YAAA,CAAa,OAAA,GAAU,OAAO,UAAA,EAAW;AACzC,IAAA,YAAA,CAAa,OAAA,GAAU,KAAK,GAAA,EAAI;AAChC,IAAA,gBAAA,CAAiB,OAAA,GAAU,KAAK,GAAA,EAAI;AAGpC,IAAA,MAAM,gBAAgB,YAAY;AAChC,MAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAC/B,MAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAE/B,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AACtB,QAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,oCAAoC,CAAA;AAC7D,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,iCAAA,CAAA,EAAqC;AAAA,UACzE,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS;AAAA,YACP,cAAA,EAAgB,kBAAA;AAAA,YAChB,WAAA,EAAa;AAAA,WACf;AAAA,UACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,YACnB,MAAA;AAAA,YACA,WAAW,YAAA,CAAa,OAAA;AAAA,YACxB,YAAY,aAAA;AAAc,WAC3B;AAAA,SACF,CAAA;AAED,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,MAAM,IAAI,MAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,QACnE;AAEA,QAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,QAAA,cAAA,CAAe,UAAU,IAAA,CAAK,EAAA;AAC9B,QAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,2BAAA,EAA6B,KAAK,EAAE,CAAA;AAAA,MAC7D,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,kCAAA,EAAoC,KAAK,CAAA;AAAA,MACpE;AAAA,IACF,CAAA;AAEA,IAAA,aAAA,EAAc;AAGd,IAAA,MAAM,qBAAqB,MAAM;AAC/B,MAAA,IAAI,CAAC,eAAe,OAAA,EAAS;AAE7B,MAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAC/B,MAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAE/B,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AAExB,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,MAAM,kBAAkB,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,gBAAA,CAAiB,WAAW,GAAI,CAAA;AAC1E,MAAA,YAAA,CAAa,OAAA,CAAQ,cAAA,CAAe,OAAO,CAAA,GAAI,eAAA;AAG/C,MAAA,MAAM,OAAA,GAAU,KAAK,SAAA,CAAU;AAAA,QAC7B,aAAa,cAAA,CAAe,OAAA;AAAA,QAC5B,MAAM,cAAA,CAAe,OAAA;AAAA,QACrB,SAAS,UAAA,CAAW,OAAA;AAAA,QACpB,WAAW,YAAA,CAAa,OAAA;AAAA,QACxB,kBAAkB,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,YAAA,CAAa,WAAW,GAAI;AAAA,OACjE,CAAA;AAED,MAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,kBAAA,EAAoB,CAAA;AAE7D,MAAiB,IAAI,OAAA,CAAQ;AAAA,QAC3B,cAAA,EAAgB,kBAAA;AAAA,QAChB,WAAA,EAAa;AAAA,OACd;AAGD,MAAA,MAAM,OAAO,SAAA,CAAU,UAAA;AAAA,QACrB,GAAG,MAAM,CAAA,mCAAA,CAAA;AAAA,QACT;AAAA,OACF;AAEA,MAAA,IAAI,OAAO,OAAA,CAAQ,GAAA,CAAI,8BAAA,EAAgC,IAAA,GAAO,YAAY,QAAQ,CAAA;AAAA,IACpF,CAAA;AAEA,IAAA,MAAA,CAAO,gBAAA,CAAiB,gBAAgB,kBAAkB,CAAA;AAE1D,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,gBAAgB,kBAAkB,CAAA;AAAA,IAC/D,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,OAAA,EAAS,KAAK,CAAC,CAAA;AAG3B,EAAA,MAAM,eAAA,GAAkBC,iBAAA,CAAY,OAAO,IAAA,KAAiB;AAC1D,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,cAAA,CAAe,OAAA,EAAS;AAEzC,IAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAC/B,IAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAE/B,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AACtB,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,oCAAoC,CAAA;AAC7D,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAGrB,IAAA,MAAM,eAAe,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,gBAAA,CAAiB,WAAW,GAAI,CAAA;AACvE,IAAA,YAAA,CAAa,OAAA,CAAQ,cAAA,CAAe,OAAO,CAAA,GAAI,YAAA;AAG/C,IAAA,cAAA,CAAe,OAAA,GAAU,IAAA;AACzB,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,UAAA,CAAW,SAAS,IAAI,CAAA;AACtD,IAAA,gBAAA,CAAiB,OAAA,GAAU,GAAA;AAG3B,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,gCAAA,CAAA,EAAoC;AAAA,QACxE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,WAAA,EAAa;AAAA,SACf;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,aAAa,cAAA,CAAe,OAAA;AAAA,UAC5B,IAAA;AAAA,UACA,SAAS,UAAA,CAAW,OAAA;AAAA,UACpB,WAAW,YAAA,CAAa;AAAA,SACzB;AAAA,OACF,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,MAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,MACnE;AAEA,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,0BAAA,EAA4B,IAAI,CAAA;AAAA,IACzD,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,8BAAA,EAAgC,KAAK,CAAA;AAAA,IAChE;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,KAAK,CAAC,CAAA;AAGnB,EAAA,MAAM,aAAA,GAAgBA,kBAAY,YAAY;AAC5C,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,cAAA,CAAe,OAAA,EAAS;AAEzC,IAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAC/B,IAAA,MAAM,SAAU,MAAA,CAAe,oBAAA;AAE/B,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AACtB,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,oCAAoC,CAAA;AAC7D,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AAGrB,IAAA,MAAM,gBAAgB,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,gBAAA,CAAiB,WAAW,GAAI,CAAA;AACxE,IAAA,YAAA,CAAa,OAAA,CAAQ,cAAA,CAAe,OAAO,CAAA,GAAI,aAAA;AAE/C,IAAA,IAAI;AAIF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,oCAAA,CAAA,EAAwC;AAAA,QAC5E,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,WAAA,EAAa;AAAA,SACf;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,aAAa,cAAA,CAAe,OAAA;AAAA,UAC5B,UAAA;AAAA,UACA,WAAW,YAAA,CAAa,OAAA;AAAA,UACxB,kBAAkB,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,YAAA,CAAa,WAAW,GAAI;AAAA,SACjE;AAAA,OACF,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,MAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,MACnE;AAEA,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,8CAA8C,CAAA;AAGrE,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,gCAAA,CAAA,EAAoC;AAAA,UACvD,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS;AAAA,YACP,cAAA,EAAgB,kBAAA;AAAA,YAChB,WAAA,EAAa;AAAA,WACf;AAAA,UACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,YACnB,WAAW,YAAA,CAAa,OAAA;AAAA,YACxB,cAAA,EAAgB,iBAAA;AAAA,YAChB,QAAA,EAAU,EAAE,MAAA,EAAQ,WAAA,EAAa,eAAe,OAAA,EAAQ;AAAA,YACxD,UAAU,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,QAAA,GAAW,GAAA;AAAA,YACrE,UAAU,OAAO,QAAA,KAAa,WAAA,GAAc,QAAA,CAAS,YAAY,IAAA,GAAO,IAAA;AAAA,YACxE,YAAY,aAAA;AAAc,WAC3B;AAAA,SACF,CAAA;AAAA,MACH,SAAS,OAAA,EAAS;AAChB,QAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,qCAAA,EAAuC,OAAO,CAAA;AAAA,MACzE;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,oCAAA,EAAsC,KAAK,CAAA;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,OAAA,EAAS,UAAA,EAAY,MAAA,EAAQ,KAAK,CAAC,CAAA;AAEvC,EAAA,OAAO;AAAA,IACL,eAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAW,YAAA,CAAa;AAAA,GAC1B;AACF;AAGA,SAAS,aAAA,GAAiD;AACxD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,SAAA;AAC1C,EAAA,MAAM,KAAK,SAAA,CAAU,SAAA;AACrB,EAAA,IAAI,4BAAA,CAA6B,IAAA,CAAK,EAAE,CAAA,EAAG,OAAO,QAAA;AAClD,EAAA,IAAI,4DAAA,CAA6D,IAAA,CAAK,EAAE,CAAA,EAAG,OAAO,QAAA;AAClF,EAAA,OAAO,SAAA;AACT;;;ACtQO,IAAM,4BAAA,GACX;;;ACgBF,SAAS,YAAA,CAAa,SAAiB,QAAA,EAA6B;AAElE,EAAA,IAAI,QAAA,EAAU,WAAW,GAAA,EAAK;AAC5B,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AACjD,IAAA,MAAM,OAAA,GAAU,MAAA,GAAS,QAAA,CAAS,MAAA,EAAQ,EAAE,CAAA,GAAI,GAAA;AAChD,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,IAAK,OAAA,GAAU,CAAA,EAAG,OAAO,IAAA,CAAK,GAAA,CAAI,OAAA,GAAU,GAAA,EAAM,GAAK,CAAA;AAAA,EAClF;AAEA,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,EAAM,GAAA,GAAM,KAAK,OAAO,CAAA;AAC1C;AASA,eAAsB,cAAA,CACpB,GAAA,EACA,IAAA,EACA,OAAA,GAA6B,EAAC,EACX;AACnB,EAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,IAAW,CAAA;AACnC,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,IAAA;AACvC,EAAA,IAAI,SAAA;AAEJ,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,OAAA,EAAS,OAAA,EAAA,EAAW;AACnD,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAC5D,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,MAAA,YAAA,CAAa,KAAK,CAAA;AAElB,MAAA,IAAA,CAAK,SAAS,MAAA,KAAW,GAAA,IAAO,SAAS,MAAA,IAAU,GAAA,KAAQ,UAAU,OAAA,EAAS;AAC5E,QAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY,UAAA,CAAW,SAAS,YAAA,CAAa,OAAA,EAAS,QAAQ,CAAC,CAAC,CAAA;AACnF,QAAA;AAAA,MACF;AACA,MAAA,OAAO,QAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,SAAA,GAAY,KAAA;AAEZ,MAAA,IAAI,UAAU,OAAA,EAAS;AACrB,QAAA,MAAM,IAAI,QAAQ,CAAC,OAAA,KAAY,WAAW,OAAA,EAAS,YAAA,CAAa,OAAO,CAAC,CAAC,CAAA;AACzE,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,YAAqB,KAAA,GACvB,SAAA,GACA,IAAI,MAAM,mEAAmE,CAAA;AACnF;;;AC/DA,SAAS,WAAW,eAAA,EAA8C;AAChE,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,MAAA;AAC1C,EAAA,IAAI,iBAAiB,OAAO,eAAA;AAC5B,EAAA,MAAM,GAAA,GAAM,MAAA;AACZ,EAAA,OAAO,GAAA,CAAI,+BAAA,IAAmC,OAAA,CAAQ,GAAA,CAAI,8BAAA;AAC5D;AAGA,IAAM,yBAAA,GAA4B,GAAA;AAElC,SAAS,WAAW,OAAA,EAA+B;AACjD,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA;AAAA,IACF;AACA,IAAA,MAAM,GAAA,GAAM,MAAA;AACZ,IAAA,IAAI,GAAA,CAAI,YAAY,UAAA,EAAY;AAC9B,MAAA,OAAA,CAAQ,IAAI,UAAU,CAAA;AACtB,MAAA;AAAA,IACF;AAKA,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,MAAM,MAAA,GAAS,CAAC,KAAA,KAAe;AAC7B,MAAA,IAAI,OAAA,EAAS;AACb,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf,CAAA;AACA,IAAA,MAAM,SAAS,UAAA,CAAW,MAAM,MAAA,CAAO,IAAI,GAAG,yBAAyB,CAAA;AAEvE,IAAA,MAAM,eAAe,MAAM;AACzB,MAAA,IAAI,OAAA,EAAS;AACb,MAAA,IAAI,GAAA,CAAI,YAAY,UAAA,EAAY;AAC9B,QAAA,YAAA,CAAa,MAAM,CAAA;AACnB,QAAA,MAAA,CAAO,IAAI,UAAU,CAAA;AACrB,QAAA;AAAA,MACF;AACA,MAAA,UAAA,CAAW,cAAc,EAAE,CAAA;AAAA,IAC7B,CAAA;AAEA,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,qCAAqC,CAAA;AAC7E,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,YAAA,EAAa;AACb,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,GAAM,yDAAyD,OAAO,CAAA,CAAA;AAC7E,IAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,IAAA,MAAA,CAAO,MAAA,GAAS,MAAM,YAAA,EAAa;AACnC,IAAA,MAAA,CAAO,UAAU,MAAM;AACrB,MAAA,YAAA,CAAa,MAAM,CAAA;AACnB,MAAA,MAAA,CAAO,IAAI,CAAA;AAAA,IACb,CAAA;AACA,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA,EAClC,CAAC,CAAA;AACH;AAMA,eAAsB,kBAAkB,eAAA,EAAkD;AACxF,EAAA,MAAM,OAAA,GAAU,WAAW,eAAe,CAAA;AAC1C,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,MAAA,KAAW,aAAa,OAAO,IAAA;AACtD,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GAAa,MAAM,UAAA,CAAW,OAAO,CAAA;AAC3C,IAAA,IAAI,CAAC,UAAA,EAAY,UAAA,EAAY,OAAA,EAAS,OAAO,IAAA;AAC7C,IAAA,MAAM,KAAA,GAAQ,MAAM,UAAA,CAAW,UAAA,CAAW,QAAQ,OAAA,EAAS,EAAE,MAAA,EAAQ,QAAA,EAAU,CAAA;AAC/E,IAAA,OAAO,KAAA,IAAS,IAAA;AAAA,EAClB,SAAS,GAAA,EAAK;AACZ,IAAA,OAAA,CAAQ,IAAA,CAAK,wBAAwB,GAAG,CAAA;AACxC,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;ACnEO,IAAM,sBAAA,GAAyB;AAEtC,SAAS,YAAA,GAA+D;AACtE,EAAA,MAAM,SACJ,OAAO,MAAA,KAAW,WAAA,GACb,MAAA,CAAe,wBAAwB,sBAAA,GACxC,sBAAA;AACN,EAAA,MAAM,MAAA,GACJ,OAAO,MAAA,KAAW,WAAA,GAAe,OAAe,oBAAA,GAAuB,MAAA;AACzE,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAC1B;AAEA,SAAS,YAAA,GAA8C;AACrD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,EAAC;AAC3C,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,MAAA,CAAO,SAAS,MAAM,CAAA;AACzD,EAAA,MAAM,MAAqC,EAAC;AAC5C,EAAA,KAAA,MAAW,OAAO,CAAC,YAAA,EAAc,cAAc,cAAA,EAAgB,UAAA,EAAY,aAAa,CAAA,EAAG;AACzF,IAAA,GAAA,CAAI,GAAG,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AAAA,EAC3B;AACA,EAAA,OAAO,GAAA;AACT;AAoBA,eAAsB,UAAA,CAAW;AAAA,EAC/B,MAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAAqC;AACnC,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,YAAA,EAAa;AACxC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,MAAM,6DAA6D,CAAA;AAAA,EAC/E;AAGA,EAAA,MAAM,iBAAiB,MAAA,CAAO,iBAAA,GAC1B,MAAM,iBAAA,CAAkB,MAAA,CAAO,kBAAkB,CAAA,GACjD,IAAA;AACJ,EAAA,IAAI,MAAA,CAAO,iBAAA,IAAqB,CAAC,cAAA,EAAgB;AAC/C,IAAA,MAAM,IAAI,MAAM,wDAAwD,CAAA;AAAA,EAC1E;AAEA,EAAA,MAAM,iBAAA,GAAoB,OAAO,cAAA,IAAkB,sBAAA;AACnD,EAAA,MAAM,MAAM,YAAA,EAAa;AAEzB,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,QAAQ,MAAA,CAAO,EAAA;AAAA,IACf,SAAS,MAAA,CAAO,EAAA;AAAA,IAChB,IAAA,EAAM;AAAA,MACJ,GAAG,MAAA;AAAA,MACH,GAAI,OAAO,gBAAA,GAAmB,EAAE,CAAC,iBAAiB,GAAG,aAAA,EAAc,GAAI;AAAC,KAC1E;AAAA,IACA,QAAA,EAAU;AAAA,MACR,SAAS,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,IAAA,GAAO,IAAA;AAAA,MAChE,UAAU,OAAO,QAAA,KAAa,WAAA,GAAc,QAAA,CAAS,YAAY,IAAA,GAAO,IAAA;AAAA,MACxE,SAAA,EAAW,OAAO,SAAA,KAAc,WAAA,GAAc,UAAU,SAAA,GAAY,IAAA;AAAA,MACpE,WACE,OAAO,cAAA,KAAmB,cAAc,cAAA,CAAe,OAAA,CAAQ,SAAS,CAAA,GAAI,IAAA;AAAA;AAAA;AAAA;AAAA,MAI9E,WACE,OAAO,YAAA,KAAiB,cAAc,YAAA,CAAa,OAAA,CAAQ,SAAS,CAAA,GAAI,IAAA;AAAA,MAC1E,gBAAgB,cAAA,IAAkB,MAAA;AAAA,MAClC,WAAW,GAAA,CAAI,UAAA;AAAA,MACf,WAAW,GAAA,CAAI,UAAA;AAAA,MACf,aAAa,GAAA,CAAI,YAAA;AAAA;AAAA;AAAA,MAGjB,IAAA,EACE,OAAO,MAAA,KAAW,WAAA,GACb,OAA0C,iBAAA,IAC3C,MAAA,CAAO,SAAS,IAAA,GAChB,MAAA;AAAA,MACN,aAAA,EAAe;AAAA;AACjB,GACF;AAEA,EAAA,MAAM,WAAW,MAAM,cAAA;AAAA,IACrB,GAAG,MAAM,CAAA,wBAAA,CAAA;AAAA,IACT;AAAA,MACE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,aAAA,EAAe,UAAU,MAAM,CAAA;AAAA,OACjC;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,OAAO;AAAA,KAC9B;AAAA,IACA,EAAE,OAAA,EAAS,CAAA,EAAG,SAAA,EAAW,GAAA;AAAM,GACjC;AAEA,EAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AAEnD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,GAAA,GAAA,CACJ,IAAA,EAAM,OAAA,IACN,IAAA,EAAM,KAAA,KACL,QAAA,CAAS,UAAA,IAAc,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAA,CAAA,EAE9C,QAAA,GACA,IAAA,EAAK;AACR,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,MAAM,CAAA,uBAAA,EAA0B,GAAG,CAAA,CAAA,GAAK,CAAA,uBAAA,EAA0B,SAAS,MAAM,CAAA,CAAA;AAAA,KACnF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;;;ACtBO,SAAS,OAAA,CACd,YAAA,EACA,OAAA,GAA0B,EAAC,EACZ;AACf,EAAA,MAAM;AAAA,IACJ,SAAA,EAAW,gBAAA;AAAA,IACX,SAAA;AAAA,IACA,OAAA;AAAA,IACA,gBAAgB,EAAC;AAAA,IACjB;AAAA,GACF,GAAI,OAAA;AAGJ,EAAA,MAAM,YAAY,gBAAA,KACf,OAAO,MAAA,KAAW,WAAA,GAAe,OAAe,uBAAA,GAA0B,MAAA,CAAA;AAG7E,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIC,eAAmC,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAuB,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,MAAA,EAAQ,cAAc,CAAA,GAAIA,eAAkC,aAAa,CAAA;AAChF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,cAAA,CAAiC,EAAE,CAAA;AAC/D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAAS,CAAC,CAAA;AAClC,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,eAAS,KAAK,CAAA;AACtD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAwB,IAAI,CAAA;AAGlE,EAAA,MAAM,eAAA,GAAkBH,aAAO,KAAK,CAAA;AACpC,EAAA,MAAM,YAAA,GAAeA,YAAAA,CAAO,IAAA,CAAK,GAAA,EAAK,CAAA;AAEtC,EAAA,MAAM,UAAA,GAAa,MAAM,WAAA,IAAe,CAAA;AACxC,EAAA,MAAM,WAAA,GAAe,MAAM,aAAA,IAAkB,KAAA;AAE7C,EAAA,MAAM,EAAE,eAAA,EAAiB,aAAA,EAAc,GAAI,eAAA,CAAgB;AAAA,IACzD,MAAA,EAAQ,MAAM,EAAA,IAAM,EAAA;AAAA,IACpB;AAAA,GACD,CAAA;AAGD,EAAAC,gBAAU,MAAM;AACd,IAAA,MAAM,SAAS,OAAO,MAAA,KAAW,WAAA,GAC5B,MAAA,CAAe,wBAAwB,sBAAA,GACxC,sBAAA;AAEJ,IAAA,eAAe,SAAA,GAAY;AACzB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,IAAI,CAAA;AACjB,QAAA,aAAA,CAAc,IAAI,CAAA;AAKlB,QAAA,MAAM,aAAa,MACjB,OAAO,MAAA,KAAW,WAAA,GAAe,OAAe,oBAAA,GAAuB,KAAA,CAAA;AACzE,QAAA,IAAI,SAAS,UAAA,EAAW;AACxB,QAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,EAAA,IAAM,CAAC,QAAQ,CAAA,EAAA,EAAK;AACtC,UAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,MAAM,UAAA,CAAW,CAAA,EAAG,GAAG,CAAC,CAAA;AAC3C,UAAA,MAAA,GAAS,UAAA,EAAW;AAAA,QACtB;AACA,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,MAAM,IAAI,MAAM,yFAAyF,CAAA;AAAA,QAC3G;AAEA,QAAA,MAAM,GAAA,GAAM,GAAG,MAAM,CAAA,wBAAA,CAAA;AACrB,QAAA,MAAM,IAAA,GAAoB;AAAA,UACxB,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS;AAAA,YACP,cAAA,EAAgB,kBAAA;AAAA,YAChB,aAAA,EAAe,UAAU,MAAM,CAAA;AAAA,WACjC;AAAA,UACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,YACnB;AAAA,WACD;AAAA,SACH;AAEA,QAAA,MAAM,QAAA,GAAW,MAAM,cAAA,CAAe,GAAA,EAAK,IAAA,EAAM,EAAE,OAAA,EAAS,CAAA,EAAG,SAAA,EAAW,IAAA,EAAO,CAAA;AAEjF,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,QAChE;AAEA,QAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,QAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,gBAAgB,CAAA;AAE7C,QAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,IAAA,CAAK,kBAAA,EAAoB;AAC5D,UAAA;AAAC,UAAC,MAAA,CAAe,kCAAkC,IAAA,CAAK,kBAAA;AAAA,QAC1D;AAGE,QAAA,IAAI,KAAK,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAQ,CAAA,KAAA,CAAY,EAAE,WAAA,IAAe,CAAA,KAAM,CAAA,CAAE,WAAA,IAAe,CAAA,CAAE,CAAA;AAAA,QACjF;AACA,QAAA,IAAI,KAAK,MAAA,EAAQ;AACf,UAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAQ,CAAA,KAAA,CAAY,EAAE,UAAA,IAAc,CAAA,KAAM,CAAA,CAAE,UAAA,IAAc,CAAA,CAAE,CAAA;AAAA,QAChF;AAGA,QAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,EAAO,MAAA,IAAU,CAAA;AAC1C,QAAA,MAAM,gBAAgB,WAAA,GAAc,CAAA;AAEpC,QAAA,MAAM,UAAA,GACJ,OAAO,IAAA,CAAK,eAAA,KAAoB,WAAW,IAAA,CAAK,eAAA,CAAgB,MAAK,GAAI,EAAA;AAC3E,QAAA,MAAM,eAAA,GACJ,UAAA,KACC,OAAQ,IAAA,CAAqC,cAAA,KAAmB,QAAA,GAC7D,MAAA,CAAQ,IAAA,CAAqC,cAAc,CAAA,CAAE,IAAA,EAAK,GAClE,EAAA,CAAA,IACJ,4BAAA;AAEF,QAAA,OAAA,CAAQ;AAAA,UACN,GAAG,IAAA;AAAA,UACH,eAAA;AAAA,UACA,WAAA;AAAA,UACA;AAAA,SACD,CAAA;AAGD,QAAA,MAAM,WAAoC,EAAC;AAC3C,QAAA,KAAA,MAAW,KAAA,IAAS,IAAA,CAAK,MAAA,IAAU,EAAC,EAAG;AACrC,UAAA,IAAI,KAAA,CAAM,aAAA,KAAkB,KAAA,CAAA,IAAa,KAAA,CAAM,kBAAkB,IAAA,EAAM;AACrE,YAAA,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA,CAAM,aAAA;AAAA,UAC/B;AAAA,QACF;AACA,QAAA,cAAA,CAAe,EAAE,GAAG,QAAA,EAAU,GAAG,eAAe,CAAA;AAAA,MAElD,SAAS,GAAA,EAAK;AACZ,QAAA,aAAA,CAAc,GAAY,CAAA;AAAA,MAC5B,CAAA,SAAE;AACA,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MACpB;AAAA,IACF;AAEA,IAAA,SAAA,EAAU;AAAA,EACZ,CAAA,EAAG,CAAC,YAAA,EAAc,SAAS,CAAC,CAAA;AAG5B,EAAA,MAAM,SAAA,GAAYG,cAAQ,MAAM,IAAA,EAAM,UAAU,EAAC,EAAG,CAAC,IAAI,CAAC,CAAA;AAG1D,EAAA,MAAM,MAAA,GAASA,cAAQ,MAAM;AAC3B,IAAA,IAAI,CAAC,aAAa,OAAO,SAAA;AAEzB,IAAA,MAAM,oBAAoB,IAAA,EAAM,KAAA,EAAO,KAAK,CAAA,CAAA,KAAK,CAAA,CAAE,gBAAgB,IAAI,CAAA;AACvE,IAAA,IAAI,CAAC,mBAAmB,OAAO,SAAA;AAE/B,IAAA,OAAO,UAAU,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAA,KAAY,kBAAkB,EAAE,CAAA;AAAA,EACjE,GAAG,CAAC,IAAA,EAAM,IAAA,EAAM,SAAA,EAAW,WAAW,CAAC,CAAA;AAGvC,EAAA,MAAM,cAAA,GAAiBF,iBAAAA,CAAY,CAAC,KAAA,KAA8B;AAChE,IAAA,IAAI,CAAC,KAAA,CAAM,WAAA,EAAa,SAAA,EAAW,OAAO,IAAA;AAE1C,IAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAW,UAAU,KAAA,EAAM,GAAI,MAAM,WAAA,CAAY,SAAA;AAChE,IAAA,MAAM,UAAA,GAAa,OAAO,SAAS,CAAA;AAEnC,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,QAAA;AACH,QAAA,OAAO,UAAA,KAAe,KAAA;AAAA,MACxB,KAAK,YAAA;AACH,QAAA,OAAO,UAAA,KAAe,KAAA;AAAA,MACxB,KAAK,UAAA;AACH,QAAA,OAAO,OAAO,UAAA,IAAc,EAAE,EAAE,QAAA,CAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MACxD,KAAK,cAAA;AACH,QAAA,OAAO,CAAC,OAAO,UAAA,IAAc,EAAE,EAAE,QAAA,CAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MACzD,KAAK,UAAA;AACH,QAAA,OAAO,CAAC,cAAc,UAAA,KAAe,EAAA;AAAA,MACvC,KAAK,WAAA;AACH,QAAA,OAAO,CAAC,CAAC,UAAA,IAAc,UAAA,KAAe,EAAA;AAAA,MACxC,KAAK,cAAA;AACH,QAAA,OAAO,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,MAC1C,KAAK,WAAA;AACH,QAAA,OAAO,MAAA,CAAO,UAAU,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,MAC1C;AACE,QAAA,OAAO,IAAA;AAAA;AACX,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,MAAM,aAAA,GAAgBE,cAAQ,MAAM;AAClC,IAAA,OAAO,MAAA,CAAO,OAAO,cAAc,CAAA;AAAA,EACrC,CAAA,EAAG,CAAC,MAAA,EAAQ,cAAc,CAAC,CAAA;AAG3B,EAAA,MAAM,aAAA,GAAgBF,iBAAAA,CAAY,CAAC,KAAA,KAAoC;AACrE,IAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG,OAAO,IAAA;AAEnC,IAAA,IAAI,CAAC,SAAA,EAAW,gBAAA,EAAkB,WAAA,EAAa,QAAQ,EAAE,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA,EAAG,OAAO,IAAA;AAE5F,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAC/B,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,UAAA,IAAc,EAAC;AAGnC,IAAA,IAAI,KAAA,CAAM,WAAA,KAAgB,CAAC,KAAA,IAAS,UAAU,EAAA,CAAA,EAAK;AACjD,MAAA,OAAO,KAAA,CAAM,YAAA,IAAgB,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,YAAA,CAAA;AAAA,IAC7C;AAEA,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAEnB,IAAA,MAAM,QAAA,GAAW,OAAO,KAAK,CAAA;AAG7B,IAAA,IAAI,KAAA,CAAM,UAAA,IAAc,QAAA,CAAS,MAAA,GAAS,MAAM,UAAA,EAAY;AAC1D,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,kBAAA,EAAqB,MAAM,UAAU,CAAA,WAAA,CAAA;AAAA,IAC5D;AACA,IAAA,IAAI,KAAA,CAAM,UAAA,IAAc,QAAA,CAAS,MAAA,GAAS,MAAM,UAAA,EAAY;AAC1D,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,sBAAA,EAAyB,MAAM,UAAU,CAAA,WAAA,CAAA;AAAA,IAChE;AAGA,IAAA,IAAI,MAAM,GAAA,KAAQ,MAAA,IAAa,OAAO,KAAK,CAAA,GAAI,MAAM,GAAA,EAAK;AACxD,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,kBAAA,EAAqB,MAAM,GAAG,CAAA,CAAA;AAAA,IACrD;AACA,IAAA,IAAI,MAAM,GAAA,KAAQ,MAAA,IAAa,OAAO,KAAK,CAAA,GAAI,MAAM,GAAA,EAAK;AACxD,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,sBAAA,EAAyB,MAAM,GAAG,CAAA,CAAA;AAAA,IACzD;AAGA,IAAA,IAAI,MAAM,OAAA,EAAS;AACjB,MAAA,IAAI;AACF,QAAA,IAAI,CAAC,IAAI,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,CAAE,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC7C,UAAA,OAAO,KAAA,CAAM,YAAA,IAAgB,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,WAAA,CAAA;AAAA,QAC7C;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,UAAA,KAAe,OAAA,IAAW,CAAC,4BAAA,CAA6B,IAAA,CAAK,QAAQ,CAAA,EAAG;AAChF,MAAA,OAAO,oCAAA;AAAA,IACT;AAGA,IAAA,IAAI,MAAM,UAAA,KAAe,OAAA,IAAW,CAAC,mBAAA,CAAoB,IAAA,CAAK,QAAQ,CAAA,EAAG;AACvE,MAAA,OAAO,mCAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAA,EAAQ,cAAc,CAAC,CAAA;AAG3B,EAAA,MAAM,QAAA,GAAWA,kBAAY,MAAe;AAC1C,IAAA,MAAM,YAAoC,EAAC;AAE3C,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,KAAA,GAAQ,cAAc,KAAK,CAAA;AACjC,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAAA,MAC1B;AAAA,IACF;AAEA,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,KAAW,CAAA;AAAA,EAC3C,CAAA,EAAG,CAAC,MAAA,EAAQ,aAAa,CAAC,CAAA;AAI1B,EAAA,MAAM,WAAA,GAAcA,kBAAY,MAAe;AAC7C,IAAA,MAAM,YAAoC,EAAC;AAC3C,IAAA,KAAA,MAAW,SAAS,SAAA,EAAW;AAC7B,MAAA,MAAM,KAAA,GAAQ,cAAc,KAAK,CAAA;AACjC,MAAA,IAAI,KAAA,EAAO,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAAA,IACrC;AACA,IAAA,SAAA,CAAU,SAAS,CAAA;AACnB,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,KAAW,CAAA;AAAA,EAC3C,CAAA,EAAG,CAAC,SAAA,EAAW,aAAa,CAAC,CAAA;AAG7B,EAAA,MAAM,kBAAA,GAAqBA,kBAAY,MAA+B;AACpE,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,SAAS,SAAA,EAAW;AAC7B,MAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG;AAC5B,MAAA,IAAI,KAAA,CAAM,QAAQ,MAAA,EAAQ,GAAA,CAAI,MAAM,IAAI,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAAA,IAC/D;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,SAAA,EAAW,MAAA,EAAQ,cAAc,CAAC,CAAA;AAGtC,EAAA,MAAM,aAAA,GAAgBA,iBAAAA,CAAY,CAAC,GAAA,EAAa,KAAA,KAAmB;AACjE,IAAA,cAAA,CAAe,CAAA,IAAA,MAAS,EAAE,GAAG,IAAA,EAAM,CAAC,GAAG,GAAG,OAAM,CAAE,CAAA;AAElD,IAAA,SAAA,CAAU,CAAA,IAAA,KAAQ;AAChB,MAAA,IAAI,IAAA,CAAK,GAAG,CAAA,EAAG;AACb,QAAA,MAAM,IAAA,GAAO,EAAE,GAAG,IAAA,EAAK;AACvB,QAAA,OAAO,KAAK,GAAG,CAAA;AACf,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAY,CAAC,SAAA,KAAuC;AACpE,IAAA,cAAA,CAAe,WAAS,EAAE,GAAG,IAAA,EAAM,GAAG,WAAU,CAAE,CAAA;AAAA,EACpD,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,WAAA,GAAcA,kBAAY,MAAM;AACpC,IAAA,SAAA,CAAU,EAAE,CAAA;AAAA,EACd,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,YAAY,IAAA,GAAO,UAAA;AACzB,EAAA,MAAM,YAAY,IAAA,GAAO,CAAA;AACzB,EAAA,MAAM,aAAa,IAAA,KAAS,UAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAO,IAAA,GAAO,aAAc,GAAG,CAAA;AAErD,EAAA,MAAM,QAAA,GAAWA,kBAAY,MAAe;AAC1C,IAAA,IAAI,CAAC,QAAA,EAAS,EAAG,OAAO,KAAA;AAExB,IAAA,IAAI,OAAO,UAAA,EAAY;AACrB,MAAA,MAAM,UAAU,IAAA,GAAO,CAAA;AACvB,MAAA,OAAA,CAAQ,OAAO,CAAA;AACf,MAAA,eAAA,CAAgB,OAAO,CAAA;AACvB,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT,GAAG,CAAC,IAAA,EAAM,UAAA,EAAY,QAAA,EAAU,eAAe,CAAC,CAAA;AAEhD,EAAA,MAAM,QAAA,GAAWA,kBAAY,MAAM;AACjC,IAAA,IAAI,OAAO,CAAA,EAAG;AACZ,MAAA,MAAM,UAAU,IAAA,GAAO,CAAA;AACvB,MAAA,OAAA,CAAQ,OAAO,CAAA;AACf,MAAA,eAAA,CAAgB,OAAO,CAAA;AAAA,IACzB;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,eAAe,CAAC,CAAA;AAE1B,EAAA,MAAM,QAAA,GAAWA,iBAAAA,CAAY,CAAC,UAAA,KAAuB;AACnD,IAAA,IAAI,UAAA,IAAc,CAAA,IAAK,UAAA,IAAc,UAAA,EAAY;AAC/C,MAAA,OAAA,CAAQ,UAAU,CAAA;AAClB,MAAA,eAAA,CAAgB,UAAU,CAAA;AAAA,IAC5B;AAAA,EACF,CAAA,EAAG,CAAC,UAAA,EAAY,eAAe,CAAC,CAAA;AAGhC,EAAA,MAAM,MAAA,GAASA,kBAAY,YAAY;AACrC,IAAA,IAAI,CAAC,IAAA,EAAM;AAEX,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC7B,IAAA,IAAI,CAAC,aAAY,EAAG;AAEpB,IAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,IAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,IAAA,cAAA,CAAe,IAAI,CAAA;AAEnB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW;AAAA,QAC5B,MAAA,EAAQ,IAAA;AAAA,QACR,QAAQ,kBAAA,EAAmB;AAAA,QAC3B,aAAA,EAAe,EAAA;AAAA,QACf,cAAc,YAAA,CAAa;AAAA,OAC5B,CAAA;AAED,MAAA,aAAA,EAAc;AACd,MAAA,aAAA,CAAc,IAAI,CAAA;AAClB,MAAA,SAAA,GAAY,IAAsB,CAAA;AAElC,MAAA,MAAM,aAAA,GAAgB,WAAA,KAAgB,KAAA,GACjC,WAAA,IAAe,KAAK,YAAA,GACrB,KAAA,CAAA;AACJ,MAAA,IAAI,aAAA,EAAe;AACjB,QAAA,MAAA,CAAO,SAAS,IAAA,GAAO,aAAA;AAAA,MACzB;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,MAAA,cAAA,CAAe,iEAAiE,CAAA;AAChF,MAAA,OAAA,GAAU,KAAc,CAAA;AAAA,IAC1B,CAAA,SAAE;AACA,MAAA,eAAA,CAAgB,OAAA,GAAU,KAAA;AAC1B,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,WAAA,EAAa,oBAAoB,aAAA,EAAe,SAAA,EAAW,OAAA,EAAS,WAAW,CAAC,CAAA;AAG1F,EAAA,MAAM,KAAA,GAAQA,kBAAY,MAAM;AAC9B,IAAA,cAAA,CAAe,aAAa,CAAA;AAC5B,IAAA,SAAA,CAAU,EAAE,CAAA;AACZ,IAAA,OAAA,CAAQ,CAAC,CAAA;AACT,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,cAAA,CAAe,IAAI,CAAA;AAAA,EACrB,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IAEA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA;AAAA,IAEA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IAEA,IAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IAEA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IAEA,QAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IAEA,MAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF","file":"chunk-MLJXELPA.js","sourcesContent":["/**\n * @sonordev/site-kit/forms - Form Tracking Hook\n * \n * Tracks form analytics including step progress and abandonment\n */\n\n'use client'\n\nimport { useEffect, useRef, useCallback } from 'react'\n\ninterface UseFormTrackingOptions {\n formId: string\n totalSteps: number\n enabled?: boolean\n debug?: boolean\n}\n\ninterface FormTrackingReturn {\n trackStepChange: (step: number) => void\n trackComplete: () => void\n sessionId: string\n}\n\nexport function useFormTracking({\n formId,\n totalSteps,\n enabled = true,\n debug = false,\n}: UseFormTrackingOptions): FormTrackingReturn {\n const sessionIdRef = useRef<string>('')\n const startTimeRef = useRef<number>(0)\n const stepStartTimeRef = useRef<number>(0)\n const stepTimesRef = useRef<Record<number, number>>({})\n const currentStepRef = useRef<number>(1)\n const maxStepRef = useRef<number>(1)\n const analyticsIdRef = useRef<string | null>(null)\n \n // Initialize tracking\n useEffect(() => {\n if (!enabled) return\n if (!formId) {\n if (debug) console.warn('[Forms] Tracking skipped: formId is empty')\n return\n }\n \n // Generate session ID\n sessionIdRef.current = crypto.randomUUID()\n startTimeRef.current = Date.now()\n stepStartTimeRef.current = Date.now()\n \n // Record form start\n const startTracking = async () => {\n const apiUrl = (window as any).__SITE_KIT_API_URL__\n const apiKey = (window as any).__SITE_KIT_API_KEY__\n \n if (!apiUrl || !apiKey) {\n if (debug) console.error('[Forms] Missing API URL or API key')\n return\n }\n \n try {\n const response = await fetch(`${apiUrl}/api/public/forms/analytics/start`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n formId,\n sessionId: sessionIdRef.current,\n deviceType: getDeviceType(),\n }),\n })\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n \n const data = await response.json()\n analyticsIdRef.current = data.id\n if (debug) console.log('[Forms] Started tracking:', data.id)\n } catch (error) {\n if (debug) console.error('[Forms] Error starting tracking:', error)\n }\n }\n \n startTracking()\n \n // Handle abandonment on page leave\n const handleBeforeUnload = () => {\n if (!analyticsIdRef.current) return\n \n const apiUrl = (window as any).__SITE_KIT_API_URL__\n const apiKey = (window as any).__SITE_KIT_API_KEY__\n \n if (!apiUrl || !apiKey) return\n \n const now = Date.now()\n const currentStepTime = Math.floor((now - stepStartTimeRef.current) / 1000)\n stepTimesRef.current[currentStepRef.current] = currentStepTime\n \n // Use sendBeacon for reliable delivery during page unload\n const payload = JSON.stringify({\n analyticsId: analyticsIdRef.current,\n step: currentStepRef.current,\n maxStep: maxStepRef.current,\n stepTimes: stepTimesRef.current,\n totalTimeSeconds: Math.floor((now - startTimeRef.current) / 1000),\n })\n \n const blob = new Blob([payload], { type: 'application/json' })\n // Note: sendBeacon doesn't support custom headers, API key included in URL\n const _headers = new Headers({\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n })\n \n // Try sendBeacon first (more reliable during unload)\n const sent = navigator.sendBeacon(\n `${apiUrl}/api/public/forms/analytics/abandon`,\n blob\n )\n \n if (debug) console.log('[Forms] Abandonment tracked:', sent ? 'success' : 'failed')\n }\n \n window.addEventListener('beforeunload', handleBeforeUnload)\n \n return () => {\n window.removeEventListener('beforeunload', handleBeforeUnload)\n }\n }, [formId, enabled, debug])\n \n // Track step changes\n const trackStepChange = useCallback(async (step: number) => {\n if (!enabled || !analyticsIdRef.current) return\n \n const apiUrl = (window as any).__SITE_KIT_API_URL__\n const apiKey = (window as any).__SITE_KIT_API_KEY__\n \n if (!apiUrl || !apiKey) {\n if (debug) console.error('[Forms] Missing API URL or API key')\n return\n }\n \n const now = Date.now()\n \n // Record time spent on previous step\n const prevStepTime = Math.floor((now - stepStartTimeRef.current) / 1000)\n stepTimesRef.current[currentStepRef.current] = prevStepTime\n \n // Update refs\n currentStepRef.current = step\n maxStepRef.current = Math.max(maxStepRef.current, step)\n stepStartTimeRef.current = now\n \n // Update database\n try {\n const response = await fetch(`${apiUrl}/api/public/forms/analytics/step`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n analyticsId: analyticsIdRef.current,\n step,\n maxStep: maxStepRef.current,\n stepTimes: stepTimesRef.current,\n }),\n })\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n \n if (debug) console.log('[Forms] Step changed to:', step)\n } catch (error) {\n if (debug) console.error('[Forms] Error updating step:', error)\n }\n }, [enabled, debug])\n \n // Track completion\n const trackComplete = useCallback(async () => {\n if (!enabled || !analyticsIdRef.current) return\n \n const apiUrl = (window as any).__SITE_KIT_API_URL__\n const apiKey = (window as any).__SITE_KIT_API_KEY__\n \n if (!apiUrl || !apiKey) {\n if (debug) console.error('[Forms] Missing API URL or API key')\n return\n }\n \n const now = Date.now()\n \n // Record time for final step\n const finalStepTime = Math.floor((now - stepStartTimeRef.current) / 1000)\n stepTimesRef.current[currentStepRef.current] = finalStepTime\n \n try {\n // Complete form analytics tracking\n // Note: A database trigger will automatically log this as a conversion\n // in analytics_conversions when completed_at is set\n const response = await fetch(`${apiUrl}/api/public/forms/analytics/complete`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n analyticsId: analyticsIdRef.current,\n totalSteps,\n stepTimes: stepTimesRef.current,\n totalTimeSeconds: Math.floor((now - startTimeRef.current) / 1000),\n }),\n })\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n \n if (debug) console.log('[Forms] Form completed, recording conversion')\n\n // Explicitly track as a conversion (don't rely on DB trigger)\n try {\n await fetch(`${apiUrl}/api/public/analytics/conversion`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n sessionId: sessionIdRef.current,\n conversionType: 'form_submission',\n metadata: { formId, analyticsId: analyticsIdRef.current },\n pagePath: typeof window !== 'undefined' ? window.location.pathname : '/',\n referrer: typeof document !== 'undefined' ? document.referrer || null : null,\n deviceType: getDeviceType(),\n }),\n })\n } catch (convErr) {\n if (debug) console.error('[Forms] Error recording conversion:', convErr)\n }\n } catch (error) {\n if (debug) console.error('[Forms] Error completing tracking:', error)\n }\n }, [enabled, totalSteps, formId, debug])\n \n return {\n trackStepChange,\n trackComplete,\n sessionId: sessionIdRef.current,\n }\n}\n\n// Helper\nfunction getDeviceType(): 'desktop' | 'mobile' | 'tablet' {\n if (typeof window === 'undefined') return 'desktop'\n const ua = navigator.userAgent\n if (/tablet|ipad|playbook|silk/i.test(ua)) return 'tablet'\n if (/mobile|iphone|ipod|android|blackberry|opera mini|iemobile/i.test(ua)) return 'mobile'\n return 'desktop'\n}\n\n","/** Shown when the API omits or returns an empty `success_message`. */\nexport const DEFAULT_FORM_SUCCESS_MESSAGE =\n 'Thank you for your submission! We will be in touch soon.'\n","/**\n * @sonordev/site-kit/forms - Resilient fetch\n *\n * Adds a per-attempt timeout and retries transient failures (network errors,\n * request timeouts, HTTP 429, and 5xx) with exponential backoff.\n *\n * A form submission must survive a brief API blip — a deploy, a cold start, a\n * dropped packet. A single un-retried fetch turning into \"Something went wrong\"\n * is how leads get lost.\n */\n\nexport interface FetchRetryOptions {\n /** Number of retries AFTER the first attempt (default 2 → up to 3 tries total). */\n retries?: number\n /** Per-attempt timeout in milliseconds (default 15000). */\n timeoutMs?: number\n}\n\nfunction backoffDelay(attempt: number, response?: Response): number {\n // Honor a Retry-After header on 429 responses when present.\n if (response?.status === 429) {\n const header = response.headers.get('retry-after')\n const seconds = header ? parseInt(header, 10) : NaN\n if (!Number.isNaN(seconds) && seconds > 0) return Math.min(seconds * 1000, 10000)\n }\n // Exponential backoff: 500ms, 1s, 2s, ... capped at 8s.\n return Math.min(8000, 500 * 2 ** attempt)\n}\n\n/**\n * fetch() with a timeout and automatic retries for transient failures.\n *\n * Non-transient responses (2xx, 3xx, and 4xx other than 429) are returned to\n * the caller as-is — only 429/5xx and thrown network/timeout errors are retried.\n * If every attempt fails with a thrown error, the last error is re-thrown.\n */\nexport async function fetchWithRetry(\n url: string,\n init: RequestInit,\n options: FetchRetryOptions = {},\n): Promise<Response> {\n const retries = options.retries ?? 2\n const timeoutMs = options.timeoutMs ?? 15000\n let lastError: unknown\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n try {\n const response = await fetch(url, { ...init, signal: controller.signal })\n clearTimeout(timer)\n\n if ((response.status === 429 || response.status >= 500) && attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, backoffDelay(attempt, response)))\n continue\n }\n return response\n } catch (error) {\n clearTimeout(timer)\n lastError = error\n // Network failure or timeout (AbortController) — retry while attempts remain.\n if (attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, backoffDelay(attempt)))\n continue\n }\n }\n }\n\n throw lastError instanceof Error\n ? lastError\n : new Error('Network request failed after multiple attempts. Please try again.')\n}\n","/**\n * reCAPTCHA Enterprise - Client-side token generation for site-kit forms\n *\n * Site key is read from:\n * - window.__SITE_KIT_RECAPTCHA_SITE_KEY__ (set by SiteKitProvider)\n * - process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY (when bundled in Next.js app)\n */\n\nfunction getSiteKey(explicitSiteKey?: string): string | undefined {\n if (typeof window === 'undefined') return undefined\n if (explicitSiteKey) return explicitSiteKey\n const win = window as any\n return win.__SITE_KIT_RECAPTCHA_SITE_KEY__ ?? process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY\n}\n\n/** Max time to wait for reCAPTCHA Enterprise to become usable before giving up. */\nconst RECAPTCHA_LOAD_TIMEOUT_MS = 10000\n\nfunction loadScript(siteKey: string): Promise<any> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') {\n resolve(null)\n return\n }\n const win = window as any\n if (win.grecaptcha?.enterprise) {\n resolve(win.grecaptcha)\n return\n }\n\n // Never hang the form: if the script is blocked (ad-blocker), stalls, or\n // never initializes `grecaptcha.enterprise`, resolve null after a timeout.\n // The caller treats a null result as \"no token\" rather than waiting forever.\n let settled = false\n const finish = (value: any) => {\n if (settled) return\n settled = true\n resolve(value)\n }\n const giveUp = setTimeout(() => finish(null), RECAPTCHA_LOAD_TIMEOUT_MS)\n\n const waitForReady = () => {\n if (settled) return\n if (win.grecaptcha?.enterprise) {\n clearTimeout(giveUp)\n finish(win.grecaptcha)\n return\n }\n setTimeout(waitForReady, 50)\n }\n\n const existing = document.querySelector('script[src*=\"recaptcha/enterprise\"]')\n if (existing) {\n waitForReady()\n return\n }\n\n const script = document.createElement('script')\n script.src = `https://www.google.com/recaptcha/enterprise.js?render=${siteKey}`\n script.async = true\n script.onload = () => waitForReady()\n script.onerror = () => {\n clearTimeout(giveUp)\n finish(null)\n }\n document.head.appendChild(script)\n })\n}\n\n/**\n * Get a reCAPTCHA Enterprise token for form submission.\n * Returns null if not configured or in SSR.\n */\nexport async function getRecaptchaToken(explicitSiteKey?: string): Promise<string | null> {\n const siteKey = getSiteKey(explicitSiteKey)\n if (!siteKey || typeof window === 'undefined') return null\n try {\n const grecaptcha = await loadScript(siteKey)\n if (!grecaptcha?.enterprise?.execute) return null\n const token = await grecaptcha.enterprise.execute(siteKey, { action: 'submit' })\n return token || null\n } catch (err) {\n console.warn('[site-kit reCAPTCHA]', err)\n return null\n }\n}\n","/**\n * @sonordev/site-kit/forms - Shared submission logic\n *\n * Single source of truth for sending a managed form to the Sonor API. Both\n * <ManagedForm> (via FormClient) and the headless useForm() hook submit through\n * here, so the request shape, retry behaviour, reCAPTCHA handling, and error\n * parsing can never drift between the two paths.\n */\n\nimport { fetchWithRetry } from './fetchWithRetry'\nimport { getRecaptchaToken } from './recaptcha'\nimport type { ManagedFormConfig } from './types'\n\n/**\n * Default honeypot field name. Deliberately obscure — a common name like\n * \"website\" collides with real form fields and gets every genuine submission\n * flagged as spam.\n */\nexport const DEFAULT_HONEYPOT_FIELD = '_sk_hp_url'\n\nfunction getApiConfig(): { apiUrl: string; apiKey: string | undefined } {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n return { apiUrl, apiKey }\n}\n\nfunction getUTMParams(): Record<string, string | null> {\n if (typeof window === 'undefined') return {}\n const params = new URLSearchParams(window.location.search)\n const out: Record<string, string | null> = {}\n for (const key of ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']) {\n out[key] = params.get(key)\n }\n return out\n}\n\nexport interface SubmitFormArgs {\n config: ManagedFormConfig\n /**\n * Field values to submit. The caller must pass VISIBLE values only —\n * conditionally-hidden fields should be excluded so stale values are not sent.\n */\n values: Record<string, unknown>\n /** Honeypot input value (empty string for the headless hook, which has no honeypot UI). */\n honeypotValue: string\n /** Timestamp (ms) the form was first rendered — a weak anti-bot timing signal. */\n formLoadedAt: number\n}\n\n/**\n * Submit a managed form. Throws on failure (network, timeout, or a non-2xx\n * response) with a human-readable message; resolves with the parsed API\n * response on success.\n */\nexport async function submitForm({\n config,\n values,\n honeypotValue,\n formLoadedAt,\n}: SubmitFormArgs): Promise<unknown> {\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) {\n throw new Error('API key is required. Set SONOR_API_KEY in your environment.')\n }\n\n // reCAPTCHA token is fetched right before the POST so it cannot expire.\n const recaptchaToken = config.recaptcha_enabled\n ? await getRecaptchaToken(config.recaptcha_site_key)\n : null\n if (config.recaptcha_enabled && !recaptchaToken) {\n throw new Error('Verification could not be completed. Please try again.')\n }\n\n const honeypotFieldName = config.honeypot_field || DEFAULT_HONEYPOT_FIELD\n const utm = getUTMParams()\n\n const payload = {\n formId: config.id,\n form_id: config.id,\n data: {\n ...values,\n ...(config.honeypot_enabled ? { [honeypotFieldName]: honeypotValue } : {}),\n },\n metadata: {\n pageUrl: typeof window !== 'undefined' ? window.location.href : null,\n referrer: typeof document !== 'undefined' ? document.referrer || null : null,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : null,\n sessionId:\n typeof sessionStorage !== 'undefined' ? sessionStorage.getItem('_sk_sid') : null,\n // Anonymous visitor id (_sk_vid) — the same id Analytics/Signal stamp on\n // page views, so the Sonor side can bind this lead to its browsing session\n // (page -> lead attribution). Sent on every submission; null pre-hydration.\n visitorId:\n typeof localStorage !== 'undefined' ? localStorage.getItem('_sk_vid') : null,\n recaptchaToken: recaptchaToken || undefined,\n utmSource: utm.utm_source,\n utmMedium: utm.utm_medium,\n utmCampaign: utm.utm_campaign,\n // Sub-site host — preserved on form_submissions for lead attribution\n // across multi-site projects. Resolved by SiteKitClientProviders.\n site:\n typeof window !== 'undefined'\n ? (window as { __SITE_KIT_SITE__?: string }).__SITE_KIT_SITE__ ||\n window.location.host\n : undefined,\n _formLoadedAt: formLoadedAt,\n },\n }\n\n const response = await fetchWithRetry(\n `${apiUrl}/api/public/forms/submit`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(payload),\n },\n { retries: 2, timeoutMs: 20000 },\n )\n\n const data = await response.json().catch(() => null)\n\n if (!response.ok) {\n const msg = (\n data?.message ??\n data?.error ??\n (response.statusText || `HTTP ${response.status}`)\n )\n .toString()\n .trim()\n throw new Error(\n msg ? `Failed to submit form: ${msg}` : `Failed to submit form (${response.status})`,\n )\n }\n\n return data\n}\n","/**\n * @sonordev/site-kit/forms - useForm Hook\n * \n * Headless hook for complete control over form rendering.\n * Fetches form config from API, handles validation, state, and submission.\n * \n * @example\n * ```tsx\n * const { form, fields, values, errors, setFieldValue, submit, isSubmitting } = useForm('contact-form')\n * \n * return (\n * <form onSubmit={(e) => { e.preventDefault(); submit() }}>\n * {fields.map(field => (\n * <MyCustomInput\n * key={field.slug}\n * label={field.label}\n * value={values[field.slug]}\n * error={errors[field.slug]}\n * onChange={(val) => setFieldValue(field.slug, val)}\n * />\n * ))}\n * <button type=\"submit\" disabled={isSubmitting}>Submit</button>\n * </form>\n * )\n * ```\n */\n\n'use client'\n\nimport { useState, useEffect, useCallback, useMemo, useRef } from 'react'\nimport { useFormTracking } from './useFormTracking'\nimport { fetchWithRetry } from './fetchWithRetry'\nimport { submitForm } from './submitForm'\nimport type { \n ManagedFormConfig, \n FormField, \n FormSubmission \n} from './types'\nimport { DEFAULT_FORM_SUCCESS_MESSAGE } from './defaultSuccessMessage'\n\n// ============================================\n// Types\n// ============================================\n\nexport interface UseFormOptions {\n /** Project ID (defaults to SiteKitProvider config) */\n projectId?: string\n /** Callback when form submits successfully */\n onSuccess?: (submission: FormSubmission) => void\n /** Callback when submission fails */\n onError?: (error: Error) => void\n /** Initial values to prefill */\n initialValues?: Record<string, unknown>\n /** Auto-redirect after success (override form config) */\n redirectUrl?: string | false\n}\n\nexport interface UseFormReturn {\n /** Form configuration (null while loading) */\n form: ManagedFormConfig | null\n /** Loading state */\n isLoading: boolean\n /** Error fetching form */\n fetchError: Error | null\n /** Human-readable error from the last submit attempt (null when none) */\n submitError: string | null\n\n /** All form fields */\n allFields: FormField[]\n /** Fields for current step (multi-step) or all fields (single step) */\n fields: FormField[]\n /** Visible fields only (respecting conditional logic) */\n visibleFields: FormField[]\n \n /** Current form values */\n values: Record<string, unknown>\n /** Current validation errors */\n errors: Record<string, string>\n \n /** Set a single field value */\n setFieldValue: (key: string, value: unknown) => void\n /** Set multiple field values at once */\n setValues: (values: Record<string, unknown>) => void\n /** Clear all errors */\n clearErrors: () => void\n \n /** Multi-step state */\n step: number\n totalSteps: number\n isMultiStep: boolean\n progress: number\n \n /** Multi-step navigation */\n nextStep: () => boolean\n prevStep: () => void\n goToStep: (step: number) => void\n canGoNext: boolean\n canGoPrev: boolean\n isLastStep: boolean\n \n /** Validate current step */\n validate: () => boolean\n /** Validate a single field */\n validateField: (field: FormField) => string | null\n /** Check if a field is visible (conditional logic) */\n isFieldVisible: (field: FormField) => boolean\n \n /** Submit the form */\n submit: () => Promise<void>\n /** Submission state */\n isSubmitting: boolean\n isComplete: boolean\n /** Reset form to initial state */\n reset: () => void\n}\n\n// ============================================\n// Hook\n// ============================================\n\nexport function useForm(\n formIdOrSlug: string,\n options: UseFormOptions = {}\n): UseFormReturn {\n const { \n projectId: optionsProjectId,\n onSuccess, \n onError, \n initialValues = {},\n redirectUrl,\n } = options\n \n // Get projectId from window globals if not provided\n const projectId = optionsProjectId || \n (typeof window !== 'undefined' ? (window as any).__SITE_KIT_PROJECT_ID__ : undefined)\n \n // State\n const [form, setForm] = useState<ManagedFormConfig | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [fetchError, setFetchError] = useState<Error | null>(null)\n const [values, setValuesState] = useState<Record<string, unknown>>(initialValues)\n const [errors, setErrors] = useState<Record<string, string>>({})\n const [step, setStep] = useState(1)\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [isComplete, setIsComplete] = useState(false)\n const [submitError, setSubmitError] = useState<string | null>(null)\n\n // Synchronous re-entrancy guard + anti-bot timing.\n const isSubmittingRef = useRef(false)\n const formLoadedAt = useRef(Date.now())\n\n const totalSteps = form?.total_steps || 1\n const isMultiStep = (form?.is_multi_step) || false\n \n const { trackStepChange, trackComplete } = useFormTracking({\n formId: form?.id || '',\n totalSteps,\n })\n \n // Fetch form config (project is derived from API key on the backend; projectId is optional)\n useEffect(() => {\n const apiUrl = typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n\n async function fetchForm() {\n try {\n setIsLoading(true)\n setFetchError(null)\n\n // The provider sets __SITE_KIT_API_KEY__ during its render; if this\n // hook's effect happens to run first, poll briefly for it rather than\n // failing permanently and wedging the form on \"API key is required\".\n const readApiKey = (): string | undefined =>\n typeof window !== 'undefined' ? (window as any).__SITE_KIT_API_KEY__ : undefined\n let apiKey = readApiKey()\n for (let i = 0; i < 15 && !apiKey; i++) {\n await new Promise((r) => setTimeout(r, 100))\n apiKey = readApiKey()\n }\n if (!apiKey) {\n throw new Error('API key is required. Provide it via SiteKitLayout/SiteKitProvider or set SONOR_API_KEY.')\n }\n\n const url = `${apiUrl}/api/public/forms/config`\n const init: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n formIdOrSlug: formIdOrSlug,\n }),\n }\n\n const response = await fetchWithRetry(url, init, { retries: 3, timeoutMs: 15000 })\n\n if (!response.ok) {\n throw new Error(`Failed to fetch form: ${response.statusText}`)\n }\n \n const data = await response.json()\n if (!data) throw new Error('Form not found')\n\n if (typeof window !== 'undefined' && data.recaptcha_site_key) {\n ;(window as any).__SITE_KIT_RECAPTCHA_SITE_KEY__ = data.recaptcha_site_key\n }\n \n // Sort steps and fields\n if (data.steps) {\n data.steps.sort((a: any, b: any) => (a.step_number || 0) - (b.step_number || 0))\n }\n if (data.fields) {\n data.fields.sort((a: any, b: any) => (a.sort_order || 0) - (b.sort_order || 0))\n }\n \n // Compute multi-step properties\n const total_steps = data.steps?.length || 1\n const is_multi_step = total_steps > 1\n\n const apiSuccess =\n typeof data.success_message === 'string' ? data.success_message.trim() : ''\n const success_message =\n apiSuccess ||\n (typeof (data as { successMessage?: string }).successMessage === 'string'\n ? String((data as { successMessage?: string }).successMessage).trim()\n : '') ||\n DEFAULT_FORM_SUCCESS_MESSAGE\n \n setForm({\n ...data,\n success_message,\n total_steps,\n is_multi_step,\n })\n \n // Set default values from field configs\n const defaults: Record<string, unknown> = {}\n for (const field of data.fields || []) {\n if (field.default_value !== undefined && field.default_value !== null) {\n defaults[field.slug] = field.default_value\n }\n }\n setValuesState({ ...defaults, ...initialValues })\n \n } catch (err) {\n setFetchError(err as Error)\n } finally {\n setIsLoading(false)\n }\n }\n \n fetchForm()\n }, [formIdOrSlug, projectId])\n \n // All fields\n const allFields = useMemo(() => form?.fields || [], [form])\n \n // Fields for current step\n const fields = useMemo(() => {\n if (!isMultiStep) return allFields\n \n const currentStepConfig = form?.steps?.find(s => s.step_number === step)\n if (!currentStepConfig) return allFields\n \n return allFields.filter(f => f.step_id === currentStepConfig.id)\n }, [form, step, allFields, isMultiStep])\n \n // Check if field is visible (conditional logic)\n const isFieldVisible = useCallback((field: FormField): boolean => {\n if (!field.conditional?.show_when) return true\n \n const { field: condField, operator, value } = field.conditional.show_when\n const fieldValue = values[condField]\n \n switch (operator) {\n case 'equals':\n return fieldValue === value\n case 'not_equals':\n return fieldValue !== value\n case 'contains':\n return String(fieldValue || '').includes(String(value))\n case 'not_contains':\n return !String(fieldValue || '').includes(String(value))\n case 'is_empty':\n return !fieldValue || fieldValue === ''\n case 'not_empty':\n return !!fieldValue && fieldValue !== ''\n case 'greater_than':\n return Number(fieldValue) > Number(value)\n case 'less_than':\n return Number(fieldValue) < Number(value)\n default:\n return true\n }\n }, [values])\n \n // Visible fields only\n const visibleFields = useMemo(() => {\n return fields.filter(isFieldVisible)\n }, [fields, isFieldVisible])\n \n // Validate a single field\n const validateField = useCallback((field: FormField): string | null => {\n if (!isFieldVisible(field)) return null\n // Skip display-only field types\n if (['heading', 'section_header', 'paragraph', 'hidden'].includes(field.field_type)) return null\n\n const value = values[field.slug]\n const rules = field.validation || {}\n \n // Required check\n if (field.is_required && (!value || value === '')) {\n return rules.custom_error || `${field.label} is required`\n }\n \n if (!value) return null\n \n const strValue = String(value)\n \n // Length checks\n if (rules.min_length && strValue.length < rules.min_length) {\n return `${field.label} must be at least ${rules.min_length} characters`\n }\n if (rules.max_length && strValue.length > rules.max_length) {\n return `${field.label} must be no more than ${rules.max_length} characters`\n }\n \n // Numeric checks\n if (rules.min !== undefined && Number(value) < rules.min) {\n return `${field.label} must be at least ${rules.min}`\n }\n if (rules.max !== undefined && Number(value) > rules.max) {\n return `${field.label} must be no more than ${rules.max}`\n }\n \n // Pattern check — guard against an invalid admin-entered pattern.\n if (rules.pattern) {\n try {\n if (!new RegExp(rules.pattern).test(strValue)) {\n return rules.custom_error || `${field.label} is invalid`\n }\n } catch {\n // Malformed pattern — skip rather than crashing the form.\n }\n }\n \n // Email check\n if (field.field_type === 'email' && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(strValue)) {\n return 'Please enter a valid email address'\n }\n \n // Phone check\n if (field.field_type === 'phone' && !/^[\\d\\s\\-\\+\\(\\)]+$/.test(strValue)) {\n return 'Please enter a valid phone number'\n }\n \n return null\n }, [values, isFieldVisible])\n \n // Validate current step\n const validate = useCallback((): boolean => {\n const newErrors: Record<string, string> = {}\n \n for (const field of fields) {\n const error = validateField(field)\n if (error) {\n newErrors[field.slug] = error\n }\n }\n \n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }, [fields, validateField])\n\n // Validate EVERY field across all steps — used on final submit so a required\n // field left empty on an earlier step cannot slip through.\n const validateAll = useCallback((): boolean => {\n const newErrors: Record<string, string> = {}\n for (const field of allFields) {\n const error = validateField(field)\n if (error) newErrors[field.slug] = error\n }\n setErrors(newErrors)\n return Object.keys(newErrors).length === 0\n }, [allFields, validateField])\n\n // Visible field values only — never submit a value from a conditionally-hidden field.\n const buildVisibleValues = useCallback((): Record<string, unknown> => {\n const out: Record<string, unknown> = {}\n for (const field of allFields) {\n if (!isFieldVisible(field)) continue\n if (field.slug in values) out[field.slug] = values[field.slug]\n }\n return out\n }, [allFields, values, isFieldVisible])\n\n // Set single field value\n const setFieldValue = useCallback((key: string, value: unknown) => {\n setValuesState(prev => ({ ...prev, [key]: value }))\n // Clear error when field changes\n setErrors(prev => {\n if (prev[key]) {\n const next = { ...prev }\n delete next[key]\n return next\n }\n return prev\n })\n }, [])\n \n // Set multiple values\n const setValues = useCallback((newValues: Record<string, unknown>) => {\n setValuesState(prev => ({ ...prev, ...newValues }))\n }, [])\n \n // Clear all errors\n const clearErrors = useCallback(() => {\n setErrors({})\n }, [])\n \n // Step navigation\n const canGoNext = step < totalSteps\n const canGoPrev = step > 1\n const isLastStep = step === totalSteps\n const progress = Math.round((step / totalSteps) * 100)\n \n const nextStep = useCallback((): boolean => {\n if (!validate()) return false\n \n if (step < totalSteps) {\n const newStep = step + 1\n setStep(newStep)\n trackStepChange(newStep)\n return true\n }\n return false\n }, [step, totalSteps, validate, trackStepChange])\n \n const prevStep = useCallback(() => {\n if (step > 1) {\n const newStep = step - 1\n setStep(newStep)\n trackStepChange(newStep)\n }\n }, [step, trackStepChange])\n \n const goToStep = useCallback((targetStep: number) => {\n if (targetStep >= 1 && targetStep <= totalSteps) {\n setStep(targetStep)\n trackStepChange(targetStep)\n }\n }, [totalSteps, trackStepChange])\n \n // Submit form\n const submit = useCallback(async () => {\n if (!form) return\n // Re-entrancy guard — blocks a concurrent double-submit in the same tick.\n if (isSubmittingRef.current) return\n if (!validateAll()) return\n\n isSubmittingRef.current = true\n setIsSubmitting(true)\n setSubmitError(null)\n\n try {\n const data = await submitForm({\n config: form,\n values: buildVisibleValues(),\n honeypotValue: '',\n formLoadedAt: formLoadedAt.current,\n })\n\n trackComplete()\n setIsComplete(true)\n onSuccess?.(data as FormSubmission)\n\n const finalRedirect = redirectUrl !== false\n ? (redirectUrl || form.redirect_url)\n : undefined\n if (finalRedirect) {\n window.location.href = finalRedirect\n }\n } catch (error) {\n console.error('[useForm] Submission error:', error)\n setSubmitError('Something went wrong sending your submission. Please try again.')\n onError?.(error as Error)\n } finally {\n isSubmittingRef.current = false\n setIsSubmitting(false)\n }\n }, [form, validateAll, buildVisibleValues, trackComplete, onSuccess, onError, redirectUrl])\n \n // Reset form\n const reset = useCallback(() => {\n setValuesState(initialValues)\n setErrors({})\n setStep(1)\n setIsComplete(false)\n setSubmitError(null)\n }, [initialValues])\n \n return {\n form,\n isLoading,\n fetchError,\n submitError,\n\n allFields,\n fields,\n visibleFields,\n \n values,\n errors,\n setFieldValue,\n setValues,\n clearErrors,\n \n step,\n totalSteps,\n isMultiStep,\n progress,\n \n nextStep,\n prevStep,\n goToStep,\n canGoNext,\n canGoPrev,\n isLastStep,\n \n validate,\n validateField,\n isFieldVisible,\n \n submit,\n isSubmitting,\n isComplete,\n reset,\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/layout/SiteKitClientProviders.tsx"],"names":["dynamic","useDeferredActivation","useState","getOrCreateVisitorId","getOrCreateSessionId","useRef","useCallback","jsx","SignalBridge","jsxs","Fragment","Suspense","SiteKitIdentityProvider"],"mappings":"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","file":"chunk-NNZDHLXN.js","sourcesContent":["'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) via\n * SiteKitIdentityProvider, ensuring consistent tracking across Analytics,\n * Signal, and Engage.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n SiteKitIdentityProvider,\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\n// Defer non-critical module mounting until the page is quiet: the lazy\n// modules below are dynamic(ssr:false) and never render on the server, but\n// rendering them during hydration still kicks off their chunk downloads +\n// mount effects inside the critical startup window. useDeferredActivation\n// holds them until window.load + idle or first interaction — the same\n// strategy as the hand-rolled per-site deferrals this replaces (upforge\n// `deferred-analytics.tsx`, TPS `DeferredAnalytics.tsx`). The hook is public\n// (`@sonordev/site-kit/client`) so sites can reuse it for their own scripts.\nimport { useDeferredActivation } from '../shared/defer'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n// SignalBridge is imported STATICALLY, not via dynamic(ssr:false): it is a\n// tiny SSR-safe context shell that renders children immediately and\n// lazy-loads its machinery (SignalCore) as a childless sibling internally.\n// Wrapping children in a dynamic(ssr:false) component was the old SSR-bailout\n// failure mode — do not reintroduce it.\nimport { SignalBridge } from '../signal/SignalBridge'\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n sitemapSync?: boolean\n /**\n * Defer Analytics / Engage / SitemapSync until window load + idle or first\n * interaction (default true). Pass false to restore legacy eager mounting\n * on hydration. SignalBridge is never deferred — it must apply experiment\n * variants as early as possible.\n */\n defer?: boolean\n debug?: boolean\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n defer = true,\n debug = false,\n}: SiteKitClientProvidersProps) {\n // One shared activation gate for all deferred siblings, so they mount in a\n // single commit instead of staggered re-renders.\n const modulesReady = useDeferredActivation(defer)\n // Hoist analytics config so the `site` dimension is resolvable up here.\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n\n // Resolve the sub-site identifier — the dimension that lets one Sonor project\n // host many sites (e.g. truepowersystems.com + ohiopowerstudies.com under one\n // TPS project). Precedence: explicit `analytics.site` > NEXT_PUBLIC_SITE_URL\n // host > window.location.host. Always a string (possibly empty).\n const explicitSite = analyticsConfig.site\n const envSiteUrl =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_SITE_URL\n : undefined\n let resolvedSite = explicitSite ?? ''\n if (!resolvedSite && envSiteUrl) {\n try {\n resolvedSite = new URL(envSiteUrl).host\n } catch {\n /* malformed URL — fall through to client-side host */\n }\n }\n if (!resolvedSite && typeof window !== 'undefined') {\n resolvedSite = window.location.host\n }\n const site = resolvedSite\n\n // Set window globals for modules that still read from them.\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n ;(window as any).__SITE_KIT_SITE__ = site\n }\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled. Safe to wrap: the shell is SSR-safe\n // and renders children straight through — the heavy machinery mounts as a\n // childless sibling inside it. Not gated on modulesReady: experiment\n // variants must apply as early as possible.\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n content = (\n <SignalBridge\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n >\n {content}\n </SignalBridge>\n )\n }\n\n // Add Analytics if enabled (renders alongside, doesn't wrap).\n //\n // CRITICAL: LazyAnalyticsProvider is dynamic(..., { ssr: false }). Wrapping\n // {content} inside an ssr:false component makes the entire page tree skip\n // server rendering — the route de-opts to 100% client rendering and the\n // hero / LCP element only paints after hydration (mobile LCP ~4s, Lighthouse\n // ~85). Analytics tracks via effects + a metadata ref, so it never needs to\n // wrap page content — mount it as a childless sibling, exactly like Engage.\n // Each deferred sibling is appended as `{modulesReady && <Module/>}` so the\n // children slot never moves in the tree — flipping ready only mounts the\n // sibling, it never remounts page content.\n if (analytics) {\n content = (\n <>\n {content}\n {modulesReady && (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n site={site}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n sessionTimeout={analyticsConfig.sessionDuration}\n excludePaths={analyticsConfig.excludePaths}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n />\n </Suspense>\n )}\n </>\n )\n }\n\n // Add Engage widget if enabled (renders alongside, doesn't wrap)\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n content = (\n <>\n {content}\n {modulesReady && (\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n zIndex={engageConfig.zIndex}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n )}\n </>\n )\n }\n\n // Add SitemapSync if enabled\n if (sitemapSync) {\n content = (\n <>\n {content}\n {modulesReady && <LazySitemapSync debug={debug} />}\n </>\n )\n }\n\n return (\n <SiteKitIdentityProvider visitorId={visitorId} sessionId={sessionId}>\n {content}\n </SiteKitIdentityProvider>\n )\n}\n"]}
|