@appstorys/react-web 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapters/web/storage.ts","../src/core/store.ts","../src/core/getDeviceInfo.ts","../src/core/verifyAccount.ts","../src/core/identifyWidgetPositions.ts","../src/core/CaptureService.ts","../src/core/screenCapture.ts","../src/index.ts","../src/types/index.ts","../src/components/Banner/index.tsx","../src/hooks/useCampaigns.ts","../src/core/variantResolver.ts","../src/core/trackEvent.ts","../src/core/offlineQueue.ts","../src/core/campaignHelpers.ts","../src/components/Pip/index.tsx","../src/core/fontManager.ts","../src/components/Floater/index.tsx","../src/core/trackScreen.ts","../src/core/setUserProperties.ts","../src/core/personalization.ts","../src/core/fetchAllCampaigns.ts","../src/core/reconcileUser.ts","../src/core/exitIntent.ts","../src/core/visibilityManager.ts","../src/core/userManagement.ts","../src/dev/showWidgetDebug.ts","../src/components/Story/index.tsx","../src/components/Story/StoryThumbnail.tsx","../src/components/Story/StoryGroupItem.tsx","../src/components/Story/StoryList.tsx","../src/components/Story/StoryOverlay.tsx","../src/components/common/InteractiveElements/PollSticker.tsx","../src/components/common/InteractiveElements/QuizSticker.tsx","../src/components/common/InteractiveElements/CountdownSticker.tsx","../src/components/common/InteractiveElements/PromoCodeSticker.tsx","../src/components/common/InteractiveElements/ReactionSticker.tsx","../src/components/common/InteractiveElements/RatingSticker.tsx","../src/components/common/InteractiveElements/QuestionSticker.tsx","../src/components/common/InteractiveElements/ImageQuizSticker.tsx","../src/components/common/InteractiveElements/ShopableSticker.tsx","../src/components/common/InteractiveElements/ShopableModal.tsx","../src/components/common/InteractiveElements/InteractiveItem.tsx","../src/utils/styleUtils.ts","../src/components/common/InteractiveElements/InteractiveOverlay.tsx","../src/components/common/CommonElements/PlayPauseButton.tsx","../src/components/common/CommonElements/Cta.tsx","../src/components/common/CommonElements/CrossButton.tsx","../src/components/common/CommonElements/SoundButton.tsx","../src/components/common/CommonElements/ShareButton.tsx","../src/components/Widget/index.tsx","../src/hooks/useViewportTracking.ts","../src/components/Tooltip/index.tsx","../src/components/BottomSheet/index.tsx","../src/components/Csat/index.tsx","../src/components/Survey/index.tsx"],"sourcesContent":["export class WebStorage {\n static async getItem(key: string): Promise<string | null> {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n static async setItem(key: string, value: string): Promise<void> {\n try {\n localStorage.setItem(key, value);\n } catch {\n // Fallback for private mode or full storage\n }\n }\n\n static async removeItem(key: string): Promise<void> {\n try {\n localStorage.removeItem(key);\n } catch {}\n }\n}\n","import { create } from 'zustand';\nimport { AppStorysStore, Campaign, Attributes } from '../types';\nimport { WebStorage } from '../adapters/web/storage';\n\nexport interface AppStorysActions {\n setUserId: (userId: string) => void;\n setAppId: (appId: string) => void;\n setAccountId: (accountId: string) => void;\n setCurrentScreen: (screen: string) => void;\n saveCampaigns: (campaigns: Campaign[]) => void;\n saveAllCampaigns: (campaigns: Campaign[]) => void;\n setCampaignVersion: (version: number) => void;\n setTrackedEvents: (events: string[]) => void;\n setTrackedEventMetadata: (metadata: Record<string, Attributes[]>) => void;\n setAttributes: (attributes: Attributes) => void;\n setVisibility: (visible: boolean) => void;\n setIsAnonymousUser: (isAnonymous: boolean) => void;\n setVariantMappings: (mappings: Record<string, string>) => void;\n setPersonalizationData: (data: Record<string, string>) => void;\n setScreenCaptureEnabled: (enabled: boolean) => void;\n setBaseUrl: (baseUrl?: string) => void;\n setTrackingUrl: (trackingUrl?: string) => void;\n}\n\nconst useAppStorysStore = create<AppStorysStore & AppStorysActions>((set) => ({\n userId: '',\n appId: '',\n accountId: '',\n currentScreen: '',\n campaigns: [],\n allCampaigns: [],\n campaignVersion: 2,\n trackedEvents: [],\n trackedEventMetadata: {},\n isVisible: true,\n isAnonymousUser: false,\n variantMappings: {},\n personalizationData: {},\n screenCaptureEnabled: false,\n baseUrl: undefined,\n trackingUrl: undefined,\n \n saveCampaigns: (campaigns: Campaign[]) => set({ campaigns }),\n saveAllCampaigns: (campaigns: Campaign[]) => set({ allCampaigns: campaigns }),\n setCampaignVersion: (version: number) => set({ campaignVersion: version }),\n setUserId: (userId: string) => set({ userId }),\n setAppId: (appId: string) => set({ appId }),\n setAccountId: (accountId: string) => set({ accountId }),\n setCurrentScreen: (currentScreen: string) => set({ currentScreen }),\n setAttributes: (attributes: Attributes) => set({ attributes }),\n setTrackedEvents: (trackedEvents: string[]) => set({ trackedEvents }),\n setTrackedEventMetadata: (trackedEventMetadata: Record<string, Attributes[]>) => set({ trackedEventMetadata }),\n setVisibility: (isVisible: boolean) => set({ isVisible }),\n setIsAnonymousUser: (isAnonymousUser: boolean) => set({ isAnonymousUser }),\n setVariantMappings: (variantMappings: Record<string, string>) => set({ variantMappings }),\n setPersonalizationData: (personalizationData: Record<string, string>) => set({ personalizationData }),\n setScreenCaptureEnabled: (enabled: boolean) => set({ screenCaptureEnabled: enabled }),\n setBaseUrl: (baseUrl?: string) => set({ baseUrl }),\n setTrackingUrl: (trackingUrl?: string) => set({ trackingUrl }),\n}));\n\nexport function getAppId() {\n return useAppStorysStore.getState().appId;\n}\n\nexport function getUserId() {\n return useAppStorysStore.getState().userId;\n}\n\nexport async function getAccessToken() {\n return WebStorage.getItem('access_token');\n}\n\nexport function getVariantId(campaignId?: string) {\n if (!campaignId) return undefined;\n const id = String(campaignId || '').trim();\n if (!id) return undefined;\n return useAppStorysStore.getState().variantMappings?.[id];\n}\n\nexport function getCampaigns() {\n return useAppStorysStore.getState().campaigns;\n}\n\nexport function getAllCampaigns() {\n return useAppStorysStore.getState().allCampaigns;\n}\n\nexport function getCampaignVersion() {\n return useAppStorysStore.getState().campaignVersion;\n}\n\nexport default useAppStorysStore;\n","export default async function getDeviceInfo() {\n try {\n const deviceInfo: Record<string, any> = {\n browser: navigator.userAgent,\n language: navigator.language,\n platform: 'web',\n screen_width_px: window.innerWidth,\n screen_height_px: window.innerHeight,\n screen_density: window.devicePixelRatio,\n orientation: window.innerWidth < window.innerHeight ? \"portrait\" : \"landscape\",\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n };\n\n return deviceInfo;\n } catch (error) {\n console.error(\"Error fetching device info:\", error);\n return {};\n }\n}\n","import { WebStorage } from '../adapters/web/storage';\nimport getDeviceInfo from './getDeviceInfo';\nimport useAppStorysStore from './store';\n\nconst DEVICE_INFO_SENT_KEY = 'device_info_sent';\n\nexport default async function verifyAccount(accountId: string, appId: string, userId: string): Promise<boolean> {\n try {\n const requestBody: any = {\n account_id: accountId,\n app_id: appId,\n user_id: userId\n };\n\n const deviceInfoAlreadySent = await WebStorage.getItem(DEVICE_INFO_SENT_KEY);\n\n if (!deviceInfoAlreadySent) {\n // This is the very first initialization after app install\n const deviceInfo = await getDeviceInfo();\n requestBody.attributes = {\n ...deviceInfo\n };\n console.log('First time verification - including device info in attributes');\n } else {\n console.log('Device info already sent previously - skipping');\n }\n\n const state = useAppStorysStore.getState();\n const baseUrl = state.baseUrl || 'https://users.appstorys.co';\n\n const response = await fetch(`${baseUrl}/${accountId}/validate-account`, {\n method: 'POST',\n body: JSON.stringify(requestBody),\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n });\n\n console.log('Verify account body', requestBody);\n console.log('Verifying account', response.status, response.statusText);\n\n if (response.ok) {\n const data = await response.json();\n console.log('Account verified', data);\n const { access_token, refresh_token } = data;\n\n if (access_token && refresh_token) {\n await WebStorage.setItem('access_token', access_token);\n await WebStorage.setItem('refresh_token', refresh_token);\n\n // Mark device info as sent if it was included in this request\n if (requestBody.attributes) {\n await WebStorage.setItem(DEVICE_INFO_SENT_KEY, 'true');\n console.log('Device info sent flag set');\n }\n\n return true;\n }\n }\n return false;\n } catch (error) {\n console.error('Error when verifying AppStorys account', error);\n return false;\n }\n}\n","import { getAccessToken } from './store';\n\nexport default async function identifyWidgetPositions(screenName: string, positionList?: string[]) {\n if (!positionList || positionList.length === 0) {\n console.info('AppStorys: identifyWidgetPositions called with empty positionList; skipping');\n return;\n }\n\n const accessToken = await getAccessToken();\n if (!accessToken) {\n console.error('AppStorys: identifyWidgetPositions - access token not found');\n return;\n }\n\n try {\n const endpoint = 'https://backend.appstorys.co/api/v2/appinfo/identify-positions/';\n console.info('AppStorys: identifyWidgetPositions payload', { screen_name: screenName, position_list: positionList });\n const resp = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n 'Accept': 'application/json'\n },\n body: JSON.stringify({\n screen_name: screenName,\n position_list: positionList,\n }),\n });\n\n if (!resp.ok) {\n console.error('AppStorys: identifyWidgetPositions failed', resp.status, await resp.text());\n } else {\n console.info('AppStorys: identifyWidgetPositions OK');\n }\n } catch (err) {\n console.error('AppStorys: identifyWidgetPositions error', err);\n }\n}\n","import { getAccessToken, getUserId } from './store';\nimport verifyAccount from './verifyAccount';\nimport identifyWidgetPositions from './identifyWidgetPositions';\nimport useAppStorysStore from './store';\n\ntype LayoutFrame = {\n x: number;\n y: number;\n width: number;\n height: number;\n screenWidth?: number;\n screenHeight?: number;\n};\n\ntype LayoutInfo = { id: string; frame: LayoutFrame };\n\nconst layoutData: Record<string, LayoutInfo[]> = {};\n\nfunction normalizeWidgetId(id?: string) {\n if (!id) return id;\n return id.startsWith('widget_') ? id : `widget_${id}`;\n}\n\nfunction extractPositionsFromCampaigns(): string[] {\n try {\n const all = useAppStorysStore.getState().allCampaigns || [];\n const positions: string[] = [];\n\n all.forEach((c: any) => {\n if (c && c.position && typeof c.position === 'string') {\n positions.push(String(c.position));\n }\n\n try {\n if (c && c.campaign_type === 'WID' && c.details) {\n const d = c.details;\n if (typeof d === 'object') {\n if (d.id && typeof d.id === 'string') positions.push(String(d.id));\n if (d.variants && typeof d.variants === 'object') {\n Object.values(d.variants).forEach((v: any) => { if (v && v.id && typeof v.id === 'string') positions.push(String(v.id)); });\n }\n }\n }\n } catch (e) {\n // ignore per-campaign extraction errors\n }\n });\n\n return positions.filter((v): v is string => !!v).map((p) => normalizeWidgetId(String(p))!).filter((v): v is string => !!v);\n } catch (e) {\n return [];\n }\n}\nfunction mapServerPositionsToDOM(screenName: string) {\n try {\n const positions = extractPositionsFromCampaigns();\n if (!positions || positions.length === 0) return [];\n\n const mapped: string[] = [];\n\n positions.forEach((pos) => {\n const key = pos.replace(/^widget_/, '');\n // try multiple selectors to find the matching element\n const selectors = [\n `[data-as-id=\"${key}\"]`,\n `#${key}`,\n `.${key}`,\n `[data-widget=\"${key}\"]`,\n ];\n\n let el: Element | null = null;\n for (const sel of selectors) {\n el = document.querySelector(sel);\n if (el) break;\n }\n\n if (el) {\n const rect = el.getBoundingClientRect();\n const frame: LayoutFrame = {\n x: Math.round(rect.left),\n y: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n screenWidth: window.innerWidth,\n screenHeight: window.innerHeight,\n };\n\n // store using the raw key (no widget_ prefix) so children JSON matches collected ids\n CaptureService.addLayoutInfo(screenName, key, frame);\n mapped.push(key);\n } else {\n // not found in DOM; skip\n }\n });\n\n console.info('AppStorys: mapServerPositionsToDOM mapped', mapped.length, 'server positions to DOM elements', mapped);\n return mapped;\n } catch (e) {\n console.warn('AppStorys: mapServerPositionsToDOM error', e);\n return [];\n }\n}\n\nfunction ensureList(screenName: string) {\n if (!layoutData[screenName]) layoutData[screenName] = [];\n return layoutData[screenName];\n}\n\n/**\n * Build a fresh FormData for the identify-elements request.\n */\nfunction buildFormData(\n screenName: string,\n userId: string,\n children: string,\n blob: Blob\n): FormData {\n const form = new FormData();\n \n // Sanitize screenName for filename\n const safeScreenName = screenName.replace(/[^a-z0-9]/gi, '_');\n const filename = `screenshot_${userId}_${safeScreenName}_${Date.now()}.png`;\n\n const file = new File([blob], filename, { type: 'image/png' });\n\n form.append('screenName', screenName);\n form.append('user_id', userId);\n form.append('children', children);\n form.append('screenshot', file);\n\n // Diagnostic logging\n try {\n console.groupCollapsed('AppStorys: FormData Payload Diagnostic');\n console.info(' screenName:', screenName);\n console.info(' user_id:', userId);\n console.info(' children:', JSON.parse(children));\n console.info(' screenshot:', file.name, `(${file.size} bytes)`);\n console.groupEnd();\n } catch (e) {\n console.warn('AppStorys: Could not run FormData diagnostics', e);\n }\n\n return form;\n}\n\nexport default class CaptureService {\n static setup(screenName: string, enabled: boolean) {\n const s = useAppStorysStore.getState();\n s.setScreenCaptureEnabled(enabled);\n s.setCurrentScreen(screenName);\n }\n\n /**\n * Manually add layout information for an element.\n */\n static addLayoutInfo(screenName: string, id: string, frame: LayoutFrame) {\n const list = ensureList(screenName);\n const idx = list.findIndex(l => l.id === id);\n \n // Auto-fill screen dimensions if missing\n const enrichedFrame: LayoutFrame = {\n ...frame,\n screenWidth: frame.screenWidth || window.innerWidth,\n screenHeight: frame.screenHeight || window.innerHeight,\n };\n\n const info = { id, frame: enrichedFrame };\n if (idx >= 0) list[idx] = info; else list.push(info);\n }\n\n /**\n * Automatically collect all elements marked with [data-as-id].\n */\n static collectElements(screenName: string) {\n this.clearLayoutData(screenName);\n const elements = document.querySelectorAll('[data-as-id]');\n const screenWidth = window.innerWidth;\n const screenHeight = window.innerHeight;\n const foundIds: string[] = [];\n\n elements.forEach((el) => {\n const id = el.getAttribute('data-as-id');\n if (id) {\n foundIds.push(id);\n const rect = el.getBoundingClientRect();\n this.addLayoutInfo(screenName, id, {\n x: Math.round(rect.left),\n y: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n screenWidth,\n screenHeight\n });\n }\n });\n\n console.info(`AppStorys: Identified ${elements.length} elements:`, foundIds);\n }\n\n static clearLayoutData(screenName: string) {\n layoutData[screenName] = [];\n }\n\n static getLayoutData(screenName: string) {\n return layoutData[screenName] || [];\n }\n\n static async takeScreenshot(screenName: string, positionList?: string[]) {\n try {\n if (!screenName) {\n console.error('AppStorys: Screen name is required');\n return false;\n }\n\n console.info('AppStorys: Starting takeScreenshot for', screenName);\n\n const s = useAppStorysStore.getState();\n s.setCurrentScreen(screenName);\n\n // ── Step 0: Auto-collect elements before capture ──────────────────\n this.collectElements(screenName);\n\n // Also try to map server-declared widget positions to DOM elements\n try {\n const mapped = mapServerPositionsToDOM(screenName);\n if (mapped && mapped.length > 0) console.info('AppStorys: mapServerPositionsToDOM added', mapped.length, 'elements');\n } catch (e) {\n /* ignore */\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n\n // ── Step 1: Capture ────────────────────────────────────────────────\n const win: any = window as any;\n let blob: Blob | null = null;\n\n if (typeof win.html2canvas !== 'function') {\n try {\n await new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://html2canvas.hertzen.com/dist/html2canvas.min.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load html2canvas'));\n document.head.appendChild(script);\n });\n } catch (loadErr) {\n console.warn('AppStorys: html2canvas load error', loadErr);\n }\n }\n\n if (typeof win.html2canvas === 'function') {\n try {\n const canvas = await win.html2canvas(document.documentElement, {\n useCORS: true,\n allowTaint: true,\n logging: false,\n scale: window.devicePixelRatio || 1,\n });\n blob = await new Promise<Blob | null>(resolve =>\n canvas.toBlob((b: Blob | null) => resolve(b), 'image/png')\n );\n } catch (err) {\n console.warn('AppStorys: html2canvas capture failed (falling back to getDisplayMedia)', err);\n blob = null;\n }\n }\n\n if (!blob && navigator.mediaDevices && (navigator.mediaDevices as any).getDisplayMedia) {\n try {\n const stream = await (navigator.mediaDevices as any).getDisplayMedia({ video: true });\n const video = document.createElement('video');\n video.srcObject = stream;\n await video.play();\n const canvas = document.createElement('canvas');\n canvas.width = video.videoWidth || window.innerWidth;\n canvas.height = video.videoHeight || window.innerHeight;\n const ctx = canvas.getContext('2d');\n if (ctx) ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n blob = await new Promise<Blob | null>(resolve =>\n canvas.toBlob((b: Blob | null) => resolve(b), 'image/png')\n );\n video.pause();\n stream.getTracks().forEach((t: MediaStreamTrack) => t.stop());\n } catch (err) {\n console.warn('AppStorys: getDisplayMedia capture failed', err);\n }\n }\n\n if (!blob) {\n console.warn('AppStorys: Capture failed — no blob generated');\n return false;\n }\n\n // ── Step 2: Auth ──────────────────────────────────────────────────\n let accessToken = await getAccessToken();\n const userId = getUserId();\n\n if (!userId) {\n console.warn('AppStorys: No userId');\n return false;\n }\n\n if (!accessToken) {\n const state = useAppStorysStore.getState();\n if (state.accountId && state.appId && state.userId) {\n const refreshed = await verifyAccount(state.accountId, state.appId, state.userId);\n if (refreshed) accessToken = await getAccessToken();\n }\n }\n\n if (!accessToken) {\n console.warn('AppStorys: No token available');\n return false;\n }\n\n // ── Step 3: Send ───────────────────────────────────────────────────\n const endpoint = 'https://backend.appstorys.co/api/v1/appinfo/identify-elements/';\n const children = JSON.stringify(this.getLayoutData(screenName) || []);\n \n const body = buildFormData(screenName, userId, children, blob);\n \n console.info('AppStorys: Sending identify-elements with payload size:', children.length);\n\n let resp = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n 'Accept': 'application/json'\n },\n body: body,\n });\n\n if (resp.status === 401) {\n console.warn('AppStorys: 401 response — retrying once');\n const state = useAppStorysStore.getState();\n if (state.accountId && state.appId && state.userId) {\n const refreshed = await verifyAccount(state.accountId, state.appId, state.userId);\n if (refreshed) {\n const newToken = await getAccessToken();\n if (newToken) {\n resp = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${newToken}`,\n 'Accept': 'application/json'\n },\n body: buildFormData(screenName, userId, children, blob),\n });\n }\n }\n }\n }\n\n if (!resp.ok) {\n const text = await resp.text();\n console.error('AppStorys: identify-elements failed', resp.status, text);\n return false;\n }\n\n console.info('AppStorys: identify-elements success ✓');\n\n // After identify-elements succeeds, call identifyWidgetPositions.\n // If caller didn't provide a `positionList`, derive it from collected layout data.\n try {\n let positionsToSend = positionList;\n let normalized: string[] = [];\n if (!positionsToSend || positionsToSend.length === 0) {\n const data = this.getLayoutData(screenName) || [];\n normalized = data.map(d => normalizeWidgetId(d.id)).filter((v): v is string => !!v);\n } else {\n normalized = positionsToSend.map(id => normalizeWidgetId(id)).filter((v): v is string => !!v);\n }\n\n // Merge with server-declared positions (dedupe)\n const serverPositions = extractPositionsFromCampaigns();\n const combined = Array.from(new Set<string>([...normalized, ...serverPositions]));\n console.info('AppStorys: identifyWidgetPositions will send', combined.length, 'positions (collected + server)', combined);\n await identifyWidgetPositions(screenName, combined);\n } catch (e) {\n console.warn('AppStorys: identifyWidgetPositions failed', e);\n }\n\n return true;\n } catch (err) {\n console.error('AppStorys: takeScreenshot error', err);\n return false;\n }\n }\n}\n\nexport type { LayoutFrame, LayoutInfo };\n\n// Dev helper: force a positions POST for the current screen\n;(function attachDevHelpers() {\n try {\n const win: any = window as any;\n win.AppStorysForceIdentifyPositions = async (screenName?: string) => {\n const s = useAppStorysStore.getState();\n const name = screenName || s.currentScreen;\n if (!name) {\n console.warn('AppStorys: AppStorysForceIdentifyPositions - no screen name available');\n return;\n }\n const data = CaptureService.getLayoutData(name) || [];\n const positions = data.map(d => normalizeWidgetId(d.id)).filter((v): v is string => !!v);\n console.info('AppStorys: AppStorysForceIdentifyPositions sending', positions.length, 'positions for', name, positions);\n try {\n await identifyWidgetPositions(name, positions);\n console.info('AppStorys: AppStorysForceIdentifyPositions completed');\n } catch (err) {\n console.error('AppStorys: AppStorysForceIdentifyPositions error', err);\n }\n };\n } catch (e) {\n /* ignore */\n }\n})();\n","import useAppStorysStore from './store';\nimport CaptureService from './CaptureService';\n\nfunction injectStyles() {\n if (document.getElementById('appstorys-capture-styles')) return;\n const style = document.createElement('style');\n style.id = 'appstorys-capture-styles';\n style.innerHTML = `\n @keyframes appstorys-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n .appstorys-spinner {\n width: 20px;\n height: 20px;\n border: 3px solid rgba(255,255,255,0.3);\n border-top: 3px solid #fff;\n border-radius: 50%;\n animation: appstorys-spin 0.8s linear infinite;\n }\n `;\n document.head.appendChild(style);\n}\n\nfunction createButton(): HTMLButtonElement {\n injectStyles();\n const btn = document.createElement('button');\n btn.id = 'appstorys-screen-capture-btn';\n btn.title = 'Capture screen';\n Object.assign(btn.style, {\n position: 'fixed',\n left: '16px',\n bottom: '16px',\n width: '100px',\n height: '56px',\n borderRadius: '28px',\n background: '#ff6a00',\n color: '#fff',\n border: 'none',\n boxShadow: '0 6px 18px rgba(0,0,0,0.2)',\n zIndex: '2147483647',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '14px',\n fontWeight: '600',\n fontFamily: 'sans-serif',\n transition: 'all 0.2s ease'\n } as CSSStyleDeclaration);\n btn.innerText = 'Capture';\n return btn;\n}\n\nexport function mountScreenCaptureButton() {\n try {\n const state = useAppStorysStore.getState();\n const win: any = window as any;\n const debugForce = Boolean(win.__APPSTORYS_DEBUG_CAPTURE);\n console.info('AppStorys: mountScreenCaptureButton called, screenCaptureEnabled=', state.screenCaptureEnabled, 'debugForce=', debugForce);\n \n if (!state.screenCaptureEnabled && !debugForce) {\n return null;\n }\n\n if (document.getElementById('appstorys-screen-capture-btn')) return null;\n\n const btn = createButton();\n\n btn.addEventListener('click', async () => {\n btn.disabled = true;\n const originalText = btn.innerText;\n btn.innerHTML = '<div class=\"appstorys-spinner\"></div>';\n \n const s = useAppStorysStore.getState();\n const screenName = s.currentScreen || (typeof window !== 'undefined' ? window.location.pathname : '');\n \n try {\n await CaptureService.takeScreenshot(screenName);\n } catch (err) {\n console.error('CaptureService error', err);\n }\n \n btn.disabled = false;\n btn.innerText = originalText;\n btn.animate([{ transform: 'scale(1.0)' }, { transform: 'scale(1.05)' }, { transform: 'scale(1.0)' }], { duration: 300 });\n });\n\n document.body.appendChild(btn);\n console.info('AppStorys: screen capture button mounted');\n return btn;\n } catch (err) {\n console.error('mountScreenCaptureButton error', err);\n return null;\n }\n}\n\n// Expose a helper for dev to mount manually from console\ntry {\n (window as any).AppStorysMountCapture = function() {\n try {\n return mountScreenCaptureButton();\n } catch (e) {\n console.error('AppStorysMountCapture failed', e);\n return null;\n }\n };\n} catch (e) {\n // ignore\n}\n\n// Expose a helper to inspect store state from the console\ntry {\n (window as any).AppStorysDebugState = function() {\n try {\n const s = useAppStorysStore.getState();\n console.info('AppStorys store state:', s);\n return s;\n } catch (e) {\n console.error('AppStorysDebugState failed', e);\n return null;\n }\n };\n} catch (e) {\n // ignore\n}\n\n// Expose a helper to debug token\ntry {\n (window as any).AppStorysDebugToken = function() {\n try {\n const token = localStorage.getItem('access_token') || '';\n const len = token.length;\n const masked = token ? token.slice(0, 20) + '...' + token.slice(-10) : '(none)';\n console.info('Token length:', len, 'masked:', masked);\n if (token && token.includes('.')) {\n try {\n const parts = token.split('.');\n if (parts.length === 3) {\n const payload = JSON.parse(atob(parts[1]));\n console.info('Token payload:', payload);\n if (payload.exp) {\n const exp = new Date(payload.exp * 1000);\n const now = new Date();\n console.info('Token expires:', exp.toISOString(), 'Expired:', now > exp);\n }\n }\n } catch (e) {\n console.warn('Could not decode JWT:', e);\n }\n }\n return token ? 'Token present' : 'No token';\n } catch (e) {\n console.error('AppStorysDebugToken failed', e);\n return null;\n }\n };\n} catch (e) {\n // ignore\n}\n","import { SdkState, InitializationOptions, Attributes } from './types';\nimport { Banner } from './components/Banner';\nimport { Pip } from './components/Pip';\nimport Floater from './components/Floater';\nimport trackEvent from './core/trackEvent';\nimport trackScreen from './core/trackScreen';\nimport verifyAccount from './core/verifyAccount';\nimport setUserProperties from './core/setUserProperties';\nimport { personalizeText } from './core/personalization';\nimport fetchAllCampaigns from './core/fetchAllCampaigns';\nimport useAppStorysStore from './core/store';\nimport { getAccessToken } from './core/store';\nimport { revealCampaignFromLink } from './core/campaignHelpers';\nimport reconcileAnonymousUser from './core/reconcileUser';\nimport { exitIntentManager } from './core/exitIntent';\nimport { visibilityManager } from './core/visibilityManager';\nimport { getOrCreateAnonymousUserId, getStoredAnonymousUserId, clearAnonymousUserId } from './core/userManagement';\nimport { preloadFontsFromCampaigns } from './core/fontManager';\nimport './dev/showWidgetDebug';\n\nclass AppStorys {\n private state: SdkState = SdkState.uninitialized;\n private navigateToScreen?: (screen: string) => void;\n\n public async initialize(options: InitializationOptions) {\n const { appId, accountId, userId } = options;\n this.navigateToScreen = options.navigateToScreen;\n\n if (this.state === SdkState.initializing) return;\n\n if (this.state === SdkState.initialized) {\n const state = useAppStorysStore.getState();\n\n // If SDK is already initialized with an anonymous user and now a real userId is provided\n if (state.isAnonymousUser && userId && userId.trim() !== '') {\n console.log('AppStorys: Reconciling anonymous user with identified user...');\n await this.reconcileUser(state.userId, userId, appId, accountId);\n return;\n }\n\n if (state.appId === appId && state.accountId === accountId && state.userId === userId) {\n return;\n }\n }\n\n this.state = SdkState.initializing;\n\n try {\n let finalUserId: string;\n let isAnonymous: boolean;\n\n if (!userId || userId.trim() === '') {\n finalUserId = await getOrCreateAnonymousUserId();\n isAnonymous = true;\n } else {\n const storedAnonymousUserId = await getStoredAnonymousUserId();\n if (storedAnonymousUserId && storedAnonymousUserId !== userId) {\n // Reconcile will happen after verification, matching RN logic\n console.log('AppStorys: Found previous anonymous user, will reconcile after verification.');\n }\n finalUserId = userId;\n isAnonymous = false;\n }\n\n const success = await verifyAccount(accountId, appId, finalUserId);\n if (!success) {\n this.state = SdkState.error;\n return;\n }\n\n // Step 1.5: Reconcile if we moved from anonymous to identified\n if (!isAnonymous) {\n const storedAnonymousUserId = await getStoredAnonymousUserId();\n if (storedAnonymousUserId && storedAnonymousUserId !== finalUserId) {\n await reconcileAnonymousUser(storedAnonymousUserId, finalUserId);\n await clearAnonymousUserId();\n }\n }\n\n // Fire a non-blocking call to track-user-res so it appears in the browser Network tab\n try {\n const accessToken = await getAccessToken();\n const usersBase = options.baseUrl || 'https://users.appstorys.co';\n // Fire-and-handle response to update store flags (do not block init)\n fetch(`${usersBase}/v2/${accountId}/track-user-res`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}),\n },\n body: JSON.stringify({\n user_id: finalUserId,\n screenName: (typeof window !== 'undefined' && window.location && window.location.pathname) ? window.location.pathname : '',\n silentUpdate: true,\n }),\n })\n .then(async (resp) => {\n if (!resp.ok) return;\n try {\n const data = await resp.json();\n const s = useAppStorysStore.getState();\n if (typeof data.screen_capture_enabled !== 'undefined') {\n const val = Boolean(data.screen_capture_enabled);\n console.info('AppStorys: track-user-res returned screen_capture_enabled=', val);\n s.setScreenCaptureEnabled(val);\n }\n } catch (e) {\n /* ignore */\n }\n })\n .catch((err) => console.warn('track-user-res (init) failed', err));\n } catch (err) {\n console.warn('track-user-res (init) setup failed', err);\n }\n\n const { campaigns, version } = await fetchAllCampaigns(accountId);\n\n // Non-blocking: preload any remote fonts referenced by campaign styling.\n // Backend can send fontFamily as a URL (e.g. .ttf). Browsers need @font-face.\n try {\n void preloadFontsFromCampaigns(campaigns as any);\n } catch (err) {\n console.warn('Failed to preload campaign fonts', err);\n }\n\n const state = useAppStorysStore.getState();\n state.setAppId(appId);\n state.setAccountId(accountId);\n state.setUserId(finalUserId);\n state.setIsAnonymousUser(isAnonymous);\n state.setBaseUrl(options.baseUrl);\n state.setTrackingUrl(options.trackingUrl);\n state.saveAllCampaigns(campaigns);\n state.setCampaignVersion(version);\n\n // After campaigns and store are populated, mount screen-capture button if enabled\n try {\n const s = useAppStorysStore.getState();\n if (s.screenCaptureEnabled) {\n const scModule = await import('./core/screenCapture');\n scModule.mountScreenCaptureButton();\n }\n } catch (err) {\n // mounting failure shouldn't block initialization\n console.warn('Failed to mount screen capture button', err);\n }\n\n // Initialize Exit Intent / Back Press listeners\n exitIntentManager.setup();\n\n // Initialize Visibility listeners\n visibilityManager.setup();\n\n this.state = SdkState.initialized;\n } catch (e) {\n this.state = SdkState.error;\n console.error('AppStorys initialization failed:', e);\n }\n }\n\n /**\n * Reconciles an already initialized anonymous user with a newly provided identified user.\n */\n private async reconcileUser(\n anonymousUserId: string,\n identifiedUserId: string,\n appId: string,\n accountId: string\n ) {\n try {\n const success = await verifyAccount(accountId, appId, identifiedUserId);\n if (!success) {\n console.error('AppStorys: Failed to verify identified user account during reconciliation.');\n return;\n }\n\n const reconciled = await reconcileAnonymousUser(anonymousUserId, identifiedUserId);\n if (!reconciled) {\n console.error('AppStorys: Failed to reconcile anonymous and identified users.');\n return;\n }\n\n await clearAnonymousUserId();\n\n const state = useAppStorysStore.getState();\n state.setUserId(identifiedUserId);\n state.setIsAnonymousUser(false);\n } catch (error) {\n console.error('AppStorys: Error during user reconciliation:', error);\n }\n }\n\n public async trackScreen(screenName: string) {\n await this.ensureInitialized();\n return trackScreen(screenName);\n }\n\n public async trackEvent(event: string, campaignId?: string, metadata?: Attributes) {\n await this.ensureInitialized();\n return trackEvent(event, campaignId, metadata);\n }\n\n public async setUserProperties(attributes: Attributes) {\n await this.ensureInitialized();\n return setUserProperties(attributes);\n }\n\n public handleLink(link: string | any) {\n if (!link) return;\n\n if (typeof link === 'string') {\n // First try reveal flow: if link references a campaign id, reveal it\n try {\n if (!link.startsWith('http')) {\n const revealed = revealCampaignFromLink(link);\n if (revealed) return;\n }\n } catch (err) {\n // ignore helper errors and fallback to normal behavior\n console.warn('revealCampaignFromLink error', err);\n }\n\n if (link.startsWith('http')) {\n window.open(link, '_blank');\n } else {\n this.navigateToScreen?.(link);\n }\n } else if (typeof link === 'object' && link.value) {\n try {\n const revealed = revealCampaignFromLink(link.value);\n if (revealed) return;\n } catch (err) {\n // ignore\n }\n this.navigateToScreen?.(link.value);\n }\n }\n\n /**\n * Gets the visibility status of the SDK.\n * @returns boolean indicating whether the SDK is considered visible.\n */\n public get visibility(): boolean {\n return useAppStorysStore.getState().isVisible;\n }\n\n /**\n * Manually sets the visibility status of the SDK.\n * Useful for host apps that want to pause/resume SDK activities programmatically.\n * @param isVisible - boolean indicating visibility status.\n */\n public set visibility(isVisible: boolean) {\n visibilityManager.updateVisibility(isVisible);\n }\n\n private async ensureInitialized() {\n if (this.state === SdkState.initialized) return;\n\n const startTime = Date.now();\n while ((this.state as SdkState) !== SdkState.initialized) {\n if (this.state === SdkState.error) throw new Error('AppStorys SDK error');\n if (Date.now() - startTime > 10000) throw new Error('AppStorys SDK initialization timeout');\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n }\n public personalizeText(text: string): string {\n return personalizeText(text);\n }\n}\n\nimport { Story } from './components/Story';\nimport { Widget } from './components/Widget';\nimport Tooltip from './components/Tooltip';\nimport { BottomSheet } from './components/BottomSheet';\nimport Csat from './components/Csat';\nimport Survey from './components/Survey';\n\nconst instance = new AppStorys();\nexport { instance as AppStorys, Banner, Story, Pip, Widget, Floater, Tooltip, BottomSheet, Csat, Survey, personalizeText };\nexport * from './types';\n\n","export type CampaignType = 'BAN' | 'FLT' | 'PIP' | 'SUR' | 'CSAT' | 'WID' | 'MOD' | 'BTS' | 'SCRT' | 'STR' | 'TLTP' | 'TTP';\n\n\nexport interface CrossButtonConfig {\n color: {\n cross: string;\n fill: string;\n stroke: string;\n };\n enabled: boolean;\n image: string;\n margin: {\n bottom: number;\n left: number;\n right: number;\n top: number;\n };\n selectedStyle?: string;\n size: number;\n}\n\nexport interface StorySlideCtaBorderRadius {\n topLeft?: number;\n topRight?: number;\n bottomLeft?: number;\n bottomRight?: number;\n}\n\nexport interface TriggerEventConfig {\n key?: string;\n operator?: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte';\n value?: string;\n back_press?: boolean;\n}\n\nexport interface TriggerEventObject {\n event: string;\n event_config: TriggerEventConfig[];\n}\n\nexport type TriggerEvent = string | TriggerEventObject;\n\nexport interface BaseCampaign {\n id: string;\n campaign_type: CampaignType;\n trigger_event?: TriggerEvent;\n position?: string;\n screen?: string;\n details: any;\n}\n\nexport interface CampaignBanner extends BaseCampaign {\n campaign_type: 'BAN';\n details: {\n id: string;\n image: string | null;\n lottie_data: string | null;\n width: null | number;\n height: null | number;\n link: null | string;\n styling: {\n bottomLeftRadius?: string;\n bottomRightRadius?: string;\n topLeftRadius?: string;\n topRightRadius?: string;\n marginBottom?: string;\n marginLeft?: string;\n marginRight?: string;\n crossButton?: CrossButtonConfig;\n [key: string]: any;\n };\n };\n}\n\nexport interface Attributes {\n [key: string]: any;\n}\n\nexport enum SdkState {\n uninitialized = 'uninitialized',\n initializing = 'initializing',\n initialized = 'initialized',\n error = 'error'\n}\n\nexport interface AppStorysStore {\n userId: string;\n appId: string;\n accountId: string;\n currentScreen: string;\n campaigns: Campaign[];\n allCampaigns: Campaign[];\n campaignVersion: number;\n trackedEvents: string[];\n trackedEventMetadata: Record<string, Attributes[]>;\n attributes?: Attributes;\n isVisible: boolean;\n isAnonymousUser: boolean;\n variantMappings: Record<string, string>;\n personalizationData: Record<string, string>;\n screenCaptureEnabled?: boolean;\n baseUrl?: string;\n trackingUrl?: string;\n}\n\nexport interface StorySlideCtaContainer {\n alignment?: string;\n backgroundColor?: string;\n borderColor?: string;\n borderWidth?: number;\n ctaFullWidth?: boolean;\n ctaWidth?: number;\n height?: number;\n}\n\nexport interface StorySlideCtaText {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n}\n\nexport interface StorySlideCta {\n container?: StorySlideCtaContainer;\n cornerRadius?: StorySlideCtaBorderRadius;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n text?: StorySlideCtaText;\n}\n\nexport interface StorySlideStyling {\n cta?: StorySlideCta;\n meta?: {\n editorSource?: string;\n };\n pc_redirect_type?: string;\n rdrType?: string;\n}\n\nexport interface StorySlide {\n button_text?: string;\n content?: any;\n id: string;\n image: string | null;\n interactions?: any[];\n link: string | null;\n order: number;\n parent: string;\n personalizationData?: any;\n styling?: StorySlideStyling;\n video: string | null;\n}\n\nexport interface StoryGroupStyling {\n cornerRadius?: {\n bottomLeft?: number;\n bottomRight?: number;\n topLeft?: number;\n topRight?: number;\n };\n crossButton?: CrossButtonConfig;\n name?: {\n font?: string;\n fontFamily?: string;\n size?: number;\n };\n ringWidth?: number;\n share?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n enabled?: boolean;\n image?: string;\n margin?: {\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n size?: number;\n slideShowTime?: number;\n soundToggle?: {\n defaultSound?: string;\n enabled?: boolean;\n mute?: any;\n unmute?: any;\n };\n storyGroupText?: string;\n}\n\nexport interface Story {\n cohorts: any;\n id: string;\n name: string;\n nameColor: string;\n order: number;\n ringColor: string;\n slides: StorySlide[];\n styling?: StoryGroupStyling;\n thumbnail: string;\n}\n\nexport interface CampaignStory extends BaseCampaign {\n campaign_type: 'STR';\n details: Story[];\n}\n\nexport interface WidgetImage {\n cohorts: any;\n id: string;\n image: string;\n link: string;\n order: number;\n}\n\nexport interface CampaignWidget extends BaseCampaign {\n campaign_type: 'WID';\n details: {\n height: number;\n id: string;\n styling: {\n borderRadius: number;\n bottomLeftRadius: number;\n bottomMargin: number;\n bottomRightRadius: number;\n leftMargin: number;\n rightMargin: number;\n topLeftRadius: number;\n topMargin: number;\n topRightRadius: number;\n type: string;\n };\n widget_images: WidgetImage[];\n width: number;\n type?: string;\n };\n}\n\nexport interface TooltipStyling {\n appearance?: {\n arrowStyle?: { height?: number; width?: number };\n backdropOpacity?: number;\n colors?: { arrow?: string; backdrop?: string; tooltip?: string };\n cornerRadius?: { bottomLeft?: number; bottomRight?: number; topLeft?: number; topRight?: number };\n highlight?: { padding?: number; radius?: number };\n padding?: { bottom?: number; left?: number; right?: number; top?: number };\n };\n cta?: {\n container?: {\n alignment?: string;\n backgroundColor?: string;\n borderColor?: string;\n borderWidth?: number;\n ctaFullWidth?: boolean;\n ctaWidth?: number;\n height?: number;\n };\n cornerRadius?: { bottomLeft?: number; bottomRight?: number; topLeft?: number; topRight?: number };\n margin?: { bottom?: number; left?: number; right?: number; top?: number };\n text?: { color?: string; fontDecoration?: string[]; fontFamily?: string; fontSize?: number };\n };\n subTitle?: {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n margin?: { bottom?: number; left?: number; right?: number; top?: number };\n textAlign?: string;\n };\n title?: {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n margin?: { bottom?: number; left?: number; right?: number; top?: number };\n textAlign?: string;\n };\n}\n\nexport interface TooltipItem {\n _id: string;\n arrowPosition?: \"left\" | \"right\" | \"top\" | \"bottom\" | string;\n clickAction?: \"nextStep\" | \"close\" | string;\n ctaText?: string;\n enableBackdrop?: boolean;\n eventName?: string;\n link?: string;\n order?: number;\n position?: string;\n styling?: TooltipStyling;\n subtitleText?: string;\n target?: string;\n titleText?: string;\n url?: string | null;\n}\n\nexport interface CampaignTooltip extends BaseCampaign {\n campaign_type: 'TTP';\n details: {\n tooltips?: TooltipItem[];\n \n titleText?: string;\n subtitleText?: string;\n target?: string;\n styling?: TooltipStyling;\n } & Partial<TooltipItem>;\n display_trigger?: boolean;\n}\n\nexport interface BottomSheetElement {\n id: string;\n type: 'image' | 'cta' | 'body' | string;\n order: number;\n [key: string]: any;\n}\n\nexport interface CampaignBottomSheet extends BaseCampaign {\n campaign_type: 'BTS';\n details: {\n backdropColor?: string;\n backdropOpacity?: number;\n backgroundColor?: string;\n bottomsheetType?: string;\n cornerRadius?: {\n bottomLeft?: number;\n bottomRight?: number;\n topLeft?: number;\n topRight?: number;\n };\n crossButton?: CrossButtonConfig;\n elements: BottomSheetElement[];\n id: string;\n name: string;\n };\n}\n\nexport interface SurveyTextStyle {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n textAlign?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n borderwidth?: number;\n}\n\nexport interface SurveyOptionColors {\n background?: string;\n border?: string;\n text?: string;\n}\n\nexport interface SurveyOptionStyle {\n colors?: SurveyOptionColors;\n textStyle?: SurveyTextStyle;\n}\n\nexport interface SurveySlideLogicRule {\n redirectTo?: string;\n selectOption?: string[];\n}\n\nexport interface SurveySlide {\n additionalComment?: {\n enabled?: boolean;\n placeholder?: string;\n };\n id: string;\n logic?: SurveySlideLogicRule[];\n options?: Record<string, string>;\n order: number;\n parent: string;\n question?: string;\n submitButtonText?: string;\n subtitle?: string;\n title?: string;\n}\n\nexport interface SurveyThankYouButtonConfig {\n action?: string;\n enabled?: boolean;\n redirectUrl?: string;\n}\n\nexport interface SurveyCampaignDetails {\n id: string;\n name?: string;\n slides?: SurveySlide[];\n styling?: {\n appearance?: {\n backdropColor?: string;\n backdropOpacity?: number;\n backgroundColor?: string;\n cornerRadius?: {\n topLeft?: number;\n topRight?: number;\n bottomLeft?: number;\n bottomRight?: number;\n };\n displayDelay?: number;\n };\n content?: {\n isIntroductionPage?: boolean;\n isThankyouPage?: boolean;\n };\n crossButton?: CrossButtonConfig;\n cta?: StorySlideCta;\n options?: {\n additionalComments?: SurveyOptionStyle;\n bulletSpacing?: number;\n cornerRadius?: StorySlideCtaBorderRadius;\n nonSelectedOptions?: SurveyOptionStyle;\n optionListStyle?: string;\n optionsHeight?: number;\n optionsSpacing?: number;\n selectedOptions?: SurveyOptionStyle;\n };\n subtitle?: {\n textStyle?: SurveyTextStyle;\n };\n thankyouPage?: {\n cta?: StorySlideCta;\n imageStyle?: {\n height?: number;\n width?: number;\n };\n subtitle?: {\n textStyle?: SurveyTextStyle;\n };\n title?: {\n textStyle?: SurveyTextStyle;\n };\n };\n title?: {\n textStyle?: SurveyTextStyle;\n };\n };\n thankYouButtonConfig?: SurveyThankYouButtonConfig;\n thankYouButtonText?: string;\n thankYouImage?: string;\n thankYouText?: string;\n thankYouTitle?: string;\n}\n\nexport interface CampaignSurvey extends BaseCampaign {\n campaign_type: 'SUR';\n details: SurveyCampaignDetails;\n}\n\nexport interface CsatTextStyle {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n textAlign?: string;\n}\n\nexport interface CsatSpacing {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\nexport interface CsatCampaignDetails {\n campaign?: string;\n description_text?: string;\n feedback_option?: Record<string, string>;\n height?: number;\n highStarText?: string;\n id: string;\n link?: string;\n lowStarText?: string;\n styling?: {\n appearance?: {\n backgroundColor?: string;\n borderRadius?: number;\n displayDelay?: number;\n margin?: CsatSpacing;\n padding?: CsatSpacing;\n };\n crossButton?: CrossButtonConfig;\n feedbackPage?: {\n additionalComments?: {\n borderWidth?: number;\n colors?: {\n background?: string;\n border?: string;\n text?: string;\n };\n enabled?: boolean;\n placeholder?: string;\n textStyle?: CsatTextStyle;\n };\n options?: {\n cornerRadius?: {\n topLeft?: number;\n topRight?: number;\n bottomLeft?: number;\n bottomRight?: number;\n };\n margin?: CsatSpacing;\n nonSelectedOptions?: {\n borderWidth?: number;\n colors?: {\n background?: string;\n border?: string;\n text?: string;\n };\n textStyle?: CsatTextStyle;\n };\n optionsHeight?: number;\n optionsSpacing?: number;\n selectedOptions?: {\n borderWidth?: number;\n colors?: {\n background?: string;\n border?: string;\n text?: string;\n };\n textStyle?: CsatTextStyle;\n };\n };\n submitButton?: {\n cta?: StorySlideCta;\n enabled?: boolean;\n text?: string;\n };\n };\n initialFeedback?: {\n subtitle?: {\n margin?: CsatSpacing;\n textStyle?: CsatTextStyle;\n };\n title?: {\n margin?: CsatSpacing;\n textStyle?: CsatTextStyle;\n };\n };\n rating?: {\n emoji?: string[] | Record<string, string> | string | null;\n highRatingSubtitle?: string;\n highRatingTitle?: string;\n lowRatingSubtitle?: string;\n lowRatingTitle?: string;\n number?: number | { min?: number; max?: number } | null;\n ratingType?: string;\n star?: {\n high?: {\n stylingContainer?: { background?: string; border?: string; borderWidth?: number };\n stylingStar?: { background?: string; border?: string; borderWidth?: number };\n };\n low?: {\n stylingContainer?: { background?: string; border?: string; borderWidth?: number };\n stylingStar?: { background?: string; border?: string; borderWidth?: number };\n };\n unselected?: {\n stylingContainer?: { background?: string; border?: string; borderWidth?: number };\n stylingStar?: { background?: string; border?: string; borderWidth?: number };\n };\n };\n };\n thankyouPage?: {\n doneButton?: {\n cta?: StorySlideCta;\n text?: string;\n };\n imageStyle?: {\n height?: number;\n width?: number;\n };\n subtitle?: {\n margin?: CsatSpacing;\n textStyle?: CsatTextStyle;\n };\n title?: {\n margin?: CsatSpacing;\n textStyle?: CsatTextStyle;\n };\n };\n };\n thankyouDescription?: string;\n thankyouImage?: string;\n thankyouText?: string;\n title?: string;\n width?: number;\n}\n\nexport interface CampaignCsat extends BaseCampaign {\n campaign_type: 'CSAT';\n details: CsatCampaignDetails;\n}\n\nexport type Campaign = CampaignBanner | CampaignStory | CampaignWidget | CampaignTooltip | CampaignBottomSheet | CampaignCsat | CampaignSurvey | BaseCampaign;\n\nexport interface InitializationOptions {\n appId: string;\n accountId: string;\n userId?: string;\n baseUrl?: string;\n trackingUrl?: string;\n navigateToScreen?: (screen: string) => void;\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport * as LottieModule from 'lottie-react';\nimport { CampaignBanner } from '../../types';\nimport useAppStorysStore from '../../core/store';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\n\nconst Lottie =\n (LottieModule as any).default?.default ??\n (LottieModule as any).default ??\n (LottieModule as any).Lottie ??\n (LottieModule as any);\n\nexport const Banner: React.FC = () => {\n const data = useCampaigns<CampaignBanner>('BAN');\n const sdkVisible = useAppStorysStore((state) => state.isVisible);\n const [isDismissed, setIsDismissed] = useState(false);\n const [lottieData, setLottieData] = useState<any>(null);\n const [aspectRatio, setAspectRatio] = useState<number | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState<number>(0);\n\n useEffect(() => {\n if (data) {\n setIsDismissed(false);\n void trackEvent('viewed', data.id);\n\n // Fetch Lottie data if available\n if (data.details.lottie_data) {\n fetch(data.details.lottie_data)\n .then(res => res.json())\n .then(json => {\n setLottieData(json);\n if (json.w && json.h) {\n setAspectRatio(json.h / json.w);\n }\n })\n .catch(err => console.error('Error loading Lottie:', err));\n }\n }\n }, [data]);\n\n useEffect(() => {\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.offsetWidth);\n }\n };\n\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [data, isDismissed]);\n\n if (!data || isDismissed || !sdkVisible) return null;\n\n const { details } = data;\n const styling = details.styling || {};\n \n // Calculate height based on aspect ratio or fixed height\n let calculatedHeight: string | number = details.height || 'auto';\n if (aspectRatio && containerWidth) {\n calculatedHeight = containerWidth * aspectRatio;\n }\n\n const bannerStyle: React.CSSProperties = {\n position: 'fixed' as const,\n left: styling.marginLeft ? `${styling.marginLeft}px` : '10px',\n right: styling.marginRight ? `${styling.marginRight}px` : '10px',\n bottom: styling.marginBottom ? `${styling.marginBottom}px` : '10px',\n backgroundColor: 'transparent',\n borderRadius: `${styling.topRightRadius || 0}px ${styling.topLeftRadius || 0}px ${styling.bottomRightRadius || 0}px ${styling.bottomLeftRadius || 0}px`,\n overflow: 'hidden',\n zIndex: 9999,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: details.link ? 'pointer' : 'default',\n };\n\n const mediaStyle: React.CSSProperties = {\n width: '100%',\n height: typeof calculatedHeight === 'number' ? `${calculatedHeight}px` : calculatedHeight,\n display: 'block',\n objectFit: 'cover',\n };\n\n const handleClose = (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsDismissed(true);\n void trackEvent('banner_closed', data.id);\n };\n\n const handleClick = () => {\n if (details.link) {\n void trackEvent('clicked', data.id);\n if (details.link.startsWith('http')) {\n window.open(details.link, '_blank');\n } else {\n // Try reveal via campaign id first\n try {\n const revealed = revealCampaignFromLink(details.link);\n if (revealed) return;\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n // Fallback to logging/navigation\n console.log('Internal link:', details.link);\n }\n }\n };\n\n return (\n <div ref={containerRef} style={bannerStyle} onClick={handleClick}>\n {lottieData ? (() => {\n const LottieComp = (Lottie as any).default || Lottie;\n return (\n <LottieComp \n animationData={lottieData} \n loop={true} \n autoplay={sdkVisible}\n style={mediaStyle}\n />\n );\n })() : details.image ? (\n <img src={details.image} alt=\"Campaign Banner\" style={mediaStyle} />\n ) : null}\n \n {styling.crossButton?.enabled && (\n <button \n onClick={handleClose}\n style={{\n position: 'absolute',\n top: '5px',\n right: '5px',\n background: 'rgba(0,0,0,0.3)',\n color: 'white',\n border: 'none',\n borderRadius: '50%',\n width: '24px',\n height: '24px',\n lineHeight: '22px',\n textAlign: 'center',\n cursor: 'pointer',\n padding: '0',\n fontSize: '14px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 10\n }}\n >\n ✕\n </button>\n )}\n </div>\n );\n};\n","import { useMemo } from \"react\";\nimport { Campaign, TriggerEventConfig, TriggerEventObject, Attributes } from \"../types\";\nimport useAppStorysStore from \"../core/store\";\nimport { resolveCampaignVariant } from \"../core/variantResolver\";\n\nexport const BACK_PRESS_SENTINEL = '__back_press_triggered__';\n\ninterface UseCampaignsOptions {\n position?: string;\n screenContains?: string;\n}\n\nfunction normalizeScreenName(screen?: string | null): string {\n return (screen || '').trim().toLowerCase();\n}\n\nfunction isScreenMatch(campaignScreen: string | undefined, currentScreen: string): boolean {\n const normalizedCampaignScreen = normalizeScreenName(campaignScreen);\n const normalizedCurrentScreen = normalizeScreenName(currentScreen);\n return !normalizedCampaignScreen || normalizedCampaignScreen === normalizedCurrentScreen;\n}\n\nfunction compareValues(actual: string, operator: TriggerEventConfig['operator'], expected: string): boolean {\n const numActual = Number(actual);\n const numExpected = Number(expected);\n const useNumeric = !isNaN(numActual) && !isNaN(numExpected);\n\n switch (operator) {\n case 'eq': return useNumeric ? numActual === numExpected : actual === expected;\n case 'neq': return useNumeric ? numActual !== numExpected : actual !== expected;\n case 'gt': return useNumeric ? numActual > numExpected : actual > expected;\n case 'gte': return useNumeric ? numActual >= numExpected : actual >= expected;\n case 'lt': return useNumeric ? numActual < numExpected : actual < expected;\n case 'lte': return useNumeric ? numActual <= numExpected : actual <= expected;\n default: return false;\n }\n}\n\nfunction matchesEventConditions(\n event_config: TriggerEventConfig[],\n metadataList: Attributes[],\n): boolean {\n const realConditions = event_config.filter((c) => c.back_press == null);\n if (realConditions.length === 0) return true;\n\n return metadataList.some((meta) =>\n realConditions.every((condition) => {\n const actual = meta[condition.key!];\n if (actual === undefined || actual === null) return false;\n return compareValues(String(actual), condition.operator!, condition.value!);\n })\n );\n}\n\nfunction isTriggerEventSatisfied(\n campaign: Campaign,\n trackedEvents: string[],\n trackedEventMetadata: Record<string, Attributes[]>,\n): boolean {\n // Support both the typed `trigger_event` and legacy `trigger` fields from campaign JSON\n const t = campaign as any;\n const trigger_event = (t.trigger_event ?? t.trigger) as TriggerEvent | undefined;\n const id = (campaign as Campaign & { id?: string }).id;\n // If a campaign carries any trigger information, do not show it by default.\n // The presence of `trigger_event` or legacy `trigger` indicates it's intended\n // to be shown only in response to an event; hide unless that event handling\n // code explicitly adds it back to the visible campaigns list.\n if (trigger_event) return false;\n\n return true;\n}\n\n/**\n * Checks whether any currently loaded campaign is a back_press (exit intent) campaign\n * that is ready to show but not yet triggered.\n */\nexport function isBackPressCampaignReady(): boolean {\n const { campaigns, trackedEvents, trackedEventMetadata, currentScreen } = useAppStorysStore.getState();\n\n return campaigns.some((campaign) => {\n if (campaign.screen && campaign.screen !== currentScreen) return false;\n\n const te = (campaign as any).trigger_event;\n if (!te || typeof te === 'string') return false;\n\n const { event, event_config } = te as TriggerEventObject;\n if (!(event_config ?? []).some((c: TriggerEventConfig) => c.back_press === true)) return false;\n\n // Already consumed\n if (trackedEvents.includes(BACK_PRESS_SENTINEL)) return false;\n\n // The underlying event must have been tracked\n if (!trackedEvents.includes(event)) return false;\n\n // Non-back_press conditions must also pass\n const realConditions = (event_config ?? []).filter((c: TriggerEventConfig) => c.back_press == null);\n if (realConditions.length === 0) return true;\n\n const metadataList = trackedEventMetadata[event] || [];\n return matchesEventConditions(realConditions, metadataList);\n });\n}\n\nexport default function useCampaigns<T extends Campaign>(campaignType: string, options?: UseCampaignsOptions): T | undefined {\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const trackedEvents = useAppStorysStore((state) => state.trackedEvents);\n const trackedEventMetadata = useAppStorysStore((state) => state.trackedEventMetadata);\n const variantMappings = useAppStorysStore((state) => state.variantMappings);\n\n return useMemo(\n () => {\n const matchCampaign = (list: Campaign[]) => list.find((campaign) =>\n isScreenMatch(campaign.screen, currentScreen) &&\n campaign.campaign_type === campaignType &&\n (options?.position ? campaign.position === options.position : true) &&\n isTriggerEventSatisfied(campaign, trackedEvents, trackedEventMetadata)\n );\n\n const fromEligible = campaigns && campaigns.length > 0 ? matchCampaign(campaigns) : undefined;\n const campaign = fromEligible ?? matchCampaign(allCampaigns || []);\n\n if (!campaign) return undefined;\n return resolveCampaignVariant(campaign) as T | undefined;\n },\n [campaigns, allCampaigns, trackedEvents, trackedEventMetadata, variantMappings, campaignType, options, currentScreen],\n );\n}\n\nexport function useCampaignsList<T extends Campaign>(campaignType: string, options?: UseCampaignsOptions): T[] {\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const trackedEvents = useAppStorysStore((state) => state.trackedEvents);\n const trackedEventMetadata = useAppStorysStore((state) => state.trackedEventMetadata);\n\n return useMemo(() => {\n const list = (campaigns && campaigns.length > 0) ? campaigns : (allCampaigns || []);\n\n const filtered = list.filter((campaign) => {\n if (campaign.campaign_type !== campaignType) return false;\n if (options?.position && campaign.position !== options.position) return false;\n if (!isTriggerEventSatisfied(campaign, trackedEvents, trackedEventMetadata)) return false;\n\n // If caller passed a screenContains option, match substring (case-insensitive)\n if (options?.screenContains) {\n const needle = (options.screenContains || '').trim().toLowerCase();\n const cs = (campaign.screen || '').trim().toLowerCase();\n return cs.includes(needle);\n }\n\n // Fallback to existing screen matching logic\n return isScreenMatch(campaign.screen, currentScreen);\n });\n\n return filtered.map((c) => resolveCampaignVariant(c) as T) as T[];\n }, [campaigns, allCampaigns, trackedEvents, trackedEventMetadata, campaignType, options, currentScreen]);\n}\n","import { Campaign } from \"../types\";\nimport useAppStorysStore from \"./store\";\n\nconst getVariantId = (campaignId: string): string | undefined => {\n return useAppStorysStore.getState().variantMappings[campaignId];\n};\n\nexport function hasVariants(campaign: Campaign): boolean {\n return !!(campaign.details && typeof campaign.details === 'object' && 'variants' in campaign.details);\n}\n\nexport function resolveCampaignVariant<T extends Campaign>(campaign: T): T {\n if (!hasVariants(campaign)) {\n return campaign;\n }\n\n const variantId = getVariantId(campaign.id || '');\n \n if (!variantId) {\n return campaign;\n }\n\n const variants = (campaign.details as any)?.variants;\n \n if (!variants || typeof variants !== 'object') {\n return campaign;\n }\n\n const variantDetails = variants[variantId];\n \n if (!variantDetails) {\n return campaign;\n }\n\n // Merge base campaign details first, then overlay variant details so\n // variant-specific fields take precedence when keys overlap.\n const baseDetails = (typeof campaign.details === 'object')\n ? Object.fromEntries(Object.entries(campaign.details).filter(([key]) => key !== 'variants'))\n : {};\n\n const resolvedCampaign = {\n ...campaign,\n details: {\n ...baseDetails,\n ...variantDetails,\n },\n _variantId: variantId,\n } as T;\n \n return resolvedCampaign;\n}\n\nexport function getCampaignVariantId(campaign: Campaign): string | undefined {\n if ('_variantId' in campaign) {\n return (campaign as any)._variantId;\n }\n \n if (hasVariants(campaign)) {\n return getVariantId(campaign.id || '');\n }\n \n return undefined;\n}\n","import useAppStorysStore, { getAccessToken, getUserId, getVariantId } from \"./store\";\nimport { Attributes } from \"../types\";\nimport getDeviceInfo from \"./getDeviceInfo\";\nimport { sendOrQueue } from \"./offlineQueue\";\n\nexport default async function trackEvent(event: string, campaignId?: string, metadata?: Attributes) {\n try {\n if (!event) return;\n\n const accessToken = await getAccessToken();\n const state = useAppStorysStore.getState();\n\n const excludedEvents = [\n \"viewed\",\n \"clicked\",\n \"csat captured\",\n \"survey captured\",\n \"shared\"\n ];\n\n if (!excludedEvents.includes(event)) {\n const trackedEvents = state.trackedEvents;\n if (!trackedEvents.includes(event)) {\n state.setTrackedEvents([...trackedEvents, event]);\n } else {\n const updatedEvents = trackedEvents.filter(e => e !== event);\n updatedEvents.push(event);\n state.setTrackedEvents(updatedEvents);\n }\n\n if (metadata && Object.keys(metadata).length > 0) {\n const currentMeta = state.trackedEventMetadata || {};\n const existing = currentMeta[event] || [];\n state.setTrackedEventMetadata({\n ...currentMeta,\n [event]: [...existing, metadata],\n });\n }\n }\n\n let finalMetadata: Record<string, any> = {\n ...(metadata || {}),\n };\n\n if (!excludedEvents.includes(event)) {\n const deviceInfo = await getDeviceInfo();\n finalMetadata = {\n ...finalMetadata,\n ...deviceInfo,\n };\n }\n\n // Mirror native: include variant_id when a mapping exists for the campaign id\n if (campaignId && String(campaignId).trim() !== \"\") {\n const variantId = getVariantId(campaignId);\n if (variantId) {\n finalMetadata.variant_id = variantId;\n // console.debug(`Including variant_id in analytics: ${variantId}`);\n }\n }\n\n const body: Record<string, any> = {\n user_id: getUserId(),\n event: event,\n metadata: finalMetadata,\n };\n if (campaignId) {\n body.campaign_id = campaignId;\n }\n\n const trackingUrl = state.trackingUrl || 'https://tracking.appstorys.co';\n\n if (accessToken) {\n await sendOrQueue({\n url: `${trackingUrl}/capture-event`,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: body,\n });\n }\n } catch (error) {\n console.error('Error in trackEvent', error);\n }\n}\n","import { WebStorage } from '../adapters/web/storage';\nimport useAppStorysStore, { getAccessToken } from './store';\nimport verifyAccount from './verifyAccount';\n\nconst OFFLINE_QUEUE_KEY = \"appstorys_offline_queue\";\n\nexport interface QueuedRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n body: any;\n retryCount?: number;\n lastAttempt?: number;\n authRetried?: boolean;\n}\n\nasync function getQueue(): Promise<QueuedRequest[]> {\n const existing = await WebStorage.getItem(OFFLINE_QUEUE_KEY);\n return existing ? JSON.parse(existing) : [];\n}\n\nasync function saveQueue(queue: QueuedRequest[]) {\n await WebStorage.setItem(OFFLINE_QUEUE_KEY, JSON.stringify(queue));\n}\n\nfunction getBackoffDelay(retryCount: number): number {\n // Exponential backoff: 30s, 1min, 2min (max 2min)\n return Math.min(30000 * Math.pow(2, retryCount), 120000);\n}\n\nfunction shouldRetryRequest(request: QueuedRequest): boolean {\n const maxRetries = 3;\n const retryCount = request.retryCount || 0;\n const lastAttempt = request.lastAttempt || 0;\n const backoffDelay = getBackoffDelay(retryCount);\n\n return retryCount < maxRetries && Date.now() - lastAttempt >= backoffDelay;\n}\n\nasync function validateCredentials(): Promise<boolean> {\n const state = useAppStorysStore.getState();\n if (!state.accountId || !state.appId) return false;\n \n return await verifyAccount(\n state.accountId,\n state.appId,\n state.userId\n );\n}\n\nasync function handleAuthError(\n request: QueuedRequest,\n onSuccess: (request: QueuedRequest) => void\n) {\n const credentialsValid = await validateCredentials();\n\n if (credentialsValid) {\n const newToken = await WebStorage.getItem('access_token');\n if (newToken) {\n request.headers = {\n ...request.headers,\n Authorization: `Bearer ${newToken}`,\n };\n }\n request.authRetried = true;\n request.lastAttempt = Date.now();\n onSuccess(request);\n }\n}\n\nasync function handleCriticalError(\n request: QueuedRequest, \n onSuccess: (request: QueuedRequest) => void\n) {\n const retryCount = (request.retryCount || 0) + 1;\n\n if (retryCount <= 3) {\n request.retryCount = retryCount;\n request.lastAttempt = Date.now();\n onSuccess(request);\n }\n}\n\nasync function addToQueue(request: QueuedRequest) {\n const queue = await getQueue();\n queue.push(request);\n await saveQueue(queue);\n}\n\nexport async function flushQueue() {\n const queue = await getQueue();\n if (queue.length === 0) return;\n\n const newQueue: QueuedRequest[] = [];\n\n for (const req of queue) {\n if (!shouldRetryRequest(req)) {\n newQueue.push(req);\n continue;\n }\n\n try {\n const res = await fetch(req.url, {\n method: req.method,\n headers: req.headers,\n body: JSON.stringify(req.body),\n });\n\n if (res.ok) continue;\n\n if (res.status === 401 || res.status === 403) {\n if (!req.authRetried) {\n await handleAuthError(req, (r) => newQueue.push(r));\n }\n } else if (res.status >= 500) {\n await handleCriticalError(req, (r) => newQueue.push(r));\n }\n } catch (err) {\n await handleCriticalError(req, (r) => newQueue.push(r));\n }\n }\n\n await saveQueue(newQueue);\n}\n\nexport async function sendOrQueue(request: QueuedRequest): Promise<Response | void> {\n if (!navigator.onLine) {\n await addToQueue(request);\n return;\n }\n\n // Auto-flush existing queue\n await flushQueue();\n\n try {\n const res = await fetch(request.url, {\n method: request.method,\n headers: request.headers,\n body: JSON.stringify(request.body),\n });\n\n if (res.ok) return res;\n\n if (res.status === 401 || res.status === 403) {\n await handleAuthError(request, addToQueue);\n } else if (res.status >= 500) {\n await handleCriticalError(request, addToQueue);\n }\n\n return res;\n } catch (err) {\n await handleCriticalError(request, addToQueue);\n return;\n }\n}\n","import useAppStorysStore from './store';\n\nexport function isTriggerDriven(campaign: any): boolean {\n return Boolean((campaign && (campaign.trigger_event ?? campaign.trigger)));\n}\n\nexport function revealCampaignFromLink(link: string): boolean {\n if (!link) return false;\n const s = useAppStorysStore.getState();\n const all = s.allCampaigns || [];\n const existing = s.campaigns || [];\n\n const normalizedLink = String(link).trim();\n\n const referenced = all.find((c: any) => {\n if (!c) return false;\n const cid = String(c.id || '').trim();\n const details = c.details || {};\n const detailsCampaign = String(details.campaign || details.id || '').trim();\n if (cid && cid === normalizedLink) return true;\n if (detailsCampaign && detailsCampaign === normalizedLink) return true;\n if (cid && normalizedLink.includes(cid)) return true;\n if (detailsCampaign && normalizedLink.includes(detailsCampaign)) return true;\n return false;\n });\n\n if (!referenced) return false;\n\n const revealed: any = { ...referenced };\n delete revealed.trigger_event;\n delete revealed.trigger;\n revealed.display_trigger = true;\n\n const idx = existing.findIndex((c: any) => String(c.id || '') === String(revealed.id || ''));\n if (idx === -1) {\n s.saveCampaigns([revealed, ...existing]);\n } else {\n const existingItem = existing[idx];\n const existingHasTrigger = Boolean((existingItem as any).trigger_event ?? (existingItem as any).trigger);\n if (existingHasTrigger) {\n const next = [...existing];\n next[idx] = revealed;\n s.saveCampaigns(next);\n }\n }\n\n return true;\n}\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport useCampaigns from \"../../hooks/useCampaigns\";\nimport trackEvent from \"../../core/trackEvent\";\nimport useAppStorysStore from \"../../core/store\";\nimport { Campaign } from \"../../types\";\nimport { resolveCampaignVariant } from \"../../core/variantResolver\";\nimport { resolveFontFamily } from \"../../core/fontManager\";\n\ninterface PipCampaignDetails {\n button_text?: string;\n crossButtonImage?: string | null;\n height?: number | string;\n width?: number | string;\n large_video?: string;\n small_video?: string;\n link?: string;\n maximiseImage?: string | null;\n minimiseImage?: string | null;\n muteImage?: string | null;\n position?: \"left\" | \"right\" | string;\n unmuteImage?: string | null;\n styling?: {\n appearance?: {\n defaultSound?: string;\n pipHeight?: string | number;\n pipWidth?: string | number;\n };\n crossButton?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n enabled?: boolean;\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n cta?: {\n container?: {\n backgroundColor?: string;\n borderColor?: string;\n borderWidth?: number;\n ctaWidth?: number;\n ctaFullWidth?: boolean;\n height?: number;\n };\n text?: {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n };\n };\n expandControls?: {\n enabled?: boolean;\n maximise?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n minimise?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n };\n expandablePip?: string;\n isMovable?: boolean;\n pipBottomPadding?: number | string;\n pipTopPadding?: number | string;\n soundToggle?: {\n enabled?: boolean;\n defaultSound?: string;\n mute?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n unmute?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n };\n };\n}\n\ninterface IconConfig {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n}\n\ntype PipCampaign = Campaign & {\n campaign_type: \"PIP\";\n details: PipCampaignDetails;\n display_trigger?: boolean;\n screen?: string;\n position?: string;\n id: string;\n};\n\nconst normalizeScreen = (value?: string | null): string => (value || \"\").trim().toLowerCase();\n\nconst parseNumber = (value: unknown, fallback: number): number => {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nfunction PipIcon({ iconType, color }: { iconType: \"close\" | \"expand\" | \"minimize\" | \"mute\" | \"unmute\"; color: string }) {\n const stroke = color || \"#FFFFFF\";\n\n if (iconType === \"close\") {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n\n if (iconType === \"expand\") {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polyline points=\"8,3 3,3 3,8\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <line x1=\"3\" y1=\"3\" x2=\"9\" y2=\"9\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <polyline points=\"16,21 21,21 21,16\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n\n if (iconType === \"minimize\") {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polyline points=\"9,9 3,9 3,3\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <line x1=\"3\" y1=\"9\" x2=\"9\" y2=\"3\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <polyline points=\"15,15 21,15 21,21\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <line x1=\"15\" y1=\"21\" x2=\"21\" y2=\"15\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n\n if (iconType === \"mute\") {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polygon points=\"4,10 8,10 13,6 13,18 8,14 4,14\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinejoin=\"round\" />\n <line x1=\"16\" y1=\"8\" x2=\"21\" y2=\"16\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <line x1=\"21\" y1=\"8\" x2=\"16\" y2=\"16\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polygon points=\"4,10 8,10 13,6 13,18 8,14 4,14\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinejoin=\"round\" />\n <path d=\"M16 10 Q18 12 16 14\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <path d=\"M18 8 Q22 12 18 16\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n\nfunction IconButton({\n iconType,\n config,\n imageOverride,\n onClick,\n}: {\n iconType: \"close\" | \"expand\" | \"minimize\" | \"mute\" | \"unmute\";\n config?: IconConfig;\n imageOverride?: string | null;\n onClick: () => void;\n}) {\n const iconSize = parseNumber(config?.size, 18);\n const buttonSize = Math.max(24, iconSize + 10);\n const margin = config?.margin || {};\n\n const imageUrl = imageOverride || config?.image;\n const iconColor = config?.color?.cross || \"#FFFFFF\";\n const fillColor = config?.color?.fill || \"rgba(0,0,0,0.55)\";\n const strokeColor = config?.color?.stroke || \"rgba(255,255,255,0.35)\";\n\n return (\n <button\n data-control-button=\"true\"\n type=\"button\"\n onPointerDown={(e) => { e.preventDefault(); e.stopPropagation(); }}\n onPointerUp={(e) => { e.preventDefault(); e.stopPropagation(); }}\n onMouseDown={(e) => { e.preventDefault(); e.stopPropagation(); }}\n onTouchStart={(e) => { e.preventDefault(); e.stopPropagation(); }}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onClick(); }}\n title={config?.selectedStyle || iconType}\n style={{\n width: buttonSize,\n height: buttonSize,\n borderRadius: 999,\n pointerEvents: 'auto',\n zIndex: 10030,\n position: 'relative',\n border: `1px solid ${strokeColor}`,\n background: fillColor,\n color: iconColor,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n padding: 0,\n marginTop: parseNumber(margin.top, 0),\n marginRight: parseNumber(margin.right, 0),\n marginBottom: parseNumber(margin.bottom, 0),\n marginLeft: parseNumber(margin.left, 0),\n }}\n >\n {imageUrl ? (\n <img\n src={imageUrl}\n alt={iconType}\n style={{ width: iconSize, height: iconSize, objectFit: \"contain\" }}\n />\n ) : (\n <PipIcon iconType={iconType} color={iconColor} />\n )}\n </button>\n );\n}\n\nconst Pip: React.FC = () => {\n const hookData = useCampaigns<PipCampaign>(\"PIP\");\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n const sdkVisible = useAppStorysStore((state) => state.isVisible);\n\n const [isClosed, setIsClosed] = useState(false);\n const [isExpanded, setIsExpanded] = useState(false);\n const [isMuted, setIsMuted] = useState(true);\n const [isDragging, setIsDragging] = useState(false);\n const [dragPosition, setDragPosition] = useState<{ x: number; y: number } | null>(null);\n\n const dragOffsetRef = useRef({ x: 0, y: 0 });\n const videoRef = useRef<HTMLVideoElement | null>(null);\n\n const data = useMemo(() => {\n if (hookData) return hookData;\n\n const screen = normalizeScreen(currentScreen);\n const findFromList = (source: Campaign[]) => source.find((campaign) => {\n const item = campaign as PipCampaign;\n const isPip = item.campaign_type === \"PIP\";\n const matchesScreen = !normalizeScreen(item.screen) || normalizeScreen(item.screen) === screen;\n const hasTrigger = Boolean((item as any).trigger_event ?? (item as any).trigger);\n const displayTriggerReady = item.display_trigger !== false && !hasTrigger;\n return isPip && matchesScreen && displayTriggerReady;\n }) as PipCampaign | undefined;\n\n const found = findFromList(campaigns) ?? findFromList(allCampaigns);\n return found ? (resolveCampaignVariant(found) as PipCampaign) : undefined;\n }, [hookData, campaigns, allCampaigns, currentScreen]);\n\n // When variants are enabled, `resolveCampaignVariant` can produce a new object each render.\n // Stabilize the reference so effects don't reset state on every render.\n const stableData = useMemo(\n () => data,\n [data?.id, (data as any)?.details?.id]\n );\n\n useEffect(() => {\n if (!stableData) return;\n\n const details = (stableData as any).details || {};\n\n const defaultSoundSetting =\n details?.styling?.soundToggle?.defaultSound ||\n details?.styling?.appearance?.defaultSound ||\n \"yes\";\n\n setIsMuted(String(defaultSoundSetting).toLowerCase() !== \"yes\");\n setIsClosed(false);\n setIsExpanded(false);\n setDragPosition(null);\n\n // Match native: send only event + campaign id (no extra metadata)\n void trackEvent(\"viewed\", stableData.id);\n }, [stableData]);\n\n // Emit an `analyze` analytics event when the PIP is expanded\n // NOTE: analytics for expand are emitted where the action happens\n // (see expand handler below) to match native timing/args.\n\n useEffect(() => {\n if (videoRef.current) {\n videoRef.current.muted = isMuted;\n }\n }, [isMuted]);\n\n useEffect(() => {\n if (!isDragging) return;\n\n const onMouseMove = (event: MouseEvent) => {\n const nextX = event.clientX - dragOffsetRef.current.x;\n const nextY = event.clientY - dragOffsetRef.current.y;\n setDragPosition({ x: Math.max(0, nextX), y: Math.max(0, nextY) });\n };\n\n const onMouseUp = () => {\n setIsDragging(false);\n };\n\n window.addEventListener(\"mousemove\", onMouseMove);\n window.addEventListener(\"mouseup\", onMouseUp);\n\n return () => {\n window.removeEventListener(\"mousemove\", onMouseMove);\n window.removeEventListener(\"mouseup\", onMouseUp);\n };\n }, [isDragging]);\n\n if (!stableData || !stableData.details || isClosed || !sdkVisible) return null;\n\n const details = stableData.details;\n const styling = details.styling || {};\n const appearance = styling.appearance || {};\n\n const configuredWidth = parseNumber(details.width ?? appearance.pipWidth, 150);\n const configuredHeight = parseNumber(details.height ?? appearance.pipHeight, 300);\n\n // Keep mini PIP landscape rectangular like the web reference.\n const miniWidth = Math.max(configuredWidth, configuredHeight);\n const miniHeight = Math.min(configuredWidth, configuredHeight);\n\n const ctaContainer = styling.cta?.container || {};\n const ctaText = styling.cta?.text || {};\n const hasCta = Boolean(details.button_text && details.button_text.trim().length > 0);\n\n const ctaHeight = parseNumber(styling.cta?.container?.height, 42);\n const expandedExtraHeight = hasCta ? ctaHeight + 24 : 0;\n\n const bottomPadding = parseNumber(styling.pipBottomPadding, 20);\n const topPadding = parseNumber(styling.pipTopPadding, 0);\n\n const videoSource = isExpanded ? details.large_video || details.small_video : details.small_video || details.large_video;\n\n const position = (details.position || stableData.position || \"right\").toLowerCase();\n const isMovable = Boolean(styling.isMovable);\n const soundEnabled = styling.soundToggle?.enabled !== false;\n const closeEnabled = styling.crossButton?.enabled !== false;\n const expandEnabled =\n styling.expandControls?.enabled !== false &&\n String(styling.expandablePip || \"yes\").toLowerCase() === \"yes\";\n\n const closeConfig = styling.crossButton;\n const expandConfig = isExpanded ? styling.expandControls?.minimise : styling.expandControls?.maximise;\n const soundConfig = isMuted ? styling.soundToggle?.mute : styling.soundToggle?.unmute;\n\n const wrapperStyle: React.CSSProperties = {\n position: \"fixed\",\n zIndex: 10020,\n width: isExpanded ? \"100vw\" : miniWidth,\n height: isExpanded ? \"100vh\" : miniHeight,\n borderRadius: 0,\n overflow: \"hidden\",\n background: \"#000\",\n boxShadow: \"0 16px 40px rgba(0,0,0,0.35)\",\n cursor: isDragging ? \"grabbing\" : isMovable && !isExpanded ? \"grab\" : \"default\",\n transition: isDragging ? \"none\" : \"width 180ms ease, height 180ms ease, transform 180ms ease\",\n };\n\n if (dragPosition && !isExpanded) {\n wrapperStyle.left = dragPosition.x;\n wrapperStyle.top = dragPosition.y;\n } else if (isExpanded) {\n wrapperStyle.left = 0;\n wrapperStyle.top = 0;\n wrapperStyle.right = 0;\n wrapperStyle.bottom = 0;\n } else {\n if (position === \"left\") {\n wrapperStyle.left = 24;\n } else {\n wrapperStyle.right = 24;\n }\n\n if (topPadding > 0) {\n wrapperStyle.top = topPadding;\n } else {\n wrapperStyle.bottom = bottomPadding + 20;\n }\n }\n\n const onWrapperMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n if (!isMovable || isExpanded) return;\n\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-control-button='true']\")) return;\n\n const rect = event.currentTarget.getBoundingClientRect();\n dragOffsetRef.current = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n\n setDragPosition({ x: rect.left, y: rect.top });\n setIsDragging(true);\n };\n\n const handleOpenLink = () => {\n if (!details.link) return;\n // Match native: only send event + campaign id\n void trackEvent(\"clicked\", stableData.id);\n const link = String(details.link).trim();\n\n try {\n const s = useAppStorysStore.getState();\n const all = s.allCampaigns || [];\n const existing = s.campaigns || [];\n const referenced = all.find((c: any) => c.id === link);\n console.log('[Pip] clicked link=', link, 'allCount=', all.length, 'visibleCount=', existing.length, 'referenced=', !!referenced);\n if (referenced) {\n const revealed: any = { ...referenced };\n delete revealed.trigger_event;\n delete revealed.trigger;\n revealed.display_trigger = true;\n\n const idx = existing.findIndex((c: any) => c.id === revealed.id);\n if (idx === -1) {\n s.saveCampaigns([revealed, ...existing]);\n } else {\n const existingItem = existing[idx];\n const existingHasTrigger = Boolean((existingItem as any).trigger_event ?? (existingItem as any).trigger);\n if (existingHasTrigger) {\n const next = [...existing];\n next[idx] = revealed;\n s.saveCampaigns(next);\n }\n }\n return;\n }\n } catch (err) {\n // fallback to open as URL\n }\n\n window.open(details.link, \"_blank\");\n };\n\n if (!videoSource) return null;\n\n return (\n <div style={wrapperStyle} onMouseDown={onWrapperMouseDown}>\n <video\n ref={videoRef}\n src={videoSource}\n autoPlay\n loop\n playsInline\n muted={isMuted}\n style={{ width: \"100%\", height: isExpanded && hasCta ? `calc(100% - ${expandedExtraHeight}px)` : \"100%\", objectFit: isExpanded ? \"contain\" : \"cover\" }}\n onClick={handleOpenLink}\n onEnded={() => {\n if (data) void trackEvent(\"analyze\", data.id);\n }}\n />\n\n <div\n style={{\n position: \"absolute\",\n top: 8,\n right: 8,\n display: \"flex\",\n gap: 8,\n zIndex: 2,\n }}\n >\n {soundEnabled && (\n <IconButton\n iconType={isMuted ? \"mute\" : \"unmute\"}\n config={soundConfig}\n imageOverride={isMuted ? details.muteImage : details.unmuteImage}\n onClick={() => setIsMuted((prev) => !prev)}\n />\n )}\n\n {expandEnabled && (\n <IconButton\n iconType={isExpanded ? \"minimize\" : \"expand\"}\n config={expandConfig}\n imageOverride={isExpanded ? details.minimiseImage : details.maximiseImage}\n onClick={() => {\n console.log('[Pip] expand button clicked - isExpanded before:', isExpanded);\n setIsExpanded((prev) => {\n const next = !prev;\n // Match native: when expanding, emit `viewed` then `analyze` with only campaign id\n if (next && stableData?.id) {\n void trackEvent('viewed', stableData.id);\n void trackEvent('analyze', stableData.id);\n }\n return next;\n });\n }}\n />\n )}\n\n {closeEnabled && (\n <IconButton\n iconType=\"close\"\n config={closeConfig}\n imageOverride={details.crossButtonImage}\n onClick={() => setIsClosed(true)}\n />\n )}\n </div>\n\n {isExpanded && hasCta && (\n <button\n data-control-button=\"true\"\n onClick={handleOpenLink}\n style={{\n position: \"absolute\",\n left: 12,\n right: 12,\n bottom: 12,\n height: ctaContainer.height || 42,\n width: ctaContainer.ctaFullWidth ? \"auto\" : ctaContainer.ctaWidth || \"auto\",\n margin: ctaContainer.ctaFullWidth ? \"0\" : \"0 auto\",\n background: ctaContainer.backgroundColor || \"#F7921C\",\n color: ctaText.color || \"#fff\",\n border: `${ctaContainer.borderWidth || 0}px solid ${ctaContainer.borderColor || \"transparent\"}`,\n borderRadius: 10,\n fontSize: ctaText.fontSize || 14,\n fontFamily: resolveFontFamily(ctaText.fontFamily),\n fontWeight: 600,\n cursor: details.link ? \"pointer\" : \"default\",\n }}\n >\n {details.button_text}\n </button>\n )}\n </div>\n );\n};\n\nexport { Pip };\nexport default Pip;\n","type LoadStatus = 'pending' | 'loaded' | 'failed';\n\ninterface FontEntry {\n status: LoadStatus;\n name: string;\n listeners: Array<(name: string | undefined) => void>;\n}\n\nfunction isRemoteFontUrl(value: string): boolean {\n const v = value.trim();\n return v.startsWith('http://') || v.startsWith('https://');\n}\n\nfunction fontNameFromUrl(url: string): string {\n try {\n const pathname = new URL(url).pathname;\n const filename = pathname.split('/').pop() || url;\n return filename.split('?')[0].replace(/\\.[^.]+$/, '') || `font_${filename.length}`;\n } catch {\n const filename = url.split('/').pop() ?? url;\n return filename.split('?')[0].replace(/\\.[^.]+$/, '') || `font_${url.length}`;\n }\n}\n\nfunction ensureStyleTag(fontName: string, url: string): void {\n if (typeof document === 'undefined') return;\n const id = `appstorys-font-${fontName}`;\n if (document.getElementById(id)) return;\n\n const style = document.createElement('style');\n style.id = id;\n style.type = 'text/css';\n style.textContent = `@font-face{font-family:\"${fontName}\";src:url(\"${url}\");font-style:normal;font-weight:normal;font-display:swap;}`;\n document.head.appendChild(style);\n}\n\nconst cache = new Map<string, FontEntry>();\n\nasync function doLoad(url: string, entry: FontEntry): Promise<void> {\n try {\n // Always inject @font-face so CSS can reference the family.\n ensureStyleTag(entry.name, url);\n\n // If FontFace API exists, await load so consumers can gate rendering.\n const FontFaceCtor = (globalThis as any).FontFace as\n | (new (family: string, source: string) => FontFace)\n | undefined;\n\n if (typeof document !== 'undefined' && FontFaceCtor && (document as any).fonts?.add) {\n const face = new FontFaceCtor(entry.name, `url(${url})`);\n await face.load();\n (document as any).fonts.add(face);\n } else if (typeof document !== 'undefined' && (document as any).fonts?.load) {\n await (document as any).fonts.load(`1em \"${entry.name}\"`);\n }\n\n entry.status = 'loaded';\n entry.listeners.forEach((cb) => cb(entry.name));\n } catch (err) {\n console.warn(`[FontManager] Failed to load font from \"${url}\":`, err);\n entry.status = 'failed';\n entry.listeners.forEach((cb) => cb(undefined));\n } finally {\n entry.listeners = [];\n }\n}\n\nexport const FontManager = {\n async load(url: string | undefined | null): Promise<string | undefined> {\n if (!url) return undefined;\n if (!isRemoteFontUrl(url)) return undefined;\n\n const existing = cache.get(url);\n if (existing) {\n if (existing.status === 'loaded') return existing.name;\n if (existing.status === 'failed') return undefined;\n return new Promise<string | undefined>((resolve) => existing.listeners.push(resolve));\n }\n\n const name = fontNameFromUrl(url);\n const entry: FontEntry = { status: 'pending', name, listeners: [] };\n cache.set(url, entry);\n\n const first = new Promise<string | undefined>((resolve) => entry.listeners.push(resolve));\n void doLoad(url, entry);\n return first;\n },\n\n ensure(url: string | undefined | null): string | undefined {\n if (!url) return undefined;\n if (!isRemoteFontUrl(url)) return undefined;\n\n const name = fontNameFromUrl(url);\n ensureStyleTag(name, url);\n void FontManager.load(url);\n return name;\n },\n\n getSync(url: string | undefined | null): string | undefined {\n if (!url) return undefined;\n const entry = cache.get(url);\n return entry?.status === 'loaded' ? entry.name : undefined;\n },\n\n _clearCache(): void {\n cache.clear();\n },\n};\n\nexport function resolveFontFamily(fontFamily?: string | null): string | undefined {\n if (!fontFamily) return undefined;\n if (isRemoteFontUrl(fontFamily)) return FontManager.ensure(fontFamily);\n return fontFamily;\n}\n\nexport function collectFontUrls(input: unknown): string[] {\n const urls = new Set<string>();\n const visited = new WeakSet<object>();\n\n const walk = (value: unknown) => {\n if (value == null) return;\n if (typeof value === 'string') return;\n\n if (Array.isArray(value)) {\n for (const item of value) walk(item);\n return;\n }\n\n if (typeof value === 'object') {\n if (visited.has(value as object)) return;\n visited.add(value as object);\n\n for (const [key, v] of Object.entries(value as Record<string, unknown>)) {\n if (key === 'fontFamily' && typeof v === 'string' && isRemoteFontUrl(v)) {\n urls.add(v);\n }\n walk(v);\n }\n }\n };\n\n walk(input);\n return Array.from(urls);\n}\n\nexport async function preloadFontsFromCampaigns(campaigns: unknown[]): Promise<void> {\n const urls = new Set<string>();\n for (const c of campaigns) collectFontUrls(c).forEach((u) => urls.add(u));\n await Promise.all(Array.from(urls).map((url) => FontManager.load(url)));\n}\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { LottiePlayer } from \"lottie-react\";\nimport useCampaigns from \"../../hooks/useCampaigns\";\nimport { hasVariants, resolveCampaignVariant } from \"../../core/variantResolver\";\nimport trackEvent from \"../../core/trackEvent\";\nimport useAppStorysStore from \"../../core/store\";\nimport { Campaign } from \"../../types\";\n\ninterface FloaterStyling {\n bottomLeftRadius?: number | string;\n bottomRightRadius?: number | string;\n topLeftRadius?: number | string;\n topRightRadius?: number | string;\n marginBottom?: number | string;\n marginLeft?: number | string;\n marginRight?: number | string;\n marginTop?: number | string;\n}\n\ninterface FloaterDetails {\n id?: string;\n image?: string;\n lottie_data?: string | Record<string, unknown>;\n link?: string;\n position?: string;\n width?: number | string;\n height?: number | string;\n styling?: FloaterStyling;\n}\n\ntype FloaterCampaign = Campaign & {\n campaign_type: \"FLT\";\n details: FloaterDetails;\n display_trigger?: boolean;\n};\n\nconst toNumber = (value: unknown, fallback = 0): number => {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst normalizeScreen = (value?: string | null): string => (value || \"\").trim().toLowerCase();\n\nconst MEDIA_BUCKET_HOST = \"appstorysmediabucketdev.s3.ap-south-1.amazonaws.com\";\n\nconst resolveLottieCandidateUrls = (url: string): string[] => {\n try {\n if (typeof window === \"undefined\") return [url];\n\n const parsed = new URL(url);\n if (parsed.hostname !== MEDIA_BUCKET_HOST) return [url];\n\n const isDevServer = Boolean(window.location.port);\n const proxyUrl = `/appstorys-media${parsed.pathname}${parsed.search}`;\n\n if (isDevServer) {\n // Prefer proxy in dev (works for localhost and LAN IP access), keep source URL as fallback.\n return [proxyUrl, url];\n }\n\n return [url];\n } catch {\n return [url];\n }\n};\n\nconst isLikelyLottieJson = (value: unknown): value is Record<string, unknown> => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const candidate = value as Record<string, unknown>;\n return Array.isArray(candidate.layers) || Array.isArray(candidate.assets) || typeof candidate.v === \"string\";\n};\n\nclass FloaterLottieErrorBoundary extends React.Component<\n { onError: () => void; children: React.ReactNode },\n { hasError: boolean }\n> {\n constructor(props: { onError: () => void; children: React.ReactNode }) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError() {\n return { hasError: true };\n }\n\n componentDidCatch() {\n this.props.onError();\n }\n\n render() {\n if (this.state.hasError) return null;\n return this.props.children;\n }\n}\n\nconst Floater: React.FC = () => {\n const [lottieData, setLottieData] = useState<any>(null);\n const [lottieUrls, setLottieUrls] = useState<string[]>([]);\n const [lottieFailed, setLottieFailed] = useState(false);\n const [lottieLoading, setLottieLoading] = useState(false);\n const lottieContainerRef = useRef<HTMLDivElement | null>(null);\n const lottieAnimationRef = useRef<any>(null);\n const hookData = useCampaigns<FloaterCampaign>(\"FLT\");\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n const sdkVisible = useAppStorysStore((state) => state.isVisible);\n const viewedKeyRef = useRef<string | null>(null);\n\n const data = hookData ??\n ((): FloaterCampaign | undefined => {\n const found = [...campaigns, ...allCampaigns].find((campaign) => {\n const item = campaign as FloaterCampaign;\n if (item.campaign_type !== \"FLT\") return false;\n // Hide campaigns that are explicitly display_trigger=false or that carry a trigger\n const hasTrigger = Boolean((item as any).trigger_event ?? (item as any).trigger);\n if (item.display_trigger === false || hasTrigger) return false;\n return !normalizeScreen(item.screen) || normalizeScreen(item.screen) === normalizeScreen(currentScreen);\n }) as FloaterCampaign | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as FloaterCampaign;\n } catch {\n return found;\n }\n })();\n\n const campaignId = data?.id;\n const mappedVariantId = useAppStorysStore((state) => (campaignId ? state.variantMappings[campaignId] : undefined));\n\n useEffect(() => {\n if (!data?.id) return;\n if (!sdkVisible) return;\n\n // If this campaign supports variants, wait until a variant mapping exists\n // so `trackEvent` can attach `variant_id` consistently.\n const needsVariant = hasVariants(data);\n if (needsVariant && !mappedVariantId) return;\n\n const viewKey = `${data.id}:${mappedVariantId || \"\"}`;\n if (viewedKeyRef.current === viewKey) return;\n viewedKeyRef.current = viewKey;\n\n void trackEvent(\"viewed\", data.id);\n }, [data?.id, mappedVariantId, sdkVisible]);\n\n useEffect(() => {\n const lottieSource = data?.details?.lottie_data;\n\n setLottieData(null);\n setLottieUrls([]);\n setLottieFailed(false);\n setLottieLoading(false);\n\n if (!lottieSource) return;\n\n if (isLikelyLottieJson(lottieSource)) {\n setLottieData(lottieSource);\n setLottieLoading(true);\n return;\n }\n\n if (typeof lottieSource !== \"string\") {\n setLottieFailed(true);\n return;\n }\n\n const candidateUrls = resolveLottieCandidateUrls(lottieSource);\n setLottieUrls(candidateUrls);\n setLottieLoading(true);\n }, [data?.details?.lottie_data]);\n\n useEffect(() => {\n if (!data?.details?.lottie_data || !lottieContainerRef.current) return;\n\n const lottie = LottiePlayer as any;\n if (!lottie || typeof lottie.loadAnimation !== \"function\") {\n setLottieFailed(true);\n setLottieLoading(false);\n return;\n }\n\n let cancelled = false;\n let activeAnimation: any = null;\n\n const cleanupCurrent = () => {\n if (activeAnimation && typeof activeAnimation.destroy === \"function\") {\n activeAnimation.destroy();\n }\n activeAnimation = null;\n lottieAnimationRef.current = null;\n };\n\n const tryLoadByPath = (paths: string[], index: number) => {\n if (cancelled) return;\n if (index >= paths.length) {\n setLottieFailed(true);\n setLottieLoading(false);\n console.error(\"[Floater] lottie load failed\", { lottieUrls: paths });\n return;\n }\n\n cleanupCurrent();\n\n const animation = lottie.loadAnimation({\n container: lottieContainerRef.current,\n renderer: \"svg\",\n loop: true,\n autoplay: true,\n path: paths[index],\n });\n\n activeAnimation = animation;\n lottieAnimationRef.current = animation;\n\n animation.addEventListener(\"DOMLoaded\", () => {\n if (cancelled) return;\n setLottieLoading(false);\n });\n\n animation.addEventListener(\"data_failed\", () => {\n if (cancelled) return;\n tryLoadByPath(paths, index + 1);\n });\n };\n\n if (lottieData) {\n cleanupCurrent();\n const animation = lottie.loadAnimation({\n container: lottieContainerRef.current,\n renderer: \"svg\",\n loop: true,\n autoplay: true,\n animationData: lottieData,\n });\n activeAnimation = animation;\n lottieAnimationRef.current = animation;\n animation.addEventListener(\"DOMLoaded\", () => {\n if (!cancelled) {\n setLottieLoading(false);\n }\n });\n animation.addEventListener(\"data_failed\", () => {\n if (!cancelled) {\n setLottieFailed(true);\n setLottieLoading(false);\n }\n });\n } else if (lottieUrls.length > 0) {\n tryLoadByPath(lottieUrls, 0);\n }\n\n return () => {\n cancelled = true;\n cleanupCurrent();\n };\n }, [data?.details?.lottie_data, lottieData, lottieUrls]);\n\n if (!data || !data.details || !sdkVisible) return null;\n const { details } = data;\n const styling = details.styling || {};\n\n const resolvedPosition =\n typeof details.position === \"string\"\n ? details.position\n : typeof data.position === \"string\"\n ? data.position\n : \"right\";\n const position = resolvedPosition.toLowerCase() === \"left\" ? \"left\" : \"right\";\n\n const positionStyle: React.CSSProperties = {\n position: \"fixed\",\n left: position === \"left\" ? toNumber(styling.marginLeft, 12) : undefined,\n right: position === \"left\" ? undefined : toNumber(styling.marginRight, 12),\n top: toNumber(styling.marginTop, 0) > 0 ? toNumber(styling.marginTop, 0) : undefined,\n bottom: toNumber(styling.marginTop, 0) > 0 ? undefined : toNumber(styling.marginBottom, 80),\n zIndex: 10040,\n display: \"flex\",\n };\n\n const floaterStyle: React.CSSProperties = {\n width: toNumber(details.width, 60),\n height: toNumber(details.height, 60),\n background: \"transparent\",\n overflow: \"hidden\",\n borderBottomLeftRadius: toNumber(styling.bottomLeftRadius, 0),\n borderBottomRightRadius: toNumber(styling.bottomRightRadius, 0),\n borderTopLeftRadius: toNumber(styling.topLeftRadius, 0),\n borderTopRightRadius: toNumber(styling.topRightRadius, 0),\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: details.link ? \"pointer\" : \"default\",\n boxShadow: \"0 8px 18px rgba(0,0,0,0.2)\",\n };\n\n const handleClick = async () => {\n if (!details.link) return;\n\n await trackEvent(\"clicked\", data.id);\n const link = String(details.link).trim();\n\n try {\n const s = useAppStorysStore.getState();\n const all = s.allCampaigns || [];\n const existing = s.campaigns || [];\n\n // Robust matching: try several candidate matchers\n const referenced = all.find((c: any) => {\n if (!c) return false;\n const cid = String(c.id || \"\").trim();\n const details = c.details || {};\n const detailsCampaign = String(details.campaign || details.id || \"\").trim();\n if (cid && cid === link) return true;\n if (detailsCampaign && detailsCampaign === link) return true;\n // allow if the link contains the id or vice-versa\n if (cid && link.includes(cid)) return true;\n if (detailsCampaign && link.includes(detailsCampaign)) return true;\n return false;\n });\n\n console.log(\"[Floater] clicked link=\", link, \"allCampaignsCount=\", all.length, \"visibleCount=\", existing.length);\n console.log(\"[Floater] all ids=\", all.map((c: any) => c.id).slice(0,50));\n console.log(\"[Floater] referenced found=\", !!referenced, referenced && (referenced.id || referenced.details?.campaign || referenced.details?.id));\n\n if (referenced) {\n const revealed: any = { ...referenced };\n // Neglect trigger for this reveal flow\n delete revealed.trigger_event;\n delete revealed.trigger;\n revealed.display_trigger = true;\n const idx = existing.findIndex((c: any) => c.id === revealed.id);\n if (idx === -1) {\n console.log('[Floater] revealing campaign (prepended)', revealed.id);\n s.saveCampaigns([revealed, ...existing]);\n } else {\n const existingItem = existing[idx];\n const existingHasTrigger = Boolean((existingItem as any).trigger_event ?? (existingItem as any).trigger);\n if (existingHasTrigger) {\n // Replace the existing triggered entry with revealed copy (neglect trigger)\n const next = [...existing];\n next[idx] = revealed;\n console.log('[Floater] replacing existing triggered campaign with revealed one', revealed.id);\n s.saveCampaigns(next);\n } else {\n console.log('[Floater] campaign already visible and not trigger-driven', revealed.id);\n }\n }\n return;\n }\n } catch (err) {\n // fallback to open as URL\n console.warn('[Floater] error while resolving referenced campaign', err);\n }\n\n try {\n window.open(details.link, \"_blank\");\n } catch (err) {\n // ignore\n }\n };\n\n const canRenderLottie = Boolean(details.lottie_data && !lottieFailed);\n const canRenderImage = Boolean(details.image);\n const canRenderLoadingPlaceholder = Boolean(details.lottie_data && lottieLoading && !lottieData && !lottieFailed);\n\n if (!canRenderLottie && !canRenderImage && !canRenderLoadingPlaceholder) return null;\n\n return (\n <div style={positionStyle}>\n <div style={floaterStyle} onClick={() => void handleClick()}>\n {canRenderLottie ? (\n <FloaterLottieErrorBoundary key={String(details.lottie_data)} onError={() => setLottieFailed(true)}>\n <div ref={lottieContainerRef} style={{ width: \"100%\", height: \"100%\", display: \"block\" }} />\n </FloaterLottieErrorBoundary>\n ) : canRenderLoadingPlaceholder ? (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(0,0,0,0.08)\",\n color: \"#333\",\n fontSize: 10,\n fontWeight: 600,\n }}\n >\n ...\n </div>\n ) : (\n <img\n src={details.image}\n alt=\"floater\"\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default Floater;\n","import useAppStorysStore, { getAccessToken, getUserId } from \"./store\";\nimport { Campaign } from \"../types\";\n\nfunction normalizeScreenName(screen?: string | null): string {\n return (screen || \"\").trim().toLowerCase();\n}\n\nfunction isScreenMatch(campaign: Campaign, screenName: string): boolean {\n const campaignScreen = normalizeScreenName(campaign.screen);\n const currentScreen = normalizeScreenName(screenName);\n return !campaignScreen || campaignScreen === currentScreen;\n}\n\nexport default async function trackScreen(screenName: string) {\n try {\n const state = useAppStorysStore.getState();\n const accessToken = await getAccessToken();\n const accountId = state.accountId;\n\n if (!accessToken || !accountId) return;\n\n state.setCurrentScreen(screenName);\n state.setTrackedEvents([]); // Reset tracked events for new screen\n\n const baseUrl = state.baseUrl || 'https://users.appstorys.co';\n\n const response = await fetch(`${baseUrl}/v2/${accountId}/track-user-res`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`\n },\n body: JSON.stringify({\n user_id: getUserId(),\n screenName\n }),\n });\n\n if (!response.ok) return;\n\n const data = await response.json();\n\n // Update screen-capture flag from response\n if (typeof data.screen_capture_enabled !== 'undefined') {\n state.setScreenCaptureEnabled(Boolean(data.screen_capture_enabled));\n }\n\n // Handle variants\n if (data.variants && data.variants.length > 0) {\n const variantMappings: Record<string, string> = {};\n data.variants.forEach((variant: any) => {\n variantMappings[variant.id] = variant.v_id;\n });\n state.setVariantMappings(variantMappings);\n }\n\n // Handle personalization\n if (data.personalization_data) {\n state.setPersonalizationData(data.personalization_data);\n }\n\n // Filter campaigns\n const allCampaigns = state.allCampaigns || [];\n const eligibleCampaignIds = data.eligibleCampaignList || [];\n\n const foundCampaigns = allCampaigns.filter(campaign =>\n eligibleCampaignIds.includes(campaign.id!) &&\n isScreenMatch(campaign, screenName)\n );\n\n // Fetch missing campaigns if necessary\n const foundCampaignIds = foundCampaigns.map(c => c.id!);\n const missingCampaignIds = eligibleCampaignIds.filter((id: string) => !foundCampaignIds.includes(id));\n\n let missingCampaigns: Campaign[] = [];\n if (missingCampaignIds.length > 0) {\n const fallbackResponse = await fetch(`${baseUrl}/load-campaign-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`\n },\n body: JSON.stringify(missingCampaignIds),\n });\n\n if (fallbackResponse.ok) {\n const fallbackData = await fallbackResponse.json();\n missingCampaigns = fallbackData.filter((campaign: Campaign) =>\n isScreenMatch(campaign, screenName)\n );\n }\n }\n\n const eligibleCampaigns = [...foundCampaigns, ...missingCampaigns];\n\n // Keep display-trigger campaigns available even when eligibility API is partial.\n const displayTriggeredCampaigns = allCampaigns.filter((campaign: Campaign & { display_trigger?: boolean }) => {\n const hasTrigger = Boolean((campaign as any).trigger_event ?? (campaign as any).trigger);\n return isScreenMatch(campaign, screenName) && campaign.display_trigger === true && !hasTrigger;\n });\n\n const mergedCampaigns = [...eligibleCampaigns];\n const seenCampaignIds = new Set(mergedCampaigns.map((campaign) => campaign.id));\n\n for (const campaign of displayTriggeredCampaigns) {\n if (!seenCampaignIds.has(campaign.id)) {\n mergedCampaigns.push(campaign);\n seenCampaignIds.add(campaign.id);\n }\n }\n\n state.saveCampaigns(mergedCampaigns);\n } catch (error) {\n console.error('Error when tracking screen:', screenName, error);\n }\n}\n","import useAppStorysStore, { getAccessToken, getUserId } from \"./store\";\nimport { Attributes } from \"../types\";\nimport getDeviceInfo from \"./getDeviceInfo\";\nimport { sendOrQueue } from \"./offlineQueue\";\n\n/**\n * Sets custom attributes for the user.\n * These properties can be used for campaign targeting and segmentation.\n * \n * @param attributes - A key-value object of user properties.\n */\nexport default async function setUserProperties(attributes: Attributes) {\n try {\n const accessToken = await getAccessToken();\n const userId = getUserId();\n const state = useAppStorysStore.getState();\n\n if (!accessToken || !userId) {\n console.warn(\"AppStorys: Missing accessToken or userId. Ensure SDK is initialized before setting user properties.\");\n return;\n }\n\n let finalMetadata: Record<string, any> = {\n ...(attributes || {}),\n };\n\n const deviceInfo = await getDeviceInfo();\n finalMetadata = {\n ...finalMetadata,\n ...deviceInfo,\n };\n\n const bodyData: any = {\n user_id: userId,\n attributes: finalMetadata\n };\n\n const baseUrl = state.baseUrl || 'https://users.appstorys.co';\n\n await sendOrQueue({\n url: `${baseUrl}/update-user-atr`,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: bodyData,\n });\n\n } catch (error) {\n console.error(\"AppStorys: Error in setUserProperties:\", error);\n }\n}\n","import useAppStorysStore from '../core/store';\n\nexport function personalizeText(text: string): string {\n if (!text || text.trim() === '') {\n return text;\n }\n\n const personalizationData = useAppStorysStore.getState().personalizationData;\n\n if (!personalizationData || Object.keys(personalizationData).length === 0) {\n return replacePlaceholdersWithFallback(text);\n }\n\n const regex = /\\{\\{([^|}\\s]+)\\s*\\|\\s*([^}]+)\\}\\}/g;\n\n return text.replace(regex, (_, variableName, fallbackValue) => {\n const trimmedVariable = variableName.trim();\n const trimmedFallback = fallbackValue.trim();\n\n return personalizationData[trimmedVariable] ?? trimmedFallback;\n });\n}\n\nfunction replacePlaceholdersWithFallback(text: string): string {\n const regex = /\\{\\{[^|}\\s]+\\s*\\|\\s*([^}]+)\\}\\}/g;\n\n return text.replace(regex, (_, fallbackValue) => {\n return fallbackValue.trim();\n });\n}\n","import { WebStorage } from '../adapters/web/storage';\nimport { Campaign } from '../types';\nimport { getAccessToken, getUserId } from './store';\nimport useAppStorysStore from './store';\n\nconst STORAGE_KEY_CAMPAIGNS = \"appstorys_campaigns_cache\";\nconst STORAGE_KEY_ETAG = \"appstorys_campaigns_etag\";\nconst STORAGE_KEY_VERSION = \"appstorys_campaigns_version\";\n\nexport interface FetchCampaignsResult {\n campaigns: Campaign[];\n version: number;\n}\n\nexport default async function fetchAllCampaigns(accountId: string, screenName?: string): Promise<FetchCampaignsResult> {\n try {\n const isLocalDev =\n typeof window !== \"undefined\" &&\n (window.location.hostname === \"localhost\" || window.location.hostname === \"127.0.0.1\");\n\n const url = isLocalDev\n ? `/appstorys-campaigns/clients/${accountId}/campaigns.json`\n : `https://dev-cdn-campaign-appstorys.s3.ap-south-1.amazonaws.com/clients/${accountId}/campaigns.json`;\n\n const cachedData = await WebStorage.getItem(STORAGE_KEY_CAMPAIGNS);\n const cachedEtag = await WebStorage.getItem(STORAGE_KEY_ETAG);\n const cachedVersion = await WebStorage.getItem(STORAGE_KEY_VERSION);\n\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n };\n\n // Keep ETag revalidation for non-local environments only.\n if (!isLocalDev && cachedEtag) {\n headers[\"If-None-Match\"] = cachedEtag;\n }\n\n const response = await fetch(url, {\n method: \"GET\",\n headers,\n ...(isLocalDev ? { cache: \"no-store\" as RequestCache } : {}),\n });\n\n if (response.status === 304) {\n return {\n campaigns: cachedData ? JSON.parse(cachedData) : [],\n version: cachedVersion ? parseInt(cachedVersion) : 1,\n };\n }\n\n const newEtag = response.headers.get(\"ETag\");\n const responseData: any[] = await response.json();\n\n let version = 2;\n let campaigns: Campaign[] = responseData;\n\n // Determine an effective screen name. If caller didn't provide one, try\n // to fetch it from the users service `v2/{accountId}/track-user-res`.\n let effectiveScreenName = screenName;\n if (!effectiveScreenName) {\n try {\n const accessToken = await getAccessToken();\n const userId = getUserId();\n const usersBase = isLocalDev ? '/appstorys-users' : 'https://users.appstorys.co';\n\n const trackResp = await fetch(`${usersBase}/v2/${accountId}/track-user-res`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}),\n },\n body: JSON.stringify({\n user_id: userId,\n screenName: (typeof window !== 'undefined' && window.location && window.location.pathname) ? window.location.pathname : '',\n silentUpdate: true,\n }),\n });\n\n if (trackResp.ok) {\n const trackData = await trackResp.json();\n console.info('AppStorys: fetchAllCampaigns track-user-res returned', trackData);\n const possibleScreen = trackData?.screenName || trackData?.screen || trackData?.currentScreen || trackData?.screen_name || trackData?.current_screen;\n if (possibleScreen) {\n effectiveScreenName = possibleScreen;\n }\n try {\n const s = useAppStorysStore.getState();\n if (typeof trackData.screen_capture_enabled !== 'undefined') {\n s.setScreenCaptureEnabled(Boolean(trackData.screen_capture_enabled));\n }\n } catch (err) {\n // ignore\n }\n }\n } catch (err) {\n console.warn('Could not fetch screen name from track-user-res:', err);\n }\n }\n\n if (responseData.length > 0 && responseData[0].version !== undefined) {\n version = responseData[0].version;\n campaigns = responseData.slice(1);\n }\n\n // If no campaigns found in the primary source, try fallback using track-user and load-campaign-data\n if ((!campaigns || campaigns.length === 0)) {\n try {\n const accessToken = await getAccessToken();\n const userId = getUserId();\n const usersBase = isLocalDev ? '/appstorys-users' : 'https://users.appstorys.co';\n\n const trackResp = await fetch(`${usersBase}/v2/${accountId}/track-user-res`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}),\n },\n body: JSON.stringify({\n user_id: userId,\n screenName: (typeof window !== 'undefined' && window.location && window.location.pathname) ? window.location.pathname : '',\n silentUpdate: true,\n }),\n });\n\n if (trackResp.ok) {\n const trackData = await trackResp.json();\n const userIdFromResp = trackData?.user_id || trackData?.id || trackData?.userId || userId;\n\n try {\n const s = useAppStorysStore.getState();\n if (typeof trackData.screen_capture_enabled !== 'undefined') {\n s.setScreenCaptureEnabled(Boolean(trackData.screen_capture_enabled));\n }\n } catch (err) {\n // ignore\n }\n\n if (userIdFromResp) {\n const loadUrl = isLocalDev\n ? `/appstorys-users/load-campaign-data`\n : `https://users.appstorys.com/load-campaign-data`;\n\n const fallbackResponse = await fetch(loadUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}),\n },\n body: JSON.stringify({ user_id: userIdFromResp }),\n });\n\n if (fallbackResponse.ok) {\n const fallbackData: any[] = await fallbackResponse.json();\n console.log(`Fetched ${fallbackData.length} missing campaigns from fallback`);\n console.log('Fallback campaigns:', JSON.stringify(fallbackData, null, 2));\n\n // Use fallback campaigns if available\n if (fallbackData && fallbackData.length > 0) {\n campaigns = fallbackData as Campaign[];\n }\n } else {\n console.error('Failed to fetch missing campaigns:', await fallbackResponse.text());\n }\n }\n }\n } catch (error) {\n console.error('Error fetching missing campaigns via fallback:', error);\n }\n }\n\n // Filter campaigns by effective screenName if available\n if (effectiveScreenName && campaigns && campaigns.length > 0) {\n const normalize = (s?: string | null) => (s || '').trim().toLowerCase();\n const current = normalize(effectiveScreenName);\n campaigns = campaigns.filter(campaign => !normalize(campaign.screen) || normalize(campaign.screen) === current);\n }\n\n await WebStorage.setItem(STORAGE_KEY_CAMPAIGNS, JSON.stringify(campaigns));\n await WebStorage.setItem(STORAGE_KEY_VERSION, version.toString());\n\n if (newEtag) {\n await WebStorage.setItem(STORAGE_KEY_ETAG, newEtag);\n }\n\n return { campaigns, version };\n\n } catch (error) {\n console.error(\"Error fetching campaigns:\", error);\n const cachedData = await WebStorage.getItem(STORAGE_KEY_CAMPAIGNS);\n const cachedVersion = await WebStorage.getItem(STORAGE_KEY_VERSION);\n\n return {\n campaigns: cachedData ? JSON.parse(cachedData) : [],\n version: cachedVersion ? parseInt(cachedVersion) : 1,\n };\n }\n}\n","import useAppStorysStore, { getAccessToken } from \"./store\";\n\ninterface ReconcileUserRequest {\n anonymous_user_id: string;\n identified_user_id: string;\n}\n\n/**\n * Reconciles an anonymous user with an identified user.\n * This merges the anonymous user's data with the identified user's data.\n * \n * @param anonymousUserId - The previous anonymous user ID\n * @param identifiedUserId - The new identified user ID\n * @returns Promise<boolean> - true if reconciliation was successful, false otherwise\n */\nexport default async function reconcileAnonymousUser(\n anonymousUserId: string,\n identifiedUserId: string\n): Promise<boolean> {\n try {\n const accessToken = await getAccessToken();\n const state = useAppStorysStore.getState();\n \n if (!accessToken) {\n console.error('AppStorys: Access token not found for reconciliation');\n return false;\n }\n\n const requestBody: ReconcileUserRequest = {\n anonymous_user_id: anonymousUserId,\n identified_user_id: identifiedUserId,\n };\n\n const baseUrl = state.baseUrl || 'https://users.appstorys.co';\n\n const response = await fetch(`${baseUrl}/reconcile-anonymous-user`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n },\n body: JSON.stringify(requestBody),\n });\n\n if (response.ok) {\n return true;\n } else {\n const errorText = await response.text();\n console.error('AppStorys: Failed to reconcile anonymous user:', response.status, errorText);\n return false;\n }\n } catch (error) {\n console.error('AppStorys: Error in reconcileAnonymousUser:', error);\n return false;\n }\n}\n","import useAppStorysStore from \"./store\";\nimport { isBackPressCampaignReady, BACK_PRESS_SENTINEL } from \"../hooks/useCampaigns\";\n\n/**\n * Manages 'Exit Intent' or 'Back Press' behavior for the Web SDK.\n * This translates the mobile back button behavior to web-friendly triggers:\n * 1. Mouse leaving the viewport towards the top (classic exit intent).\n * 2. Intercepting the browser's back button via the PopState API.\n */\nclass ExitIntentManager {\n private isInitialized = false;\n\n public setup() {\n if (this.isInitialized || typeof window === 'undefined') return;\n\n // 1. Mouse Move / Exit Intent\n document.addEventListener('mouseleave', this.handleMouseLeave);\n\n // 2. Browser Back Button (PopState)\n window.addEventListener('popstate', this.handlePopState);\n \n // We should push an initial state so we can intercept the first back press\n if (window.history.state !== 'appstorys_navigation') {\n window.history.pushState('appstorys_navigation', '');\n }\n\n this.isInitialized = true;\n }\n\n public destroy() {\n if (!this.isInitialized || typeof window === 'undefined') return;\n document.removeEventListener('mouseleave', this.handleMouseLeave);\n window.removeEventListener('popstate', this.handlePopState);\n this.isInitialized = false;\n }\n\n private handleMouseLeave = (e: MouseEvent) => {\n // Only trigger if mouse leaves the TOP of the window\n if (e.clientY <= 0 && isBackPressCampaignReady()) {\n this.triggerCampaign();\n }\n };\n\n private handlePopState = () => {\n if (isBackPressCampaignReady()) {\n // Prevent default navigation\n window.history.pushState('appstorys_navigation', '');\n this.triggerCampaign();\n }\n };\n\n private triggerCampaign() {\n const state = useAppStorysStore.getState();\n const { trackedEvents } = state;\n\n if (!trackedEvents.includes(BACK_PRESS_SENTINEL)) {\n console.log('AppStorys: Exit Intent triggered. Displaying campaign.');\n state.setTrackedEvents([...trackedEvents, BACK_PRESS_SENTINEL]);\n }\n }\n}\n\nexport const exitIntentManager = new ExitIntentManager();\n","import useAppStorysStore from \"./store\";\n\n/**\n * Manages the visibility state of the SDK.\n * It listens to the browser's Page Visibility API and updates the global store.\n * This is crucial for pausing/resuming resource-heavy operations like video playback (PiP).\n */\nclass VisibilityManager {\n private isInitialized = false;\n\n public setup() {\n if (this.isInitialized || typeof document === 'undefined') return;\n\n document.addEventListener('visibilitychange', this.handleVisibilityChange);\n \n // Set initial state\n this.updateVisibility(document.visibilityState === 'visible');\n \n this.isInitialized = true;\n }\n\n public destroy() {\n if (!this.isInitialized || typeof document === 'undefined') return;\n document.removeEventListener('visibilitychange', this.handleVisibilityChange);\n this.isInitialized = false;\n }\n\n private handleVisibilityChange = () => {\n this.updateVisibility(document.visibilityState === 'visible');\n };\n\n /**\n * Updates the global SDK visibility state.\n * Can be called by the visibilitychange listener or manually via the public API.\n */\n public updateVisibility(isVisible: boolean) {\n const state = useAppStorysStore.getState();\n if (state.isVisible !== isVisible) {\n console.log(`AppStorys: SDK visibility changed to ${isVisible ? 'visible' : 'hidden'}`);\n state.setVisibility(isVisible);\n }\n }\n}\n\nexport const visibilityManager = new VisibilityManager();\n","import { WebStorage } from '../adapters/web/storage';\n\nconst ANONYMOUS_USER_KEY = 'anonymous_user_id';\n\nexport async function generateAnonymousUserId(): Promise<string> {\n const currentTimeMs = Date.now();\n const browserName = navigator.userAgent.split(' ')[0].replace(/[^a-zA-Z0-9]/g, '_');\n return `${currentTimeMs}_${browserName}`;\n}\n\nexport async function getOrCreateAnonymousUserId(): Promise<string> {\n try {\n const storedUserId = await WebStorage.getItem(ANONYMOUS_USER_KEY);\n \n if (storedUserId) {\n return storedUserId;\n }\n \n const newUserId = await generateAnonymousUserId();\n await WebStorage.setItem(ANONYMOUS_USER_KEY, newUserId);\n return newUserId;\n } catch (error) {\n console.error('Error managing anonymous user ID:', error);\n return await generateAnonymousUserId();\n }\n}\n\nexport async function clearAnonymousUserId(): Promise<void> {\n try {\n await WebStorage.removeItem(ANONYMOUS_USER_KEY);\n } catch (error) {\n console.error('Error clearing anonymous user ID:', error);\n }\n}\n\nexport async function getStoredAnonymousUserId(): Promise<string | null> {\n try {\n return await WebStorage.getItem(ANONYMOUS_USER_KEY);\n } catch (error) {\n console.error('Error getting stored anonymous user ID:', error);\n return null;\n }\n}\n","// Dev helper: visually mark host elements that can receive widgets\ndeclare global {\n interface Window {\n AppStorysShowWidgetElements?: () => void;\n }\n}\n\nfunction injectStyles() {\n if (document.getElementById('appstorys-widget-debug-styles')) return;\n const style = document.createElement('style');\n style.id = 'appstorys-widget-debug-styles';\n style.innerHTML = `\n .appstorys-widget-debug-pill {\n position: absolute;\n top: 8px;\n left: 8px;\n background: #ff7a18;\n color: white;\n padding: 6px 10px;\n border-radius: 14px;\n font-weight: 700;\n font-size: 12px;\n z-index: 2147483647;\n box-shadow: 0 6px 18px rgba(0,0,0,0.12);\n pointer-events: none;\n }\n .appstorys-widget-debug-overlay {\n outline: 3px dashed rgba(255,122,24,0.85);\n outline-offset: 6px;\n }\n `;\n document.head.appendChild(style);\n}\n\nfunction makePill(text: string) {\n const pill = document.createElement('div');\n pill.className = 'appstorys-widget-debug-pill';\n pill.textContent = text;\n return pill;\n}\n\nfunction ensureRelative(el: Element) {\n const node = el as HTMLElement;\n const computed = getComputedStyle(node);\n if (computed.position === 'static' || !computed.position) {\n node.style.position = 'relative';\n }\n}\n\nwindow.AppStorysShowWidgetElements = function showWidgetElements() {\n try {\n injectStyles();\n const matches = Array.from(document.querySelectorAll('[data-as-id], [data-widget], [data-widget-id]'));\n if (!matches.length) {\n // fallback: try obvious ids/classes used in examples\n const fallbacks = ['#hero_section', '.hero_section', '#header_container', '.header_container'];\n fallbacks.forEach(sel => {\n const el = document.querySelector(sel);\n if (el) matches.push(el);\n });\n }\n\n if (!matches.length) {\n // last resort: mark body top-left\n const pill = makePill('Widget');\n pill.style.position = 'fixed';\n pill.style.top = '12px';\n pill.style.left = '12px';\n pill.style.pointerEvents = 'auto';\n document.body.appendChild(pill);\n return;\n }\n\n matches.forEach((el, idx) => {\n const target = el as HTMLElement;\n ensureRelative(target);\n target.classList.add('appstorys-widget-debug-overlay');\n // remove existing pill if present\n const existing = target.querySelector('.appstorys-widget-debug-pill');\n if (existing) existing.remove();\n const pill = makePill('Widget ' + (idx + 1));\n target.appendChild(pill);\n });\n } catch (err) {\n // swallow errors in dev helper\n // eslint-disable-next-line no-console\n console.error('AppStorysShowWidgetElements error', err);\n }\n};\n\nexport {};\n","import React, { useState, useEffect } from 'react';\nimport { CampaignStory } from '../../types';\nimport useAppStorysStore from '../../core/store';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport trackEvent from '../../core/trackEvent';\nimport { StoryList } from './StoryList';\nimport { StoryOverlay } from './StoryOverlay';\n\nexport const Story: React.FC = () => {\n const data = useCampaigns<CampaignStory>('STR');\n const sdkVisible = useAppStorysStore((state) => state.isVisible);\n const [activeStoryIndex, setActiveStoryIndex] = useState<number | null>(null);\n const [viewedStories, setViewedStories] = useState<string[]>([]);\n\n useEffect(() => {\n try {\n const saved = localStorage.getItem('app_storys_viewed_stories');\n if (saved) {\n setViewedStories(JSON.parse(saved));\n }\n } catch (e) {\n console.error('Failed to load viewed stories:', e);\n }\n }, []);\n\n useEffect(() => {\n if (data && data.details) {\n void trackEvent('story_module_viewed', data.id);\n }\n }, [data]);\n\n if (!data || !data.details || data.details.length === 0 || !sdkVisible) return null;\n\n const handleStoryClick = (index: number) => {\n setActiveStoryIndex(index);\n const story = data.details[index];\n void trackEvent('story_opened', data.id, { story_id: story.id, story_name: story.name });\n };\n\n const handleNextStory = () => {\n if (activeStoryIndex === null) return;\n if (activeStoryIndex < data.details.length - 1) {\n setActiveStoryIndex(activeStoryIndex + 1);\n } else {\n setActiveStoryIndex(null);\n }\n };\n\n const handlePrevStory = () => {\n if (activeStoryIndex === null) return;\n if (activeStoryIndex > 0) {\n setActiveStoryIndex(activeStoryIndex - 1);\n }\n };\n\n return (\n <div className=\"story-group-container\" style={{\n width: '100vw',\n position: 'relative',\n left: '50%',\n right: '50%',\n marginLeft: '-50vw',\n marginRight: '-50vw',\n boxSizing: 'border-box'\n }}>\n <StoryList \n stories={data.details} \n viewedStories={viewedStories} \n onStoryClick={handleStoryClick} \n />\n {activeStoryIndex !== null && (\n <StoryOverlay \n stories={data.details}\n activeStoryIndex={activeStoryIndex}\n dataId={data.id}\n viewedStories={viewedStories}\n setViewedStories={setViewedStories}\n onNextStory={handleNextStory}\n onPrevStory={handlePrevStory}\n onClose={() => setActiveStoryIndex(null)}\n />\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport * as LottieModule from 'lottie-react';\n\nconst Lottie =\n (LottieModule as any).default?.default ??\n (LottieModule as any).default ??\n (LottieModule as any).Lottie ??\n (LottieModule as any);\n\ninterface StoryThumbnailProps {\n src: string;\n alt?: string;\n style?: React.CSSProperties;\n size?: number;\n}\n\nexport const StoryThumbnail: React.FC<StoryThumbnailProps> = ({ src, alt, style, size }) => {\n const [lottieData, setLottieData] = useState<any>(null);\n const [lottieFailed, setLottieFailed] = useState(false);\n\n useEffect(() => {\n if (src && src.toLowerCase().endsWith('.json')) {\n fetch(src)\n .then(res => {\n if (!res.ok) throw new Error('Failed to fetch Lottie');\n return res.json();\n })\n .then(json => {\n setLottieData(json);\n setLottieFailed(false);\n })\n .catch(err => {\n console.error('AppStorys: Error loading Lottie thumbnail:', err);\n setLottieFailed(true);\n });\n } else {\n setLottieData(null);\n setLottieFailed(false);\n }\n }, [src]);\n\n const baseStyle: React.CSSProperties = {\n width: size ? `${size}px` : (style?.width || '100%'),\n height: size ? `${size}px` : (style?.height || '100%'),\n objectFit: 'cover',\n display: 'block',\n ...style\n };\n\n if (lottieData && !lottieFailed) {\n const LottieComp = (Lottie as any).default || Lottie;\n return (\n <LottieComp \n animationData={lottieData} \n loop={true} \n autoplay={true}\n style={baseStyle}\n />\n );\n }\n\n return (\n <img\n src={src}\n alt={alt || 'story thumbnail'}\n style={baseStyle}\n onError={() => setLottieFailed(true)}\n />\n );\n};\n","import React from 'react';\nimport { Story as StoryType } from '../../types';\nimport { StoryThumbnail } from './StoryThumbnail';\nimport { resolveFontFamily } from '../../core/fontManager';\n\ninterface StoryGroupItemProps {\n story: StoryType;\n isViewed: boolean;\n onClick: () => void;\n}\n\nexport const StoryGroupItem: React.FC<StoryGroupItemProps> = ({ story, isViewed, onClick }) => {\n const styling = story.styling || {};\n const size = styling.size || 80;\n const ringWidth = styling.ringWidth || 3;\n const ringColor = isViewed ? '#E5E7EB' : (story.ringColor || '#FF0000');\n const nameColor = story.nameColor || '#333333';\n \n const cornerRadius = styling.cornerRadius;\n const borderRadiusStr = cornerRadius \n ? `${cornerRadius.topLeft || 0}px ${cornerRadius.topRight || 0}px ${cornerRadius.bottomRight || 0}px ${cornerRadius.bottomLeft || 0}px` \n : '50%';\n const imgBorderRadiusStr = cornerRadius \n ? `${Math.max(0, (cornerRadius.topLeft || 0) - 3)}px ${Math.max(0, (cornerRadius.topRight || 0) - 3)}px ${Math.max(0, (cornerRadius.bottomRight || 0) - 3)}px ${Math.max(0, (cornerRadius.bottomLeft || 0) - 3)}px` \n : '50%';\n\n return (\n <div\n onClick={onClick}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n flexShrink: 0\n }}\n >\n <div style={{\n width: `${size}px`,\n height: `${size}px`,\n borderRadius: borderRadiusStr,\n border: `${ringWidth}px solid ${ringColor}`,\n padding: '3px',\n boxSizing: 'border-box',\n transition: 'transform 0.1s ease',\n overflow: 'hidden',\n backgroundColor: '#f5f5f5'\n }}>\n <StoryThumbnail\n src={story.thumbnail}\n alt={story.name}\n style={{\n borderRadius: imgBorderRadiusStr,\n }}\n />\n </div>\n <span style={{\n marginTop: '6px',\n fontSize: `${styling.name?.size || 12}px`,\n fontFamily: resolveFontFamily(styling.name?.fontFamily) || 'sans-serif',\n fontWeight: styling.name?.font === 'Bold' ? 'bold' : 'normal',\n color: nameColor,\n maxWidth: `${size + 10}px`,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap'\n }}>\n {story.name}\n </span>\n </div>\n );\n};\n","import React from 'react';\nimport { Story as StoryType } from '../../types';\nimport { StoryGroupItem } from './StoryGroupItem';\n\ninterface StoryListProps {\n stories: StoryType[];\n viewedStories: string[];\n onStoryClick: (index: number) => void;\n}\n\nexport const StoryList: React.FC<StoryListProps> = ({ stories, viewedStories, onStoryClick }) => {\n return (\n <div style={{\n display: 'flex',\n gap: '18px',\n padding: '16px 20px',\n overflowX: 'auto',\n WebkitOverflowScrolling: 'touch',\n justifyContent: 'flex-start'\n }}>\n {stories.sort((a, b) => a.order - b.order).map((story, index) => (\n <StoryGroupItem\n key={story.id}\n story={story}\n isViewed={viewedStories.includes(story.id)}\n onClick={() => onStoryClick(index)}\n />\n ))}\n </div>\n );\n};\n","import React, { useState, useEffect, useRef } from 'react';\nimport { Story as StoryType, StorySlide } from '../../types';\nimport trackEvent from '../../core/trackEvent';\nimport useAppStorysStore, { getAccessToken } from '../../core/store';\nimport { InteractiveOverlay } from '../common/InteractiveElements/InteractiveOverlay';\nimport { StickerData } from '../common/InteractiveElements/types';\nimport PlayPauseButton from '../common/CommonElements/PlayPauseButton';\nimport Cta from '../common/CommonElements/Cta';\nimport CrossButton from '../common/CommonElements/CrossButton';\nimport { SoundButton } from '../common/CommonElements/SoundButton';\nimport ShareButton from '../common/CommonElements/ShareButton';\nimport { parseBackground } from '../../utils/styleUtils';\nimport { StoryThumbnail } from './StoryThumbnail';\n\n\ninterface StoryOverlayProps {\n stories: StoryType[];\n activeStoryIndex: number;\n dataId: string;\n viewedStories: string[];\n setViewedStories: React.Dispatch<React.SetStateAction<string[]>>;\n onNextStory: () => void;\n onPrevStory: () => void;\n onClose: () => void;\n}\n\n// ─── Animation constants ───────────────────────────────────────────────────────\nconst SIDE_CARD_SCALE = 0.63; // how much side/preview cards are scaled\nconst SIDE_CARD_OFFSET = 420; // px — horizontal distance from center to side card origin\nconst ANIM_DURATION = 580; // ms — matches video (~8 frames @ 15fps)\n// Easing: slow-in, fast-middle, slow-out (sinusoidal ease-in-out)\n// Incoming card slides slightly faster than outgoing shrinks for natural depth feel\nconst EASING_OUTGOING = 'cubic-bezier(0.65, 0, 0.35, 1)'; // smooth symmetrical\nconst EASING_INCOMING = 'cubic-bezier(0.45, 0, 0.25, 1)'; // slightly faster lead-in\n\n// Helper: compute the CSS transform for a card given its role\ntype CardRole = 'center' | 'left' | 'right' | 'far-left' | 'far-right' | 'hidden';\n\nfunction getRoleTransform(role: CardRole, cardWidth: number): React.CSSProperties {\n const FAR_SIDE_CARD_OFFSET = SIDE_CARD_OFFSET + (cardWidth * SIDE_CARD_SCALE) + 27; // px - distance for the second sub slide\n switch (role) {\n case 'center':\n return {\n transform: 'translateX(0px) scale(1)',\n opacity: 1,\n zIndex: 10,\n pointerEvents: 'auto',\n boxShadow: '0 32px 64px -12px rgba(0,0,0,0.9)',\n filter: 'brightness(1)',\n };\n case 'left':\n return {\n transform: `translateX(-${SIDE_CARD_OFFSET}px) scale(${SIDE_CARD_SCALE})`,\n opacity: 1,\n filter: 'brightness(0.55)',\n zIndex: 5,\n pointerEvents: 'auto',\n boxShadow: '0 8px 24px rgba(0,0,0,0.5)',\n };\n case 'right':\n return {\n transform: `translateX(${SIDE_CARD_OFFSET}px) scale(${SIDE_CARD_SCALE})`,\n opacity: 1,\n filter: 'brightness(0.55)',\n zIndex: 5,\n pointerEvents: 'auto',\n boxShadow: '0 8px 24px rgba(0,0,0,0.5)',\n };\n case 'far-left':\n return {\n transform: `translateX(-${FAR_SIDE_CARD_OFFSET}px) scale(${SIDE_CARD_SCALE})`,\n opacity: 1,\n filter: 'brightness(0.3)',\n zIndex: 2,\n pointerEvents: 'none',\n };\n case 'far-right':\n return {\n transform: `translateX(${FAR_SIDE_CARD_OFFSET}px) scale(${SIDE_CARD_SCALE})`,\n opacity: 1,\n filter: 'brightness(0.3)',\n zIndex: 2,\n pointerEvents: 'none',\n };\n case 'hidden':\n default:\n return {\n opacity: 0,\n zIndex: 1,\n pointerEvents: 'none',\n transform: 'translateX(0px) scale(1)',\n filter: 'brightness(1)',\n };\n }\n}\n\n// ─── StoryVideo Helper Component ─────────────────────────────────────────────\n// Ensures videos are properly paused when they slide out of the active center\ninterface StoryVideoProps {\n src: string;\n isActive: boolean;\n isAnimating: boolean;\n isMuted: boolean;\n onLoadedData?: () => void;\n activeVideoRef: React.MutableRefObject<HTMLVideoElement | null>;\n}\n\nconst StoryVideo: React.FC<StoryVideoProps> = ({ src, isActive, isAnimating, isMuted, onLoadedData, activeVideoRef }) => {\n const localRef = React.useRef<HTMLVideoElement>(null);\n\n React.useEffect(() => {\n if (isActive && !isAnimating) {\n activeVideoRef.current = localRef.current;\n localRef.current?.play().catch(() => { });\n if (localRef.current && localRef.current.readyState >= 2) {\n onLoadedData?.();\n }\n } else {\n localRef.current?.pause();\n if (activeVideoRef.current === localRef.current) {\n activeVideoRef.current = null;\n }\n }\n }, [isActive, isAnimating, src, activeVideoRef]);\n\n return (\n <video\n ref={localRef}\n src={src}\n playsInline\n muted={isMuted}\n onLoadedData={isActive && !isAnimating ? onLoadedData : undefined}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n );\n};\n\nexport const StoryOverlay: React.FC<StoryOverlayProps> = ({\n stories,\n activeStoryIndex,\n dataId,\n viewedStories,\n setViewedStories,\n onNextStory,\n onPrevStory,\n onClose,\n}) => {\n const [activeSlideIndex, setActiveSlideIndex] = useState<number>(0);\n const [progress, setProgress] = useState<number>(0);\n const [isMuted, setIsMuted] = useState<boolean>(false);\n const [videoLoaded, setVideoLoaded] = useState<boolean>(false);\n const [isPaused, setIsPaused] = useState<boolean>(false);\n const [showShortcuts, setShowShortcuts] = useState<boolean>(false);\n const [showToast, setShowToast] = useState<string | null>(null);\n const [isDesktop, setIsDesktop] = useState(typeof window !== 'undefined' ? window.innerWidth >= 1024 : false);\n\n // ─── NEW: animation state ──────────────────────────────────────────────────\n // outgoingIndex: the slide that's currently animating OUT\n // incomingIndex: the slide that's currently animating IN (= the next activeSlideIndex)\n // direction: which way the transition goes\n const [isAnimating, setIsAnimating] = useState(false);\n const [outgoingIndex, setOutgoingIndex] = useState<number | null>(null);\n const [incomingIndex, setIncomingIndex] = useState<number | null>(null);\n const [direction, setDirection] = useState<'next' | 'prev' | null>(null);\n // ──────────────────────────────────────────────────────────────────────────\n\n useEffect(() => {\n const handleResize = () => {\n setIsDesktop(window.innerWidth >= 1024);\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n const progressTimerRef = useRef<any>(null);\n const activeVideoRef = useRef<HTMLVideoElement | null>(null);\n const clickStartTimeRef = useRef<number>(0);\n\n const currentStory = stories[activeStoryIndex];\n const currentSlide = currentStory?.slides[activeSlideIndex];\n\n const currentSlideStyling = currentSlide?.styling as any;\n const slideEditorSource = currentSlideStyling?.editorSource || currentSlideStyling?.meta?.editorSource;\n const slideIsStudio = slideEditorSource === 'studio' || slideEditorSource === 'editor';\n const slideBgImage = slideIsStudio ? currentSlideStyling?.background?.media?.mediaUrl : currentSlide?.image;\n const slideCtaText = slideIsStudio ? currentSlide?.content?.button_text : currentSlide?.button_text;\n const slideCtaLink = slideIsStudio ? currentSlide?.content?.link : currentSlide?.link;\n const slideVideo = currentSlide?.video || (slideIsStudio ? currentSlide?.content?.video?.[0]?.link : undefined);\n\n // ─── Dynamic Canva Dimensions ───\n const currentCanva = currentSlide?.content?.canva;\n const canvaRatio = (currentCanva && currentCanva.width && currentCanva.height) \n ? (currentCanva.width / currentCanva.height) \n : (400 / 700);\n \n const CARD_HEIGHT = 700;\n const CARD_WIDTH = Math.round(CARD_HEIGHT * canvaRatio);\n\n const handleShare = async () => {\n const shareData = {\n title: currentStory.name,\n text: `Check out this story: ${currentStory.name}`,\n url: window.location.href,\n };\n\n if (currentSlide?.id) {\n void trackEvent('shared', dataId, { story_slide: currentSlide.id });\n }\n\n if (navigator.share) {\n try {\n await navigator.share(shareData);\n } catch (err) { }\n } else {\n if (navigator.clipboard) {\n try {\n await navigator.clipboard.writeText(window.location.href);\n setShowToast('Story link copied to clipboard!');\n setTimeout(() => setShowToast(null), 2500);\n } catch (err) { }\n }\n }\n };\n\n useEffect(() => {\n setActiveSlideIndex(0);\n setProgress(0);\n setVideoLoaded(false);\n setIsPaused(false);\n setIsAnimating(false);\n setOutgoingIndex(null);\n setIncomingIndex(null);\n setDirection(null);\n }, [activeStoryIndex]);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (document.activeElement?.tagName === 'INPUT' || document.activeElement?.tagName === 'TEXTAREA') return;\n switch (e.key) {\n case 'ArrowRight': handleNextSlide(); break;\n case 'ArrowLeft': handlePrevSlide(); break;\n case ' ':\n e.preventDefault();\n setIsPaused(prev => !prev);\n break;\n case 'Escape': onClose(); break;\n case 's':\n case 'S':\n e.preventDefault();\n handleShare();\n break;\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [activeSlideIndex, activeStoryIndex, isPaused, currentStory, onClose]);\n\n useEffect(() => {\n if (currentStory && currentSlide) {\n void trackEvent('viewed', dataId, { story_slide: currentSlide.id });\n }\n }, [activeSlideIndex, currentStory?.id, dataId]);\n\n useEffect(() => {\n if (currentStory && currentSlide) {\n const slideTime = currentStory.styling?.slideShowTime || 5;\n const isVideo = !!slideVideo;\n\n if (progressTimerRef.current) clearInterval(progressTimerRef.current);\n\n if (isPaused) {\n if (activeVideoRef.current) activeVideoRef.current.pause();\n return;\n } else {\n if (activeVideoRef.current) activeVideoRef.current.play().catch(() => { });\n }\n\n if (isVideo && !videoLoaded) return;\n if (isAnimating) return;\n\n progressTimerRef.current = setInterval(() => {\n setProgress((prev) => {\n if (prev >= 100) {\n handleNextSlide();\n return 100;\n }\n return prev + (100 / (slideTime * 10));\n });\n }, 100);\n\n return () => {\n if (progressTimerRef.current) clearInterval(progressTimerRef.current);\n };\n }\n }, [activeStoryIndex, activeSlideIndex, isPaused, videoLoaded, isAnimating]);\n\n if (!currentSlide) return null;\n\n // ─── NEW: Core transition function ────────────────────────────────────────\n const triggerSlideTransition = (dir: 'next' | 'prev', targetIndex: number) => {\n if (isAnimating) return;\n setDirection(dir);\n setOutgoingIndex(activeSlideIndex);\n setIncomingIndex(targetIndex);\n setIsAnimating(true);\n\n // After animation completes, commit the new active index and clean up\n setTimeout(() => {\n setActiveSlideIndex(targetIndex);\n setProgress(0);\n setVideoLoaded(false);\n setIsAnimating(false);\n setOutgoingIndex(null);\n setIncomingIndex(null);\n setDirection(null);\n }, ANIM_DURATION + 20); // +20ms buffer so CSS transition fully completes before state flush\n };\n\n const handleNextSlide = () => {\n if (isAnimating) return;\n if (activeSlideIndex < currentStory.slides.length - 1) {\n triggerSlideTransition('next', activeSlideIndex + 1);\n } else {\n if (!viewedStories.includes(currentStory.id)) {\n const updated = [...viewedStories, currentStory.id];\n setViewedStories(updated);\n localStorage.setItem('app_storys_viewed_stories', JSON.stringify(updated));\n }\n onNextStory();\n }\n };\n\n const handlePrevSlide = () => {\n if (isAnimating) return;\n if (activeSlideIndex > 0) {\n triggerSlideTransition('prev', activeSlideIndex - 1);\n } else {\n onPrevStory();\n }\n };\n // ──────────────────────────────────────────────────────────────────────────\n\n const handleMouseDownNav = () => {\n clickStartTimeRef.current = Date.now();\n setIsPaused(true);\n };\n\n const handleMouseUpNav = (dir: 'next' | 'prev') => {\n setIsPaused(false);\n const duration = Date.now() - clickStartTimeRef.current;\n if (duration < 300) {\n if (dir === 'next') handleNextSlide();\n else handlePrevSlide();\n }\n };\n\n const handleVideoLoad = () => setVideoLoaded(true);\n\n const handleClickCTA = (slide: StorySlide) => {\n const styling = slide?.styling as any;\n const editorSource = styling?.editorSource || styling?.meta?.editorSource;\n const isStudio = editorSource === 'studio' || editorSource === 'editor';\n const link = isStudio ? slide.content?.link : slide.link;\n\n if (link) {\n void trackEvent('clicked', dataId, { story_slide: slide.id });\n if (link.startsWith('http')) {\n window.open(link, '_blank');\n } else {\n window.location.href = link;\n }\n }\n };\n\n const toggleMute = (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsMuted(!isMuted);\n };\n\n const crossConfig = currentStory?.styling?.crossButton;\n const soundConfig = currentStory?.styling?.soundToggle;\n const ctaStyling = currentSlide?.styling?.cta;\n\n // ─── NEW: Compute role for each slide during animation ────────────────────\n /**\n * Returns the CardRole for a given slide index.\n *\n * Idle (not animating):\n * activeSlideIndex-1 → 'left' (visible side preview)\n * activeSlideIndex → 'center' (active card)\n * activeSlideIndex+1 → 'right' (visible side preview)\n * everything else → 'hidden'\n *\n * Animating NEXT (outgoing=activeSlideIndex → left, incoming=activeSlideIndex+1 → center):\n * outgoingIndex → 'left' (animates: center → left)\n * incomingIndex → 'center' (animates: right → center)\n * outgoingIndex-1 → 'far-left' (fades away)\n * incomingIndex+1 → 'right' (slides into the right preview spot)\n *\n * Animating PREV:\n * outgoingIndex → 'right' (animates: center → right)\n * incomingIndex → 'center' (animates: left → center)\n * outgoingIndex+1 → 'far-right'\n * incomingIndex-1 → 'left'\n */\n const getSlideRole = (idx: number): CardRole => {\n if (!isAnimating) {\n if (idx === activeSlideIndex) return 'center';\n if (idx === activeSlideIndex - 1) return 'left';\n if (idx === activeSlideIndex - 2) return 'far-left';\n if (idx === activeSlideIndex + 1) return 'right';\n if (idx === activeSlideIndex + 2) return 'far-right';\n return 'hidden';\n }\n\n // During animation\n if (direction === 'next') {\n if (idx === outgoingIndex) return 'left'; // shrinks & moves left\n if (idx === incomingIndex) return 'center'; // slides in from right\n if (idx === (outgoingIndex ?? 0) - 1) return 'far-left'; // previous left becomes far-left\n if (idx === (outgoingIndex ?? 0) - 2) return 'hidden'; // previous far-left becomes hidden\n if (idx === (incomingIndex ?? 0) + 1) return 'right'; // next-next becomes right\n if (idx === (incomingIndex ?? 0) + 2) return 'far-right'; // new card becomes far-right\n return 'hidden';\n } else {\n // direction === 'prev'\n if (idx === outgoingIndex) return 'right'; // shrinks & moves right\n if (idx === incomingIndex) return 'center'; // slides in from left\n if (idx === (outgoingIndex ?? 0) + 1) return 'far-right';\n if (idx === (outgoingIndex ?? 0) + 2) return 'hidden';\n if (idx === (incomingIndex ?? 0) - 1) return 'left';\n if (idx === (incomingIndex ?? 0) - 2) return 'far-left';\n return 'hidden';\n }\n };\n\n /**\n * The \"starting position\" of a card before the animation begins.\n * When isAnimating becomes true, the card needs to be at its SOURCE position\n * on frame 0, then CSS transition carries it to its TARGET position.\n *\n * The trick: we set the initial transform via inline style BEFORE\n * adding the transition class, so the first paint shows the source pos,\n * and the second paint (after React flushes) shows the target with transition.\n *\n * Since React batches state updates and the transition is applied together\n * with the role assignment, we achieve this by always defining both the\n * \"source role\" and the \"target role\" in the same render. The CSS transition\n * property does the interpolation.\n *\n * For the INCOMING card (next slide going → center on a 'next' transition):\n * It must START at the 'right' position and END at 'center'.\n * In getSlideRole it returns 'center' immediately, so we need its\n * initial position to be 'right' BEFORE isAnimating was true.\n * → We solve this with a \"pre-transition\" frame using a separate useEffect trick,\n * BUT the simplest CSS-only approach is:\n * Give the incoming card 'right' transform with NO transition for 1 frame,\n * then switch to 'center' with transition.\n *\n * Simpler approach used here: we render incoming slide at its START role\n * during the first frame via a `pendingRole` system, then swap to target role.\n */\n // ──────────────────────────────────────────────────────────────────────────\n\n // Responsive Styles\n const backdropStyle: React.CSSProperties = isDesktop ? {\n position: 'fixed',\n top: 0, left: 0,\n width: '100vw', height: '100vh',\n background: 'radial-gradient(circle at center, #0B1424 0%, #03070E 100%)',\n zIndex: 100000,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n overflow: 'hidden',\n color: 'white'\n } : {\n position: 'fixed',\n top: 0, left: 0,\n width: '100vw', height: '100vh',\n backgroundColor: 'rgba(0,0,0,0.95)',\n zIndex: 100000,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n };\n\n const centerCardBaseStyle: React.CSSProperties = isDesktop ? {\n position: 'absolute',\n width: `${CARD_WIDTH}px`,\n height: `${CARD_HEIGHT}px`,\n backgroundColor: '#000',\n borderRadius: '20px',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.8)',\n border: '1px solid rgba(255, 255, 255, 0.1)',\n // transition is applied per-card below\n } : {\n position: 'relative',\n width: '100%',\n maxWidth: '450px',\n height: '100%',\n maxHeight: '850px',\n backgroundColor: '#000',\n borderRadius: '0px',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column'\n };\n\n // Mobile side card style (unchanged from original)\n const sideCardStyle: React.CSSProperties = {\n width: '240px',\n height: '420px',\n backgroundColor: '#000',\n borderRadius: '16px',\n overflow: 'hidden',\n opacity: 1,\n filter: 'brightness(0.6)',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 10px 20px rgba(0,0,0,0.5)',\n border: '1px solid rgba(255, 255, 255, 0.05)',\n transform: 'scale(0.9)',\n transition: 'all 0.3s ease',\n cursor: 'pointer'\n };\n\n // ─── Determine which slides to render (visible window) ────────────────────\n const slidesToRender = currentStory.slides.reduce<number[]>((acc, _, idx) => {\n const role = getSlideRole(idx);\n if (role !== 'hidden') acc.push(idx);\n // Also include indices just outside the window that might be 'hidden' but\n // need to be mounted for the incoming animation to have something to transition from.\n return acc;\n }, []);\n\n // Always include activeSlideIndex ± 2 so cards are pre-mounted for transitions\n const renderSet = new Set(slidesToRender);\n renderSet.add(activeSlideIndex);\n if (activeSlideIndex > 0) renderSet.add(activeSlideIndex - 1);\n if (activeSlideIndex > 1) renderSet.add(activeSlideIndex - 2);\n if (activeSlideIndex < currentStory.slides.length - 1) renderSet.add(activeSlideIndex + 1);\n if (activeSlideIndex < currentStory.slides.length - 2) renderSet.add(activeSlideIndex + 2);\n\n return (\n <div style={backdropStyle} onClick={() => !isDesktop && handleNextSlide()}>\n\n {/* Dynamic Ambient Glow Background */}\n <div\n key={`${activeStoryIndex}-${isAnimating ? incomingIndex : activeSlideIndex}`}\n style={{\n position: 'absolute', top: 0, left: 0, right: 0, bottom: 0,\n zIndex: 0, overflow: 'hidden', pointerEvents: 'none',\n transition: 'all 0.6s ease-in-out'\n }}\n >\n {slideVideo ? (\n <video src={slideVideo} style={{ width: '100%', height: '100%', objectFit: 'cover', filter: 'blur(120px) saturate(1.8) opacity(0.35)' }} muted />\n ) : (\n <StoryThumbnail\n src={slideBgImage || currentStory.thumbnail}\n style={{ width: '100%', height: '100%', filter: 'blur(120px) saturate(1.8) opacity(0.35)' }}\n />\n )}\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(5, 5, 8, 0.4)' }} />\n </div>\n\n {isDesktop && (\n <div style={{\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n paddingTop: '20px',\n zIndex: 10\n }}>\n {/* Progress Bar */}\n <div style={{\n width: '100%',\n display: 'flex',\n gap: '8px',\n padding: '0 20px',\n boxSizing: 'border-box',\n }}>\n {currentStory.slides.map((_, idx) => {\n const displayIndex = isAnimating && incomingIndex !== null ? incomingIndex : activeSlideIndex;\n let fillWidth = '0%';\n if (idx < displayIndex) fillWidth = '100%';\n else if (idx === displayIndex) fillWidth = `${progress}%`;\n\n return (\n <div key={idx} style={{\n flex: 1, height: '3px',\n backgroundColor: 'rgba(255,255,255,0.15)',\n borderRadius: '2px', overflow: 'hidden'\n }}>\n <div style={{\n width: fillWidth, height: '100%',\n backgroundColor: 'white',\n transition: idx === displayIndex ? 'width 0.1s linear' : 'none'\n }} />\n </div>\n );\n })}\n </div>\n\n {/* Icons Grid */}\n <div style={{\n width: '100%',\n maxWidth: '1400px',\n margin: '0 auto',\n display: 'grid',\n gridTemplateColumns: `minmax(0, 1fr) ${CARD_WIDTH}px minmax(0, 1fr)`,\n gap: '12px',\n alignItems: 'center',\n marginTop: '16px',\n padding: '0 20px',\n boxSizing: 'border-box',\n zIndex: showShortcuts ? 2000 : 10\n }}>\n <div style={{ paddingLeft: '0px' }} />\n\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>\n <StoryThumbnail\n src={currentStory.thumbnail}\n alt={currentStory.name}\n style={{ width: '44px', height: '44px', borderRadius: '50%', border: '2px solid white', margin: 0 }}\n />\n <span style={{ color: 'white', fontWeight: 'bold', fontSize: '16px', whiteSpace: 'nowrap' }}>\n {currentStory.name}\n </span>\n </div>\n <div style={{ display: 'flex', gap: '8px' }}>\n <ShareButton\n config={{\n enabled: currentStory?.styling?.share?.enabled ?? true,\n image: currentStory?.styling?.share?.image ?? '',\n color: {\n cross: currentStory?.styling?.share?.color?.cross ?? '#ffffff',\n fill: currentStory?.styling?.share?.color?.fill ?? 'rgba(255,255,255,0.08)',\n stroke: currentStory?.styling?.share?.color?.stroke ?? 'transparent',\n },\n margin: { top: 0, bottom: 0, left: 0, right: 0 },\n size: currentStory?.styling?.share?.size ?? 44\n }}\n onPress={handleShare}\n style={{ position: 'relative', borderRadius: '12px' }}\n />\n <SoundButton\n config={{\n size: 44,\n color: { cross: '#ffffff', fill: 'rgba(255,255,255,0.08)', stroke: 'transparent' },\n margin: { top: 0, bottom: 0, left: 0, right: 0 },\n image: '' // Force common SVG icons\n }}\n onPress={toggleMute}\n type={isMuted ? 'mute' : 'unmute'}\n enabled={!!soundConfig?.enabled && !!slideVideo}\n style={{ position: 'relative', borderRadius: '12px' }}\n />\n <PlayPauseButton isPaused={isPaused} onPress={() => setIsPaused(!isPaused)} size={44} style={{ borderRadius: '12px' }} />\n </div>\n </div>\n\n <div style={{ display: 'flex', gap: '10px', flex: 1, justifyContent: 'flex-end', paddingRight: '0px' }}>\n <div style={{ position: 'relative' }}>\n <button\n onClick={() => { setShowShortcuts(!showShortcuts); setIsPaused(!showShortcuts); }}\n style={{\n width: '44px', height: '44px',\n background: showShortcuts ? 'rgba(255,255,255,0.15)' : 'rgba(255,255,255,0.08)',\n border: showShortcuts ? '1px solid white' : '1px solid rgba(255,255,255,0.1)',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n borderRadius: '12px', cursor: 'pointer', transition: 'all 0.2s',\n padding: 0, outline: 'none'\n }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\n </svg>\n </button>\n {showShortcuts && (\n <>\n <style>{`\n @keyframes fadeUp {\n from { opacity: 0; transform: translateY(10px) scale(0.95); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n `}</style>\n <div style={{ position: 'absolute', top: '46px', right: 0, width: '260px', background: 'rgba(25, 25, 25, 0.98)', border: '1px solid rgba(255,255,255,0.08)', borderRadius: '16px', padding: '18px', boxShadow: '0 20px 25px -5px rgba(0,0,0,0.4), 0 10px 10px -5px rgba(0,0,0,0.4)', zIndex: 1001, animation: 'fadeUp 0.25s cubic-bezier(0.4, 0, 0.2, 1) forwards' }}>\n <div style={{ fontSize: '11px', fontWeight: 'bold', color: '#9CA3AF', letterSpacing: '1px', textTransform: 'uppercase', marginBottom: '16px', paddingBottom: '10px', borderBottom: '1px solid rgba(255,255,255,0.06)' }}>Keyboard Shortcuts</div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n {[\n { key: '→', label: 'Next slide' },\n { key: '←', label: 'Previous slide' },\n { key: 'space', label: 'Play/Pause' },\n { key: 'esc', label: 'Close story' },\n { key: 'S', label: 'Share story link' },\n ].map(({ key, label }) => (\n <div key={key} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <span style={{ background: 'rgba(255,255,255,0.08)', padding: '5px 8px', borderRadius: '5px', fontSize: '12px', color: 'white', border: '1px solid rgba(255,255,255,0.1)' }}>{key}</span>\n <span style={{ fontSize: '13px', color: '#E5E7EB', fontWeight: '500' }}>{label}</span>\n </div>\n ))}\n </div>\n </div>\n </>\n )}\n </div>\n <CrossButton\n config={{\n enabled: crossConfig?.enabled ?? true,\n image: '', // Force common SVG icon\n color: { cross: '#ffffff', fill: 'rgba(255,255,255,0.08)', stroke: 'transparent' },\n margin: { top: 0, bottom: 0, left: 0, right: 0 },\n size: 44\n }}\n onPress={onClose}\n style={{ position: 'relative', borderRadius: '12px' }}\n />\n </div>\n </div>\n </div>\n )}\n\n {/* Main Vertically Centered Wrapper */}\n <div style={{\n flex: 1, width: '100%',\n display: 'flex', flexDirection: 'column',\n justifyContent: 'center', alignItems: 'center',\n gap: '20px'\n }}>\n\n\n {/* ── Story Player Container ── */}\n <div\n style={{\n display: isDesktop ? 'grid' : 'flex',\n gridTemplateColumns: isDesktop ? `minmax(0, 1fr) ${CARD_WIDTH}px minmax(0, 1fr)` : 'none',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '12px',\n width: '100%',\n maxWidth: '1400px',\n position: 'relative'\n }}\n onClick={(e) => isDesktop && e.stopPropagation()}\n >\n {/* Left column (desktop only) */}\n {isDesktop && (\n <div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: '12px', width: '100%', boxSizing: 'border-box' }}>\n {(activeSlideIndex > 0 || activeStoryIndex > 0) && (\n <button\n onClick={handlePrevSlide}\n style={{ background: 'rgba(0,0,0,0.5)', border: 'none', color: 'white', borderRadius: '50%', width: '40px', height: '40px', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', fontSize: '18px', backdropFilter: 'blur(5px)', transition: 'background 0.2s' }}\n onMouseEnter={(e) => e.currentTarget.style.background = 'rgba(0,0,0,0.7)'}\n onMouseLeave={(e) => e.currentTarget.style.background = 'rgba(0,0,0,0.5)'}\n >‹</button>\n )}\n </div>\n )}\n\n {/* ── CENTER: Story card stack (desktop) / single card (mobile) ── */}\n {isDesktop ? (\n // ─── DESKTOP: absolute-positioned card stack with transform-based animation ───\n <div style={{\n width: `${CARD_WIDTH}px`,\n height: `${CARD_HEIGHT}px`,\n position: 'relative',\n zIndex: 5,\n // overflow visible so side cards can poke out\n overflow: 'visible',\n }}>\n {Array.from(renderSet).sort((a, b) => a - b).map((index) => {\n const slide = currentStory.slides[index];\n if (!slide) return null;\n\n const role = getSlideRole(index);\n const roleStyle = getRoleTransform(role, CARD_WIDTH);\n\n const slideStyling = slide?.styling as any;\n const editorSource = slideStyling?.editorSource || slideStyling?.meta?.editorSource;\n const isStudio = editorSource === 'studio' || editorSource === 'editor';\n const bgImage = slideStyling?.background?.media?.mediaUrl || slide?.image;\n const video = slide?.video || (isStudio ? slide?.content?.video?.[0]?.link : undefined);\n const bgColor = parseBackground(slideStyling?.background) || '#000000';\n const slideCtaTextLocal = isStudio ? slide?.content?.button_text : slide?.button_text;\n const slideCtaLinkLocal = isStudio ? slide?.content?.link : slide?.link;\n\n const isCurrent = index === activeSlideIndex && !isAnimating;\n const isIncoming = isAnimating && index === incomingIndex;\n const isActive = isCurrent || isIncoming;\n\n const containerStyles: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: isStudio ? bgColor : '#000',\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n borderRadius: '16px',\n };\n\n return (\n <div\n key={slide.id || index}\n style={{\n ...centerCardBaseStyle,\n // Override position to absolute for the stacking\n position: 'absolute',\n top: 0,\n left: 0,\n width: `${CARD_WIDTH}px`,\n height: `${CARD_HEIGHT}px`,\n // Apply role-based transform + transition\n ...roleStyle,\n transition: role === 'hidden' || role === 'far-left' || role === 'far-right'\n ? `opacity ${ANIM_DURATION}ms ease, transform ${ANIM_DURATION}ms ease`\n : index === outgoingIndex\n ? `transform ${ANIM_DURATION}ms ${EASING_OUTGOING}, opacity ${ANIM_DURATION}ms ${EASING_OUTGOING}, filter ${ANIM_DURATION}ms ${EASING_OUTGOING}`\n : `transform ${ANIM_DURATION}ms ${EASING_INCOMING}, opacity ${ANIM_DURATION}ms ${EASING_INCOMING}, filter ${ANIM_DURATION}ms ${EASING_INCOMING}`,\n transformOrigin: 'center center',\n willChange: 'transform, opacity, filter',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Content */}\n <div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, width: '30%', zIndex: 5, cursor: 'pointer' }} onMouseDown={handleMouseDownNav} onMouseUp={() => handleMouseUpNav('prev')} onTouchStart={handleMouseDownNav} onTouchEnd={() => handleMouseUpNav('prev')} />\n <div style={{ position: 'absolute', top: 0, bottom: 0, right: 0, width: '70%', zIndex: 4, cursor: 'pointer' }} onMouseDown={handleMouseDownNav} onMouseUp={() => handleMouseUpNav('next')} onTouchStart={handleMouseDownNav} onTouchEnd={() => handleMouseUpNav('next')} />\n\n <div style={containerStyles}>\n {video ? (\n <StoryVideo\n src={video}\n isActive={isActive}\n isAnimating={isAnimating}\n isMuted={isMuted}\n onLoadedData={handleVideoLoad}\n activeVideoRef={activeVideoRef}\n />\n ) : (\n (bgImage || (!isStudio && currentStory?.thumbnail)) && (\n <StoryThumbnail\n src={bgImage || currentStory?.thumbnail}\n alt=\"Story content\"\n style={{ width: '100%', height: '100%', objectFit: isStudio ? 'contain' : 'cover' }}\n />\n )\n )}\n <InteractiveOverlay\n content={{\n ...slide.content,\n styling: {\n ...(slide.content as any)?.styling,\n ...(slide as any)?.styling,\n },\n interactions: slide.interactions,\n }}\n elapsedTime={isActive ? (progress / 100) * (currentStory.styling?.slideShowTime || 5) : 0}\n onInteraction={async (interactionData: any) => {\n if (!isActive) return;\n setIsPaused(true);\n const { type, questionId, pollId, quizId, optionId, value, stickerId } = interactionData;\n let interaction_type = type?.split('_')[0] || 'interaction';\n if (interaction_type === 'quizz') interaction_type = 'quiz';\n if (type?.startsWith('image_quiz')) interaction_type = 'quiz';\n const interaction_id = stickerId || questionId || pollId || quizId || slide.id;\n const selected = optionId || interactionData.selected_option || '';\n const state = useAppStorysStore.getState();\n const userId = state.userId || 'anonymous';\n const trackingUrl = state.trackingUrl || 'https://tracking.appstorys.co';\n const accessToken = await getAccessToken();\n fetch(`${trackingUrl}/capture-event`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}) },\n body: JSON.stringify({\n user_id: userId, campaign_id: dataId, event: 'interaction',\n metadata: { interaction_type, interaction_id, slide_id: slide.id, selected_option: String(selected), value: String(value || '') }\n })\n }).catch(err => console.error('AppStorys: Instant Tracking Failed', err));\n }}\n />\n </div>\n\n {(slideCtaTextLocal || slideCtaLinkLocal) && (\n <Cta\n cta={slide?.styling?.cta}\n buttonText={slideCtaTextLocal || 'Learn More'}\n onPress={(e) => { if (e && e.stopPropagation) e.stopPropagation(); handleClickCTA(slide); }}\n />\n )}\n </div>\n );\n })}\n </div>\n ) : (\n // ─── MOBILE: original single card layout (unchanged) ───\n <div style={{\n width: '100%',\n maxWidth: '450px',\n height: '100%',\n maxHeight: '850px',\n overflow: 'hidden',\n position: 'relative',\n zIndex: 5,\n display: 'flex',\n flexDirection: 'column'\n }}>\n {currentStory.slides.map((slide, index) => {\n if (Math.abs(index - activeSlideIndex) > 1) {\n return <div key={slide.id || index} style={{ display: 'none' }} />;\n }\n\n const slideStyling = slide?.styling as any;\n const editorSource = slideStyling?.editorSource || slideStyling?.meta?.editorSource;\n const isStudio = editorSource === 'studio' || editorSource === 'editor';\n const bgImage = slideStyling?.background?.media?.mediaUrl || slide?.image;\n const video = slide?.video || (isStudio ? slide?.content?.video?.[0]?.link : undefined);\n const bgColor = parseBackground(slideStyling?.background) || '#000000';\n const slideCtaTextLocal = isStudio ? slide?.content?.button_text : slide?.button_text;\n const slideCtaLinkLocal = isStudio ? slide?.content?.link : slide?.link;\n\n const isCurrent = index === activeSlideIndex;\n\n if (!isCurrent) return null;\n\n return (\n <div key={slide.id || index} style={{ width: '100%', height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>\n <div style={{ ...centerCardBaseStyle }} onClick={(e) => e.stopPropagation()}>\n\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, display: 'flex', gap: '4px', padding: '10px', zIndex: 10 }}>\n {currentStory.slides.map((_, idx) => {\n let fillWidth = idx < activeSlideIndex ? '100%' : idx === activeSlideIndex ? `${progress}%` : '0%';\n return (\n <div key={idx} style={{ flex: 1, height: '3px', backgroundColor: 'rgba(255,255,255,0.3)', borderRadius: '2px', overflow: 'hidden' }}>\n <div style={{ width: fillWidth, height: '100%', backgroundColor: 'white', transition: idx === activeSlideIndex ? 'width 0.1s linear' : 'none' }} />\n </div>\n );\n })}\n </div>\n\n <div style={{ position: 'absolute', top: '20px', left: '10px', right: '10px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', zIndex: 10, padding: '5px' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n <StoryThumbnail src={currentStory.thumbnail} alt={currentStory.name} style={{ width: '32px', height: '32px', borderRadius: '50%' }} />\n <span style={{ color: 'white', fontWeight: 'bold', fontSize: '14px', textShadow: '0 1px 3px rgba(0,0,0,0.8)' }}>{currentStory.name}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>\n <SoundButton config={{ size: 32, color: { cross: '#ffffff', fill: 'rgba(255,255,255,0.08)', stroke: 'transparent' }, margin: { top: 0, bottom: 0, left: 0, right: 0 }, image: '' }} onPress={toggleMute} type={isMuted ? 'mute' : 'unmute'} enabled={!!soundConfig?.enabled && !!video} style={{ position: 'relative', borderRadius: '10px' }} />\n <CrossButton config={{ enabled: crossConfig?.enabled !== false, image: '', color: { cross: '#ffffff', fill: 'rgba(255,255,255,0.08)', stroke: 'transparent' }, margin: { top: 0, bottom: 0, left: 0, right: 0 }, size: 32 }} onPress={onClose} style={{ position: 'relative', borderRadius: '10px' }} />\n </div>\n </div>\n\n <div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, width: '30%', zIndex: 5, cursor: 'pointer' }} onMouseDown={handleMouseDownNav} onMouseUp={() => handleMouseUpNav('prev')} onTouchStart={handleMouseDownNav} onTouchEnd={() => handleMouseUpNav('prev')} />\n <div style={{ position: 'absolute', top: 0, bottom: 0, right: 0, width: '70%', zIndex: 4, cursor: 'pointer' }} onMouseDown={handleMouseDownNav} onMouseUp={() => handleMouseUpNav('next')} onTouchStart={handleMouseDownNav} onTouchEnd={() => handleMouseUpNav('next')} />\n\n <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', background: isStudio ? bgColor : '#000', position: 'relative', width: '100%', height: '100%', overflow: 'hidden', borderRadius: '0px' }}>\n {video ? (\n <StoryVideo\n src={video}\n isActive={isCurrent}\n isAnimating={isAnimating}\n isMuted={isMuted}\n onLoadedData={handleVideoLoad}\n activeVideoRef={activeVideoRef}\n />\n ) : (\n (bgImage || currentStory?.thumbnail) && (\n <StoryThumbnail src={bgImage || currentStory?.thumbnail} alt=\"Story content\" style={{ width: '100%', height: '100%', objectFit: isStudio ? 'contain' : 'cover' }} />\n )\n )}\n <InteractiveOverlay\n content={{ ...slide.content, styling: { ...(slide.content as any)?.styling, ...(slide as any)?.styling }, interactions: slide.interactions }}\n elapsedTime={(progress / 100) * (currentStory.styling?.slideShowTime || 5)}\n onInteraction={async (interactionData: any) => {\n setIsPaused(true);\n const { type, questionId, pollId, quizId, optionId, value, stickerId } = interactionData;\n let interaction_type = type?.split('_')[0] || 'interaction';\n if (interaction_type === 'quizz') interaction_type = 'quiz';\n if (type?.startsWith('image_quiz')) interaction_type = 'quiz';\n const interaction_id = stickerId || questionId || pollId || quizId || slide.id;\n const selected = optionId || interactionData.selected_option || '';\n const state = useAppStorysStore.getState();\n const userId = state.userId || 'anonymous';\n const trackingUrl = state.trackingUrl || 'https://tracking.appstorys.co';\n const accessToken = await getAccessToken();\n fetch(`${trackingUrl}/capture-event`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}) },\n body: JSON.stringify({ user_id: userId, campaign_id: dataId, event: 'interaction', metadata: { interaction_type, interaction_id, slide_id: slide.id, selected_option: String(selected), value: String(value || '') } })\n }).catch(err => console.error('AppStorys: Instant Tracking Failed', err));\n }}\n />\n </div>\n\n {(slideCtaTextLocal || slideCtaLinkLocal) && (\n <Cta cta={slide?.styling?.cta} buttonText={slideCtaTextLocal || 'Learn More'} onPress={(e) => { if (e && e.stopPropagation) e.stopPropagation(); handleClickCTA(slide); }} />\n )}\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Right column (desktop only) */}\n {isDesktop && (\n <div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', gap: '12px', width: '100%', boxSizing: 'border-box' }}>\n <button\n onClick={handleNextSlide}\n style={{ background: 'rgba(0,0,0,0.5)', border: 'none', color: 'white', borderRadius: '50%', width: '40px', height: '40px', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', fontSize: '18px', backdropFilter: 'blur(5px)', transition: 'background 0.2s' }}\n onMouseEnter={(e) => e.currentTarget.style.background = 'rgba(0,0,0,0.7)'}\n onMouseLeave={(e) => e.currentTarget.style.background = 'rgba(0,0,0,0.5)'}\n >›</button>\n </div>\n )}\n\n {/* Previous Stories float */}\n {isDesktop && activeStoryIndex > 0 && (\n <div style={{ position: 'absolute', bottom: '40px', left: '40px', display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: '5px', zIndex: 20 }}>\n <span style={{ fontSize: '11px', fontWeight: 'bold', color: 'rgba(255,255,255,0.75)', letterSpacing: '0.4px', paddingLeft: '2px' }}>Previous Stories</span>\n <div style={{ background: 'rgba(255, 255, 255, 0.06)', padding: '8px 14px', borderRadius: '14px', display: 'flex', alignItems: 'center', gap: '12px', backdropFilter: 'blur(16px)', cursor: 'pointer', boxShadow: '0 8px 16px rgba(0, 0, 0, 0.25)', transition: 'all 0.2s', maxWidth: '280px' }} onClick={onPrevStory}>\n <span style={{ color: 'white', fontSize: '15px' }}>←</span>\n <div style={{ width: '40px', height: '40px', borderRadius: '50%', border: '2px solid white', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'white', flexShrink: 0 }}>\n <StoryThumbnail src={stories[activeStoryIndex - 1].thumbnail} style={{ width: '36px', height: '36px', borderRadius: '50%' }} />\n </div>\n <span style={{ fontSize: '14px', color: 'white', fontWeight: '500', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0 }}>{stories[activeStoryIndex - 1].name}</span>\n </div>\n </div>\n )}\n\n {/* Next Stories float */}\n {isDesktop && activeStoryIndex < stories.length - 1 && (\n <div style={{ position: 'absolute', bottom: '40px', right: '40px', display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: '5px', zIndex: 20 }}>\n <span style={{ fontSize: '11px', fontWeight: 'bold', color: 'rgba(255,255,255,0.75)', letterSpacing: '0.4px', paddingLeft: '2px' }}>Next Stories</span>\n <div style={{ background: 'rgba(255, 255, 255, 0.06)', padding: '8px 14px', borderRadius: '14px', display: 'flex', alignItems: 'center', gap: '12px', backdropFilter: 'blur(16px)', cursor: 'pointer', boxShadow: '0 8px 16px rgba(0, 0, 0, 0.25)', transition: 'all 0.2s', maxWidth: '280px' }} onClick={onNextStory}>\n <div style={{ width: '40px', height: '40px', borderRadius: '50%', border: '2px solid white', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'white', flexShrink: 0 }}>\n <StoryThumbnail src={stories[activeStoryIndex + 1].thumbnail} style={{ width: '36px', height: '36px', borderRadius: '50%' }} />\n </div>\n <span style={{ fontSize: '14px', color: 'white', fontWeight: '500', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0 }}>{stories[activeStoryIndex + 1].name}</span>\n <span style={{ color: 'white', fontSize: '15px' }}>→</span>\n </div>\n </div>\n )}\n\n {/* Toast */}\n {showToast && (\n <div style={{ position: 'absolute', bottom: '40px', left: '50%', transform: 'translateX(-50%)', background: 'rgba(20, 20, 20, 0.96)', border: '1px solid rgba(255,255,255,0.08)', padding: '12px 24px', borderRadius: '12px', color: 'white', fontSize: '13px', fontWeight: '500', boxShadow: '0 10px 20px rgba(0,0,0,0.5)', backdropFilter: 'blur(10px)', zIndex: 1000 }}>\n {showToast}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};","import React from 'react';\nimport { PollStickerData, StickerProps } from './types';\n\nexport const PollSticker: React.FC<StickerProps<PollStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const isHorizontal = data.layout?.type === 'horizontal';\n const defaults = {\n headerTextColor: '#000000',\n optionBgColor: '#1A1A1A',\n optionTextColor: '#FFFFFF',\n backgroundColor: '#FFFFFF',\n borderRadius: 24,\n padding: 20,\n };\n\n const styling = data.styling || {};\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: `${styling.borderRadius ?? defaults.borderRadius}px`,\n overflow: 'hidden',\n boxShadow: styling.shadow || '0 12px 24px rgba(0,0,0,0.1)',\n boxSizing: 'border-box',\n width: '100%',\n opacity: styling.opacity ?? 1,\n padding: `${styling.padding ?? defaults.padding}px`,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '16px',\n };\n\n const questionStyle: React.CSSProperties = {\n color: styling.headerTextColor || defaults.headerTextColor,\n textAlign: 'center',\n fontWeight: '800',\n fontSize: `${styling.fontSize ? styling.fontSize + 4 : 20}px`,\n lineHeight: '1.2',\n margin: '0',\n width: '100%',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n };\n\n const optionsContainerStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: isHorizontal ? 'row' : 'column',\n gap: '4px',\n width: '100%',\n backgroundColor: '#1A1A1A',\n borderRadius: '12px',\n overflow: 'hidden',\n padding: '2px',\n };\n\n const optionStyle: React.CSSProperties = {\n backgroundColor: styling.optionBgColor || 'transparent',\n color: styling.optionTextColor || defaults.optionTextColor,\n padding: isHorizontal ? '14px 10px' : '16px 20px',\n fontSize: `${styling.fontSize ? styling.fontSize + 1 : 16}px`,\n fontWeight: '700',\n cursor: 'pointer',\n border: 'none',\n width: '100%',\n textAlign: 'center',\n boxSizing: 'border-box',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'background 0.2s',\n flex: 1,\n borderRight: isHorizontal ? '1px solid rgba(255,255,255,0.1)' : 'none',\n borderBottom: !isHorizontal ? '1px solid rgba(255,255,255,0.1)' : 'none',\n };\n\n const handleOptionClick = (optionId: string) => {\n if (isEditing) return;\n onInteraction?.({\n type: 'poll',\n pollId: data.id,\n optionId: optionId,\n stickerId: data.id\n });\n };\n\n const options = Array.isArray(data.options) ? data.options : [];\n\n return (\n <div style={containerStyle}>\n <h3 style={questionStyle}>{data.question || 'Ask A Question...'}</h3>\n <div style={optionsContainerStyle}>\n {options.map((option, index) => (\n <button\n key={option.id}\n style={{\n ...optionStyle,\n borderRight: isHorizontal && index === options.length - 1 ? 'none' : optionStyle.borderRight,\n borderBottom: !isHorizontal && index === options.length - 1 ? 'none' : optionStyle.borderBottom\n }}\n onClick={() => handleOptionClick(option.id)}\n onMouseOver={(e) => {\n if (!isEditing) e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.1)';\n }}\n onMouseOut={(e) => {\n if (!isEditing) e.currentTarget.style.backgroundColor = styling.optionBgColor || 'transparent';\n }}\n >\n {option.text}\n {option.percentage !== undefined && (\n <span style={{ fontSize: '11px', opacity: 0.6, marginLeft: '8px' }}>{option.percentage}%</span>\n )}\n </button>\n ))}\n </div>\n </div>\n );\n};","import React, { useState } from 'react';\nimport { QuizStickerData, StickerProps } from './types';\n\nexport const QuizSticker: React.FC<StickerProps<QuizStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const [selectedOptionId, setSelectedOptionId] = useState<string | null>(null);\n\n const defaults = {\n backgroundColor: '#FFFFFF',\n borderRadius: 20,\n padding: 16,\n questionTextColor: '#FFFFFF', // Changed from #111111 to white for black header\n questionBgColor: '#000000',\n optionBgColor: '#FFFFFF',\n optionTextColor: '#2B2B2B',\n borderColor: '#E5E7EB',\n activeColor: '#10b981', // Success Green\n incorrectColor: '#ef4444', // Error Red\n labelBgColor: '#FFFFFF',\n labelTextColor: '#111111',\n labelBorderColor: '#111111',\n };\n\n const styling = (data as any).styling || {};\n const cardPadding = styling.padding ?? defaults.padding;\n const questionFontSize = styling.fontSize ? styling.fontSize + 6 : 22; // Larger default\n const optionFontSize = styling.optionFontSize || 17; // Larger default\n const optionRadius = styling.optionBorderRadius || 14;\n const borderColor = styling.borderColor || defaults.borderColor;\n const labelSize = Math.min(Math.max(Math.round(optionFontSize * 2.1), 18), 32);\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: `${styling.borderRadius ?? defaults.borderRadius}px`,\n padding: `${cardPadding}px`,\n paddingTop: 0, // Header will handle its own top padding\n boxShadow: styling.shadow || '0 10px 30px rgba(0,0,0,0.12)',\n boxSizing: 'border-box',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden', // Ensure header doesn't bleed\n opacity: styling.opacity ?? 1,\n };\n\n const questionStyle: React.CSSProperties = {\n color: styling.questionTextColor || defaults.questionTextColor,\n backgroundColor: styling.questionBgColor || defaults.questionBgColor,\n fontWeight: '900',\n fontSize: `${questionFontSize}px`,\n lineHeight: 1.25,\n margin: `0 -${cardPadding}px 16px -${cardPadding}px`, // Flush edges\n textAlign: 'center',\n padding: `24px ${cardPadding}px`,\n borderTopLeftRadius: `${styling.borderRadius ?? defaults.borderRadius}px`,\n borderTopRightRadius: `${styling.borderRadius ?? defaults.borderRadius}px`,\n letterSpacing: '-0.01em',\n };\n\n const optionStyle: React.CSSProperties = {\n backgroundColor: styling.optionBgColor || defaults.optionBgColor,\n color: styling.optionTextColor || defaults.optionTextColor,\n padding: `${styling.optionPadding || Math.max(cardPadding * 0.7, 10)}px ${Math.max(cardPadding * 0.8, 12)}px`,\n borderRadius: `${optionRadius}px`,\n border: `1px solid ${borderColor}`,\n display: 'flex',\n alignItems: 'center',\n gap: `${Math.max(Math.round(labelSize * 0.45), 8)}px`,\n cursor: selectedOptionId ? 'default' : 'pointer',\n width: '100%',\n textAlign: 'left',\n boxSizing: 'border-box',\n transition: 'all 0.2s ease',\n boxShadow: '0 1px 2px rgba(15,23,42,0.03)',\n };\n\n const labelStyle: React.CSSProperties = {\n width: `${labelSize}px`,\n height: `${labelSize}px`,\n minWidth: `${labelSize}px`,\n borderRadius: '50%',\n backgroundColor: styling.labelBgColor || defaults.labelBgColor,\n color: styling.labelTextColor || defaults.labelTextColor,\n border: `${Math.max(Math.round(labelSize * 0.08), 1)}px solid ${styling.labelBorderColor || defaults.labelBorderColor}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontWeight: '700',\n fontSize: `${Math.max(Math.round(labelSize * 0.46), 10)}px`,\n };\n\n const bodyStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: `0 0 ${styling.borderRadius ?? defaults.borderRadius}px ${styling.borderRadius ?? defaults.borderRadius}px`,\n display: 'flex',\n flexDirection: 'column',\n gap: `${Math.max(cardPadding * 0.55, 8)}px`,\n };\n\n const handleOptionClick = (optionId: string) => {\n if (isEditing || selectedOptionId) return; // ignore multiple clicks\n setSelectedOptionId(optionId);\n onInteraction?.({\n type: 'quiz',\n quizId: data.id,\n optionId: optionId,\n stickerId: data.id\n });\n };\n\n const alphabet = ['A', 'B', 'C', 'D', 'E', 'F'];\n const options = Array.isArray(data.options) ? data.options : [];\n\n if (options.length === 0 && !isEditing) {\n console.warn('AppStorys: QuizSticker has no options!', data.id);\n }\n\n return (\n <div style={{ ...containerStyle, background: styling.backgroundColor || defaults.backgroundColor }}>\n {data.question && <h3 style={questionStyle}>{data.question}</h3>}\n <div style={{ ...bodyStyle, background: 'transparent' }}>\n {options.map((option, index) => {\n const label = (option as any).label || alphabet[index] || '•';\n const isSelected = option.id === selectedOptionId;\n const isCorrect = (option as any).isCorrect === true;\n\n let currentOptionStyle = { ...optionStyle };\n let currentLabelStyle = { ...labelStyle };\n\n if (selectedOptionId) {\n if (isCorrect) {\n currentOptionStyle.backgroundColor = styling.activeColor || defaults.activeColor;\n currentOptionStyle.borderColor = styling.activeColor || defaults.activeColor;\n currentOptionStyle.color = '#FFFFFF';\n } else if (isSelected) {\n currentOptionStyle.backgroundColor = styling.incorrectColor || defaults.incorrectColor;\n currentOptionStyle.borderColor = styling.incorrectColor || defaults.incorrectColor;\n currentOptionStyle.color = '#FFFFFF';\n }\n }\n\n return (\n <button\n key={option.id}\n style={currentOptionStyle}\n onClick={() => handleOptionClick(option.id)}\n disabled={!!selectedOptionId}\n >\n <div style={labelStyle} className=\"letter-circle\">{label}</div>\n <span style={{ fontWeight: '600', fontSize: `${optionFontSize}px` }}>{option.text}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n};","import React, { useState, useEffect } from 'react';\nimport { CountdownStickerData, StickerProps } from './types';\n\nexport const CountdownSticker: React.FC<StickerProps<CountdownStickerData>> = ({\n data,\n}) => {\n const [timeLeft, setTimeLeft] = useState({ days: '00', hours: '00', minutes: '00', seconds: '00' });\n\n useEffect(() => {\n if (!data.targetDate) return;\n\n const calculateTime = () => {\n const difference = +new Date(data.targetDate) - +new Date();\n if (difference > 0) {\n const days = Math.floor(difference / (1000 * 60 * 60 * 24));\n const hours = Math.floor((difference / (1000 * 60 * 60)) % 24);\n const minutes = Math.floor((difference / 1000 / 60) % 60);\n const seconds = Math.floor((difference / 1000) % 60);\n\n setTimeLeft({\n days: days.toString().padStart(2, '0'),\n hours: hours.toString().padStart(2, '0'),\n minutes: minutes.toString().padStart(2, '0'),\n seconds: seconds.toString().padStart(2, '0')\n });\n } else {\n setTimeLeft({ days: '00', hours: '00', minutes: '00', seconds: '00' });\n }\n };\n\n const timer = setInterval(calculateTime, 1000);\n calculateTime(); \n return () => clearInterval(timer);\n }, [data.targetDate]);\n\n const styling = data.styling || {};\n const display = data.display || { showDays: true, showHours: true, showMinutes: true, showSeconds: true };\n\n const digitSize = Number(styling.digitSize || 18);\n const safeDigitSize = !isNaN(digitSize) && digitSize > 0 ? digitSize : 18;\n const labelFontSize =\n typeof (styling as any).labelFontSize !== 'undefined'\n ? Number((styling as any).labelFontSize)\n : Math.max(10, Math.round(safeDigitSize * 0.55));\n const boxHeight = Math.max(30, Math.round(safeDigitSize * 1.8));\n const boxMinWidth = Math.max(24, Math.round(safeDigitSize * 1.3));\n const boxRadius = Math.max(6, Math.round(safeDigitSize * 0.35));\n const gridGap = Math.max(6, Math.round(safeDigitSize * 0.25));\n\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || '#FFFFFF',\n borderRadius: `${styling.borderRadius !== undefined ? styling.borderRadius : 16}px`,\n padding: `${styling.padding !== undefined ? styling.padding : 16}px`,\n boxShadow: styling.shadow || '0 10px 30px rgba(0,0,0,0.08)',\n width: '100%',\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '8px',\n border: styling.borderColor ? `1px solid ${styling.borderColor}` : 'none',\n overflow: 'hidden',\n opacity: styling.opacity ?? 1,\n };\n\n const titleStyle: React.CSSProperties = {\n color: styling.titleColor || '#000000',\n fontWeight: '700',\n fontSize: `${styling.fontSize ? styling.fontSize : 14}px`,\n width: '100%',\n textAlign: 'center',\n marginBottom: '4px'\n };\n\n const timerGridStyle: React.CSSProperties = {\n display: 'flex',\n gap: `${gridGap}px`,\n width: '100%',\n justifyContent: 'center',\n alignItems: 'center',\n flexWrap: 'nowrap'\n };\n\n const segmentStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '2px'\n };\n\n const digitGroupStyle: React.CSSProperties = {\n display: 'flex',\n gap: '2px'\n };\n\n const boxStyle: React.CSSProperties = {\n backgroundColor: styling.digitBackground || '#F1F3F5',\n borderRadius: `${boxRadius}px`,\n minWidth: `${boxMinWidth}px`,\n height: `${boxHeight}px`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: `${safeDigitSize}px`,\n fontWeight: 'bold',\n color: styling.digitColor || '#1A202C',\n padding: '0 4px',\n };\n\n const labelStyle: React.CSSProperties = {\n fontSize: `${Math.max(9, labelFontSize)}px`,\n color: styling.labelColor || '#A0AEC0',\n fontWeight: '600',\n textTransform: 'lowercase'\n };\n\n const separatorStyle: React.CSSProperties = {\n fontSize: `${Math.max(14, Math.round(safeDigitSize * 0.9))}px`,\n fontWeight: '700',\n color: styling.labelColor || '#A0AEC0',\n display: 'flex',\n alignItems: 'center',\n lineHeight: 1,\n };\n\n const renderDigitGroup = (value: string, label: string) => (\n <div style={segmentStyle}>\n <div style={digitGroupStyle}>\n {value.split('').map((digit, i) => (\n <div key={i} style={boxStyle}>{digit}</div>\n ))}\n </div>\n <span style={labelStyle}>{label}</span>\n </div>\n );\n\n // Build items based on display configuration\n const items: React.ReactNode[] = [];\n let shownCount = 0;\n\n if (display.showDays !== false) {\n items.push(renderDigitGroup(timeLeft.days, 'days'));\n shownCount++;\n }\n \n if (display.showHours !== false) {\n if (shownCount > 0) items.push(<div key=\"sep-h\" style={separatorStyle}>:</div>);\n items.push(renderDigitGroup(timeLeft.hours, 'hours'));\n shownCount++;\n }\n \n if (display.showMinutes !== false) {\n if (shownCount > 0) items.push(<div key=\"sep-m\" style={separatorStyle}>:</div>);\n items.push(renderDigitGroup(timeLeft.minutes, 'min'));\n shownCount++;\n }\n \n if (display.showSeconds !== false) {\n if (shownCount > 0) items.push(<div key=\"sep-s\" style={separatorStyle}>:</div>);\n items.push(renderDigitGroup(timeLeft.seconds, 'sec'));\n shownCount++;\n }\n\n return (\n <div style={containerStyle}>\n {data.title && <div style={titleStyle}>{data.title}</div>}\n <div style={timerGridStyle}>\n {items}\n </div>\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { PromoCodeStickerData, StickerProps } from './types';\n\nexport const PromoCodeSticker: React.FC<StickerProps<PromoCodeStickerData>> = ({\n data,\n onInteraction,\n}) => {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = () => {\n if (data.code) {\n navigator.clipboard.writeText(data.code).catch(() => { });\n setCopied(true);\n\n // Trigger interaction event via capture-event\n onInteraction?.({\n type: 'promo_code',\n value: 'copied',\n stickerId: data.id,\n code: data.code\n });\n\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n const styling = data.styling || {};\n\n // Ticket-like pill style with side notches\n const ticketPillStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || '#FFFFFF',\n padding: '12px 18px',\n borderRadius: '12px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n height: '60px',\n boxSizing: 'border-box',\n position: 'relative',\n filter: 'drop-shadow(0 8px 16px rgba(0,0,0,0.1))',\n cursor: 'pointer',\n // Using a clip-path or mask-image for professional notches\n clipPath: 'polygon(0% 0%, 0% 40%, 4% 50%, 0% 60%, 0% 100%, 100% 100%, 100% 60%, 96% 50%, 100% 40%, 100% 0%)',\n // Fallback for notch look using radial gradients\n backgroundImage: `\n radial-gradient(circle at 0px 30px, transparent 8px, white 8.5px),\n radial-gradient(circle at 100% 30px, transparent 8px, white 8.5px)\n `,\n backgroundPosition: '0 0, 100% 0',\n backgroundSize: '100% 100%',\n backgroundRepeat: 'no-repeat',\n };\n\n const percentageBoxStyle: React.CSSProperties = {\n width: '36px',\n height: '36px',\n borderRadius: '8px',\n backgroundColor: '#F1F3F5',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '18px',\n fontWeight: '800',\n color: '#2D3748',\n border: '1px solid #E2E8F0'\n };\n\n const codeStyle: React.CSSProperties = {\n fontSize: `${styling.fontSize || 18}px`,\n fontWeight: '800',\n color: '#1A202C',\n letterSpacing: '1px',\n flex: 1,\n textAlign: 'center'\n };\n\n return (\n <div style={ticketPillStyle} onClick={handleCopy}>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: '12px', flex: 1 }}>\n <div style={percentageBoxStyle}>%</div>\n <span style={codeStyle}>{data.code || 'OFFER20'}</span>\n </div>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>\n {copied && <span style={{ fontSize: '11px', color: '#10B981', fontWeight: '700' }}>Copied!</span>}\n <div style={{ padding: '8px', display: 'flex', alignItems: 'center' }}>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#4A5568\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\n </svg>\n </div>\n </div>\n\n </div>\n );\n};\n","import React from 'react';\nimport { ReactionStickerData, StickerProps } from './types';\n\nexport const ReactionSticker: React.FC<StickerProps<ReactionStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const defaults = {\n emojis: ['😍', '👍'],\n };\n\n const emojis = Array.isArray(data.emojis) ? data.emojis : (Array.isArray(defaults.emojis) ? defaults.emojis : []);\n\n const handleReaction = (emoji: string) => {\n if (isEditing) return;\n onInteraction?.({\n type: 'reaction',\n reactionId: data.id,\n emoji: emoji,\n stickerId: data.id\n });\n };\n\n const containerStyle: React.CSSProperties = {\n display: 'flex',\n gap: '20px',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n padding: '12px',\n };\n\n const bubbleStyle: React.CSSProperties = {\n backgroundColor: '#FFFFFF',\n width: '64px',\n height: '64px',\n borderRadius: '100px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n boxShadow: '0 8px 30px rgba(0,0,0,0.12)',\n fontSize: '32px',\n cursor: isEditing ? 'default' : 'pointer',\n transition: 'all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)',\n border: 'none',\n outline: 'none',\n padding: 0,\n position: 'relative',\n zIndex: 1,\n };\n\n return (\n <div style={containerStyle}>\n {emojis.map((emoji, idx) => (\n <button\n key={idx}\n style={bubbleStyle}\n onClick={() => handleReaction(emoji)}\n onMouseOver={(e) => {\n if (!isEditing) e.currentTarget.style.transform = 'scale(1.15) translateY(-4px)';\n }}\n onMouseOut={(e) => {\n if (!isEditing) e.currentTarget.style.transform = 'scale(1) translateY(0)';\n }}\n >\n {emoji}\n </button>\n ))}\n </div>\n );\n};","import React, { useState, useRef, useEffect } from 'react';\nimport { RatingStickerData, StickerProps } from './types';\n\nexport const RatingSticker: React.FC<StickerProps<RatingStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const maxRating = data.maxRating || 5;\n const currentRating = data.currentRating ?? Math.floor(maxRating / 2);\n const [val, setVal] = useState(currentRating);\n const sliderTrackRef = useRef<HTMLDivElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const defaults = {\n backgroundColor: '#FFFFFF',\n borderRadius: 36,\n padding: 24,\n titleColor: '#000000',\n titleFontSize: 24,\n sliderTrackColor: '#F3F4F6',\n sliderFillColor: '#F97316',\n emojiSize: 42,\n };\n\n const styling = data.styling || {};\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: `${styling.borderRadius ?? defaults.borderRadius}px`,\n padding: `${styling.padding ?? defaults.padding}px`,\n boxShadow: styling.shadow || '0 12px 30px rgba(0,0,0,0.08)',\n boxSizing: 'border-box',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '20px',\n cursor: 'default',\n opacity: styling.opacity ?? 1,\n };\n\n const titleStyle: React.CSSProperties = {\n color: styling.titleColor || defaults.titleColor,\n fontWeight: '900',\n fontSize: `${styling.titleFontSize || defaults.titleFontSize}px`,\n margin: '0',\n textAlign: 'center',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n width: '100%',\n };\n\n const trackStyle: React.CSSProperties = {\n width: '100%',\n height: '18px',\n backgroundColor: styling.sliderTrackColor || defaults.sliderTrackColor,\n borderRadius: '100px',\n position: 'relative',\n cursor: isEditing ? 'default' : 'pointer',\n marginTop: '24px',\n marginBottom: '8px',\n userSelect: 'none',\n };\n\n const percentage = (val / maxRating) * 100;\n\n const fillStyle: React.CSSProperties = {\n width: `${percentage}%`,\n height: '100%',\n background: styling.sliderFillColor || 'linear-gradient(90deg, #FF4582, #e11d48)',\n borderRadius: '100px',\n transition: isDragging ? 'none' : 'width 0.1s ease',\n };\n\n const emojiSize = styling.emojiSize || defaults.emojiSize;\n const thumbStyle: React.CSSProperties = {\n position: 'absolute',\n left: `calc(${percentage}% - ${emojiSize / 2}px)`,\n top: `-${emojiSize / 4}px`,\n fontSize: `${emojiSize}px`,\n userSelect: 'none',\n cursor: 'grab',\n transition: isDragging ? 'none' : 'left 0.1s ease',\n filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.2))',\n };\n\n const handleDrag = (clientX: number) => {\n if (!sliderTrackRef.current || isEditing) return;\n const rect = sliderTrackRef.current.getBoundingClientRect();\n let offsetX = clientX - rect.left;\n if (offsetX < 0) offsetX = 0;\n if (offsetX > rect.width) offsetX = rect.width;\n\n const ratio = offsetX / rect.width;\n const computedVal = Math.round(ratio * maxRating * 10) / 10; // high precision, or snap: Math.round(ratio * maxRating)\n setVal(computedVal);\n };\n\n const onMouseDown = (e: React.MouseEvent) => {\n if (isEditing) return;\n setIsDragging(true);\n handleDrag(e.clientX);\n };\n\n const onTouchStart = (e: React.TouchEvent) => {\n if (isEditing) return;\n setIsDragging(true);\n handleDrag(e.touches[0].clientX);\n };\n\n useEffect(() => {\n const onMouseMove = (e: MouseEvent) => {\n if (isDragging) handleDrag(e.clientX);\n };\n\n const onMouseUp = () => {\n if (isDragging) {\n setIsDragging(false);\n onInteraction?.({\n type: 'rating',\n ratingId: data.id,\n value: val,\n stickerId: data.id\n });\n }\n };\n\n const onTouchMove = (e: TouchEvent) => {\n if (isDragging) handleDrag(e.touches[0].clientX);\n };\n\n if (isDragging) {\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('mouseup', onMouseUp);\n window.addEventListener('touchmove', onTouchMove);\n window.addEventListener('touchend', onMouseUp);\n }\n\n return () => {\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('mouseup', onMouseUp);\n window.removeEventListener('touchmove', onTouchMove);\n window.removeEventListener('touchend', onMouseUp);\n };\n }, [isDragging, val]);\n\n return (\n <div style={containerStyle}>\n <h3 style={titleStyle}>{data.title || 'Do you like my space?'}</h3>\n <div\n ref={sliderTrackRef}\n style={trackStyle}\n onMouseDown={onMouseDown}\n onTouchStart={onTouchStart}\n >\n <div style={fillStyle} />\n <div style={thumbStyle} className=\"interactive-emoji-thumb\">\n {data.emoji || '😍'}\n </div>\n </div>\n </div>\n );\n};","import React, { useState } from 'react';\nimport { QuestionStickerData, StickerProps } from './types';\n\nexport const QuestionSticker: React.FC<StickerProps<QuestionStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const [value, setValue] = useState('');\n\n const defaults = {\n backgroundColor: '#FFFFFF',\n borderRadius: 16,\n padding: 16,\n promptColor: '#111111',\n inputBgColor: '#FFFFFF',\n borderColor: '#EFEFEF',\n textColor: '#333333',\n placeholderColor: '#A0AEC0',\n };\n\n const styling = data.styling || {};\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: `${styling.borderRadius ?? defaults.borderRadius}px`,\n padding: `${styling.padding ?? defaults.padding}px`,\n boxShadow: styling.shadow || '0 8px 24px rgba(0,0,0,0.06)',\n boxSizing: 'border-box',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '12px',\n border: `1px solid ${styling.borderColor || '#F0F0F0'}`,\n };\n\n const questionStyle: React.CSSProperties = {\n color: styling.promptColor || defaults.promptColor,\n fontWeight: '700',\n fontSize: `${styling.fontSize ? styling.fontSize + 2 : 16}px`,\n textAlign: 'center',\n marginBottom: '2px',\n width: '100%',\n };\n\n const inputContainerStyle: React.CSSProperties = {\n width: '100%',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n };\n\n const inputStyle: React.CSSProperties = {\n backgroundColor: styling.inputBgColor || '#F1F3F5',\n border: 'none',\n borderRadius: '30px',\n padding: '14px 45px 14px 20px',\n width: '100%',\n boxSizing: 'border-box',\n color: styling.inputTextColor || '#1A202C',\n fontSize: `${styling.fontSize || 14}px`,\n outline: 'none',\n textAlign: 'left',\n cursor: isEditing ? 'default' : 'text',\n boxShadow: 'inset 0 1px 2px rgba(0,0,0,0.05)',\n };\n\n const sendButtonStyle: React.CSSProperties = {\n position: 'absolute',\n right: '10px',\n background: styling.submitBackground || '#FE6B35',\n color: 'white',\n border: 'none',\n borderRadius: '50%',\n width: '32px',\n height: '32px',\n display: value.length > 0 ? 'flex' : 'none',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'transform 0.2s',\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (isEditing) return;\n setValue(e.target.value);\n };\n\n const handleSend = () => {\n if (isEditing || !value.trim()) return;\n onInteraction?.({\n type: 'question',\n questionId: data.id,\n value: value.trim(),\n stickerId: data.id\n });\n setValue(''); // Clear after send\n };\n\n return (\n <div style={containerStyle}>\n <div style={questionStyle}>{data.question || 'Ask me anything'}</div>\n <div style={inputContainerStyle}>\n <input\n type=\"text\"\n value={value}\n placeholder={data.placeholder || 'Type your answer...'}\n style={inputStyle}\n disabled={isEditing}\n onChange={handleChange}\n onKeyDown={(e) => e.key === 'Enter' && handleSend()}\n />\n <button style={sendButtonStyle} onClick={handleSend}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </div>\n </div>\n );\n};","import React, { useState } from 'react';\nimport { ImageQuizStickerData, StickerProps } from './types';\n\nexport const ImageQuizSticker: React.FC<StickerProps<ImageQuizStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const [selectedOptionId, setSelectedOptionId] = useState<string | null>(null);\n\n const defaults = {\n backgroundColor: '#FFFFFF',\n borderRadius: 20,\n padding: 16,\n questionTextColor: '#111111',\n optionBgColor: '#F7FAFC',\n optionTextColor: '#2D3748',\n borderColor: '#E2E8F0',\n activeColor: '#10B981', // Success Green\n incorrectColor: '#EF4444', // Error Red\n };\n\n const styling = (data as any).styling || {};\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: `${styling.borderRadius ?? defaults.borderRadius}px`,\n padding: `${styling.padding ?? defaults.padding}px`,\n boxShadow: styling.shadow || '0 8px 24px rgba(0,0,0,0.06)',\n boxSizing: 'border-box',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n border: styling.borderColor ? `1px solid ${styling.borderColor}` : 'none',\n };\n\n const questionStyle: React.CSSProperties = {\n color: styling.questionTextColor || defaults.questionTextColor,\n fontWeight: '800',\n fontSize: `${styling.fontSize ? styling.fontSize + 2 : 16}px`,\n margin: '0 0 4px 0',\n textAlign: 'left',\n };\n\n const gridStyle: React.CSSProperties = {\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: '12px',\n width: '100%',\n };\n\n const optionStyle: React.CSSProperties = {\n backgroundColor: styling.optionBgColor || defaults.optionBgColor,\n color: styling.optionTextColor || defaults.optionTextColor,\n borderRadius: '16px',\n border: `2px solid ${styling.borderColor || defaults.borderColor}`,\n cursor: selectedOptionId ? 'default' : 'pointer',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n padding: '8px',\n boxSizing: 'border-box',\n transition: 'all 0.2s ease',\n overflow: 'hidden',\n };\n\n const handleOptionClick = (optionId: string) => {\n if (isEditing || selectedOptionId) return;\n setSelectedOptionId(optionId);\n onInteraction?.({\n type: 'image',\n quizId: data.id,\n optionId: optionId,\n stickerId: data.id\n });\n };\n\n const placeholderImg = \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Crect width='100%25' height='100%25' fill='%23EDF2F7'/%3E%3Cpath d='M30 40 L40 30 L50 40 L60 30 L70 40 V60 H30 Z' fill='%23A0AEC0'/%3E%3Ccircle cx='40' cy='45' r='5' fill='%23FFFFFF'/%3E%3C/svg%3E\";\n\n const options = Array.isArray(data.options) ? data.options : [];\n\n return (\n <div style={containerStyle}>\n {data.question && <h3 style={questionStyle}>{data.question}</h3>}\n <div style={gridStyle}>\n {options.map((option) => {\n const isSelected = option.id === selectedOptionId;\n const isCorrect = (option as any).isCorrect === true;\n\n let currentOptionStyle = { ...optionStyle };\n if (selectedOptionId) {\n if (isCorrect) {\n currentOptionStyle.borderColor = styling.activeColor || defaults.activeColor;\n currentOptionStyle.backgroundColor = 'rgba(16, 185, 129, 0.05)';\n } else if (isSelected) {\n currentOptionStyle.borderColor = styling.incorrectColor || defaults.incorrectColor;\n currentOptionStyle.backgroundColor = 'rgba(239, 68, 68, 0.05)';\n }\n }\n\n return (\n <button\n key={option.id}\n style={currentOptionStyle}\n onClick={() => handleOptionClick(option.id)}\n disabled={!!selectedOptionId}\n onMouseOver={(e) => {\n if (!isEditing && !selectedOptionId) e.currentTarget.style.transform = 'translateY(-2px)';\n }}\n onMouseOut={(e) => {\n if (!isEditing && !selectedOptionId) e.currentTarget.style.transform = 'translateY(0)';\n }}\n >\n <div style={{\n width: '100%',\n aspectRatio: '1',\n borderRadius: '12px',\n overflow: 'hidden',\n backgroundColor: '#EDF2F7',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: '8px',\n position: 'relative'\n }}>\n <img\n src={option.image || placeholderImg}\n alt={option.text}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n\n {selectedOptionId && (\n <div style={{\n position: 'absolute',\n top: '6px',\n right: '6px',\n width: '24px',\n height: '24px',\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: isCorrect ? defaults.activeColor : isSelected ? defaults.incorrectColor : '#A0AEC0',\n color: '#FFFFFF',\n fontSize: '12px',\n fontWeight: 'bold'\n }}>\n {isCorrect ? '✓' : isSelected ? '✕' : ''}\n </div>\n )}\n </div>\n <span style={{\n fontWeight: '600',\n fontSize: `${styling.optionFontSize || 13}px`,\n color: selectedOptionId && isCorrect ? defaults.activeColor : defaults.optionTextColor,\n width: '100%',\n textAlign: 'center',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis'\n }}>{option.text}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n};","import React, { useState } from 'react';\nimport { ShopableStickerData, StickerProps, ShopableProduct } from './types';\nimport { ShopableModal } from './ShopableModal';\n\nexport const ShopableSticker: React.FC<StickerProps<ShopableStickerData>> = ({\n data,\n onInteraction,\n isEditing,\n}) => {\n const { products, styling } = data;\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [selectedProduct, setSelectedProduct] = useState<ShopableProduct | null>(null);\n\n const handleProductClick = (e: React.MouseEvent, product: ShopableProduct) => {\n e.stopPropagation();\n if (isEditing) return;\n\n if (data.shopableType === 'product') {\n setSelectedProduct(product);\n setIsModalOpen(true);\n if (onInteraction) {\n onInteraction({\n type: 'product_view',\n stickerId: data.id,\n productId: product.productId || product.id,\n value: product.title,\n });\n }\n return;\n }\n\n // Static Redirection Logic\n let url = product.redirectUrl || product.url;\n if (url && !url.startsWith('http') && !url.startsWith('//')) {\n url = 'https://' + url;\n }\n\n if (onInteraction) {\n onInteraction({\n type: 'buy',\n stickerId: data.id,\n productId: product.id,\n value: product.title,\n selected_option: url,\n });\n }\n\n if (url) {\n try {\n window.open(url, '_blank', 'noopener,noreferrer');\n } catch (error) {\n console.error('AppStorys: Redirect failed', error);\n window.location.href = url;\n }\n }\n };\n\n const handleAddToCart = (item: any) => {\n if (onInteraction) {\n onInteraction({\n type: 'add_to_cart',\n stickerId: data.id,\n productId: item.productId,\n value: item.title,\n selected_option: JSON.stringify({\n size: item.selectedSize,\n color: item.selectedColor,\n quantity: item.quantity\n }),\n });\n }\n };\n\n const containerStyle: React.CSSProperties = {\n width: '100%',\n height: '100%',\n display: 'flex',\n gap: '12px',\n overflowX: 'auto',\n padding: '0 1px',\n scrollSnapType: 'x mandatory',\n scrollbarWidth: 'none',\n msOverflowStyle: 'none',\n WebkitOverflowScrolling: 'touch',\n pointerEvents: 'auto',\n };\n\n const cardStyle: React.CSSProperties = {\n flex: '0 0 auto',\n width: '100%',\n backgroundColor: styling?.cardBackground || '#ffffff',\n borderRadius: styling?.cardBorderRadius !== undefined\n ? `${styling.cardBorderRadius}px`\n : (styling?.cardRadiusPercent !== undefined ? `${styling.cardRadiusPercent}%` : '12px'),\n overflow: 'hidden',\n boxShadow: styling?.shadow || '0 -2px 12px rgba(0,0,0,0.12)',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n padding: '8px 12px',\n position: 'relative',\n scrollSnapAlign: 'center',\n transition: 'transform 0.2s ease',\n cursor: 'pointer',\n boxSizing: 'border-box',\n pointerEvents: 'auto',\n opacity: styling?.opacity ?? 1,\n marginBottom: 0,\n };\n\n const imageContainerStyle: React.CSSProperties = {\n width: '64px',\n height: '64px',\n borderRadius: styling?.imageRadius !== undefined ? `${styling.imageRadius}px` : '12px',\n overflow: 'hidden',\n backgroundColor: '#f5f5f5',\n flexShrink: 0,\n };\n\n const contentContainerStyle: React.CSSProperties = {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n padding: '0 12px',\n minWidth: 0,\n };\n\n return (\n <>\n <div style={containerStyle} className=\"shopable-container\">\n <style>{`\n .shopable-container::-webkit-scrollbar { display: none; }\n .shopable-card:active { transform: scale(0.98); }\n `}</style>\n {products.map((product) => (\n <div\n key={product.id}\n style={cardStyle}\n className=\"shopable-card\"\n onClick={(e) => handleProductClick(e, product)}\n >\n {/* Product Image */}\n <div style={imageContainerStyle}>\n <img src={product.image} alt={product.title} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n </div>\n\n {/* Product Details */}\n <div style={contentContainerStyle}>\n <span style={{\n color: styling?.titleColor || styling?.textColor || '#1a1b2e',\n fontSize: styling?.titleFontSize ? `${styling.titleFontSize}px` : '15px',\n fontWeight: styling?.titleFontWeight || '700',\n lineHeight: '1.2',\n display: 'block',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n marginBottom: '1px'\n }}>\n {product.title}\n </span>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: '6px', flexWrap: 'wrap' }}>\n <span style={{\n color: styling?.priceColor || styling?.textColor || '#1a1b2e',\n fontSize: styling?.priceFontSize ? `${styling.priceFontSize}px` : '18px',\n fontWeight: styling?.priceFontWeight || '800',\n display: 'block'\n }}>\n {product.price}\n </span>\n {product.oldPrice && (\n <span style={{\n color: styling?.mrpColor || '#8b8b98',\n fontSize: styling?.mrpFontSize ? `${styling.mrpFontSize}px` : '12px',\n fontWeight: styling?.mrpFontWeight || '500',\n textDecoration: 'line-through'\n }}>\n {product.oldPrice}\n </span>\n )}\n </div>\n </div>\n\n {/* Buy Button */}\n <div style={{\n backgroundColor: styling?.buttonBackground || '#000000',\n color: styling?.buttonTextColor || '#ffffff',\n fontSize: styling?.buttonFontSize ? `${styling.buttonFontSize}px` : '14px',\n fontWeight: '700',\n padding: '10px 18px',\n borderRadius: styling?.buttonBorderRadius !== undefined ? `${styling.buttonBorderRadius}px` : '100px',\n textAlign: 'center',\n flexShrink: 0,\n whiteSpace: 'nowrap'\n }}>\n Buy Now\n </div>\n </div>\n ))}\n </div>\n\n {/* Premium Product Details Modal */}\n {isModalOpen && selectedProduct && (\n <ShopableModal\n product={selectedProduct}\n styling={styling}\n onClose={() => setIsModalOpen(false)}\n onAddToCart={handleAddToCart}\n />\n )}\n </>\n );\n};\n\n","import React, { useState, useEffect } from 'react';\nimport { ShopableProduct } from './types';\n\ninterface ShopableModalProps {\n product: ShopableProduct;\n styling: any;\n onClose: () => void;\n onAddToCart: (item: any) => void;\n}\n\nexport const ShopableModal: React.FC<ShopableModalProps> = ({\n product,\n styling,\n onClose,\n onAddToCart,\n}) => {\n const [selectedSize, setSelectedSize] = useState<string>('');\n const [selectedColorIndex, setSelectedColorIndex] = useState<number>(0);\n const [quantity, setQuantity] = useState<number>(1);\n const [isSuccess, setIsSuccess] = useState<boolean>(false);\n const [isVisible, setIsVisible] = useState<boolean>(false);\n\n const attributes = product.attributes || {};\n const colors = attributes.colors || [];\n const sizes = attributes.sizes || [];\n const imageUrls = attributes.imageUrls || [product.image];\n const description = attributes.description || '';\n\n useEffect(() => {\n if (sizes.length > 0) setSelectedSize(sizes[0]);\n setIsVisible(true);\n }, [sizes]);\n\n const handleAddToCart = () => {\n const item = {\n productId: product.productId || product.id,\n title: product.title,\n selectedSize,\n selectedColor: colors[selectedColorIndex]?.name,\n quantity,\n price: product.price,\n };\n onAddToCart(item);\n \n // Handle Redirection\n let url = product.redirectUrl || product.url;\n if (url) {\n if (!url.startsWith('http') && !url.startsWith('//')) {\n url = 'https://' + url;\n }\n try {\n window.open(url, '_blank', 'noopener,noreferrer');\n } catch (error) {\n console.error('AppStorys: Redirect failed', error);\n }\n }\n \n setIsSuccess(true);\n };\n\n const handleDismiss = () => {\n setIsVisible(false);\n setTimeout(onClose, 400); // Match transiton duration\n };\n\n // Base Colors from styling\n const buttonBg = styling?.buttonBackground || '#000000';\n const buttonFg = styling?.buttonTextColor || '#ffffff';\n const titleFg = styling?.titleColor || styling?.textColor || '#1a1a2e';\n const priceFg = styling?.priceColor || styling?.textColor || '#1a1a2e';\n const mrpFg = styling?.mrpColor || '#8b8b98';\n \n const titleWeight = styling?.titleFontWeight || '600';\n const priceWeight = styling?.priceFontWeight || '700';\n const mrpWeight = styling?.mrpFontWeight || '500';\n\n if (isSuccess) {\n return (\n <div className=\"appstorys-shopable-success-overlay\" style={overlayStyle}>\n <div className=\"appstorys-shopable-backdrop\" style={backdropStyle} onClick={handleDismiss} />\n <div className=\"appstorys-shopable-sheet\" style={{\n ...sheetStyle,\n height: 'auto',\n minHeight: '310px',\n animation: 'appstorys-slide-up 0.4s cubic-bezier(0.2, 0.8, 0.2, 1)',\n }}>\n <div style={dragHandleStyle} onClick={handleDismiss} />\n <div style={{ padding: '0 20px 24px', textAlign: 'center' }}>\n <div style={{ \n backgroundColor: '#F3F4F6', \n borderRadius: '20px', \n padding: '22px', \n marginTop: '16px',\n display: 'flex', \n flexDirection: 'column', \n alignItems: 'center',\n gap: '12px'\n }}>\n <h3 style={{ margin: 0, fontSize: '16px', fontWeight: '600', lineHeight: '1.4' }}>\n Added to your bag<br />successfully\n </h3>\n {/* Smile Arc Icon SVG */}\n <svg width=\"44\" height=\"26\" viewBox=\"0 0 44 26\" fill=\"none\">\n <path d=\"M4 4C4 4 11 22 22 22C33 22 40 4 40 4\" stroke=\"currentColor\" strokeWidth=\"2.8\" strokeLinecap=\"round\" />\n </svg>\n </div>\n\n <div style={{ marginTop: '24px', display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <button \n onClick={handleDismiss}\n style={{ \n ...buttonBaseStyle, \n backgroundColor: '#000000', \n color: '#ffffff',\n padding: '17px',\n fontSize: '16px',\n fontWeight: '600'\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px' }}>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z\"/><path d=\"M3 6h18\"/><path d=\"M16 10a4 4 0 0 1-8 0\"/>\n </svg>\n Go to checkout\n </div>\n </button>\n <button \n onClick={handleDismiss}\n style={{ \n ...buttonBaseStyle, \n backgroundColor: 'transparent', \n color: '#000000',\n border: '1px solid rgba(0,0,0,0.1)',\n padding: '15px',\n fontSize: '16px'\n }}\n >\n Continue with stories\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div className={`appstorys-shopable-overlay ${isVisible ? 'visible' : ''}`} style={overlayStyle}>\n <div className=\"appstorys-shopable-backdrop\" style={backdropStyle} onClick={handleDismiss} />\n <div className=\"appstorys-shopable-sheet\" style={{\n ...sheetStyle,\n transform: isVisible ? 'translateY(0)' : 'translateY(100%)',\n opacity: isVisible ? 1 : 0,\n }}>\n {/* Header */}\n <div style={headerStyle}>\n <div style={dragHandleStyle} onClick={handleDismiss} />\n <button style={closeButtonStyle} onClick={handleDismiss}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n\n <div style={scrollContentStyle}>\n {/* Gallery Section */}\n <div style={gallerySectionStyle}>\n {imageUrls.map((url, i) => (\n <div key={i} style={{\n minWidth: imageUrls.length > 1 ? '85%' : '100%',\n aspectRatio: '1.2 / 1',\n maxHeight: '240px',\n borderRadius: '16px',\n overflow: 'hidden',\n backgroundColor: '#F9FAFB'\n }}>\n <img src={url} alt={product.title} style={{ width: '100%', height: '100%', objectFit: 'contain' }} />\n </div>\n ))}\n </div>\n\n <div style={{ padding: '0 20px 20px' }}>\n <h2 style={{ \n margin: '16px 0 4px', \n fontSize: styling?.titleFontSize ? `${styling.titleFontSize}px` : '20px', \n fontWeight: titleWeight, \n color: titleFg,\n lineHeight: '1.2' \n }}>\n {product.title}\n </h2>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: '8px', marginBottom: '16px' }}>\n <span style={{ \n fontSize: styling?.priceFontSize ? `${styling.priceFontSize}px` : '18px', \n fontWeight: priceWeight, \n color: priceFg \n }}>\n {product.price}\n </span>\n {product.oldPrice && (\n <span style={{ \n fontSize: styling?.mrpFontSize ? `${styling.mrpFontSize}px` : '14px', \n color: mrpFg, \n textDecoration: 'line-through',\n fontWeight: mrpWeight\n }}>\n {product.oldPrice}\n </span>\n )}\n </div>\n {/* Color Section */}\n {colors.length > 0 && (\n <div style={sectionStyle}>\n <div style={sectionTitleStyle}>COLOR</div>\n <div style={{ display: 'flex', gap: '14px', marginTop: '12px' }}>\n {colors.map((color, i) => (\n <div key={color.id} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '5px' }}>\n <button\n onClick={() => setSelectedColorIndex(i)}\n style={{\n width: '36px', height: '36px', borderRadius: '50%', border: 'none',\n backgroundColor: color.hex || '#gray',\n position: 'relative', cursor: 'pointer',\n boxShadow: selectedColorIndex === i ? '0 0 0 2px #fff, 0 0 0 4px #000' : 'none',\n transition: 'all 0.2s ease'\n }}\n />\n <div style={{ \n width: '5px', height: '5px', borderRadius: '50%', \n backgroundColor: selectedColorIndex === i ? '#000' : 'transparent',\n transition: 'all 0.2s ease'\n }} />\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Size Section */}\n {sizes.length > 0 && (\n <div style={sectionStyle}>\n <div style={sectionTitleStyle}>SIZE</div>\n <div style={{ display: 'flex', gap: '10px', marginTop: '12px', flexWrap: 'wrap' }}>\n {sizes.map((size) => (\n <div key={size} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }}>\n <button\n onClick={() => setSelectedSize(size)}\n style={{\n minWidth: '42px', height: '42px', borderRadius: '50%',\n backgroundColor: 'transparent',\n border: `1px solid ${selectedSize === size ? '#000' : 'rgba(0,0,0,0.1)'}`,\n color: selectedSize === size ? '#000' : '#8b8b98',\n fontSize: '13px', fontWeight: '500', cursor: 'pointer',\n transition: 'all 0.2s ease'\n }}\n >\n {size}\n </button>\n <div style={{ \n width: '5px', height: '5px', borderRadius: '50%', \n backgroundColor: selectedSize === size ? '#000' : 'transparent',\n transition: 'all 0.2s ease'\n }} />\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Description */}\n {description && (\n <div style={sectionStyle}>\n <div style={sectionTitleStyle}>DESCRIPTION</div>\n <p style={{ \n margin: '8px 0 0', fontSize: '14px', lineHeight: '1.5', color: '#8b8b98',\n wordBreak: 'break-word'\n }}>\n {description}\n </p>\n </div>\n )}\n </div>\n </div>\n\n {/* Sticky Bottom Bar */}\n <div style={bottomBarStyle}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1px', minWidth: '75px' }}>\n <div style={{ fontSize: '15px', fontWeight: priceWeight, color: priceFg }}>{product.price}</div>\n {product.oldPrice && (\n <div style={{ fontSize: '11px', color: mrpFg, textDecoration: 'line-through', fontWeight: mrpWeight }}>{product.oldPrice}</div>\n )}\n </div>\n\n <div style={stepperStyle}>\n <button style={stepperBtnStyle} onClick={() => setQuantity(q => Math.max(1, q - 1))}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" /></svg>\n </button>\n <span style={{ fontSize: '16px', fontWeight: '700', minWidth: '18px', textAlign: 'center', color: '#000000', display: 'inline-block' }}>{quantity}</span>\n <button style={stepperBtnStyle} onClick={() => setQuantity(q => q + 1)}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" /><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" /></svg>\n </button>\n </div>\n\n {(() => {\n const availability = attributes.availability?.toLowerCase() || '';\n const isOutOfStock = availability === 'out of stock' || availability === 'out-of-stock';\n \n return (\n <button \n onClick={isOutOfStock ? undefined : handleAddToCart} \n disabled={isOutOfStock}\n style={{\n ...buttonBaseStyle,\n backgroundColor: isOutOfStock ? '#F3F4F6' : buttonBg,\n color: isOutOfStock ? '#9CA3AF' : buttonFg,\n flex: '1',\n padding: '12px 8px',\n gap: '6px',\n cursor: isOutOfStock ? 'not-allowed' : 'pointer',\n opacity: isOutOfStock ? 0.8 : 1\n }}\n >\n {!isOutOfStock && (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <path d=\"M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z\"/><path d=\"M3 6h18\"/><path d=\"M16 10a4 4 0 0 1-8 0\"/>\n </svg>\n )}\n <span style={{ fontSize: '12px', fontWeight: '700', whiteSpace: 'nowrap' }}>\n {isOutOfStock ? 'Out of Stock' : 'Add to cart'}\n </span>\n </button>\n );\n })()}\n </div>\n </div>\n\n <style>{`\n @keyframes appstorys-slide-up {\n from { transform: translateY(100%); }\n to { transform: translateY(0); }\n }\n .appstorys-shopable-overlay {\n position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000;\n display: flex; align-items: flex-end; justify-content: center;\n visibility: hidden;\n }\n .appstorys-shopable-overlay.visible {\n visibility: visible;\n }\n `}</style>\n </div>\n );\n};\n\n// Styles\nconst overlayStyle: React.CSSProperties = {\n position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10000,\n display: 'flex', alignItems: 'flex-end', justifyContent: 'center', pointerEvents: 'auto',\n fontFamily: \"'Inter', system-ui, -apple-system, sans-serif\",\n width: '100%', height: '100%',\n boxSizing: 'border-box'\n};\n\nconst backdropStyle: React.CSSProperties = {\n position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.45)',\n cursor: 'pointer'\n};\n\nconst sheetStyle: React.CSSProperties = {\n position: 'relative', width: '100%', maxWidth: '500px',\n backgroundColor: '#fff', borderTopLeftRadius: '28px', borderTopRightRadius: '28px',\n borderBottomLeftRadius: 0, borderBottomRightRadius: 0,\n maxHeight: '60vh', display: 'flex', flexDirection: 'column', margin: 0,\n transition: 'transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.4s ease',\n boxShadow: '0 -8px 24px rgba(0,0,0,0.15)', overflow: 'hidden',\n boxSizing: 'border-box'\n};\n\nconst headerStyle: React.CSSProperties = {\n height: '48px', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', flexShrink: 0\n};\n\nconst dragHandleStyle: React.CSSProperties = {\n width: '36px', height: '5px', backgroundColor: 'rgba(0,0,0,0.1)', borderRadius: '3px', cursor: 'pointer'\n};\n\nconst closeButtonStyle: React.CSSProperties = {\n position: 'absolute', right: '18px', top: '16px', border: 'none',\n width: '28px', height: '28px', borderRadius: '50%', backgroundColor: '#F3F4F6',\n display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#666', cursor: 'pointer'\n};\n\nconst scrollContentStyle: React.CSSProperties = {\n flex: 1, overflowY: 'auto', WebkitOverflowScrolling: 'touch'\n};\n\nconst gallerySectionStyle: React.CSSProperties = {\n padding: '0 16px 20px', display: 'flex', gap: '8px', overflowX: 'auto', scrollSnapType: 'x mandatory'\n};\n\nconst sectionStyle: React.CSSProperties = {\n marginTop: '20px'\n};\n\nconst sectionTitleStyle: React.CSSProperties = {\n fontSize: '11px', fontWeight: '600', color: 'rgba(0,0,0,0.5)', letterSpacing: '1.4px'\n};\n\nconst bottomBarStyle: React.CSSProperties = {\n padding: '12px 16px calc(20px + env(safe-area-inset-bottom, 0px))',\n borderTop: '1px solid rgba(0,0,0,0.05)', display: 'flex', alignItems: 'center', gap: '8px',\n backgroundColor: '#fff', boxShadow: '0 -4px 12px rgba(0,0,0,0.06)', zIndex: 10,\n boxSizing: 'border-box'\n};\n\nconst stepperStyle: React.CSSProperties = {\n display: 'flex', alignItems: 'center', gap: '10px', padding: '10px 12px',\n borderRadius: '100px', border: '1px solid rgba(0,0,0,0.1)'\n};\n\nconst stepperBtnStyle: React.CSSProperties = {\n border: 'none', backgroundColor: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center'\n};\n\nconst buttonBaseStyle: React.CSSProperties = {\n border: 'none', borderRadius: '100px', cursor: 'pointer',\n display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.2s ease'\n};\n","import React from 'react';\nimport { resolveFontFamily } from '../../../core/fontManager';\nimport { StickerData } from './types';\nimport { PollSticker } from './PollSticker';\nimport { QuizSticker } from './QuizSticker';\nimport { CountdownSticker } from './CountdownSticker';\nimport { PromoCodeSticker } from './PromoCodeSticker';\nimport { ReactionSticker } from './ReactionSticker';\nimport { RatingSticker } from './RatingSticker';\nimport { QuestionSticker } from './QuestionSticker';\nimport { ImageQuizSticker } from './ImageQuizSticker';\nimport { ShopableSticker } from './ShopableSticker';\n\ninterface InteractiveItemProps {\n data: StickerData;\n onInteraction?: (data: any) => void;\n isEditing?: boolean;\n}\n\nexport const InteractiveItem: React.FC<InteractiveItemProps> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const defaults = {\n x: 10,\n y: 15,\n width: 80, // percentage\n rotation: 0,\n };\n\n const x = data.x ?? defaults.x;\n const y = data.y ?? defaults.y;\n const width = data.width ?? defaults.width;\n const rotation = data.rotation ?? defaults.rotation;\n\n const wrapperStyle: React.CSSProperties = {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: `${width}%`,\n height: (data as any).height ? `${(data as any).height}%` : 'auto',\n transform: `rotate(${rotation}deg)`,\n zIndex: 10,\n transformOrigin: 'center center',\n boxSizing: 'border-box',\n cursor: isEditing ? 'move' : 'default',\n pointerEvents: 'auto',\n };\n\n const animationStyle: React.CSSProperties = {\n width: '100%',\n height: '100%',\n animation: (data as any).styling?.animation,\n animationFillMode: 'forwards',\n };\n\n const renderSticker = () => {\n const stickerType = (data as any).type;\n switch (stickerType) {\n case 'poll':\n return <PollSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'quiz':\n return <QuizSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'rating':\n return <RatingSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'question':\n case 'input':\n return <QuestionSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'image_quiz':\n return <ImageQuizSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'countdown':\n return <CountdownSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'promo_code':\n case 'promo':\n return <PromoCodeSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'reaction':\n return <ReactionSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'buy':\n case 'shopable':\n return <ShopableSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'image':\n return <img src={(data as any).url} alt=\"static overlay\" style={{ width: '100%', height: '100%', objectFit: 'fill' }} />;\n case 'text': {\n const textStyle = (data as any).styling || {};\n return (\n <span style={{\n color: textStyle.color || '#000000',\n fontSize: `${textStyle.fontSize || 14}px`,\n fontFamily: resolveFontFamily(textStyle.fontFamily) || 'Arial',\n fontStyle: textStyle.fontStyle || 'normal',\n fontWeight: textStyle.fontWeight || 'normal',\n wordBreak: 'break-word',\n display: 'inline-block',\n }}>\n {(data as any).text}\n </span>\n );\n }\n default:\n return (\n <div style={{ padding: '10px', background: 'white', color: 'black', borderRadius: '4px' }}>\n Unsupported interactive element: {(data as any).type}\n </div>\n );\n }\n };\n\n return (\n <div style={wrapperStyle} className={`interactive-item-z${(data as any).z ?? 0}`}>\n <div style={animationStyle}>\n {renderSticker()}\n </div>\n </div>\n );\n};","export const parseBackground = (bg: any): string | undefined => {\n if (!bg) return undefined;\n if (typeof bg === 'string') return bg;\n\n // Some payloads send colors directly without a nested `color` object.\n // Examples: { solid: '#ffffff' } or { value: '#ffffff' }\n if (typeof bg === 'object') {\n if (typeof bg.solid === 'string' && bg.solid) return bg.solid;\n if (typeof bg.value === 'string' && bg.value) return bg.value;\n }\n\n const color = bg.color || {};\n if (color.type === 'gradient' && color.gradient) {\n const { direction = 'right', from, to, stops = [] } = color.gradient;\n const dirMap: Record<string, string> = {\n right: 'to right',\n left: 'to left',\n top: 'to top',\n bottom: 'to bottom',\n };\n const cssDir = dirMap[direction] || direction;\n\n if (stops.length > 0) {\n const stopStr = stops\n .map((s: any) => `${s.color} ${Math.round((s.offset || 0) * 100)}%`)\n .join(', ');\n return `linear-gradient(${cssDir}, ${stopStr})`;\n }\n return `linear-gradient(${cssDir}, ${from}, ${to})`;\n }\n\n return color.solid || color.value || undefined;\n};\n\nexport const getAnimationStyles = (anim: any): string | undefined => {\n if (!anim || anim.type === 'none') return undefined;\n const type = String(anim.type).toLowerCase();\n const duration = anim.duration || 0.6;\n\n if (type === 'fade') return `appstorys-fade-in ${duration}s ease-out forwards`;\n if (type === 'classic') return `appstorys-classic-in ${duration}s cubic-bezier(0.34, 1.56, 0.64, 1) forwards`;\n if (type === 'rotate') return `appstorys-rotate-in ${duration}s ease-out forwards`;\n if (type === 'bounce') return `appstorys-bounce-in ${duration + 0.2}s cubic-bezier(0.68, -0.6, 0.32, 1.6) forwards`;\n\n return undefined;\n};","import React from 'react';\nimport { StickerData } from './types';\nimport { InteractiveItem } from './InteractiveItem';\nimport { parseBackground, getAnimationStyles } from '../../../utils/styleUtils';\nimport { resolveFontFamily } from '../../../core/fontManager';\n\ninterface InteractiveOverlayProps {\n content?: any; // Pass fully packed backend content structure\n onInteraction?: (data: any) => void;\n isEditing?: boolean;\n elapsedTime?: number;\n}\n\nconst getEditorSource = (item: any, content: any): 'studio' | 'dashboard' => {\n const editorSource =\n item?.styling?.editorSource ||\n item?.styling?.meta?.editorSource ||\n item?.style?.editorSource ||\n content?.editorSource ||\n content?.meta?.editorSource;\n\n return editorSource === 'studio' || editorSource === 'editor' ? 'studio' : 'dashboard';\n};\n\nconst normalizeOptions = (options: any, isCorrect?: string | boolean | null): any[] => {\n if (Array.isArray(options)) {\n return options.map((option, index) => {\n const optionId = option?.id || option?.key || option?.value || `option_${index + 1}`;\n const optionLabel = option?.label || option?.optionLabel;\n const optionText =\n typeof option === 'string'\n ? option\n : option?.text || option?.title || optionLabel || '';\n\n return {\n id: String(optionId),\n text: optionText,\n image: option?.image || option?.imageUrl || '',\n label: optionLabel,\n isCorrect: option?.isCorrect === true || String(optionId) === String(isCorrect),\n };\n });\n }\n\n if (options && typeof options === 'object') {\n return Object.entries(options).map(([key, value]) => {\n const optionValue = typeof value === 'string' ? { text: value } : ((value as any) || {});\n return {\n id: key,\n text: optionValue.text || optionValue.title || optionValue.label || '',\n image: optionValue.image || optionValue.imageUrl || '',\n label: optionValue.label,\n isCorrect: key === String(isCorrect),\n };\n });\n }\n\n return [];\n};\n\nconst normalizeReactionEmojis = (data: any): string[] => {\n if (Array.isArray(data?.emojis)) {\n return data.emojis.map((emoji: any) => String(emoji));\n }\n\n return normalizeOptions(data?.options).map((option) => option.text).filter(Boolean);\n};\n\nconst normalizeElementType = (type: any): string => {\n const normalized = String(type || '').toLowerCase();\n if (normalized === 'quizz') return 'quiz';\n if (normalized === 'rate') return 'rating';\n if (normalized === 'input' || normalized === 'ask_question' || normalized === 'askquestion') return 'question';\n if (normalized === 'promo' || normalized === 'promocode') return 'promo_code';\n return normalized;\n};\n\n// Helper to combine endDate and endTime into ISO string\nconst getCountdownTarget = (data: any) => {\n if (data.targetDate) return data.targetDate;\n if (!data.endDate) return new Date(Date.now() + 86400000).toISOString();\n\n try {\n const combined = `${data.endDate}${data.endTime ? `T${data.endTime}` : ''}`;\n return new Date(combined).toISOString();\n } catch (e) {\n return data.endDate || new Date(Date.now() + 86400000).toISOString();\n }\n};\n\nexport const InteractiveOverlay: React.FC<InteractiveOverlayProps> = ({\n content = {},\n onInteraction,\n isEditing = false,\n elapsedTime = 0,\n}) => {\n const canva = content?.canva || { height: 1920, width: 1080 };\n const canvaWidth = canva?.width || 1080;\n const canvaHeight = canva?.height || 1920;\n const scale_factor = 0.352; // standard width desktop factor scaling 380/1080\n\n const elements = content?.elements || [];\n const images = content?.image || [];\n const texts = content?.text || [];\n const interactions = content?.interactions || [];\n const shopableContent = (Array.isArray(content?.shopable) && content.shopable.length > 0)\n ? content.shopable\n : (Array.isArray(content?.styling?.shopable) ? content.styling.shopable : []);\n const shopableIds = new Set(shopableContent.map((s: any) => s.id));\n const shopableStyling = (content?.styling?.shopable || []).concat(shopableContent.map((s: any) => s.styling).filter(Boolean));\n\n if (elements.length === 0 && images.length === 0 && texts.length === 0 && interactions.length === 0 && shopableContent.length === 0) return null;\n\n // 1. Map interactive elements\n const displayElements = elements\n .filter((item: any) => !shopableIds.has(item.id))\n .map((item: any): StickerData => {\n const custom = item.custom || {};\n const data = custom.data || {};\n const style = custom.style || item.styling || {};\n const source = getEditorSource(item, content);\n\n const position = item.position || item.postion || {};\n const size = item.size || {};\n\n // Safe coordinate conversion with bulletproof Number parsing.\n // Studio often sends `{ position: {x,y}, size: {width,height} }` instead of direct `x/y/width`.\n const rawX = item.x !== undefined ? item.x : position.x;\n const rawY = item.y !== undefined ? item.y : position.y;\n const rawW = item.width !== undefined ? item.width : size.width;\n\n const x_percent = rawX !== undefined && !isNaN(Number(rawX)) ? (Number(rawX) / canvaWidth) * 100 : 10;\n const y_percent = rawY !== undefined && !isNaN(Number(rawY)) ? (Number(rawY) / canvaHeight) * 100 : 15;\n const width_percent = rawW !== undefined && !isNaN(Number(rawW)) ? (Number(rawW) / canvaWidth) * 100 : 80;\n\n const baseData = {\n id: item.id || Math.random().toString(),\n type: normalizeElementType(custom.interactiveType || item.widgetType || item.type || 'unknown'),\n x: x_percent,\n y: y_percent,\n width: width_percent,\n rotation: style.rotation ?? item.rotation ?? 0,\n z: item.z ?? item.position?.z ?? style.z ?? 10,\n duration: data.duration || style.duration,\n styling: {\n backgroundColor: parseBackground(style.background || style.containerBgColor || style.backgroundColor),\n borderRadius: (style.borderRadius !== undefined ? (style.borderRadius >= 100 ? 999 : style.borderRadius * scale_factor) : (style.radius !== undefined ? (style.radius >= 100 ? 999 : style.radius * scale_factor) : 0)),\n padding: (style.containerPadding !== undefined ? style.containerPadding : (style.padding !== undefined ? style.padding : 0)) * scale_factor,\n shadow: style.shadow,\n fontSize: style.questionFontSize ? style.questionFontSize * scale_factor : undefined,\n opacity: style.opacity ?? 1,\n animation: getAnimationStyles(style.animation),\n },\n };\n\n if (baseData.type === 'poll') {\n const normalizedOpts = normalizeOptions(data.options);\n return {\n ...baseData,\n type: 'poll',\n question: data.question || data.title || 'Poll Question',\n options: normalizedOpts,\n layout: data.layout || { type: 'vertical', columns: 1 },\n styling: {\n ...baseData.styling,\n headerColor: style.headerBgColor || style.background,\n headerTextColor: style.questionColor || style.questionTextColor || (style.question?.color),\n optionBgColor: style.optionBgColor || style.options?.background || '#1A1A1A',\n optionTextColor: style.optionTextColor || style.options?.textColor || '#ffffff',\n optionBorderRadius: style.optionBorderRadius !== undefined ? style.optionBorderRadius * scale_factor : (style.options?.radius !== undefined ? style.options?.radius * scale_factor : 0),\n },\n } as any;\n }\n\n if (baseData.type === 'quiz') {\n const colors = style.colors || {};\n const normalizedOpts = normalizeOptions(data.options, data.isCorrect);\n return {\n ...baseData,\n type: 'quiz',\n question: data.question || data.title || 'Quiz Question',\n options: normalizedOpts,\n showExplanation: data.showExplanation,\n url: data.url,\n styling: {\n ...baseData.styling,\n backgroundColor: style.background || style.containerBgColor || style.backgroundColor || 'transparent',\n questionTextColor: style.questionColor || colors.questionColor || style.question?.color || style.colors?.questionText || '#FF0000',\n questionBgColor: style.questionBgColor || colors.questionBackground || style.question?.background || style.colors?.questionBg || '#3BFF00',\n optionBgColor: style.optionBgColor || colors.optionBackground || style.options?.background || style.colors?.optionBg || '#C100FF',\n optionTextColor: style.optionTextColor || colors.optionTextColor || style.options?.textColor || style.colors?.optionText || '#ffffff',\n borderColor: style.borderColor || 'transparent',\n activeColor: style.correctColor || colors.correctColor || style.correctBorderColor || '#00D9FF',\n incorrectColor: style.incorrectColor || colors.incorrectColor || '#ef4444',\n optionBorderRadius: (style.optionRadius !== undefined ? (style.optionRadius >= 100 ? 999 : style.optionRadius * scale_factor) : (style.optionBorderRadius !== undefined ? (style.optionBorderRadius >= 100 ? 999 : style.optionBorderRadius * scale_factor) : 100)),\n optionFontSize: (style.optionFontSize ? style.optionFontSize : (style.typography?.optionSize ? style.typography?.optionSize : (style.options?.fontSize ? style.options?.fontSize : 16))) * scale_factor * 1.25,\n },\n } as any;\n }\n\n if (baseData.type === 'rating') {\n return {\n ...baseData,\n type: 'rating',\n title: data.title || 'Do you like my space?',\n emoji: data.emoji || '😍',\n currentRating: data.currentRating,\n maxRating: data.maxRating,\n styling: {\n ...baseData.styling,\n sliderTrackColor: style.colors?.sliderTrack || style.sliderTrack,\n sliderFillColor: style.colors?.sliderFill || style.sliderFill,\n emojiSize: style.emojiSize ? style.emojiSize * 0.45 : undefined,\n titleColor: style.colors?.titleColor || style.titleColor,\n titleFontSize: style.titleFontSize ? style.titleFontSize * 0.4 : undefined,\n },\n } as any;\n }\n\n if (baseData.type === 'question') {\n return {\n ...baseData,\n type: 'question',\n question: data.question || data.title || 'Ask me a question',\n placeholder: data.placeholder || 'Type your answer...',\n styling: {\n ...baseData.styling,\n promptColor: style.questionColor || style.textColor,\n inputBgColor: style.inputBgColor,\n inputTextColor: style.inputTextColor,\n submitBackground: style.submitBackground,\n },\n } as any;\n }\n\n if (baseData.type === 'image_quiz' || baseData.type === 'imageQuiz' || (custom.interactiveType || '').toLowerCase() === 'media_quiz') {\n return {\n ...baseData,\n type: 'image_quiz',\n question: data.question || data.title || 'Image Quiz',\n options: normalizeOptions(data.options || []),\n styling: {\n ...baseData.styling,\n questionTextColor: style.questionColor,\n activeColor: style.correctColor || style.correctBorderColor,\n incorrectColor: style.incorrectColor,\n imageRadius: style.imageRadius ? style.imageRadius * scale_factor : undefined,\n },\n } as any;\n }\n\n if (baseData.type === 'countdown') {\n return {\n ...baseData,\n type: 'countdown',\n title: data.title || 'Ends in...',\n targetDate: getCountdownTarget(data),\n styling: {\n ...baseData.styling,\n borderColor: style.borderColor,\n digitBackground: style.digitBackground,\n digitColor: style.digitColor,\n digitSize: style.digitSize ? style.digitSize * scale_factor : undefined,\n labelColor: style.labelColor,\n titleColor: style.titleColor,\n },\n display: data.display,\n } as any;\n }\n\n if (baseData.type === 'promo_code') {\n return {\n ...baseData,\n type: 'promo_code',\n code: data.code || 'CODE20',\n styling: {\n ...baseData.styling,\n borderColor: style.borderColor,\n },\n } as any;\n }\n\n if (baseData.type === 'reaction' || baseData.type === 'emoji_reaction') {\n const emojisArray = normalizeReactionEmojis(data);\n\n return {\n ...baseData,\n type: 'reaction',\n emojis: emojisArray.length > 0 ? emojisArray : ['😍', '👍'],\n source,\n } as any;\n }\n\n return baseData as any;\n });\n\n // 1b. Map interactions (new structure supported for story interaction types)\n const displayInteractions = (content?.interactions || [])\n .filter((item: any) => !shopableIds.has(item.id))\n .map((item: any): StickerData => {\n const data = item.config || {};\n const style = item.styling || item.style || {}; // Map both structures\n const source = getEditorSource(item, content);\n\n const typeStr = normalizeElementType(item.interaction_type || item.type);\n\n // Support position and size structures framed sizing absolute layout setups\n const position = style.position || item.position || {};\n const size = style.size || item.size || {};\n\n // Support both direct dimensions and nested size/position structures scales framing\n const posX = position.x ?? item.x;\n const posY = position.y ?? item.y;\n const sizeW = size.width ?? item.width;\n const sizeH = size.height ?? item.height;\n\n // Fall back to defaults (10, 15, 80) if no dimension is provided or parsed to NaN\n const x_percent = posX !== undefined && !isNaN(Number(posX)) ? (Number(posX) / canvaWidth) * 100 : 10;\n const y_percent = posY !== undefined && !isNaN(Number(posY)) ? (Number(posY) / canvaHeight) * 100 : 15;\n const width_percent = sizeW !== undefined && !isNaN(Number(sizeW)) ? (Number(sizeW) / canvaWidth) * 100 : 80;\n const height_percent = sizeH !== undefined && !isNaN(Number(sizeH)) ? (Number(sizeH) / canvaHeight) * 100 : undefined;\n\n const baseData = {\n id: item.id || Math.random().toString(),\n type: typeStr,\n x: x_percent,\n y: y_percent,\n width: width_percent,\n height: height_percent,\n rotation: style.rotation ?? item.rotation ?? 0,\n z: item.z ?? item.position?.z ?? style.z ?? 10,\n source,\n duration: data.duration || style.duration,\n styling: {\n backgroundColor: parseBackground(style.background || style.containerBgColor || style.backgroundColor),\n borderRadius: (style.borderRadius !== undefined ? (style.borderRadius >= 100 ? 999 : style.borderRadius * scale_factor) : (style.radius !== undefined ? (style.radius >= 100 ? 999 : style.radius * scale_factor) : 0)),\n padding: (style.containerPadding !== undefined ? style.containerPadding : (style.padding !== undefined ? style.padding : 0)) * scale_factor,\n shadow: style.shadow,\n fontSize: style.questionSize ? style.questionSize * scale_factor : (style.questionFontSize ? style.questionFontSize * scale_factor : undefined),\n opacity: style.opacity ?? 1,\n animation: getAnimationStyles(style.animation),\n },\n };\n\n if (baseData.type === 'rating' || baseData.type === 'rate') {\n const colors = style.colors || {};\n return {\n ...baseData,\n type: 'rating',\n title: data.title || 'Do you like my space?',\n emoji: data.emoji || '😍',\n currentRating: data.currentRating,\n maxRating: data.maxRating,\n styling: {\n ...baseData.styling,\n sliderTrackColor: colors.sliderTrack || style.colors?.sliderTrack || style.colors?.sliderTrack,\n sliderFillColor: colors.sliderFill || style.colors?.sliderFill || style.sliderFill,\n emojiSize: style.emojiSize ? style.emojiSize * 0.45 : undefined,\n titleColor: colors.titleColor || style.colors?.titleColor || style.titleColor,\n titleFontSize: style.titleFontSize ? style.titleFontSize * 0.4 : undefined,\n },\n } as any;\n }\n\n if (baseData.type === 'poll') {\n const normalizedOpts = normalizeOptions(data.options);\n return {\n ...baseData,\n type: 'poll',\n question: data.question || data.title || 'Poll Question',\n options: normalizedOpts,\n layout: data.layout || { type: 'vertical', columns: 1 },\n styling: {\n ...baseData.styling,\n headerColor: style.headerBgColor || style.background,\n headerTextColor: style.questionColor || style.questionTextColor || (style.question?.color),\n optionBgColor: style.optionBgColor || style.options?.background || '#1A1A1A',\n optionTextColor: style.optionTextColor || style.options?.textColor || '#ffffff',\n optionBorderRadius: style.optionBorderRadius !== undefined ? style.optionBorderRadius * scale_factor : (style.options?.radius !== undefined ? style.options?.radius * scale_factor : 0),\n },\n } as any;\n }\n\n if (baseData.type === 'quiz') {\n const colors = style.colors || {};\n const normalizedOpts = normalizeOptions(data.options, data.isCorrect);\n return {\n ...baseData,\n type: 'quiz',\n question: data.question || data.title || 'Quiz Question',\n options: normalizedOpts,\n showExplanation: data.showExplanation,\n url: data.url,\n styling: {\n ...baseData.styling,\n backgroundColor: style.background || style.containerBgColor || style.backgroundColor || 'transparent',\n questionTextColor: style.questionColor || colors.questionColor || style.question?.color || style.colors?.questionText || '#FF0000',\n questionBgColor: style.questionBgColor || colors.questionBackground || style.question?.background || style.colors?.questionBg || '#3BFF00',\n optionBgColor: style.optionBgColor || colors.optionBackground || style.options?.background || style.colors?.optionBg || '#C100FF',\n optionTextColor: style.optionTextColor || colors.optionTextColor || style.options?.textColor || style.colors?.optionText || '#ffffff',\n borderColor: style.borderColor || 'transparent',\n activeColor: style.correctColor || colors.correctColor || style.correctBorderColor || '#00D9FF',\n incorrectColor: style.incorrectColor || colors.incorrectColor || '#ef4444',\n optionBorderRadius: (style.optionRadius !== undefined ? (style.optionRadius >= 100 ? 999 : style.optionRadius * scale_factor) : (style.optionBorderRadius !== undefined ? (style.optionBorderRadius >= 100 ? 999 : style.optionBorderRadius * scale_factor) : 100)),\n optionFontSize: (style.optionFontSize ? style.optionFontSize : (style.typography?.optionSize ? style.typography?.optionSize : (style.options?.fontSize ? style.options?.fontSize : 16))) * scale_factor * 1.25,\n },\n } as any;\n }\n\n if (baseData.type === 'question') {\n return {\n ...baseData,\n type: 'question',\n question: data.question || data.title || 'Ask me a question',\n placeholder: data.placeholder || 'Type your answer...',\n styling: {\n ...baseData.styling,\n promptColor: style.questionColor || style.promptColor || style.textColor,\n inputBgColor: style.inputBackground || style.inputBgColor,\n inputTextColor: style.inputTextColor,\n submitBackground: style.submitBackground,\n },\n } as any;\n }\n\n if (baseData.type === 'image_quiz' || baseData.type === 'imageQuiz' || typeStr === 'media_quiz') {\n return {\n ...baseData,\n type: 'image_quiz',\n question: data.question || data.title || 'Image Quiz',\n options: normalizeOptions(data.options || []),\n styling: {\n ...baseData.styling,\n questionTextColor: style.questionColor,\n activeColor: style.correctColor || style.correctBorderColor,\n incorrectColor: style.incorrectColor,\n imageRadius: style.imageRadius ? style.imageRadius * scale_factor : undefined,\n },\n } as any;\n }\n\n if (baseData.type === 'countdown') {\n return {\n ...baseData,\n type: 'countdown',\n title: data.title || 'Ends in...',\n targetDate: getCountdownTarget(data),\n styling: {\n ...baseData.styling,\n borderColor: style.borderColor,\n digitBackground: style.digitBackground,\n digitColor: style.digitColor,\n // Countdown digit/font sizes appear to be authored for final display already; scaling makes them too small.\n digitSize: (style.digitSize || style.fontSize) ? Number(style.digitSize || style.fontSize) : undefined,\n labelColor: style.labelColor,\n titleColor: style.titleColor,\n // Provide an optional label font size if backend uses a single fontSize.\n labelFontSize: style.labelFontSize ? Number(style.labelFontSize) : undefined,\n },\n display: data.display || item.display,\n } as any;\n }\n\n if (baseData.type === 'promo_code') {\n return {\n ...baseData,\n type: 'promo_code',\n code: data.code || 'CODE20',\n styling: {\n ...baseData.styling,\n borderColor: style.borderColor,\n },\n } as any;\n }\n\n if (baseData.type === 'reaction' || baseData.type === 'emoji_reaction') {\n const emojisArray = normalizeReactionEmojis(data);\n\n return {\n ...baseData,\n type: 'reaction',\n emojis: emojisArray.length > 0 ? emojisArray : ['😍', '👍'],\n } as any;\n }\n\n return baseData as any;\n });\n\n // 1c. Map shopable elements\n const displayShopable = shopableContent.map((item: any) => {\n const matchedStyling =\n shopableStyling.find((s: any) => String(s?.id) === String(item?.id)) ||\n shopableStyling.find((s: any) => s?.id === undefined) ||\n {};\n\n // Some payloads send styling directly on each shopable item instead of item.styling/content.styling.shopable\n const inlineStyling = {\n position: item?.position,\n size: item?.size,\n rotation: item?.rotation,\n z: item?.z,\n background: item?.background,\n cardBackground: item?.cardBackground,\n cardBorderRadius: item?.cardBorderRadius,\n cardRadiusPercent: item?.cardRadiusPercent,\n transparent: item?.transparent,\n textColor: item?.textColor,\n buttonBackground: item?.buttonBackground,\n buttonTextColor: item?.buttonTextColor,\n buttonFontSize: item?.buttonFontSize,\n buttonBorderRadius: item?.buttonBorderRadius,\n titleColor: item?.titleColor,\n titleFontSize: item?.titleFontSize,\n titleFontWeight: item?.titleFontWeight,\n priceColor: item?.priceColor,\n priceFontSize: item?.priceFontSize,\n priceFontWeight: item?.priceFontWeight,\n mrpColor: item?.mrpColor,\n mrpFontSize: item?.mrpFontSize,\n mrpFontWeight: item?.mrpFontWeight,\n imageRadius: item?.imageRadius,\n opacity: item?.opacity,\n animation: item?.animation,\n };\n\n const styling = {\n ...matchedStyling,\n ...(item?.styling || {}),\n ...Object.fromEntries(Object.entries(inlineStyling).filter(([, value]) => value !== undefined)),\n };\n\n const position = styling.position || {};\n const size = styling.size || {};\n\n // Radius values coming from Studio are based on the 1080x1920-ish canvas units.\n // Converting `cardRadiusPercent` directly to CSS '%' makes the card overly round.\n // Prefer a scaled px value.\n const rawCardBorderRadius = styling.cardBorderRadius !== undefined ? Number(styling.cardBorderRadius) : undefined;\n const rawCardRadiusPercent = styling.cardRadiusPercent !== undefined ? Number(styling.cardRadiusPercent) : undefined;\n const rawHeight = size.height !== undefined ? Number(size.height) : undefined;\n const radiusFromPercent =\n rawCardBorderRadius === undefined && rawCardRadiusPercent !== undefined && rawHeight !== undefined\n ? (Math.max(0, Math.min(100, rawCardRadiusPercent)) / 100) * (rawHeight / 2)\n : undefined;\n\n const resolvedCardBorderRadius = (rawCardBorderRadius ?? radiusFromPercent);\n const resolvedCardBorderRadiusPx =\n resolvedCardBorderRadius !== undefined && !isNaN(resolvedCardBorderRadius)\n ? resolvedCardBorderRadius * scale_factor\n : undefined;\n\n // Standard coordinate conversion - using backend data directly as requested\n const x_percent = position.x !== undefined ? (Number(position.x) / canvaWidth) * 100 : 0;\n const width_percent = size.width !== undefined ? (Number(size.width) / canvaWidth) * 100 : 100;\n const height_percent = size.height !== undefined ? (Number(size.height) / canvaHeight) * 100 : undefined;\n\n // Default to the bottom if position is missing, otherwise use provided Y\n let y_percent = position.y !== undefined ? (Number(position.y) / canvaHeight) * 100 : (height_percent ? 100 - height_percent - 2.5 : 85);\n\n // Tighten the bottom-snapping logic to remove the \"space\" as requested\n if (height_percent && (y_percent + height_percent) > 96) {\n y_percent = Math.max(0, 100 - height_percent);\n } else if (y_percent > 75 && height_percent && (y_percent + height_percent) > 91) {\n y_percent = Math.max(0, 100 - height_percent - 1);\n }\n\n const isProductType = Array.isArray(item.product) && item.product.length > 0;\n const itemsSource = isProductType ? item.product : (item.static || []);\n\n return {\n id: item.id || Math.random().toString(),\n type: 'buy',\n shopableType: isProductType ? 'product' : 'static',\n x: x_percent,\n y: y_percent,\n width: width_percent,\n height: height_percent,\n rotation: styling.rotation ?? 0,\n z: styling.z ?? 10,\n products: itemsSource.map((p: any) => {\n // Handle potential nesting in productData key as seen in latest backend JSON\n const sourceData = p.productData || p || {};\n const attr = sourceData.attributes || p.attributes || {};\n\n // If sales_price exists in attributes, it's the current price, and p.price is the old price\n const currentPrice = attr.sales_price || sourceData.price || attr.price || p.price;\n const oldPrice = attr.sales_price ? (sourceData.price || attr.price || p.price) : (sourceData.oldPrice || p.oldPrice);\n\n // Robust attribute mapping - ensure all metadata is preserved for the modal\n const colorVal = sourceData.color || attr.color || p.color;\n const sizeVal = sourceData.size || attr.size || p.size;\n \n let colors = attr.colors || [];\n if (colors.length === 0 && colorVal) {\n colors = [{ id: colorVal, hex: colorVal, name: colorVal }];\n }\n\n let sizes = attr.sizes || [];\n if (sizes.length === 0 && sizeVal) {\n sizes = typeof sizeVal === 'string' ? sizeVal.split(',').map(s => s.trim()) : [sizeVal];\n }\n\n const consolidatedAttributes = {\n description: sourceData.description || attr.description || p.description,\n color: colorVal,\n size: sizeVal,\n colors: colors,\n sizes: sizes,\n imageUrls: attr.imageUrls || [attr.image_link || sourceData.imageUrl || sourceData.image || p.imageUrl || p.image || p.url].filter(Boolean),\n availability: sourceData.availability || attr.availability || p.availability,\n tags: sourceData.tags || attr.tags || p.tags,\n ...attr,\n };\n\n return {\n id: sourceData.productId || sourceData.id || p.productId || p.id || Math.random().toString(),\n image: attr.image_link || sourceData.imageUrl || sourceData.image || p.imageUrl || p.image || p.url,\n url: sourceData.link || sourceData.url || p.link || p.url || p.redirectUrl,\n title: sourceData.title || p.title,\n price: currentPrice,\n oldPrice: oldPrice,\n redirectUrl: p.redirectUrl || sourceData.link || p.link || p.url,\n svg: sourceData.svg || p.svg,\n productId: sourceData.productId || p.productId,\n collectionId: sourceData.collectionId || p.collectionId,\n feedId: sourceData.feedId || p.feedId,\n attributes: consolidatedAttributes,\n };\n }),\n styling: {\n backgroundColor: parseBackground(styling.background),\n cardBackground: parseBackground(styling.cardBackground) || parseBackground(styling.background) || '#ffffff',\n cardBorderRadius: resolvedCardBorderRadiusPx !== undefined ? resolvedCardBorderRadiusPx : 10,\n // Keep for backward compatibility, but UI should prefer px radius above.\n cardRadiusPercent: rawCardRadiusPercent,\n transparent: styling.transparent === true,\n textColor: styling.textColor || '#ffffff',\n buttonBackground: styling.buttonBackground || '#000000',\n buttonTextColor: styling.buttonTextColor || '#ffffff',\n buttonFontSize: styling.buttonFontSize || 12,\n buttonBorderRadius: styling.buttonBorderRadius !== undefined ? styling.buttonBorderRadius : 100,\n titleColor: styling.titleColor || styling.textColor || '#1a1a2e',\n titleFontSize: styling.titleFontSize || 14,\n titleFontWeight: styling.titleFontWeight ? String(styling.titleFontWeight) : '600',\n priceColor: styling.priceColor || styling.textColor || '#1a1a2e',\n priceFontSize: styling.priceFontSize || 16,\n priceFontWeight: styling.priceFontWeight ? String(styling.priceFontWeight) : '700',\n mrpColor: styling.mrpColor || '#8b8b98',\n mrpFontSize: styling.mrpFontSize || 12,\n mrpFontWeight: styling.mrpFontWeight ? String(styling.mrpFontWeight) : '500',\n imageRadius: styling.imageRadius !== undefined ? Number(styling.imageRadius) * scale_factor : 10,\n animation: getAnimationStyles(styling.animation),\n },\n };\n });\n\n // 2. Map static images\n const displayImages = images.map((img: any) => {\n const position = img.position || img.postion || { x: 0, y: 0 };\n return {\n id: img.id || Math.random().toString(),\n type: 'image',\n x: (position.x / canvaWidth) * 100,\n y: (position.y / canvaHeight) * 100,\n width: (img.width / canvaWidth) * 100,\n height: img.height ? (img.height / canvaHeight) * 100 : undefined,\n url: img.link || img.url,\n z: img.z ?? 0,\n };\n });\n\n // 3. Map static text\n const displayText = texts.map((txt: any) => {\n const position = txt.position || { x: 0, y: 0 };\n const font = txt.font || {};\n return {\n id: txt.id || Math.random().toString(),\n type: 'text',\n x: (position.x / canvaWidth) * 100,\n y: (position.y / canvaHeight) * 100,\n width: txt.size?.width ? (txt.size.width / canvaWidth) * 100 : undefined,\n text: txt.value,\n z: txt.z ?? 1,\n styling: {\n color: txt.color || '#000000',\n fontSize: font.fontSize ? font.fontSize * scale_factor : undefined,\n fontFamily: resolveFontFamily(font.fontFamily),\n fontStyle: font.fontStyle,\n fontWeight: font.fontWeight,\n },\n };\n });\n\n // Combine & Sort by Z index index layer mappings stack\n const displayItems = [...displayElements, ...displayInteractions, ...displayShopable, ...displayImages, ...displayText]\n .filter((item: any) => {\n if (!item.duration) return true;\n const { start, end } = item.duration;\n return elapsedTime >= start && elapsedTime <= end;\n })\n .sort((a: any, b: any) => (a.z ?? 0) - (b.z ?? 0));\n\n const overlayStyle: React.CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n pointerEvents: 'none',\n overflow: 'hidden',\n };\n\n return (\n <div style={overlayStyle}>\n <style>{`\n @keyframes appstorys-fade-in {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n @keyframes appstorys-classic-in {\n 0% { opacity: 0; transform: scale(0.7); }\n 70% { opacity: 1; transform: scale(1.05); }\n 100% { opacity: 1; transform: scale(1); }\n }\n @keyframes appstorys-rotate-in {\n from { opacity: 0; transform: rotate(-20deg) scale(0.5); }\n to { opacity: 1; transform: rotate(0deg) scale(1); }\n }\n @keyframes appstorys-bounce-in {\n 0% { opacity: 0; transform: scale(0.3); }\n 50% { opacity: 1; transform: scale(1.1); }\n 70% { opacity: 1; transform: scale(0.95); }\n 100% { opacity: 1; transform: scale(1); }\n }\n `}</style>\n {displayItems.map((item: any) => {\n if (!item || typeof item !== 'object') return null;\n const typeStr = (item.type || '').toLowerCase();\n if (!typeStr) return null; // Ignore invalid element items\n\n return (\n <InteractiveItem\n key={item.id}\n data={item as StickerData}\n onInteraction={onInteraction}\n isEditing={isEditing}\n />\n );\n })}\n </div>\n );\n};","import React, { useState } from 'react';\n\ninterface PlayPauseButtonProps {\n isPaused: boolean;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n style?: React.CSSProperties;\n size?: number;\n}\n\nexport const PlayPauseButton: React.FC<PlayPauseButtonProps> = ({ \n isPaused, \n onPress, \n style, \n size = 36 \n}) => {\n const [isHovered, setIsHovered] = useState(false);\n\n return (\n <button\n onClick={onPress}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n background: isHovered ? 'rgba(255, 255, 255, 0.15)' : 'rgba(255, 255, 255, 0.08)',\n border: isHovered ? '1px solid white' : '1px solid rgba(255, 255, 255, 0.1)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '10px',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n padding: 0,\n outline: 'none',\n ...style,\n }}\n >\n {isPaused ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\">\n <path d=\"M5 3.867v16.266c0 .54.58.88 1.05.61l14.133-8.133c.46-.27.46-.94 0-1.21L6.05 3.257C5.58 2.987 5 3.327 5 3.867z\" />\n </svg>\n ) : (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n )}\n </button>\n );\n};\n\nexport default PlayPauseButton;\n","import React from 'react';\nimport { StorySlideCta } from '../../../types';\nimport { personalizeText } from '../../../core/personalization';\nimport { resolveFontFamily } from '../../../core/fontManager';\n\ninterface CtaProps {\n cta?: StorySlideCta | null;\n buttonText?: string;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\nconst mapAlignment = (alignment?: string) => {\n switch (alignment) {\n case \"left\": return \"flex-start\";\n case \"right\": return \"flex-end\";\n default: return \"center\";\n }\n};\n\nconst Cta: React.FC<CtaProps> = ({ cta, buttonText, onPress }) => {\n if (!cta || !buttonText || buttonText.trim() === '') {\n return null;\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n bottom: cta?.margin?.bottom,\n left: cta?.margin?.left,\n right: cta?.margin?.right,\n display: 'flex',\n justifyContent: mapAlignment(cta?.container?.alignment),\n width: '100%',\n pointerEvents: 'none',\n boxSizing: 'border-box',\n zIndex: 10,\n }}\n >\n <button\n style={{\n backgroundColor: cta?.container?.backgroundColor || '#F7921C',\n borderColor: cta?.container?.borderColor || 'transparent',\n borderWidth: cta?.container?.borderWidth ?? 0,\n borderStyle: cta?.container?.borderWidth ? 'solid' : 'none',\n borderTopRightRadius: cta?.cornerRadius?.topRight,\n borderTopLeftRadius: cta?.cornerRadius?.topLeft,\n borderBottomRightRadius: cta?.cornerRadius?.bottomRight,\n borderBottomLeftRadius: cta?.cornerRadius?.bottomLeft,\n height: cta?.container?.height || 42,\n width: cta?.container?.ctaFullWidth\n ? \"100%\"\n : cta?.container?.ctaWidth || \"auto\",\n justifyContent: \"center\",\n alignItems: \"center\",\n display: 'flex',\n cursor: 'pointer',\n outline: 'none',\n pointerEvents: 'auto',\n padding: '0 12px',\n boxSizing: 'border-box',\n }}\n onClick={onPress}\n >\n <span\n style={{\n color: cta?.text?.color || '#ffffff',\n fontSize: cta?.text?.fontSize || 14,\n fontFamily: resolveFontFamily(cta?.text?.fontFamily),\n fontWeight: cta?.text?.fontDecoration?.includes(\"bold\") ? \"bold\" : \"normal\",\n fontStyle: cta?.text?.fontDecoration?.includes(\"italic\") ? \"italic\" : \"normal\",\n textDecorationLine: cta?.text?.fontDecoration?.includes(\"underline\") ? \"underline\" : \"none\",\n textAlign: \"center\",\n }}\n >\n {personalizeText(buttonText)}\n </span>\n </button>\n </div>\n );\n};\n\nexport default Cta;","import React from 'react';\n\nexport interface CrossButtonConfig {\n color: {\n cross: string;\n fill: string;\n stroke: string;\n };\n enabled: boolean;\n image: string;\n margin: {\n bottom: number;\n left: number;\n right: number;\n top: number;\n };\n selectedStyle?: string;\n size: number;\n}\n\ninterface CrossButtonProps {\n config?: CrossButtonConfig | null;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n style?: React.CSSProperties;\n ignoreSizeAndMargin?: boolean;\n}\n\nconst CrossButton: React.FC<CrossButtonProps> = ({ config, onPress, style, ignoreSizeAndMargin = false }) => {\n if (!config || !config.enabled) {\n return null;\n }\n\n const {\n size: backendSize = 18,\n margin,\n color,\n image,\n selectedStyle,\n } = config;\n\n const size = ignoreSizeAndMargin ? 40 : backendSize;\n\n const containerStyle: React.CSSProperties = {\n marginTop: ignoreSizeAndMargin ? 0 : (margin?.top ?? 0),\n marginBottom: ignoreSizeAndMargin ? 0 : (margin?.bottom ?? 0),\n marginLeft: ignoreSizeAndMargin ? 0 : (margin?.left ?? 0),\n marginRight: ignoreSizeAndMargin ? 0 : (margin?.right ?? 0),\n width: size,\n height: size,\n backgroundColor: color?.fill || 'transparent',\n borderColor: color?.stroke || 'transparent',\n borderWidth: size * 0.05,\n borderRadius: '50%',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 1000000,\n position: 'absolute',\n display: 'flex',\n padding: 0,\n cursor: 'pointer',\n outline: 'none',\n borderStyle: color?.stroke ? 'solid' : 'none',\n ...style,\n };\n\n const renderDefaultIcon = () => {\n const stroke = color?.cross || '#ffffff';\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n </svg>\n );\n };\n\n return (\n <button\n onClick={onPress}\n style={containerStyle}\n title={selectedStyle || ''}\n >\n {image && image.trim() !== '' ? (\n <img\n src={image}\n style={{ width: size, height: size, objectFit: 'contain' }}\n alt=\"close\"\n />\n ) : (\n renderDefaultIcon()\n )}\n </button>\n );\n};\n\nexport default CrossButton;","import React from 'react';\nimport { PipButtonConfig } from '../../Pip/types';\n\ninterface SoundButtonProps {\n config: PipButtonConfig | null;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n style?: React.CSSProperties;\n ignoreSizeAndMargin?: boolean;\n enabled?: boolean;\n type: 'mute' | 'unmute';\n}\n\nexport const SoundButton: React.FC<SoundButtonProps> = ({\n config,\n onPress,\n ignoreSizeAndMargin = false,\n enabled,\n style,\n type,\n}) => {\n if (!config || !enabled) {\n return null;\n }\n\n const {\n size: backendSize = 18,\n margin,\n color,\n image,\n selectedStyle,\n } = config;\n\n const size = ignoreSizeAndMargin ? 40 : backendSize;\n\n // Safe margin access with correct defaults\n const marginTop = ignoreSizeAndMargin ? 0 : (margin?.top ?? 0);\n const marginBottom = ignoreSizeAndMargin ? 0 : (margin?.bottom ?? 0);\n const marginLeft = ignoreSizeAndMargin ? 0 : (margin?.left ?? 0);\n const marginRight = ignoreSizeAndMargin ? 0 : (margin?.right ?? 0);\n\n const containerStyle: React.CSSProperties = {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n width: size,\n height: size,\n backgroundColor: color?.fill || 'transparent',\n borderColor: color?.stroke || 'transparent',\n borderWidth: size * 0.05,\n borderRadius: '50%',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 1000000,\n display: 'flex',\n ...(ignoreSizeAndMargin\n ? {}\n : {\n marginTop: config.margin?.top ?? 0,\n marginRight: config.margin?.right ?? 0,\n marginBottom: config.margin?.bottom ?? 0,\n marginLeft: config.margin?.left ?? 0,\n }),\n ...style,\n };\n\n const renderDefaultIcon = () => {\n const stroke = color?.cross || '#ffffff';\n if (type === 'mute') {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polygon points=\"4,10 8,10 13,6 13,18 8,14 4,14\" fill=\"none\" stroke={stroke} strokeWidth=\"2.2\" strokeLinejoin=\"round\" />\n <line x1=\"16\" y1=\"8\" x2=\"21\" y2=\"16\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <line x1=\"21\" y1=\"8\" x2=\"16\" y2=\"16\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n </svg>\n );\n } else {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polygon points=\"4,10 8,10 13,6 13,18 8,14 4,14\" fill=\"none\" stroke={stroke} strokeWidth=\"2.2\" strokeLinejoin=\"round\" />\n <path d=\"M16 10 Q18 12 16 14\" fill=\"none\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <path d=\"M18 8 Q22 12 18 16\" fill=\"none\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n };\n\n return (\n <button\n onClick={onPress}\n style={{\n ...containerStyle,\n border: containerStyle.borderColor ? `${containerStyle.borderWidth}px solid ${containerStyle.borderColor as string}` : 'none',\n padding: 0,\n cursor: 'pointer',\n outline: 'none',\n }}\n title={selectedStyle || ''}\n >\n {image && image.trim() !== '' ? (\n <img\n src={image}\n style={{ width: size, height: size, objectFit: 'contain' }}\n alt={type}\n />\n ) : (\n renderDefaultIcon()\n )}\n </button>\n );\n};","import React from 'react';\n\nexport interface ShareButtonConfig {\n color: {\n cross: string;\n fill: string;\n stroke: string;\n };\n enabled: boolean;\n image: string;\n margin: {\n bottom: number;\n left: number;\n right: number;\n top: number;\n };\n selectedStyle?: string;\n size: number;\n}\n\ninterface ShareButtonProps {\n config: ShareButtonConfig | null;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n style?: React.CSSProperties;\n ignoreSizeAndMargin?: boolean;\n}\n\nconst ShareButton: React.FC<ShareButtonProps> = ({ config, onPress, ignoreSizeAndMargin = false, style }) => {\n if (!config || config.enabled === false) {\n return null;\n }\n\n const {\n size: backendSize = 18,\n margin,\n color,\n image,\n selectedStyle,\n } = config;\n\n const size = ignoreSizeAndMargin ? 40 : backendSize;\n\n const containerStyle: React.CSSProperties = {\n marginTop: ignoreSizeAndMargin ? 0 : (margin?.top ?? 0),\n marginBottom: ignoreSizeAndMargin ? 0 : (margin?.bottom ?? 0),\n marginLeft: ignoreSizeAndMargin ? 0 : (margin?.left ?? 0),\n marginRight: ignoreSizeAndMargin ? 0 : (margin?.right ?? 0),\n width: size,\n height: size,\n backgroundColor: color?.fill || 'transparent',\n borderColor: color?.stroke || 'transparent',\n borderWidth: size * 0.05,\n borderRadius: '50%',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 1000000,\n position: 'absolute',\n display: 'flex',\n padding: 0,\n cursor: 'pointer',\n outline: 'none',\n borderStyle: color?.stroke ? 'solid' : 'none',\n ...style,\n };\n\n const renderDefaultIcon = () => {\n const stroke = color?.cross || '#ffffff';\n return (\n <svg viewBox=\"0 0 24 24\" width=\"60%\" height=\"60%\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <circle cx=\"18\" cy=\"5\" r=\"3\" />\n <circle cx=\"6\" cy=\"12\" r=\"3\" />\n <circle cx=\"18\" cy=\"19\" r=\"3\" />\n <line x1=\"8.59\" y1=\"13.51\" x2=\"15.42\" y2=\"17.49\" />\n <line x1=\"15.41\" y1=\"6.51\" x2=\"8.59\" y2=\"10.49\" />\n </svg>\n );\n };\n\n return (\n <button\n onClick={onPress}\n style={containerStyle}\n title={selectedStyle || ''}\n >\n {image && image.trim() !== '' ? (\n <img\n src={image}\n style={{ width: size, height: size, objectFit: 'contain' }}\n alt=\"share\"\n />\n ) : (\n renderDefaultIcon()\n )}\n </button>\n );\n};\n\nexport default ShareButton;","import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { CampaignWidget } from '../../types';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport useViewportTracking from '../../hooks/useViewportTracking';\n\ninterface WidgetProps {\n position?: string;\n}\n\n/**\n * Simple web widget component mirroring RN Widgets.tsx implementation\n * - Accepts optional position prop\n * - Fetches single campaign via useCampaigns hook\n * - Renders carousel with auto-advance (full) or manual scroll (half)\n * - Portals into host element if position target found\n */\nexport const Widget: React.FC<WidgetProps> = ({ position }) => {\n const hookData = useCampaigns<CampaignWidget>('WID', { position });\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n\n const normalizeScreen = (value?: string | null): string => (value || '').trim().toLowerCase();\n\n const data = hookData ?? ((): CampaignWidget | undefined => {\n const screen = normalizeScreen(currentScreen);\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign) => {\n const item = campaign as CampaignWidget;\n if (item.campaign_type !== 'WID') return false;\n if (position && item.position !== position) return false;\n const hasTrigger = Boolean((item as any).trigger_event ?? (item as any).trigger);\n const displayTriggerReady = (item as any).display_trigger !== false && !hasTrigger;\n const matchesScreen = !normalizeScreen(item.screen) || normalizeScreen(item.screen) === screen;\n return displayTriggerReady && matchesScreen;\n }) as CampaignWidget | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignWidget;\n } catch {\n return found;\n }\n })();\n const [activeIndex, setActiveIndex] = useState(0);\n const containerRef = useRef<HTMLDivElement>(null);\n const autoAdvanceRef = useRef<ReturnType<typeof setInterval> | null>(null);\n // Derived values (must be declared unconditionally so hooks stay stable)\n const details = data?.details || ({} as any);\n const images = (details.widget_images || []) as any[];\n const styling = details.styling || {};\n const widgetType = details.type || 'full';\n const isHalf = widgetType === 'half';\n\n // Track per-image impressions only when widget is visible in viewport\n const trackedImpressionsRef = useRef<string[]>([]);\n const isInViewportRef = useRef(false);\n\n // Viewport tracking: set flag and track first image when widget enters view\n const trackFirstImpression = useCallback(() => {\n isInViewportRef.current = true;\n const firstImage = images[activeIndex];\n if (firstImage?.id) trackImpression(firstImage.id);\n }, [images, activeIndex]); // eslint-disable-line\n const viewportRef = useViewportTracking(trackFirstImpression);\n\n const trackImpression = (widgetImageId?: string) => {\n if (!data?.id || !widgetImageId) return;\n if (!isInViewportRef.current) return; // gate: only track if in viewport\n if (trackedImpressionsRef.current.includes(widgetImageId)) return;\n trackedImpressionsRef.current.push(widgetImageId);\n void trackEvent('viewed', data.id, { widget_image: widgetImageId });\n };\n\n // Auto-advance full widgets every 5 seconds\n useEffect(() => {\n if (widgetType === 'full' && images.length > 1) {\n autoAdvanceRef.current = setInterval(() => {\n setActiveIndex((prev) => {\n const next = prev + 1;\n return next >= images.length ? 0 : next;\n });\n }, 5000);\n\n return () => {\n if (autoAdvanceRef.current) {\n clearInterval(autoAdvanceRef.current as any);\n }\n };\n }\n return undefined;\n }, [widgetType, images.length]);\n\n const handleClick = (imageId: string, link: string) => {\n if (data?.id) void trackEvent('clicked', data.id, { widget_image: imageId });\n if (link) {\n // Try reveal flow for internal campaign links first\n if (!link.startsWith('http')) {\n try {\n const revealed = revealCampaignFromLink(link);\n if (revealed) return;\n } catch (err) {\n console.warn('[Widget] revealCampaignFromLink error', err);\n }\n console.log('[Widget] Internal link:', link);\n return;\n }\n\n window.open(link, '_blank');\n }\n };\n\n const handleScroll = () => {\n if (containerRef.current && isHalf) {\n const { scrollLeft, offsetWidth } = containerRef.current;\n const itemWidth = (offsetWidth / 2) + 12;\n const index = Math.round(scrollLeft / itemWidth);\n setActiveIndex(index);\n }\n };\n\n // For full widgets: track impression when active slide changes\n useEffect(() => {\n if (!data?.id || widgetType !== 'full' || images.length === 0) return;\n const img = images[activeIndex];\n if (img && img.id) trackImpression(img.id);\n }, [activeIndex, data?.id, images, widgetType]);\n\n // For half widgets: track impressions based on visible area (50% coverage)\n useEffect(() => {\n if (!data?.id || !containerRef.current || !isHalf) return;\n\n const el = containerRef.current;\n const checkVisibility = () => {\n const { scrollLeft, offsetWidth } = el;\n const itemWidth = (offsetWidth / 2) + 12;\n images.forEach((img: any, idx: number) => {\n const itemLeft = idx * itemWidth;\n const itemRight = itemLeft + itemWidth;\n const viewLeft = scrollLeft;\n const viewRight = scrollLeft + offsetWidth;\n const overlap = Math.max(0, Math.min(itemRight, viewRight) - Math.max(itemLeft, viewLeft));\n if (overlap / itemWidth >= 0.5) {\n trackImpression(img.id);\n }\n });\n };\n\n // initial check\n checkVisibility();\n // listen for scroll events\n el.addEventListener('scroll', checkVisibility);\n return () => el.removeEventListener('scroll', checkVisibility);\n }, [data?.id, isHalf, images]);\n\n // Container styles\n const containerStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'row',\n flexWrap: isHalf ? 'nowrap' : 'wrap',\n gap: '12px',\n width: '100%',\n height: isHalf && details.height ? `${details.height}px` : 'auto',\n marginTop: styling.topMargin ? `${styling.topMargin}px` : '0px',\n marginBottom: styling.bottomMargin ? `${styling.bottomMargin}px` : '0px',\n marginLeft: styling.leftMargin ? `${styling.leftMargin}px` : '0px',\n marginRight: styling.rightMargin ? `${styling.rightMargin}px` : '0px',\n boxSizing: 'border-box',\n overflowX: isHalf ? 'auto' : 'hidden',\n overflowY: 'hidden',\n scrollSnapType: isHalf ? 'x mandatory' : undefined,\n msOverflowStyle: 'none',\n scrollbarWidth: 'none',\n };\n\n // Item styles\n const getItemStyle = (index: number): React.CSSProperties => ({\n flex: isHalf ? '0 0 calc(50% - 6px)' : '0 0 100%',\n height: isHalf && details.height ? `${details.height}px` : 'auto',\n cursor: 'pointer',\n position: 'relative',\n overflow: 'hidden',\n borderRadius: styling.borderRadius ? `${styling.borderRadius}px` : '0px',\n borderTopLeftRadius: styling.topLeftRadius ? `${styling.topLeftRadius}px` : undefined,\n borderTopRightRadius: styling.topRightRadius ? `${styling.topRightRadius}px` : undefined,\n borderBottomLeftRadius: styling.bottomLeftRadius ? `${styling.bottomLeftRadius}px` : undefined,\n borderBottomRightRadius: styling.bottomRightRadius ? `${styling.bottomRightRadius}px` : undefined,\n boxShadow: '0 4px 12px rgba(0,0,0,0.08)',\n scrollSnapAlign: 'start',\n });\n\n // Render content\n const content = (\n <div style={{ width: '100%', position: 'relative' }}>\n <style>{`\n .widget-scroll-container::-webkit-scrollbar {\n display: none;\n }\n `}</style>\n\n {/* Carousel/grid container */}\n <div\n ref={(el) => { (containerRef as any).current = el; viewportRef(el as HTMLElement); }}\n className=\"widget-scroll-container\"\n style={containerStyle}\n onScroll={handleScroll}\n >\n {isHalf\n ? // Half: show all images (2 per row with horizontal scroll)\n images.map((img: any, idx: number) => (\n <div key={img.id} style={getItemStyle(idx)}>\n <img\n src={img.image}\n alt=\"widget\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n display: 'block',\n }}\n onClick={() => handleClick(img.id, img.link)}\n />\n </div>\n ))\n : // Full: show only current slide (auto-advances)\n images.length > 0 && (\n <div key={`slide-${activeIndex}`} style={getItemStyle(0)}>\n <img\n src={images[activeIndex].image}\n alt=\"widget\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n display: 'block',\n }}\n onClick={() => handleClick(images[activeIndex].id, images[activeIndex].link)}\n />\n </div>\n )}\n </div>\n\n {/* Dots indicator for full widgets */}\n {widgetType === 'full' && images.length > 1 && (\n <div style={{\n display: 'flex',\n justifyContent: 'center',\n gap: '6px',\n marginTop: '8px',\n width: '100%'\n }}>\n {images.map((_: any, i: number) => (\n <div\n key={i}\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: i === activeIndex ? '#333' : '#ccc',\n transition: 'background-color 0.2s ease',\n }}\n />\n ))}\n </div>\n )}\n </div>\n );\n\n // Try to find host element if position is declared (mirror RN behavior)\n let target: Element | null = null;\n if (data?.position) {\n const key = String(data.position || '').replace(/^widget_/, '');\n const selectors = [\n `[data-as-id=\"${key}\"]`,\n `#${key}`,\n `.${key}`,\n `[data-widget=\"${key}\"]`,\n ];\n\n for (const sel of selectors) {\n try {\n const el = document.querySelector(sel);\n if (el) {\n target = el;\n console.log('[Widget] Portal target found:', sel, 'for campaign', data?.id);\n break;\n }\n } catch (e) {\n // ignore\n }\n }\n\n if (!target) {\n console.log('[Widget] No portal target found for position:', data?.position, 'rendering inline for campaign:', data?.id);\n }\n }\n\n // Portal into host if found, otherwise render inline\n if (target) {\n return createPortal(content, target);\n }\n\n return content;\n};\n\nexport default Widget;\n","import { useEffect, useRef } from 'react';\n\n/**\n * Viewport-based `viewed` tracking hook.\n *\n * Fires `onVisible()` only once when the observed element enters the viewport\n * with at least `threshold` (default 50%) of it visible.\n *\n * This ensures `viewed` analytics events are NOT sent for campaigns that are\n * below the fold or otherwise outside the user's visible screen, mirroring\n * native viewport-based impression tracking.\n *\n * @param onVisible - callback to run when element enters viewport\n * @param threshold - fraction of element that must be visible (0–1, default 0.5)\n */\nexport default function useViewportTracking(\n onVisible: () => void,\n threshold = 0.5\n): React.RefCallback<HTMLElement> {\n const onVisibleRef = useRef(onVisible);\n const hasTrackedRef = useRef(false);\n const elementRef = useRef<HTMLElement | null>(null);\n const observerRef = useRef<IntersectionObserver | null>(null);\n\n // Always keep callback ref fresh without re-subscribing observer\n useEffect(() => {\n onVisibleRef.current = onVisible;\n }, [onVisible]);\n\n const refCallback: React.RefCallback<HTMLElement> = (el) => {\n // Disconnect existing observer if element changes\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n elementRef.current = el;\n hasTrackedRef.current = false; // reset on campaign data change\n\n if (!el) {\n // Element unmounted or ref cleaned up, do nothing\n return;\n }\n\n if (typeof IntersectionObserver === 'undefined') {\n // Fallback: browsers without IntersectionObserver fire immediately\n onVisibleRef.current();\n return;\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n observerRef.current = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n \n if (entry.isIntersecting && !hasTrackedRef.current) {\n // Require the element to stay in viewport for 500ms to avoid false\n // positives from layout shifts during initial page load\n if (!timeoutId) {\n timeoutId = setTimeout(() => {\n hasTrackedRef.current = true;\n onVisibleRef.current();\n observerRef.current?.disconnect();\n timeoutId = null;\n }, 500);\n }\n } else {\n // If it leaves viewport before 500ms, cancel the tracking\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n },\n { threshold }\n );\n\n observerRef.current.observe(el);\n };\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n observerRef.current?.disconnect();\n };\n }, []);\n\n return refCallback;\n}\n","import React, { useEffect, useLayoutEffect, useMemo, useRef, useState, useCallback } from \"react\";\nimport useCampaigns from \"../../hooks/useCampaigns\";\nimport trackEvent from \"../../core/trackEvent\";\nimport useAppStorysStore from \"../../core/store\";\nimport { BaseCampaign } from \"../../types\";\nimport { resolveFontFamily } from \"../../core/fontManager\";\nimport useViewportTracking from \"../../hooks/useViewportTracking\";\n\n\nimport { CampaignTooltip, TooltipItem, TooltipStyling } from \"../../types\";\n\nconst normalizeScreen = (value?: string | null): string => (value || \"\").trim().toLowerCase();\n\nexport const Tooltip: React.FC = () => {\n const hookData = useCampaigns<CampaignTooltip>(\"TTP\");\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n\n const [currentStep, setCurrentStep] = useState(0);\n const [isDismissed, setIsDismissed] = useState(false);\n const [targetRect, setTargetRect] = useState<DOMRect | null>(null);\n const [tooltipSize, setTooltipSize] = useState({ width: 0, height: 0 });\n\n const tooltipRef = useRef<HTMLDivElement>(null);\n const observerRef = useRef<MutationObserver | null>(null);\n\n const data = useMemo(() => {\n if (hookData) return hookData;\n\n const screen = normalizeScreen(currentScreen);\n const findFromList = (source: any[]) => source.find((campaign) => {\n const item = campaign as BaseCampaign;\n const isTooltip = item.campaign_type === \"TTP\" || item.campaign_type === \"TLTP\";\n const matchesScreen = !normalizeScreen(item.screen) || normalizeScreen(item.screen) === screen;\n const hasTrigger = Boolean((item as any).trigger_event ?? (item as any).trigger);\n const displayTriggerReady = (item as any).display_trigger !== false && !hasTrigger;\n return isTooltip && matchesScreen && displayTriggerReady;\n }) as CampaignTooltip | undefined;\n\n return findFromList(campaigns) ?? findFromList(allCampaigns);\n }, [hookData, campaigns, allCampaigns, currentScreen]);\n\n const tooltips = useMemo(() => {\n if (data?.details?.tooltips && Array.isArray(data.details.tooltips)) {\n return [...data.details.tooltips].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n }\n\n // Support for single step fully flat campaigns\n if (data?.details?.target || data?.details?.titleText) {\n return [{ ...data.details, _id: data.id } as TooltipItem];\n }\n\n return [];\n }, [data]);\n\n const currentTooltip = tooltips[currentStep];\n\n useEffect(() => {\n // Intentionally no-op here: viewed should be emitted when tooltip is actually shown\n // (i.e. when target element is measured and tooltip is displayed). Native emits\n // `viewed` from the overlay show path with `tooltip_id` metadata.\n }, [data]);\n\n // Track `viewed` when the tooltip enters the viewport\n const viewedTooltipsRef = useRef<Set<string>>(new Set());\n const trackViewed = useCallback(() => {\n if (!data || !currentTooltip || isDismissed || !sdkVisible) return;\n\n try {\n const tooltipId = (currentTooltip as any)._id || (currentTooltip as any).id || undefined;\n const key = String(data.id || '') + '::' + String(tooltipId || '');\n if (!viewedTooltipsRef.current.has(key)) {\n viewedTooltipsRef.current.add(key);\n void trackEvent('viewed', data.id, { tooltip_id: tooltipId });\n }\n } catch (e) {\n // ignore\n }\n }, [data, currentTooltip, isDismissed, sdkVisible]);\n const viewportRef = useViewportTracking(trackViewed);\n\n\n // Find target element and get rect\n useEffect(() => {\n if (!currentTooltip?.target || isDismissed) return;\n\n setTargetRect(null);\n\n const findTarget = (scroll = false) => {\n const targetId = currentTooltip.target;\n if (!targetId) return null;\n\n const el = document.getElementById(targetId) ||\n document.querySelector(`[data-id=\"${targetId}\"]`) ||\n document.querySelector(`.${targetId}`);\n\n if (el) {\n setTargetRect(el.getBoundingClientRect());\n if (scroll) {\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n return el;\n }\n return null;\n };\n\n // Initial check\n const el = findTarget(true);\n\n // Setup MutationObserver to watch for element appearing\n if (!el) {\n observerRef.current = new MutationObserver(() => {\n const found = findTarget(true);\n if (found) {\n observerRef.current?.disconnect();\n }\n });\n observerRef.current.observe(document.body, { childList: true, subtree: true });\n }\n\n // Resize and scroll listener\n const handleResizeOrScroll = () => {\n const targetEl = findTarget(false);\n if (targetEl) {\n setTargetRect(targetEl.getBoundingClientRect());\n }\n };\n\n window.addEventListener(\"resize\", handleResizeOrScroll);\n window.addEventListener(\"scroll\", handleResizeOrScroll, { passive: true });\n\n return () => {\n observerRef.current?.disconnect();\n window.removeEventListener(\"resize\", handleResizeOrScroll);\n window.removeEventListener(\"scroll\", handleResizeOrScroll);\n };\n }, [currentTooltip, isDismissed, currentStep]);\n\n // Measure tooltip content\n useLayoutEffect(() => {\n if (tooltipRef.current && targetRect) {\n const { width, height } = tooltipRef.current.getBoundingClientRect();\n setTooltipSize({ width, height });\n }\n }, [currentTooltip, targetRect]);\n\n if (!data || !currentTooltip || isDismissed || !sdkVisible || !targetRect) return null;\n\n const styling = currentTooltip.styling || {};\n const appearance = styling.appearance || {};\n const colors = appearance.colors || {};\n const cta = styling.cta || {};\n const ctaContainer = cta.container || {};\n const ctaCorner = cta.cornerRadius || {};\n const ctaText = cta.text || {};\n\n const arrowPos = currentTooltip.arrowPosition || \"left\";\n const arrowStyle = appearance.arrowStyle || { width: 6, height: 12 };\n const arrowSize = arrowStyle.width || 6; // fallback\n\n const absoluteTop = targetRect.top + window.scrollY;\n const absoluteLeft = targetRect.left + window.scrollX;\n\n let tooltipLeft = 0;\n let tooltipTop = 0;\n\n // Offset gap between target and tooltip (excluding arrow itself)\n const offsetGap = 8;\n\n if (arrowPos === \"left\") {\n tooltipLeft = absoluteLeft + targetRect.width + offsetGap;\n tooltipTop = absoluteTop + (targetRect.height / 2) - (tooltipSize.height / 2);\n } else if (arrowPos === \"right\") {\n tooltipLeft = absoluteLeft - tooltipSize.width - offsetGap;\n tooltipTop = absoluteTop + (targetRect.height / 2) - (tooltipSize.height / 2);\n } else if (arrowPos === \"top\") {\n tooltipTop = absoluteTop + targetRect.height + offsetGap;\n tooltipLeft = absoluteLeft + (targetRect.width / 2) - (tooltipSize.width / 2);\n } else if (arrowPos === \"bottom\") {\n tooltipTop = absoluteTop - tooltipSize.height - offsetGap;\n tooltipLeft = absoluteLeft + (targetRect.width / 2) - (tooltipSize.width / 2);\n }\n\n // Bounds checking to prevent cutting off at viewport edge\n const safeMargin = 8;\n const viewportTop = window.scrollY;\n const viewportBottom = window.scrollY + window.innerHeight;\n const viewportLeft = window.scrollX;\n const viewportRight = window.scrollX + window.innerWidth;\n\n if (tooltipSize.height > 0) {\n tooltipTop = Math.max(viewportTop + safeMargin, Math.min(viewportBottom - tooltipSize.height - safeMargin, tooltipTop));\n }\n if (tooltipSize.width > 0) {\n tooltipLeft = Math.max(viewportLeft + safeMargin, Math.min(viewportRight - tooltipSize.width - safeMargin, tooltipLeft));\n }\n\n const handleNext = () => {\n const action = currentTooltip.clickAction || \"nextStep\";\n const targetLink = currentTooltip.link || currentTooltip.url;\n\n // Mirror native: emit `clicked` with tooltip identifier before action\n try {\n const tooltipId = (currentTooltip as any)._id || (currentTooltip as any).id || undefined;\n if (data?.id) {\n void trackEvent('clicked', data.id, { tooltip_id: tooltipId });\n }\n } catch (e) {\n // ignore tracking errors\n }\n\n if (action === \"close\") {\n setIsDismissed(true);\n if (targetLink) window.open(targetLink, \"_blank\");\n return;\n }\n\n if (currentStep < tooltips.length - 1) {\n setCurrentStep((prev: number) => prev + 1);\n } else {\n setIsDismissed(true);\n if (targetLink) {\n window.open(targetLink, \"_blank\");\n }\n }\n };\n\n const handleBackdropClick = () => {\n if (currentTooltip.enableBackdrop) {\n setIsDismissed(true);\n }\n };\n\n return (\n <>\n {currentTooltip.enableBackdrop && (\n <div\n style={{\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: colors.backdrop || \"rgba(0, 0, 0, 0.7)\",\n opacity: appearance.backdropOpacity ? appearance.backdropOpacity / 100 : 0.7,\n zIndex: 10000,\n }}\n onClick={handleBackdropClick}\n />\n )}\n\n <div\n ref={(el) => { (tooltipRef as any).current = el; viewportRef(el as HTMLElement); }}\n style={{\n position: \"absolute\",\n top: tooltipTop,\n left: tooltipLeft,\n zIndex: 10001,\n backgroundColor: colors.tooltip || \"#FE6B35\",\n padding: `${appearance.padding?.top ?? 8}px ${appearance.padding?.right ?? 8}px ${appearance.padding?.bottom ?? 8}px ${appearance.padding?.left ?? 8}px`,\n borderRadius: `${appearance.cornerRadius?.topLeft ?? 12}px ${appearance.cornerRadius?.topRight ?? 12}px ${appearance.cornerRadius?.bottomRight ?? 12}px ${appearance.cornerRadius?.bottomLeft ?? 12}px`,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n maxWidth: 300,\n minWidth: 200,\n transition: \"top 0.2s ease, left 0.2s ease\",\n }}\n >\n <div\n style={{\n position: \"absolute\",\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n ...(arrowPos === \"left\" && {\n left: -offsetGap,\n top: Math.max(12, Math.min(tooltipSize.height - arrowSize * 2 - 12, absoluteTop + (targetRect.height / 2) - tooltipTop - arrowSize)),\n borderWidth: `${arrowSize}px ${offsetGap}px ${arrowSize}px 0`,\n borderColor: `transparent ${colors.tooltip || \"#FE6B35\"} transparent transparent`,\n }),\n ...(arrowPos === \"right\" && {\n right: -offsetGap,\n top: Math.max(12, Math.min(tooltipSize.height - arrowSize * 2 - 12, absoluteTop + (targetRect.height / 2) - tooltipTop - arrowSize)),\n borderWidth: `${arrowSize}px 0 ${arrowSize}px ${offsetGap}px`,\n borderColor: `transparent transparent transparent ${colors.tooltip || \"#FE6B35\"}`,\n }),\n ...(arrowPos === \"top\" && {\n top: -offsetGap,\n left: Math.max(12, Math.min(tooltipSize.width - arrowSize * 2 - 12, absoluteLeft + (targetRect.width / 2) - tooltipLeft - arrowSize)),\n borderWidth: `0 ${arrowSize}px ${offsetGap}px ${arrowSize}px`,\n borderColor: `transparent transparent ${colors.tooltip || \"#FE6B35\"} transparent`,\n }),\n ...(arrowPos === \"bottom\" && {\n bottom: -offsetGap,\n left: Math.max(12, Math.min(tooltipSize.width - arrowSize * 2 - 12, absoluteLeft + (targetRect.width / 2) - tooltipLeft - arrowSize)),\n borderWidth: `${offsetGap}px ${arrowSize}px 0 ${arrowSize}px`,\n borderColor: `${colors.tooltip || \"#FE6B35\"} transparent transparent transparent`,\n }),\n }}\n />\n\n {currentTooltip.titleText && (\n <div\n style={{\n color: styling.title?.color || \"#ffffff\",\n fontFamily: resolveFontFamily(styling.title?.fontFamily) || \"Arial\",\n fontSize: styling.title?.fontSize || 14,\n textAlign: (styling.title?.textAlign as any) || \"center\",\n marginBottom: styling.title?.margin?.bottom ?? 4,\n marginTop: styling.title?.margin?.top ?? 0,\n marginLeft: styling.title?.margin?.left ?? 0,\n marginRight: styling.title?.margin?.right ?? 0,\n fontWeight: styling.title?.fontDecoration?.includes(\"bold\") ? \"bold\" : 600,\n fontStyle: styling.title?.fontDecoration?.includes(\"italic\") ? \"italic\" : \"normal\",\n textDecoration: styling.title?.fontDecoration?.includes(\"underline\") ? \"underline\" : \"none\",\n }}\n >\n {currentTooltip.titleText}\n </div>\n )}\n\n {currentTooltip.subtitleText && (\n <div\n style={{\n color: styling.subTitle?.color || \"#ffffff\",\n fontFamily: resolveFontFamily(styling.subTitle?.fontFamily) || \"Arial\",\n fontSize: styling.subTitle?.fontSize || 12,\n textAlign: (styling.subTitle?.textAlign as any) || \"center\",\n marginBottom: styling.subTitle?.margin?.bottom ?? 8,\n marginTop: styling.subTitle?.margin?.top ?? 0,\n marginLeft: styling.subTitle?.margin?.left ?? 0,\n marginRight: styling.subTitle?.margin?.right ?? 0,\n fontWeight: styling.subTitle?.fontDecoration?.includes(\"bold\") ? \"bold\" : \"normal\",\n fontStyle: styling.subTitle?.fontDecoration?.includes(\"italic\") ? \"italic\" : \"normal\",\n textDecoration: styling.subTitle?.fontDecoration?.includes(\"underline\") ? \"underline\" : \"none\",\n }}\n >\n {currentTooltip.subtitleText}\n </div>\n )}\n\n {currentTooltip.ctaText && (\n <div\n style={{\n display: \"flex\",\n justifyContent: ctaContainer.alignment === \"right\" ? \"flex-end\" : ctaContainer.alignment === \"left\" ? \"flex-start\" : \"center\",\n marginTop: 8,\n }}\n >\n <button\n onClick={handleNext}\n style={{\n width: ctaContainer.ctaFullWidth ? \"100%\" : ctaContainer.ctaWidth || \"auto\",\n height: ctaContainer.height || 35,\n background: ctaContainer.backgroundColor || \"#F7921C\",\n color: ctaText.color || \"#ffffff\",\n border: `${ctaContainer.borderWidth || 0}px solid ${ctaContainer.borderColor || \"transparent\"}`,\n borderRadius: `${ctaCorner.topLeft ?? 7}px ${ctaCorner.topRight ?? 7}px ${ctaCorner.bottomRight ?? 7}px ${ctaCorner.bottomLeft ?? 7}px`,\n fontSize: ctaText.fontSize || 14,\n fontFamily: resolveFontFamily(ctaText.fontFamily) || \"Arial\",\n fontWeight: ctaText.fontDecoration?.includes(\"bold\") ? \"bold\" : \"normal\",\n fontStyle: ctaText.fontDecoration?.includes(\"italic\") ? \"italic\" : \"normal\",\n textDecoration: ctaText.fontDecoration?.includes(\"underline\") ? \"underline\" : \"none\",\n cursor: \"pointer\",\n padding: \"0 12px\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {currentTooltip.ctaText}\n </button>\n </div>\n )}\n </div>\n </>\n );\n};\n\nexport default Tooltip;\n","import React, { useEffect, useState } from 'react';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport { resolveFontFamily } from '../../core/fontManager';\nimport { CampaignBottomSheet, BottomSheetElement } from '../../types';\nimport CrossButton from '../common/CommonElements/CrossButton';\n\nexport const BottomSheet: React.FC = () => {\n const hookData = useCampaigns<CampaignBottomSheet>('BTS');\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n\n const data = hookData ?? ((): CampaignBottomSheet | undefined => {\n const screen = (currentScreen || '').trim().toLowerCase();\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign: any) => {\n if (!campaign) return false;\n if (campaign.campaign_type !== 'BTS') return false;\n const hasTrigger = Boolean(campaign.trigger_event ?? campaign.trigger);\n // keep display-trigger campaigns available only when not trigger-driven\n const displayTriggerReady = (campaign as any).display_trigger !== false && !hasTrigger;\n if (!displayTriggerReady) return false;\n const cs = (campaign.screen || '').trim().toLowerCase();\n return !cs || cs === screen;\n }) as CampaignBottomSheet | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignBottomSheet;\n } catch {\n return found;\n }\n })();\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n const [isDismissed, setIsDismissed] = useState(false);\n\n useEffect(() => {\n if (data) {\n setIsDismissed(false);\n // Match RN: send generic `viewed` event for campaigns\n void trackEvent('viewed', data.id);\n }\n }, [data]);\n\n const removeTrackedEvent = (eventKey: string) => {\n try {\n const state = useAppStorysStore.getState();\n const tracked = state.trackedEvents || [];\n const next = tracked.filter((e: string) => e !== eventKey);\n state.setTrackedEvents(next);\n } catch (e) {\n // ignore\n }\n };\n\n if (!data || isDismissed || !sdkVisible) return null;\n\n const { details } = data;\n const elements = details.elements || [];\n const sortedElements = [...elements].sort((a, b) => (a.order || 0) - (b.order || 0));\n\n // Determine opacity: if it's high (>1), treat as percentage\n let opacity = details.backdropOpacity ?? 0.5;\n if (opacity > 1) {\n opacity = opacity / 100;\n }\n\n const renderElement = (element: BottomSheetElement) => {\n switch (element.type) {\n case 'image': {\n const imgStyle: React.CSSProperties = {\n width: '100%',\n display: 'block',\n objectFit: 'contain',\n backgroundColor: element.imageBackgroundColor || 'transparent',\n paddingBottom: element.paddingBottom ?? 0,\n paddingLeft: element.paddingLeft ?? 0,\n paddingRight: element.paddingRight ?? 0,\n paddingTop: element.paddingTop ?? 0,\n cursor: element.imageLink ? 'pointer' : 'default',\n };\n return (\n <div key={element.id} style={{ textAlign: element.alignment || 'left', width: '100%' }}>\n {element.url && (\n <img \n src={element.url} \n alt=\"\" \n style={imgStyle} \n onClick={() => {\n if (!element.imageLink) return;\n if (data?.id) void trackEvent('clicked', data.id);\n try {\n const link = String(element.imageLink || '').trim();\n if (link && !link.startsWith('http')) {\n const revealed = revealCampaignFromLink(link);\n if (revealed) return;\n }\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n try {\n window.open(element.imageLink, '_blank');\n } catch (err) {\n // ignore\n }\n }}\n />\n )}\n </div>\n );\n }\n\n case 'cta': {\n const ctaData = element.cta || {};\n const container = ctaData.container || {};\n const cornerRadius = ctaData.cornerRadius || {};\n const margin = ctaData.margin || {};\n const textStyle = ctaData.text || {};\n\n return (\n <div \n key={element.id}\n style={{\n display: 'flex',\n justifyContent: container.alignment === 'center' ? 'center' : container.alignment === 'right' ? 'flex-end' : 'flex-start',\n width: '100%',\n marginTop: margin.top ?? 0,\n marginBottom: margin.bottom ?? 0,\n marginLeft: margin.left ?? 0,\n marginRight: margin.right ?? 0,\n }}\n >\n <button\n style={{\n width: container.ctaFullWidth ? '100%' : container.ctaWidth || 'auto',\n height: container.height || 45,\n backgroundColor: container.ctaBoxColor || container.backgroundColor || '#FE6B35',\n color: textStyle.color || '#ffffff',\n border: `${container.borderWidth || 0}px solid ${container.borderColor || 'transparent'}`,\n borderRadius: `${cornerRadius.topLeft ?? 12}px ${cornerRadius.topRight ?? 12}px ${cornerRadius.bottomRight ?? 12}px ${cornerRadius.bottomLeft ?? 12}px`,\n fontSize: textStyle.fontSize || 14,\n fontFamily: resolveFontFamily(textStyle.fontFamily) || 'Arial',\n fontWeight: textStyle.fontDecoration?.includes('bold') ? 'bold' : 'normal',\n fontStyle: textStyle.fontDecoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: textStyle.fontDecoration?.includes('underline') ? 'underline' : 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 16px',\n }}\n onClick={() => {\n const link = element.ctaLink || element.url;\n if (!link) return;\n if (data?.id) void trackEvent('clicked', data.id);\n try {\n const l = String(link || '').trim();\n if (l && !l.startsWith('http')) {\n const revealed = revealCampaignFromLink(l);\n if (revealed) return;\n }\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n try {\n window.open(link, '_blank');\n } catch (err) {\n // ignore\n }\n }}\n >\n {element.ctaText || 'Button'}\n </button>\n </div>\n );\n }\n\n case 'body': {\n const titleStyle = element.titleFontStyle || {};\n const descStyle = element.descriptionFontStyle || {};\n \n return (\n <div \n key={element.id}\n style={{\n width: '100%',\n backgroundColor: element.bodyBackgroundColor || 'transparent',\n marginTop: element.marginTop ?? 0,\n marginBottom: element.marginBottom ?? 20,\n marginLeft: element.marginLeft ?? 4,\n marginRight: element.marginRight ?? 4,\n }}\n >\n {element.titleText && (\n <div style={{\n color: titleStyle.colour || '#000000',\n fontSize: titleStyle.fontSize ? `${titleStyle.fontSize}px` : element.titleFontSize ? `${element.titleFontSize}px` : '16px',\n fontFamily: resolveFontFamily(titleStyle.fontFamily) || 'inherit',\n textAlign: titleStyle.alignment || 'left',\n lineHeight: element.titleLineHeight || 1.2,\n fontWeight: titleStyle.decoration?.includes('bold') ? 'bold' : '600',\n fontStyle: titleStyle.decoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: titleStyle.decoration?.includes('underline') ? 'underline' : 'none',\n marginBottom: element.spacingBetweenTitleDesc ?? 4,\n }}>\n {element.titleText}\n </div>\n )}\n \n {element.descriptionText && (\n <div style={{\n color: descStyle.colour || '#000000',\n fontSize: descStyle.fontSize ? `${descStyle.fontSize}px` : element.descriptionFontSize ? `${element.descriptionFontSize}px` : '14px',\n fontFamily: resolveFontFamily(descStyle.fontFamily) || 'inherit',\n textAlign: descStyle.alignment || 'left',\n lineHeight: element.descriptionLineHeight || 1.5,\n fontWeight: descStyle.decoration?.includes('bold') ? 'bold' : 'normal',\n fontStyle: descStyle.decoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: descStyle.decoration?.includes('underline') ? 'underline' : 'none',\n }}>\n {element.descriptionText}\n </div>\n )}\n </div>\n );\n }\n\n default:\n return null;\n }\n };\n\n return (\n <>\n <div \n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: details.backdropColor || 'rgba(0,0,0,0.5)',\n opacity: opacity,\n zIndex: 999998,\n transition: 'opacity 0.3s ease',\n }}\n onClick={() => {\n if (data?.id) removeTrackedEvent(`viaAppStorys${data.id}`);\n setIsDismissed(true);\n }}\n />\n <div \n style={{\n position: 'fixed',\n bottom: 0,\n left: '50%',\n transform: 'translateX(-50%)',\n width: '100%',\n maxWidth: '500px', // Responsive safety\n backgroundColor: details.backgroundColor || '#FFFFFF',\n borderTopLeftRadius: `${details.cornerRadius?.topLeft ?? 16}px`,\n borderTopRightRadius: `${details.cornerRadius?.topRight ?? 16}px`,\n borderBottomLeftRadius: `${details.cornerRadius?.bottomLeft ?? 0}px`,\n borderBottomRightRadius: `${details.cornerRadius?.bottomRight ?? 0}px`,\n zIndex: 999999,\n padding: '24px 16px',\n boxShadow: '0 -4px 16px rgba(0,0,0,0.15)',\n maxHeight: '85vh',\n overflowY: 'auto',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n transition: 'transform 0.3s ease-out',\n }}\n >\n <div style={{\n width: '40px',\n height: '5px',\n backgroundColor: '#E0E0E0',\n borderRadius: '2.5px',\n marginBottom: '16px',\n cursor: 'pointer'\n }} onClick={() => setIsDismissed(true)} />\n\n {details.crossButton?.enabled && (\n <CrossButton \n config={details.crossButton}\n onPress={() => {\n if (data?.id) removeTrackedEvent(`viaAppStorys${data.id}`);\n setIsDismissed(true);\n }}\n style={{\n top: details.crossButton?.margin?.top ?? 12,\n right: details.crossButton?.margin?.right ?? 12,\n }}\n />\n )}\n \n <div style={{ width: '100%', display: 'flex', flexDirection: 'column', gap: '12px' }}>\n {sortedElements.map(renderElement)}\n </div>\n </div>\n </>\n );\n};\n\nexport default BottomSheet;\n","import React, { useEffect, useMemo, useState } from 'react';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport CrossButton from '../common/CommonElements/CrossButton';\nimport { CampaignCsat, CsatCampaignDetails, CsatSpacing, CsatTextStyle } from '../../types';\nimport { resolveFontFamily } from '../../core/fontManager';\n\nconst FIVE_STAR_MAX = 5;\nconst LOW_RATING_CUTOFF = 3;\n\nfunction asSpacingValue(value?: number): string | undefined {\n if (value == null) return undefined;\n return `${value}px`;\n}\n\nfunction spacingToStyle(spacing?: CsatSpacing): React.CSSProperties {\n return {\n marginTop: asSpacingValue(spacing?.top),\n marginRight: asSpacingValue(spacing?.right),\n marginBottom: asSpacingValue(spacing?.bottom),\n marginLeft: asSpacingValue(spacing?.left),\n };\n}\n\nfunction applyFontFamily(fontFamily?: string): string | undefined {\n return resolveFontFamily(fontFamily);\n}\n\nfunction textStyleToCss(textStyle?: CsatTextStyle): React.CSSProperties {\n if (!textStyle) return {};\n\n return {\n color: textStyle.color,\n fontSize: textStyle.fontSize,\n fontFamily: applyFontFamily(textStyle.fontFamily),\n textAlign: textStyle.textAlign as React.CSSProperties['textAlign'],\n fontWeight: textStyle.fontDecoration?.includes('bold') ? 'bold' : undefined,\n fontStyle: textStyle.fontDecoration?.includes('italic') ? 'italic' : undefined,\n textDecoration: textStyle.fontDecoration?.includes('underline') ? 'underline' : undefined,\n };\n}\n\nfunction getCornerRadius(cornerRadius?: { topLeft?: number; topRight?: number; bottomRight?: number; bottomLeft?: number }): string {\n return `${cornerRadius?.topLeft ?? 8}px ${cornerRadius?.topRight ?? 8}px ${cornerRadius?.bottomRight ?? 8}px ${cornerRadius?.bottomLeft ?? 8}px`;\n}\n\nfunction getAlignment(alignment?: string): React.CSSProperties['justifyContent'] {\n if (alignment === 'right') return 'flex-end';\n if (alignment === 'left') return 'flex-start';\n return 'center';\n}\n\nfunction getRatingType(details: CsatCampaignDetails): 'star' | 'number' | 'emoji' {\n const ratingType = details.styling?.rating?.ratingType;\n if (ratingType === 'number' || ratingType === 'emoji' || ratingType === 'star') return ratingType;\n return 'star';\n}\n\nfunction getEmojiChoices(details: CsatCampaignDetails): string[] {\n const configured = details.styling?.rating?.emoji as unknown;\n\n if (Array.isArray(configured)) {\n return configured.filter((item): item is string => typeof item === 'string' && item.trim().length > 0);\n }\n\n if (configured && typeof configured === 'object') {\n const values = Object.values(configured as Record<string, unknown>)\n .filter((item): item is string => typeof item === 'string' && item.trim().length > 0);\n if (values.length > 0) return values;\n }\n\n if (typeof configured === 'string' && configured.trim()) {\n if (configured.includes(',')) {\n const split = configured.split(',').map((item) => item.trim()).filter(Boolean);\n if (split.length > 0) return split;\n }\n return [configured];\n }\n\n return ['😠', '😕', '😐', '🙂', '😍'];\n}\n\nfunction getNumberChoices(details: CsatCampaignDetails): number[] {\n // Force a 5-point numeric scale (1–5) regardless of backend config.\n // This matches the requested UI and avoids rendering 0–10 style scales.\n return Array.from({ length: 5 }, (_, index) => index + 1);\n}\n\nfunction asNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value;\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value);\n if (Number.isFinite(parsed) && parsed >= 0) return parsed;\n }\n return undefined;\n}\n\nfunction getNumberRatingGap(details: CsatCampaignDetails): number {\n const rating = (details.styling?.rating as Record<string, unknown> | undefined) || undefined;\n const directCandidates = [\n rating?.['numberSpacing'],\n rating?.['numberGap'],\n rating?.['number_spacing'],\n rating?.['number_gap'],\n rating?.['spacingBetweenNumbers'],\n rating?.['spaceBetweenNumbers'],\n rating?.['numberOptionsSpacing'],\n ];\n\n for (const candidate of directCandidates) {\n const maybe = asNonNegativeNumber(candidate);\n if (maybe != null) return maybe;\n }\n\n const numberConfig = rating?.['number'];\n if (numberConfig && typeof numberConfig === 'object') {\n const obj = numberConfig as Record<string, unknown>;\n const nestedCandidates = [obj['spacing'], obj['gap'], obj['optionsSpacing'], obj['numberSpacing'], obj['numberGap']];\n for (const candidate of nestedCandidates) {\n const maybe = asNonNegativeNumber(candidate);\n if (maybe != null) return maybe;\n }\n }\n\n return 8;\n}\n\nfunction getRatingMax(details: CsatCampaignDetails): number {\n const ratingType = getRatingType(details);\n\n if (ratingType === 'emoji') return Math.max(1, getEmojiChoices(details).length);\n if (ratingType === 'number') {\n const choices = getNumberChoices(details);\n return Math.max(1, choices.length);\n }\n\n return FIVE_STAR_MAX;\n}\n\nconst StarIcon: React.FC<{ fill: string; stroke: string }> = ({ fill, stroke }) => (\n <svg viewBox=\"0 0 24 24\" width=\"22\" height=\"22\" aria-hidden>\n <path\n d=\"M12 2.25l2.91 5.89 6.5.95-4.7 4.58 1.11 6.46L12 17.03 6.18 20.13l1.11-6.46-4.7-4.58 6.5-.95L12 2.25z\"\n fill={fill}\n stroke={stroke}\n strokeWidth=\"1.4\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\ninterface FormContentProps {\n details: CsatCampaignDetails;\n appearance?: { backgroundColor?: string };\n rating: number;\n selectedOptions: string[];\n comments: string;\n isHighRating: boolean;\n feedbackOptions: string[];\n onRate: (value: number) => void;\n onToggleOption: (option: string) => void;\n onCommentChange: (value: string) => void;\n onInlineSubmit: () => void;\n canSubmit: boolean;\n}\n\nconst CsatFormContent: React.FC<FormContentProps> = ({\n details,\n appearance,\n rating,\n selectedOptions,\n comments,\n isHighRating,\n feedbackOptions,\n onRate,\n onToggleOption,\n onCommentChange,\n onInlineSubmit,\n canSubmit,\n}) => {\n const styling = details.styling || {};\n const feedbackPage = styling.feedbackPage || {};\n const ratingStyle = styling.rating || {};\n const initialFeedback = styling.initialFeedback || {};\n const submitCta = feedbackPage.submitButton?.cta;\n const ratingType = getRatingType(details);\n const numberChoices = ratingType === 'number' ? getNumberChoices(details) : [];\n const emojiChoices = ratingType === 'emoji' ? getEmojiChoices(details) : [];\n\n const numberGap = ratingType === 'number' ? getNumberRatingGap(details) : 8;\n\n const selectedStarConfig = isHighRating ? ratingStyle.star?.high : ratingStyle.star?.low;\n\n return (\n <>\n <div style={spacingToStyle(initialFeedback.title?.margin)}>\n <div\n style={{\n ...(textStyleToCss(initialFeedback.title?.textStyle)),\n color: initialFeedback.title?.textStyle?.color || '#101828',\n fontSize: initialFeedback.title?.textStyle?.fontSize || 20,\n lineHeight: 1.3,\n }}\n >\n {details.title || 'How was your experience?'}\n </div>\n </div>\n\n <div style={spacingToStyle(initialFeedback.subtitle?.margin)}>\n <div\n style={{\n ...(textStyleToCss(initialFeedback.subtitle?.textStyle)),\n color: initialFeedback.subtitle?.textStyle?.color || '#4b5563',\n fontSize: initialFeedback.subtitle?.textStyle?.fontSize || 14,\n lineHeight: 1.4,\n }}\n >\n {details.description_text || 'Your feedback helps us improve your experience.'}\n </div>\n </div>\n\n <div style={{ marginTop: 8, display: 'flex', justifyContent: 'center', gap: ratingType === 'number' ? numberGap : 8, flexWrap: 'wrap' }}>\n {ratingType === 'star' && Array.from({ length: FIVE_STAR_MAX }, (_, index) => {\n const value = index + 1;\n const isSelected = value <= rating;\n const starContainerStyle = isSelected\n ? selectedStarConfig?.stylingContainer\n : ratingStyle.star?.unselected?.stylingContainer;\n const starStyle = isSelected\n ? selectedStarConfig?.stylingStar\n : ratingStyle.star?.unselected?.stylingStar;\n\n return (\n <button\n key={value}\n onClick={() => onRate(value)}\n style={{\n border: `${starContainerStyle?.borderWidth ?? 1}px solid ${starContainerStyle?.border || '#d1d5db'}`,\n background: starContainerStyle?.background || '#ffffff',\n borderRadius: 10,\n width: 44,\n height: 44,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n padding: 0,\n }}\n aria-label={`Rate ${value} out of ${FIVE_STAR_MAX}`}\n >\n <StarIcon\n fill={starStyle?.background || (isSelected ? '#f59e0b' : '#e5e7eb')}\n stroke={starStyle?.border || (isSelected ? '#d97706' : '#9ca3af')}\n />\n </button>\n );\n })}\n\n {ratingType === 'number' && numberChoices.map((value, index) => {\n const selected = value === rating;\n return (\n <button\n key={`${value}-${index}`}\n onClick={() => onRate(value)}\n style={{\n border: `1px solid ${selected ? '#1d4ed8' : '#d1d5db'}`,\n background: selected ? '#dbeafe' : '#ffffff',\n color: selected ? '#1d4ed8' : '#111827',\n borderRadius: 8,\n minWidth: 36,\n height: 36,\n padding: '0 10px',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n fontWeight: 600,\n }}\n aria-label={`Rate ${value}`}\n >\n {value}\n </button>\n );\n })}\n\n {ratingType === 'emoji' && emojiChoices.map((emoji, index) => {\n const value = index + 1;\n const selected = value === rating;\n return (\n <button\n key={`${emoji}-${index}`}\n onClick={() => onRate(value)}\n style={{\n border: `1px solid ${selected ? '#1d4ed8' : '#d1d5db'}`,\n background: selected ? '#dbeafe' : '#ffffff',\n borderRadius: '999px',\n width: 44,\n height: 44,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n fontSize: 22,\n }}\n aria-label={`Emoji rating ${index + 1}`}\n >\n {emoji}\n </button>\n );\n })}\n </div>\n\n {rating > 0 && (\n <div style={{ marginTop: 6, textAlign: 'center', color: '#374151', fontSize: 14 }}>\n {isHighRating ? (details.highStarText || ratingStyle.highRatingSubtitle) : (details.lowStarText || ratingStyle.lowRatingSubtitle)}\n </div>\n )}\n\n {rating > 0 && rating <= LOW_RATING_CUTOFF && (\n <>\n {feedbackOptions.length > 0 && (\n <div\n style={{\n ...spacingToStyle(feedbackPage.options?.margin),\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'stretch',\n gap: feedbackPage.options?.optionsSpacing ?? 8,\n width: '100%',\n }}\n >\n {feedbackOptions.map((option) => {\n const isActive = selectedOptions.includes(option);\n const styleSource = isActive ? feedbackPage.options?.selectedOptions : feedbackPage.options?.nonSelectedOptions;\n\n return (\n <button\n key={option}\n onClick={() => onToggleOption(option)}\n style={{\n border: `${styleSource?.borderWidth ?? 1}px solid ${styleSource?.colors?.border || '#d1d5db'}`,\n background: styleSource?.colors?.background || '#f9fafb',\n color: styleSource?.colors?.text || '#111827',\n width: '100%',\n height: feedbackPage.options?.optionsHeight || 38,\n borderRadius: getCornerRadius(feedbackPage.options?.cornerRadius),\n padding: '0 14px',\n cursor: 'pointer',\n textAlign: 'center',\n ...(textStyleToCss(styleSource?.textStyle)),\n }}\n >\n {option}\n </button>\n );\n })}\n </div>\n )}\n\n <textarea\n value={comments}\n onChange={(event) => onCommentChange(event.target.value)}\n placeholder={feedbackPage.additionalComments?.placeholder || 'Tell us what we can improve'}\n style={{\n width: '100%',\n boxSizing: 'border-box',\n minHeight: 56,\n height: 56,\n maxHeight: 64,\n marginTop: 8,\n resize: 'none',\n overflowY: 'auto',\n border: `${feedbackPage.additionalComments?.borderWidth ?? 1}px solid ${feedbackPage.additionalComments?.colors?.border || '#d1d5db'}`,\n background: feedbackPage.additionalComments?.colors?.background || '#ffffff',\n color: feedbackPage.additionalComments?.colors?.text || '#111827',\n borderRadius: 8,\n padding: '12px',\n ...(textStyleToCss(feedbackPage.additionalComments?.textStyle)),\n }}\n />\n\n <div\n style={{\n position: 'sticky',\n bottom: 0,\n marginTop: 8,\n paddingTop: 6,\n paddingBottom: 6,\n background: appearance?.backgroundColor || '#2f6ef5',\n display: 'flex',\n justifyContent: 'center',\n }}\n >\n <button\n onClick={() => onInlineSubmit()}\n disabled={!canSubmit}\n style={{\n width: Math.max(140, Math.min(asNonNegativeNumber(submitCta?.container?.ctaWidth) ?? 180, 220)),\n maxWidth: '100%',\n minHeight: 30,\n height: Math.max(30, Math.min(Number(submitCta?.container?.height) || 34, 34)),\n border: `${submitCta?.container?.borderWidth ?? 1}px solid ${submitCta?.container?.borderColor || '#ff7a00'}`,\n background: submitCta?.container?.backgroundColor || '#ff2bc2',\n color: submitCta?.text?.color || '#ffffff',\n borderRadius: getCornerRadius(submitCta?.cornerRadius),\n fontFamily: applyFontFamily(submitCta?.text?.fontFamily),\n fontSize: Math.min(Number(submitCta?.text?.fontSize) || 14, 14),\n fontWeight: submitCta?.text?.fontDecoration?.includes('bold') ? 'bold' : 600,\n cursor: canSubmit ? 'pointer' : 'not-allowed',\n opacity: canSubmit ? 1 : 0.65,\n padding: '0 12px',\n }}\n >\n {feedbackPage.submitButton?.text || 'Submit'}\n </button>\n </div>\n </>\n )}\n\n </>\n );\n};\n\ninterface ThankYouContentProps {\n details: CsatCampaignDetails;\n isHighRating: boolean;\n onDone: () => void;\n}\n\nconst CsatThankYouContent: React.FC<ThankYouContentProps> = ({ details, isHighRating, onDone }) => {\n const styling = details.styling || {};\n const thankyouPage = styling.thankyouPage || {};\n const ratingStyle = styling.rating || {};\n const doneAlign = getAlignment(thankyouPage.doneButton?.cta?.container?.alignment);\n\n return (\n <>\n {details.thankyouImage && (\n <div style={{ display: 'flex', justifyContent: 'center', marginTop: 6 }}>\n <img\n src={details.thankyouImage}\n alt=\"thank you\"\n style={{\n width: thankyouPage.imageStyle?.width || 80,\n height: thankyouPage.imageStyle?.height || 80,\n objectFit: 'cover',\n borderRadius: 8,\n }}\n />\n </div>\n )}\n\n <div style={{ ...spacingToStyle(thankyouPage.title?.margin), textAlign: 'center' }}>\n <div\n style={{\n ...(textStyleToCss(thankyouPage.title?.textStyle)),\n color: thankyouPage.title?.textStyle?.color || '#111827',\n fontSize: thankyouPage.title?.textStyle?.fontSize || 20,\n fontWeight: thankyouPage.title?.textStyle?.fontDecoration?.includes('bold') ? 'bold' : 600,\n }}\n >\n {details.thankyouText || (isHighRating ? ratingStyle.highRatingTitle : ratingStyle.lowRatingTitle) || 'Thank you for your feedback'}\n </div>\n </div>\n\n <div style={{ ...spacingToStyle(thankyouPage.subtitle?.margin), textAlign: 'center' }}>\n <div\n style={{\n ...(textStyleToCss(thankyouPage.subtitle?.textStyle)),\n color: thankyouPage.subtitle?.textStyle?.color || '#4b5563',\n fontSize: thankyouPage.subtitle?.textStyle?.fontSize || 14,\n }}\n >\n {details.thankyouDescription || (isHighRating ? ratingStyle.highRatingSubtitle : ratingStyle.lowRatingSubtitle) || 'We appreciate your time.'}\n </div>\n </div>\n\n <div\n style={{\n marginTop: thankyouPage.doneButton?.cta?.margin?.top ?? 14,\n marginBottom: thankyouPage.doneButton?.cta?.margin?.bottom ?? 0,\n marginLeft: thankyouPage.doneButton?.cta?.margin?.left ?? 0,\n marginRight: thankyouPage.doneButton?.cta?.margin?.right ?? 0,\n display: 'flex',\n justifyContent: doneAlign,\n }}\n >\n <button\n onClick={onDone}\n style={{\n width: thankyouPage.doneButton?.cta?.container?.ctaFullWidth ? '100%' : thankyouPage.doneButton?.cta?.container?.ctaWidth || 'auto',\n height: thankyouPage.doneButton?.cta?.container?.height || 45,\n border: `${thankyouPage.doneButton?.cta?.container?.borderWidth ?? 0}px solid ${thankyouPage.doneButton?.cta?.container?.borderColor || 'transparent'}`,\n background: thankyouPage.doneButton?.cta?.container?.backgroundColor || '#111827',\n color: thankyouPage.doneButton?.cta?.text?.color || '#ffffff',\n borderRadius: getCornerRadius(thankyouPage.doneButton?.cta?.cornerRadius),\n fontFamily: applyFontFamily(thankyouPage.doneButton?.cta?.text?.fontFamily),\n fontSize: thankyouPage.doneButton?.cta?.text?.fontSize || 16,\n fontWeight: thankyouPage.doneButton?.cta?.text?.fontDecoration?.includes('bold') ? 'bold' : 500,\n cursor: 'pointer',\n padding: '0 16px',\n }}\n >\n {thankyouPage.doneButton?.text || (isHighRating ? 'Rate Now' : 'Done')}\n </button>\n </div>\n </>\n );\n};\n\nexport const Csat: React.FC = () => {\n const hookData = useCampaigns<CampaignCsat>('CSAT');\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n\n const data = hookData ?? ((): CampaignCsat | undefined => {\n const screen = (currentScreen || '').trim().toLowerCase();\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign: any) => {\n if (!campaign) return false;\n if (campaign.campaign_type !== 'CSAT') return false;\n const hasTrigger = Boolean(campaign.trigger_event ?? campaign.trigger);\n const displayTriggerReady = (campaign as any).display_trigger !== false && !hasTrigger;\n if (!displayTriggerReady) return false;\n const cs = (campaign.screen || '').trim().toLowerCase();\n return !cs || cs === screen;\n }) as CampaignCsat | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignCsat;\n } catch {\n return found;\n }\n })();\n\n const [isDismissed, setIsDismissed] = useState(false);\n const [canDisplay, setCanDisplay] = useState(false);\n const [rating, setRating] = useState(0);\n const [selectedOptions, setSelectedOptions] = useState<string[]>([]);\n const [comments, setComments] = useState('');\n const [isSubmitted, setIsSubmitted] = useState(false);\n\n useEffect(() => {\n if (!data) return;\n setIsDismissed(false);\n setCanDisplay(false);\n setRating(0);\n setSelectedOptions([]);\n setComments('');\n setIsSubmitted(false);\n\n const delay = data.details?.styling?.appearance?.displayDelay ?? 0;\n const timeoutId = globalThis.setTimeout(() => {\n setCanDisplay(true);\n void trackEvent('viewed', data.id);\n }, Math.max(0, delay) * 1000);\n\n return () => globalThis.clearTimeout(timeoutId);\n }, [data]);\n\n const feedbackOptions = useMemo(() => {\n const source = data?.details?.feedback_option || {};\n return Object.keys(source)\n .sort((a, b) => a.localeCompare(b))\n .map((key) => source[key])\n .filter(Boolean);\n }, [data]);\n\n if (!data || !sdkVisible || isDismissed || !canDisplay) return null;\n\n const details = data.details;\n const styling = details.styling || {};\n const appearance = styling.appearance || {};\n\n const isHighRating = rating > LOW_RATING_CUTOFF;\n\n const configuredWidth = Number(details.width ?? 80);\n const compactCardWidth = Math.max(660, Math.min(1080, configuredWidth * 10));\n\n const handleToggleOption = (option: string) => {\n setSelectedOptions((prev) => (prev.includes(option) ? prev.filter((item) => item !== option) : [...prev, option]));\n };\n\n const handleSubmit = async (override?: { rating?: number; options?: string[]; comments?: string }) => {\n const ratingValue = override?.rating ?? rating;\n if (ratingValue < 1) return;\n setIsSubmitted(true);\n\n const campaignId = details.id || data.id;\n const selectedOption = (override?.options ?? selectedOptions)[0] || \"\";\n const additionalComments = override?.comments ?? comments ?? \"\";\n\n void trackEvent('csat captured', campaignId, {\n starCount: ratingValue,\n selectedOption: selectedOption,\n additionalComments: additionalComments,\n });\n };\n\n const handleRate = (value: number) => {\n setRating(value);\n if (value > LOW_RATING_CUTOFF) {\n setSelectedOptions([]);\n setComments('');\n // Mirror RN: show thanks after 1s and send `csat captured` with RN keys\n const campaignId = details.id || data?.id;\n setTimeout(() => {\n setIsSubmitted(true);\n try {\n void trackEvent('csat captured', campaignId, {\n starCount: value,\n selectedOption: \"\",\n additionalComments: \"\",\n });\n } catch (e) {\n console.warn('Error sending csat captured', e);\n }\n }, 1000);\n }\n };\n\n const handleDone = () => {\n if (isHighRating && details.link) {\n const campaignId = (data && data.id) || undefined;\n try {\n if (campaignId) void trackEvent('clicked', campaignId);\n } catch (err) {\n // ignore track errors\n }\n\n try {\n const link = String(details.link || '').trim();\n if (link && !link.startsWith('http')) {\n const revealed = revealCampaignFromLink(link);\n if (revealed) {\n setIsDismissed(true);\n return;\n }\n }\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n try {\n globalThis.open(details.link, '_blank');\n } catch (err) {\n // ignore\n }\n }\n\n setIsDismissed(true);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 999999,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'flex-end',\n paddingLeft: '10px',\n paddingRight: '10px',\n paddingBottom: '10px',\n pointerEvents: 'none',\n }}\n >\n <div\n style={{\n position: 'relative',\n width: `min(${compactCardWidth}px, 96vw)`,\n maxWidth: '96vw',\n minWidth: '320px',\n minHeight: '220px',\n maxHeight: '55vh',\n overflow: 'hidden',\n backgroundColor: appearance.backgroundColor || '#2f6ef5',\n borderRadius: `${appearance.borderRadius ?? 12}px`,\n boxSizing: 'border-box',\n paddingTop: '8px',\n paddingRight: asSpacingValue(appearance.padding?.right) || '12px',\n paddingBottom: '4px',\n paddingLeft: asSpacingValue(appearance.padding?.left) || '12px',\n marginTop: asSpacingValue(appearance.margin?.top),\n marginRight: asSpacingValue(appearance.margin?.right),\n marginBottom: asSpacingValue(appearance.margin?.bottom),\n marginLeft: asSpacingValue(appearance.margin?.left),\n pointerEvents: 'auto',\n boxShadow: '0 14px 36px rgba(0, 0, 0, 0.25)',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <style>\n {`\n .appstorys-csat-scroll {\n scrollbar-width: none; /* Firefox */\n -ms-overflow-style: none; /* IE/Edge */\n }\n .appstorys-csat-scroll::-webkit-scrollbar {\n width: 0;\n height: 0;\n display: none; /* Chrome/Safari */\n }\n `}\n </style>\n\n {styling.crossButton?.enabled && (\n <CrossButton\n config={styling.crossButton}\n onPress={() => setIsDismissed(true)}\n style={{\n top: styling.crossButton?.margin?.top ?? 10,\n right: styling.crossButton?.margin?.right ?? 10,\n }}\n />\n )}\n\n <div\n className=\"appstorys-csat-scroll\"\n style={{\n flex: 1,\n minHeight: 0,\n overflowY: 'auto',\n paddingBottom: 4,\n }}\n >\n {isSubmitted ? (\n <CsatThankYouContent\n details={details}\n isHighRating={isHighRating}\n onDone={handleDone}\n />\n ) : (\n <CsatFormContent\n details={details}\n rating={rating}\n selectedOptions={selectedOptions}\n comments={comments}\n isHighRating={isHighRating}\n feedbackOptions={feedbackOptions}\n onRate={handleRate}\n onToggleOption={handleToggleOption}\n onCommentChange={setComments}\n onInlineSubmit={handleSubmit}\n canSubmit={rating >= 1}\n appearance={appearance}\n />\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default Csat;\n","import React, { useEffect, useMemo, useState } from 'react';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport CrossButton from '../common/CommonElements/CrossButton';\nimport { CampaignSurvey, SurveyCampaignDetails, SurveySlide, SurveyTextStyle } from '../../types';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport { resolveFontFamily } from '../../core/fontManager';\n\nfunction asSpacingValue(value?: number): string | undefined {\n if (value == null) return undefined;\n return `${value}px`;\n}\n\nfunction applyFontFamily(fontFamily?: string): string | undefined {\n return resolveFontFamily(fontFamily);\n}\n\nfunction textStyleToCss(textStyle?: SurveyTextStyle): React.CSSProperties {\n if (!textStyle) return {};\n\n return {\n color: textStyle.color,\n fontSize: textStyle.fontSize,\n fontFamily: applyFontFamily(textStyle.fontFamily),\n textAlign: textStyle.textAlign as React.CSSProperties['textAlign'],\n fontWeight: textStyle.fontDecoration?.includes('bold') ? 'bold' : undefined,\n fontStyle: textStyle.fontDecoration?.includes('italic') ? 'italic' : undefined,\n textDecoration: textStyle.fontDecoration?.includes('underline') ? 'underline' : undefined,\n };\n}\n\nfunction marginToStyle(margin?: SurveyTextStyle['margin']): React.CSSProperties {\n return {\n marginTop: asSpacingValue(margin?.top),\n marginRight: asSpacingValue(margin?.right),\n marginBottom: asSpacingValue(margin?.bottom),\n marginLeft: asSpacingValue(margin?.left),\n };\n}\n\nfunction getCornerRadius(cornerRadius?: { topLeft?: number; topRight?: number; bottomRight?: number; bottomLeft?: number }): string {\n return `${cornerRadius?.topLeft ?? 12}px ${cornerRadius?.topRight ?? 12}px ${cornerRadius?.bottomRight ?? cornerRadius?.topRight ?? 12}px ${cornerRadius?.bottomLeft ?? cornerRadius?.topLeft ?? 12}px`;\n}\n\nfunction getAlignment(alignment?: string): React.CSSProperties['justifyContent'] {\n if (alignment === 'right') return 'flex-end';\n if (alignment === 'left') return 'flex-start';\n return 'center';\n}\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction hexToRgba(hex: string, alpha: number): string {\n const raw = (hex || '').trim().replace('#', '');\n if (raw.length === 3) {\n const r = Number.parseInt(raw[0] + raw[0], 16);\n const g = Number.parseInt(raw[1] + raw[1], 16);\n const b = Number.parseInt(raw[2] + raw[2], 16);\n return `rgba(${r}, ${g}, ${b}, ${clamp01(alpha)})`;\n }\n\n if (raw.length === 6) {\n const r = Number.parseInt(raw.slice(0, 2), 16);\n const g = Number.parseInt(raw.slice(2, 4), 16);\n const b = Number.parseInt(raw.slice(4, 6), 16);\n return `rgba(${r}, ${g}, ${b}, ${clamp01(alpha)})`;\n }\n\n return `rgba(0, 0, 0, ${clamp01(alpha)})`;\n}\n\nfunction normalizeBackdropOpacity(opacity?: number): number {\n if (opacity == null) return 0.4;\n const value = Number(opacity);\n if (!Number.isFinite(value)) return 0.4;\n if (value > 1) return clamp01(value / 100);\n return clamp01(value);\n}\n\nfunction getOrderedSlides(details: SurveyCampaignDetails): SurveySlide[] {\n const slides = details.slides || [];\n return [...slides].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n}\n\nfunction getOrderedOptions(slide?: SurveySlide): string[] {\n const options = slide?.options || {};\n const keys = Object.keys(options);\n\n const parseIndex = (key: string): number | undefined => {\n const match = /(\\d+)/.exec(key);\n if (!match) return undefined;\n const parsed = Number(match[1]);\n return Number.isFinite(parsed) ? parsed : undefined;\n };\n\n keys.sort((a, b) => {\n const ai = parseIndex(a);\n const bi = parseIndex(b);\n\n if (ai != null && bi != null) return ai - bi;\n if (ai != null) return -1;\n if (bi != null) return 1;\n return a.localeCompare(b);\n });\n\n return keys\n .map((key) => options[key])\n .filter((value): value is string => typeof value === 'string' && value.trim().length > 0);\n}\n\nfunction getBulletLabel(optionListStyle: string | undefined, index: number): string | null {\n if (!optionListStyle) return null;\n\n if (optionListStyle === 'alphabet') {\n const start = 'A'.codePointAt(0) ?? 65;\n return String.fromCodePoint(start + (index % 26));\n }\n\n if (optionListStyle === 'number') {\n return String(index + 1);\n }\n\n return null;\n}\n\nfunction asNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value;\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value);\n if (Number.isFinite(parsed) && parsed >= 0) return parsed;\n }\n return undefined;\n}\n\nfunction getBorderWidthFromTextStyle(textStyle?: SurveyTextStyle): number {\n return asNonNegativeNumber(textStyle?.borderwidth) ?? 1;\n}\n\ninterface SurveyResponsesMap {\n [slideId: string]: {\n option?: string;\n comment?: string;\n };\n}\n\ninterface SurveyFormContentProps {\n details: SurveyCampaignDetails;\n slide: SurveySlide;\n appearance?: SurveyCampaignDetails['styling'] extends { appearance?: infer A } ? A : any;\n selectedOption: string | null;\n comment: string;\n onSelectOption: (option: string) => void;\n onCommentChange: (value: string) => void;\n onSubmit: () => void;\n canSubmit: boolean;\n}\n\nconst SurveyFormContent: React.FC<SurveyFormContentProps> = ({\n details,\n slide,\n appearance,\n selectedOption,\n comment,\n onSelectOption,\n onCommentChange,\n onSubmit,\n canSubmit,\n}) => {\n const styling = details.styling || {};\n const optionsStyle = styling.options || {};\n const cta = styling.cta;\n\n const options = useMemo(() => getOrderedOptions(slide), [slide]);\n const optionRowGap = optionsStyle.optionsSpacing ?? 8;\n const bulletGap = optionsStyle.bulletSpacing ?? 10;\n const optionHeight = optionsStyle.optionsHeight ?? 44;\n\n const ctaAlign = getAlignment(cta?.container?.alignment);\n\n return (\n <>\n <div style={marginToStyle(styling.title?.textStyle?.margin)}>\n <div\n style={{\n ...(textStyleToCss(styling.title?.textStyle)),\n color: styling.title?.textStyle?.color || '#111827',\n fontSize: styling.title?.textStyle?.fontSize || 20,\n lineHeight: 1.3,\n fontWeight: styling.title?.textStyle?.fontDecoration?.includes('bold') ? 'bold' : 700,\n }}\n >\n {slide.title || slide.question || details.name || 'Survey'}\n </div>\n </div>\n\n {(slide.subtitle || styling.subtitle?.textStyle) && (\n <div style={marginToStyle(styling.subtitle?.textStyle?.margin)}>\n <div\n style={{\n ...(textStyleToCss(styling.subtitle?.textStyle)),\n color: styling.subtitle?.textStyle?.color || '#6b7280',\n fontSize: styling.subtitle?.textStyle?.fontSize || 14,\n lineHeight: 1.35,\n }}\n >\n {slide.subtitle || ''}\n </div>\n </div>\n )}\n\n {options.length > 0 && (\n <div\n style={{\n marginTop: 10,\n display: 'flex',\n flexDirection: 'column',\n gap: optionRowGap,\n }}\n >\n {options.map((option, index) => {\n const isActive = selectedOption === option;\n const styleSource = isActive ? optionsStyle.selectedOptions : optionsStyle.nonSelectedOptions;\n const borderWidth = getBorderWidthFromTextStyle(styleSource?.textStyle);\n const bulletLabel = getBulletLabel(optionsStyle.optionListStyle, index);\n\n return (\n <button\n key={`${option}-${index}`}\n onClick={() => onSelectOption(option)}\n style={{\n width: '100%',\n boxSizing: 'border-box',\n height: optionHeight,\n borderRadius: getCornerRadius(optionsStyle.cornerRadius),\n border: `${borderWidth}px solid ${styleSource?.colors?.border || '#e5e7eb'}`,\n background: styleSource?.colors?.background || '#ffffff',\n color: styleSource?.colors?.text || '#111827',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: bulletGap,\n paddingLeft: 14,\n paddingRight: 14,\n textAlign: 'left',\n ...(textStyleToCss(styleSource?.textStyle)),\n }}\n aria-pressed={isActive}\n >\n <span\n aria-hidden\n style={{\n width: 16,\n height: 16,\n borderRadius: 4,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: `1.5px solid ${styleSource?.colors?.border || '#111827'}`,\n background: '#ffffff',\n flex: '0 0 auto',\n fontSize: 11,\n fontWeight: 700,\n color: styleSource?.colors?.text || '#111827',\n }}\n >\n {isActive ? '✓' : (bulletLabel || '')}\n </span>\n\n <span style={{ flex: 1, minWidth: 0 }}>{option}</span>\n </button>\n );\n })}\n </div>\n )}\n\n {slide.additionalComment?.enabled && (\n <textarea\n value={comment}\n onChange={(event) => onCommentChange(event.target.value)}\n placeholder={slide.additionalComment?.placeholder || ''}\n style={{\n marginTop: 10,\n width: '100%',\n boxSizing: 'border-box',\n minHeight: 72,\n resize: 'none',\n overflowY: 'auto',\n border: `${getBorderWidthFromTextStyle(optionsStyle.additionalComments?.textStyle)}px solid ${optionsStyle.additionalComments?.colors?.border || '#e5e7eb'}`,\n background: optionsStyle.additionalComments?.colors?.background || '#ffffff',\n color: optionsStyle.additionalComments?.colors?.text || '#111827',\n borderRadius: 10,\n padding: '12px',\n ...(textStyleToCss(optionsStyle.additionalComments?.textStyle)),\n }}\n />\n )}\n\n <div\n style={{\n position: 'sticky',\n bottom: 0,\n marginTop: 12,\n paddingTop: 10,\n paddingBottom: 6,\n background: appearance?.backgroundColor || '#ffffff',\n }}\n >\n <div\n style={{\n marginTop: cta?.margin?.top ?? 0,\n marginBottom: cta?.margin?.bottom ?? 0,\n marginLeft: cta?.margin?.left ?? 0,\n marginRight: cta?.margin?.right ?? 0,\n display: 'flex',\n justifyContent: ctaAlign,\n }}\n >\n <button\n onClick={onSubmit}\n disabled={!canSubmit}\n style={{\n width: cta?.container?.ctaFullWidth ? '100%' : (cta?.container?.ctaWidth ?? '100%'),\n height: cta?.container?.height ?? 44,\n border: `${cta?.container?.borderWidth ?? 0}px solid ${cta?.container?.borderColor || 'transparent'}`,\n background: cta?.container?.backgroundColor || '#111827',\n color: cta?.text?.color || '#ffffff',\n borderRadius: getCornerRadius(cta?.cornerRadius),\n fontFamily: applyFontFamily(cta?.text?.fontFamily),\n fontSize: cta?.text?.fontSize || 14,\n fontWeight: cta?.text?.fontDecoration?.includes('bold') ? 'bold' : 600,\n cursor: canSubmit ? 'pointer' : 'not-allowed',\n opacity: canSubmit ? 1 : 0.6,\n padding: '0 16px',\n }}\n >\n {slide.submitButtonText || 'Submit'}\n </button>\n </div>\n </div>\n </>\n );\n};\n\ninterface SurveyThankYouContentProps {\n details: SurveyCampaignDetails;\n onDone: () => void;\n}\n\nconst SurveyThankYouContent: React.FC<SurveyThankYouContentProps> = ({ details, onDone }) => {\n const styling = details.styling || {};\n const thankyouPage = styling.thankyouPage || {};\n\n const cta = thankyouPage.cta;\n const ctaAlign = getAlignment(cta?.container?.alignment);\n\n return (\n <>\n {details.thankYouImage && (\n <div style={{ display: 'flex', justifyContent: 'center', marginTop: 8 }}>\n <img\n src={details.thankYouImage}\n alt=\"thank you\"\n style={{\n width: thankyouPage.imageStyle?.width || 80,\n height: thankyouPage.imageStyle?.height || 80,\n objectFit: 'cover',\n borderRadius: 10,\n }}\n />\n </div>\n )}\n\n <div style={{ ...marginToStyle(thankyouPage.title?.textStyle?.margin) }}>\n <div\n style={{\n ...(textStyleToCss(thankyouPage.title?.textStyle)),\n color: thankyouPage.title?.textStyle?.color || '#111827',\n fontSize: thankyouPage.title?.textStyle?.fontSize || 20,\n lineHeight: 1.3,\n fontWeight: thankyouPage.title?.textStyle?.fontDecoration?.includes('bold') ? 'bold' : 700,\n }}\n >\n {details.thankYouTitle || 'Thank you'}\n </div>\n </div>\n\n <div style={{ ...marginToStyle(thankyouPage.subtitle?.textStyle?.margin) }}>\n <div\n style={{\n ...(textStyleToCss(thankyouPage.subtitle?.textStyle)),\n color: thankyouPage.subtitle?.textStyle?.color || '#6b7280',\n fontSize: thankyouPage.subtitle?.textStyle?.fontSize || 14,\n lineHeight: 1.35,\n }}\n >\n {details.thankYouText || ''}\n </div>\n </div>\n\n {(details.thankYouButtonText || cta) && (\n <div\n style={{\n marginTop: cta?.margin?.top ?? 14,\n marginBottom: cta?.margin?.bottom ?? 0,\n marginLeft: cta?.margin?.left ?? 0,\n marginRight: cta?.margin?.right ?? 0,\n display: 'flex',\n justifyContent: ctaAlign,\n }}\n >\n <button\n onClick={onDone}\n style={{\n width: cta?.container?.ctaFullWidth ? '100%' : (cta?.container?.ctaWidth ?? 'auto'),\n height: cta?.container?.height ?? 40,\n border: `${cta?.container?.borderWidth ?? 0}px solid ${cta?.container?.borderColor || 'transparent'}`,\n background: cta?.container?.backgroundColor || '#111827',\n color: cta?.text?.color || '#ffffff',\n borderRadius: getCornerRadius(cta?.cornerRadius),\n fontFamily: applyFontFamily(cta?.text?.fontFamily),\n fontSize: cta?.text?.fontSize || 14,\n fontWeight: cta?.text?.fontDecoration?.includes('bold') ? 'bold' : 600,\n cursor: 'pointer',\n padding: '0 16px',\n }}\n >\n {details.thankYouButtonText || 'Done'}\n </button>\n </div>\n )}\n </>\n );\n};\n\nexport const Survey: React.FC = () => {\n const hookData = useCampaigns<CampaignSurvey>('SUR');\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n\n const data = hookData ?? ((): CampaignSurvey | undefined => {\n const screen = (currentScreen || '').trim().toLowerCase();\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign: any) => {\n if (!campaign) return false;\n if (campaign.campaign_type !== 'SUR') return false;\n const hasTrigger = Boolean(campaign.trigger_event ?? campaign.trigger);\n const displayTriggerReady = (campaign as any).display_trigger !== false && !hasTrigger;\n if (!displayTriggerReady) return false;\n const cs = (campaign.screen || '').trim().toLowerCase();\n return !cs || cs === screen;\n }) as CampaignSurvey | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignSurvey;\n } catch {\n return found;\n }\n })();\n\n const [isDismissed, setIsDismissed] = useState(false);\n const [canDisplay, setCanDisplay] = useState(false);\n const [currentIndex, setCurrentIndex] = useState(0);\n const [selectedOption, setSelectedOption] = useState<string | null>(null);\n const [comment, setComment] = useState('');\n const [responses, setResponses] = useState<SurveyResponsesMap>({});\n const [isSubmitted, setIsSubmitted] = useState(false);\n\n useEffect(() => {\n if (!data) return;\n\n setIsDismissed(false);\n setCanDisplay(false);\n setCurrentIndex(0);\n setSelectedOption(null);\n setComment('');\n setResponses({});\n setIsSubmitted(false);\n\n const delay = data.details?.styling?.appearance?.displayDelay ?? 0;\n const timeoutId = globalThis.setTimeout(() => {\n setCanDisplay(true);\n // Include survey identifiers in initial view event so backend can map impressions\n const surveyId = data.details?.id;\n const orderedSlides = getOrderedSlides(data.details);\n const firstSlideId = orderedSlides.length > 0 ? orderedSlides[0].id : undefined;\n void trackEvent('viewed', data.id, {\n survey_id: surveyId,\n slide_id: firstSlideId,\n });\n }, Math.max(0, delay) * 1000);\n\n return () => globalThis.clearTimeout(timeoutId);\n }, [data]);\n\n const slides = useMemo(() => (data ? getOrderedSlides(data.details) : []), [data]);\n const slide = slides[currentIndex];\n\n useEffect(() => {\n if (!slide) return;\n const existing = responses[slide.id];\n setSelectedOption(existing?.option ?? null);\n setComment(existing?.comment ?? '');\n }, [slide?.id]);\n\n if (!data || !sdkVisible || isDismissed || !canDisplay) return null;\n\n const details: SurveyCampaignDetails = data.details;\n const styling = details.styling || {};\n const appearance = styling.appearance || {};\n\n const backdropColor = appearance.backdropColor || '#000000';\n const backdropOpacity = normalizeBackdropOpacity(appearance.backdropOpacity);\n\n const handleSelectOption = (option: string) => {\n setSelectedOption((prev) => (prev === option ? null : option));\n };\n\n const submitSurvey = async (finalResponses: SurveyResponsesMap, finalSlideId: string) => {\n const responsesArray = slides.map((s) => ({\n slide_id: s.id,\n order: s.order,\n title: s.title,\n question: s.question,\n selected_options: finalResponses[s.id]?.option,\n comment: finalResponses[s.id]?.comment,\n }));\n\n // Use top-level campaign id for capture payload (campaign_id)\n const campaignId = data.id;\n\n // Mirror RN: include selected options and any 'other' text in metadata\n // Map selected option values back to their option keys (option1, option2, ...)\n const selectedOptionsKeys: string[] = [];\n for (const s of slides) {\n const selectedValue = finalResponses[s.id]?.option;\n if (!selectedValue) continue;\n const optionEntry = Object.entries(s.options || {}).find(([, val]) => String(val) === String(selectedValue));\n if (optionEntry) selectedOptionsKeys.push(optionEntry[0]);\n }\n const otherText = responsesArray.map(r => r.comment).filter(Boolean as any).join(' || ') || \"\";\n\n // Send survey identifiers and captured answers (match native `survey captured`)\n const captureCampaignId = details.id || campaignId;\n void trackEvent('survey captured', captureCampaignId, {\n survey_id: details.id,\n slide_id: finalSlideId,\n selected_options: selectedOptionsKeys,\n otherText,\n });\n\n const shouldShowThankYou = styling.content?.isThankyouPage !== false;\n if (shouldShowThankYou) {\n setIsSubmitted(true);\n } else {\n setIsDismissed(true);\n }\n };\n\n const handleSubmitCurrent = async () => {\n if (!slide) return;\n if (!selectedOption) return;\n\n const nextResponses: SurveyResponsesMap = {\n ...responses,\n [slide.id]: {\n option: selectedOption,\n comment,\n },\n };\n\n setResponses(nextResponses);\n\n // Send a capture event for the current slide (mirror RN per-slide capture behavior)\n try {\n const campaignId = data.id;\n // map the selected option value to its key\n let optionKey: string | null = null;\n if (selectedOption && slide && slide.options) {\n const found = Object.entries(slide.options).find(([, val]) => String(val) === String(selectedOption));\n if (found) optionKey = found[0];\n }\n // Per-slide capture: use native `survey captured` with details.id as campaign id\n const perSlideCampaignId = details.id || campaignId;\n void trackEvent('survey captured', perSlideCampaignId, {\n survey_id: details.id,\n slide_id: slide.id,\n selected_options: optionKey ? [optionKey] : [],\n otherText: comment || \"\",\n });\n } catch (e) {\n console.warn('Error sending per-slide survey captured', e);\n }\n\n const rules = slide.logic || [];\n const matchedRule = rules.find((rule) =>\n (rule.selectOption || []).includes(selectedOption)\n );\n\n if (matchedRule?.redirectTo === 'thank-you') {\n await submitSurvey(nextResponses, slide.id);\n return;\n }\n\n const isLastSlide = currentIndex >= slides.length - 1;\n if (isLastSlide) {\n await submitSurvey(nextResponses, slide.id);\n return;\n }\n\n setCurrentIndex((prev) => Math.min(prev + 1, slides.length - 1));\n };\n\n const handleDone = () => {\n const config = details.thankYouButtonConfig;\n if (config?.enabled && config.redirectUrl) {\n try {\n const redirect = String(config.redirectUrl || '').trim();\n if (redirect && !redirect.startsWith('http')) {\n const revealed = revealCampaignFromLink(redirect);\n if (revealed) {\n setIsDismissed(true);\n return;\n }\n }\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n try {\n globalThis.open(config.redirectUrl, '_blank');\n } catch (err) {\n // ignore\n }\n }\n setIsDismissed(true);\n };\n\n const handleDismiss = async () => {\n try {\n const campaignId = data?.id;\n const surveyId = details?.id;\n const slideId = slide?.id;\n await trackEvent('SurveyDismissed', campaignId, {\n survey_id: surveyId,\n slide_id: slideId,\n });\n } catch (err) {\n console.warn('Error sending SurveyDismissed', err);\n } finally {\n setIsDismissed(true);\n }\n };\n\n if (!slide) return null;\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 999999,\n display: 'flex',\n justifyContent: 'flex-end',\n alignItems: 'flex-end',\n padding: 12,\n pointerEvents: 'none',\n }}\n >\n <div\n aria-hidden\n style={{\n position: 'absolute',\n inset: 0,\n background: hexToRgba(backdropColor, backdropOpacity),\n }}\n />\n\n <div\n style={{\n position: 'relative',\n width: 'min(420px, 92vw)',\n maxWidth: '92vw',\n minWidth: '320px',\n maxHeight: '80vh',\n overflow: 'hidden',\n backgroundColor: appearance.backgroundColor || '#ffffff',\n borderRadius: getCornerRadius(appearance.cornerRadius),\n boxSizing: 'border-box',\n paddingTop: 14,\n paddingRight: 16,\n paddingBottom: 10,\n paddingLeft: 16,\n pointerEvents: 'auto',\n boxShadow: '0 14px 36px rgba(0, 0, 0, 0.25)',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <style>\n {`\n .appstorys-survey-scroll {\n scrollbar-width: none; /* Firefox */\n -ms-overflow-style: none; /* IE/Edge */\n }\n .appstorys-survey-scroll::-webkit-scrollbar {\n width: 0;\n height: 0;\n display: none; /* Chrome/Safari */\n }\n `}\n </style>\n\n {styling.crossButton?.enabled && (\n <CrossButton\n config={styling.crossButton}\n onPress={handleDismiss}\n style={{\n top: styling.crossButton?.margin?.top ?? 10,\n right: styling.crossButton?.margin?.right ?? 10,\n }}\n />\n )}\n\n <div\n className=\"appstorys-survey-scroll\"\n style={{\n flex: 1,\n minHeight: 0,\n overflowY: 'auto',\n paddingRight: 2,\n }}\n >\n {isSubmitted ? (\n <SurveyThankYouContent details={details} onDone={handleDone} />\n ) : (\n <SurveyFormContent\n details={details}\n slide={slide}\n appearance={appearance}\n selectedOption={selectedOption}\n comment={comment}\n onSelectOption={handleSelectOption}\n onCommentChange={setComment}\n onSubmit={handleSubmitCurrent}\n canSubmit={selectedOption != null}\n />\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default Survey;\n"],"mappings":"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","names":["WebStorage","init_storage","__esmMin","key","value","getUserId","useAppStorysStore","getAccessToken","WebStorage","getVariantId","campaignId","id","import_zustand","store_default","init_store","__esmMin","init_storage","set","campaigns","version","userId","appId","accountId","currentScreen","attributes","trackedEvents","trackedEventMetadata","isVisible","isAnonymousUser","variantMappings","personalizationData","enabled","baseUrl","trackingUrl","getDeviceInfo","error","init_getDeviceInfo","__esmMin","verifyAccount","accountId","appId","userId","requestBody","WebStorage","DEVICE_INFO_SENT_KEY","deviceInfo","getDeviceInfo","baseUrl","store_default","response","data","access_token","refresh_token","error","init_verifyAccount","__esmMin","init_storage","init_getDeviceInfo","init_store","identifyWidgetPositions","screenName","positionList","accessToken","getAccessToken","endpoint","resp","err","init_identifyWidgetPositions","__esmMin","init_store","normalizeWidgetId","id","extractPositionsFromCampaigns","all","store_default","positions","c","d","v","p","mapServerPositionsToDOM","screenName","mapped","pos","key","selectors","el","sel","rect","frame","CaptureService","ensureList","layoutData","buildFormData","userId","children","blob","form","safeScreenName","filename","file","e","init_CaptureService","__esmMin","init_store","init_verifyAccount","init_identifyWidgetPositions","enabled","s","list","idx","l","enrichedFrame","info","elements","screenWidth","screenHeight","foundIds","positionList","resolve","win","reject","script","loadErr","canvas","b","err","stream","video","ctx","t","accessToken","getAccessToken","getUserId","state","verifyAccount","endpoint","body","resp","newToken","text","positionsToSend","normalized","serverPositions","combined","identifyWidgetPositions","name","screenCapture_exports","__export","mountScreenCaptureButton","injectStyles","style","createButton","btn","state","store_default","debugForce","originalText","screenName","CaptureService","err","init_screenCapture","__esmMin","init_store","init_CaptureService","e","s","token","len","masked","parts","payload","exp","now","index_exports","__export","instance","Banner","BottomSheet","Csat_default","Floater_default","Pip","SdkState","Story","Survey_default","Tooltip_default","Widget","personalizeText","__toCommonJS","SdkState","import_react","LottieModule","init_store","import_react","init_store","init_store","getVariantId","campaignId","store_default","hasVariants","campaign","resolveCampaignVariant","variantId","variants","variantDetails","baseDetails","key","BACK_PRESS_SENTINEL","normalizeScreenName","screen","isScreenMatch","campaignScreen","currentScreen","normalizedCampaignScreen","normalizedCurrentScreen","compareValues","actual","operator","expected","numActual","numExpected","useNumeric","matchesEventConditions","event_config","metadataList","realConditions","c","meta","condition","isTriggerEventSatisfied","campaign","trackedEvents","trackedEventMetadata","t","trigger_event","id","isBackPressCampaignReady","campaigns","store_default","te","event","useCampaigns","campaignType","options","state","allCampaigns","variantMappings","matchCampaign","list","resolveCampaignVariant","init_store","init_getDeviceInfo","init_storage","init_store","init_verifyAccount","OFFLINE_QUEUE_KEY","getQueue","existing","WebStorage","saveQueue","queue","getBackoffDelay","retryCount","shouldRetryRequest","request","lastAttempt","backoffDelay","validateCredentials","state","store_default","verifyAccount","handleAuthError","onSuccess","newToken","handleCriticalError","addToQueue","flushQueue","newQueue","req","res","r","sendOrQueue","trackEvent","event","campaignId","metadata","accessToken","getAccessToken","state","store_default","excludedEvents","trackedEvents","updatedEvents","e","currentMeta","existing","finalMetadata","deviceInfo","getDeviceInfo","variantId","getVariantId","body","getUserId","trackingUrl","sendOrQueue","error","init_store","revealCampaignFromLink","link","s","store_default","all","existing","normalizedLink","referenced","cid","details","detailsCampaign","revealed","idx","existingItem","next","import_jsx_runtime","Lottie","LottieModule","Banner","data","useCampaigns","sdkVisible","store_default","state","isDismissed","setIsDismissed","lottieData","setLottieData","aspectRatio","setAspectRatio","containerRef","containerWidth","setContainerWidth","trackEvent","res","json","err","updateWidth","details","styling","calculatedHeight","bannerStyle","mediaStyle","handleClose","e","revealCampaignFromLink","LottieComp","import_react","init_store","isRemoteFontUrl","value","v","fontNameFromUrl","url","filename","ensureStyleTag","fontName","id","style","cache","doLoad","entry","FontFaceCtor","face","cb","err","FontManager","existing","resolve","first","name","resolveFontFamily","fontFamily","collectFontUrls","input","urls","visited","walk","item","key","preloadFontsFromCampaigns","campaigns","c","u","import_jsx_runtime","normalizeScreen","value","parseNumber","fallback","parsed","PipIcon","iconType","color","stroke","IconButton","config","imageOverride","onClick","iconSize","buttonSize","margin","imageUrl","iconColor","fillColor","strokeColor","e","Pip","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","sdkVisible","isClosed","setIsClosed","isExpanded","setIsExpanded","isMuted","setIsMuted","isDragging","setIsDragging","dragPosition","setDragPosition","dragOffsetRef","videoRef","data","screen","findFromList","source","campaign","item","isPip","matchesScreen","hasTrigger","displayTriggerReady","found","resolveCampaignVariant","stableData","details","defaultSoundSetting","trackEvent","onMouseMove","event","nextX","nextY","onMouseUp","styling","appearance","configuredWidth","configuredHeight","miniWidth","miniHeight","ctaContainer","ctaText","hasCta","ctaHeight","expandedExtraHeight","bottomPadding","topPadding","videoSource","position","isMovable","soundEnabled","closeEnabled","expandEnabled","closeConfig","expandConfig","soundConfig","wrapperStyle","onWrapperMouseDown","rect","handleOpenLink","link","s","all","existing","referenced","c","revealed","idx","existingItem","next","prev","resolveFontFamily","import_react","import_lottie_react","init_store","import_jsx_runtime","toNumber","value","fallback","parsed","normalizeScreen","MEDIA_BUCKET_HOST","resolveLottieCandidateUrls","url","isDevServer","proxyUrl","isLikelyLottieJson","candidate","FloaterLottieErrorBoundary","React","props","Floater","lottieData","setLottieData","lottieUrls","setLottieUrls","lottieFailed","setLottieFailed","lottieLoading","setLottieLoading","lottieContainerRef","lottieAnimationRef","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","sdkVisible","viewedKeyRef","data","found","campaign","item","hasTrigger","resolveCampaignVariant","campaignId","mappedVariantId","hasVariants","viewKey","trackEvent","lottieSource","candidateUrls","lottie","cancelled","activeAnimation","cleanupCurrent","tryLoadByPath","paths","index","animation","details","styling","position","positionStyle","floaterStyle","handleClick","link","s","all","existing","referenced","c","cid","detailsCampaign","revealed","idx","existingItem","next","err","canRenderLottie","canRenderImage","canRenderLoadingPlaceholder","Floater_default","init_store","normalizeScreenName","screen","isScreenMatch","campaign","screenName","campaignScreen","currentScreen","trackScreen","state","store_default","accessToken","getAccessToken","accountId","baseUrl","response","getUserId","data","variantMappings","variant","allCampaigns","eligibleCampaignIds","foundCampaigns","foundCampaignIds","c","missingCampaignIds","id","missingCampaigns","fallbackResponse","eligibleCampaigns","displayTriggeredCampaigns","hasTrigger","mergedCampaigns","seenCampaignIds","error","init_verifyAccount","init_store","init_getDeviceInfo","setUserProperties","attributes","accessToken","getAccessToken","userId","getUserId","state","store_default","finalMetadata","deviceInfo","getDeviceInfo","bodyData","baseUrl","sendOrQueue","error","init_store","personalizeText","text","personalizationData","store_default","replacePlaceholdersWithFallback","regex","_","variableName","fallbackValue","trimmedVariable","trimmedFallback","init_storage","init_store","STORAGE_KEY_CAMPAIGNS","STORAGE_KEY_ETAG","STORAGE_KEY_VERSION","fetchAllCampaigns","accountId","screenName","isLocalDev","url","cachedData","WebStorage","cachedEtag","cachedVersion","headers","response","newEtag","responseData","version","campaigns","effectiveScreenName","accessToken","getAccessToken","userId","getUserId","trackResp","trackData","possibleScreen","s","store_default","err","userIdFromResp","fallbackResponse","fallbackData","error","normalize","current","campaign","init_store","init_store","reconcileAnonymousUser","anonymousUserId","identifiedUserId","accessToken","getAccessToken","state","store_default","requestBody","baseUrl","response","errorText","error","init_store","ExitIntentManager","isBackPressCampaignReady","state","store_default","trackedEvents","BACK_PRESS_SENTINEL","exitIntentManager","init_store","VisibilityManager","isVisible","state","store_default","visibilityManager","init_storage","ANONYMOUS_USER_KEY","generateAnonymousUserId","currentTimeMs","browserName","getOrCreateAnonymousUserId","storedUserId","WebStorage","newUserId","error","clearAnonymousUserId","getStoredAnonymousUserId","injectStyles","style","makePill","text","pill","ensureRelative","el","node","computed","matches","sel","idx","target","existing","err","import_react","init_store","import_react","LottieModule","import_jsx_runtime","Lottie","StoryThumbnail","src","alt","style","size","lottieData","setLottieData","lottieFailed","setLottieFailed","res","json","err","baseStyle","LottieComp","import_jsx_runtime","StoryGroupItem","story","isViewed","onClick","styling","size","ringWidth","ringColor","nameColor","cornerRadius","borderRadiusStr","imgBorderRadiusStr","StoryThumbnail","resolveFontFamily","import_jsx_runtime","StoryList","stories","viewedStories","onStoryClick","a","b","story","index","StoryGroupItem","import_react","init_store","import_jsx_runtime","PollSticker","data","onInteraction","isEditing","isHorizontal","defaults","styling","containerStyle","questionStyle","optionsContainerStyle","optionStyle","handleOptionClick","optionId","options","option","index","e","import_react","import_jsx_runtime","QuizSticker","data","onInteraction","isEditing","selectedOptionId","setSelectedOptionId","defaults","styling","cardPadding","questionFontSize","optionFontSize","optionRadius","borderColor","labelSize","containerStyle","questionStyle","optionStyle","labelStyle","bodyStyle","handleOptionClick","optionId","alphabet","options","option","index","label","isSelected","isCorrect","currentOptionStyle","currentLabelStyle","import_react","import_jsx_runtime","CountdownSticker","data","timeLeft","setTimeLeft","calculateTime","difference","days","hours","minutes","seconds","timer","styling","display","digitSize","safeDigitSize","labelFontSize","boxHeight","boxMinWidth","boxRadius","gridGap","containerStyle","titleStyle","timerGridStyle","segmentStyle","digitGroupStyle","boxStyle","labelStyle","separatorStyle","renderDigitGroup","value","label","digit","i","items","shownCount","import_react","import_jsx_runtime","PromoCodeSticker","data","onInteraction","copied","setCopied","handleCopy","styling","ticketPillStyle","percentageBoxStyle","codeStyle","import_jsx_runtime","ReactionSticker","data","onInteraction","isEditing","defaults","emojis","handleReaction","emoji","containerStyle","bubbleStyle","idx","e","import_react","import_jsx_runtime","RatingSticker","data","onInteraction","isEditing","maxRating","currentRating","val","setVal","sliderTrackRef","isDragging","setIsDragging","defaults","styling","containerStyle","titleStyle","trackStyle","percentage","fillStyle","emojiSize","thumbStyle","handleDrag","clientX","rect","offsetX","ratio","computedVal","onMouseDown","e","onTouchStart","onMouseMove","onMouseUp","onTouchMove","import_react","import_jsx_runtime","QuestionSticker","data","onInteraction","isEditing","value","setValue","defaults","styling","containerStyle","questionStyle","inputContainerStyle","inputStyle","sendButtonStyle","handleChange","e","handleSend","import_react","import_jsx_runtime","ImageQuizSticker","data","onInteraction","isEditing","selectedOptionId","setSelectedOptionId","defaults","styling","containerStyle","questionStyle","gridStyle","optionStyle","handleOptionClick","optionId","placeholderImg","options","option","isSelected","isCorrect","currentOptionStyle","e","import_react","import_react","import_jsx_runtime","ShopableModal","product","styling","onClose","onAddToCart","selectedSize","setSelectedSize","selectedColorIndex","setSelectedColorIndex","quantity","setQuantity","isSuccess","setIsSuccess","isVisible","setIsVisible","attributes","colors","sizes","imageUrls","description","handleAddToCart","item","url","error","handleDismiss","buttonBg","buttonFg","titleFg","priceFg","mrpFg","titleWeight","priceWeight","mrpWeight","overlayStyle","backdropStyle","sheetStyle","dragHandleStyle","buttonBaseStyle","headerStyle","closeButtonStyle","scrollContentStyle","gallerySectionStyle","i","sectionStyle","sectionTitleStyle","color","size","bottomBarStyle","stepperStyle","stepperBtnStyle","q","availability","isOutOfStock","import_jsx_runtime","ShopableSticker","data","onInteraction","isEditing","products","styling","isModalOpen","setIsModalOpen","selectedProduct","setSelectedProduct","handleProductClick","e","product","url","error","handleAddToCart","item","containerStyle","cardStyle","imageContainerStyle","contentContainerStyle","ShopableModal","import_jsx_runtime","InteractiveItem","data","onInteraction","isEditing","defaults","x","y","width","rotation","wrapperStyle","animationStyle","renderSticker","PollSticker","QuizSticker","RatingSticker","QuestionSticker","ImageQuizSticker","CountdownSticker","PromoCodeSticker","ReactionSticker","ShopableSticker","textStyle","resolveFontFamily","parseBackground","bg","color","direction","from","to","stops","cssDir","stopStr","s","getAnimationStyles","anim","type","duration","import_jsx_runtime","getEditorSource","item","content","editorSource","normalizeOptions","options","isCorrect","option","index","optionId","optionLabel","optionText","key","value","optionValue","normalizeReactionEmojis","data","emoji","normalizeElementType","type","normalized","getCountdownTarget","combined","InteractiveOverlay","onInteraction","isEditing","elapsedTime","canva","canvaWidth","canvaHeight","scale_factor","elements","images","texts","interactions","shopableContent","shopableIds","s","shopableStyling","displayElements","custom","style","source","position","size","rawX","rawY","rawW","x_percent","y_percent","width_percent","baseData","parseBackground","getAnimationStyles","normalizedOpts","colors","emojisArray","displayInteractions","typeStr","posX","posY","sizeW","sizeH","height_percent","displayShopable","matchedStyling","inlineStyling","styling","rawCardBorderRadius","rawCardRadiusPercent","rawHeight","radiusFromPercent","resolvedCardBorderRadius","resolvedCardBorderRadiusPx","isProductType","itemsSource","p","sourceData","attr","currentPrice","oldPrice","colorVal","sizeVal","sizes","consolidatedAttributes","displayImages","img","displayText","txt","font","resolveFontFamily","displayItems","start","end","a","b","InteractiveItem","import_react","import_jsx_runtime","PlayPauseButton","isPaused","onPress","style","size","isHovered","setIsHovered","PlayPauseButton_default","import_jsx_runtime","mapAlignment","alignment","Cta","cta","buttonText","onPress","resolveFontFamily","personalizeText","Cta_default","import_jsx_runtime","CrossButton","config","onPress","style","ignoreSizeAndMargin","backendSize","margin","color","image","selectedStyle","size","containerStyle","renderDefaultIcon","stroke","CrossButton_default","import_jsx_runtime","SoundButton","config","onPress","ignoreSizeAndMargin","enabled","style","type","backendSize","margin","color","image","selectedStyle","size","marginTop","marginBottom","marginLeft","marginRight","containerStyle","renderDefaultIcon","stroke","import_jsx_runtime","ShareButton","config","onPress","ignoreSizeAndMargin","style","backendSize","margin","color","image","selectedStyle","size","containerStyle","renderDefaultIcon","stroke","ShareButton_default","import_jsx_runtime","SIDE_CARD_SCALE","SIDE_CARD_OFFSET","ANIM_DURATION","EASING_OUTGOING","EASING_INCOMING","getRoleTransform","role","cardWidth","FAR_SIDE_CARD_OFFSET","StoryVideo","src","isActive","isAnimating","isMuted","onLoadedData","activeVideoRef","localRef","React","StoryOverlay","stories","activeStoryIndex","dataId","viewedStories","setViewedStories","onNextStory","onPrevStory","onClose","activeSlideIndex","setActiveSlideIndex","progress","setProgress","setIsMuted","videoLoaded","setVideoLoaded","isPaused","setIsPaused","showShortcuts","setShowShortcuts","showToast","setShowToast","isDesktop","setIsDesktop","setIsAnimating","outgoingIndex","setOutgoingIndex","incomingIndex","setIncomingIndex","direction","setDirection","handleResize","progressTimerRef","clickStartTimeRef","currentStory","currentSlide","currentSlideStyling","slideEditorSource","slideIsStudio","slideBgImage","slideCtaText","slideCtaLink","slideVideo","currentCanva","canvaRatio","CARD_HEIGHT","CARD_WIDTH","handleShare","shareData","trackEvent","handleKeyDown","e","handleNextSlide","handlePrevSlide","prev","slideTime","isVideo","triggerSlideTransition","dir","targetIndex","updated","handleMouseDownNav","handleMouseUpNav","handleVideoLoad","handleClickCTA","slide","styling","editorSource","link","toggleMute","crossConfig","soundConfig","ctaStyling","getSlideRole","idx","backdropStyle","centerCardBaseStyle","sideCardStyle","slidesToRender","acc","_","renderSet","StoryThumbnail","displayIndex","fillWidth","ShareButton_default","SoundButton","PlayPauseButton_default","key","label","CrossButton_default","a","b","index","roleStyle","slideStyling","isStudio","bgImage","video","bgColor","parseBackground","slideCtaTextLocal","slideCtaLinkLocal","containerStyles","InteractiveOverlay","interactionData","type","questionId","pollId","quizId","optionId","value","stickerId","interaction_type","interaction_id","selected","state","store_default","userId","trackingUrl","accessToken","getAccessToken","err","Cta_default","isCurrent","import_jsx_runtime","Story","data","useCampaigns","sdkVisible","store_default","state","activeStoryIndex","setActiveStoryIndex","viewedStories","setViewedStories","saved","e","trackEvent","handleStoryClick","index","story","handleNextStory","handlePrevStory","StoryList","StoryOverlay","import_react","import_react_dom","init_store","import_react","useViewportTracking","onVisible","threshold","onVisibleRef","hasTrackedRef","elementRef","observerRef","refCallback","el","timeoutId","entries","import_jsx_runtime","Widget","position","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","normalizeScreen","value","data","screen","found","campaign","item","hasTrigger","displayTriggerReady","matchesScreen","resolveCampaignVariant","activeIndex","setActiveIndex","containerRef","autoAdvanceRef","details","images","styling","widgetType","isHalf","trackedImpressionsRef","isInViewportRef","trackFirstImpression","firstImage","trackImpression","viewportRef","useViewportTracking","widgetImageId","trackEvent","prev","next","handleClick","imageId","link","revealCampaignFromLink","err","handleScroll","scrollLeft","offsetWidth","itemWidth","index","img","el","checkVisibility","idx","itemLeft","itemRight","viewLeft","viewRight","containerStyle","getItemStyle","content","_","i","target","key","selectors","sel","import_react","init_store","import_jsx_runtime","normalizeScreen","value","Tooltip","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","sdkVisible","currentStep","setCurrentStep","isDismissed","setIsDismissed","targetRect","setTargetRect","tooltipSize","setTooltipSize","tooltipRef","observerRef","data","screen","findFromList","source","campaign","item","isTooltip","matchesScreen","hasTrigger","displayTriggerReady","tooltips","a","b","currentTooltip","viewedTooltipsRef","trackViewed","tooltipId","key","trackEvent","viewportRef","useViewportTracking","findTarget","scroll","targetId","el","handleResizeOrScroll","targetEl","width","height","styling","appearance","colors","cta","ctaContainer","ctaCorner","ctaText","arrowPos","arrowSize","absoluteTop","absoluteLeft","tooltipLeft","tooltipTop","offsetGap","safeMargin","viewportTop","viewportBottom","viewportLeft","viewportRight","handleNext","action","targetLink","prev","handleBackdropClick","resolveFontFamily","Tooltip_default","import_react","init_store","import_jsx_runtime","BottomSheet","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","data","screen","found","campaign","hasTrigger","cs","resolveCampaignVariant","sdkVisible","isDismissed","setIsDismissed","trackEvent","removeTrackedEvent","eventKey","next","e","details","sortedElements","a","opacity","renderElement","element","imgStyle","link","revealCampaignFromLink","err","ctaData","container","cornerRadius","margin","textStyle","resolveFontFamily","l","titleStyle","descStyle","CrossButton_default","import_react","init_store","import_jsx_runtime","FIVE_STAR_MAX","LOW_RATING_CUTOFF","asSpacingValue","value","spacingToStyle","spacing","applyFontFamily","fontFamily","resolveFontFamily","textStyleToCss","textStyle","getCornerRadius","cornerRadius","getAlignment","alignment","getRatingType","details","ratingType","getEmojiChoices","configured","item","values","split","getNumberChoices","_","index","asNonNegativeNumber","parsed","getNumberRatingGap","rating","directCandidates","candidate","maybe","numberConfig","obj","nestedCandidates","StarIcon","fill","stroke","CsatFormContent","details","appearance","rating","selectedOptions","comments","isHighRating","feedbackOptions","onRate","onToggleOption","onCommentChange","onInlineSubmit","canSubmit","styling","feedbackPage","ratingStyle","initialFeedback","submitCta","ratingType","getRatingType","numberChoices","getNumberChoices","emojiChoices","getEmojiChoices","numberGap","getNumberRatingGap","selectedStarConfig","spacingToStyle","textStyleToCss","FIVE_STAR_MAX","_","index","value","isSelected","starContainerStyle","starStyle","selected","emoji","LOW_RATING_CUTOFF","option","styleSource","getCornerRadius","event","asNonNegativeNumber","applyFontFamily","CsatThankYouContent","onDone","thankyouPage","doneAlign","getAlignment","Csat","hookData","useCampaigns","sdkVisible","store_default","state","campaigns","allCampaigns","currentScreen","data","screen","found","campaign","hasTrigger","cs","resolveCampaignVariant","isDismissed","setIsDismissed","canDisplay","setCanDisplay","setRating","setSelectedOptions","setComments","isSubmitted","setIsSubmitted","delay","timeoutId","trackEvent","source","a","b","key","configuredWidth","compactCardWidth","handleToggleOption","prev","item","handleSubmit","override","ratingValue","campaignId","selectedOption","additionalComments","handleRate","e","handleDone","link","revealCampaignFromLink","err","asSpacingValue","CrossButton_default","Csat_default","import_react","init_store","import_jsx_runtime","asSpacingValue","value","applyFontFamily","fontFamily","resolveFontFamily","textStyleToCss","textStyle","marginToStyle","margin","getCornerRadius","cornerRadius","getAlignment","alignment","clamp01","hexToRgba","hex","alpha","raw","r","g","b","normalizeBackdropOpacity","opacity","getOrderedSlides","details","a","getOrderedOptions","slide","options","keys","parseIndex","key","match","parsed","ai","bi","getBulletLabel","optionListStyle","index","start","asNonNegativeNumber","getBorderWidthFromTextStyle","SurveyFormContent","appearance","selectedOption","comment","onSelectOption","onCommentChange","onSubmit","canSubmit","styling","optionsStyle","cta","optionRowGap","bulletGap","optionHeight","ctaAlign","option","isActive","styleSource","borderWidth","bulletLabel","event","SurveyThankYouContent","onDone","thankyouPage","Survey","hookData","useCampaigns","sdkVisible","store_default","state","campaigns","allCampaigns","currentScreen","data","screen","found","campaign","hasTrigger","cs","resolveCampaignVariant","isDismissed","setIsDismissed","canDisplay","setCanDisplay","currentIndex","setCurrentIndex","setSelectedOption","setComment","responses","setResponses","isSubmitted","setIsSubmitted","delay","timeoutId","surveyId","orderedSlides","firstSlideId","trackEvent","slides","existing","backdropColor","backdropOpacity","handleSelectOption","prev","submitSurvey","finalResponses","finalSlideId","responsesArray","s","campaignId","selectedOptionsKeys","selectedValue","optionEntry","val","otherText","captureCampaignId","handleSubmitCurrent","nextResponses","optionKey","perSlideCampaignId","e","rule","handleDone","config","redirect","revealCampaignFromLink","err","handleDismiss","slideId","CrossButton_default","Survey_default","AppStorys","options","appId","accountId","userId","state","store_default","finalUserId","isAnonymous","getOrCreateAnonymousUserId","storedAnonymousUserId","getStoredAnonymousUserId","verifyAccount","reconcileAnonymousUser","clearAnonymousUserId","accessToken","getAccessToken","usersBase","resp","data","s","val","err","campaigns","version","fetchAllCampaigns","preloadFontsFromCampaigns","exitIntentManager","visibilityManager","e","anonymousUserId","identifiedUserId","error","screenName","trackScreen","event","campaignId","metadata","trackEvent","attributes","setUserProperties","link","revealCampaignFromLink","isVisible","startTime","resolve","text","personalizeText","instance"]}
1
+ {"version":3,"sources":["../src/adapters/web/storage.ts","../src/core/store.ts","../src/core/getDeviceInfo.ts","../src/core/verifyAccount.ts","../src/core/identifyWidgetPositions.ts","../src/core/CaptureService.ts","../src/core/screenCapture.ts","../src/index.ts","../src/types/index.ts","../src/components/Banner/index.tsx","../src/hooks/useCampaigns.ts","../src/core/abTesting/index.ts","../src/core/trackEvent.ts","../src/core/offlineQueue.ts","../src/core/campaignHelpers.ts","../src/components/common/CommonElements/CrossButton.tsx","../src/components/Pip/index.tsx","../src/core/fontManager.ts","../src/components/Floater/index.tsx","../src/core/trackScreen.ts","../src/core/setUserProperties.ts","../src/core/personalization.ts","../src/core/fetchAllCampaigns.ts","../src/core/reconcileUser.ts","../src/core/exitIntent.ts","../src/core/visibilityManager.ts","../src/core/userManagement.ts","../src/dev/showWidgetDebug.ts","../src/components/Story/index.tsx","../src/components/Story/StoryThumbnail.tsx","../src/components/Story/StoryGroupItem.tsx","../src/components/Story/StoryList.tsx","../src/components/Story/StoryOverlay.tsx","../src/utils/styleUtils.ts","../src/components/common/InteractiveElements/PollSticker.tsx","../src/components/common/InteractiveElements/QuizSticker.tsx","../src/components/common/InteractiveElements/CountdownSticker.tsx","../src/components/common/InteractiveElements/PromoCodeSticker.tsx","../src/components/common/InteractiveElements/ReactionSticker.tsx","../src/components/common/InteractiveElements/RatingSticker.tsx","../src/components/common/InteractiveElements/QuestionSticker.tsx","../src/components/common/InteractiveElements/ImageQuizSticker.tsx","../src/components/common/InteractiveElements/ShopableSticker.tsx","../src/components/common/InteractiveElements/ShopableModal.tsx","../src/components/common/InteractiveElements/InteractiveItem.tsx","../src/components/common/InteractiveElements/InteractiveOverlay.tsx","../src/components/common/CommonElements/PlayPauseButton.tsx","../src/components/common/CommonElements/Cta.tsx","../src/components/common/CommonElements/SoundButton.tsx","../src/components/common/CommonElements/ShareButton.tsx","../src/components/Widget/index.tsx","../src/hooks/useViewportTracking.ts","../src/core/resolveTarget.ts","../src/components/Tooltip/index.tsx","../src/components/BottomSheet/index.tsx","../src/components/Csat/index.tsx","../src/components/Survey/index.tsx","../src/components/Modal/index.tsx","../src/components/Modal/components/ModalWithCta.tsx","../src/components/Modal/components/MediaOnlyModal.tsx","../src/components/Trackable/index.tsx"],"sourcesContent":["export class WebStorage {\n static async getItem(key: string): Promise<string | null> {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n static async setItem(key: string, value: string): Promise<void> {\n try {\n localStorage.setItem(key, value);\n } catch {\n // Fallback for private mode or full storage\n }\n }\n\n static async removeItem(key: string): Promise<void> {\n try {\n localStorage.removeItem(key);\n } catch {}\n }\n}\n","import { create } from 'zustand';\nimport { AppStorysStore, Campaign, Attributes } from '../types';\nimport { WebStorage } from '../adapters/web/storage';\n\nexport interface AppStorysActions {\n setUserId: (userId: string) => void;\n setAppId: (appId: string) => void;\n setAccountId: (accountId: string) => void;\n setCurrentScreen: (screen: string) => void;\n saveCampaigns: (campaigns: Campaign[]) => void;\n saveAllCampaigns: (campaigns: Campaign[]) => void;\n setCampaignVersion: (version: number) => void;\n setTrackedEvents: (events: string[]) => void;\n setTrackedEventMetadata: (metadata: Record<string, Attributes[]>) => void;\n setAttributes: (attributes: Attributes) => void;\n setVisibility: (visible: boolean) => void;\n setIsAnonymousUser: (isAnonymous: boolean) => void;\n setVariantMappings: (mappings: Record<string, string>) => void;\n setPersonalizationData: (data: Record<string, string>) => void;\n setScreenCaptureEnabled: (enabled: boolean) => void;\n setBaseUrl: (baseUrl?: string) => void;\n setTrackingUrl: (trackingUrl?: string) => void;\n}\n\nconst useAppStorysStore = create<AppStorysStore & AppStorysActions>((set) => ({\n userId: '',\n appId: '',\n accountId: '',\n currentScreen: '',\n campaigns: [],\n allCampaigns: [],\n campaignVersion: 2,\n trackedEvents: [],\n trackedEventMetadata: {},\n isVisible: true,\n isAnonymousUser: false,\n variantMappings: {},\n personalizationData: {},\n screenCaptureEnabled: false,\n baseUrl: undefined,\n trackingUrl: undefined,\n \n saveCampaigns: (campaigns: Campaign[]) => set({ campaigns }),\n saveAllCampaigns: (campaigns: Campaign[]) => set({ allCampaigns: campaigns }),\n setCampaignVersion: (version: number) => set({ campaignVersion: version }),\n setUserId: (userId: string) => set({ userId }),\n setAppId: (appId: string) => set({ appId }),\n setAccountId: (accountId: string) => set({ accountId }),\n setCurrentScreen: (currentScreen: string) => set({ currentScreen }),\n setAttributes: (attributes: Attributes) => set({ attributes }),\n setTrackedEvents: (trackedEvents: string[]) => set({ trackedEvents }),\n setTrackedEventMetadata: (trackedEventMetadata: Record<string, Attributes[]>) => set({ trackedEventMetadata }),\n setVisibility: (isVisible: boolean) => set({ isVisible }),\n setIsAnonymousUser: (isAnonymousUser: boolean) => set({ isAnonymousUser }),\n setVariantMappings: (variantMappings: Record<string, string>) => set({ variantMappings }),\n setPersonalizationData: (personalizationData: Record<string, string>) => set({ personalizationData }),\n setScreenCaptureEnabled: (enabled: boolean) => set({ screenCaptureEnabled: enabled }),\n setBaseUrl: (baseUrl?: string) => set({ baseUrl }),\n setTrackingUrl: (trackingUrl?: string) => set({ trackingUrl }),\n}));\n\nexport function getAppId() {\n return useAppStorysStore.getState().appId;\n}\n\nexport function getUserId() {\n return useAppStorysStore.getState().userId;\n}\n\nexport async function getAccessToken() {\n return WebStorage.getItem('access_token');\n}\n\nexport function getVariantId(campaignId?: string) {\n if (!campaignId) return undefined;\n const id = String(campaignId || '').trim();\n if (!id) return undefined;\n return useAppStorysStore.getState().variantMappings?.[id];\n}\n\nexport function getCampaigns() {\n return useAppStorysStore.getState().campaigns;\n}\n\nexport function getAllCampaigns() {\n return useAppStorysStore.getState().allCampaigns;\n}\n\nexport function getCampaignVersion() {\n return useAppStorysStore.getState().campaignVersion;\n}\n\nexport default useAppStorysStore;\n","export default async function getDeviceInfo() {\n try {\n const deviceInfo: Record<string, any> = {\n browser: navigator.userAgent,\n language: navigator.language,\n platform: 'web',\n screen_width_px: window.innerWidth,\n screen_height_px: window.innerHeight,\n screen_density: window.devicePixelRatio,\n orientation: window.innerWidth < window.innerHeight ? \"portrait\" : \"landscape\",\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n };\n\n return deviceInfo;\n } catch (error) {\n console.error(\"Error fetching device info:\", error);\n return {};\n }\n}\n","import { WebStorage } from '../adapters/web/storage';\nimport getDeviceInfo from './getDeviceInfo';\nimport useAppStorysStore from './store';\n\nconst DEVICE_INFO_SENT_KEY = 'device_info_sent';\n\nexport default async function verifyAccount(accountId: string, appId: string, userId: string): Promise<boolean> {\n try {\n const requestBody: any = {\n account_id: accountId,\n app_id: appId,\n user_id: userId\n };\n\n const deviceInfoAlreadySent = await WebStorage.getItem(DEVICE_INFO_SENT_KEY);\n\n if (!deviceInfoAlreadySent) {\n // This is the very first initialization after app install\n const deviceInfo = await getDeviceInfo();\n requestBody.attributes = {\n ...deviceInfo\n };\n console.log('First time verification - including device info in attributes');\n } else {\n console.log('Device info already sent previously - skipping');\n }\n\n const state = useAppStorysStore.getState();\n const baseUrl = state.baseUrl || 'https://users.appstorys.co';\n\n const response = await fetch(`${baseUrl}/${accountId}/validate-account`, {\n method: 'POST',\n body: JSON.stringify(requestBody),\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n });\n\n console.log('Verify account body', requestBody);\n console.log('Verifying account', response.status, response.statusText);\n\n if (response.ok) {\n const data = await response.json();\n console.log('Account verified', data);\n const { access_token, refresh_token } = data;\n\n if (access_token && refresh_token) {\n await WebStorage.setItem('access_token', access_token);\n await WebStorage.setItem('refresh_token', refresh_token);\n\n // Mark device info as sent if it was included in this request\n if (requestBody.attributes) {\n await WebStorage.setItem(DEVICE_INFO_SENT_KEY, 'true');\n console.log('Device info sent flag set');\n }\n\n return true;\n }\n }\n return false;\n } catch (error) {\n console.error('Error when verifying AppStorys account', error);\n return false;\n }\n}\n","import { getAccessToken } from './store';\n\nexport default async function identifyWidgetPositions(screenName: string, positionList?: string[]) {\n if (!positionList || positionList.length === 0) {\n console.info('AppStorys: identifyWidgetPositions called with empty positionList; skipping');\n return;\n }\n\n const accessToken = await getAccessToken();\n if (!accessToken) {\n console.error('AppStorys: identifyWidgetPositions - access token not found');\n return;\n }\n\n try {\n const endpoint = 'https://backend.appstorys.co/api/v2/appinfo/identify-positions/';\n console.info('AppStorys: identifyWidgetPositions payload', { screen_name: screenName, position_list: positionList });\n const resp = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n 'Accept': 'application/json'\n },\n body: JSON.stringify({\n screen_name: screenName,\n position_list: positionList,\n }),\n });\n\n if (!resp.ok) {\n console.error('AppStorys: identifyWidgetPositions failed', resp.status, await resp.text());\n } else {\n console.info('AppStorys: identifyWidgetPositions OK');\n }\n } catch (err) {\n console.error('AppStorys: identifyWidgetPositions error', err);\n }\n}\n","import { getAccessToken, getUserId } from './store';\nimport verifyAccount from './verifyAccount';\nimport identifyWidgetPositions from './identifyWidgetPositions';\nimport useAppStorysStore from './store';\n\ntype LayoutFrame = {\n x: number;\n y: number;\n width: number;\n height: number;\n screenWidth?: number;\n screenHeight?: number;\n};\n\ntype LayoutInfo = { id: string; frame: LayoutFrame };\n\nconst layoutData: Record<string, LayoutInfo[]> = {};\n\nfunction normalizeWidgetId(id?: string) {\n if (!id) return id;\n return id.startsWith('widget_') ? id : `widget_${id}`;\n}\n\nfunction extractPositionsFromCampaigns(): string[] {\n try {\n const all = useAppStorysStore.getState().allCampaigns || [];\n const positions: string[] = [];\n\n all.forEach((c: any) => {\n if (c && c.position && typeof c.position === 'string') {\n positions.push(String(c.position));\n }\n\n try {\n if (c && c.campaign_type === 'WID' && c.details) {\n const d = c.details;\n if (typeof d === 'object') {\n if (d.id && typeof d.id === 'string') positions.push(String(d.id));\n if (d.variants && typeof d.variants === 'object') {\n Object.values(d.variants).forEach((v: any) => { if (v && v.id && typeof v.id === 'string') positions.push(String(v.id)); });\n }\n }\n }\n } catch (e) {\n // ignore per-campaign extraction errors\n }\n });\n\n return positions.filter((v): v is string => !!v).map((p) => normalizeWidgetId(String(p))!).filter((v): v is string => !!v);\n } catch (e) {\n return [];\n }\n}\nfunction mapServerPositionsToDOM(screenName: string) {\n try {\n const positions = extractPositionsFromCampaigns();\n if (!positions || positions.length === 0) return [];\n\n const mapped: string[] = [];\n\n positions.forEach((pos) => {\n const key = pos.replace(/^widget_/, '');\n // try multiple selectors to find the matching element\n const selectors = [\n `[data-as-id=\"${key}\"]`,\n `#${key}`,\n `.${key}`,\n `[data-widget=\"${key}\"]`,\n ];\n\n let el: Element | null = null;\n for (const sel of selectors) {\n el = document.querySelector(sel);\n if (el) break;\n }\n\n if (el) {\n const rect = el.getBoundingClientRect();\n const frame: LayoutFrame = {\n x: Math.round(rect.left),\n y: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n screenWidth: window.innerWidth,\n screenHeight: window.innerHeight,\n };\n\n // store using the raw key (no widget_ prefix) so children JSON matches collected ids\n CaptureService.addLayoutInfo(screenName, key, frame);\n mapped.push(key);\n } else {\n // not found in DOM; skip\n }\n });\n\n console.info('AppStorys: mapServerPositionsToDOM mapped', mapped.length, 'server positions to DOM elements', mapped);\n return mapped;\n } catch (e) {\n console.warn('AppStorys: mapServerPositionsToDOM error', e);\n return [];\n }\n}\n\nfunction ensureList(screenName: string) {\n if (!layoutData[screenName]) layoutData[screenName] = [];\n return layoutData[screenName];\n}\n\n/**\n * Build a fresh FormData for the identify-elements request.\n */\nfunction buildFormData(\n screenName: string,\n userId: string,\n children: string,\n blob: Blob\n): FormData {\n const form = new FormData();\n \n // Sanitize screenName for filename\n const safeScreenName = screenName.replace(/[^a-z0-9]/gi, '_');\n const filename = `screenshot_${userId}_${safeScreenName}_${Date.now()}.png`;\n\n const file = new File([blob], filename, { type: 'image/png' });\n\n form.append('screenName', screenName);\n form.append('user_id', userId);\n form.append('children', children);\n form.append('screenshot', file);\n\n // Diagnostic logging\n try {\n console.groupCollapsed('AppStorys: FormData Payload Diagnostic');\n console.info(' screenName:', screenName);\n console.info(' user_id:', userId);\n console.info(' children:', JSON.parse(children));\n console.info(' screenshot:', file.name, `(${file.size} bytes)`);\n console.groupEnd();\n } catch (e) {\n console.warn('AppStorys: Could not run FormData diagnostics', e);\n }\n\n return form;\n}\n\nexport default class CaptureService {\n static setup(screenName: string, enabled: boolean) {\n const s = useAppStorysStore.getState();\n s.setScreenCaptureEnabled(enabled);\n s.setCurrentScreen(screenName);\n }\n\n /**\n * Manually add layout information for an element.\n */\n static addLayoutInfo(screenName: string, id: string, frame: LayoutFrame) {\n const list = ensureList(screenName);\n const idx = list.findIndex(l => l.id === id);\n \n // Auto-fill screen dimensions if missing\n const enrichedFrame: LayoutFrame = {\n ...frame,\n screenWidth: frame.screenWidth || window.innerWidth,\n screenHeight: frame.screenHeight || window.innerHeight,\n };\n\n const info = { id, frame: enrichedFrame };\n if (idx >= 0) list[idx] = info; else list.push(info);\n }\n\n /**\n * Automatically collect all elements marked with [data-as-id].\n */\n static collectElements(screenName: string) {\n this.clearLayoutData(screenName);\n const elements = document.querySelectorAll('[data-as-id]');\n const screenWidth = window.innerWidth;\n const screenHeight = window.innerHeight;\n const foundIds: string[] = [];\n\n elements.forEach((el) => {\n const id = el.getAttribute('data-as-id');\n if (id) {\n foundIds.push(id);\n const rect = el.getBoundingClientRect();\n this.addLayoutInfo(screenName, id, {\n x: Math.round(rect.left),\n y: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n screenWidth,\n screenHeight\n });\n }\n });\n\n console.info(`AppStorys: Identified ${elements.length} elements:`, foundIds);\n }\n\n static clearLayoutData(screenName: string) {\n layoutData[screenName] = [];\n }\n\n static getLayoutData(screenName: string) {\n return layoutData[screenName] || [];\n }\n\n static async takeScreenshot(screenName: string, positionList?: string[]) {\n try {\n if (!screenName) {\n console.error('AppStorys: Screen name is required');\n return false;\n }\n\n console.info('AppStorys: Starting takeScreenshot for', screenName);\n\n const s = useAppStorysStore.getState();\n s.setCurrentScreen(screenName);\n\n // ── Step 0: Auto-collect elements before capture ──────────────────\n this.collectElements(screenName);\n\n // Also try to map server-declared widget positions to DOM elements\n try {\n const mapped = mapServerPositionsToDOM(screenName);\n if (mapped && mapped.length > 0) console.info('AppStorys: mapServerPositionsToDOM added', mapped.length, 'elements');\n } catch (e) {\n /* ignore */\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n\n // ── Step 1: Capture ────────────────────────────────────────────────\n const win: any = window as any;\n let blob: Blob | null = null;\n\n if (typeof win.html2canvas !== 'function') {\n try {\n await new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://html2canvas.hertzen.com/dist/html2canvas.min.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load html2canvas'));\n document.head.appendChild(script);\n });\n } catch (loadErr) {\n console.warn('AppStorys: html2canvas load error', loadErr);\n }\n }\n\n if (typeof win.html2canvas === 'function') {\n try {\n const canvas = await win.html2canvas(document.documentElement, {\n useCORS: true,\n allowTaint: true,\n logging: false,\n scale: window.devicePixelRatio || 1,\n });\n blob = await new Promise<Blob | null>(resolve =>\n canvas.toBlob((b: Blob | null) => resolve(b), 'image/png')\n );\n } catch (err) {\n console.warn('AppStorys: html2canvas capture failed (falling back to getDisplayMedia)', err);\n blob = null;\n }\n }\n\n if (!blob && navigator.mediaDevices && (navigator.mediaDevices as any).getDisplayMedia) {\n try {\n const stream = await (navigator.mediaDevices as any).getDisplayMedia({ video: true });\n const video = document.createElement('video');\n video.srcObject = stream;\n await video.play();\n const canvas = document.createElement('canvas');\n canvas.width = video.videoWidth || window.innerWidth;\n canvas.height = video.videoHeight || window.innerHeight;\n const ctx = canvas.getContext('2d');\n if (ctx) ctx.drawImage(video, 0, 0, canvas.width, canvas.height);\n blob = await new Promise<Blob | null>(resolve =>\n canvas.toBlob((b: Blob | null) => resolve(b), 'image/png')\n );\n video.pause();\n stream.getTracks().forEach((t: MediaStreamTrack) => t.stop());\n } catch (err) {\n console.warn('AppStorys: getDisplayMedia capture failed', err);\n }\n }\n\n if (!blob) {\n console.warn('AppStorys: Capture failed — no blob generated');\n return false;\n }\n\n // ── Step 2: Auth ──────────────────────────────────────────────────\n let accessToken = await getAccessToken();\n const userId = getUserId();\n\n if (!userId) {\n console.warn('AppStorys: No userId');\n return false;\n }\n\n if (!accessToken) {\n const state = useAppStorysStore.getState();\n if (state.accountId && state.appId && state.userId) {\n const refreshed = await verifyAccount(state.accountId, state.appId, state.userId);\n if (refreshed) accessToken = await getAccessToken();\n }\n }\n\n if (!accessToken) {\n console.warn('AppStorys: No token available');\n return false;\n }\n\n // ── Step 3: Send ───────────────────────────────────────────────────\n const endpoint = 'https://backend.appstorys.co/api/v1/appinfo/identify-elements/';\n const children = JSON.stringify(this.getLayoutData(screenName) || []);\n \n const body = buildFormData(screenName, userId, children, blob);\n \n console.info('AppStorys: Sending identify-elements with payload size:', children.length);\n\n let resp = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${accessToken}`,\n 'Accept': 'application/json'\n },\n body: body,\n });\n\n if (resp.status === 401) {\n console.warn('AppStorys: 401 response — retrying once');\n const state = useAppStorysStore.getState();\n if (state.accountId && state.appId && state.userId) {\n const refreshed = await verifyAccount(state.accountId, state.appId, state.userId);\n if (refreshed) {\n const newToken = await getAccessToken();\n if (newToken) {\n resp = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${newToken}`,\n 'Accept': 'application/json'\n },\n body: buildFormData(screenName, userId, children, blob),\n });\n }\n }\n }\n }\n\n if (!resp.ok) {\n const text = await resp.text();\n console.error('AppStorys: identify-elements failed', resp.status, text);\n return false;\n }\n\n console.info('AppStorys: identify-elements success ✓');\n\n // After identify-elements succeeds, call identifyWidgetPositions.\n // If caller didn't provide a `positionList`, derive it from collected layout data.\n try {\n let positionsToSend = positionList;\n let normalized: string[] = [];\n if (!positionsToSend || positionsToSend.length === 0) {\n const data = this.getLayoutData(screenName) || [];\n normalized = data.map(d => normalizeWidgetId(d.id)).filter((v): v is string => !!v);\n } else {\n normalized = positionsToSend.map(id => normalizeWidgetId(id)).filter((v): v is string => !!v);\n }\n\n // Note: intentionally NOT merging in raw extractPositionsFromCampaigns() here.\n // `normalized` already reflects every id that mapServerPositionsToDOM/collectElements\n // actually found in the live DOM this capture; re-merging the unfiltered server list\n // would re-report positions that no longer exist on the page as still valid.\n console.info('AppStorys: identifyWidgetPositions will send', normalized.length, 'positions (DOM-verified)', normalized);\n await identifyWidgetPositions(screenName, normalized);\n } catch (e) {\n console.warn('AppStorys: identifyWidgetPositions failed', e);\n }\n\n return true;\n } catch (err) {\n console.error('AppStorys: takeScreenshot error', err);\n return false;\n }\n }\n}\n\nexport type { LayoutFrame, LayoutInfo };\n\n// Dev helper: force a positions POST for the current screen\n;(function attachDevHelpers() {\n try {\n const win: any = window as any;\n win.AppStorysForceIdentifyPositions = async (screenName?: string) => {\n const s = useAppStorysStore.getState();\n const name = screenName || s.currentScreen;\n if (!name) {\n console.warn('AppStorys: AppStorysForceIdentifyPositions - no screen name available');\n return;\n }\n const data = CaptureService.getLayoutData(name) || [];\n const positions = data.map(d => normalizeWidgetId(d.id)).filter((v): v is string => !!v);\n console.info('AppStorys: AppStorysForceIdentifyPositions sending', positions.length, 'positions for', name, positions);\n try {\n await identifyWidgetPositions(name, positions);\n console.info('AppStorys: AppStorysForceIdentifyPositions completed');\n } catch (err) {\n console.error('AppStorys: AppStorysForceIdentifyPositions error', err);\n }\n };\n } catch (e) {\n /* ignore */\n }\n})();\n","import useAppStorysStore from './store';\nimport CaptureService from './CaptureService';\n\nfunction injectStyles() {\n if (document.getElementById('appstorys-capture-styles')) return;\n const style = document.createElement('style');\n style.id = 'appstorys-capture-styles';\n style.innerHTML = `\n @keyframes appstorys-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n .appstorys-spinner {\n width: 20px;\n height: 20px;\n border: 3px solid rgba(255,255,255,0.3);\n border-top: 3px solid #fff;\n border-radius: 50%;\n animation: appstorys-spin 0.8s linear infinite;\n }\n `;\n document.head.appendChild(style);\n}\n\nfunction createButton(): HTMLButtonElement {\n injectStyles();\n const btn = document.createElement('button');\n btn.id = 'appstorys-screen-capture-btn';\n btn.title = 'Capture screen';\n Object.assign(btn.style, {\n position: 'fixed',\n left: '16px',\n bottom: '16px',\n width: '100px',\n height: '56px',\n borderRadius: '28px',\n background: '#ff6a00',\n color: '#fff',\n border: 'none',\n boxShadow: '0 6px 18px rgba(0,0,0,0.2)',\n zIndex: '2147483647',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '14px',\n fontWeight: '600',\n fontFamily: 'sans-serif',\n transition: 'all 0.2s ease'\n } as CSSStyleDeclaration);\n btn.innerText = 'Capture';\n return btn;\n}\n\nexport function mountScreenCaptureButton() {\n try {\n const state = useAppStorysStore.getState();\n const win: any = window as any;\n const debugForce = Boolean(win.__APPSTORYS_DEBUG_CAPTURE);\n console.info('AppStorys: mountScreenCaptureButton called, screenCaptureEnabled=', state.screenCaptureEnabled, 'debugForce=', debugForce);\n \n if (!state.screenCaptureEnabled && !debugForce) {\n return null;\n }\n\n if (document.getElementById('appstorys-screen-capture-btn')) return null;\n\n const btn = createButton();\n\n btn.addEventListener('click', async () => {\n btn.disabled = true;\n const originalText = btn.innerText;\n btn.innerHTML = '<div class=\"appstorys-spinner\"></div>';\n \n const s = useAppStorysStore.getState();\n const screenName = s.currentScreen || (typeof window !== 'undefined' ? window.location.pathname : '');\n \n try {\n await CaptureService.takeScreenshot(screenName);\n } catch (err) {\n console.error('CaptureService error', err);\n }\n \n btn.disabled = false;\n btn.innerText = originalText;\n btn.animate([{ transform: 'scale(1.0)' }, { transform: 'scale(1.05)' }, { transform: 'scale(1.0)' }], { duration: 300 });\n });\n\n document.body.appendChild(btn);\n console.info('AppStorys: screen capture button mounted');\n return btn;\n } catch (err) {\n console.error('mountScreenCaptureButton error', err);\n return null;\n }\n}\n\n// Expose a helper for dev to mount manually from console\ntry {\n (window as any).AppStorysMountCapture = function() {\n try {\n return mountScreenCaptureButton();\n } catch (e) {\n console.error('AppStorysMountCapture failed', e);\n return null;\n }\n };\n} catch (e) {\n // ignore\n}\n\n// Expose a helper to inspect store state from the console\ntry {\n (window as any).AppStorysDebugState = function() {\n try {\n const s = useAppStorysStore.getState();\n console.info('AppStorys store state:', s);\n return s;\n } catch (e) {\n console.error('AppStorysDebugState failed', e);\n return null;\n }\n };\n} catch (e) {\n // ignore\n}\n\n// Expose a helper to debug token\ntry {\n (window as any).AppStorysDebugToken = function() {\n try {\n const token = localStorage.getItem('access_token') || '';\n const len = token.length;\n const masked = token ? token.slice(0, 20) + '...' + token.slice(-10) : '(none)';\n console.info('Token length:', len, 'masked:', masked);\n if (token && token.includes('.')) {\n try {\n const parts = token.split('.');\n if (parts.length === 3) {\n const payload = JSON.parse(atob(parts[1]));\n console.info('Token payload:', payload);\n if (payload.exp) {\n const exp = new Date(payload.exp * 1000);\n const now = new Date();\n console.info('Token expires:', exp.toISOString(), 'Expired:', now > exp);\n }\n }\n } catch (e) {\n console.warn('Could not decode JWT:', e);\n }\n }\n return token ? 'Token present' : 'No token';\n } catch (e) {\n console.error('AppStorysDebugToken failed', e);\n return null;\n }\n };\n} catch (e) {\n // ignore\n}\n","import { SdkState, InitializationOptions, Attributes } from './types';\nimport { Banner } from './components/Banner';\nimport { Pip } from './components/Pip';\nimport Floater from './components/Floater';\nimport trackEvent from './core/trackEvent';\nimport trackScreen from './core/trackScreen';\nimport verifyAccount from './core/verifyAccount';\nimport setUserProperties from './core/setUserProperties';\nimport { personalizeText } from './core/personalization';\nimport fetchAllCampaigns from './core/fetchAllCampaigns';\nimport useAppStorysStore from './core/store';\nimport { getAccessToken } from './core/store';\nimport { revealCampaignFromLink } from './core/campaignHelpers';\nimport reconcileAnonymousUser from './core/reconcileUser';\nimport { exitIntentManager } from './core/exitIntent';\nimport { visibilityManager } from './core/visibilityManager';\nimport { getOrCreateAnonymousUserId, getStoredAnonymousUserId, clearAnonymousUserId } from './core/userManagement';\nimport { preloadFontsFromCampaigns } from './core/fontManager';\nimport './dev/showWidgetDebug';\n\nclass AppStorys {\n private state: SdkState = SdkState.uninitialized;\n private navigateToScreen?: (screen: string) => void;\n\n public async initialize(options: InitializationOptions) {\n const { appId, accountId, userId } = options;\n this.navigateToScreen = options.navigateToScreen;\n\n if (this.state === SdkState.initializing) return;\n\n if (this.state === SdkState.initialized) {\n const state = useAppStorysStore.getState();\n\n // If SDK is already initialized with an anonymous user and now a real userId is provided\n if (state.isAnonymousUser && userId && userId.trim() !== '') {\n console.log('AppStorys: Reconciling anonymous user with identified user...');\n await this.reconcileUser(state.userId, userId, appId, accountId);\n return;\n }\n\n if (state.appId === appId && state.accountId === accountId && state.userId === userId) {\n return;\n }\n }\n\n this.state = SdkState.initializing;\n\n try {\n let finalUserId: string;\n let isAnonymous: boolean;\n\n if (!userId || userId.trim() === '') {\n finalUserId = await getOrCreateAnonymousUserId();\n isAnonymous = true;\n } else {\n const storedAnonymousUserId = await getStoredAnonymousUserId();\n if (storedAnonymousUserId && storedAnonymousUserId !== userId) {\n // Reconcile will happen after verification, matching RN logic\n console.log('AppStorys: Found previous anonymous user, will reconcile after verification.');\n }\n finalUserId = userId;\n isAnonymous = false;\n }\n\n const success = await verifyAccount(accountId, appId, finalUserId);\n if (!success) {\n this.state = SdkState.error;\n return;\n }\n\n // Step 1.5: Reconcile if we moved from anonymous to identified\n if (!isAnonymous) {\n const storedAnonymousUserId = await getStoredAnonymousUserId();\n if (storedAnonymousUserId && storedAnonymousUserId !== finalUserId) {\n await reconcileAnonymousUser(storedAnonymousUserId, finalUserId);\n await clearAnonymousUserId();\n }\n }\n\n // Fire a non-blocking call to track-user-res so it appears in the browser Network tab\n try {\n const accessToken = await getAccessToken();\n const usersBase = options.baseUrl || 'https://users.appstorys.co';\n // Fire-and-handle response to update store flags (do not block init)\n fetch(`${usersBase}/v2/${accountId}/track-user-res`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}),\n },\n body: JSON.stringify({\n user_id: finalUserId,\n screenName: (typeof window !== 'undefined' && window.location && window.location.pathname) ? window.location.pathname : '',\n silentUpdate: true,\n }),\n })\n .then(async (resp) => {\n if (!resp.ok) return;\n try {\n const data = await resp.json();\n const s = useAppStorysStore.getState();\n if (typeof data.screen_capture_enabled !== 'undefined') {\n const val = Boolean(data.screen_capture_enabled);\n console.info('AppStorys: track-user-res returned screen_capture_enabled=', val);\n s.setScreenCaptureEnabled(val);\n }\n } catch (e) {\n /* ignore */\n }\n })\n .catch((err) => console.warn('track-user-res (init) failed', err));\n } catch (err) {\n console.warn('track-user-res (init) setup failed', err);\n }\n\n const { campaigns, version } = await fetchAllCampaigns(accountId);\n\n // Non-blocking: preload any remote fonts referenced by campaign styling.\n // Backend can send fontFamily as a URL (e.g. .ttf). Browsers need @font-face.\n try {\n void preloadFontsFromCampaigns(campaigns as any);\n } catch (err) {\n console.warn('Failed to preload campaign fonts', err);\n }\n\n const state = useAppStorysStore.getState();\n state.setAppId(appId);\n state.setAccountId(accountId);\n state.setUserId(finalUserId);\n state.setIsAnonymousUser(isAnonymous);\n state.setBaseUrl(options.baseUrl);\n state.setTrackingUrl(options.trackingUrl);\n state.saveAllCampaigns(campaigns);\n state.setCampaignVersion(version);\n\n // After campaigns and store are populated, mount screen-capture button if enabled\n try {\n const s = useAppStorysStore.getState();\n if (s.screenCaptureEnabled) {\n const scModule = await import('./core/screenCapture');\n scModule.mountScreenCaptureButton();\n }\n } catch (err) {\n // mounting failure shouldn't block initialization\n console.warn('Failed to mount screen capture button', err);\n }\n\n // Initialize Exit Intent / Back Press listeners\n exitIntentManager.setup();\n\n // Initialize Visibility listeners\n visibilityManager.setup();\n\n this.state = SdkState.initialized;\n } catch (e) {\n this.state = SdkState.error;\n console.error('AppStorys initialization failed:', e);\n }\n }\n\n /**\n * Reconciles an already initialized anonymous user with a newly provided identified user.\n */\n private async reconcileUser(\n anonymousUserId: string,\n identifiedUserId: string,\n appId: string,\n accountId: string\n ) {\n try {\n const success = await verifyAccount(accountId, appId, identifiedUserId);\n if (!success) {\n console.error('AppStorys: Failed to verify identified user account during reconciliation.');\n return;\n }\n\n const reconciled = await reconcileAnonymousUser(anonymousUserId, identifiedUserId);\n if (!reconciled) {\n console.error('AppStorys: Failed to reconcile anonymous and identified users.');\n return;\n }\n\n await clearAnonymousUserId();\n\n const state = useAppStorysStore.getState();\n state.setUserId(identifiedUserId);\n state.setIsAnonymousUser(false);\n } catch (error) {\n console.error('AppStorys: Error during user reconciliation:', error);\n }\n }\n\n public async trackScreen(screenName: string) {\n await this.ensureInitialized();\n return trackScreen(screenName);\n }\n\n public async trackEvent(event: string, campaignId?: string, metadata?: Attributes) {\n await this.ensureInitialized();\n return trackEvent(event, campaignId, metadata);\n }\n\n public async setUserProperties(attributes: Attributes) {\n await this.ensureInitialized();\n return setUserProperties(attributes);\n }\n\n public handleLink(link: string | any) {\n if (!link) return;\n\n if (typeof link === 'string') {\n // First try reveal flow: if link references a campaign id, reveal it\n try {\n if (!link.startsWith('http')) {\n const revealed = revealCampaignFromLink(link);\n if (revealed) return;\n }\n } catch (err) {\n // ignore helper errors and fallback to normal behavior\n console.warn('revealCampaignFromLink error', err);\n }\n\n if (link.startsWith('http')) {\n window.open(link, '_blank');\n } else {\n this.navigateToScreen?.(link);\n }\n } else if (typeof link === 'object' && link.value) {\n try {\n const revealed = revealCampaignFromLink(link.value);\n if (revealed) return;\n } catch (err) {\n // ignore\n }\n this.navigateToScreen?.(link.value);\n }\n }\n\n /**\n * Gets the visibility status of the SDK.\n * @returns boolean indicating whether the SDK is considered visible.\n */\n public get visibility(): boolean {\n return useAppStorysStore.getState().isVisible;\n }\n\n /**\n * Manually sets the visibility status of the SDK.\n * Useful for host apps that want to pause/resume SDK activities programmatically.\n * @param isVisible - boolean indicating visibility status.\n */\n public set visibility(isVisible: boolean) {\n visibilityManager.updateVisibility(isVisible);\n }\n\n private async ensureInitialized() {\n if (this.state === SdkState.initialized) return;\n\n const startTime = Date.now();\n while ((this.state as SdkState) !== SdkState.initialized) {\n if (this.state === SdkState.error) throw new Error('AppStorys SDK error');\n if (Date.now() - startTime > 10000) throw new Error('AppStorys SDK initialization timeout');\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n }\n public personalizeText(text: string): string {\n return personalizeText(text);\n }\n}\n\nimport { Story } from './components/Story';\nimport { Widget } from './components/Widget';\nimport Tooltip from './components/Tooltip';\nimport { BottomSheet } from './components/BottomSheet';\nimport Csat from './components/Csat';\nimport Survey from './components/Survey';\nimport { Modal } from './components/Modal';\nimport { Trackable } from './components/Trackable';\nexport type { TrackableProps } from './components/Trackable';\n\nconst instance = new AppStorys();\nexport { instance as AppStorys, Banner, Story, Pip, Widget, Floater, Tooltip, BottomSheet, Csat, Survey, Modal, Trackable, personalizeText };\nexport * from './types';\nexport * from './core/abTesting';\n\n","export type CampaignType = 'BAN' | 'FLT' | 'PIP' | 'SUR' | 'CSAT' | 'WID' | 'MOD' | 'BTS' | 'SCRT' | 'STR' | 'TLTP' | 'TTP';\n\n\nexport interface CrossButtonConfig {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n enabled?: boolean;\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n}\n\nexport interface StorySlideCtaBorderRadius {\n topLeft?: number;\n topRight?: number;\n bottomLeft?: number;\n bottomRight?: number;\n}\n\nexport interface TriggerEventConfig {\n key?: string;\n operator?: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte';\n value?: string;\n back_press?: boolean;\n}\n\nexport interface TriggerEventObject {\n event: string;\n event_config: TriggerEventConfig[];\n}\n\nexport type TriggerEvent = string | TriggerEventObject;\n\nexport interface BaseCampaign {\n id: string;\n campaign_type: CampaignType;\n trigger_event?: TriggerEvent;\n position?: string;\n screen?: string;\n details: any;\n}\n\nexport interface CampaignBanner extends BaseCampaign {\n campaign_type: 'BAN';\n details: {\n id: string;\n image: string | null;\n lottie_data: string | null;\n width: null | number;\n height: null | number;\n originalWidth?: null | number | string;\n originalHeight?: null | number | string;\n link: null | string;\n styling: {\n bottomLeftRadius?: string;\n bottomRightRadius?: string;\n topLeftRadius?: string;\n topRightRadius?: string;\n marginBottom?: string;\n marginLeft?: string;\n marginRight?: string;\n crossButton?: CrossButtonConfig;\n [key: string]: any;\n };\n };\n}\n\nexport interface Attributes {\n [key: string]: any;\n}\n\nexport enum SdkState {\n uninitialized = 'uninitialized',\n initializing = 'initializing',\n initialized = 'initialized',\n error = 'error'\n}\n\nexport interface AppStorysStore {\n userId: string;\n appId: string;\n accountId: string;\n currentScreen: string;\n campaigns: Campaign[];\n allCampaigns: Campaign[];\n campaignVersion: number;\n trackedEvents: string[];\n trackedEventMetadata: Record<string, Attributes[]>;\n attributes?: Attributes;\n isVisible: boolean;\n isAnonymousUser: boolean;\n variantMappings: Record<string, string>;\n personalizationData: Record<string, string>;\n screenCaptureEnabled?: boolean;\n baseUrl?: string;\n trackingUrl?: string;\n}\n\nexport interface StorySlideCtaContainer {\n alignment?: string;\n backgroundColor?: string;\n borderColor?: string;\n borderWidth?: number;\n ctaFullWidth?: boolean;\n ctaWidth?: number;\n height?: number;\n}\n\nexport interface StorySlideCtaText {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n}\n\nexport interface StorySlideCta {\n container?: StorySlideCtaContainer;\n cornerRadius?: StorySlideCtaBorderRadius;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n text?: StorySlideCtaText;\n}\n\nexport interface StorySlideStyling {\n cta?: StorySlideCta;\n meta?: {\n editorSource?: string;\n };\n pc_redirect_type?: string;\n rdrType?: string;\n}\n\nexport interface StorySlide {\n button_text?: string;\n content?: any;\n id: string;\n image: string | null;\n interactions?: any[];\n link: string | null;\n order: number;\n parent: string;\n personalizationData?: any;\n styling?: StorySlideStyling;\n video: string | null;\n}\n\nexport interface StoryGroupStyling {\n cornerRadius?: {\n bottomLeft?: number;\n bottomRight?: number;\n topLeft?: number;\n topRight?: number;\n };\n crossButton?: CrossButtonConfig;\n name?: {\n font?: string;\n fontFamily?: string;\n size?: number;\n };\n ringWidth?: number;\n share?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n enabled?: boolean;\n image?: string;\n margin?: {\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n size?: number;\n slideShowTime?: number;\n soundToggle?: {\n defaultSound?: string;\n enabled?: boolean;\n mute?: any;\n unmute?: any;\n };\n storyGroupText?: string;\n}\n\nexport interface Story {\n cohorts: any;\n id: string;\n name: string;\n nameColor: string;\n order: number;\n ringColor: string;\n slides: StorySlide[];\n styling?: StoryGroupStyling;\n thumbnail: string;\n}\n\nexport interface CampaignStory extends BaseCampaign {\n campaign_type: 'STR';\n details: Story[];\n}\n\nexport interface WidgetImage {\n cohorts: any;\n id: string;\n image: string;\n link: string;\n order: number;\n}\n\nexport interface CampaignWidget extends BaseCampaign {\n campaign_type: 'WID';\n details: {\n height: number;\n id: string;\n styling: {\n borderRadius: number;\n bottomLeftRadius: number;\n bottomMargin: number;\n bottomRightRadius: number;\n leftMargin: number;\n rightMargin: number;\n topLeftRadius: number;\n topMargin: number;\n topRightRadius: number;\n type: string;\n };\n widget_images: WidgetImage[];\n width: number;\n type?: string;\n };\n}\n\nexport interface TooltipStyling {\n appearance?: {\n arrowStyle?: { height?: number; width?: number };\n backdropOpacity?: number;\n colors?: { arrow?: string; backdrop?: string; tooltip?: string };\n cornerRadius?: { bottomLeft?: number; bottomRight?: number; topLeft?: number; topRight?: number };\n highlight?: { padding?: number; radius?: number };\n padding?: { bottom?: number; left?: number; right?: number; top?: number };\n /** When both width and height are set, the tooltip is treated as an\n * image tooltip: the container is sized to this exact (viewport-clamped)\n * box and the image is cropped to fill it edge-to-edge, matching RN's\n * `imageDimensions` + `resizeMode=\"cover\"` behavior. */\n imageDimensions?: { width?: number; height?: number };\n };\n cta?: {\n container?: {\n alignment?: string;\n backgroundColor?: string;\n borderColor?: string;\n borderWidth?: number;\n ctaFullWidth?: boolean;\n ctaWidth?: number;\n height?: number;\n };\n cornerRadius?: { bottomLeft?: number; bottomRight?: number; topLeft?: number; topRight?: number };\n margin?: { bottom?: number; left?: number; right?: number; top?: number };\n text?: { color?: string; fontDecoration?: string[]; fontFamily?: string; fontSize?: number };\n };\n subTitle?: {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n margin?: { bottom?: number; left?: number; right?: number; top?: number };\n textAlign?: string;\n };\n title?: {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n margin?: { bottom?: number; left?: number; right?: number; top?: number };\n textAlign?: string;\n };\n}\n\nexport interface TooltipItem {\n _id: string;\n arrowPosition?: \"left\" | \"right\" | \"top\" | \"bottom\" | string;\n clickAction?: \"nextStep\" | \"close\" | string;\n ctaText?: string;\n enableBackdrop?: boolean;\n eventName?: string;\n link?: string;\n order?: number;\n position?: string;\n styling?: TooltipStyling;\n subtitleText?: string;\n target?: string;\n titleText?: string;\n url?: string | null;\n}\n\nexport interface CampaignTooltip extends BaseCampaign {\n campaign_type: 'TTP';\n details: {\n tooltips?: TooltipItem[];\n \n titleText?: string;\n subtitleText?: string;\n target?: string;\n styling?: TooltipStyling;\n } & Partial<TooltipItem>;\n display_trigger?: boolean;\n}\n\nexport interface BottomSheetElement {\n id: string;\n type: 'image' | 'cta' | 'body' | string;\n order: number;\n [key: string]: any;\n}\n\nexport interface CampaignBottomSheet extends BaseCampaign {\n campaign_type: 'BTS';\n details: {\n backdropColor?: string;\n backdropOpacity?: number;\n backgroundColor?: string;\n bottomsheetType?: string;\n cornerRadius?: {\n bottomLeft?: number;\n bottomRight?: number;\n topLeft?: number;\n topRight?: number;\n };\n crossButton?: CrossButtonConfig;\n elements: BottomSheetElement[];\n id: string;\n name: string;\n };\n}\n\nexport interface SurveyTextStyle {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n textAlign?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n borderwidth?: number;\n}\n\nexport interface SurveyOptionColors {\n background?: string;\n border?: string;\n text?: string;\n}\n\nexport interface SurveyOptionStyle {\n colors?: SurveyOptionColors;\n textStyle?: SurveyTextStyle;\n}\n\nexport interface SurveySlideLogicRule {\n redirectTo?: string;\n selectOption?: string[];\n}\n\nexport interface SurveySlide {\n additionalComment?: {\n enabled?: boolean;\n placeholder?: string;\n };\n id: string;\n logic?: SurveySlideLogicRule[];\n options?: Record<string, string>;\n order: number;\n parent: string;\n question?: string;\n submitButtonText?: string;\n subtitle?: string;\n title?: string;\n}\n\nexport interface SurveyThankYouButtonConfig {\n action?: string;\n enabled?: boolean;\n redirectUrl?: string;\n}\n\nexport interface SurveyCampaignDetails {\n id: string;\n name?: string;\n slides?: SurveySlide[];\n styling?: {\n appearance?: {\n backdropColor?: string;\n backdropOpacity?: number;\n backgroundColor?: string;\n cornerRadius?: {\n topLeft?: number;\n topRight?: number;\n bottomLeft?: number;\n bottomRight?: number;\n };\n displayDelay?: number;\n };\n content?: {\n isIntroductionPage?: boolean;\n isThankyouPage?: boolean;\n };\n crossButton?: CrossButtonConfig;\n cta?: StorySlideCta;\n options?: {\n additionalComments?: SurveyOptionStyle;\n bulletSpacing?: number;\n cornerRadius?: StorySlideCtaBorderRadius;\n nonSelectedOptions?: SurveyOptionStyle;\n optionListStyle?: string;\n optionsHeight?: number;\n optionsSpacing?: number;\n selectedOptions?: SurveyOptionStyle;\n };\n subtitle?: {\n textStyle?: SurveyTextStyle;\n };\n thankyouPage?: {\n cta?: StorySlideCta;\n imageStyle?: {\n height?: number;\n width?: number;\n };\n subtitle?: {\n textStyle?: SurveyTextStyle;\n };\n title?: {\n textStyle?: SurveyTextStyle;\n };\n };\n title?: {\n textStyle?: SurveyTextStyle;\n };\n };\n thankYouButtonConfig?: SurveyThankYouButtonConfig;\n thankYouButtonText?: string;\n thankYouImage?: string;\n thankYouText?: string;\n thankYouTitle?: string;\n}\n\nexport interface CampaignSurvey extends BaseCampaign {\n campaign_type: 'SUR';\n details: SurveyCampaignDetails;\n}\n\nexport interface CsatTextStyle {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n textAlign?: string;\n}\n\nexport interface CsatSpacing {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\nexport interface CsatCampaignDetails {\n campaign?: string;\n description_text?: string;\n feedback_option?: Record<string, string>;\n height?: number;\n highStarText?: string;\n id: string;\n link?: string;\n lowStarText?: string;\n styling?: {\n appearance?: {\n backgroundColor?: string;\n borderRadius?: number;\n displayDelay?: number;\n margin?: CsatSpacing;\n padding?: CsatSpacing;\n };\n crossButton?: CrossButtonConfig;\n feedbackPage?: {\n additionalComments?: {\n borderWidth?: number;\n colors?: {\n background?: string;\n border?: string;\n text?: string;\n };\n enabled?: boolean;\n placeholder?: string;\n textStyle?: CsatTextStyle;\n };\n options?: {\n cornerRadius?: {\n topLeft?: number;\n topRight?: number;\n bottomLeft?: number;\n bottomRight?: number;\n };\n margin?: CsatSpacing;\n nonSelectedOptions?: {\n borderWidth?: number;\n colors?: {\n background?: string;\n border?: string;\n text?: string;\n };\n textStyle?: CsatTextStyle;\n };\n optionsHeight?: number;\n optionsSpacing?: number;\n selectedOptions?: {\n borderWidth?: number;\n colors?: {\n background?: string;\n border?: string;\n text?: string;\n };\n textStyle?: CsatTextStyle;\n };\n };\n submitButton?: {\n cta?: StorySlideCta;\n enabled?: boolean;\n text?: string;\n };\n };\n initialFeedback?: {\n subtitle?: {\n margin?: CsatSpacing;\n textStyle?: CsatTextStyle;\n };\n title?: {\n margin?: CsatSpacing;\n textStyle?: CsatTextStyle;\n };\n };\n rating?: {\n emoji?: string[] | Record<string, string> | string | null;\n highRatingSubtitle?: string;\n highRatingTitle?: string;\n lowRatingSubtitle?: string;\n lowRatingTitle?: string;\n number?: number | { min?: number; max?: number } | null;\n ratingType?: string;\n star?: {\n high?: {\n stylingContainer?: { background?: string; border?: string; borderWidth?: number };\n stylingStar?: { background?: string; border?: string; borderWidth?: number };\n };\n low?: {\n stylingContainer?: { background?: string; border?: string; borderWidth?: number };\n stylingStar?: { background?: string; border?: string; borderWidth?: number };\n };\n unselected?: {\n stylingContainer?: { background?: string; border?: string; borderWidth?: number };\n stylingStar?: { background?: string; border?: string; borderWidth?: number };\n };\n };\n };\n thankyouPage?: {\n doneButton?: {\n cta?: StorySlideCta;\n text?: string;\n };\n imageStyle?: {\n height?: number;\n width?: number;\n };\n subtitle?: {\n margin?: CsatSpacing;\n textStyle?: CsatTextStyle;\n };\n title?: {\n margin?: CsatSpacing;\n textStyle?: CsatTextStyle;\n };\n };\n };\n thankyouDescription?: string;\n thankyouImage?: string;\n thankyouText?: string;\n title?: string;\n width?: number;\n}\n\nexport interface CampaignCsat extends BaseCampaign {\n campaign_type: 'CSAT';\n details: CsatCampaignDetails;\n}\n\nexport interface ModalCtaRedirection {\n key?: string;\n pageName?: string;\n type?: string;\n url?: string;\n value?: string;\n}\n\nexport interface ModalMediaType {\n type?: 'image' | 'video' | string;\n url?: string;\n}\n\nexport interface ModalContent {\n chooseMediaType?: ModalMediaType;\n primaryCtaRedirection?: ModalCtaRedirection;\n primaryCtaText?: string;\n secondaryCtaRedirection?: ModalCtaRedirection;\n secondaryCtaText?: string;\n subtitleText?: string;\n titleText?: string;\n}\n\nexport interface ModalTextStyle {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n textAlign?: string;\n}\n\nexport interface ModalCtaStyle {\n container?: {\n alignment?: string;\n backgroundColor?: string;\n borderColor?: string;\n borderWidth?: number;\n ctaFullWidth?: boolean;\n ctaWidth?: number;\n height?: number;\n };\n cornerRadius?: {\n bottomLeft?: number;\n bottomRight?: number;\n topLeft?: number;\n topRight?: number;\n };\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n text?: {\n color?: string;\n fontDecoration?: string[];\n fontFamily?: string;\n fontSize?: number;\n };\n}\n\nexport interface ModalItemStyling {\n appearance?: {\n backdrop?: {\n color?: string;\n opacity?: number;\n };\n backgroundColor?: string;\n cornerRadius?: {\n bottomLeft?: number;\n bottomRight?: number;\n topLeft?: number;\n topRight?: number;\n };\n dimension?: {\n width?: number;\n height?: number;\n };\n enableBackdrop?: boolean;\n };\n crossButton?: CrossButtonConfig;\n primaryCta?: ModalCtaStyle;\n secondaryCta?: ModalCtaStyle;\n subTitle?: ModalTextStyle;\n title?: ModalTextStyle;\n}\n\nexport interface ModalItem {\n content?: ModalContent;\n modal_type?: string;\n modalType?: string;\n screen?: number;\n styling?: ModalItemStyling;\n chooseMediaType?: ModalMediaType;\n redirection?: ModalCtaRedirection;\n image?: string;\n video?: string;\n}\n\nexport interface ModalCampaignDetails {\n id: string;\n modal_type?: string;\n modalType?: string;\n modals?: ModalItem[];\n chooseMediaType?: ModalMediaType;\n redirection?: ModalCtaRedirection;\n styling?: ModalItemStyling;\n}\n\nexport interface CampaignModal extends BaseCampaign {\n campaign_type: 'MOD';\n details: ModalCampaignDetails;\n display_trigger?: boolean;\n isTesting?: boolean;\n priority?: number;\n}\n\nexport type Campaign = CampaignBanner | CampaignStory | CampaignWidget | CampaignTooltip | CampaignBottomSheet | CampaignCsat | CampaignSurvey | CampaignModal | BaseCampaign;\n\nexport interface InitializationOptions {\n appId: string;\n accountId: string;\n userId?: string;\n baseUrl?: string;\n trackingUrl?: string;\n navigateToScreen?: (screen: string) => void;\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport * as LottieModule from 'lottie-react';\nimport { CampaignBanner } from '../../types';\nimport useAppStorysStore from '../../core/store';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport CrossButton from '../common/CommonElements/CrossButton';\n\nconst Lottie =\n (LottieModule as any).default?.default ??\n (LottieModule as any).default ??\n (LottieModule as any).Lottie ??\n (LottieModule as any);\n\nexport const Banner: React.FC = () => {\n const data = useCampaigns<CampaignBanner>('BAN');\n const sdkVisible = useAppStorysStore((state) => state.isVisible);\n const [isDismissed, setIsDismissed] = useState(false);\n const [lottieData, setLottieData] = useState<any>(null);\n const [aspectRatio, setAspectRatio] = useState<number | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState<number>(0);\n\n const trackedViewRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (data?.id && trackedViewRef.current !== data.id) {\n trackedViewRef.current = data.id;\n setIsDismissed(false);\n void trackEvent('viewed', data.id);\n\n // Fetch Lottie data if available\n if (data.details?.lottie_data) {\n fetch(data.details.lottie_data)\n .then(res => res.json())\n .then(json => {\n setLottieData(json);\n if (json.w && json.h) {\n setAspectRatio(json.h / json.w);\n }\n })\n .catch(err => console.error('Error loading Lottie:', err));\n }\n }\n }, [data?.id]);\n\n useEffect(() => {\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.offsetWidth);\n }\n };\n\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [data, isDismissed]);\n\n if (!data || isDismissed || !sdkVisible) return null;\n\n const { details } = data;\n const styling = details.styling || {};\n \n // Height is already correctly driven by details.height.\n let calculatedHeight: string | number = details.height || 'auto';\n if (aspectRatio && containerWidth) {\n calculatedHeight = containerWidth * aspectRatio;\n }\n\n // Calculate width from the original image aspect ratio.\n // Use Number() so both numeric 1536 and string \"1536\" are handled safely.\n const _h = parseFloat(String(details.height));\n const _ow = parseFloat(String((details as any).originalWidth ?? details.styling?.originalWidth));\n const _oh = parseFloat(String((details as any).originalHeight ?? details.styling?.originalHeight));\n const calculatedWidth: number | null =\n Number.isFinite(_h) && _h > 0 &&\n Number.isFinite(_ow) && _ow > 0 &&\n Number.isFinite(_oh) && _oh > 0\n ? _h * (_ow / _oh)\n : null;\n\n const bannerWidthPx = calculatedWidth !== null ? `${calculatedWidth}px` : undefined;\n const bannerHeightPx = typeof calculatedHeight === 'number' ? `${calculatedHeight}px` : (calculatedHeight as string) || undefined;\n\n const marginRight = Number(styling.marginRight);\n const marginBottom = Number(styling.marginBottom);\n\n // OUTER: handles only `position: fixed` placement (right / bottom / zIndex).\n // We explicitly ignore `marginLeft` and `marginTop` for the Web SDK Banner.\n // It does NOT carry width/height — it shrink-wraps to the inner div.\n const outerStyle: React.CSSProperties = {\n position: 'fixed' as const,\n right: Number.isFinite(marginRight) ? `${marginRight}px` : '0px',\n bottom: Number.isFinite(marginBottom) ? `${marginBottom}px` : '0px',\n zIndex: 9999,\n display: 'block',\n cursor: details.link ? 'pointer' : 'default',\n };\n\n // INNER: carries explicit pixel dimensions + border-radius + overflow.\n // `position: relative` makes this the containing block for the\n // `position: absolute` cross button — so the button is ALWAYS anchored\n // to the actual image box, never to the viewport.\n const innerStyle: React.CSSProperties = {\n position: 'relative' as const,\n width: bannerWidthPx || '100%',\n height: bannerHeightPx || 'auto',\n backgroundColor: 'transparent',\n borderRadius: `${styling.topRightRadius || 0}px ${styling.topLeftRadius || 0}px ${styling.bottomRightRadius || 0}px ${styling.bottomLeftRadius || 0}px`,\n overflow: 'hidden',\n };\n\n // Image fills the inner box exactly.\n const mediaStyle: React.CSSProperties = {\n width: '100%',\n height: '100%',\n display: 'block',\n objectFit: 'contain',\n };\n\n const handleClose = (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsDismissed(true);\n void trackEvent('banner_closed', data.id);\n };\n\n const handleClick = () => {\n if (details.link) {\n void trackEvent('clicked', data.id);\n if (details.link.startsWith('http')) {\n window.open(details.link, '_blank');\n } else {\n // Try reveal via campaign id first\n try {\n const revealed = revealCampaignFromLink(details.link);\n if (revealed) return;\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n // Fallback to logging/navigation\n console.log('Internal link:', details.link);\n }\n }\n };\n\n return (\n // Outer: position:fixed — sets where the Banner sits on screen.\n <div ref={containerRef} style={outerStyle} onClick={handleClick}>\n {/*\n Inner: position:relative + explicit px size — the actual visible Banner box.\n The cross button (position:absolute) is a child of this div, so `right:5px`\n means 5px from THIS box's right edge, never from the viewport right edge.\n */}\n <div style={innerStyle}>\n {lottieData ? (() => {\n const LottieComp = (Lottie as any).default || Lottie;\n return (\n <LottieComp \n animationData={lottieData} \n loop={true} \n autoplay={sdkVisible}\n style={mediaStyle}\n />\n );\n })() : details.image ? (\n <img src={details.image} alt=\"Campaign Banner\" style={mediaStyle} />\n ) : null}\n\n {styling.crossButton?.enabled && (\n <CrossButton\n config={styling.crossButton}\n onPress={handleClose}\n style={{\n // We anchor to top: 0, right: 0. \n // CrossButton internally applies marginTop and marginRight from the config.\n // If no config margins are provided, we add a 5px fallback anchor so it's not perfectly flush.\n top: styling.crossButton?.margin?.top !== undefined ? 0 : 5,\n right: styling.crossButton?.margin?.right !== undefined ? 0 : 5,\n }}\n />\n )}\n </div>\n </div>\n );\n};\n","import { useMemo } from \"react\";\nimport { Campaign, TriggerEventConfig, TriggerEventObject, Attributes, TriggerEvent } from \"../types\";\nimport useAppStorysStore from \"../core/store\";\nimport { resolveCampaignVariant } from \"../core/variantResolver\";\n\nexport const BACK_PRESS_SENTINEL = '__back_press_triggered__';\n\ninterface UseCampaignsOptions {\n position?: string;\n screenContains?: string;\n}\n\nfunction normalizeScreenName(screen?: string | null): string {\n return (screen || '').trim().toLowerCase();\n}\n\nfunction isScreenMatch(campaignScreen: string | undefined, currentScreen: string): boolean {\n const normalizedCampaignScreen = normalizeScreenName(campaignScreen);\n const normalizedCurrentScreen = normalizeScreenName(currentScreen);\n return !normalizedCampaignScreen || normalizedCampaignScreen === normalizedCurrentScreen;\n}\n\nfunction compareValues(actual: string, operator: TriggerEventConfig['operator'], expected: string): boolean {\n const numActual = Number(actual);\n const numExpected = Number(expected);\n const useNumeric = !isNaN(numActual) && !isNaN(numExpected);\n\n switch (operator) {\n case 'eq': return useNumeric ? numActual === numExpected : actual === expected;\n case 'neq': return useNumeric ? numActual !== numExpected : actual !== expected;\n case 'gt': return useNumeric ? numActual > numExpected : actual > expected;\n case 'gte': return useNumeric ? numActual >= numExpected : actual >= expected;\n case 'lt': return useNumeric ? numActual < numExpected : actual < expected;\n case 'lte': return useNumeric ? numActual <= numExpected : actual <= expected;\n default: return false;\n }\n}\n\nfunction matchesEventConditions(\n event_config: TriggerEventConfig[],\n metadataList: Attributes[],\n): boolean {\n const realConditions = event_config.filter((c) => c.back_press == null);\n if (realConditions.length === 0) return true;\n\n return metadataList.some((meta) =>\n realConditions.every((condition) => {\n const actual = meta[condition.key!];\n if (actual === undefined || actual === null) return false;\n return compareValues(String(actual), condition.operator!, condition.value!);\n })\n );\n}\n\nfunction isTriggerEventSatisfied(\n campaign: Campaign,\n trackedEvents: string[],\n trackedEventMetadata: Record<string, Attributes[]>,\n): boolean {\n // Support both the typed `trigger_event` and legacy `trigger` fields from campaign JSON\n const t = campaign as any;\n const trigger_event = (t.trigger_event ?? t.trigger) as TriggerEvent | undefined;\n const id = (campaign as Campaign & { id?: string }).id;\n // If a campaign carries any trigger information, do not show it by default.\n // The presence of `trigger_event` or legacy `trigger` indicates it's intended\n // to be shown only in response to an event; hide unless that event handling\n // code explicitly adds it back to the visible campaigns list.\n if (trigger_event) return false;\n\n return true;\n}\n\n/**\n * Checks whether any currently loaded campaign is a back_press (exit intent) campaign\n * that is ready to show but not yet triggered.\n */\nexport function isBackPressCampaignReady(): boolean {\n const { campaigns, trackedEvents, trackedEventMetadata, currentScreen } = useAppStorysStore.getState();\n\n return campaigns.some((campaign) => {\n if (campaign.screen && campaign.screen !== currentScreen) return false;\n\n const te = (campaign as any).trigger_event;\n if (!te || typeof te === 'string') return false;\n\n const { event, event_config } = te as TriggerEventObject;\n if (!(event_config ?? []).some((c: TriggerEventConfig) => c.back_press === true)) return false;\n\n // Already consumed\n if (trackedEvents.includes(BACK_PRESS_SENTINEL)) return false;\n\n // The underlying event must have been tracked\n if (!trackedEvents.includes(event)) return false;\n\n // Non-back_press conditions must also pass\n const realConditions = (event_config ?? []).filter((c: TriggerEventConfig) => c.back_press == null);\n if (realConditions.length === 0) return true;\n\n const metadataList = trackedEventMetadata[event] || [];\n return matchesEventConditions(realConditions, metadataList);\n });\n}\n\nexport default function useCampaigns<T extends Campaign>(campaignType: string, options?: UseCampaignsOptions): T | undefined {\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const trackedEvents = useAppStorysStore((state) => state.trackedEvents);\n const trackedEventMetadata = useAppStorysStore((state) => state.trackedEventMetadata);\n const variantMappings = useAppStorysStore((state) => state.variantMappings);\n\n return useMemo(\n () => {\n const matchCampaign = (list: Campaign[]) => list.find((campaign) =>\n isScreenMatch(campaign.screen, currentScreen) &&\n campaign.campaign_type === campaignType &&\n (options?.position ? campaign.position === options.position : true) &&\n isTriggerEventSatisfied(campaign, trackedEvents, trackedEventMetadata)\n );\n\n const fromEligible = campaigns && campaigns.length > 0 ? matchCampaign(campaigns) : undefined;\n const campaign = fromEligible ?? matchCampaign(allCampaigns || []);\n\n if (!campaign) return undefined;\n return resolveCampaignVariant(campaign) as T | undefined;\n },\n [campaigns, allCampaigns, trackedEvents, trackedEventMetadata, variantMappings, campaignType, options, currentScreen],\n );\n}\n\nexport function useCampaignsList<T extends Campaign>(campaignType: string, options?: UseCampaignsOptions): T[] {\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const trackedEvents = useAppStorysStore((state) => state.trackedEvents);\n const trackedEventMetadata = useAppStorysStore((state) => state.trackedEventMetadata);\n\n return useMemo(() => {\n const list = (campaigns && campaigns.length > 0) ? campaigns : (allCampaigns || []);\n\n const filtered = list.filter((campaign) => {\n if (campaign.campaign_type !== campaignType) return false;\n if (options?.position && campaign.position !== options.position) return false;\n if (!isTriggerEventSatisfied(campaign, trackedEvents, trackedEventMetadata)) return false;\n\n // If caller passed a screenContains option, match substring (case-insensitive)\n if (options?.screenContains) {\n const needle = (options.screenContains || '').trim().toLowerCase();\n const cs = (campaign.screen || '').trim().toLowerCase();\n return cs.includes(needle);\n }\n\n // Fallback to existing screen matching logic\n return isScreenMatch(campaign.screen, currentScreen);\n });\n\n return filtered.map((c) => resolveCampaignVariant(c) as T) as T[];\n }, [campaigns, allCampaigns, trackedEvents, trackedEventMetadata, campaignType, options, currentScreen]);\n}\n","import { Campaign } from \"../../types\";\nimport useAppStorysStore from \"../store\";\n\nexport interface VariantDetails {\n id?: string;\n name?: string;\n weight?: number;\n isControl?: boolean;\n isActive?: boolean;\n modal_type?: string;\n modals?: any[];\n [key: string]: any;\n}\n\nexport type VariantsMap = Record<string, VariantDetails>;\n\nconst STORAGE_KEY_VARIANTS = 'appstorys_variant_mappings';\n\n// In-memory cache for instant synchronous lookup across renders\nconst inMemoryVariantCache: Record<string, string> = {};\n\nfunction simpleHash(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash |= 0;\n }\n return Math.abs(hash);\n}\n\nfunction loadStoredMappings(): Record<string, string> {\n if (typeof window === 'undefined') return {};\n try {\n const raw = localStorage.getItem(STORAGE_KEY_VARIANTS);\n if (raw) return JSON.parse(raw);\n } catch {\n // ignore\n }\n return {};\n}\n\nfunction persistVariantMapping(campaignId: string, variantId: string): void {\n if (!campaignId || !variantId) return;\n\n // 1. Update in-memory cache\n inMemoryVariantCache[campaignId] = variantId;\n\n // 2. Update Zustand store\n try {\n const state = useAppStorysStore.getState();\n const current = state.variantMappings || {};\n if (current[campaignId] !== variantId) {\n state.setVariantMappings({\n ...current,\n [campaignId]: variantId,\n });\n }\n } catch {\n // ignore\n }\n\n // 3. Update localStorage\n if (typeof window !== 'undefined') {\n try {\n const stored = loadStoredMappings();\n stored[campaignId] = variantId;\n localStorage.setItem(STORAGE_KEY_VARIANTS, JSON.stringify(stored));\n } catch {\n // ignore\n }\n }\n}\n\nexport const getVariantId = (campaignId: string): string | undefined => {\n if (!campaignId) return undefined;\n\n // Check 1: In-memory cache\n if (inMemoryVariantCache[campaignId]) {\n return inMemoryVariantCache[campaignId];\n }\n\n // Check 2: Zustand store\n const fromStore = useAppStorysStore.getState().variantMappings?.[campaignId];\n if (fromStore) {\n inMemoryVariantCache[campaignId] = fromStore;\n return fromStore;\n }\n\n // Check 3: localStorage\n const stored = loadStoredMappings();\n if (stored[campaignId]) {\n inMemoryVariantCache[campaignId] = stored[campaignId];\n try {\n useAppStorysStore.getState().setVariantMappings({\n ...(useAppStorysStore.getState().variantMappings || {}),\n [campaignId]: stored[campaignId],\n });\n } catch {\n // ignore\n }\n return stored[campaignId];\n }\n\n return undefined;\n};\n\nexport function hasVariants(campaign: Campaign | any): boolean {\n if (!campaign) return false;\n if (campaign.hasVariants === true) return true;\n if (campaign.variants && typeof campaign.variants === 'object' && Object.keys(campaign.variants).length > 0) {\n return true;\n }\n if (campaign.details && typeof campaign.details === 'object' && campaign.details.variants) {\n const v = campaign.details.variants;\n if (typeof v === 'object' && Object.keys(v).length > 0) return true;\n }\n return false;\n}\n\nexport function selectVariantByWeight(variants: VariantsMap, campaignId?: string): string | undefined {\n const keys = Object.keys(variants);\n if (keys.length === 0) return undefined;\n\n const activeKeys = keys.filter((key) => variants[key] && variants[key].isActive !== false);\n const eligibleKeys = activeKeys.length > 0 ? activeKeys : keys;\n\n const totalWeight = eligibleKeys.reduce((sum, key) => sum + (Number(variants[key]?.weight) || 0), 0);\n\n if (totalWeight > 0) {\n // Deterministic selection based on campaignId and userId to prevent variant switching across renders/sessions\n const userId = useAppStorysStore.getState().userId || 'default';\n const seed = `${campaignId || 'campaign'}_${userId}`;\n const hashVal = simpleHash(seed);\n let roll = ((hashVal % 10000) / 10000) * totalWeight;\n\n for (const key of eligibleKeys) {\n const w = Number(variants[key]?.weight) || 0;\n if (roll < w) return key;\n roll -= w;\n }\n }\n\n return eligibleKeys[0];\n}\n\nexport function resolveCampaignVariant<T extends Campaign>(campaign: T): T {\n if (!campaign || !hasVariants(campaign)) {\n return campaign;\n }\n\n const c = campaign as any;\n const variants: VariantsMap | undefined = c.variants || c.details?.variants;\n\n if (!variants || typeof variants !== 'object' || Object.keys(variants).length === 0) {\n return campaign;\n }\n\n let variantId = getVariantId(c.id || '');\n\n if (!variantId || !variants[variantId]) {\n variantId = selectVariantByWeight(variants, c.id);\n if (c.id && variantId) {\n persistVariantMapping(c.id, variantId);\n }\n }\n\n if (!variantId || !variants[variantId]) {\n return campaign;\n }\n\n const variantDetails = variants[variantId];\n\n const baseDetails = (c.details && typeof c.details === 'object')\n ? Object.fromEntries(Object.entries(c.details).filter(([key]: [string, any]) => key !== 'variants'))\n : {};\n\n const mergedDetails = {\n ...baseDetails,\n ...variantDetails,\n };\n\n return {\n ...campaign,\n details: mergedDetails,\n _variantId: variantId,\n } as T;\n}\n\nexport function getCampaignVariantId(campaign: Campaign): string | undefined {\n if (!campaign) return undefined;\n if ('_variantId' in campaign) {\n return (campaign as any)._variantId;\n }\n\n if (hasVariants(campaign)) {\n return getVariantId(campaign.id || '');\n }\n\n return undefined;\n}\n\nexport default resolveCampaignVariant;\n","import useAppStorysStore, { getAccessToken, getUserId, getVariantId } from \"./store\";\nimport { Attributes } from \"../types\";\nimport getDeviceInfo from \"./getDeviceInfo\";\nimport { sendOrQueue } from \"./offlineQueue\";\n\nexport default async function trackEvent(event: string, campaignId?: string, metadata?: Attributes) {\n try {\n if (!event) return;\n\n const accessToken = await getAccessToken();\n const state = useAppStorysStore.getState();\n\n const excludedEvents = [\n \"viewed\",\n \"clicked\",\n \"csat captured\",\n \"survey captured\",\n \"shared\"\n ];\n\n if (!excludedEvents.includes(event)) {\n const trackedEvents = state.trackedEvents;\n if (!trackedEvents.includes(event)) {\n state.setTrackedEvents([...trackedEvents, event]);\n } else {\n const updatedEvents = trackedEvents.filter(e => e !== event);\n updatedEvents.push(event);\n state.setTrackedEvents(updatedEvents);\n }\n\n if (metadata && Object.keys(metadata).length > 0) {\n const currentMeta = state.trackedEventMetadata || {};\n const existing = currentMeta[event] || [];\n state.setTrackedEventMetadata({\n ...currentMeta,\n [event]: [...existing, metadata],\n });\n }\n }\n\n let finalMetadata: Record<string, any> = {\n ...(metadata || {}),\n };\n\n if (!excludedEvents.includes(event)) {\n const deviceInfo = await getDeviceInfo();\n finalMetadata = {\n ...finalMetadata,\n ...deviceInfo,\n };\n }\n\n // Mirror native: include variant_id when a mapping exists for the campaign id or passed in metadata\n if (campaignId && String(campaignId).trim() !== \"\") {\n const variantId = metadata?.variant_id || getVariantId(campaignId);\n if (variantId) {\n finalMetadata.variant_id = variantId;\n }\n }\n\n const body: Record<string, any> = {\n user_id: getUserId(),\n event: event,\n metadata: finalMetadata,\n };\n if (campaignId) {\n body.campaign_id = campaignId;\n }\n\n const trackingUrl = state.trackingUrl || 'https://tracking.appstorys.co';\n\n if (accessToken) {\n await sendOrQueue({\n url: `${trackingUrl}/capture-event`,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: body,\n });\n }\n } catch (error) {\n console.error('Error in trackEvent', error);\n }\n}\n","import { WebStorage } from '../adapters/web/storage';\nimport useAppStorysStore, { getAccessToken } from './store';\nimport verifyAccount from './verifyAccount';\n\nconst OFFLINE_QUEUE_KEY = \"appstorys_offline_queue\";\n\nexport interface QueuedRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n body: any;\n retryCount?: number;\n lastAttempt?: number;\n authRetried?: boolean;\n}\n\nasync function getQueue(): Promise<QueuedRequest[]> {\n const existing = await WebStorage.getItem(OFFLINE_QUEUE_KEY);\n return existing ? JSON.parse(existing) : [];\n}\n\nasync function saveQueue(queue: QueuedRequest[]) {\n await WebStorage.setItem(OFFLINE_QUEUE_KEY, JSON.stringify(queue));\n}\n\nfunction getBackoffDelay(retryCount: number): number {\n // Exponential backoff: 30s, 1min, 2min (max 2min)\n return Math.min(30000 * Math.pow(2, retryCount), 120000);\n}\n\nfunction shouldRetryRequest(request: QueuedRequest): boolean {\n const maxRetries = 3;\n const retryCount = request.retryCount || 0;\n const lastAttempt = request.lastAttempt || 0;\n const backoffDelay = getBackoffDelay(retryCount);\n\n return retryCount < maxRetries && Date.now() - lastAttempt >= backoffDelay;\n}\n\nasync function validateCredentials(): Promise<boolean> {\n const state = useAppStorysStore.getState();\n if (!state.accountId || !state.appId) return false;\n \n return await verifyAccount(\n state.accountId,\n state.appId,\n state.userId\n );\n}\n\nasync function handleAuthError(\n request: QueuedRequest,\n onSuccess: (request: QueuedRequest) => void\n) {\n const credentialsValid = await validateCredentials();\n\n if (credentialsValid) {\n const newToken = await WebStorage.getItem('access_token');\n if (newToken) {\n request.headers = {\n ...request.headers,\n Authorization: `Bearer ${newToken}`,\n };\n }\n request.authRetried = true;\n request.lastAttempt = Date.now();\n onSuccess(request);\n }\n}\n\nasync function handleCriticalError(\n request: QueuedRequest, \n onSuccess: (request: QueuedRequest) => void\n) {\n const retryCount = (request.retryCount || 0) + 1;\n\n if (retryCount <= 3) {\n request.retryCount = retryCount;\n request.lastAttempt = Date.now();\n onSuccess(request);\n }\n}\n\nasync function addToQueue(request: QueuedRequest) {\n const queue = await getQueue();\n queue.push(request);\n await saveQueue(queue);\n}\n\nexport async function flushQueue() {\n const queue = await getQueue();\n if (queue.length === 0) return;\n\n const newQueue: QueuedRequest[] = [];\n\n for (const req of queue) {\n if (!shouldRetryRequest(req)) {\n newQueue.push(req);\n continue;\n }\n\n try {\n const res = await fetch(req.url, {\n method: req.method,\n headers: req.headers,\n body: JSON.stringify(req.body),\n });\n\n if (res.ok) continue;\n\n if (res.status === 401 || res.status === 403) {\n if (!req.authRetried) {\n await handleAuthError(req, (r) => newQueue.push(r));\n }\n } else if (res.status >= 500) {\n await handleCriticalError(req, (r) => newQueue.push(r));\n }\n } catch (err) {\n await handleCriticalError(req, (r) => newQueue.push(r));\n }\n }\n\n await saveQueue(newQueue);\n}\n\nexport async function sendOrQueue(request: QueuedRequest): Promise<Response | void> {\n if (!navigator.onLine) {\n await addToQueue(request);\n return;\n }\n\n // Auto-flush existing queue\n await flushQueue();\n\n try {\n const res = await fetch(request.url, {\n method: request.method,\n headers: request.headers,\n body: JSON.stringify(request.body),\n });\n\n if (res.ok) return res;\n\n if (res.status === 401 || res.status === 403) {\n await handleAuthError(request, addToQueue);\n } else if (res.status >= 500) {\n await handleCriticalError(request, addToQueue);\n }\n\n return res;\n } catch (err) {\n await handleCriticalError(request, addToQueue);\n return;\n }\n}\n","import useAppStorysStore from './store';\n\nexport function isTriggerDriven(campaign: any): boolean {\n return Boolean((campaign && (campaign.trigger_event ?? campaign.trigger)));\n}\n\nexport function revealCampaignFromLink(link: string): boolean {\n if (!link) return false;\n const s = useAppStorysStore.getState();\n const all = s.allCampaigns || [];\n const existing = s.campaigns || [];\n\n const normalizedLink = String(link).trim();\n\n const referenced = all.find((c: any) => {\n if (!c) return false;\n const cid = String(c.id || '').trim();\n const details = c.details || {};\n const detailsCampaign = String(details.campaign || details.id || '').trim();\n if (cid && cid === normalizedLink) return true;\n if (detailsCampaign && detailsCampaign === normalizedLink) return true;\n if (cid && normalizedLink.includes(cid)) return true;\n if (detailsCampaign && normalizedLink.includes(detailsCampaign)) return true;\n return false;\n });\n\n if (!referenced) return false;\n\n const revealed: any = { ...referenced };\n delete revealed.trigger_event;\n delete revealed.trigger;\n revealed.display_trigger = true;\n\n const idx = existing.findIndex((c: any) => String(c.id || '') === String(revealed.id || ''));\n if (idx === -1) {\n s.saveCampaigns([revealed, ...existing]);\n } else {\n const existingItem = existing[idx];\n const existingHasTrigger = Boolean((existingItem as any).trigger_event ?? (existingItem as any).trigger);\n if (existingHasTrigger) {\n const next = [...existing];\n next[idx] = revealed;\n s.saveCampaigns(next);\n }\n }\n\n return true;\n}\n","import React from 'react';\n\nexport interface CrossButtonConfig {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n enabled?: boolean;\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n}\n\ninterface CrossButtonProps {\n config?: CrossButtonConfig | null;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n style?: React.CSSProperties;\n ignoreSizeAndMargin?: boolean;\n}\n\nconst CrossButton: React.FC<CrossButtonProps> = ({ config, onPress, style, ignoreSizeAndMargin = false }) => {\n if (!config || !config.enabled) {\n return null;\n }\n\n const backendSize = config.size;\n const margin = config.margin;\n const color = config.color;\n const image = config.image;\n const selectedStyle = config.selectedStyle;\n\n // Safe defaults & clamp checks\n const safeSize = (backendSize !== undefined && backendSize !== null && backendSize >= 0) ? backendSize : 18;\n const size = ignoreSizeAndMargin ? 40 : safeSize;\n\n const marginTop = (margin?.top !== undefined && margin?.top !== null && margin.top >= 0) ? margin.top : 0;\n const marginBottom = (margin?.bottom !== undefined && margin?.bottom !== null && margin.bottom >= 0) ? margin.bottom : 0;\n const marginLeft = (margin?.left !== undefined && margin?.left !== null && margin.left >= 0) ? margin.left : 0;\n const marginRight = (margin?.right !== undefined && margin?.right !== null && margin.right >= 0) ? margin.right : 0;\n\n const containerStyle: React.CSSProperties = {\n marginTop: ignoreSizeAndMargin ? 0 : marginTop,\n marginBottom: ignoreSizeAndMargin ? 0 : marginBottom,\n marginLeft: ignoreSizeAndMargin ? 0 : marginLeft,\n marginRight: ignoreSizeAndMargin ? 0 : marginRight,\n width: size,\n height: size,\n backgroundColor: color?.fill || 'transparent',\n borderColor: color?.stroke || 'transparent',\n borderWidth: size * 0.05,\n borderRadius: '50%',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 1000000,\n position: 'absolute',\n display: 'flex',\n padding: 0,\n cursor: 'pointer',\n outline: 'none',\n borderStyle: color?.stroke ? 'solid' : 'none',\n ...style,\n };\n\n const renderDefaultIcon = () => {\n const stroke = color?.cross || '#ffffff';\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n </svg>\n );\n };\n\n return (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onPress(e);\n }}\n style={containerStyle}\n title={selectedStyle || ''}\n >\n {image && image.trim() !== '' ? (\n <img\n src={image}\n style={{ width: size, height: size, objectFit: 'contain' }}\n alt=\"close\"\n />\n ) : (\n renderDefaultIcon()\n )}\n </button>\n );\n};\n\nexport default CrossButton;","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport useCampaigns from \"../../hooks/useCampaigns\";\nimport trackEvent from \"../../core/trackEvent\";\nimport useAppStorysStore from \"../../core/store\";\nimport { Campaign } from \"../../types\";\nimport { resolveCampaignVariant } from \"../../core/variantResolver\";\nimport { resolveFontFamily } from \"../../core/fontManager\";\n\ninterface PipCampaignDetails {\n button_text?: string;\n crossButtonImage?: string | null;\n height?: number | string;\n width?: number | string;\n large_video?: string;\n small_video?: string;\n link?: string;\n maximiseImage?: string | null;\n minimiseImage?: string | null;\n muteImage?: string | null;\n position?: \"left\" | \"right\" | string;\n unmuteImage?: string | null;\n styling?: {\n appearance?: {\n defaultSound?: string;\n pipHeight?: string | number;\n pipWidth?: string | number;\n };\n crossButton?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n enabled?: boolean;\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n cta?: {\n container?: {\n backgroundColor?: string;\n borderColor?: string;\n borderWidth?: number;\n ctaWidth?: number;\n ctaFullWidth?: boolean;\n height?: number;\n };\n text?: {\n color?: string;\n fontFamily?: string;\n fontSize?: number;\n };\n };\n expandControls?: {\n enabled?: boolean;\n maximise?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n minimise?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n };\n expandablePip?: string;\n isMovable?: boolean;\n pipBottomPadding?: number | string;\n pipTopPadding?: number | string;\n soundToggle?: {\n enabled?: boolean;\n defaultSound?: string;\n mute?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n unmute?: {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n };\n };\n };\n}\n\ninterface IconConfig {\n color?: {\n cross?: string;\n fill?: string;\n stroke?: string;\n };\n image?: string;\n margin?: {\n bottom?: number;\n left?: number;\n right?: number;\n top?: number;\n };\n selectedStyle?: string;\n size?: number;\n}\n\ntype PipCampaign = Campaign & {\n campaign_type: \"PIP\";\n details: PipCampaignDetails;\n display_trigger?: boolean;\n screen?: string;\n position?: string;\n id: string;\n};\n\nconst normalizeScreen = (value?: string | null): string => (value || \"\").trim().toLowerCase();\n\nconst parseNumber = (value: unknown, fallback: number): number => {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\n/** Dashboard \"Expandable PiP\" may arrive as \"yes\"/\"Yes\"/true/1 — treat all as enabled. */\nconst isExpandableEnabled = (value: unknown): boolean => {\n if (value === true || value === 1) return true;\n if (value === false || value === 0) return false;\n if (value == null || value === \"\") return false;\n const normalized = String(value).trim().toLowerCase();\n return normalized === \"yes\" || normalized === \"true\" || normalized === \"1\";\n};\n\nfunction PipIcon({ iconType, color }: { iconType: \"close\" | \"expand\" | \"minimize\" | \"mute\" | \"unmute\"; color: string }) {\n const stroke = color || \"#FFFFFF\";\n\n if (iconType === \"close\") {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n\n if (iconType === \"expand\") {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polyline points=\"8,3 3,3 3,8\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <line x1=\"3\" y1=\"3\" x2=\"9\" y2=\"9\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <polyline points=\"16,21 21,21 21,16\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n\n if (iconType === \"minimize\") {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polyline points=\"9,9 3,9 3,3\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <line x1=\"3\" y1=\"9\" x2=\"9\" y2=\"3\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <polyline points=\"15,15 21,15 21,21\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <line x1=\"15\" y1=\"21\" x2=\"21\" y2=\"15\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n\n if (iconType === \"mute\") {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polygon points=\"4,10 8,10 13,6 13,18 8,14 4,14\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinejoin=\"round\" />\n <line x1=\"16\" y1=\"8\" x2=\"21\" y2=\"16\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <line x1=\"21\" y1=\"8\" x2=\"16\" y2=\"16\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polygon points=\"4,10 8,10 13,6 13,18 8,14 4,14\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinejoin=\"round\" />\n <path d=\"M16 10 Q18 12 16 14\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <path d=\"M18 8 Q22 12 18 16\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n\nfunction IconButton({\n iconType,\n config,\n imageOverride,\n onClick,\n}: {\n iconType: \"close\" | \"expand\" | \"minimize\" | \"mute\" | \"unmute\";\n config?: IconConfig;\n imageOverride?: string | null;\n onClick: () => void;\n}) {\n const iconSize = parseNumber(config?.size, 18);\n const buttonSize = Math.max(24, iconSize + 10);\n const margin = config?.margin || {};\n\n const imageUrl = imageOverride || config?.image;\n const iconColor = config?.color?.cross || \"#FFFFFF\";\n const fillColor = config?.color?.fill || \"rgba(0,0,0,0.55)\";\n const strokeColor = config?.color?.stroke || \"rgba(255,255,255,0.35)\";\n\n return (\n <button\n data-control-button=\"true\"\n type=\"button\"\n onPointerDown={(e) => { e.preventDefault(); e.stopPropagation(); }}\n onPointerUp={(e) => { e.preventDefault(); e.stopPropagation(); }}\n onMouseDown={(e) => { e.preventDefault(); e.stopPropagation(); }}\n onTouchStart={(e) => { e.preventDefault(); e.stopPropagation(); }}\n onClick={(e) => { e.preventDefault(); e.stopPropagation(); onClick(); }}\n title={config?.selectedStyle || iconType}\n style={{\n width: buttonSize,\n height: buttonSize,\n borderRadius: 999,\n pointerEvents: 'auto',\n zIndex: 10030,\n position: 'relative',\n border: `1px solid ${strokeColor}`,\n background: fillColor,\n color: iconColor,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n padding: 0,\n marginTop: parseNumber(margin.top, 0),\n marginRight: parseNumber(margin.right, 0),\n marginBottom: parseNumber(margin.bottom, 0),\n marginLeft: parseNumber(margin.left, 0),\n }}\n >\n {imageUrl ? (\n <img\n src={imageUrl}\n alt={iconType}\n style={{ width: iconSize, height: iconSize, objectFit: \"contain\" }}\n />\n ) : (\n <PipIcon iconType={iconType} color={iconColor} />\n )}\n </button>\n );\n}\n\nconst Pip: React.FC = () => {\n const hookData = useCampaigns<PipCampaign>(\"PIP\");\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n const sdkVisible = useAppStorysStore((state) => state.isVisible);\n\n const [isClosed, setIsClosed] = useState(false);\n const [isExpanded, setIsExpanded] = useState(false);\n const [isMuted, setIsMuted] = useState(true);\n const [isDragging, setIsDragging] = useState(false);\n const [dragPosition, setDragPosition] = useState<{ x: number; y: number } | null>(null);\n\n const dragOffsetRef = useRef({ x: 0, y: 0 });\n const videoRef = useRef<HTMLVideoElement | null>(null);\n // Tracks the pointer position where a drag began and whether the pointer\n // actually moved, so a drag doesn't get mistaken for a click (which expands).\n const dragStartRef = useRef({ x: 0, y: 0 });\n const didDragRef = useRef(false);\n\n const data = useMemo(() => {\n if (hookData) return hookData;\n\n const screen = normalizeScreen(currentScreen);\n const findFromList = (source: Campaign[]) => source.find((campaign) => {\n const item = campaign as PipCampaign;\n const isPip = item.campaign_type === \"PIP\";\n const matchesScreen = !normalizeScreen(item.screen) || normalizeScreen(item.screen) === screen;\n const hasTrigger = Boolean((item as any).trigger_event ?? (item as any).trigger);\n const displayTriggerReady = item.display_trigger !== false && !hasTrigger;\n return isPip && matchesScreen && displayTriggerReady;\n }) as PipCampaign | undefined;\n\n const found = findFromList(campaigns) ?? findFromList(allCampaigns);\n return found ? (resolveCampaignVariant(found) as PipCampaign) : undefined;\n }, [hookData, campaigns, allCampaigns, currentScreen]);\n\n // When variants are enabled, `resolveCampaignVariant` can produce a new object each render.\n // Stabilize the reference so effects don't reset state on every render.\n const stableData = useMemo(\n () => data,\n [data?.id, (data as any)?.details?.id]\n );\n\n useEffect(() => {\n if (!stableData) return;\n\n const details = (stableData as any).details || {};\n\n const defaultSoundSetting =\n details?.styling?.soundToggle?.defaultSound ||\n details?.styling?.appearance?.defaultSound ||\n \"yes\";\n\n setIsMuted(String(defaultSoundSetting).toLowerCase() !== \"yes\");\n setIsClosed(false);\n setIsExpanded(false);\n setDragPosition(null);\n\n // Match native: send only event + campaign id (no extra metadata)\n void trackEvent(\"viewed\", stableData.id);\n }, [stableData]);\n\n // Emit an `analyze` analytics event when the PIP is expanded\n // NOTE: analytics for expand are emitted where the action happens\n // (see expand handler below) to match native timing/args.\n\n useEffect(() => {\n if (videoRef.current) {\n videoRef.current.muted = isMuted;\n }\n }, [isMuted]);\n\n useEffect(() => {\n if (!isDragging) return;\n\n const onMouseMove = (event: MouseEvent) => {\n const dx = event.clientX - dragStartRef.current.x;\n const dy = event.clientY - dragStartRef.current.y;\n // Only treat as a drag once the pointer has moved beyond a small threshold,\n // so a tiny jitter during a click still counts as a click.\n if (Math.abs(dx) > 4 || Math.abs(dy) > 4) {\n didDragRef.current = true;\n }\n const nextX = event.clientX - dragOffsetRef.current.x;\n const nextY = event.clientY - dragOffsetRef.current.y;\n setDragPosition({ x: Math.max(0, nextX), y: Math.max(0, nextY) });\n };\n\n const onMouseUp = () => {\n setIsDragging(false);\n };\n\n window.addEventListener(\"mousemove\", onMouseMove);\n window.addEventListener(\"mouseup\", onMouseUp);\n\n return () => {\n window.removeEventListener(\"mousemove\", onMouseMove);\n window.removeEventListener(\"mouseup\", onMouseUp);\n };\n }, [isDragging]);\n\n if (!stableData || !stableData.details || isClosed || !sdkVisible) return null;\n\n const details = stableData.details;\n const styling = details.styling || {};\n const appearance = styling.appearance || {};\n\n const configuredWidth = parseNumber(details.width ?? appearance.pipWidth, 150);\n const configuredHeight = parseNumber(details.height ?? appearance.pipHeight, 300);\n\n // Respect the configured axes directly so width and height map 1:1 with the\n // dashboard values (previously max/min forced a landscape shape, which made\n // changing height appear to change width and vice versa).\n const miniWidth = configuredWidth;\n const miniHeight = configuredHeight;\n\n const ctaContainer = styling.cta?.container || {};\n const ctaText = styling.cta?.text || {};\n const hasCta = Boolean(details.button_text && details.button_text.trim().length > 0);\n\n const ctaHeight = parseNumber(styling.cta?.container?.height, 42);\n const expandedExtraHeight = hasCta ? ctaHeight + 24 : 0;\n\n const bottomPadding = parseNumber(styling.pipBottomPadding, 20);\n const topPadding = parseNumber(styling.pipTopPadding, 0);\n\n const videoSource = isExpanded ? details.large_video || details.small_video : details.small_video || details.large_video;\n\n const position = (details.position || stableData.position || \"right\").toLowerCase();\n const isMovable = Boolean(styling.isMovable);\n const soundEnabled = styling.soundToggle?.enabled !== false;\n const closeEnabled = styling.crossButton?.enabled !== false;\n // Prefer dashboard \"Expandable PiP\" (expandablePip); fall back to expandControls.enabled.\n const expandablePipRaw =\n (styling as any).expandablePip ??\n (details as any).expandablePip ??\n (details as any).expandable_pip;\n const expandEnabled =\n expandablePipRaw != null && expandablePipRaw !== \"\"\n ? isExpandableEnabled(expandablePipRaw)\n : styling.expandControls?.enabled !== false;\n\n const closeConfig = styling.crossButton;\n const expandConfig = isExpanded ? styling.expandControls?.minimise : styling.expandControls?.maximise;\n const soundConfig = isMuted ? styling.soundToggle?.mute : styling.soundToggle?.unmute;\n\n const toggleExpand = () => {\n setIsExpanded((prev) => {\n const next = !prev;\n // Match native: when expanding, emit `viewed` then `analyze` with only campaign id\n if (next && stableData?.id) {\n void trackEvent(\"viewed\", stableData.id);\n void trackEvent(\"analyze\", stableData.id);\n }\n return next;\n });\n };\n\n const wrapperStyle: React.CSSProperties = {\n position: \"fixed\",\n zIndex: 10020,\n // When expanded, size the fullscreen view from the inset:0 values set below\n // (auto width/height) instead of 100vw/100dvw. Viewport units include the\n // page scrollbar width, which pushed the right-aligned controls (close\n // button) off-screen; insets match the visible viewport exactly.\n width: isExpanded ? \"auto\" : miniWidth,\n height: isExpanded ? \"auto\" : miniHeight,\n borderRadius: 0,\n overflow: \"hidden\",\n background: \"#000\",\n boxShadow: \"0 16px 40px rgba(0,0,0,0.35)\",\n cursor: isDragging ? \"grabbing\" : isMovable && !isExpanded ? \"grab\" : \"default\",\n transition: isDragging ? \"none\" : \"width 180ms ease, height 180ms ease, transform 180ms ease\",\n };\n\n if (dragPosition && !isExpanded) {\n wrapperStyle.left = dragPosition.x;\n wrapperStyle.top = dragPosition.y;\n } else if (isExpanded) {\n wrapperStyle.left = 0;\n wrapperStyle.top = 0;\n wrapperStyle.right = 0;\n wrapperStyle.bottom = 0;\n } else {\n if (position === \"left\") {\n wrapperStyle.left = 24;\n } else {\n wrapperStyle.right = 24;\n }\n\n if (topPadding > 0) {\n wrapperStyle.top = topPadding;\n } else {\n wrapperStyle.bottom = bottomPadding + 20;\n }\n }\n\n const onWrapperMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n if (!isMovable || isExpanded) return;\n\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-control-button='true']\")) return;\n\n const rect = event.currentTarget.getBoundingClientRect();\n dragOffsetRef.current = {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n };\n\n dragStartRef.current = { x: event.clientX, y: event.clientY };\n didDragRef.current = false;\n\n setDragPosition({ x: rect.left, y: rect.top });\n setIsDragging(true);\n };\n\n const handleOpenLink = () => {\n if (!details.link) return;\n // Match native: only send event + campaign id\n void trackEvent(\"clicked\", stableData.id);\n const link = String(details.link).trim();\n\n try {\n const s = useAppStorysStore.getState();\n const all = s.allCampaigns || [];\n const existing = s.campaigns || [];\n const referenced = all.find((c: any) => c.id === link);\n console.log('[Pip] clicked link=', link, 'allCount=', all.length, 'visibleCount=', existing.length, 'referenced=', !!referenced);\n if (referenced) {\n const revealed: any = { ...referenced };\n delete revealed.trigger_event;\n delete revealed.trigger;\n revealed.display_trigger = true;\n\n const idx = existing.findIndex((c: any) => c.id === revealed.id);\n if (idx === -1) {\n s.saveCampaigns([revealed, ...existing]);\n } else {\n const existingItem = existing[idx];\n const existingHasTrigger = Boolean((existingItem as any).trigger_event ?? (existingItem as any).trigger);\n if (existingHasTrigger) {\n const next = [...existing];\n next[idx] = revealed;\n s.saveCampaigns(next);\n }\n }\n return;\n }\n } catch (err) {\n // fallback to open as URL\n }\n\n window.open(details.link, \"_blank\");\n };\n\n if (!videoSource) return null;\n\n return (\n <div style={wrapperStyle} onMouseDown={onWrapperMouseDown}>\n <video\n ref={videoRef}\n src={videoSource}\n autoPlay\n loop\n playsInline\n muted={isMuted}\n style={{\n width: \"100%\",\n height: isExpanded && hasCta ? `calc(100% - ${expandedExtraHeight}px)` : \"100%\",\n objectFit: isExpanded ? \"contain\" : \"cover\",\n cursor: expandEnabled && !isExpanded ? \"pointer\" : details.link ? \"pointer\" : \"default\",\n }}\n onClick={() => {\n // Ignore the click synthesized at the end of a drag so moving the PIP\n // doesn't expand it — only a genuine click should expand.\n if (didDragRef.current) {\n didDragRef.current = false;\n return;\n }\n // When expandable: click mini video to expand; click expanded video to minimize\n // (CTA button still handles redirect when present). Otherwise keep link behavior.\n if (expandEnabled) {\n toggleExpand();\n return;\n }\n handleOpenLink();\n }}\n onEnded={() => {\n if (data) void trackEvent(\"analyze\", data.id);\n }}\n />\n\n <div\n style={{\n position: \"absolute\",\n top: 8,\n right: 8,\n display: \"flex\",\n gap: 8,\n zIndex: 2,\n }}\n >\n {soundEnabled && (\n <IconButton\n iconType={isMuted ? \"mute\" : \"unmute\"}\n config={soundConfig}\n imageOverride={isMuted ? details.muteImage : details.unmuteImage}\n onClick={() => setIsMuted((prev) => !prev)}\n />\n )}\n\n {expandEnabled && (\n <IconButton\n iconType={isExpanded ? \"minimize\" : \"expand\"}\n config={expandConfig}\n imageOverride={isExpanded ? details.minimiseImage : details.maximiseImage}\n onClick={toggleExpand}\n />\n )}\n\n {closeEnabled && (\n <IconButton\n iconType=\"close\"\n config={closeConfig}\n imageOverride={details.crossButtonImage}\n onClick={() => setIsClosed(true)}\n />\n )}\n </div>\n\n {isExpanded && hasCta && (\n <button\n data-control-button=\"true\"\n onClick={handleOpenLink}\n style={{\n position: \"absolute\",\n left: 12,\n right: 12,\n bottom: 12,\n height: ctaContainer.height || 42,\n width: ctaContainer.ctaFullWidth ? \"auto\" : ctaContainer.ctaWidth || \"auto\",\n maxWidth: \"calc(100% - 24px)\",\n margin: ctaContainer.ctaFullWidth ? \"0\" : \"0 auto\",\n background: ctaContainer.backgroundColor || \"#F7921C\",\n color: ctaText.color || \"#fff\",\n border: `${ctaContainer.borderWidth || 0}px solid ${ctaContainer.borderColor || \"transparent\"}`,\n borderRadius: 10,\n fontSize: ctaText.fontSize || 14,\n fontFamily: resolveFontFamily(ctaText.fontFamily),\n fontWeight: 600,\n cursor: details.link ? \"pointer\" : \"default\",\n }}\n >\n {details.button_text}\n </button>\n )}\n </div>\n );\n};\n\nexport { Pip };\nexport default Pip;\n","type LoadStatus = 'pending' | 'loaded' | 'failed';\n\ninterface FontEntry {\n status: LoadStatus;\n name: string;\n listeners: Array<(name: string | undefined) => void>;\n}\n\nfunction isRemoteFontUrl(value: string): boolean {\n const v = value.trim();\n return v.startsWith('http://') || v.startsWith('https://');\n}\n\nfunction fontNameFromUrl(url: string): string {\n try {\n const pathname = new URL(url).pathname;\n const filename = pathname.split('/').pop() || url;\n return filename.split('?')[0].replace(/\\.[^.]+$/, '') || `font_${filename.length}`;\n } catch {\n const filename = url.split('/').pop() ?? url;\n return filename.split('?')[0].replace(/\\.[^.]+$/, '') || `font_${url.length}`;\n }\n}\n\nfunction ensureStyleTag(fontName: string, url: string): void {\n if (typeof document === 'undefined') return;\n const id = `appstorys-font-${fontName}`;\n if (document.getElementById(id)) return;\n\n const style = document.createElement('style');\n style.id = id;\n style.type = 'text/css';\n style.textContent = `@font-face{font-family:\"${fontName}\";src:url(\"${url}\");font-style:normal;font-weight:normal;font-display:swap;}`;\n document.head.appendChild(style);\n}\n\nconst cache = new Map<string, FontEntry>();\n\nasync function doLoad(url: string, entry: FontEntry): Promise<void> {\n try {\n // Always inject @font-face so CSS can reference the family.\n ensureStyleTag(entry.name, url);\n\n // If FontFace API exists, await load so consumers can gate rendering.\n const FontFaceCtor = (globalThis as any).FontFace as\n | (new (family: string, source: string) => FontFace)\n | undefined;\n\n if (typeof document !== 'undefined' && FontFaceCtor && (document as any).fonts?.add) {\n const face = new FontFaceCtor(entry.name, `url(${url})`);\n await face.load();\n (document as any).fonts.add(face);\n } else if (typeof document !== 'undefined' && (document as any).fonts?.load) {\n await (document as any).fonts.load(`1em \"${entry.name}\"`);\n }\n\n entry.status = 'loaded';\n entry.listeners.forEach((cb) => cb(entry.name));\n } catch (err) {\n console.warn(`[FontManager] Failed to load font from \"${url}\":`, err);\n entry.status = 'failed';\n entry.listeners.forEach((cb) => cb(undefined));\n } finally {\n entry.listeners = [];\n }\n}\n\nexport const FontManager = {\n async load(url: string | undefined | null): Promise<string | undefined> {\n if (!url) return undefined;\n if (!isRemoteFontUrl(url)) return undefined;\n\n const existing = cache.get(url);\n if (existing) {\n if (existing.status === 'loaded') return existing.name;\n if (existing.status === 'failed') return undefined;\n return new Promise<string | undefined>((resolve) => existing.listeners.push(resolve));\n }\n\n const name = fontNameFromUrl(url);\n const entry: FontEntry = { status: 'pending', name, listeners: [] };\n cache.set(url, entry);\n\n const first = new Promise<string | undefined>((resolve) => entry.listeners.push(resolve));\n void doLoad(url, entry);\n return first;\n },\n\n ensure(url: string | undefined | null): string | undefined {\n if (!url) return undefined;\n if (!isRemoteFontUrl(url)) return undefined;\n\n const name = fontNameFromUrl(url);\n ensureStyleTag(name, url);\n void FontManager.load(url);\n return name;\n },\n\n getSync(url: string | undefined | null): string | undefined {\n if (!url) return undefined;\n const entry = cache.get(url);\n return entry?.status === 'loaded' ? entry.name : undefined;\n },\n\n _clearCache(): void {\n cache.clear();\n },\n};\n\nexport function resolveFontFamily(fontFamily?: string | null): string | undefined {\n if (!fontFamily) return undefined;\n if (isRemoteFontUrl(fontFamily)) return FontManager.ensure(fontFamily);\n return fontFamily;\n}\n\nexport function collectFontUrls(input: unknown): string[] {\n const urls = new Set<string>();\n const visited = new WeakSet<object>();\n\n const walk = (value: unknown) => {\n if (value == null) return;\n if (typeof value === 'string') return;\n\n if (Array.isArray(value)) {\n for (const item of value) walk(item);\n return;\n }\n\n if (typeof value === 'object') {\n if (visited.has(value as object)) return;\n visited.add(value as object);\n\n for (const [key, v] of Object.entries(value as Record<string, unknown>)) {\n if (key === 'fontFamily' && typeof v === 'string' && isRemoteFontUrl(v)) {\n urls.add(v);\n }\n walk(v);\n }\n }\n };\n\n walk(input);\n return Array.from(urls);\n}\n\nexport async function preloadFontsFromCampaigns(campaigns: unknown[]): Promise<void> {\n const urls = new Set<string>();\n for (const c of campaigns) collectFontUrls(c).forEach((u) => urls.add(u));\n await Promise.all(Array.from(urls).map((url) => FontManager.load(url)));\n}\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { LottiePlayer } from \"lottie-react\";\nimport useCampaigns from \"../../hooks/useCampaigns\";\nimport { hasVariants, resolveCampaignVariant } from \"../../core/variantResolver\";\nimport trackEvent from \"../../core/trackEvent\";\nimport useAppStorysStore from \"../../core/store\";\nimport { Campaign } from \"../../types\";\n\ninterface FloaterStyling {\n bottomLeftRadius?: number | string;\n bottomRightRadius?: number | string;\n topLeftRadius?: number | string;\n topRightRadius?: number | string;\n marginBottom?: number | string;\n marginLeft?: number | string;\n marginRight?: number | string;\n marginTop?: number | string;\n}\n\ninterface FloaterDetails {\n id?: string;\n image?: string;\n lottie_data?: string | Record<string, unknown>;\n link?: string;\n position?: string;\n width?: number | string;\n height?: number | string;\n styling?: FloaterStyling;\n}\n\ntype FloaterCampaign = Campaign & {\n campaign_type: \"FLT\";\n details: FloaterDetails;\n display_trigger?: boolean;\n};\n\nconst toNumber = (value: unknown, fallback = 0): number => {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst normalizeScreen = (value?: string | null): string => (value || \"\").trim().toLowerCase();\n\nconst MEDIA_BUCKET_HOST = \"appstorysmediabucketdev.s3.ap-south-1.amazonaws.com\";\n\nconst resolveLottieCandidateUrls = (url: string): string[] => {\n try {\n if (typeof window === \"undefined\") return [url];\n\n const parsed = new URL(url);\n if (parsed.hostname !== MEDIA_BUCKET_HOST) return [url];\n\n const isDevServer = Boolean(window.location.port);\n const proxyUrl = `/appstorys-media${parsed.pathname}${parsed.search}`;\n\n if (isDevServer) {\n // Prefer proxy in dev (works for localhost and LAN IP access), keep source URL as fallback.\n return [proxyUrl, url];\n }\n\n return [url];\n } catch {\n return [url];\n }\n};\n\nconst isLikelyLottieJson = (value: unknown): value is Record<string, unknown> => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const candidate = value as Record<string, unknown>;\n return Array.isArray(candidate.layers) || Array.isArray(candidate.assets) || typeof candidate.v === \"string\";\n};\n\nclass FloaterLottieErrorBoundary extends React.Component<\n { onError: () => void; children: React.ReactNode },\n { hasError: boolean }\n> {\n constructor(props: { onError: () => void; children: React.ReactNode }) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError() {\n return { hasError: true };\n }\n\n componentDidCatch() {\n this.props.onError();\n }\n\n render() {\n if (this.state.hasError) return null;\n return this.props.children;\n }\n}\n\nconst Floater: React.FC = () => {\n const [lottieData, setLottieData] = useState<any>(null);\n const [lottieUrls, setLottieUrls] = useState<string[]>([]);\n const [lottieFailed, setLottieFailed] = useState(false);\n const [lottieLoading, setLottieLoading] = useState(false);\n const lottieContainerRef = useRef<HTMLDivElement | null>(null);\n const lottieAnimationRef = useRef<any>(null);\n const hookData = useCampaigns<FloaterCampaign>(\"FLT\");\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n const sdkVisible = useAppStorysStore((state) => state.isVisible);\n const viewedKeyRef = useRef<string | null>(null);\n\n const data = hookData ??\n ((): FloaterCampaign | undefined => {\n const found = [...campaigns, ...allCampaigns].find((campaign) => {\n const item = campaign as FloaterCampaign;\n if (item.campaign_type !== \"FLT\") return false;\n // Hide campaigns that are explicitly display_trigger=false or that carry a trigger\n const hasTrigger = Boolean((item as any).trigger_event ?? (item as any).trigger);\n if (item.display_trigger === false || hasTrigger) return false;\n return !normalizeScreen(item.screen) || normalizeScreen(item.screen) === normalizeScreen(currentScreen);\n }) as FloaterCampaign | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as FloaterCampaign;\n } catch {\n return found;\n }\n })();\n\n const campaignId = data?.id;\n const mappedVariantId = useAppStorysStore((state) => (campaignId ? state.variantMappings[campaignId] : undefined));\n\n useEffect(() => {\n if (!data?.id) return;\n if (!sdkVisible) return;\n\n // If this campaign supports variants, wait until a variant mapping exists\n // so `trackEvent` can attach `variant_id` consistently.\n const needsVariant = hasVariants(data);\n if (needsVariant && !mappedVariantId) return;\n\n const viewKey = `${data.id}:${mappedVariantId || \"\"}`;\n if (viewedKeyRef.current === viewKey) return;\n viewedKeyRef.current = viewKey;\n\n void trackEvent(\"viewed\", data.id);\n }, [data?.id, mappedVariantId, sdkVisible]);\n\n useEffect(() => {\n const lottieSource = data?.details?.lottie_data;\n\n setLottieData(null);\n setLottieUrls([]);\n setLottieFailed(false);\n setLottieLoading(false);\n\n if (!lottieSource) return;\n\n if (isLikelyLottieJson(lottieSource)) {\n setLottieData(lottieSource);\n setLottieLoading(true);\n return;\n }\n\n if (typeof lottieSource !== \"string\") {\n setLottieFailed(true);\n return;\n }\n\n const candidateUrls = resolveLottieCandidateUrls(lottieSource);\n setLottieUrls(candidateUrls);\n setLottieLoading(true);\n }, [data?.details?.lottie_data]);\n\n useEffect(() => {\n if (!data?.details?.lottie_data || !lottieContainerRef.current) return;\n\n const lottie = LottiePlayer as any;\n if (!lottie || typeof lottie.loadAnimation !== \"function\") {\n setLottieFailed(true);\n setLottieLoading(false);\n return;\n }\n\n let cancelled = false;\n let activeAnimation: any = null;\n\n const cleanupCurrent = () => {\n if (activeAnimation && typeof activeAnimation.destroy === \"function\") {\n activeAnimation.destroy();\n }\n activeAnimation = null;\n lottieAnimationRef.current = null;\n };\n\n const tryLoadByPath = (paths: string[], index: number) => {\n if (cancelled) return;\n if (index >= paths.length) {\n setLottieFailed(true);\n setLottieLoading(false);\n console.error(\"[Floater] lottie load failed\", { lottieUrls: paths });\n return;\n }\n\n cleanupCurrent();\n\n const animation = lottie.loadAnimation({\n container: lottieContainerRef.current,\n renderer: \"svg\",\n loop: true,\n autoplay: true,\n path: paths[index],\n });\n\n activeAnimation = animation;\n lottieAnimationRef.current = animation;\n\n animation.addEventListener(\"DOMLoaded\", () => {\n if (cancelled) return;\n setLottieLoading(false);\n });\n\n animation.addEventListener(\"data_failed\", () => {\n if (cancelled) return;\n tryLoadByPath(paths, index + 1);\n });\n };\n\n if (lottieData) {\n cleanupCurrent();\n const animation = lottie.loadAnimation({\n container: lottieContainerRef.current,\n renderer: \"svg\",\n loop: true,\n autoplay: true,\n animationData: lottieData,\n });\n activeAnimation = animation;\n lottieAnimationRef.current = animation;\n animation.addEventListener(\"DOMLoaded\", () => {\n if (!cancelled) {\n setLottieLoading(false);\n }\n });\n animation.addEventListener(\"data_failed\", () => {\n if (!cancelled) {\n setLottieFailed(true);\n setLottieLoading(false);\n }\n });\n } else if (lottieUrls.length > 0) {\n tryLoadByPath(lottieUrls, 0);\n }\n\n return () => {\n cancelled = true;\n cleanupCurrent();\n };\n }, [data?.details?.lottie_data, lottieData, lottieUrls]);\n\n if (!data || !data.details || !sdkVisible) return null;\n const { details } = data;\n const styling = details.styling || {};\n\n const resolvedPosition =\n typeof details.position === \"string\"\n ? details.position\n : typeof data.position === \"string\"\n ? data.position\n : \"right\";\n const position = resolvedPosition.toLowerCase() === \"left\" ? \"left\" : \"right\";\n\n const positionStyle: React.CSSProperties = {\n position: \"fixed\",\n left: position === \"left\" ? toNumber(styling.marginLeft, 12) : undefined,\n right: position === \"left\" ? undefined : toNumber(styling.marginRight, 12),\n top: toNumber(styling.marginTop, 0) > 0 ? toNumber(styling.marginTop, 0) : undefined,\n bottom: toNumber(styling.marginTop, 0) > 0 ? undefined : toNumber(styling.marginBottom, 80),\n zIndex: 10040,\n display: \"flex\",\n };\n\n const floaterStyle: React.CSSProperties = {\n width: toNumber(details.width, 60),\n height: toNumber(details.height, 60),\n background: \"transparent\",\n overflow: \"hidden\",\n borderBottomLeftRadius: toNumber(styling.bottomLeftRadius, 0),\n borderBottomRightRadius: toNumber(styling.bottomRightRadius, 0),\n borderTopLeftRadius: toNumber(styling.topLeftRadius, 0),\n borderTopRightRadius: toNumber(styling.topRightRadius, 0),\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: details.link ? \"pointer\" : \"default\",\n boxShadow: \"0 8px 18px rgba(0,0,0,0.2)\",\n };\n\n const handleClick = async () => {\n if (!details.link) return;\n\n await trackEvent(\"clicked\", data.id);\n const link = String(details.link).trim();\n\n try {\n const s = useAppStorysStore.getState();\n const all = s.allCampaigns || [];\n const existing = s.campaigns || [];\n\n // Robust matching: try several candidate matchers\n const referenced = all.find((c: any) => {\n if (!c) return false;\n const cid = String(c.id || \"\").trim();\n const details = c.details || {};\n const detailsCampaign = String(details.campaign || details.id || \"\").trim();\n if (cid && cid === link) return true;\n if (detailsCampaign && detailsCampaign === link) return true;\n // allow if the link contains the id or vice-versa\n if (cid && link.includes(cid)) return true;\n if (detailsCampaign && link.includes(detailsCampaign)) return true;\n return false;\n });\n\n console.log(\"[Floater] clicked link=\", link, \"allCampaignsCount=\", all.length, \"visibleCount=\", existing.length);\n console.log(\"[Floater] all ids=\", all.map((c: any) => c.id).slice(0,50));\n console.log(\"[Floater] referenced found=\", !!referenced, referenced && (referenced.id || referenced.details?.campaign || referenced.details?.id));\n\n if (referenced) {\n const revealed: any = { ...referenced };\n // Neglect trigger for this reveal flow\n delete revealed.trigger_event;\n delete revealed.trigger;\n revealed.display_trigger = true;\n const idx = existing.findIndex((c: any) => c.id === revealed.id);\n if (idx === -1) {\n console.log('[Floater] revealing campaign (prepended)', revealed.id);\n s.saveCampaigns([revealed, ...existing]);\n } else {\n const existingItem = existing[idx];\n const existingHasTrigger = Boolean((existingItem as any).trigger_event ?? (existingItem as any).trigger);\n if (existingHasTrigger) {\n // Replace the existing triggered entry with revealed copy (neglect trigger)\n const next = [...existing];\n next[idx] = revealed;\n console.log('[Floater] replacing existing triggered campaign with revealed one', revealed.id);\n s.saveCampaigns(next);\n } else {\n console.log('[Floater] campaign already visible and not trigger-driven', revealed.id);\n }\n }\n return;\n }\n } catch (err) {\n // fallback to open as URL\n console.warn('[Floater] error while resolving referenced campaign', err);\n }\n\n try {\n window.open(details.link, \"_blank\");\n } catch (err) {\n // ignore\n }\n };\n\n const canRenderLottie = Boolean(details.lottie_data && !lottieFailed);\n const canRenderImage = Boolean(details.image);\n const canRenderLoadingPlaceholder = Boolean(details.lottie_data && lottieLoading && !lottieData && !lottieFailed);\n\n if (!canRenderLottie && !canRenderImage && !canRenderLoadingPlaceholder) return null;\n\n return (\n <div style={positionStyle}>\n <div style={floaterStyle} onClick={() => void handleClick()}>\n {canRenderLottie ? (\n <FloaterLottieErrorBoundary key={String(details.lottie_data)} onError={() => setLottieFailed(true)}>\n <div ref={lottieContainerRef} style={{ width: \"100%\", height: \"100%\", display: \"block\" }} />\n </FloaterLottieErrorBoundary>\n ) : canRenderLoadingPlaceholder ? (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"rgba(0,0,0,0.08)\",\n color: \"#333\",\n fontSize: 10,\n fontWeight: 600,\n }}\n >\n ...\n </div>\n ) : (\n <img\n src={details.image}\n alt=\"floater\"\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default Floater;\n","import useAppStorysStore, { getAccessToken, getUserId } from \"./store\";\nimport { Campaign } from \"../types\";\n\nfunction normalizeScreenName(screen?: string | null): string {\n return (screen || \"\").trim().toLowerCase();\n}\n\nfunction isScreenMatch(campaign: Campaign, screenName: string): boolean {\n const campaignScreen = normalizeScreenName(campaign.screen);\n const currentScreen = normalizeScreenName(screenName);\n return !campaignScreen || campaignScreen === currentScreen;\n}\n\nexport default async function trackScreen(screenName: string) {\n try {\n const state = useAppStorysStore.getState();\n const accessToken = await getAccessToken();\n const accountId = state.accountId;\n\n if (!accessToken || !accountId) return;\n\n state.setCurrentScreen(screenName);\n state.setTrackedEvents([]); // Reset tracked events for new screen\n\n const baseUrl = state.baseUrl || 'https://users.appstorys.co';\n\n const response = await fetch(`${baseUrl}/v2/${accountId}/track-user-res`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`\n },\n body: JSON.stringify({\n user_id: getUserId(),\n screenName\n }),\n });\n\n if (!response.ok) return;\n\n const data = await response.json();\n\n // Update screen-capture flag from response\n if (typeof data.screen_capture_enabled !== 'undefined') {\n state.setScreenCaptureEnabled(Boolean(data.screen_capture_enabled));\n }\n\n // Handle variants\n if (data.variants && data.variants.length > 0) {\n const variantMappings: Record<string, string> = {};\n data.variants.forEach((variant: any) => {\n variantMappings[variant.id] = variant.v_id;\n });\n state.setVariantMappings(variantMappings);\n }\n\n // Handle personalization\n if (data.personalization_data) {\n state.setPersonalizationData(data.personalization_data);\n }\n\n // Filter campaigns\n const allCampaigns = state.allCampaigns || [];\n const eligibleCampaignIds = data.eligibleCampaignList || [];\n\n const foundCampaigns = allCampaigns.filter(campaign =>\n eligibleCampaignIds.includes(campaign.id!) &&\n isScreenMatch(campaign, screenName)\n );\n\n // Fetch missing campaigns if necessary\n const foundCampaignIds = foundCampaigns.map(c => c.id!);\n const missingCampaignIds = eligibleCampaignIds.filter((id: string) => !foundCampaignIds.includes(id));\n\n let missingCampaigns: Campaign[] = [];\n if (missingCampaignIds.length > 0) {\n const fallbackResponse = await fetch(`${baseUrl}/load-campaign-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`\n },\n body: JSON.stringify(missingCampaignIds),\n });\n\n if (fallbackResponse.ok) {\n const fallbackData = await fallbackResponse.json();\n missingCampaigns = fallbackData.filter((campaign: Campaign) =>\n isScreenMatch(campaign, screenName)\n );\n }\n }\n\n const eligibleCampaigns = [...foundCampaigns, ...missingCampaigns];\n\n // Keep display-trigger campaigns available even when eligibility API is partial.\n const displayTriggeredCampaigns = allCampaigns.filter((campaign: Campaign & { display_trigger?: boolean }) => {\n const hasTrigger = Boolean((campaign as any).trigger_event ?? (campaign as any).trigger);\n return isScreenMatch(campaign, screenName) && campaign.display_trigger === true && !hasTrigger;\n });\n\n const mergedCampaigns = [...eligibleCampaigns];\n const seenCampaignIds = new Set(mergedCampaigns.map((campaign) => campaign.id));\n\n for (const campaign of displayTriggeredCampaigns) {\n if (!seenCampaignIds.has(campaign.id)) {\n mergedCampaigns.push(campaign);\n seenCampaignIds.add(campaign.id);\n }\n }\n\n state.saveCampaigns(mergedCampaigns);\n } catch (error) {\n console.error('Error when tracking screen:', screenName, error);\n }\n}\n","import useAppStorysStore, { getAccessToken, getUserId } from \"./store\";\nimport { Attributes } from \"../types\";\nimport getDeviceInfo from \"./getDeviceInfo\";\nimport { sendOrQueue } from \"./offlineQueue\";\n\n/**\n * Sets custom attributes for the user.\n * These properties can be used for campaign targeting and segmentation.\n * \n * @param attributes - A key-value object of user properties.\n */\nexport default async function setUserProperties(attributes: Attributes) {\n try {\n const accessToken = await getAccessToken();\n const userId = getUserId();\n const state = useAppStorysStore.getState();\n\n if (!accessToken || !userId) {\n console.warn(\"AppStorys: Missing accessToken or userId. Ensure SDK is initialized before setting user properties.\");\n return;\n }\n\n let finalMetadata: Record<string, any> = {\n ...(attributes || {}),\n };\n\n const deviceInfo = await getDeviceInfo();\n finalMetadata = {\n ...finalMetadata,\n ...deviceInfo,\n };\n\n const bodyData: any = {\n user_id: userId,\n attributes: finalMetadata\n };\n\n const baseUrl = state.baseUrl || 'https://users.appstorys.co';\n\n await sendOrQueue({\n url: `${baseUrl}/update-user-atr`,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: bodyData,\n });\n\n } catch (error) {\n console.error(\"AppStorys: Error in setUserProperties:\", error);\n }\n}\n","import useAppStorysStore from '../core/store';\n\nexport function personalizeText(text: string): string {\n if (!text || text.trim() === '') {\n return text;\n }\n\n const personalizationData = useAppStorysStore.getState().personalizationData;\n\n if (!personalizationData || Object.keys(personalizationData).length === 0) {\n return replacePlaceholdersWithFallback(text);\n }\n\n const regex = /\\{\\{([^|}\\s]+)\\s*\\|\\s*([^}]+)\\}\\}/g;\n\n return text.replace(regex, (_, variableName, fallbackValue) => {\n const trimmedVariable = variableName.trim();\n const trimmedFallback = fallbackValue.trim();\n\n return personalizationData[trimmedVariable] ?? trimmedFallback;\n });\n}\n\nfunction replacePlaceholdersWithFallback(text: string): string {\n const regex = /\\{\\{[^|}\\s]+\\s*\\|\\s*([^}]+)\\}\\}/g;\n\n return text.replace(regex, (_, fallbackValue) => {\n return fallbackValue.trim();\n });\n}\n","import { WebStorage } from '../adapters/web/storage';\nimport { Campaign } from '../types';\nimport { getAccessToken, getUserId } from './store';\nimport useAppStorysStore from './store';\n\nconst STORAGE_KEY_CAMPAIGNS = \"appstorys_campaigns_cache\";\nconst STORAGE_KEY_ETAG = \"appstorys_campaigns_etag\";\nconst STORAGE_KEY_VERSION = \"appstorys_campaigns_version\";\n\nexport interface FetchCampaignsResult {\n campaigns: Campaign[];\n version: number;\n}\n\nexport default async function fetchAllCampaigns(accountId: string, screenName?: string): Promise<FetchCampaignsResult> {\n try {\n const isLocalDev =\n typeof window !== \"undefined\" &&\n (window.location.hostname === \"localhost\" || window.location.hostname === \"127.0.0.1\");\n\n const url = isLocalDev\n ? `/appstorys-campaigns/clients/${accountId}/campaigns.json`\n : `https://dev-cdn-campaign-appstorys.s3.ap-south-1.amazonaws.com/clients/${accountId}/campaigns.json`;\n\n const cachedData = await WebStorage.getItem(STORAGE_KEY_CAMPAIGNS);\n const cachedEtag = await WebStorage.getItem(STORAGE_KEY_ETAG);\n const cachedVersion = await WebStorage.getItem(STORAGE_KEY_VERSION);\n\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n };\n\n // Keep ETag revalidation for non-local environments only.\n if (!isLocalDev && cachedEtag) {\n headers[\"If-None-Match\"] = cachedEtag;\n }\n\n const response = await fetch(url, {\n method: \"GET\",\n headers,\n ...(isLocalDev ? { cache: \"no-store\" as RequestCache } : {}),\n });\n\n if (response.status === 304) {\n return {\n campaigns: cachedData ? JSON.parse(cachedData) : [],\n version: cachedVersion ? parseInt(cachedVersion) : 1,\n };\n }\n\n const newEtag = response.headers.get(\"ETag\");\n const responseData: any[] = await response.json();\n\n let version = 2;\n let campaigns: Campaign[] = responseData;\n\n // Determine an effective screen name. If caller didn't provide one, try\n // to fetch it from the users service `v2/{accountId}/track-user-res`.\n let effectiveScreenName = screenName;\n if (!effectiveScreenName) {\n try {\n const accessToken = await getAccessToken();\n const userId = getUserId();\n const usersBase = isLocalDev ? '/appstorys-users' : 'https://users.appstorys.co';\n\n const trackResp = await fetch(`${usersBase}/v2/${accountId}/track-user-res`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}),\n },\n body: JSON.stringify({\n user_id: userId,\n screenName: (typeof window !== 'undefined' && window.location && window.location.pathname) ? window.location.pathname : '',\n silentUpdate: true,\n }),\n });\n\n if (trackResp.ok) {\n const trackData = await trackResp.json();\n console.info('AppStorys: fetchAllCampaigns track-user-res returned', trackData);\n const possibleScreen = trackData?.screenName || trackData?.screen || trackData?.currentScreen || trackData?.screen_name || trackData?.current_screen;\n if (possibleScreen) {\n effectiveScreenName = possibleScreen;\n }\n try {\n const s = useAppStorysStore.getState();\n if (typeof trackData.screen_capture_enabled !== 'undefined') {\n s.setScreenCaptureEnabled(Boolean(trackData.screen_capture_enabled));\n }\n } catch (err) {\n // ignore\n }\n }\n } catch (err) {\n console.warn('Could not fetch screen name from track-user-res:', err);\n }\n }\n\n if (responseData.length > 0 && responseData[0].version !== undefined) {\n version = responseData[0].version;\n campaigns = responseData.slice(1);\n }\n\n // If no campaigns found in the primary source, try fallback using track-user and load-campaign-data\n if ((!campaigns || campaigns.length === 0)) {\n try {\n const accessToken = await getAccessToken();\n const userId = getUserId();\n const usersBase = isLocalDev ? '/appstorys-users' : 'https://users.appstorys.co';\n\n const trackResp = await fetch(`${usersBase}/v2/${accountId}/track-user-res`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}),\n },\n body: JSON.stringify({\n user_id: userId,\n screenName: (typeof window !== 'undefined' && window.location && window.location.pathname) ? window.location.pathname : '',\n silentUpdate: true,\n }),\n });\n\n if (trackResp.ok) {\n const trackData = await trackResp.json();\n const userIdFromResp = trackData?.user_id || trackData?.id || trackData?.userId || userId;\n\n try {\n const s = useAppStorysStore.getState();\n if (typeof trackData.screen_capture_enabled !== 'undefined') {\n s.setScreenCaptureEnabled(Boolean(trackData.screen_capture_enabled));\n }\n } catch (err) {\n // ignore\n }\n\n if (userIdFromResp) {\n const loadUrl = isLocalDev\n ? `/appstorys-users/load-campaign-data`\n : `https://users.appstorys.com/load-campaign-data`;\n\n const fallbackResponse = await fetch(loadUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}),\n },\n body: JSON.stringify({ user_id: userIdFromResp }),\n });\n\n if (fallbackResponse.ok) {\n const fallbackData: any[] = await fallbackResponse.json();\n console.log(`Fetched ${fallbackData.length} missing campaigns from fallback`);\n console.log('Fallback campaigns:', JSON.stringify(fallbackData, null, 2));\n\n // Use fallback campaigns if available\n if (fallbackData && fallbackData.length > 0) {\n campaigns = fallbackData as Campaign[];\n }\n } else {\n console.error('Failed to fetch missing campaigns:', await fallbackResponse.text());\n }\n }\n }\n } catch (error) {\n console.error('Error fetching missing campaigns via fallback:', error);\n }\n }\n\n // Filter campaigns by effective screenName if available\n if (effectiveScreenName && campaigns && campaigns.length > 0) {\n const normalize = (s?: string | null) => (s || '').trim().toLowerCase();\n const current = normalize(effectiveScreenName);\n campaigns = campaigns.filter(campaign => !normalize(campaign.screen) || normalize(campaign.screen) === current);\n }\n\n await WebStorage.setItem(STORAGE_KEY_CAMPAIGNS, JSON.stringify(campaigns));\n await WebStorage.setItem(STORAGE_KEY_VERSION, version.toString());\n\n if (newEtag) {\n await WebStorage.setItem(STORAGE_KEY_ETAG, newEtag);\n }\n\n return { campaigns, version };\n\n } catch (error) {\n console.error(\"Error fetching campaigns:\", error);\n const cachedData = await WebStorage.getItem(STORAGE_KEY_CAMPAIGNS);\n const cachedVersion = await WebStorage.getItem(STORAGE_KEY_VERSION);\n\n return {\n campaigns: cachedData ? JSON.parse(cachedData) : [],\n version: cachedVersion ? parseInt(cachedVersion) : 1,\n };\n }\n}\n","import useAppStorysStore, { getAccessToken } from \"./store\";\n\ninterface ReconcileUserRequest {\n anonymous_user_id: string;\n identified_user_id: string;\n}\n\n/**\n * Reconciles an anonymous user with an identified user.\n * This merges the anonymous user's data with the identified user's data.\n * \n * @param anonymousUserId - The previous anonymous user ID\n * @param identifiedUserId - The new identified user ID\n * @returns Promise<boolean> - true if reconciliation was successful, false otherwise\n */\nexport default async function reconcileAnonymousUser(\n anonymousUserId: string,\n identifiedUserId: string\n): Promise<boolean> {\n try {\n const accessToken = await getAccessToken();\n const state = useAppStorysStore.getState();\n \n if (!accessToken) {\n console.error('AppStorys: Access token not found for reconciliation');\n return false;\n }\n\n const requestBody: ReconcileUserRequest = {\n anonymous_user_id: anonymousUserId,\n identified_user_id: identifiedUserId,\n };\n\n const baseUrl = state.baseUrl || 'https://users.appstorys.co';\n\n const response = await fetch(`${baseUrl}/reconcile-anonymous-user`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n },\n body: JSON.stringify(requestBody),\n });\n\n if (response.ok) {\n return true;\n } else {\n const errorText = await response.text();\n console.error('AppStorys: Failed to reconcile anonymous user:', response.status, errorText);\n return false;\n }\n } catch (error) {\n console.error('AppStorys: Error in reconcileAnonymousUser:', error);\n return false;\n }\n}\n","import useAppStorysStore from \"./store\";\nimport { isBackPressCampaignReady, BACK_PRESS_SENTINEL } from \"../hooks/useCampaigns\";\n\n/**\n * Manages 'Exit Intent' or 'Back Press' behavior for the Web SDK.\n * This translates the mobile back button behavior to web-friendly triggers:\n * 1. Mouse leaving the viewport towards the top (classic exit intent).\n * 2. Intercepting the browser's back button via the PopState API.\n */\nclass ExitIntentManager {\n private isInitialized = false;\n\n public setup() {\n if (this.isInitialized || typeof window === 'undefined') return;\n\n // 1. Mouse Move / Exit Intent\n document.addEventListener('mouseleave', this.handleMouseLeave);\n\n // 2. Browser Back Button (PopState)\n window.addEventListener('popstate', this.handlePopState);\n \n // We should push an initial state so we can intercept the first back press\n if (window.history.state !== 'appstorys_navigation') {\n window.history.pushState('appstorys_navigation', '');\n }\n\n this.isInitialized = true;\n }\n\n public destroy() {\n if (!this.isInitialized || typeof window === 'undefined') return;\n document.removeEventListener('mouseleave', this.handleMouseLeave);\n window.removeEventListener('popstate', this.handlePopState);\n this.isInitialized = false;\n }\n\n private handleMouseLeave = (e: MouseEvent) => {\n // Only trigger if mouse leaves the TOP of the window\n if (e.clientY <= 0 && isBackPressCampaignReady()) {\n this.triggerCampaign();\n }\n };\n\n private handlePopState = () => {\n if (isBackPressCampaignReady()) {\n // Prevent default navigation\n window.history.pushState('appstorys_navigation', '');\n this.triggerCampaign();\n }\n };\n\n private triggerCampaign() {\n const state = useAppStorysStore.getState();\n const { trackedEvents } = state;\n\n if (!trackedEvents.includes(BACK_PRESS_SENTINEL)) {\n console.log('AppStorys: Exit Intent triggered. Displaying campaign.');\n state.setTrackedEvents([...trackedEvents, BACK_PRESS_SENTINEL]);\n }\n }\n}\n\nexport const exitIntentManager = new ExitIntentManager();\n","import useAppStorysStore from \"./store\";\n\n/**\n * Manages the visibility state of the SDK.\n * It listens to the browser's Page Visibility API and updates the global store.\n * This is crucial for pausing/resuming resource-heavy operations like video playback (PiP).\n */\nclass VisibilityManager {\n private isInitialized = false;\n\n public setup() {\n if (this.isInitialized || typeof document === 'undefined') return;\n\n document.addEventListener('visibilitychange', this.handleVisibilityChange);\n \n // Set initial state\n this.updateVisibility(document.visibilityState === 'visible');\n \n this.isInitialized = true;\n }\n\n public destroy() {\n if (!this.isInitialized || typeof document === 'undefined') return;\n document.removeEventListener('visibilitychange', this.handleVisibilityChange);\n this.isInitialized = false;\n }\n\n private handleVisibilityChange = () => {\n this.updateVisibility(document.visibilityState === 'visible');\n };\n\n /**\n * Updates the global SDK visibility state.\n * Can be called by the visibilitychange listener or manually via the public API.\n */\n public updateVisibility(isVisible: boolean) {\n const state = useAppStorysStore.getState();\n if (state.isVisible !== isVisible) {\n console.log(`AppStorys: SDK visibility changed to ${isVisible ? 'visible' : 'hidden'}`);\n state.setVisibility(isVisible);\n }\n }\n}\n\nexport const visibilityManager = new VisibilityManager();\n","import { WebStorage } from '../adapters/web/storage';\n\nconst ANONYMOUS_USER_KEY = 'anonymous_user_id';\n\nexport async function generateAnonymousUserId(): Promise<string> {\n const currentTimeMs = Date.now();\n const browserName = navigator.userAgent.split(' ')[0].replace(/[^a-zA-Z0-9]/g, '_');\n return `${currentTimeMs}_${browserName}`;\n}\n\nexport async function getOrCreateAnonymousUserId(): Promise<string> {\n try {\n const storedUserId = await WebStorage.getItem(ANONYMOUS_USER_KEY);\n \n if (storedUserId) {\n return storedUserId;\n }\n \n const newUserId = await generateAnonymousUserId();\n await WebStorage.setItem(ANONYMOUS_USER_KEY, newUserId);\n return newUserId;\n } catch (error) {\n console.error('Error managing anonymous user ID:', error);\n return await generateAnonymousUserId();\n }\n}\n\nexport async function clearAnonymousUserId(): Promise<void> {\n try {\n await WebStorage.removeItem(ANONYMOUS_USER_KEY);\n } catch (error) {\n console.error('Error clearing anonymous user ID:', error);\n }\n}\n\nexport async function getStoredAnonymousUserId(): Promise<string | null> {\n try {\n return await WebStorage.getItem(ANONYMOUS_USER_KEY);\n } catch (error) {\n console.error('Error getting stored anonymous user ID:', error);\n return null;\n }\n}\n","// Dev helper: visually mark host elements that can receive widgets\ndeclare global {\n interface Window {\n AppStorysShowWidgetElements?: () => void;\n }\n}\n\nfunction injectStyles() {\n if (document.getElementById('appstorys-widget-debug-styles')) return;\n const style = document.createElement('style');\n style.id = 'appstorys-widget-debug-styles';\n style.innerHTML = `\n .appstorys-widget-debug-pill {\n position: absolute;\n top: 8px;\n left: 8px;\n background: #ff7a18;\n color: white;\n padding: 6px 10px;\n border-radius: 14px;\n font-weight: 700;\n font-size: 12px;\n z-index: 2147483647;\n box-shadow: 0 6px 18px rgba(0,0,0,0.12);\n pointer-events: none;\n }\n .appstorys-widget-debug-overlay {\n outline: 3px dashed rgba(255,122,24,0.85);\n outline-offset: 6px;\n }\n `;\n document.head.appendChild(style);\n}\n\nfunction makePill(text: string) {\n const pill = document.createElement('div');\n pill.className = 'appstorys-widget-debug-pill';\n pill.textContent = text;\n return pill;\n}\n\nfunction ensureRelative(el: Element) {\n const node = el as HTMLElement;\n const computed = getComputedStyle(node);\n if (computed.position === 'static' || !computed.position) {\n node.style.position = 'relative';\n }\n}\n\nwindow.AppStorysShowWidgetElements = function showWidgetElements() {\n try {\n injectStyles();\n const matches = Array.from(document.querySelectorAll('[data-as-id], [data-widget], [data-widget-id]'));\n if (!matches.length) {\n // fallback: try obvious ids/classes used in examples\n const fallbacks = ['#hero_section', '.hero_section', '#header_container', '.header_container'];\n fallbacks.forEach(sel => {\n const el = document.querySelector(sel);\n if (el) matches.push(el);\n });\n }\n\n if (!matches.length) {\n // last resort: mark body top-left\n const pill = makePill('Widget');\n pill.style.position = 'fixed';\n pill.style.top = '12px';\n pill.style.left = '12px';\n pill.style.pointerEvents = 'auto';\n document.body.appendChild(pill);\n return;\n }\n\n matches.forEach((el, idx) => {\n const target = el as HTMLElement;\n ensureRelative(target);\n target.classList.add('appstorys-widget-debug-overlay');\n // remove existing pill if present\n const existing = target.querySelector('.appstorys-widget-debug-pill');\n if (existing) existing.remove();\n const pill = makePill('Widget ' + (idx + 1));\n target.appendChild(pill);\n });\n } catch (err) {\n // swallow errors in dev helper\n // eslint-disable-next-line no-console\n console.error('AppStorysShowWidgetElements error', err);\n }\n};\n\nexport {};\n","import React, { useState, useEffect } from 'react';\nimport { CampaignStory } from '../../types';\nimport useAppStorysStore from '../../core/store';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport trackEvent from '../../core/trackEvent';\nimport { StoryList } from './StoryList';\nimport { StoryOverlay } from './StoryOverlay';\n\nexport const Story: React.FC = () => {\n const data = useCampaigns<CampaignStory>('STR');\n const sdkVisible = useAppStorysStore((state) => state.isVisible);\n const [activeStoryIndex, setActiveStoryIndex] = useState<number | null>(null);\n const [viewedStories, setViewedStories] = useState<string[]>([]);\n\n useEffect(() => {\n try {\n const saved = localStorage.getItem('app_storys_viewed_stories');\n if (saved) {\n setViewedStories(JSON.parse(saved));\n }\n } catch (e) {\n console.error('Failed to load viewed stories:', e);\n }\n }, []);\n\n useEffect(() => {\n if (data && data.details) {\n void trackEvent('story_module_viewed', data.id);\n }\n }, [data]);\n\n if (!data || !data.details || data.details.length === 0 || !sdkVisible) return null;\n\n const handleStoryClick = (index: number) => {\n setActiveStoryIndex(index);\n };\n\n const handleNextStory = () => {\n if (activeStoryIndex === null) return;\n if (activeStoryIndex < data.details.length - 1) {\n setActiveStoryIndex(activeStoryIndex + 1);\n } else {\n setActiveStoryIndex(null);\n }\n };\n\n const handlePrevStory = () => {\n if (activeStoryIndex === null) return;\n if (activeStoryIndex > 0) {\n setActiveStoryIndex(activeStoryIndex - 1);\n }\n };\n\n return (\n <div className=\"story-group-container\" style={{\n width: '100vw',\n position: 'relative',\n left: '50%',\n right: '50%',\n marginLeft: '-50vw',\n marginRight: '-50vw',\n boxSizing: 'border-box'\n }}>\n <StoryList \n stories={data.details} \n viewedStories={viewedStories} \n onStoryClick={handleStoryClick} \n />\n {activeStoryIndex !== null && (\n <StoryOverlay \n stories={data.details}\n activeStoryIndex={activeStoryIndex}\n dataId={data.id}\n viewedStories={viewedStories}\n setViewedStories={setViewedStories}\n onNextStory={handleNextStory}\n onPrevStory={handlePrevStory}\n onClose={() => setActiveStoryIndex(null)}\n />\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport * as LottieModule from 'lottie-react';\n\nconst Lottie =\n (LottieModule as any).default?.default ??\n (LottieModule as any).default ??\n (LottieModule as any).Lottie ??\n (LottieModule as any);\n\ninterface StoryThumbnailProps {\n src: string;\n alt?: string;\n style?: React.CSSProperties;\n size?: number;\n}\n\nexport const StoryThumbnail: React.FC<StoryThumbnailProps> = ({ src, alt, style, size }) => {\n const [lottieData, setLottieData] = useState<any>(null);\n const [lottieFailed, setLottieFailed] = useState(false);\n\n useEffect(() => {\n if (src && src.toLowerCase().endsWith('.json')) {\n fetch(src)\n .then(res => {\n if (!res.ok) throw new Error('Failed to fetch Lottie');\n return res.json();\n })\n .then(json => {\n setLottieData(json);\n setLottieFailed(false);\n })\n .catch(err => {\n console.error('AppStorys: Error loading Lottie thumbnail:', err);\n setLottieFailed(true);\n });\n } else {\n setLottieData(null);\n setLottieFailed(false);\n }\n }, [src]);\n\n const baseStyle: React.CSSProperties = {\n width: size ? `${size}px` : (style?.width || '100%'),\n height: size ? `${size}px` : (style?.height || '100%'),\n objectFit: 'cover',\n display: 'block',\n ...style\n };\n\n if (lottieData && !lottieFailed) {\n const LottieComp = (Lottie as any).default || Lottie;\n return (\n <LottieComp \n animationData={lottieData} \n loop={true} \n autoplay={true}\n style={baseStyle}\n />\n );\n }\n\n return (\n <img\n src={src}\n alt={alt || 'story thumbnail'}\n style={baseStyle}\n onError={() => setLottieFailed(true)}\n />\n );\n};\n","import React from 'react';\nimport { Story as StoryType } from '../../types';\nimport { StoryThumbnail } from './StoryThumbnail';\nimport { resolveFontFamily } from '../../core/fontManager';\n\ninterface StoryGroupItemProps {\n story: StoryType;\n isViewed: boolean;\n onClick: () => void;\n}\n\nexport const StoryGroupItem: React.FC<StoryGroupItemProps> = ({ story, isViewed, onClick }) => {\n const styling = story.styling || {};\n const size = styling.size || 80;\n const ringWidth = styling.ringWidth || 3;\n const ringColor = isViewed ? '#E5E7EB' : (story.ringColor || '#FF0000');\n const nameColor = story.nameColor || '#333333';\n \n const cornerRadius = styling.cornerRadius;\n const borderRadiusStr = cornerRadius \n ? `${cornerRadius.topLeft || 0}px ${cornerRadius.topRight || 0}px ${cornerRadius.bottomRight || 0}px ${cornerRadius.bottomLeft || 0}px` \n : '50%';\n const imgBorderRadiusStr = cornerRadius \n ? `${Math.max(0, (cornerRadius.topLeft || 0) - 3)}px ${Math.max(0, (cornerRadius.topRight || 0) - 3)}px ${Math.max(0, (cornerRadius.bottomRight || 0) - 3)}px ${Math.max(0, (cornerRadius.bottomLeft || 0) - 3)}px` \n : '50%';\n\n return (\n <div\n onClick={onClick}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n flexShrink: 0\n }}\n >\n <div style={{\n width: `${size}px`,\n height: `${size}px`,\n borderRadius: borderRadiusStr,\n border: `${ringWidth}px solid ${ringColor}`,\n padding: '3px',\n boxSizing: 'border-box',\n transition: 'transform 0.1s ease',\n overflow: 'hidden',\n backgroundColor: '#f5f5f5'\n }}>\n <StoryThumbnail\n src={story.thumbnail}\n alt={story.name}\n style={{\n borderRadius: imgBorderRadiusStr,\n }}\n />\n </div>\n <span style={{\n marginTop: '6px',\n fontSize: `${styling.name?.size || 12}px`,\n fontFamily: resolveFontFamily(styling.name?.fontFamily) || 'sans-serif',\n fontWeight: styling.name?.font === 'Bold' ? 'bold' : 'normal',\n color: nameColor,\n maxWidth: `${size + 10}px`,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap'\n }}>\n {story.name}\n </span>\n </div>\n );\n};\n","import React from 'react';\nimport { Story as StoryType } from '../../types';\nimport { StoryGroupItem } from './StoryGroupItem';\n\ninterface StoryListProps {\n stories: StoryType[];\n viewedStories: string[];\n onStoryClick: (index: number) => void;\n}\n\nexport const StoryList: React.FC<StoryListProps> = ({ stories, viewedStories, onStoryClick }) => {\n return (\n <div style={{\n display: 'flex',\n gap: '18px',\n padding: '16px 20px',\n overflowX: 'auto',\n WebkitOverflowScrolling: 'touch',\n justifyContent: 'flex-start'\n }}>\n {stories.sort((a, b) => a.order - b.order).map((story, index) => (\n <StoryGroupItem\n key={story.id}\n story={story}\n isViewed={viewedStories.includes(story.id)}\n onClick={() => onStoryClick(index)}\n />\n ))}\n </div>\n );\n};\n","import React, { useState, useEffect, useRef } from 'react';\nimport { Story as StoryType, StorySlide } from '../../types';\nimport trackEvent from '../../core/trackEvent';\nimport useAppStorysStore, { getAccessToken } from '../../core/store';\nimport { InteractiveOverlay } from '../common/InteractiveElements/InteractiveOverlay';\nimport { StickerData } from '../common/InteractiveElements/types';\nimport PlayPauseButton from '../common/CommonElements/PlayPauseButton';\nimport Cta from '../common/CommonElements/Cta';\nimport CrossButton from '../common/CommonElements/CrossButton';\nimport { SoundButton } from '../common/CommonElements/SoundButton';\nimport ShareButton from '../common/CommonElements/ShareButton';\nimport { parseBackground } from '../../utils/styleUtils';\nimport { StoryThumbnail } from './StoryThumbnail';\n\n\ninterface StoryOverlayProps {\n stories: StoryType[];\n activeStoryIndex: number;\n dataId: string;\n viewedStories: string[];\n setViewedStories: React.Dispatch<React.SetStateAction<string[]>>;\n onNextStory: () => void;\n onPrevStory: () => void;\n onClose: () => void;\n}\n\n// ─── Animation constants ───────────────────────────────────────────────────────\nconst SIDE_CARD_SCALE = 0.63; // how much side/preview cards are scaled\nconst SIDE_CARD_OFFSET = 420; // px — horizontal distance from center to side card origin\nconst ANIM_DURATION = 580; // ms — matches video (~8 frames @ 15fps)\n// Easing: slow-in, fast-middle, slow-out (sinusoidal ease-in-out)\n// Incoming card slides slightly faster than outgoing shrinks for natural depth feel\nconst EASING_OUTGOING = 'cubic-bezier(0.65, 0, 0.35, 1)'; // smooth symmetrical\nconst EASING_INCOMING = 'cubic-bezier(0.45, 0, 0.25, 1)'; // slightly faster lead-in\n\n// Helper: compute the CSS transform for a card given its role\ntype CardRole = 'center' | 'left' | 'right' | 'far-left' | 'far-right' | 'hidden';\n\nfunction getRoleTransform(role: CardRole, cardWidth: number): React.CSSProperties {\n const sideCardOffset = Math.round(cardWidth * 1.08);\n const farSideCardOffset = sideCardOffset + Math.round(cardWidth * SIDE_CARD_SCALE) + 20;\n switch (role) {\n case 'center':\n return {\n transform: 'translateX(0px) scale(1)',\n opacity: 1,\n zIndex: 10,\n pointerEvents: 'auto',\n boxShadow: '0 32px 64px -12px rgba(0,0,0,0.9)',\n filter: 'brightness(1)',\n };\n case 'left':\n return {\n transform: `translateX(-${sideCardOffset}px) scale(${SIDE_CARD_SCALE})`,\n opacity: 1,\n filter: 'brightness(0.55)',\n zIndex: 5,\n pointerEvents: 'auto',\n boxShadow: '0 8px 24px rgba(0,0,0,0.5)',\n };\n case 'right':\n return {\n transform: `translateX(${sideCardOffset}px) scale(${SIDE_CARD_SCALE})`,\n opacity: 1,\n filter: 'brightness(0.55)',\n zIndex: 5,\n pointerEvents: 'auto',\n boxShadow: '0 8px 24px rgba(0,0,0,0.5)',\n };\n case 'far-left':\n return {\n transform: `translateX(-${farSideCardOffset}px) scale(${SIDE_CARD_SCALE})`,\n opacity: 1,\n filter: 'brightness(0.3)',\n zIndex: 2,\n pointerEvents: 'none',\n };\n case 'far-right':\n return {\n transform: `translateX(${farSideCardOffset}px) scale(${SIDE_CARD_SCALE})`,\n opacity: 1,\n filter: 'brightness(0.3)',\n zIndex: 2,\n pointerEvents: 'none',\n };\n case 'hidden':\n default:\n return {\n opacity: 0,\n zIndex: 1,\n pointerEvents: 'none',\n transform: 'translateX(0px) scale(1)',\n filter: 'brightness(1)',\n };\n }\n}\n\n// ─── StoryVideo Helper Component ─────────────────────────────────────────────\n// Ensures videos are properly paused when they slide out of the active center\ninterface StoryVideoProps {\n src: string;\n isActive: boolean;\n isAnimating: boolean;\n isMuted: boolean;\n onLoadedData?: () => void;\n activeVideoRef: React.MutableRefObject<HTMLVideoElement | null>;\n objectFit?: React.CSSProperties['objectFit'];\n}\n\nconst StoryVideo: React.FC<StoryVideoProps> = ({ src, isActive, isAnimating, isMuted, onLoadedData, activeVideoRef, objectFit = 'cover' }) => {\n const localRef = React.useRef<HTMLVideoElement>(null);\n\n React.useEffect(() => {\n if (isActive && !isAnimating) {\n activeVideoRef.current = localRef.current;\n localRef.current?.play().catch(() => { });\n if (localRef.current && localRef.current.readyState >= 2) {\n onLoadedData?.();\n }\n } else {\n localRef.current?.pause();\n if (activeVideoRef.current === localRef.current) {\n activeVideoRef.current = null;\n }\n }\n }, [isActive, isAnimating, src, activeVideoRef]);\n\n return (\n <video\n ref={localRef}\n src={src}\n playsInline\n muted={isMuted}\n onLoadedData={isActive && !isAnimating ? onLoadedData : undefined}\n style={{ width: '100%', height: '100%', objectFit }}\n />\n );\n};\n\nconst VIEWED_SLIDES_KEY = 'appstorys_viewed_slide_ids';\nconst CLICKED_INTERACTIONS_KEY = 'appstorys_clicked_interaction_ids';\n\nconst hasViewedSlide = (slideId: string): boolean => {\n try {\n const data = localStorage.getItem(VIEWED_SLIDES_KEY);\n if (!data) return false;\n const parsed = JSON.parse(data);\n return Array.isArray(parsed) && parsed.includes(slideId);\n } catch (e) {\n return false;\n }\n};\n\nconst markSlideAsViewed = (slideId: string) => {\n try {\n const data = localStorage.getItem(VIEWED_SLIDES_KEY);\n const parsed = data ? JSON.parse(data) : [];\n if (Array.isArray(parsed) && !parsed.includes(slideId)) {\n parsed.push(slideId);\n localStorage.setItem(VIEWED_SLIDES_KEY, JSON.stringify(parsed));\n }\n } catch (e) {\n // ignore\n }\n};\n\nconst hasClickedInteraction = (interactionId: string): boolean => {\n try {\n const data = localStorage.getItem(CLICKED_INTERACTIONS_KEY);\n if (!data) return false;\n const parsed = JSON.parse(data);\n return Array.isArray(parsed) && parsed.includes(interactionId);\n } catch (e) {\n return false;\n }\n};\n\nconst markInteractionAsClicked = (interactionId: string) => {\n try {\n const data = localStorage.getItem(CLICKED_INTERACTIONS_KEY);\n const parsed = data ? JSON.parse(data) : [];\n if (Array.isArray(parsed) && !parsed.includes(interactionId)) {\n parsed.push(interactionId);\n localStorage.setItem(CLICKED_INTERACTIONS_KEY, JSON.stringify(parsed));\n }\n } catch (e) {\n // ignore\n }\n};\n\nexport const StoryOverlay: React.FC<StoryOverlayProps> = ({\n stories,\n activeStoryIndex,\n dataId,\n viewedStories,\n setViewedStories,\n onNextStory,\n onPrevStory,\n onClose,\n}) => {\n const [activeSlideIndex, setActiveSlideIndex] = useState<number>(0);\n const [progress, setProgress] = useState<number>(0);\n const [isMuted, setIsMuted] = useState<boolean>(false);\n const [videoLoaded, setVideoLoaded] = useState<boolean>(false);\n const [isPaused, setIsPaused] = useState<boolean>(false);\n const [showShortcuts, setShowShortcuts] = useState<boolean>(false);\n const [showToast, setShowToast] = useState<string | null>(null);\n const [viewportSize, setViewportSize] = useState({\n width: typeof window !== 'undefined' ? window.innerWidth : 1280,\n height: typeof window !== 'undefined' ? window.innerHeight : 800,\n });\n const [isDesktop, setIsDesktop] = useState(typeof window !== 'undefined' ? window.innerWidth >= 1024 : false);\n\n // ─── NEW: animation state ──────────────────────────────────────────────────\n // outgoingIndex: the slide that's currently animating OUT\n // incomingIndex: the slide that's currently animating IN (= the next activeSlideIndex)\n // direction: which way the transition goes\n const [isAnimating, setIsAnimating] = useState(false);\n const [outgoingIndex, setOutgoingIndex] = useState<number | null>(null);\n const [incomingIndex, setIncomingIndex] = useState<number | null>(null);\n const [direction, setDirection] = useState<'next' | 'prev' | null>(null);\n\n // ─── Story Group Transition State ─────────────────────────────────────────\n const [isGroupAnimating, setIsGroupAnimating] = useState(false);\n const [groupAnimPhase, setGroupAnimPhase] = useState<'none' | 'out' | 'in'>('none');\n const [groupDir, setGroupDir] = useState<'next' | 'prev' | null>(null);\n // ──────────────────────────────────────────────────────────────────────────\n // ──────────────────────────────────────────────────────────────────────────\n\n useEffect(() => {\n const handleResize = () => {\n setViewportSize({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n setIsDesktop(window.innerWidth >= 1024);\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n const progressTimerRef = useRef<any>(null);\n const activeVideoRef = useRef<HTMLVideoElement | null>(null);\n const clickStartTimeRef = useRef<number>(0);\n const lastTrackedSlideId = useRef<string | null>(null);\n\n const currentStory = stories[activeStoryIndex];\n const currentSlide = currentStory?.slides[activeSlideIndex];\n\n const currentSlideStyling = currentSlide?.styling as any;\n const slideEditorSource = currentSlideStyling?.editorSource || currentSlideStyling?.meta?.editorSource;\n const slideIsStudio = slideEditorSource === 'studio' || slideEditorSource === 'editor';\n const slideBgImage = slideIsStudio ? currentSlideStyling?.background?.media?.mediaUrl : currentSlide?.image;\n const slideCtaText = slideIsStudio ? currentSlide?.content?.button_text : currentSlide?.button_text;\n const slideCtaLink = slideIsStudio ? currentSlide?.content?.link : currentSlide?.link;\n const slideVideo = currentSlide?.video || (slideIsStudio ? currentSlide?.content?.video?.[0]?.link : undefined);\n\n // ─── Dynamic Canva Dimensions & Responsive Sizing ───\n const currentCanva = currentSlide?.content?.canva;\n const canvaRatio = (currentCanva && currentCanva.width && currentCanva.height) \n ? (currentCanva.width / currentCanva.height) \n : (9 / 16);\n \n // Calculate max allowable height fitting within viewport\n const headerFooterReserved = isDesktop ? 160 : 80;\n const availHeight = Math.max(350, viewportSize.height - headerFooterReserved);\n const availWidth = isDesktop ? viewportSize.width * 0.75 : viewportSize.width * 0.95;\n\n const computedCardHeight = Math.min(availHeight, availWidth / canvaRatio);\n\n const CARD_HEIGHT = isDesktop\n ? Math.round(Math.max(450, Math.min(computedCardHeight, 850)))\n : Math.round(Math.min(availHeight, 850));\n\n const CARD_WIDTH = Math.round(CARD_HEIGHT * canvaRatio);\n\n const handleShare = async () => {\n const shareData = {\n title: currentStory.name,\n text: `Check out this story: ${currentStory.name}`,\n url: window.location.href,\n };\n\n if (currentSlide?.id) {\n void trackEvent('shared', dataId, { story_slide: currentSlide.id });\n }\n\n if (navigator.share) {\n try {\n await navigator.share(shareData);\n } catch (err) { }\n } else {\n if (navigator.clipboard) {\n try {\n await navigator.clipboard.writeText(window.location.href);\n setShowToast('Story link copied to clipboard!');\n setTimeout(() => setShowToast(null), 2500);\n } catch (err) { }\n }\n }\n };\n\n useEffect(() => {\n setActiveSlideIndex(0);\n setProgress(0);\n setVideoLoaded(false);\n setIsPaused(false);\n setIsAnimating(false);\n setOutgoingIndex(null);\n setIncomingIndex(null);\n setDirection(null);\n }, [activeStoryIndex]);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (document.activeElement?.tagName === 'INPUT' || document.activeElement?.tagName === 'TEXTAREA') return;\n switch (e.key) {\n case 'ArrowRight': handleNextSlide(); break;\n case 'ArrowLeft': handlePrevSlide(); break;\n case ' ':\n e.preventDefault();\n setIsPaused(prev => !prev);\n break;\n case 'Escape': onClose(); break;\n case 's':\n case 'S':\n e.preventDefault();\n handleShare();\n break;\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [activeSlideIndex, activeStoryIndex, isPaused, currentStory, onClose]);\n\n useEffect(() => {\n if (currentStory && currentSlide && lastTrackedSlideId.current !== currentSlide.id) {\n lastTrackedSlideId.current = currentSlide.id;\n if (!hasViewedSlide(currentSlide.id)) {\n markSlideAsViewed(currentSlide.id);\n void trackEvent('viewed', dataId, { story_slide: currentSlide.id });\n }\n }\n }, [activeSlideIndex, currentStory?.id, dataId, currentSlide?.id]);\n\n useEffect(() => {\n if (currentStory && currentSlide) {\n const slideTime = currentStory.styling?.slideShowTime || 5;\n const isVideo = !!slideVideo;\n\n if (progressTimerRef.current) clearInterval(progressTimerRef.current);\n\n if (isPaused) {\n if (activeVideoRef.current) activeVideoRef.current.pause();\n return;\n } else {\n if (activeVideoRef.current) activeVideoRef.current.play().catch(() => { });\n }\n\n if (isVideo && !videoLoaded) return;\n if (isAnimating) return;\n\n progressTimerRef.current = setInterval(() => {\n setProgress((prev) => {\n if (prev >= 100) {\n handleNextSlide();\n return 100;\n }\n return prev + (100 / (slideTime * 10));\n });\n }, 100);\n\n return () => {\n if (progressTimerRef.current) clearInterval(progressTimerRef.current);\n };\n }\n }, [activeStoryIndex, activeSlideIndex, isPaused, videoLoaded, isAnimating]);\n\n if (!currentSlide) return null;\n\n // ─── NEW: Core transition function ────────────────────────────────────────\n const triggerSlideTransition = (dir: 'next' | 'prev', targetIndex: number) => {\n if (isAnimating) return;\n setDirection(dir);\n setOutgoingIndex(activeSlideIndex);\n setIncomingIndex(targetIndex);\n setIsAnimating(true);\n\n // After animation completes, commit the new active index and clean up\n setTimeout(() => {\n setActiveSlideIndex(targetIndex);\n setProgress(0);\n setVideoLoaded(false);\n setIsAnimating(false);\n setOutgoingIndex(null);\n setIncomingIndex(null);\n setDirection(null);\n }, ANIM_DURATION + 20); // +20ms buffer so CSS transition fully completes before state flush\n };\n\n const handleNextSlide = () => {\n if (isAnimating || isGroupAnimating) return;\n if (activeSlideIndex < currentStory.slides.length - 1) {\n triggerSlideTransition('next', activeSlideIndex + 1);\n } else {\n if (!viewedStories.includes(currentStory.id)) {\n const updated = [...viewedStories, currentStory.id];\n setViewedStories(updated);\n localStorage.setItem('app_storys_viewed_stories', JSON.stringify(updated));\n }\n triggerGroupTransition('next');\n }\n };\n\n const handlePrevSlide = () => {\n if (isAnimating || isGroupAnimating) return;\n if (activeSlideIndex > 0) {\n triggerSlideTransition('prev', activeSlideIndex - 1);\n } else {\n triggerGroupTransition('prev');\n }\n };\n\n // ─── Story Group Transition Handler ──────────────────────────────────────\n const triggerGroupTransition = (dir: 'next' | 'prev') => {\n if (isGroupAnimating || isAnimating) return;\n\n if (dir === 'next') {\n if (activeStoryIndex >= stories.length - 1) {\n onNextStory();\n return;\n }\n } else {\n if (activeStoryIndex <= 0) {\n onPrevStory();\n return;\n }\n }\n\n setIsGroupAnimating(true);\n setGroupDir(dir);\n setGroupAnimPhase('out');\n\n // Stage 1: Slide OUT current story group (280ms)\n setTimeout(() => {\n // Change to target story group in state\n if (dir === 'next') {\n onNextStory();\n } else {\n onPrevStory();\n }\n \n // Stage 2: Render incoming group offscreen (prepare-in)\n setGroupAnimPhase('prepare-in');\n\n // Stage 3: Trigger entrance transition to center on next frame\n setTimeout(() => {\n setGroupAnimPhase('in');\n\n // Stage 4: Clean up animation state when complete\n setTimeout(() => {\n setIsGroupAnimating(false);\n setGroupAnimPhase('none');\n setGroupDir(null);\n }, 320);\n }, 35);\n }, 280);\n };\n\n const getGroupAnimStyle = (): React.CSSProperties => {\n if (groupAnimPhase === 'out') {\n const translateX = groupDir === 'next' ? -120 : 120;\n return {\n transform: `translateX(${translateX}px) scale(0.92)`,\n opacity: 0,\n filter: 'blur(6px)',\n transition: 'transform 280ms cubic-bezier(0.4, 0, 0.2, 1), opacity 280ms cubic-bezier(0.4, 0, 0.2, 1), filter 280ms cubic-bezier(0.4, 0, 0.2, 1)',\n willChange: 'transform, opacity, filter',\n };\n }\n if (groupAnimPhase === 'prepare-in') {\n const translateX = groupDir === 'next' ? 120 : -120;\n return {\n transform: `translateX(${translateX}px) scale(0.92)`,\n opacity: 0,\n filter: 'blur(6px)',\n transition: 'none',\n willChange: 'transform, opacity, filter',\n };\n }\n if (groupAnimPhase === 'in') {\n return {\n transform: 'translateX(0px) scale(1)',\n opacity: 1,\n filter: 'blur(0px)',\n transition: 'transform 320ms cubic-bezier(0.16, 1, 0.3, 1), opacity 320ms cubic-bezier(0.16, 1, 0.3, 1), filter 320ms cubic-bezier(0.16, 1, 0.3, 1)',\n willChange: 'transform, opacity, filter',\n };\n }\n return {\n transition: 'transform 320ms cubic-bezier(0.16, 1, 0.3, 1), opacity 320ms cubic-bezier(0.16, 1, 0.3, 1), filter 320ms cubic-bezier(0.16, 1, 0.3, 1)',\n };\n };\n // ──────────────────────────────────────────────────────────────────────────\n // ──────────────────────────────────────────────────────────────────────────\n\n const handleMouseDownNav = () => {\n clickStartTimeRef.current = Date.now();\n setIsPaused(true);\n };\n\n const handleMouseUpNav = (dir: 'next' | 'prev') => {\n setIsPaused(false);\n const duration = Date.now() - clickStartTimeRef.current;\n if (duration < 300) {\n if (dir === 'next') handleNextSlide();\n else handlePrevSlide();\n }\n };\n\n const handleVideoLoad = () => setVideoLoaded(true);\n\n const handleClickCTA = (slide: StorySlide) => {\n const styling = slide?.styling as any;\n const editorSource = styling?.editorSource || styling?.meta?.editorSource;\n const isStudio = editorSource === 'studio' || editorSource === 'editor';\n const link = isStudio ? slide.content?.link : slide.link;\n\n if (link) {\n const clickId = `cta_slide_${slide.id}`;\n if (!hasClickedInteraction(clickId)) {\n markInteractionAsClicked(clickId);\n void trackEvent('clicked', dataId, { story_slide: slide.id });\n }\n if (link.startsWith('http')) {\n window.open(link, '_blank');\n } else {\n window.location.href = link;\n }\n }\n };\n\n const handleOverlayInteraction = async (interactionData: any, slide: StorySlide) => {\n const { type, questionId, pollId, quizId, optionId, value, stickerId, redirectUrl } = interactionData;\n\n if (type === 'cta') {\n if (redirectUrl) {\n const clickId = stickerId || `cta_sticker_${slide.id}`;\n if (!hasClickedInteraction(clickId)) {\n markInteractionAsClicked(clickId);\n void trackEvent('clicked', dataId, { story_slide: slide.id, cta_id: stickerId });\n }\n if (redirectUrl.startsWith('http')) {\n window.open(redirectUrl, '_blank');\n } else {\n window.location.href = redirectUrl;\n }\n }\n return;\n }\n\n setIsPaused(true);\n let interaction_type = type?.split('_')[0] || 'interaction';\n if (interaction_type === 'quizz') interaction_type = 'quiz';\n if (type?.startsWith('image_quiz')) interaction_type = 'quiz';\n const interaction_id = stickerId || questionId || pollId || quizId || slide.id;\n\n if (hasClickedInteraction(interaction_id)) {\n return;\n }\n markInteractionAsClicked(interaction_id);\n\n const selected = optionId || interactionData.selected_option || interactionData.emoji || '';\n const state = useAppStorysStore.getState();\n const userId = state.userId || 'anonymous';\n const trackingUrl = state.trackingUrl || 'https://tracking.appstorys.co';\n const accessToken = await getAccessToken();\n\n const bodyMetadata: Record<string, any> = {\n interaction_type,\n interaction_id,\n story_slide: slide.id,\n selected_option: String(selected)\n };\n if (value !== undefined && value !== null && value !== '') {\n bodyMetadata.value = String(value);\n }\n\n fetch(`${trackingUrl}/capture-event`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}) },\n body: JSON.stringify({\n user_id: userId, campaign_id: dataId, event: 'clicked',\n metadata: bodyMetadata\n })\n }).catch(err => console.error('AppStorys: Instant Tracking Failed', err));\n };\n\n const toggleMute = (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsMuted(!isMuted);\n };\n\n const crossConfig = currentStory?.styling?.crossButton;\n const soundConfig = currentStory?.styling?.soundToggle;\n const ctaStyling = currentSlide?.styling?.cta;\n\n // ─── NEW: Compute role for each slide during animation ────────────────────\n /**\n * Returns the CardRole for a given slide index.\n *\n * Idle (not animating):\n * activeSlideIndex-1 → 'left' (visible side preview)\n * activeSlideIndex → 'center' (active card)\n * activeSlideIndex+1 → 'right' (visible side preview)\n * everything else → 'hidden'\n *\n * Animating NEXT (outgoing=activeSlideIndex → left, incoming=activeSlideIndex+1 → center):\n * outgoingIndex → 'left' (animates: center → left)\n * incomingIndex → 'center' (animates: right → center)\n * outgoingIndex-1 → 'far-left' (fades away)\n * incomingIndex+1 → 'right' (slides into the right preview spot)\n *\n * Animating PREV:\n * outgoingIndex → 'right' (animates: center → right)\n * incomingIndex → 'center' (animates: left → center)\n * outgoingIndex+1 → 'far-right'\n * incomingIndex-1 → 'left'\n */\n const getSlideRole = (idx: number): CardRole => {\n if (!isAnimating) {\n if (idx === activeSlideIndex) return 'center';\n if (idx === activeSlideIndex - 1) return 'left';\n if (idx === activeSlideIndex - 2) return 'far-left';\n if (idx === activeSlideIndex + 1) return 'right';\n if (idx === activeSlideIndex + 2) return 'far-right';\n return 'hidden';\n }\n\n // During animation\n if (direction === 'next') {\n if (idx === outgoingIndex) return 'left'; // shrinks & moves left\n if (idx === incomingIndex) return 'center'; // slides in from right\n if (idx === (outgoingIndex ?? 0) - 1) return 'far-left'; // previous left becomes far-left\n if (idx === (outgoingIndex ?? 0) - 2) return 'hidden'; // previous far-left becomes hidden\n if (idx === (incomingIndex ?? 0) + 1) return 'right'; // next-next becomes right\n if (idx === (incomingIndex ?? 0) + 2) return 'far-right'; // new card becomes far-right\n return 'hidden';\n } else {\n // direction === 'prev'\n if (idx === outgoingIndex) return 'right'; // shrinks & moves right\n if (idx === incomingIndex) return 'center'; // slides in from left\n if (idx === (outgoingIndex ?? 0) + 1) return 'far-right';\n if (idx === (outgoingIndex ?? 0) + 2) return 'hidden';\n if (idx === (incomingIndex ?? 0) - 1) return 'left';\n if (idx === (incomingIndex ?? 0) - 2) return 'far-left';\n return 'hidden';\n }\n };\n\n /**\n * The \"starting position\" of a card before the animation begins.\n * When isAnimating becomes true, the card needs to be at its SOURCE position\n * on frame 0, then CSS transition carries it to its TARGET position.\n *\n * The trick: we set the initial transform via inline style BEFORE\n * adding the transition class, so the first paint shows the source pos,\n * and the second paint (after React flushes) shows the target with transition.\n *\n * Since React batches state updates and the transition is applied together\n * with the role assignment, we achieve this by always defining both the\n * \"source role\" and the \"target role\" in the same render. The CSS transition\n * property does the interpolation.\n *\n * For the INCOMING card (next slide going → center on a 'next' transition):\n * It must START at the 'right' position and END at 'center'.\n * In getSlideRole it returns 'center' immediately, so we need its\n * initial position to be 'right' BEFORE isAnimating was true.\n * → We solve this with a \"pre-transition\" frame using a separate useEffect trick,\n * BUT the simplest CSS-only approach is:\n * Give the incoming card 'right' transform with NO transition for 1 frame,\n * then switch to 'center' with transition.\n *\n * Simpler approach used here: we render incoming slide at its START role\n * during the first frame via a `pendingRole` system, then swap to target role.\n */\n // ──────────────────────────────────────────────────────────────────────────\n\n // Responsive Styles\n const backdropStyle: React.CSSProperties = isDesktop ? {\n position: 'fixed',\n top: 0, left: 0,\n width: '100vw', height: '100vh',\n background: 'radial-gradient(circle at center, #0B1424 0%, #03070E 100%)',\n zIndex: 100000,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n overflow: 'hidden',\n color: 'white'\n } : {\n position: 'fixed',\n top: 0, left: 0,\n width: '100vw', height: '100vh',\n backgroundColor: 'rgba(0,0,0,0.95)',\n zIndex: 100000,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center'\n };\n\n const centerCardBaseStyle: React.CSSProperties = isDesktop ? {\n position: 'absolute',\n width: `${CARD_WIDTH}px`,\n height: `${CARD_HEIGHT}px`,\n backgroundColor: '#000',\n borderRadius: '20px',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.8)',\n border: '1px solid rgba(255, 255, 255, 0.1)',\n // transition is applied per-card below\n } : {\n position: 'relative',\n width: `${CARD_WIDTH}px`,\n maxWidth: '100vw',\n height: `${CARD_HEIGHT}px`,\n maxHeight: '92vh',\n aspectRatio: `${canvaRatio}`,\n backgroundColor: '#000',\n borderRadius: '12px',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column'\n };\n\n // Mobile side card style (unchanged from original)\n const sideCardStyle: React.CSSProperties = {\n width: '240px',\n height: '420px',\n backgroundColor: '#000',\n borderRadius: '16px',\n overflow: 'hidden',\n opacity: 1,\n filter: 'brightness(0.6)',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 10px 20px rgba(0,0,0,0.5)',\n border: '1px solid rgba(255, 255, 255, 0.05)',\n transform: 'scale(0.9)',\n transition: 'all 0.3s ease',\n cursor: 'pointer'\n };\n\n // ─── Determine which slides to render (visible window) ────────────────────\n const slidesToRender = currentStory.slides.reduce<number[]>((acc, _, idx) => {\n const role = getSlideRole(idx);\n if (role !== 'hidden') acc.push(idx);\n // Also include indices just outside the window that might be 'hidden' but\n // need to be mounted for the incoming animation to have something to transition from.\n return acc;\n }, []);\n\n // Always include activeSlideIndex ± 2 so cards are pre-mounted for transitions\n const renderSet = new Set(slidesToRender);\n renderSet.add(activeSlideIndex);\n if (activeSlideIndex > 0) renderSet.add(activeSlideIndex - 1);\n if (activeSlideIndex > 1) renderSet.add(activeSlideIndex - 2);\n if (activeSlideIndex < currentStory.slides.length - 1) renderSet.add(activeSlideIndex + 1);\n if (activeSlideIndex < currentStory.slides.length - 2) renderSet.add(activeSlideIndex + 2);\n\n return (\n <div style={backdropStyle} onClick={() => !isDesktop && handleNextSlide()}>\n\n {/* Dynamic Ambient Glow Background */}\n <div\n key={`${activeStoryIndex}-${isAnimating ? incomingIndex : activeSlideIndex}`}\n style={{\n position: 'absolute', top: 0, left: 0, right: 0, bottom: 0,\n zIndex: 0, overflow: 'hidden', pointerEvents: 'none',\n transition: 'all 0.6s ease-in-out'\n }}\n >\n {slideVideo ? (\n <video src={slideVideo} style={{ width: '100%', height: '100%', objectFit: 'cover', filter: 'blur(120px) saturate(1.8) opacity(0.35)' }} muted />\n ) : (\n <StoryThumbnail\n src={slideBgImage || currentStory.thumbnail}\n style={{ width: '100%', height: '100%', filter: 'blur(120px) saturate(1.8) opacity(0.35)' }}\n />\n )}\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(5, 5, 8, 0.4)' }} />\n </div>\n\n {isDesktop && (\n <div style={{\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n paddingTop: '20px',\n zIndex: 10,\n ...getGroupAnimStyle(),\n }}>\n {/* Progress Bar */}\n <div style={{\n width: '100%',\n display: 'flex',\n gap: '8px',\n padding: '0 20px',\n boxSizing: 'border-box',\n }}>\n {currentStory.slides.map((_, idx) => {\n const displayIndex = isAnimating && incomingIndex !== null ? incomingIndex : activeSlideIndex;\n let fillWidth = '0%';\n if (idx < displayIndex) fillWidth = '100%';\n else if (idx === displayIndex) fillWidth = `${progress}%`;\n\n return (\n <div key={idx} style={{\n flex: 1, height: '3px',\n backgroundColor: 'rgba(255,255,255,0.15)',\n borderRadius: '2px', overflow: 'hidden'\n }}>\n <div style={{\n width: fillWidth, height: '100%',\n backgroundColor: 'white',\n transition: idx === displayIndex ? 'width 0.1s linear' : 'none'\n }} />\n </div>\n );\n })}\n </div>\n\n {/* Icons Grid */}\n <div style={{\n width: '100%',\n margin: '0 auto',\n display: 'grid',\n gridTemplateColumns: `minmax(0, 1fr) ${CARD_WIDTH}px minmax(0, 1fr)`,\n gap: '12px',\n alignItems: 'center',\n marginTop: '16px',\n padding: '0 20px',\n boxSizing: 'border-box',\n zIndex: showShortcuts ? 2000 : 10\n }}>\n <div style={{ paddingLeft: '0px' }} />\n\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>\n <StoryThumbnail\n src={currentStory.thumbnail}\n alt={currentStory.name}\n style={{ width: '44px', height: '44px', borderRadius: '50%', border: '2px solid white', margin: 0 }}\n />\n <span style={{ color: 'white', fontWeight: 'bold', fontSize: '16px', whiteSpace: 'nowrap' }}>\n {currentStory.name}\n </span>\n </div>\n <div style={{ display: 'flex', gap: '8px' }}>\n <ShareButton\n config={{\n enabled: currentStory?.styling?.share?.enabled ?? true,\n image: currentStory?.styling?.share?.image ?? '',\n color: {\n cross: currentStory?.styling?.share?.color?.cross ?? '#ffffff',\n fill: currentStory?.styling?.share?.color?.fill ?? 'rgba(255,255,255,0.08)',\n stroke: currentStory?.styling?.share?.color?.stroke ?? 'transparent',\n },\n margin: { top: 0, bottom: 0, left: 0, right: 0 },\n size: currentStory?.styling?.share?.size ?? 44\n }}\n onPress={handleShare}\n style={{ position: 'relative', borderRadius: '12px' }}\n />\n <SoundButton\n config={{\n size: 44,\n color: { cross: '#ffffff', fill: 'rgba(255,255,255,0.08)', stroke: 'transparent' },\n margin: { top: 0, bottom: 0, left: 0, right: 0 },\n image: '' // Force common SVG icons\n }}\n onPress={toggleMute}\n type={isMuted ? 'mute' : 'unmute'}\n enabled={!!soundConfig?.enabled && !!slideVideo}\n style={{ position: 'relative', borderRadius: '12px' }}\n />\n <PlayPauseButton isPaused={isPaused} onPress={() => setIsPaused(!isPaused)} size={44} style={{ borderRadius: '12px' }} />\n </div>\n </div>\n\n <div style={{ display: 'flex', gap: '10px', flex: 1, justifyContent: 'flex-end', paddingRight: '0px' }}>\n <div style={{ position: 'relative' }}>\n <button\n onClick={() => { setShowShortcuts(!showShortcuts); setIsPaused(!showShortcuts); }}\n style={{\n width: '44px', height: '44px',\n background: showShortcuts ? 'rgba(255,255,255,0.15)' : 'rgba(255,255,255,0.08)',\n border: showShortcuts ? '1px solid white' : '1px solid rgba(255,255,255,0.1)',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n borderRadius: '12px', cursor: 'pointer', transition: 'all 0.2s',\n padding: 0, outline: 'none'\n }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\n </svg>\n </button>\n {showShortcuts && (\n <>\n <style>{`\n @keyframes fadeUp {\n from { opacity: 0; transform: translateY(10px) scale(0.95); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n `}</style>\n <div style={{ position: 'absolute', top: '46px', right: 0, width: '260px', background: 'rgba(25, 25, 25, 0.98)', border: '1px solid rgba(255,255,255,0.08)', borderRadius: '16px', padding: '18px', boxShadow: '0 20px 25px -5px rgba(0,0,0,0.4), 0 10px 10px -5px rgba(0,0,0,0.4)', zIndex: 1001, animation: 'fadeUp 0.25s cubic-bezier(0.4, 0, 0.2, 1) forwards' }}>\n <div style={{ fontSize: '11px', fontWeight: 'bold', color: '#9CA3AF', letterSpacing: '1px', textTransform: 'uppercase', marginBottom: '16px', paddingBottom: '10px', borderBottom: '1px solid rgba(255,255,255,0.06)' }}>Keyboard Shortcuts</div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n {[\n { key: '→', label: 'Next slide' },\n { key: '←', label: 'Previous slide' },\n { key: 'space', label: 'Play/Pause' },\n { key: 'esc', label: 'Close story' },\n { key: 'S', label: 'Share story link' },\n ].map(({ key, label }) => (\n <div key={key} style={{ display: 'flex', alignItems: 'center', gap: '14px', justifyContent: 'flex-start' }}>\n <span style={{ minWidth: '54px', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(255,255,255,0.08)', padding: '5px 8px', borderRadius: '5px', fontSize: '12px', color: 'white', border: '1px solid rgba(255,255,255,0.1)', boxSizing: 'border-box' }}>{key}</span>\n <span style={{ fontSize: '13px', color: '#E5E7EB', fontWeight: '500', textAlign: 'left' }}>{label}</span>\n </div>\n ))}\n </div>\n </div>\n </>\n )}\n </div>\n <CrossButton\n config={{\n enabled: crossConfig?.enabled ?? true,\n image: '', // Force common SVG icon\n color: { cross: '#ffffff', fill: 'rgba(255,255,255,0.08)', stroke: 'transparent' },\n margin: { top: 0, bottom: 0, left: 0, right: 0 },\n size: 44\n }}\n onPress={onClose}\n style={{ position: 'relative', borderRadius: '12px' }}\n />\n </div>\n </div>\n </div>\n )}\n\n {/* Main Container Wrapper */}\n <div style={{\n flex: 1, width: '100%',\n display: 'flex', flexDirection: 'column',\n justifyContent: isDesktop ? 'flex-start' : 'center',\n alignItems: 'center',\n paddingTop: isDesktop ? '14px' : '0px',\n ...getGroupAnimStyle(),\n }}>\n\n\n {/* ── Story Player Container ── */}\n <div\n style={{\n display: isDesktop ? 'grid' : 'flex',\n gridTemplateColumns: isDesktop ? `minmax(0, 1fr) ${CARD_WIDTH}px minmax(0, 1fr)` : 'none',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '12px',\n width: '100%',\n maxWidth: '1400px',\n position: 'relative'\n }}\n onClick={(e) => isDesktop && e.stopPropagation()}\n >\n {/* Left column (desktop only) */}\n {isDesktop && (\n <div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: '12px', width: '100%', boxSizing: 'border-box' }}>\n {(activeSlideIndex > 0 || activeStoryIndex > 0) && (\n <button\n onClick={handlePrevSlide}\n style={{ background: 'rgba(0,0,0,0.45)', border: '1px solid rgba(255,255,255,0.1)', color: 'white', borderRadius: '50%', width: '44px', height: '44px', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', backdropFilter: 'blur(10px)', transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)', boxShadow: '0 8px 16px rgba(0,0,0,0.3)', outline: 'none' }}\n onMouseEnter={(e) => { e.currentTarget.style.background = 'rgba(0,0,0,0.75)'; e.currentTarget.style.transform = 'scale(1.1)'; e.currentTarget.style.borderColor = 'rgba(255,255,255,0.25)'; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = 'rgba(0,0,0,0.45)'; e.currentTarget.style.transform = 'scale(1)'; e.currentTarget.style.borderColor = 'rgba(255,255,255,0.1)'; }}\n >\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"15 18 9 12 15 6\"></polyline>\n </svg>\n </button>\n )}\n </div>\n )}\n\n {/* ── CENTER: Story card stack (desktop) / single card (mobile) ── */}\n {isDesktop ? (\n // ─── DESKTOP: absolute-positioned card stack with transform-based animation ───\n <div style={{\n width: `${CARD_WIDTH}px`,\n height: `${CARD_HEIGHT}px`,\n position: 'relative',\n zIndex: 5,\n // overflow visible so side cards can poke out\n overflow: 'visible',\n }}>\n {Array.from(renderSet).sort((a, b) => a - b).map((index) => {\n const slide = currentStory.slides[index];\n if (!slide) return null;\n\n const role = getSlideRole(index);\n const roleStyle = getRoleTransform(role, CARD_WIDTH);\n\n const slideStyling = slide?.styling as any;\n const editorSource = slideStyling?.editorSource || slideStyling?.meta?.editorSource;\n const isStudio = editorSource === 'studio' || editorSource === 'editor';\n const bgImage = slideStyling?.background?.media?.mediaUrl || slide?.image;\n const video = slide?.video || (isStudio ? slide?.content?.video?.[0]?.link : undefined);\n const bgColor = parseBackground(slideStyling?.background) || '#000000';\n const slideCtaTextLocal = isStudio ? slide?.content?.button_text : slide?.button_text;\n const slideCtaLinkLocal = isStudio ? slide?.content?.link : slide?.link;\n\n const mediaSizing = slideStyling?.background?.media?.sizing;\n const objectFit = mediaSizing === 'fill' ? 'cover' : mediaSizing === 'fit' ? 'contain' : mediaSizing === 'stretch' ? 'fill' : (isStudio ? 'contain' : 'cover');\n\n const isCurrent = index === activeSlideIndex && !isAnimating;\n const isIncoming = isAnimating && index === incomingIndex;\n const isActive = isCurrent || isIncoming;\n\n const containerStyles: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: isStudio ? bgColor : '#000',\n position: 'relative',\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n borderRadius: '16px',\n };\n\n return (\n <div\n key={slide.id || index}\n style={{\n ...centerCardBaseStyle,\n // Override position to absolute for the stacking\n position: 'absolute',\n top: 0,\n left: 0,\n width: `${CARD_WIDTH}px`,\n height: `${CARD_HEIGHT}px`,\n // Apply role-based transform + transition\n ...roleStyle,\n transition: role === 'hidden' || role === 'far-left' || role === 'far-right'\n ? `opacity ${ANIM_DURATION}ms ease, transform ${ANIM_DURATION}ms ease`\n : index === outgoingIndex\n ? `transform ${ANIM_DURATION}ms ${EASING_OUTGOING}, opacity ${ANIM_DURATION}ms ${EASING_OUTGOING}, filter ${ANIM_DURATION}ms ${EASING_OUTGOING}`\n : `transform ${ANIM_DURATION}ms ${EASING_INCOMING}, opacity ${ANIM_DURATION}ms ${EASING_INCOMING}, filter ${ANIM_DURATION}ms ${EASING_INCOMING}`,\n transformOrigin: 'center center',\n willChange: 'transform, opacity, filter',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Content */}\n <div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, width: '30%', zIndex: 5, cursor: 'pointer' }} onMouseDown={handleMouseDownNav} onMouseUp={() => handleMouseUpNav('prev')} onTouchStart={handleMouseDownNav} onTouchEnd={() => handleMouseUpNav('prev')} />\n <div style={{ position: 'absolute', top: 0, bottom: 0, right: 0, width: '70%', zIndex: 4, cursor: 'pointer' }} onMouseDown={handleMouseDownNav} onMouseUp={() => handleMouseUpNav('next')} onTouchStart={handleMouseDownNav} onTouchEnd={() => handleMouseUpNav('next')} />\n\n <div style={containerStyles}>\n {video ? (\n <StoryVideo\n src={video}\n isActive={isActive}\n isAnimating={isAnimating}\n isMuted={isMuted}\n onLoadedData={handleVideoLoad}\n activeVideoRef={activeVideoRef}\n objectFit={objectFit}\n />\n ) : (\n (bgImage || (!isStudio && currentStory?.thumbnail)) && (\n <StoryThumbnail\n src={bgImage || currentStory?.thumbnail}\n alt=\"Story content\"\n style={{ width: '100%', height: '100%', objectFit: objectFit }}\n />\n )\n )}\n <InteractiveOverlay\n content={{\n ...slide.content,\n styling: {\n ...(slide.content as any)?.styling,\n ...(slide as any)?.styling,\n },\n interactions: slide.interactions,\n }}\n elapsedTime={isActive ? (progress / 100) * (currentStory.styling?.slideShowTime || 5) : 0}\n onInteraction={async (interactionData: any) => {\n if (!isActive) return;\n handleOverlayInteraction(interactionData, slide);\n }}\n />\n </div>\n\n {(slideCtaTextLocal || slideCtaLinkLocal) && (\n <Cta\n cta={slide?.styling?.cta}\n buttonText={slideCtaTextLocal || 'Learn More'}\n onPress={(e) => { if (e && e.stopPropagation) e.stopPropagation(); handleClickCTA(slide); }}\n />\n )}\n </div>\n );\n })}\n </div>\n ) : (\n // ─── MOBILE: single responsive card maintaining aspect ratio ───\n <div style={{\n width: `${CARD_WIDTH}px`,\n maxWidth: '100vw',\n height: `${CARD_HEIGHT}px`,\n maxHeight: '92vh',\n aspectRatio: `${canvaRatio}`,\n overflow: 'hidden',\n position: 'relative',\n zIndex: 5,\n display: 'flex',\n flexDirection: 'column'\n }}>\n {currentStory.slides.map((slide, index) => {\n if (Math.abs(index - activeSlideIndex) > 1) {\n return <div key={slide.id || index} style={{ display: 'none' }} />;\n }\n\n const slideStyling = slide?.styling as any;\n const editorSource = slideStyling?.editorSource || slideStyling?.meta?.editorSource;\n const isStudio = editorSource === 'studio' || editorSource === 'editor';\n const bgImage = slideStyling?.background?.media?.mediaUrl || slide?.image;\n const video = slide?.video || (isStudio ? slide?.content?.video?.[0]?.link : undefined);\n const bgColor = parseBackground(slideStyling?.background) || '#000000';\n const slideCtaTextLocal = isStudio ? slide?.content?.button_text : slide?.button_text;\n const slideCtaLinkLocal = isStudio ? slide?.content?.link : slide?.link;\n\n const mediaSizing = slideStyling?.background?.media?.sizing;\n const objectFit = mediaSizing === 'fill' ? 'cover' : mediaSizing === 'fit' ? 'contain' : mediaSizing === 'stretch' ? 'fill' : (isStudio ? 'contain' : 'cover');\n\n const isCurrent = index === activeSlideIndex;\n\n if (!isCurrent) return null;\n\n return (\n <div key={slide.id || index} style={{ width: '100%', height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>\n <div style={{ ...centerCardBaseStyle }} onClick={(e) => e.stopPropagation()}>\n\n <div style={{ position: 'absolute', top: 0, left: 0, right: 0, display: 'flex', gap: '4px', padding: '10px', zIndex: 10 }}>\n {currentStory.slides.map((_, idx) => {\n let fillWidth = idx < activeSlideIndex ? '100%' : idx === activeSlideIndex ? `${progress}%` : '0%';\n return (\n <div key={idx} style={{ flex: 1, height: '3px', backgroundColor: 'rgba(255,255,255,0.3)', borderRadius: '2px', overflow: 'hidden' }}>\n <div style={{ width: fillWidth, height: '100%', backgroundColor: 'white', transition: idx === activeSlideIndex ? 'width 0.1s linear' : 'none' }} />\n </div>\n );\n })}\n </div>\n\n <div style={{ position: 'absolute', top: '20px', left: '10px', right: '10px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', zIndex: 10, padding: '5px' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n <StoryThumbnail src={currentStory.thumbnail} alt={currentStory.name} style={{ width: '32px', height: '32px', borderRadius: '50%' }} />\n <span style={{ color: 'white', fontWeight: 'bold', fontSize: '14px', textShadow: '0 1px 3px rgba(0,0,0,0.8)' }}>{currentStory.name}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>\n <SoundButton config={{ size: 32, color: { cross: '#ffffff', fill: 'rgba(255,255,255,0.08)', stroke: 'transparent' }, margin: { top: 0, bottom: 0, left: 0, right: 0 }, image: '' }} onPress={toggleMute} type={isMuted ? 'mute' : 'unmute'} enabled={!!soundConfig?.enabled && !!video} style={{ position: 'relative', borderRadius: '10px' }} />\n <CrossButton config={{ enabled: crossConfig?.enabled !== false, image: '', color: { cross: '#ffffff', fill: 'rgba(255,255,255,0.08)', stroke: 'transparent' }, margin: { top: 0, bottom: 0, left: 0, right: 0 }, size: 32 }} onPress={onClose} style={{ position: 'relative', borderRadius: '10px' }} />\n </div>\n </div>\n\n <div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, width: '30%', zIndex: 5, cursor: 'pointer' }} onMouseDown={handleMouseDownNav} onMouseUp={() => handleMouseUpNav('prev')} onTouchStart={handleMouseDownNav} onTouchEnd={() => handleMouseUpNav('prev')} />\n <div style={{ position: 'absolute', top: 0, bottom: 0, right: 0, width: '70%', zIndex: 4, cursor: 'pointer' }} onMouseDown={handleMouseDownNav} onMouseUp={() => handleMouseUpNav('next')} onTouchStart={handleMouseDownNav} onTouchEnd={() => handleMouseUpNav('next')} />\n\n <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', background: isStudio ? bgColor : '#000', position: 'relative', width: '100%', height: '100%', overflow: 'hidden', borderRadius: '0px' }}>\n {video ? (\n <StoryVideo\n src={video}\n isActive={isCurrent}\n isAnimating={isAnimating}\n isMuted={isMuted}\n onLoadedData={handleVideoLoad}\n activeVideoRef={activeVideoRef}\n objectFit={objectFit}\n />\n ) : (\n (bgImage || currentStory?.thumbnail) && (\n <StoryThumbnail src={bgImage || currentStory?.thumbnail} alt=\"Story content\" style={{ width: '100%', height: '100%', objectFit: objectFit }} />\n )\n )}\n <InteractiveOverlay\n content={{ ...slide.content, styling: { ...(slide.content as any)?.styling, ...(slide as any)?.styling }, interactions: slide.interactions }}\n elapsedTime={(progress / 100) * (currentStory.styling?.slideShowTime || 5)}\n onInteraction={async (interactionData: any) => {\n handleOverlayInteraction(interactionData, slide);\n }}\n />\n </div>\n\n {(slideCtaTextLocal || slideCtaLinkLocal) && (\n <Cta cta={slide?.styling?.cta} buttonText={slideCtaTextLocal || 'Learn More'} onPress={(e) => { if (e && e.stopPropagation) e.stopPropagation(); handleClickCTA(slide); }} />\n )}\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Right column (desktop only) */}\n {isDesktop && (\n <div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', gap: '12px', width: '100%', boxSizing: 'border-box' }}>\n <button\n onClick={handleNextSlide}\n style={{ background: 'rgba(0,0,0,0.45)', border: '1px solid rgba(255,255,255,0.1)', color: 'white', borderRadius: '50%', width: '44px', height: '44px', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', backdropFilter: 'blur(10px)', transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)', boxShadow: '0 8px 16px rgba(0,0,0,0.3)', outline: 'none' }}\n onMouseEnter={(e) => { e.currentTarget.style.background = 'rgba(0,0,0,0.75)'; e.currentTarget.style.transform = 'scale(1.1)'; e.currentTarget.style.borderColor = 'rgba(255,255,255,0.25)'; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = 'rgba(0,0,0,0.45)'; e.currentTarget.style.transform = 'scale(1)'; e.currentTarget.style.borderColor = 'rgba(255,255,255,0.1)'; }}\n >\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </button>\n </div>\n )}\n\n </div>\n </div>\n\n {/* Previous Stories float (desktop only, viewport-relative) */}\n {isDesktop && activeStoryIndex > 0 && (\n <div style={{ position: 'absolute', bottom: '36px', left: '24px', display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: '6px', zIndex: 20 }}>\n <span style={{ fontSize: '11px', fontWeight: '600', color: 'rgba(255,255,255,0.65)', letterSpacing: '0.6px', textTransform: 'uppercase', paddingLeft: '2px' }}>Previous Stories</span>\n <div\n style={{ background: 'rgba(255, 255, 255, 0.08)', border: '1px solid rgba(255, 255, 255, 0.12)', padding: '8px 16px', borderRadius: '16px', display: 'flex', alignItems: 'center', gap: '12px', backdropFilter: 'blur(20px)', cursor: 'pointer', boxShadow: '0 10px 24px rgba(0, 0, 0, 0.3)', transition: 'all 0.25s cubic-bezier(0.4, 0, 0.2, 1)', maxWidth: '280px' }}\n onClick={() => triggerGroupTransition('prev')}\n onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-2px) scale(1.03)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.12)'; e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.25)'; }}\n onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0px) scale(1)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.08)'; e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.12)'; }}\n >\n <span style={{ color: 'white', fontSize: '14px', display: 'flex' }}>←</span>\n <div style={{ width: '36px', height: '36px', borderRadius: '50%', border: '2px solid rgba(255,255,255,0.8)', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'white', flexShrink: 0, overflow: 'hidden' }}>\n <StoryThumbnail src={stories[activeStoryIndex - 1].thumbnail} style={{ width: '100%', height: '100%', borderRadius: '50%' }} />\n </div>\n <span style={{ fontSize: '13px', color: 'white', fontWeight: '600', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0 }}>{stories[activeStoryIndex - 1].name}</span>\n </div>\n </div>\n )}\n\n {/* Next Stories float (desktop only, viewport-relative) */}\n {isDesktop && activeStoryIndex < stories.length - 1 && (\n <div style={{ position: 'absolute', bottom: '36px', right: '24px', display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: '6px', zIndex: 20 }}>\n <span style={{ fontSize: '11px', fontWeight: '600', color: 'rgba(255,255,255,0.65)', letterSpacing: '0.6px', textTransform: 'uppercase', paddingRight: '2px' }}>Next Stories</span>\n <div\n style={{ background: 'rgba(255, 255, 255, 0.08)', border: '1px solid rgba(255, 255, 255, 0.12)', padding: '8px 16px', borderRadius: '16px', display: 'flex', alignItems: 'center', gap: '12px', backdropFilter: 'blur(20px)', cursor: 'pointer', boxShadow: '0 10px 24px rgba(0, 0, 0, 0.3)', transition: 'all 0.25s cubic-bezier(0.4, 0, 0.2, 1)', maxWidth: '280px' }}\n onClick={() => triggerGroupTransition('next')}\n onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-2px) scale(1.03)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.12)'; e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.25)'; }}\n onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0px) scale(1)'; e.currentTarget.style.background = 'rgba(255, 255, 255, 0.08)'; e.currentTarget.style.borderColor = 'rgba(255, 255, 255, 0.12)'; }}\n >\n <div style={{ width: '36px', height: '36px', borderRadius: '50%', border: '2px solid rgba(255,255,255,0.8)', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'white', flexShrink: 0, overflow: 'hidden' }}>\n <StoryThumbnail src={stories[activeStoryIndex + 1].thumbnail} style={{ width: '100%', height: '100%', borderRadius: '50%' }} />\n </div>\n <span style={{ fontSize: '13px', color: 'white', fontWeight: '600', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0 }}>{stories[activeStoryIndex + 1].name}</span>\n <span style={{ color: 'white', fontSize: '14px', display: 'flex' }}>→</span>\n </div>\n </div>\n )}\n\n {/* Toast */}\n {showToast && (\n <div style={{ position: 'absolute', bottom: '40px', left: '50%', transform: 'translateX(-50%)', background: 'rgba(20, 20, 20, 0.96)', border: '1px solid rgba(255,255,255,0.08)', padding: '12px 24px', borderRadius: '12px', color: 'white', fontSize: '13px', fontWeight: '500', boxShadow: '0 10px 20px rgba(0,0,0,0.5)', backdropFilter: 'blur(10px)', zIndex: 1000 }}>\n {showToast}\n </div>\n )}\n </div>\n );\n};","export const parseColor = (val: any): string | undefined => {\n if (!val) return undefined;\n if (typeof val === 'string') return val;\n if (typeof val === 'object') {\n if (typeof val.color === 'string') return val.color;\n if (typeof val.color === 'object' && val.color) {\n const parsed = parseColor(val.color);\n if (parsed) return parsed;\n }\n if (typeof val.solid === 'string' && val.solid) return val.solid;\n if (typeof val.value === 'string' && val.value) return val.value;\n if (typeof val.hex === 'string' && val.hex) return val.hex;\n }\n return undefined;\n};\n\nexport const parseBackground = (bg: any): string | undefined => {\n if (!bg) return undefined;\n if (typeof bg === 'string') return bg;\n\n // Some payloads send colors directly without a nested `color` object.\n // Examples: { solid: '#ffffff' } or { value: '#ffffff' }\n if (typeof bg === 'object') {\n if (typeof bg.solid === 'string' && bg.solid) return bg.solid;\n if (typeof bg.value === 'string' && bg.value) return bg.value;\n if (typeof bg.color === 'string' && bg.color) return bg.color;\n }\n\n const color = bg.color || {};\n if (typeof color === 'object' && color) {\n if (color.type === 'gradient' && color.gradient) {\n const { direction = 'right', from, to, stops = [] } = color.gradient;\n const dirMap: Record<string, string> = {\n right: 'to right',\n left: 'to left',\n top: 'to top',\n bottom: 'to bottom',\n };\n const cssDir = dirMap[direction] || direction;\n\n if (stops.length > 0) {\n const stopStr = stops\n .map((s: any) => {\n const rawOffset = s.offset;\n let offsetStr = '0%';\n if (rawOffset !== undefined && rawOffset !== null) {\n const str = String(rawOffset).trim();\n if (str.endsWith('%')) {\n offsetStr = str;\n } else {\n const num = Number(str);\n if (!isNaN(num)) {\n offsetStr = num > 1 ? `${num}%` : `${Math.round(num * 100)}%`;\n }\n }\n }\n return `${s.color} ${offsetStr}`;\n })\n .join(', ');\n return `linear-gradient(${cssDir}, ${stopStr})`;\n }\n return `linear-gradient(${cssDir}, ${from}, ${to})`;\n }\n }\n\n return parseColor(bg);\n};\n\nexport const getAnimationStyles = (anim: any): string | undefined => {\n if (!anim || anim.type === 'none') return undefined;\n const type = String(anim.type).toLowerCase();\n const duration = anim.duration || 0.6;\n\n if (type === 'fade') return `appstorys-fade-in ${duration}s ease-out forwards`;\n if (type === 'classic') return `appstorys-classic-in ${duration}s cubic-bezier(0.34, 1.56, 0.64, 1) forwards`;\n if (type === 'rotate') return `appstorys-rotate-in ${duration}s ease-out forwards`;\n if (type === 'bounce') return `appstorys-bounce-in ${duration + 0.2}s cubic-bezier(0.68, -0.6, 0.32, 1.6) forwards`;\n\n return undefined;\n};\n\nexport const toCSSValue = (val: any, defaultUnit = 'px'): string => {\n if (val === undefined || val === null || val === '') return '';\n const str = String(val).trim();\n if (/^[\\d.-]+$/.test(str)) {\n return `${str}${defaultUnit}`;\n }\n return str;\n};","import React from 'react';\nimport { PollStickerData, StickerProps } from './types';\nimport { toCSSValue } from '../../../utils/styleUtils';\n\nexport const PollSticker: React.FC<StickerProps<PollStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const [selectedOptionId, setSelectedOptionId] = React.useState<string | null>(() => {\n try {\n return localStorage.getItem(`appstorys_poll_${data.id}`);\n } catch (e) {\n return null;\n }\n });\n\n const isHorizontal = data.layout?.type === 'horizontal';\n const defaults = {\n headerTextColor: '#000000',\n optionBgColor: '#1A1A1A',\n optionTextColor: '#FFFFFF',\n backgroundColor: '#FFFFFF',\n borderRadius: 24,\n padding: 20,\n };\n\n const styling = data.styling || {};\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: toCSSValue(styling.borderRadius ?? defaults.borderRadius),\n overflow: 'hidden',\n boxShadow: styling.shadow || '0 12px 24px rgba(0,0,0,0.1)',\n boxSizing: 'border-box',\n width: '100%',\n opacity: styling.opacity ?? 1,\n padding: toCSSValue(styling.padding ?? defaults.padding),\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '10px',\n };\n\n const questionStyle: React.CSSProperties = {\n color: styling.headerTextColor || defaults.headerTextColor,\n textAlign: 'center',\n fontWeight: '800',\n fontSize: typeof styling.fontSize === 'string' ? `min(${styling.fontSize}, 16px)` : `${styling.fontSize ? Math.min(Number(styling.fontSize), 16) : 15}px`,\n lineHeight: '1.25',\n margin: '0',\n width: '100%',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n };\n\n const optionsContainerStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: isHorizontal ? 'row' : 'column',\n gap: selectedOptionId && isHorizontal ? '0px' : '4px',\n width: '100%',\n backgroundColor: '#1A1A1A',\n borderRadius: '12px',\n overflow: 'hidden',\n padding: '0px',\n };\n\n const optionStyle: React.CSSProperties = {\n backgroundColor: styling.optionBgColor || 'transparent',\n color: styling.optionTextColor || defaults.optionTextColor,\n padding: isHorizontal ? '10px 8px' : '10px 14px',\n fontSize: typeof styling.fontSize === 'string' ? `min(${styling.fontSize}, 14px)` : `${styling.fontSize ? Math.min(Number(styling.fontSize), 14) : 13}px`,\n fontWeight: '700',\n cursor: selectedOptionId ? 'default' : 'pointer',\n border: 'none',\n width: '100%',\n textAlign: 'center',\n boxSizing: 'border-box',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)',\n flex: 1,\n borderRight: isHorizontal ? '1px solid rgba(255,255,255,0.1)' : 'none',\n borderBottom: !isHorizontal ? '1px solid rgba(255,255,255,0.1)' : 'none',\n position: 'relative',\n overflow: 'hidden',\n };\n\n const options = Array.isArray(data.options) ? data.options : [];\n\n const getOptionPercentage = (optionId: string) => {\n const option = options.find((o) => o.id === optionId);\n if (!option) return 0;\n if (option.percentage !== undefined) return option.percentage;\n if (option.votes !== undefined) {\n const total = options.reduce((sum, o) => sum + (o.votes || 0), 0);\n if (total > 0) return Math.round((option.votes / total) * 100);\n }\n // Fallback if we voted\n if (selectedOptionId) {\n if (optionId === selectedOptionId) {\n return options.length === 1 ? 100 : 60;\n } else {\n return Math.round(40 / (options.length - 1));\n }\n }\n return 0;\n };\n\n const hexToRgba = (hex: string, opacity: number) => {\n let cleaned = hex.replace('#', '');\n if (cleaned.length === 3) {\n cleaned = cleaned.split('').map(char => char + char).join('');\n }\n const r = parseInt(cleaned.substring(0, 2), 16) || 0;\n const g = parseInt(cleaned.substring(2, 4), 16) || 0;\n const b = parseInt(cleaned.substring(4, 6), 16) || 0;\n return `rgba(${r}, ${g}, ${b}, ${opacity})`;\n };\n\n const getFillColor = (optionId: string) => {\n const isActive = optionId === selectedOptionId;\n const colorObj = isActive ? styling.activeResultBarColor : styling.inactiveResultBarColor;\n const color = colorObj?.color || (isActive ? '#F97316' : '#404040');\n const opacity = colorObj?.opacity !== undefined ? colorObj.opacity / 100 : 1;\n if (color.startsWith('#') && (color.length === 7 || color.length === 4)) {\n return hexToRgba(color, opacity);\n }\n return color;\n };\n\n const handleOptionClick = (optionId: string) => {\n if (isEditing || selectedOptionId) return;\n setSelectedOptionId(optionId);\n try {\n localStorage.setItem(`appstorys_poll_${data.id}`, optionId);\n } catch (e) {}\n onInteraction?.({\n type: 'poll',\n pollId: data.id,\n optionId: optionId,\n stickerId: data.id\n });\n };\n\n return (\n <div style={containerStyle}>\n <h3 style={questionStyle}>{data.question || 'Ask A Question...'}</h3>\n <div style={optionsContainerStyle}>\n {options.map((option, index) => {\n const percentage = getOptionPercentage(option.id);\n const isVoted = selectedOptionId !== null;\n const isActive = option.id === selectedOptionId;\n\n const buttonBgColor = isVoted\n ? (isHorizontal ? getFillColor(option.id) : (styling.optionBgColor || 'transparent'))\n : (styling.optionBgColor || 'transparent');\n\n return (\n <button\n key={option.id}\n style={{\n ...optionStyle,\n flex: isVoted && isHorizontal ? percentage : 1,\n backgroundColor: buttonBgColor,\n borderRight: isVoted\n ? 'none'\n : (isHorizontal && index === options.length - 1 ? 'none' : optionStyle.borderRight),\n borderBottom: isVoted\n ? 'none'\n : (!isHorizontal && index === options.length - 1 ? 'none' : optionStyle.borderBottom),\n }}\n onClick={() => handleOptionClick(option.id)}\n disabled={isVoted}\n onMouseOver={(e) => {\n if (!isEditing && !isVoted) e.currentTarget.style.backgroundColor = 'rgba(255,255,255,0.1)';\n }}\n onMouseOut={(e) => {\n if (!isEditing && !isVoted) e.currentTarget.style.backgroundColor = styling.optionBgColor || 'transparent';\n }}\n >\n {isVoted && !isHorizontal && (\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n bottom: 0,\n width: `${percentage}%`,\n backgroundColor: getFillColor(option.id),\n transition: 'width 0.6s cubic-bezier(0.4, 0, 0.2, 1)',\n zIndex: 1\n }} />\n )}\n <div style={{\n display: 'flex',\n flexDirection: isHorizontal ? 'column' : 'row',\n justifyContent: isHorizontal ? 'center' : 'space-between',\n alignItems: 'center',\n width: '100%',\n zIndex: 2,\n position: 'relative'\n }}>\n <span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{option.text}</span>\n {isVoted && (\n <span style={{\n fontWeight: '800',\n fontSize: isHorizontal ? '12px' : '15px',\n marginTop: isHorizontal ? '4px' : '0'\n }}>\n {percentage}%\n </span>\n )}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n );\n};","import React, { useState } from 'react';\nimport { QuizStickerData, StickerProps } from './types';\nimport { toCSSValue } from '../../../utils/styleUtils';\n\nexport const QuizSticker: React.FC<StickerProps<QuizStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const [selectedOptionId, setSelectedOptionId] = useState<string | null>(() => {\n try {\n return localStorage.getItem(`appstorys_quiz_${data.id}`);\n } catch (e) {\n return null;\n }\n });\n\n const defaults = {\n backgroundColor: '#FFFFFF',\n borderRadius: 20,\n padding: 16,\n questionTextColor: '#FFFFFF', // Changed from #111111 to white for black header\n questionBgColor: '#000000',\n optionBgColor: '#FFFFFF',\n optionTextColor: '#2B2B2B',\n borderColor: '#E5E7EB',\n activeColor: '#10b981', // Success Green\n incorrectColor: '#ef4444', // Error Red\n labelBgColor: '#FFFFFF',\n labelTextColor: '#111111',\n labelBorderColor: '#111111',\n };\n\n const styling = (data as any).styling || {};\n const cardPadding = toCSSValue(styling.padding ?? defaults.padding);\n \n const isFontSizeString = typeof styling.fontSize === 'string';\n const questionFontSize = isFontSizeString ? `min(${styling.fontSize}, 16px)` : `${styling.fontSize ? Math.min(Number(styling.fontSize), 16) : 15}px`;\n \n const isOptionFontSizeString = typeof styling.optionFontSize === 'string';\n const optionFontSize = toCSSValue(styling.optionFontSize || 13);\n \n const optionRadius = toCSSValue(styling.optionBorderRadius || 14);\n const borderColor = styling.borderColor || defaults.borderColor;\n\n const labelSizeCSS = isOptionFontSizeString \n ? `max(min(calc(${optionFontSize} * 1.8), 24px), 16px)` \n : `${Math.min(Math.max(Math.round(Number(styling.optionFontSize || 13) * 1.8), 16), 24)}px`;\n\n const labelBorderWidthCSS = isOptionFontSizeString\n ? `max(calc(${labelSizeCSS} * 0.08), 1px)`\n : `${Math.max(Math.round(Number(labelSizeCSS.replace('px', '')) * 0.08), 1)}px`;\n\n const labelFontSizeCSS = isOptionFontSizeString\n ? `max(calc(${labelSizeCSS} * 0.46), 10px)`\n : `${Math.max(Math.round(Number(labelSizeCSS.replace('px', '')) * 0.46), 10)}px`;\n\n const optionGapCSS = isOptionFontSizeString\n ? `max(calc(${labelSizeCSS} * 0.45), 8px)`\n : `${Math.max(Math.round(Number(labelSizeCSS.replace('px', '')) * 0.45), 8)}px`;\n\n const optionPaddingCSS = isOptionFontSizeString\n ? `calc(${cardPadding} * 0.6) calc(${cardPadding} * 0.7)`\n : `11px 14px`;\n\n const bodyGapCSS = isOptionFontSizeString\n ? `max(calc(${cardPadding} * 0.45), 8px)`\n : `8px`;\n\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: toCSSValue(styling.borderRadius ?? defaults.borderRadius),\n padding: cardPadding,\n paddingTop: 0, // Header will handle its own top padding\n paddingBottom: '12px',\n boxShadow: styling.shadow || '0 10px 30px rgba(0,0,0,0.12)',\n boxSizing: 'border-box',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden', // Ensure header doesn't bleed\n opacity: styling.opacity ?? 1,\n };\n\n const questionStyle: React.CSSProperties = {\n color: styling.questionTextColor || defaults.questionTextColor,\n backgroundColor: styling.questionBgColor || defaults.questionBgColor,\n fontWeight: '900',\n fontSize: questionFontSize,\n lineHeight: 1.25,\n margin: `0 calc(-1 * ${cardPadding}) 12px calc(-1 * ${cardPadding})`, // Flush edges\n textAlign: 'center',\n padding: `16px ${cardPadding}`,\n borderTopLeftRadius: toCSSValue(styling.borderRadius ?? defaults.borderRadius),\n borderTopRightRadius: toCSSValue(styling.borderRadius ?? defaults.borderRadius),\n letterSpacing: '-0.01em',\n };\n\n const optionStyle: React.CSSProperties = {\n backgroundColor: styling.optionBgColor || defaults.optionBgColor,\n color: styling.optionTextColor || defaults.optionTextColor,\n padding: optionPaddingCSS,\n borderRadius: optionRadius,\n border: `1px solid ${borderColor}`,\n display: 'flex',\n alignItems: 'center',\n gap: optionGapCSS,\n cursor: selectedOptionId ? 'default' : 'pointer',\n width: '100%',\n textAlign: 'left',\n boxSizing: 'border-box',\n transition: 'all 0.2s ease',\n boxShadow: '0 1px 2px rgba(15,23,42,0.03)',\n };\n\n const labelStyle: React.CSSProperties = {\n width: labelSizeCSS,\n height: labelSizeCSS,\n minWidth: labelSizeCSS,\n borderRadius: '50%',\n backgroundColor: styling.labelBgColor || defaults.labelBgColor,\n color: styling.labelTextColor || defaults.labelTextColor,\n border: `${labelBorderWidthCSS} solid ${styling.labelBorderColor || defaults.labelBorderColor}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontWeight: '700',\n fontSize: labelFontSizeCSS,\n };\n\n const bodyStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: `0 0 ${toCSSValue(styling.borderRadius ?? defaults.borderRadius)} ${toCSSValue(styling.borderRadius ?? defaults.borderRadius)}`,\n display: 'flex',\n flexDirection: 'column',\n gap: bodyGapCSS,\n };\n\n const handleOptionClick = (optionId: string) => {\n if (isEditing || selectedOptionId) return; // ignore multiple clicks\n setSelectedOptionId(optionId);\n try {\n localStorage.setItem(`appstorys_quiz_${data.id}`, optionId);\n } catch (e) {}\n onInteraction?.({\n type: 'quiz',\n quizId: data.id,\n optionId: optionId,\n stickerId: data.id\n });\n };\n\n const alphabet = ['A', 'B', 'C', 'D', 'E', 'F'];\n const options = Array.isArray(data.options) ? data.options : [];\n\n if (options.length === 0 && !isEditing) {\n console.warn('AppStorys: QuizSticker has no options!', data.id);\n }\n\n return (\n <div style={{ ...containerStyle, background: styling.backgroundColor || defaults.backgroundColor }}>\n {data.question && <h3 style={questionStyle}>{data.question}</h3>}\n <div style={{ ...bodyStyle, background: 'transparent' }}>\n {options.map((option, index) => {\n const label = (option as any).label || alphabet[index] || '•';\n const isSelected = option.id === selectedOptionId;\n const isCorrect = (option as any).isCorrect === true;\n\n let currentOptionStyle = { ...optionStyle };\n let currentLabelStyle = { ...labelStyle };\n\n if (selectedOptionId) {\n if (isCorrect) {\n currentOptionStyle.backgroundColor = styling.activeColor || defaults.activeColor;\n currentOptionStyle.borderColor = styling.activeColor || defaults.activeColor;\n currentOptionStyle.color = '#FFFFFF';\n } else if (isSelected) {\n currentOptionStyle.backgroundColor = styling.incorrectColor || defaults.incorrectColor;\n currentOptionStyle.borderColor = styling.incorrectColor || defaults.incorrectColor;\n currentOptionStyle.color = '#FFFFFF';\n }\n }\n\n return (\n <button\n key={option.id}\n style={currentOptionStyle}\n onClick={() => handleOptionClick(option.id)}\n disabled={!!selectedOptionId}\n >\n <div style={labelStyle} className=\"letter-circle\">{label}</div>\n <span style={{ fontWeight: '600', fontSize: optionFontSize }}>{option.text}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n};","import React, { useState, useEffect } from 'react';\nimport { CountdownStickerData, StickerProps } from './types';\nimport { toCSSValue } from '../../../utils/styleUtils';\n\nexport const CountdownSticker: React.FC<StickerProps<CountdownStickerData>> = ({\n data,\n}) => {\n const [timeLeft, setTimeLeft] = useState({ days: '00', hours: '00', minutes: '00', seconds: '00' });\n\n useEffect(() => {\n if (!data.targetDate) return;\n\n const calculateTime = () => {\n const difference = +new Date(data.targetDate) - +new Date();\n if (difference > 0) {\n const days = Math.floor(difference / (1000 * 60 * 60 * 24));\n const hours = Math.floor((difference / (1000 * 60 * 60)) % 24);\n const minutes = Math.floor((difference / 1000 / 60) % 60);\n const seconds = Math.floor((difference / 1000) % 60);\n\n setTimeLeft({\n days: days.toString().padStart(2, '0'),\n hours: hours.toString().padStart(2, '0'),\n minutes: minutes.toString().padStart(2, '0'),\n seconds: seconds.toString().padStart(2, '0')\n });\n } else {\n setTimeLeft({ days: '00', hours: '00', minutes: '00', seconds: '00' });\n }\n };\n\n const timer = setInterval(calculateTime, 1000);\n calculateTime(); \n return () => clearInterval(timer);\n }, [data.targetDate]);\n\n const styling = data.styling || {};\n const display = data.display || { showDays: true, showHours: true, showMinutes: true, showSeconds: true };\n\n const rawDigitSize = styling.digitSize || styling.fontSize;\n const isDigitSizeString = typeof rawDigitSize === 'string';\n\n const digitSizeCSS = isDigitSizeString ? rawDigitSize : `${!isNaN(Number(rawDigitSize)) && Number(rawDigitSize) > 0 ? Number(rawDigitSize) : 18}px`;\n const labelFontSizeCSS = (styling as any).labelFontSize \n ? toCSSValue((styling as any).labelFontSize) \n : (isDigitSizeString ? `calc(${digitSizeCSS} * 0.45)` : `${Math.max(10, Math.round(Number(rawDigitSize || 18) * 0.45))}px`);\n const boxHeightCSS = isDigitSizeString ? `calc(${digitSizeCSS} * 1.65)` : `${Math.max(36, Math.round(Number(rawDigitSize || 18) * 1.65))}px`;\n const boxMinWidthCSS = isDigitSizeString ? `calc(${digitSizeCSS} * 0.95)` : `${Math.max(26, Math.round(Number(rawDigitSize || 18) * 0.95))}px`;\n const boxRadiusCSS = isDigitSizeString ? `calc(${digitSizeCSS} * 0.25)` : `${Math.max(6, Math.round(Number(rawDigitSize || 18) * 0.25))}px`;\n const gridGapCSS = isDigitSizeString ? `calc(${digitSizeCSS} * 0.15)` : `${Math.max(6, Math.round(Number(rawDigitSize || 18) * 0.15))}px`;\n const separatorSizeCSS = isDigitSizeString ? `calc(${digitSizeCSS} * 0.75)` : `${Math.max(14, Math.round(Number(rawDigitSize || 18) * 0.75))}px`;\n\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || '#FFFFFF',\n borderRadius: toCSSValue(styling.borderRadius !== undefined ? styling.borderRadius : 16),\n padding: styling.padding ? toCSSValue(styling.padding) : '16px 18px',\n boxShadow: styling.shadow || '0 10px 30px rgba(0,0,0,0.08)',\n width: '100%',\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '10px',\n border: styling.borderColor ? `1px solid ${styling.borderColor}` : 'none',\n overflow: 'hidden',\n opacity: styling.opacity ?? 1,\n };\n\n const titleStyle: React.CSSProperties = {\n color: styling.titleColor || '#000000',\n fontWeight: '700',\n fontSize: toCSSValue(styling.fontSize || 14),\n width: '100%',\n textAlign: 'center',\n marginBottom: '4px'\n };\n\n const timerGridStyle: React.CSSProperties = {\n display: 'flex',\n gap: gridGapCSS,\n width: '100%',\n justifyContent: 'center',\n alignItems: 'center',\n flexWrap: 'nowrap'\n };\n\n const segmentStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '2px'\n };\n\n const digitGroupStyle: React.CSSProperties = {\n display: 'flex',\n gap: '2px'\n };\n\n const boxStyle: React.CSSProperties = {\n backgroundColor: styling.digitBackground || '#F1F3F5',\n borderRadius: boxRadiusCSS,\n minWidth: boxMinWidthCSS,\n height: boxHeightCSS,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: digitSizeCSS,\n fontWeight: 'bold',\n color: styling.digitColor || '#1A202C',\n padding: '0 4px',\n };\n\n const labelStyle: React.CSSProperties = {\n fontSize: isDigitSizeString ? labelFontSizeCSS : `${Math.max(9, Number(String(labelFontSizeCSS).replace('px', '')))}px`,\n color: styling.labelColor || '#A0AEC0',\n fontWeight: '600',\n textTransform: 'lowercase'\n };\n\n const separatorStyle: React.CSSProperties = {\n fontSize: separatorSizeCSS,\n fontWeight: '700',\n color: styling.labelColor || '#A0AEC0',\n display: 'flex',\n alignItems: 'center',\n lineHeight: 1,\n };\n\n const renderDigitGroup = (value: string, label: string) => (\n <div style={segmentStyle}>\n <div style={digitGroupStyle}>\n {value.split('').map((digit, i) => (\n <div key={i} style={boxStyle}>{digit}</div>\n ))}\n </div>\n <span style={labelStyle}>{label}</span>\n </div>\n );\n\n // Build items based on display configuration\n const items: React.ReactNode[] = [];\n let shownCount = 0;\n\n if (display.showDays !== false) {\n items.push(renderDigitGroup(timeLeft.days, 'days'));\n shownCount++;\n }\n \n if (display.showHours !== false) {\n if (shownCount > 0) items.push(<div key=\"sep-h\" style={separatorStyle}>:</div>);\n items.push(renderDigitGroup(timeLeft.hours, 'hours'));\n shownCount++;\n }\n \n if (display.showMinutes !== false) {\n if (shownCount > 0) items.push(<div key=\"sep-m\" style={separatorStyle}>:</div>);\n items.push(renderDigitGroup(timeLeft.minutes, 'minutes'));\n shownCount++;\n }\n \n if (display.showSeconds !== false) {\n if (shownCount > 0) items.push(<div key=\"sep-s\" style={separatorStyle}>:</div>);\n items.push(renderDigitGroup(timeLeft.seconds, 'seconds'));\n shownCount++;\n }\n\n return (\n <div style={containerStyle}>\n {data.title && <div style={titleStyle}>{data.title}</div>}\n <div style={timerGridStyle}>\n {items}\n </div>\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { PromoCodeStickerData, StickerProps } from './types';\n\nexport const PromoCodeSticker: React.FC<StickerProps<PromoCodeStickerData>> = ({\n data,\n onInteraction,\n}) => {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (data.code) {\n navigator.clipboard.writeText(data.code).catch(() => { });\n setCopied(true);\n\n // Trigger interaction event via capture-event\n onInteraction?.({\n type: 'promo_code',\n value: 'copied',\n stickerId: data.id,\n code: data.code\n });\n\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n const styling = data.styling || {};\n const bgColor = styling.backgroundColor || '#F4F4F6';\n\n const ticketPillStyle: React.CSSProperties = {\n backgroundColor: bgColor,\n padding: '8px 16px',\n borderRadius: '12px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n minHeight: '44px',\n boxSizing: 'border-box',\n position: 'relative',\n boxShadow: styling.shadow || '0 4px 16px rgba(0,0,0,0.08)',\n cursor: 'pointer',\n WebkitMaskImage: 'radial-gradient(circle at 0px 50%, transparent 6px, black 6.5px), radial-gradient(circle at 100% 50%, transparent 6px, black 6.5px)',\n maskImage: 'radial-gradient(circle at 0px 50%, transparent 6px, black 6.5px), radial-gradient(circle at 100% 50%, transparent 6px, black 6.5px)',\n WebkitMaskComposite: 'destination-in',\n maskComposite: 'intersect',\n };\n\n const percentageBoxStyle: React.CSSProperties = {\n width: '26px',\n height: '26px',\n borderRadius: '6px',\n backgroundColor: '#FFFFFF',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '13px',\n fontWeight: '900',\n color: '#000000',\n border: '1.8px solid #000000',\n flexShrink: 0,\n };\n\n const codeStyle: React.CSSProperties = {\n fontSize: '13px',\n fontWeight: '700',\n color: copied ? '#10B981' : '#000000',\n fontFamily: '\"SF Mono\", \"Roboto Mono\", Menlo, Consolas, \"Courier New\", monospace',\n letterSpacing: '0.5px',\n textAlign: 'center',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n display: 'block',\n width: '100%',\n transition: 'color 0.2s ease',\n };\n\n return (\n <div style={ticketPillStyle} onClick={handleCopy}>\n {/* Column 1: Percentage Box */}\n <div style={percentageBoxStyle}>%</div>\n\n {/* Column 2: Code Text (strictly bounded in center) */}\n <div style={{ flex: 1, minWidth: 0, padding: '0 8px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <span style={codeStyle}>\n {copied ? 'Copied!' : (data.code || 'OFFER20')}\n </span>\n </div>\n\n {/* Column 3: Copy Icon with vertical dashed break border on left */}\n <div style={{ flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', borderLeft: '1.5px dashed rgba(0,0,0,0.2)', paddingLeft: '10px', marginLeft: '4px', height: '24px' }}>\n {copied ? (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#10B981\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\"></polyline>\n </svg>\n ) : (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <rect x=\"8\" y=\"8\" width=\"12\" height=\"12\" rx=\"2.5\" stroke=\"#000000\" strokeWidth=\"2\" fill=\"none\" />\n <rect x=\"4\" y=\"4\" width=\"12\" height=\"12\" rx=\"2.5\" stroke=\"#000000\" strokeWidth=\"2\" fill=\"none\" />\n </svg>\n )}\n </div>\n </div>\n );\n};\n","import React, { useState, useEffect } from 'react';\nimport { ReactionStickerData, StickerProps } from './types';\n\nexport const ReactionSticker: React.FC<StickerProps<ReactionStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const defaults = {\n emojis: ['😍', '👍'],\n };\n\n const emojis = Array.isArray(data.emojis) ? data.emojis : (Array.isArray(defaults.emojis) ? defaults.emojis : []);\n\n const [hasVoted, setHasVoted] = useState(() => {\n try {\n return localStorage.getItem(`appstorys_reaction_${data.id}`) !== null;\n } catch (e) {\n return false;\n }\n });\n const [counts, setCounts] = useState<Record<string, number>>({});\n\n useEffect(() => {\n const initialCounts: Record<string, number> = {};\n const savedEmoji = (() => {\n try {\n return localStorage.getItem(`appstorys_reaction_${data.id}`);\n } catch (e) {\n return null;\n }\n })();\n\n emojis.forEach((emoji) => {\n let baseCount = Math.random() > 0.5 ? 1999 : 2000;\n if (savedEmoji && emoji === savedEmoji) {\n baseCount += 1;\n }\n initialCounts[emoji] = baseCount;\n });\n setCounts(initialCounts);\n }, [data.emojis]);\n\n const handleReactionClick = (emoji: string, index: number) => {\n if (isEditing || hasVoted) return;\n\n setCounts((prev) => ({\n ...prev,\n [emoji]: (prev[emoji] || 0) + 1,\n }));\n setHasVoted(true);\n try {\n localStorage.setItem(`appstorys_reaction_${data.id}`, emoji);\n } catch (e) {}\n\n onInteraction?.({\n type: 'reaction',\n reactionId: data.id,\n optionId: `option${index + 1}`,\n selected_option: `option${index + 1}`,\n emoji: emoji,\n stickerId: data.id,\n });\n };\n\n const formatCount = (num: number): string => {\n if (num >= 1000) {\n return (num / 1000).toFixed(0) + 'k';\n }\n return String(num);\n };\n\n const containerStyle: React.CSSProperties = {\n display: 'flex',\n gap: '12px',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n padding: '12px',\n boxSizing: 'border-box',\n };\n\n const bubbleStyle: React.CSSProperties = {\n backgroundColor: '#FFFFFF',\n width: '60px',\n height: hasVoted ? '90px' : '60px',\n borderRadius: '100px',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: hasVoted ? 'space-between' : 'center',\n padding: hasVoted ? '10px 0' : '0',\n boxShadow: '0 8px 30px rgba(0,0,0,0.12)',\n cursor: isEditing || hasVoted ? 'default' : 'pointer',\n border: 'none',\n outline: 'none',\n position: 'relative',\n zIndex: 1,\n boxSizing: 'border-box',\n flexShrink: 0,\n };\n\n const emojiStyle: React.CSSProperties = {\n fontSize: '35px',\n lineHeight: '1',\n userSelect: 'none',\n };\n\n const countStyle: React.CSSProperties = {\n fontSize: '13px',\n fontWeight: '800',\n color: '#374151',\n animation: 'appstorys-reaction-fade-in 0.3s ease forwards',\n lineHeight: '1',\n userSelect: 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n };\n\n return (\n <div style={containerStyle}>\n <style>{`\n @keyframes appstorys-reaction-fade-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .appstorys-reaction-btn {\n transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) !important;\n }\n .appstorys-reaction-btn:not(.voted):not(.editing):hover {\n transform: scale(1.15) translateY(-4px) !important;\n }\n .appstorys-reaction-btn.voted {\n transform: scale(1) translateY(0) !important;\n }\n `}</style>\n {emojis.map((emoji, idx) => {\n const countVal = counts[emoji] || 2000;\n return (\n <button\n key={idx}\n className={`appstorys-reaction-btn ${hasVoted ? 'voted' : ''} ${isEditing ? 'editing' : ''}`}\n style={bubbleStyle}\n onClick={() => handleReactionClick(emoji, idx)}\n >\n <span style={emojiStyle}>{emoji}</span>\n {hasVoted && <span style={countStyle}>{formatCount(countVal)}</span>}\n </button>\n );\n })}\n </div>\n );\n};","import React, { useState, useRef, useEffect } from 'react';\nimport { RatingStickerData, StickerProps } from './types';\nimport { toCSSValue } from '../../../utils/styleUtils';\n\nexport const RatingSticker: React.FC<StickerProps<RatingStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const maxRating = data.maxRating || 5;\n const currentRating = data.currentRating ?? Math.floor(maxRating / 2);\n const [val, setVal] = useState(() => {\n try {\n const saved = localStorage.getItem(`appstorys_rating_${data.id}`);\n return saved ? Number(saved) : currentRating;\n } catch (e) {\n return currentRating;\n }\n });\n const sliderTrackRef = useRef<HTMLDivElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n const [hasSelected, setHasSelected] = useState(() => {\n try {\n return localStorage.getItem(`appstorys_rating_${data.id}`) !== null;\n } catch (e) {\n return false;\n }\n });\n const [particles, setParticles] = useState<{ id: number; scale: number; angle: number; delay: number }[]>([]);\n\n const defaults = {\n backgroundColor: '#FFFFFF',\n borderRadius: 20,\n padding: 14,\n titleColor: '#000000',\n titleFontSize: 15,\n sliderTrackColor: '#F3F4F6',\n sliderFillColor: '#F97316',\n emojiSize: 32,\n };\n\n const styling = data.styling || {};\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: toCSSValue(styling.borderRadius ?? defaults.borderRadius),\n padding: styling.padding ? toCSSValue(styling.padding) : '12px 14px',\n boxShadow: styling.shadow || '0 10px 24px rgba(0,0,0,0.08)',\n boxSizing: 'border-box',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '8px',\n cursor: 'default',\n opacity: styling.opacity ?? 1,\n };\n\n const titleStyle: React.CSSProperties = {\n color: styling.titleColor || defaults.titleColor,\n fontWeight: '700',\n fontSize: typeof styling.titleFontSize === 'string'\n ? `min(${styling.titleFontSize}, 16px)`\n : `${styling.titleFontSize ? Math.min(Number(styling.titleFontSize), 16) : 15}px`,\n margin: '0',\n textAlign: 'center',\n lineHeight: '1.25',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n width: '100%',\n };\n\n const trackStyle: React.CSSProperties = {\n width: '100%',\n height: '16px',\n backgroundColor: styling.sliderTrackColor || defaults.sliderTrackColor,\n borderRadius: '100px',\n position: 'relative',\n cursor: isEditing || hasSelected ? 'default' : 'pointer',\n marginTop: '4px',\n marginBottom: '2px',\n userSelect: 'none',\n };\n\n const percentage = (val / maxRating) * 100;\n\n const fillStyle: React.CSSProperties = {\n width: `${percentage}%`,\n height: '100%',\n background: styling.sliderFillColor || 'linear-gradient(90deg, #FF4582, #e11d48)',\n borderRadius: '100px',\n transition: isDragging ? 'none' : 'width 0.1s ease',\n };\n\n const emojiSize = styling.emojiSize || defaults.emojiSize;\n const isEmojiSizeString = typeof emojiSize === 'string';\n const emojiSizeCSS = toCSSValue(emojiSize);\n\n const thumbStyle: React.CSSProperties = {\n position: 'absolute',\n left: isEmojiSizeString \n ? `calc(${percentage}% - calc(${emojiSizeCSS} / 2))`\n : `calc(${percentage}% - ${Number(emojiSize) / 2}px)`,\n top: isEmojiSizeString\n ? `calc(50% - calc(${emojiSizeCSS} / 2))`\n : `calc(50% - ${Number(emojiSize) / 2}px)`,\n fontSize: emojiSizeCSS,\n lineHeight: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n userSelect: 'none',\n cursor: hasSelected || isEditing ? 'default' : 'grab',\n transition: isDragging ? 'none' : 'left 0.1s ease',\n filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.2))',\n animation: hasSelected ? 'thumbPop 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards' : 'none',\n };\n\n const handleDrag = (clientX: number) => {\n if (!sliderTrackRef.current || isEditing || hasSelected) return;\n const rect = sliderTrackRef.current.getBoundingClientRect();\n let offsetX = clientX - rect.left;\n if (offsetX < 0) offsetX = 0;\n if (offsetX > rect.width) offsetX = rect.width;\n\n const ratio = offsetX / rect.width;\n const computedVal = Math.round(ratio * maxRating * 10) / 10;\n setVal(computedVal);\n };\n\n const onMouseDown = (e: React.MouseEvent) => {\n if (isEditing || hasSelected) return;\n setIsDragging(true);\n handleDrag(e.clientX);\n };\n\n const onTouchStart = (e: React.TouchEvent) => {\n if (isEditing || hasSelected) return;\n setIsDragging(true);\n handleDrag(e.touches[0].clientX);\n };\n\n const triggerConfetti = () => {\n const newParticles = Array.from({ length: 16 }).map((_, i) => ({\n id: Date.now() + i,\n scale: 0.5 + Math.random() * 0.8,\n angle: (i * (360 / 16)) + (Math.random() * 15 - 7.5),\n delay: Math.random() * 0.1,\n }));\n setParticles(newParticles);\n setTimeout(() => {\n setParticles([]);\n }, 1200);\n };\n\n useEffect(() => {\n const onMouseMove = (e: MouseEvent) => {\n if (isDragging) handleDrag(e.clientX);\n };\n\n const onMouseUp = () => {\n if (isDragging) {\n setIsDragging(false);\n setHasSelected(true);\n try {\n localStorage.setItem(`appstorys_rating_${data.id}`, String(val));\n } catch (e) {}\n triggerConfetti();\n onInteraction?.({\n type: 'rating',\n ratingId: data.id,\n value: val,\n stickerId: data.id\n });\n }\n };\n\n const onTouchMove = (e: TouchEvent) => {\n if (isDragging) handleDrag(e.touches[0].clientX);\n };\n\n if (isDragging) {\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('mouseup', onMouseUp);\n window.addEventListener('touchmove', onTouchMove);\n window.addEventListener('touchend', onMouseUp);\n }\n\n return () => {\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('mouseup', onMouseUp);\n window.removeEventListener('touchmove', onTouchMove);\n window.removeEventListener('touchend', onMouseUp);\n };\n }, [isDragging, val]);\n\n return (\n <div style={containerStyle}>\n <style>{`\n @keyframes emojiBurst {\n 0% {\n transform: translate(0, 0) scale(0.3);\n opacity: 1;\n }\n 90% {\n opacity: 0.9;\n }\n 100% {\n transform: translate(var(--tx), var(--ty)) scale(var(--scale));\n opacity: 0;\n }\n }\n @keyframes thumbPop {\n 0% { transform: scale(1); }\n 50% { transform: scale(1.3); }\n 100% { transform: scale(1); }\n }\n `}</style>\n <h3 style={titleStyle}>{data.title || 'Do you like my space?'}</h3>\n <div\n ref={sliderTrackRef}\n style={trackStyle}\n onMouseDown={onMouseDown}\n onTouchStart={onTouchStart}\n >\n <div style={fillStyle} />\n <div style={thumbStyle} className=\"interactive-emoji-thumb\">\n {data.emoji || '😍'}\n {particles.map((particle) => {\n const distance = 60 + Math.random() * 80;\n const radian = (particle.angle * Math.PI) / 180;\n const tx = `${Math.cos(radian) * distance}px`;\n const ty = `${Math.sin(radian) * distance}px`;\n return (\n <span\n key={particle.id}\n style={{\n position: 'absolute',\n left: '50%',\n top: '50%',\n width: '30px',\n height: '30px',\n marginLeft: '-15px',\n marginTop: '-15px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '24px',\n pointerEvents: 'none',\n zIndex: 100,\n animation: `emojiBurst 1s cubic-bezier(0.15, 0.85, 0.35, 1) ${particle.delay}s forwards`,\n // @ts-ignore\n '--tx': tx,\n '--ty': ty,\n '--scale': particle.scale,\n }}\n >\n {data.emoji || '😍'}\n </span>\n );\n })}\n </div>\n </div>\n </div>\n );\n};","import React, { useState } from 'react';\nimport { QuestionStickerData, StickerProps } from './types';\nimport { toCSSValue } from '../../../utils/styleUtils';\n\nexport const QuestionSticker: React.FC<StickerProps<QuestionStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const [value, setValue] = useState(() => {\n try {\n return localStorage.getItem(`appstorys_question_${data.id}`) || '';\n } catch (e) {\n return '';\n }\n });\n const [hasSubmitted, setHasSubmitted] = useState(() => {\n try {\n return localStorage.getItem(`appstorys_question_${data.id}`) !== null;\n } catch (e) {\n return false;\n }\n });\n\n const defaults = {\n backgroundColor: '#FFFFFF',\n borderRadius: 16,\n padding: 16,\n promptColor: '#111111',\n inputBgColor: '#FFFFFF',\n borderColor: '#EFEFEF',\n textColor: '#333333',\n placeholderColor: '#A0AEC0',\n };\n\n const styling = data.styling || {};\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: toCSSValue(styling.borderRadius ?? defaults.borderRadius),\n padding: styling.padding ? toCSSValue(styling.padding) : '15px 16px',\n boxShadow: styling.shadow || '0 8px 24px rgba(0,0,0,0.06)',\n boxSizing: 'border-box',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '10px',\n border: `1px solid ${styling.borderColor || '#F0F0F0'}`,\n };\n\n const questionStyle: React.CSSProperties = {\n color: styling.promptColor || defaults.promptColor,\n fontWeight: '700',\n fontSize: typeof styling.fontSize === 'string' ? `min(${styling.fontSize}, 16px)` : `${styling.fontSize ? Math.min(Number(styling.fontSize), 16) : 15}px`,\n textAlign: 'center',\n marginBottom: '2px',\n width: '100%',\n };\n\n const inputContainerStyle: React.CSSProperties = {\n width: '100%',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n };\n\n const inputStyle: React.CSSProperties = {\n backgroundColor: styling.inputBgColor || '#F1F3F5',\n border: 'none',\n borderRadius: '30px',\n padding: '12px 42px 12px 16px',\n width: '100%',\n boxSizing: 'border-box',\n color: styling.inputTextColor || '#1A202C',\n fontSize: '13px',\n outline: 'none',\n textAlign: 'left',\n cursor: isEditing ? 'default' : 'text',\n boxShadow: 'inset 0 1px 2px rgba(0,0,0,0.05)',\n };\n\n const sendButtonStyle: React.CSSProperties = {\n position: 'absolute',\n right: '10px',\n background: styling.submitBackground || '#FE6B35',\n color: 'white',\n border: 'none',\n borderRadius: '50%',\n width: '32px',\n height: '32px',\n display: value.length > 0 && !hasSubmitted ? 'flex' : 'none',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'transform 0.2s',\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (isEditing || hasSubmitted) return;\n setValue(e.target.value);\n };\n\n const handleSend = () => {\n if (isEditing || !value.trim() || hasSubmitted) return;\n setHasSubmitted(true);\n try {\n localStorage.setItem(`appstorys_question_${data.id}`, value.trim());\n } catch (e) {}\n onInteraction?.({\n type: 'question',\n questionId: data.id,\n value: value.trim(),\n stickerId: data.id\n });\n };\n\n return (\n <div style={containerStyle}>\n <div style={questionStyle}>{data.question || 'Ask me anything'}</div>\n <div style={inputContainerStyle}>\n <input\n type=\"text\"\n value={value}\n placeholder={hasSubmitted ? 'Submitted!' : (data.placeholder || 'Type your answer...')}\n style={inputStyle}\n disabled={isEditing || hasSubmitted}\n onChange={handleChange}\n onKeyDown={(e) => e.key === 'Enter' && handleSend()}\n />\n <button style={sendButtonStyle} onClick={handleSend}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </div>\n </div>\n );\n};","import React, { useState } from 'react';\nimport { ImageQuizStickerData, StickerProps } from './types';\nimport { toCSSValue } from '../../../utils/styleUtils';\n\nexport const ImageQuizSticker: React.FC<StickerProps<ImageQuizStickerData>> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const [selectedOptionId, setSelectedOptionId] = useState<string | null>(() => {\n try {\n return localStorage.getItem(`appstorys_image_quiz_${data.id}`);\n } catch (e) {\n return null;\n }\n });\n\n const defaults = {\n backgroundColor: '#FFFFFF',\n borderRadius: 20,\n padding: 16,\n questionTextColor: '#111111',\n optionBgColor: '#F7FAFC',\n optionTextColor: '#2D3748',\n borderColor: '#E2E8F0',\n activeColor: '#10B981', // Success Green\n incorrectColor: '#EF4444', // Error Red\n };\n\n const styling = (data as any).styling || {};\n const paddingCSS = toCSSValue(styling.padding ?? defaults.padding);\n const borderRadiusCSS = toCSSValue(styling.borderRadius ?? defaults.borderRadius);\n\n const containerStyle: React.CSSProperties = {\n backgroundColor: styling.backgroundColor || defaults.backgroundColor,\n borderRadius: borderRadiusCSS,\n padding: paddingCSS,\n paddingTop: data.question ? 0 : paddingCSS,\n boxShadow: styling.shadow || '0 8px 24px rgba(0,0,0,0.06)',\n boxSizing: 'border-box',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n border: styling.borderColor ? `1px solid ${styling.borderColor}` : 'none',\n overflow: 'hidden',\n };\n\n const questionStyle: React.CSSProperties = {\n color: styling.questionTextColor || '#FFFFFF',\n backgroundColor: styling.questionBgColor || '#000000',\n fontWeight: '800',\n fontSize: typeof styling.fontSize === 'string' ? `min(${styling.fontSize}, 16px)` : `${styling.fontSize ? Math.min(Number(styling.fontSize), 16) : 15}px`,\n margin: `0 calc(-1 * ${paddingCSS}) 8px calc(-1 * ${paddingCSS})`,\n padding: `10px ${paddingCSS}`,\n textAlign: 'center',\n borderTopLeftRadius: borderRadiusCSS,\n borderTopRightRadius: borderRadiusCSS,\n };\n\n const gridStyle: React.CSSProperties = {\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: '8px',\n width: '100%',\n };\n\n const optionStyle: React.CSSProperties = {\n backgroundColor: styling.optionBgColor || defaults.optionBgColor,\n color: styling.optionTextColor || defaults.optionTextColor,\n borderRadius: '16px',\n border: `2px solid ${styling.borderColor || defaults.borderColor}`,\n cursor: selectedOptionId ? 'default' : 'pointer',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n padding: '8px',\n boxSizing: 'border-box',\n transition: 'all 0.2s ease',\n overflow: 'hidden',\n };\n\n const handleOptionClick = (optionId: string) => {\n if (isEditing || selectedOptionId) return;\n setSelectedOptionId(optionId);\n try {\n localStorage.setItem(`appstorys_image_quiz_${data.id}`, optionId);\n } catch (e) {}\n onInteraction?.({\n type: 'image',\n quizId: data.id,\n optionId: optionId,\n stickerId: data.id\n });\n };\n\n const placeholderImg = \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Crect width='100%25' height='100%25' fill='%23EDF2F7'/%3E%3Cpath d='M30 40 L40 30 L50 40 L60 30 L70 40 V60 H30 Z' fill='%23A0AEC0'/%3E%3Ccircle cx='40' cy='45' r='5' fill='%23FFFFFF'/%3E%3C/svg%3E\";\n\n const options = Array.isArray(data.options) ? data.options : [];\n\n return (\n <div style={containerStyle}>\n {data.question && <h3 style={questionStyle}>{data.question}</h3>}\n <div style={gridStyle}>\n {options.map((option) => {\n const isSelected = option.id === selectedOptionId;\n const isCorrect = (option as any).isCorrect === true;\n\n let currentOptionStyle = { ...optionStyle };\n if (selectedOptionId) {\n if (isCorrect) {\n currentOptionStyle.borderColor = styling.activeColor || defaults.activeColor;\n currentOptionStyle.backgroundColor = 'rgba(16, 185, 129, 0.05)';\n } else if (isSelected) {\n currentOptionStyle.borderColor = styling.incorrectColor || defaults.incorrectColor;\n currentOptionStyle.backgroundColor = 'rgba(239, 68, 68, 0.05)';\n }\n }\n\n return (\n <button\n key={option.id}\n style={currentOptionStyle}\n onClick={() => handleOptionClick(option.id)}\n disabled={!!selectedOptionId}\n onMouseOver={(e) => {\n if (!isEditing && !selectedOptionId) e.currentTarget.style.transform = 'translateY(-2px)';\n }}\n onMouseOut={(e) => {\n if (!isEditing && !selectedOptionId) e.currentTarget.style.transform = 'translateY(0)';\n }}\n >\n <div style={{\n width: '100%',\n aspectRatio: '1',\n borderRadius: '12px',\n overflow: 'hidden',\n backgroundColor: '#EDF2F7',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: '8px',\n position: 'relative'\n }}>\n <img\n src={option.image || placeholderImg}\n alt={option.text}\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n\n {selectedOptionId && (\n <div style={{\n position: 'absolute',\n top: '6px',\n right: '6px',\n width: '24px',\n height: '24px',\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: isCorrect ? defaults.activeColor : isSelected ? defaults.incorrectColor : '#A0AEC0',\n color: '#FFFFFF',\n fontSize: '12px',\n fontWeight: 'bold'\n }}>\n {isCorrect ? '✓' : isSelected ? '✕' : ''}\n </div>\n )}\n </div>\n <span style={{\n fontWeight: '600',\n fontSize: toCSSValue(styling.optionFontSize || 13),\n color: selectedOptionId && isCorrect ? defaults.activeColor : defaults.optionTextColor,\n width: '100%',\n textAlign: 'center',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis'\n }}>{option.text}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n};","import React, { useState } from 'react';\nimport { ShopableStickerData, StickerProps, ShopableProduct } from './types';\nimport { ShopableModal } from './ShopableModal';\nimport { toCSSValue } from '../../../utils/styleUtils';\n\nexport const ShopableSticker: React.FC<StickerProps<ShopableStickerData>> = ({\n data,\n onInteraction,\n isEditing,\n}) => {\n const { products, styling } = data;\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [selectedProduct, setSelectedProduct] = useState<ShopableProduct | null>(null);\n\n const handleProductClick = (e: React.MouseEvent, product: ShopableProduct) => {\n e.stopPropagation();\n if (isEditing) return;\n\n if (data.shopableType === 'product') {\n setSelectedProduct(product);\n setIsModalOpen(true);\n if (onInteraction) {\n onInteraction({\n type: 'product_view',\n stickerId: data.id,\n productId: product.productId || product.id,\n value: product.title,\n });\n }\n return;\n }\n\n // Static Redirection Logic\n let url = product.redirectUrl || product.url;\n if (url && !url.startsWith('http') && !url.startsWith('//')) {\n url = 'https://' + url;\n }\n\n if (onInteraction) {\n onInteraction({\n type: 'buy',\n stickerId: data.id,\n productId: product.id,\n value: product.title,\n selected_option: url,\n });\n }\n\n if (url) {\n try {\n window.open(url, '_blank', 'noopener,noreferrer');\n } catch (error) {\n console.error('AppStorys: Redirect failed', error);\n window.location.href = url;\n }\n }\n };\n\n const handleAddToCart = (item: any) => {\n if (onInteraction) {\n onInteraction({\n type: 'add_to_cart',\n stickerId: data.id,\n productId: item.productId,\n value: item.title,\n selected_option: JSON.stringify({\n size: item.selectedSize,\n color: item.selectedColor,\n quantity: item.quantity\n }),\n });\n }\n };\n\n const containerStyle: React.CSSProperties = {\n width: '100%',\n height: '100%',\n display: 'flex',\n gap: '12px',\n overflowX: 'auto',\n padding: '0 1px',\n scrollSnapType: 'x mandatory',\n scrollbarWidth: 'none',\n msOverflowStyle: 'none',\n WebkitOverflowScrolling: 'touch',\n pointerEvents: 'auto',\n };\n\n const cardStyle: React.CSSProperties = {\n flex: '0 0 auto',\n width: '100%',\n backgroundColor: styling?.cardBackground || '#ffffff',\n borderRadius: styling?.cardBorderRadius !== undefined\n ? toCSSValue(styling.cardBorderRadius)\n : (styling?.cardRadiusPercent !== undefined ? `${styling.cardRadiusPercent}%` : '12px'),\n overflow: 'hidden',\n boxShadow: styling?.shadow || '0 -2px 12px rgba(0,0,0,0.12)',\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n padding: '8px 12px',\n position: 'relative',\n scrollSnapAlign: 'center',\n transition: 'transform 0.2s ease',\n cursor: 'pointer',\n boxSizing: 'border-box',\n pointerEvents: 'auto',\n opacity: styling?.opacity ?? 1,\n marginBottom: 0,\n };\n\n const imageContainerStyle: React.CSSProperties = {\n width: '64px',\n height: '64px',\n borderRadius: styling?.imageRadius !== undefined ? toCSSValue(styling.imageRadius) : '12px',\n overflow: 'hidden',\n backgroundColor: '#f5f5f5',\n flexShrink: 0,\n };\n\n const contentContainerStyle: React.CSSProperties = {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n padding: '0 12px',\n minWidth: 0,\n };\n\n return (\n <>\n <div style={containerStyle} className=\"shopable-container\">\n <style>{`\n .shopable-container::-webkit-scrollbar { display: none; }\n .shopable-card:active { transform: scale(0.98); }\n `}</style>\n {products.map((product) => (\n <div\n key={product.id}\n style={cardStyle}\n className=\"shopable-card\"\n onClick={(e) => handleProductClick(e, product)}\n >\n {/* Product Image */}\n <div style={imageContainerStyle}>\n <img src={product.image} alt={product.title} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n </div>\n\n {/* Product Details */}\n <div style={contentContainerStyle}>\n <span style={{\n color: styling?.titleColor || styling?.textColor || '#1a1b2e',\n fontSize: styling?.titleFontSize ? toCSSValue(styling.titleFontSize) : '15px',\n fontWeight: styling?.titleFontWeight || '700',\n lineHeight: '1.2',\n display: 'block',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n marginBottom: '1px'\n }}>\n {product.title}\n </span>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: '6px', flexWrap: 'wrap' }}>\n <span style={{\n color: styling?.priceColor || styling?.textColor || '#1a1b2e',\n fontSize: styling?.priceFontSize ? toCSSValue(styling.priceFontSize) : '18px',\n fontWeight: styling?.priceFontWeight || '800',\n display: 'block'\n }}>\n {product.price}\n </span>\n {product.oldPrice && (\n <span style={{\n color: styling?.mrpColor || '#8b8b98',\n fontSize: styling?.mrpFontSize ? toCSSValue(styling.mrpFontSize) : '12px',\n fontWeight: styling?.mrpFontWeight || '500',\n textDecoration: 'line-through'\n }}>\n {product.oldPrice}\n </span>\n )}\n </div>\n </div>\n\n {/* Buy Button */}\n <div style={{\n backgroundColor: styling?.buttonBackground || '#000000',\n color: styling?.buttonTextColor || '#ffffff',\n fontSize: styling?.buttonFontSize ? toCSSValue(styling.buttonFontSize) : '14px',\n fontWeight: '700',\n padding: '10px 18px',\n borderRadius: styling?.buttonBorderRadius !== undefined ? toCSSValue(styling.buttonBorderRadius) : '100px',\n textAlign: 'center',\n flexShrink: 0,\n whiteSpace: 'nowrap'\n }}>\n Buy Now\n </div>\n </div>\n ))}\n </div>\n\n {/* Premium Product Details Modal */}\n {isModalOpen && selectedProduct && (\n <ShopableModal\n product={selectedProduct}\n styling={styling}\n onClose={() => setIsModalOpen(false)}\n onAddToCart={handleAddToCart}\n />\n )}\n </>\n );\n};\n\n","import React, { useState, useEffect } from 'react';\nimport { ShopableProduct } from './types';\nimport { toCSSValue } from '../../../utils/styleUtils';\n\ninterface ShopableModalProps {\n product: ShopableProduct;\n styling: any;\n onClose: () => void;\n onAddToCart: (item: any) => void;\n}\n\nexport const ShopableModal: React.FC<ShopableModalProps> = ({\n product,\n styling,\n onClose,\n onAddToCart,\n}) => {\n const [selectedSize, setSelectedSize] = useState<string>('');\n const [selectedColorIndex, setSelectedColorIndex] = useState<number>(0);\n const [quantity, setQuantity] = useState<number>(1);\n const [isSuccess, setIsSuccess] = useState<boolean>(false);\n const [isVisible, setIsVisible] = useState<boolean>(false);\n\n const attributes = product.attributes || {};\n const colors = attributes.colors || [];\n const sizes = attributes.sizes || [];\n const imageUrls = attributes.imageUrls || [product.image];\n const description = attributes.description || '';\n\n useEffect(() => {\n if (sizes.length > 0) setSelectedSize(sizes[0]);\n setIsVisible(true);\n }, [sizes]);\n\n const handleAddToCart = () => {\n const item = {\n productId: product.productId || product.id,\n title: product.title,\n selectedSize,\n selectedColor: colors[selectedColorIndex]?.name,\n quantity,\n price: product.price,\n };\n onAddToCart(item);\n \n // Handle Redirection\n let url = product.redirectUrl || product.url;\n if (url) {\n if (!url.startsWith('http') && !url.startsWith('//')) {\n url = 'https://' + url;\n }\n try {\n window.open(url, '_blank', 'noopener,noreferrer');\n } catch (error) {\n console.error('AppStorys: Redirect failed', error);\n }\n }\n \n setIsSuccess(true);\n };\n\n const handleDismiss = () => {\n setIsVisible(false);\n setTimeout(onClose, 400); // Match transiton duration\n };\n\n // Base Colors from styling\n const buttonBg = styling?.buttonBackground || '#000000';\n const buttonFg = styling?.buttonTextColor || '#ffffff';\n const titleFg = styling?.titleColor || styling?.textColor || '#1a1a2e';\n const priceFg = styling?.priceColor || styling?.textColor || '#1a1a2e';\n const mrpFg = styling?.mrpColor || '#8b8b98';\n \n const titleWeight = styling?.titleFontWeight || '600';\n const priceWeight = styling?.priceFontWeight || '700';\n const mrpWeight = styling?.mrpFontWeight || '500';\n\n if (isSuccess) {\n return (\n <div className=\"appstorys-shopable-success-overlay\" style={overlayStyle}>\n <div className=\"appstorys-shopable-backdrop\" style={backdropStyle} onClick={handleDismiss} />\n <div className=\"appstorys-shopable-sheet\" style={{\n ...sheetStyle,\n height: 'auto',\n minHeight: '310px',\n animation: 'appstorys-slide-up 0.4s cubic-bezier(0.2, 0.8, 0.2, 1)',\n }}>\n <div style={dragHandleStyle} onClick={handleDismiss} />\n <div style={{ padding: '0 20px 24px', textAlign: 'center' }}>\n <div style={{ \n backgroundColor: '#F3F4F6', \n borderRadius: '20px', \n padding: '22px', \n marginTop: '16px',\n display: 'flex', \n flexDirection: 'column', \n alignItems: 'center',\n gap: '12px'\n }}>\n <h3 style={{ margin: 0, fontSize: '16px', fontWeight: '600', lineHeight: '1.4' }}>\n Added to your bag<br />successfully\n </h3>\n {/* Smile Arc Icon SVG */}\n <svg width=\"44\" height=\"26\" viewBox=\"0 0 44 26\" fill=\"none\">\n <path d=\"M4 4C4 4 11 22 22 22C33 22 40 4 40 4\" stroke=\"currentColor\" strokeWidth=\"2.8\" strokeLinecap=\"round\" />\n </svg>\n </div>\n\n <div style={{ marginTop: '24px', display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <button \n onClick={handleDismiss}\n style={{ \n ...buttonBaseStyle, \n backgroundColor: '#000000', \n color: '#ffffff',\n padding: '17px',\n fontSize: '16px',\n fontWeight: '600'\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px' }}>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z\"/><path d=\"M3 6h18\"/><path d=\"M16 10a4 4 0 0 1-8 0\"/>\n </svg>\n Go to checkout\n </div>\n </button>\n <button \n onClick={handleDismiss}\n style={{ \n ...buttonBaseStyle, \n backgroundColor: 'transparent', \n color: '#000000',\n border: '1px solid rgba(0,0,0,0.1)',\n padding: '15px',\n fontSize: '16px'\n }}\n >\n Continue with stories\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div className={`appstorys-shopable-overlay ${isVisible ? 'visible' : ''}`} style={overlayStyle}>\n <div className=\"appstorys-shopable-backdrop\" style={backdropStyle} onClick={handleDismiss} />\n <div className=\"appstorys-shopable-sheet\" style={{\n ...sheetStyle,\n transform: isVisible ? 'translateY(0)' : 'translateY(100%)',\n opacity: isVisible ? 1 : 0,\n }}>\n {/* Header */}\n <div style={headerStyle}>\n <div style={dragHandleStyle} onClick={handleDismiss} />\n <button style={closeButtonStyle} onClick={handleDismiss}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n\n <div style={scrollContentStyle}>\n {/* Gallery Section */}\n <div style={gallerySectionStyle}>\n {imageUrls.map((url, i) => (\n <div key={i} style={{\n minWidth: imageUrls.length > 1 ? '85%' : '100%',\n aspectRatio: '1.2 / 1',\n maxHeight: '240px',\n borderRadius: '16px',\n overflow: 'hidden',\n backgroundColor: '#F9FAFB'\n }}>\n <img src={url} alt={product.title} style={{ width: '100%', height: '100%', objectFit: 'contain' }} />\n </div>\n ))}\n </div>\n\n <div style={{ padding: '0 20px 20px' }}>\n <h2 style={{ \n margin: '16px 0 4px', \n fontSize: styling?.titleFontSize ? toCSSValue(styling.titleFontSize) : '20px', \n fontWeight: titleWeight, \n color: titleFg,\n lineHeight: '1.2' \n }}>\n {product.title}\n </h2>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: '8px', marginBottom: '16px' }}>\n <span style={{ \n fontSize: styling?.priceFontSize ? toCSSValue(styling.priceFontSize) : '18px', \n fontWeight: priceWeight, \n color: priceFg \n }}>\n {product.price}\n </span>\n {product.oldPrice && (\n <span style={{ \n fontSize: styling?.mrpFontSize ? toCSSValue(styling.mrpFontSize) : '14px', \n color: mrpFg, \n textDecoration: 'line-through',\n fontWeight: mrpWeight\n }}>\n {product.oldPrice}\n </span>\n )}\n </div>\n {/* Color Section */}\n {colors.length > 0 && (\n <div style={sectionStyle}>\n <div style={sectionTitleStyle}>COLOR</div>\n <div style={{ display: 'flex', gap: '14px', marginTop: '12px' }}>\n {colors.map((color, i) => (\n <div key={color.id} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '5px' }}>\n <button\n onClick={() => setSelectedColorIndex(i)}\n style={{\n width: '36px', height: '36px', borderRadius: '50%', border: 'none',\n backgroundColor: color.hex || '#gray',\n position: 'relative', cursor: 'pointer',\n boxShadow: selectedColorIndex === i ? '0 0 0 2px #fff, 0 0 0 4px #000' : 'none',\n transition: 'all 0.2s ease'\n }}\n />\n <div style={{ \n width: '5px', height: '5px', borderRadius: '50%', \n backgroundColor: selectedColorIndex === i ? '#000' : 'transparent',\n transition: 'all 0.2s ease'\n }} />\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Size Section */}\n {sizes.length > 0 && (\n <div style={sectionStyle}>\n <div style={sectionTitleStyle}>SIZE</div>\n <div style={{ display: 'flex', gap: '10px', marginTop: '12px', flexWrap: 'wrap' }}>\n {sizes.map((size) => (\n <div key={size} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }}>\n <button\n onClick={() => setSelectedSize(size)}\n style={{\n minWidth: '42px', height: '42px', borderRadius: '50%',\n backgroundColor: 'transparent',\n border: `1px solid ${selectedSize === size ? '#000' : 'rgba(0,0,0,0.1)'}`,\n color: selectedSize === size ? '#000' : '#8b8b98',\n fontSize: '13px', fontWeight: '500', cursor: 'pointer',\n transition: 'all 0.2s ease'\n }}\n >\n {size}\n </button>\n <div style={{ \n width: '5px', height: '5px', borderRadius: '50%', \n backgroundColor: selectedSize === size ? '#000' : 'transparent',\n transition: 'all 0.2s ease'\n }} />\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Description */}\n {description && (\n <div style={sectionStyle}>\n <div style={sectionTitleStyle}>DESCRIPTION</div>\n <p style={{ \n margin: '8px 0 0', fontSize: '14px', lineHeight: '1.5', color: '#8b8b98',\n wordBreak: 'break-word'\n }}>\n {description}\n </p>\n </div>\n )}\n </div>\n </div>\n\n {/* Sticky Bottom Bar */}\n <div style={bottomBarStyle}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1px', minWidth: '75px' }}>\n <div style={{ fontSize: '15px', fontWeight: priceWeight, color: priceFg }}>{product.price}</div>\n {product.oldPrice && (\n <div style={{ fontSize: '11px', color: mrpFg, textDecoration: 'line-through', fontWeight: mrpWeight }}>{product.oldPrice}</div>\n )}\n </div>\n\n <div style={stepperStyle}>\n <button style={stepperBtnStyle} onClick={() => setQuantity(q => Math.max(1, q - 1))}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" /></svg>\n </button>\n <span style={{ fontSize: '16px', fontWeight: '700', minWidth: '18px', textAlign: 'center', color: '#000000', display: 'inline-block' }}>{quantity}</span>\n <button style={stepperBtnStyle} onClick={() => setQuantity(q => q + 1)}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" /><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" /></svg>\n </button>\n </div>\n\n {(() => {\n const availability = attributes.availability?.toLowerCase() || '';\n const isOutOfStock = availability === 'out of stock' || availability === 'out-of-stock';\n \n return (\n <button \n onClick={isOutOfStock ? undefined : handleAddToCart} \n disabled={isOutOfStock}\n style={{\n ...buttonBaseStyle,\n backgroundColor: isOutOfStock ? '#F3F4F6' : buttonBg,\n color: isOutOfStock ? '#9CA3AF' : buttonFg,\n flex: '1',\n padding: '12px 8px',\n gap: '6px',\n cursor: isOutOfStock ? 'not-allowed' : 'pointer',\n opacity: isOutOfStock ? 0.8 : 1\n }}\n >\n {!isOutOfStock && (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <path d=\"M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z\"/><path d=\"M3 6h18\"/><path d=\"M16 10a4 4 0 0 1-8 0\"/>\n </svg>\n )}\n <span style={{ fontSize: '12px', fontWeight: '700', whiteSpace: 'nowrap' }}>\n {isOutOfStock ? 'Out of Stock' : 'Add to cart'}\n </span>\n </button>\n );\n })()}\n </div>\n </div>\n\n <style>{`\n @keyframes appstorys-slide-up {\n from { transform: translateY(100%); }\n to { transform: translateY(0); }\n }\n .appstorys-shopable-overlay {\n position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000;\n display: flex; align-items: flex-end; justify-content: center;\n visibility: hidden;\n }\n .appstorys-shopable-overlay.visible {\n visibility: visible;\n }\n `}</style>\n </div>\n );\n};\n\n// Styles\nconst overlayStyle: React.CSSProperties = {\n position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, zIndex: 10000,\n display: 'flex', alignItems: 'flex-end', justifyContent: 'center', pointerEvents: 'auto',\n fontFamily: \"'Inter', system-ui, -apple-system, sans-serif\",\n width: '100%', height: '100%',\n boxSizing: 'border-box'\n};\n\nconst backdropStyle: React.CSSProperties = {\n position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.45)',\n cursor: 'pointer'\n};\n\nconst sheetStyle: React.CSSProperties = {\n position: 'relative', width: '100%', maxWidth: '500px',\n backgroundColor: '#fff', borderTopLeftRadius: '28px', borderTopRightRadius: '28px',\n borderBottomLeftRadius: 0, borderBottomRightRadius: 0,\n maxHeight: '60vh', display: 'flex', flexDirection: 'column', margin: 0,\n transition: 'transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.4s ease',\n boxShadow: '0 -8px 24px rgba(0,0,0,0.15)', overflow: 'hidden',\n boxSizing: 'border-box'\n};\n\nconst headerStyle: React.CSSProperties = {\n height: '48px', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', flexShrink: 0\n};\n\nconst dragHandleStyle: React.CSSProperties = {\n width: '36px', height: '5px', backgroundColor: 'rgba(0,0,0,0.1)', borderRadius: '3px', cursor: 'pointer'\n};\n\nconst closeButtonStyle: React.CSSProperties = {\n position: 'absolute', right: '18px', top: '16px', border: 'none',\n width: '28px', height: '28px', borderRadius: '50%', backgroundColor: '#F3F4F6',\n display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#666', cursor: 'pointer'\n};\n\nconst scrollContentStyle: React.CSSProperties = {\n flex: 1, overflowY: 'auto', WebkitOverflowScrolling: 'touch'\n};\n\nconst gallerySectionStyle: React.CSSProperties = {\n padding: '0 16px 20px', display: 'flex', gap: '8px', overflowX: 'auto', scrollSnapType: 'x mandatory'\n};\n\nconst sectionStyle: React.CSSProperties = {\n marginTop: '20px'\n};\n\nconst sectionTitleStyle: React.CSSProperties = {\n fontSize: '11px', fontWeight: '600', color: 'rgba(0,0,0,0.5)', letterSpacing: '1.4px'\n};\n\nconst bottomBarStyle: React.CSSProperties = {\n padding: '12px 16px calc(20px + env(safe-area-inset-bottom, 0px))',\n borderTop: '1px solid rgba(0,0,0,0.05)', display: 'flex', alignItems: 'center', gap: '8px',\n backgroundColor: '#fff', boxShadow: '0 -4px 12px rgba(0,0,0,0.06)', zIndex: 10,\n boxSizing: 'border-box'\n};\n\nconst stepperStyle: React.CSSProperties = {\n display: 'flex', alignItems: 'center', gap: '10px', padding: '10px 12px',\n borderRadius: '100px', border: '1px solid rgba(0,0,0,0.1)'\n};\n\nconst stepperBtnStyle: React.CSSProperties = {\n border: 'none', backgroundColor: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center'\n};\n\nconst buttonBaseStyle: React.CSSProperties = {\n border: 'none', borderRadius: '100px', cursor: 'pointer',\n display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.2s ease'\n};\n","import React from 'react';\nimport { resolveFontFamily } from '../../../core/fontManager';\nimport { toCSSValue } from '../../../utils/styleUtils';\nimport { StickerData } from './types';\nimport { PollSticker } from './PollSticker';\nimport { QuizSticker } from './QuizSticker';\nimport { CountdownSticker } from './CountdownSticker';\nimport { PromoCodeSticker } from './PromoCodeSticker';\nimport { ReactionSticker } from './ReactionSticker';\nimport { RatingSticker } from './RatingSticker';\nimport { QuestionSticker } from './QuestionSticker';\nimport { ImageQuizSticker } from './ImageQuizSticker';\nimport { ShopableSticker } from './ShopableSticker';\n\ninterface InteractiveItemProps {\n data: StickerData;\n onInteraction?: (data: any) => void;\n isEditing?: boolean;\n}\n\nexport const InteractiveItem: React.FC<InteractiveItemProps> = ({\n data,\n onInteraction,\n isEditing = false,\n}) => {\n const defaults = {\n x: 10,\n y: 15,\n width: 80, // percentage\n rotation: 0,\n };\n\n const x = data.x ?? defaults.x;\n const y = data.y ?? defaults.y;\n const width = data.width ?? defaults.width;\n const rotation = data.rotation ?? defaults.rotation;\n\n const wrapperStyle: React.CSSProperties = {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: `${width}%`,\n height: (data as any).height ? `${(data as any).height}%` : 'auto',\n transform: `rotate(${rotation}deg)`,\n zIndex: 10,\n transformOrigin: 'center center',\n boxSizing: 'border-box',\n cursor: isEditing ? 'move' : 'default',\n pointerEvents: 'auto',\n };\n\n const animationStyle: React.CSSProperties = {\n width: '100%',\n height: '100%',\n animation: (data as any).styling?.animation,\n animationFillMode: 'forwards',\n };\n\n const renderSticker = () => {\n const stickerType = (data as any).type;\n switch (stickerType) {\n case 'poll':\n return <PollSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'quiz':\n return <QuizSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'rating':\n return <RatingSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'question':\n case 'input':\n return <QuestionSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'image_quiz':\n return <ImageQuizSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'countdown':\n return <CountdownSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'promo_code':\n case 'promo':\n return <PromoCodeSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'reaction':\n return <ReactionSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'buy':\n case 'shopable':\n return <ShopableSticker data={data as any} onInteraction={onInteraction} isEditing={isEditing} />;\n case 'shape':\n case 'gif':\n case 'svg':\n case 'sticker':\n case 'image':\n return <img src={(data as any).url} alt=\"static overlay\" style={{ width: '100%', height: '100%', objectFit: 'fill' }} />;\n case 'text': {\n const textStyle = (data as any).styling || {};\n const vAlign = textStyle.verticalAlignment;\n const hAlign = textStyle.textAlign;\n\n return (\n <div style={{\n color: textStyle.color || '#000000',\n fontSize: toCSSValue(textStyle.fontSize || 14),\n fontFamily: resolveFontFamily(textStyle.fontFamily) || 'Arial',\n fontStyle: textStyle.fontStyle || 'normal',\n fontWeight: textStyle.fontWeight || 'normal',\n textDecoration: textStyle.textDecoration || 'none',\n lineHeight: textStyle.lineHeight || 'normal',\n letterSpacing: textStyle.letterSpacing || 'normal',\n opacity: textStyle.opacity ?? 1,\n wordBreak: 'break-word',\n whiteSpace: 'pre-wrap',\n width: '100%',\n height: '100%',\n display: 'flex',\n alignItems: vAlign === 'center' ? 'center' : (vAlign === 'bottom' ? 'flex-end' : 'flex-start'),\n justifyContent: hAlign === 'center' ? 'center' : (hAlign === 'right' ? 'flex-end' : 'flex-start'),\n textAlign: hAlign || 'left',\n }}>\n {(data as any).text}\n </div>\n );\n }\n case 'cta': {\n const ctaStyle = (data as any).styling || {};\n const isImage = (data as any).ctaType === 'image';\n\n if (isImage) {\n return (\n <button\n onClick={(e) => {\n e.stopPropagation();\n if (onInteraction) {\n onInteraction({\n type: 'cta',\n stickerId: data.id,\n redirectUrl: (data as any).redirectUrl,\n });\n }\n }}\n style={{\n background: 'none',\n border: 'none',\n padding: 0,\n width: '100%',\n height: '100%',\n cursor: 'pointer',\n display: 'block',\n outline: 'none',\n }}\n >\n <img\n src={(data as any).url}\n alt={(data as any).text}\n style={{ width: '100%', height: '100%', objectFit: 'contain' }}\n />\n </button>\n );\n }\n\n const borderRadius = ctaStyle.borderRadius;\n\n const text = ((data as any).text || '').trim();\n const isSwipeUp =\n text.toLowerCase().includes('swipe') ||\n String((data as any).ctaType).toLowerCase().includes('swipe') ||\n String(data.type).toLowerCase().includes('swipe') ||\n String(data.id).toLowerCase().includes('swipe');\n\n const buttonStyle: React.CSSProperties = {\n width: '100%',\n height: ctaStyle.pillH ? `${ctaStyle.pillH}cqh` : '100%',\n backgroundColor: ctaStyle.transparent ? 'transparent' : (ctaStyle.backgroundColor || '#3B82F6'),\n color: ctaStyle.textColor || '#FFFFFF',\n border: ctaStyle.borderWidth ? `${toCSSValue(ctaStyle.borderWidth)} solid ${ctaStyle.borderColor || '#FFFFFF'}` : 'none',\n borderRadius: borderRadius || '4px',\n fontSize: toCSSValue(ctaStyle.fontSize || 14),\n fontFamily: resolveFontFamily(ctaStyle.fontFamily) || 'Arial',\n fontStyle: ctaStyle.fontStyle || 'normal',\n fontWeight: ctaStyle.fontWeight || 'normal',\n textDecoration: ctaStyle.textDecoration || 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n boxSizing: 'border-box',\n outline: 'none',\n padding: '0 12px',\n wordBreak: 'break-word',\n flexShrink: 0,\n };\n\n const containerStyle: React.CSSProperties = {\n position: 'relative',\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'flex-end',\n boxSizing: 'border-box',\n animation: isSwipeUp && ctaStyle.arrowAnimation !== false ? 'appstorys-swipe-bounce 2.2s ease-in-out infinite' : 'none',\n transformOrigin: 'bottom center',\n };\n\n const arrowContainerStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexGrow: 1,\n width: '100%',\n color: ctaStyle.arrowColor || ctaStyle.textColor || '#FFFFFF',\n pointerEvents: 'none',\n boxSizing: 'border-box',\n };\n\n const arrowHeight = ctaStyle.arrowSize ? `${ctaStyle.arrowSize}cqh` : '1.5cqh';\n\n const chevronIcon = (\n <svg\n style={{ height: arrowHeight, width: 'auto' }}\n viewBox=\"0 0 28 18\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"4 14 14 4 24 14\" />\n </svg>\n );\n\n return (\n <div style={containerStyle}>\n {isSwipeUp && (\n <>\n <style>{`\n @keyframes appstorys-swipe-bounce {\n 0%, 100% {\n transform: translateY(0) scaleY(1) scaleX(1);\n }\n 40% {\n transform: translateY(-3px) scaleY(1.04) scaleX(0.98);\n }\n 75% {\n transform: translateY(1px) scaleY(0.97) scaleX(1.02);\n }\n }\n `}</style>\n <div style={arrowContainerStyle}>\n {chevronIcon}\n </div>\n </>\n )}\n <button\n onClick={(e) => {\n e.stopPropagation();\n if (onInteraction) {\n onInteraction({\n type: 'cta',\n stickerId: data.id,\n redirectUrl: (data as any).redirectUrl,\n });\n }\n }}\n style={buttonStyle}\n >\n {text || (data as any).text}\n </button>\n </div>\n );\n }\n default:\n return (\n <div style={{ padding: '10px', background: 'white', color: 'black', borderRadius: '4px' }}>\n Unsupported interactive element: {(data as any).type}\n </div>\n );\n }\n };\n\n return (\n <div style={wrapperStyle} className={`interactive-item-z${(data as any).z ?? 0}`}>\n <div style={animationStyle}>\n {renderSticker()}\n </div>\n </div>\n );\n};","import React from 'react';\nimport { StickerData } from './types';\nimport { InteractiveItem } from './InteractiveItem';\nimport { parseBackground, getAnimationStyles, parseColor } from '../../../utils/styleUtils';\nimport { resolveFontFamily } from '../../../core/fontManager';\n\ninterface InteractiveOverlayProps {\n content?: any; // Pass fully packed backend content structure\n onInteraction?: (data: any) => void;\n isEditing?: boolean;\n elapsedTime?: number;\n}\n\nconst getEditorSource = (item: any, content: any): 'studio' | 'dashboard' => {\n const editorSource =\n item?.styling?.editorSource ||\n item?.styling?.meta?.editorSource ||\n item?.style?.editorSource ||\n content?.editorSource ||\n content?.meta?.editorSource ||\n content?.styling?.editorSource ||\n content?.styling?.meta?.editorSource;\n\n return editorSource === 'studio' || editorSource === 'editor' ? 'studio' : 'dashboard';\n};\n\nconst normalizeOptions = (options: any, isCorrect?: string | boolean | null): any[] => {\n if (Array.isArray(options)) {\n return options.map((option, index) => {\n const optionId = option?.id || option?.key || option?.value || `option_${index + 1}`;\n const optionLabel = option?.label || option?.optionLabel;\n const optionText =\n typeof option === 'string'\n ? option\n : option?.text || option?.title || optionLabel || '';\n\n return {\n id: String(optionId),\n text: optionText,\n image: option?.image || option?.imageUrl || '',\n label: optionLabel,\n isCorrect: option?.isCorrect === true || String(optionId) === String(isCorrect),\n };\n });\n }\n\n if (options && typeof options === 'object') {\n return Object.entries(options).map(([key, value]) => {\n const optionValue = typeof value === 'string' ? { text: value } : ((value as any) || {});\n return {\n id: key,\n text: optionValue.text || optionValue.title || optionValue.label || '',\n image: optionValue.image || optionValue.imageUrl || '',\n label: optionValue.label,\n isCorrect: key === String(isCorrect),\n };\n });\n }\n\n return [];\n};\n\nconst normalizeReactionEmojis = (data: any): string[] => {\n if (Array.isArray(data?.emojis)) {\n return data.emojis.map((emoji: any) => String(emoji));\n }\n\n return normalizeOptions(data?.options).map((option) => option.text).filter(Boolean);\n};\n\nconst normalizeElementType = (type: any): string => {\n const normalized = String(type || '').toLowerCase();\n if (normalized === 'quizz') return 'quiz';\n if (normalized === 'rate') return 'rating';\n if (normalized === 'input' || normalized === 'ask_question' || normalized === 'askquestion') return 'question';\n if (normalized === 'promo' || normalized === 'promocode') return 'promo_code';\n return normalized;\n};\n\nconst getPromoCode = (item: any, data: any, custom: any): string => {\n const codeVal =\n data?.couponCode ||\n data?.code ||\n data?.coupon_code ||\n data?.promoCode ||\n data?.promocode ||\n data?.coupon ||\n data?.value ||\n item?.couponCode ||\n item?.code ||\n item?.coupon_code ||\n custom?.couponCode ||\n custom?.code ||\n custom?.data?.couponCode ||\n custom?.data?.code;\n return typeof codeVal === 'string' && codeVal.trim() !== '' ? codeVal.trim() : 'OFFER20';\n};\n\n// Helper to combine endDate and endTime into ISO string\nconst getCountdownTarget = (data: any) => {\n if (data.targetDate) return data.targetDate;\n if (!data.endDate) return new Date(Date.now() + 86400000).toISOString();\n\n try {\n const combined = `${data.endDate}${data.endTime ? `T${data.endTime}` : ''}`;\n return new Date(combined).toISOString();\n } catch (e) {\n return data.endDate || new Date(Date.now() + 86400000).toISOString();\n }\n};\n\nexport const InteractiveOverlay: React.FC<InteractiveOverlayProps> = ({\n content = {},\n onInteraction,\n isEditing = false,\n elapsedTime = 0,\n}) => {\n const canva = content?.canva || { height: 1920, width: 1080 };\n const canvaWidth = canva?.width || 1080;\n const canvaHeight = canva?.height || 1920;\n const scale_factor = 0.352; // standard width desktop factor scaling 380/1080\n\n const elements = content?.elements || [];\n const images = content?.image || [];\n const texts = content?.text || [];\n const ctas = content?.ctas || [];\n const interactions = content?.interactions || [];\n const shopableContent = (Array.isArray(content?.shopable) && content.shopable.length > 0)\n ? content.shopable\n : (Array.isArray(content?.styling?.shopable) ? content.styling.shopable : []);\n const shopableIds = new Set(shopableContent.map((s: any) => s.id));\n const shopableStyling = (content?.styling?.shopable || []).concat(shopableContent.map((s: any) => s.styling).filter(Boolean));\n\n const slideSource = getEditorSource(null, content);\n const slideIsStudio = slideSource === 'studio';\n\n const getScaledHeightStyle = (val: any, isStudioLocal = slideIsStudio) => {\n if (val === undefined || val === null || val === '') return undefined;\n if (isStudioLocal) return `${val}cqh`;\n const num = Number(val);\n if (isNaN(num)) return String(val);\n return `${(num / canvaHeight) * 100}cqh`;\n };\n\n const getScaledFontStyle = (val: any, isStudioLocal = slideIsStudio) => {\n if (val === undefined || val === null || val === '') return undefined;\n const num = Number(val);\n if (!isNaN(num)) {\n if (num < 10) {\n return `clamp(11px, ${num * 0.85}cqh, 18px)`;\n } else {\n const cqhVal = (num / 1920) * 100;\n return `clamp(11px, ${cqhVal * 1.5}cqh, 18px)`;\n }\n }\n return String(val);\n };\n\n if (elements.length === 0 && images.length === 0 && texts.length === 0 && interactions.length === 0 && shopableContent.length === 0 && ctas.length === 0) return null;\n\n // 1. Map interactive elements\n const displayElements = elements\n .filter((item: any) => !shopableIds.has(item.id))\n .map((item: any): StickerData => {\n const custom = item.custom || {};\n const data = custom.data || {};\n const style = custom.style || item.styling || {};\n const source = getEditorSource(item, content);\n const isStudio = source === 'studio';\n\n const position = item.position || item.postion || {};\n const size = item.size || {};\n\n // Safe coordinate conversion with bulletproof Number parsing.\n // Studio often sends `{ position: {x,y}, size: {width,height} }` instead of direct `x/y/width`.\n const rawX = item.x !== undefined ? item.x : position.x;\n const rawY = item.y !== undefined ? item.y : position.y;\n const rawW = item.width !== undefined ? item.width : size.width;\n const rawH = item.height !== undefined ? item.height : size.height;\n\n const x_percent = rawX !== undefined && !isNaN(Number(rawX)) ? (isStudio ? Number(rawX) : (Number(rawX) / canvaWidth) * 100) : 10;\n const y_percent = rawY !== undefined && !isNaN(Number(rawY)) ? (isStudio ? Number(rawY) : (Number(rawY) / canvaHeight) * 100) : 15;\n const width_percent = rawW !== undefined && !isNaN(Number(rawW)) ? (isStudio ? Number(rawW) : (Number(rawW) / canvaWidth) * 100) : 80;\n const height_percent = rawH !== undefined && !isNaN(Number(rawH)) ? (isStudio ? Number(rawH) : (Number(rawH) / canvaHeight) * 100) : undefined;\n\n const baseData = {\n id: item.id || Math.random().toString(),\n type: normalizeElementType(custom.interactiveType || item.widgetType || item.type || 'unknown'),\n x: x_percent,\n y: y_percent,\n width: width_percent,\n height: height_percent,\n url: item.url || data.url || item.link || data.link,\n rotation: style.rotation ?? item.rotation ?? 0,\n z: item.z ?? item.position?.z ?? style.z ?? 10,\n duration: data.duration || style.duration,\n styling: {\n backgroundColor: parseBackground(style.background || style.containerBgColor || style.backgroundColor),\n borderRadius: (style.borderRadius !== undefined ? (style.borderRadius >= 100 ? '999px' : getScaledHeightStyle(style.borderRadius, isStudio)) : (style.radius !== undefined ? (style.radius >= 100 ? '999px' : getScaledHeightStyle(style.radius, isStudio)) : '0px')),\n padding: getScaledHeightStyle(style.containerPadding !== undefined ? style.containerPadding : (style.padding !== undefined ? style.padding : 0), isStudio),\n shadow: style.shadow,\n fontSize: getScaledFontStyle(style.questionFontSize ?? style.questionFont?.fontSize ?? style.questionSize ?? style.fontSize, isStudio),\n opacity: style.opacity ?? 1,\n animation: getAnimationStyles(style.animation),\n },\n };\n\n if (baseData.type === 'poll') {\n const normalizedOpts = normalizeOptions(data.options);\n return {\n ...baseData,\n type: 'poll',\n question: data.question || data.title || 'Poll Question',\n options: normalizedOpts,\n layout: data.layout || { type: 'vertical', columns: 1 },\n styling: {\n ...baseData.styling,\n headerColor: parseBackground(style.headerBgColor || style.background),\n headerTextColor: parseColor(style.questionColor || style.questionTextColor || (style.question?.color)),\n optionBgColor: parseBackground(style.optionBgColor || style.options?.background) || '#1A1A1A',\n optionTextColor: parseColor(style.optionTextColor || style.options?.textColor) || '#ffffff',\n optionBorderRadius: style.optionBorderRadius !== undefined ? getScaledHeightStyle(style.optionBorderRadius, isStudio) : (style.options?.radius !== undefined ? getScaledHeightStyle(style.options?.radius, isStudio) : '0px'),\n },\n } as any;\n }\n\n if (baseData.type === 'quiz') {\n const colors = style.colors || {};\n const normalizedOpts = normalizeOptions(data.options, data.isCorrect);\n const rawOptionFontSize = style.optionFontSize ?? style.optionFont?.fontSize ?? style.typography?.optionSize ?? style.options?.fontSize ?? 16;\n return {\n ...baseData,\n type: 'quiz',\n question: data.question || data.title || 'Quiz Question',\n options: normalizedOpts,\n showExplanation: data.showExplanation,\n url: data.url,\n styling: {\n ...baseData.styling,\n backgroundColor: parseBackground(style.background || style.containerBgColor || style.backgroundColor) || 'transparent',\n questionTextColor: parseColor(style.questionColor || colors.questionColor || style.question?.color || style.colors?.questionText) || '#FFFFFF',\n questionBgColor: parseBackground(style.questionBgColor || colors.questionBackground || style.question?.background || style.colors?.questionBg) || '#000000',\n optionBgColor: parseBackground(style.optionBgColor || colors.optionBackground || style.options?.background || style.colors?.optionBg) || '#FFFFFF',\n optionTextColor: parseColor(style.optionTextColor || colors.optionTextColor || style.options?.textColor || style.colors?.optionText) || '#2B2B2B',\n borderColor: parseColor(style.borderColor) || 'transparent',\n activeColor: parseColor(style.correctColor || colors.correctColor || style.correctBorderColor) || '#10b981',\n incorrectColor: parseColor(style.incorrectColor || colors.incorrectColor) || '#ef4444',\n optionBorderRadius: (style.optionRadius !== undefined ? (style.optionRadius >= 100 ? '999px' : getScaledHeightStyle(style.optionRadius, isStudio)) : (style.optionBorderRadius !== undefined ? (style.optionBorderRadius >= 100 ? '999px' : getScaledHeightStyle(style.optionBorderRadius, isStudio)) : '100px')),\n optionFontSize: getScaledFontStyle(rawOptionFontSize, isStudio),\n },\n } as any;\n }\n\n if (baseData.type === 'rating') {\n return {\n ...baseData,\n type: 'rating',\n title: data.title || 'Do you like my space?',\n emoji: data.emoji || '😍',\n currentRating: data.currentRating,\n maxRating: data.maxRating,\n styling: {\n ...baseData.styling,\n sliderTrackColor: parseColor(style.colors?.sliderTrack || style.sliderTrack),\n sliderFillColor: parseColor(style.colors?.sliderFill || style.sliderFill),\n emojiSize: style.emojiSize ? (isStudio ? `${Math.min(Number(style.emojiSize), 32)}px` : `${Math.min(style.emojiSize * 0.45, 32)}px`) : undefined,\n titleColor: parseColor(style.colors?.titleColor || style.titleColor),\n titleFontSize: style.titleFontSize ? (isStudio ? `${Math.min(Number(style.titleFontSize), 16)}px` : `${Math.min(style.titleFontSize * 0.4, 16)}px`) : undefined,\n },\n } as any;\n }\n\n if (baseData.type === 'question') {\n return {\n ...baseData,\n type: 'question',\n question: data.question || data.title || 'Ask me a question',\n placeholder: data.placeholder || 'Type your answer...',\n styling: {\n ...baseData.styling,\n promptColor: parseColor(style.questionColor || style.textColor),\n inputBgColor: parseBackground(style.inputBgColor),\n inputTextColor: parseColor(style.inputTextColor),\n submitBackground: parseBackground(style.submitBackground),\n },\n } as any;\n }\n\n if (baseData.type === 'image_quiz' || baseData.type === 'imageQuiz' || (custom.interactiveType || '').toLowerCase() === 'media_quiz') {\n const rawOptionFontSize = style.optionFontSize ?? style.optionFont?.fontSize ?? style.typography?.optionSize ?? style.options?.fontSize ?? 13;\n return {\n ...baseData,\n type: 'image_quiz',\n question: data.question || data.title || 'Image Quiz',\n options: normalizeOptions(data.options || []),\n styling: {\n ...baseData.styling,\n questionTextColor: parseColor(style.questionColor),\n activeColor: parseColor(style.correctColor || style.correctBorderColor),\n incorrectColor: parseColor(style.incorrectColor),\n imageRadius: style.imageRadius ? getScaledHeightStyle(style.imageRadius, isStudio) : undefined,\n optionFontSize: getScaledFontStyle(rawOptionFontSize, isStudio),\n },\n } as any;\n }\n\n if (baseData.type === 'countdown') {\n return {\n ...baseData,\n type: 'countdown',\n title: data.title || 'Ends in...',\n targetDate: getCountdownTarget(data),\n styling: {\n ...baseData.styling,\n borderColor: parseColor(style.borderColor),\n digitBackground: parseBackground(style.digitBackground),\n digitColor: parseColor(style.digitColor),\n digitSize: (style.digitSize || style.fontSize) ? getScaledFontStyle(style.digitSize || style.fontSize, isStudio) : undefined,\n labelColor: parseColor(style.labelColor),\n titleColor: parseColor(style.titleColor),\n },\n display: data.display,\n } as any;\n }\n\n if (baseData.type === 'promo_code') {\n return {\n ...baseData,\n width: baseData.width ? Math.max(baseData.width, 65) : 75,\n type: 'promo_code',\n code: getPromoCode(item, data, custom),\n styling: {\n ...baseData.styling,\n borderColor: parseColor(style.borderColor),\n },\n } as any;\n }\n\n if (baseData.type === 'reaction' || baseData.type === 'emoji_reaction') {\n const emojisArray = normalizeReactionEmojis(data);\n\n return {\n ...baseData,\n type: 'reaction',\n emojis: emojisArray.length > 0 ? emojisArray : ['😍', '👍'],\n source,\n } as any;\n }\n\n return baseData as any;\n });\n\n // 1b. Map interactions (new structure supported for story interaction types)\n const displayInteractions = (content?.interactions || [])\n .filter((item: any) => !shopableIds.has(item.id))\n .map((item: any): StickerData => {\n const data = item.config || {};\n const style = item.styling || item.style || {}; // Map both structures\n const source = getEditorSource(item, content);\n const isStudio = source === 'studio';\n\n const typeStr = normalizeElementType(item.interaction_type || item.type);\n\n // Support position and size structures framed sizing absolute layout setups\n const position = style.position || item.position || {};\n const size = style.size || item.size || {};\n\n // Support both direct dimensions and nested size/position structures scales framing\n const posX = position.x ?? item.x;\n const posY = position.y ?? item.y;\n const sizeW = size.width ?? item.width;\n const sizeH = size.height ?? item.height;\n // Fall back to defaults (10, 15, 80) if no dimension is provided or parsed to NaN\n const x_percent = posX !== undefined && !isNaN(Number(posX)) ? (isStudio ? Number(posX) : (Number(posX) / canvaWidth) * 100) : 10;\n const y_percent = posY !== undefined && !isNaN(Number(posY)) ? (isStudio ? Number(posY) : (Number(posY) / canvaHeight) * 100) : 15;\n const width_percent = sizeW !== undefined && !isNaN(Number(sizeW)) ? (isStudio ? Number(sizeW) : (Number(sizeW) / canvaWidth) * 100) : 80;\n const height_percent = sizeH !== undefined && !isNaN(Number(sizeH)) ? (isStudio ? Number(sizeH) : (Number(sizeH) / canvaHeight) * 100) : undefined;\n\n const baseData = {\n id: item.id || Math.random().toString(),\n type: typeStr,\n x: x_percent,\n y: y_percent,\n width: width_percent,\n height: height_percent,\n rotation: style.rotation ?? item.rotation ?? 0,\n z: item.z ?? item.position?.z ?? style.z ?? 10,\n source,\n duration: data.duration || style.duration,\n styling: {\n backgroundColor: parseBackground(style.background || style.containerBgColor || style.backgroundColor),\n borderRadius: (style.borderRadius !== undefined ? (style.borderRadius >= 100 ? '999px' : getScaledHeightStyle(style.borderRadius, isStudio)) : (style.radius !== undefined ? (style.radius >= 100 ? '999px' : getScaledHeightStyle(style.radius, isStudio)) : '0px')),\n padding: getScaledHeightStyle(style.containerPadding !== undefined ? style.containerPadding : (style.padding !== undefined ? style.padding : 0), isStudio),\n shadow: style.shadow,\n fontSize: getScaledFontStyle(style.questionFontSize ?? style.questionFont?.fontSize ?? style.questionSize ?? style.fontSize, isStudio),\n opacity: style.opacity ?? 1,\n animation: getAnimationStyles(style.animation),\n },\n };\n\n if (baseData.type === 'rating' || baseData.type === 'rate') {\n const colors = style.colors || {};\n return {\n ...baseData,\n type: 'rating',\n title: data.title || 'Do you like my space?',\n emoji: data.emoji || '😍',\n currentRating: data.currentRating,\n maxRating: data.maxRating,\n styling: {\n ...baseData.styling,\n sliderTrackColor: parseColor(colors.sliderTrack || style.colors?.sliderTrack || style.colors?.sliderTrack),\n sliderFillColor: parseColor(colors.sliderFill || style.colors?.sliderFill || style.colors?.sliderFill),\n emojiSize: style.emojiSize ? (isStudio ? `${Math.min(Number(style.emojiSize), 32)}px` : `${Math.min(style.emojiSize * 0.45, 32)}px`) : undefined,\n titleColor: parseColor(colors.titleColor || style.colors?.titleColor || style.titleColor),\n titleFontSize: style.titleFontSize ? (isStudio ? `${Math.min(Number(style.titleFontSize), 16)}px` : `${Math.min(style.titleFontSize * 0.4, 16)}px`) : undefined,\n },\n } as any;\n }\n\n if (baseData.type === 'poll') {\n const normalizedOpts = normalizeOptions(data.options);\n return {\n ...baseData,\n type: 'poll',\n question: data.question || data.title || 'Poll Question',\n options: normalizedOpts,\n layout: data.layout || { type: 'vertical', columns: 1 },\n styling: {\n ...baseData.styling,\n headerColor: parseBackground(style.headerBgColor || style.background),\n headerTextColor: parseColor(style.questionColor || style.questionTextColor || (style.question?.color)),\n optionBgColor: parseBackground(style.optionBgColor || style.options?.background) || '#1A1A1A',\n optionTextColor: parseColor(style.optionTextColor || style.options?.textColor) || '#ffffff',\n optionBorderRadius: style.optionBorderRadius !== undefined ? getScaledHeightStyle(style.optionBorderRadius, isStudio) : (style.options?.radius !== undefined ? getScaledHeightStyle(style.options?.radius, isStudio) : '0px'),\n },\n } as any;\n }\n\n if (baseData.type === 'quiz') {\n const colors = style.colors || {};\n const normalizedOpts = normalizeOptions(data.options, data.isCorrect);\n const rawOptionFontSize = style.optionFontSize ?? style.optionFont?.fontSize ?? style.typography?.optionSize ?? style.options?.fontSize ?? 16;\n return {\n ...baseData,\n type: 'quiz',\n question: data.question || data.title || 'Quiz Question',\n options: normalizedOpts,\n showExplanation: data.showExplanation,\n url: data.url,\n styling: {\n ...baseData.styling,\n backgroundColor: parseBackground(style.background || style.containerBgColor || style.backgroundColor) || 'transparent',\n questionTextColor: parseColor(style.questionColor || colors.questionColor || style.question?.color || style.colors?.questionText) || '#FFFFFF',\n questionBgColor: parseBackground(style.questionBgColor || colors.questionBackground || style.question?.background || style.colors?.questionBg) || '#000000',\n optionBgColor: parseBackground(style.optionBgColor || colors.optionBackground || style.options?.background || style.colors?.optionBg) || '#FFFFFF',\n optionTextColor: parseColor(style.optionTextColor || colors.optionTextColor || style.options?.textColor || style.colors?.optionText) || '#2B2B2B',\n borderColor: parseColor(style.borderColor) || 'transparent',\n activeColor: parseColor(style.correctColor || colors.correctColor || style.correctBorderColor) || '#10b981',\n incorrectColor: parseColor(style.incorrectColor || colors.incorrectColor) || '#ef4444',\n optionBorderRadius: (style.optionRadius !== undefined ? (style.optionRadius >= 100 ? '999px' : getScaledHeightStyle(style.optionRadius, isStudio)) : (style.optionBorderRadius !== undefined ? (style.optionBorderRadius >= 100 ? '999px' : getScaledHeightStyle(style.optionBorderRadius, isStudio)) : '100px')),\n optionFontSize: getScaledFontStyle(rawOptionFontSize, isStudio),\n },\n } as any;\n }\n\n if (baseData.type === 'question') {\n return {\n ...baseData,\n type: 'question',\n question: data.question || data.title || 'Ask me a question',\n placeholder: data.placeholder || 'Type your answer...',\n styling: {\n ...baseData.styling,\n promptColor: parseColor(style.questionColor || style.promptColor || style.textColor),\n inputBgColor: parseBackground(style.inputBackground || style.inputBgColor),\n inputTextColor: parseColor(style.inputTextColor),\n submitBackground: parseBackground(style.submitBackground),\n },\n } as any;\n }\n\n if (baseData.type === 'image_quiz' || baseData.type === 'imageQuiz' || typeStr === 'media_quiz') {\n const rawOptionFontSize = style.optionFontSize ?? style.optionFont?.fontSize ?? style.typography?.optionSize ?? style.options?.fontSize ?? 13;\n return {\n ...baseData,\n type: 'image_quiz',\n question: data.question || data.title || 'Image Quiz',\n options: normalizeOptions(data.options || []),\n styling: {\n ...baseData.styling,\n questionTextColor: parseColor(style.questionColor),\n activeColor: parseColor(style.correctColor || style.correctBorderColor),\n incorrectColor: parseColor(style.incorrectColor),\n imageRadius: style.imageRadius ? getScaledHeightStyle(style.imageRadius, isStudio) : undefined,\n optionFontSize: getScaledFontStyle(rawOptionFontSize, isStudio),\n },\n } as any;\n }\n\n if (baseData.type === 'countdown') {\n return {\n ...baseData,\n type: 'countdown',\n title: data.title || 'Ends in...',\n targetDate: getCountdownTarget(data),\n styling: {\n ...baseData.styling,\n borderColor: parseColor(style.borderColor),\n digitBackground: parseBackground(style.digitBackground),\n digitColor: parseColor(style.digitColor),\n // Countdown digit/font sizes appear to be authored for final display already; scaling makes them too small.\n digitSize: (style.digitSize || style.fontSize) ? getScaledFontStyle(style.digitSize || style.fontSize, isStudio) : undefined,\n labelColor: parseColor(style.labelColor),\n titleColor: parseColor(style.titleColor),\n // Provide an optional label font size if backend uses a single fontSize.\n labelFontSize: style.labelFontSize ? getScaledFontStyle(style.labelFontSize, isStudio) : undefined,\n },\n display: data.display || item.display,\n } as any;\n }\n\n if (baseData.type === 'promo_code') {\n return {\n ...baseData,\n width: baseData.width ? Math.max(baseData.width, 65) : 75,\n type: 'promo_code',\n code: getPromoCode(item, data, style),\n styling: {\n ...baseData.styling,\n borderColor: parseColor(style.borderColor),\n },\n } as any;\n }\n\n if (baseData.type === 'reaction' || baseData.type === 'emoji_reaction') {\n const emojisArray = normalizeReactionEmojis(data);\n\n return {\n ...baseData,\n type: 'reaction',\n emojis: emojisArray.length > 0 ? emojisArray : ['😍', '👍'],\n } as any;\n }\n\n return baseData as any;\n });\n\n // 1c. Map shopable elements\n const displayShopable = shopableContent.map((item: any) => {\n const matchedStyling =\n shopableStyling.find((s: any) => String(s?.id) === String(item?.id)) ||\n shopableStyling.find((s: any) => s?.id === undefined) ||\n {};\n\n const source = getEditorSource(item, content);\n const isStudio = source === 'studio';\n\n // Some payloads send styling directly on each shopable item instead of item.styling/content.styling.shopable\n const inlineStyling = {\n position: item?.position,\n size: item?.size,\n rotation: item?.rotation,\n z: item?.z,\n background: item?.background,\n cardBackground: item?.cardBackground,\n cardBorderRadius: item?.cardBorderRadius,\n cardRadiusPercent: item?.cardRadiusPercent,\n transparent: item?.transparent,\n textColor: item?.textColor,\n buttonBackground: item?.buttonBackground,\n buttonTextColor: item?.buttonTextColor,\n buttonFontSize: item?.buttonFontSize,\n buttonBorderRadius: item?.buttonBorderRadius,\n titleColor: item?.titleColor,\n titleFontSize: item?.titleFontSize,\n titleFontWeight: item?.titleFontWeight,\n priceColor: item?.priceColor,\n priceFontSize: item?.priceFontSize,\n priceFontWeight: item?.priceFontWeight,\n mrpColor: item?.mrpColor,\n mrpFontSize: item?.mrpFontSize,\n mrpFontWeight: item?.mrpFontWeight,\n imageRadius: item?.imageRadius,\n opacity: item?.opacity,\n animation: item?.animation,\n };\n\n const styling = {\n ...matchedStyling,\n ...(item?.styling || {}),\n ...Object.fromEntries(Object.entries(inlineStyling).filter(([, value]) => value !== undefined)),\n };\n\n const position = styling.position || {};\n const size = styling.size || {};\n\n // Radius values coming from Studio are based on the 1080x1920-ish canvas units.\n // Converting `cardRadiusPercent` directly to CSS '%' makes the card overly round.\n // Prefer a scaled px value.\n const rawCardBorderRadius = styling.cardBorderRadius !== undefined ? Number(styling.cardBorderRadius) : undefined;\n const rawCardRadiusPercent = styling.cardRadiusPercent !== undefined ? Number(styling.cardRadiusPercent) : undefined;\n const rawHeight = size.height !== undefined ? Number(size.height) : undefined;\n const radiusFromPercent =\n rawCardBorderRadius === undefined && rawCardRadiusPercent !== undefined && rawHeight !== undefined\n ? (Math.max(0, Math.min(100, rawCardRadiusPercent)) / 100) * (rawHeight / 2)\n : undefined;\n\n const resolvedCardBorderRadius = (rawCardBorderRadius ?? radiusFromPercent);\n const resolvedCardBorderRadiusPx =\n resolvedCardBorderRadius !== undefined && !isNaN(resolvedCardBorderRadius)\n ? resolvedCardBorderRadius * scale_factor\n : undefined;\n\n // Standard coordinate conversion - using backend data directly as requested\n const x_percent = position.x !== undefined ? (isStudio ? Number(position.x) : (Number(position.x) / canvaWidth) * 100) : 0;\n const width_percent = size.width !== undefined ? (isStudio ? Number(size.width) : (Number(size.width) / canvaWidth) * 100) : 100;\n const height_percent = size.height !== undefined ? (isStudio ? Number(size.height) : (Number(size.height) / canvaHeight) * 100) : undefined;\n\n // Default to the bottom if position is missing, otherwise use provided Y\n let y_percent = position.y !== undefined ? (isStudio ? Number(position.y) : (Number(position.y) / canvaHeight) * 100) : (height_percent ? 100 - height_percent - 2.5 : 85);\n\n // Tighten the bottom-snapping logic to remove the \"space\" as requested\n if (height_percent && (y_percent + height_percent) > 96) {\n y_percent = Math.max(0, 100 - height_percent);\n } else if (y_percent > 75 && height_percent && (y_percent + height_percent) > 91) {\n y_percent = Math.max(0, 100 - height_percent - 1);\n }\n\n const isProductType = Array.isArray(item.product) && item.product.length > 0;\n const itemsSource = isProductType ? item.product : (item.static || []);\n\n return {\n id: item.id || Math.random().toString(),\n type: 'buy',\n shopableType: isProductType ? 'product' : 'static',\n x: x_percent,\n y: y_percent,\n width: width_percent,\n height: height_percent,\n rotation: styling.rotation ?? 0,\n z: styling.z ?? 10,\n products: itemsSource.map((p: any) => {\n // Handle potential nesting in productData key as seen in latest backend JSON\n const sourceData = p.productData || p || {};\n const attr = sourceData.attributes || p.attributes || {};\n\n // If sales_price exists in attributes, it's the current price, and p.price is the old price\n const currentPrice = attr.sales_price || sourceData.price || attr.price || p.price;\n const oldPrice = attr.sales_price ? (sourceData.price || attr.price || p.price) : (sourceData.oldPrice || p.oldPrice);\n\n // Robust attribute mapping - ensure all metadata is preserved for the modal\n const colorVal = sourceData.color || attr.color || p.color;\n const sizeVal = sourceData.size || attr.size || p.size;\n \n let colors = attr.colors || [];\n if (colors.length === 0 && colorVal) {\n colors = [{ id: colorVal, hex: colorVal, name: colorVal }];\n }\n\n let sizes = attr.sizes || [];\n if (sizes.length === 0 && sizeVal) {\n sizes = typeof sizeVal === 'string' ? sizeVal.split(',').map(s => s.trim()) : [sizeVal];\n }\n\n const consolidatedAttributes = {\n description: sourceData.description || attr.description || p.description,\n color: colorVal,\n size: sizeVal,\n colors: colors,\n sizes: sizes,\n imageUrls: attr.imageUrls || [attr.image_link || sourceData.imageUrl || sourceData.image || p.imageUrl || p.image || p.url].filter(Boolean),\n availability: sourceData.availability || attr.availability || p.availability,\n tags: sourceData.tags || attr.tags || p.tags,\n ...attr,\n };\n\n return {\n id: sourceData.productId || sourceData.id || p.productId || p.id || Math.random().toString(),\n image: attr.image_link || sourceData.imageUrl || sourceData.image || p.imageUrl || p.image || p.url,\n url: sourceData.link || sourceData.url || p.link || p.url || p.redirectUrl,\n title: sourceData.title || p.title,\n price: currentPrice,\n oldPrice: oldPrice,\n redirectUrl: p.redirectUrl || sourceData.link || p.link || p.url,\n svg: sourceData.svg || p.svg,\n productId: sourceData.productId || p.productId,\n collectionId: sourceData.collectionId || p.collectionId,\n feedId: sourceData.feedId || p.feedId,\n attributes: consolidatedAttributes,\n };\n }),\n styling: {\n backgroundColor: parseBackground(styling.background),\n cardBackground: parseBackground(styling.cardBackground) || parseBackground(styling.background) || '#ffffff',\n cardBorderRadius: resolvedCardBorderRadius !== undefined && !isNaN(resolvedCardBorderRadius)\n ? (isStudio ? `${resolvedCardBorderRadius}cqh` : `${resolvedCardBorderRadiusPx}px`)\n : (isStudio ? '1cqh' : '10px'),\n // Keep for backward compatibility, but UI should prefer px radius above.\n cardRadiusPercent: rawCardRadiusPercent,\n transparent: styling.transparent === true,\n textColor: parseColor(styling.textColor) || '#ffffff',\n buttonBackground: parseBackground(styling.buttonBackground) || '#000000',\n buttonTextColor: parseColor(styling.buttonTextColor) || '#ffffff',\n buttonFontSize: getScaledFontStyle(styling.buttonFontSize || 12, isStudio),\n buttonBorderRadius: styling.buttonBorderRadius !== undefined ? (isStudio ? `${styling.buttonBorderRadius}cqh` : `${styling.buttonBorderRadius}px`) : (isStudio ? '10cqh' : '100px'),\n titleColor: parseColor(styling.titleColor || styling.textColor) || '#1a1a2e',\n titleFontSize: getScaledFontStyle(styling.titleFontSize || 14, isStudio),\n titleFontWeight: styling.titleFontWeight ? String(styling.titleFontWeight) : '600',\n priceColor: parseColor(styling.priceColor || styling.textColor) || '#1a1a2e',\n priceFontSize: getScaledFontStyle(styling.priceFontSize || 16, isStudio),\n priceFontWeight: styling.priceFontWeight ? String(styling.priceFontWeight) : '700',\n mrpColor: parseColor(styling.mrpColor) || '#8b8b98',\n mrpFontSize: getScaledFontStyle(styling.mrpFontSize || 12, isStudio),\n mrpFontWeight: styling.mrpFontWeight ? String(styling.mrpFontWeight) : '500',\n imageRadius: styling.imageRadius !== undefined ? (isStudio ? `${styling.imageRadius}cqh` : `${Number(styling.imageRadius) * scale_factor}px`) : (isStudio ? '1cqh' : '10px'),\n animation: getAnimationStyles(styling.animation),\n },\n };\n });\n\n // 2. Map static images\n const displayImages = images.map((img: any) => {\n const position = img.position || img.postion || { x: 0, y: 0 };\n return {\n id: img.id || Math.random().toString(),\n type: 'image',\n x: slideIsStudio ? Number(position.x) : (position.x / canvaWidth) * 100,\n y: slideIsStudio ? Number(position.y) : (position.y / canvaHeight) * 100,\n width: slideIsStudio ? Number(img.width) : (img.width / canvaWidth) * 100,\n height: img.height ? (slideIsStudio ? Number(img.height) : (img.height / canvaHeight) * 100) : undefined,\n url: img.link || img.url,\n z: img.z ?? 0,\n };\n });\n\n // 3. Map static text\n const displayText = texts.map((txt: any) => {\n const stylingTexts = content?.styling?.text || [];\n const styleObj = stylingTexts.find((st: any) => st.id === txt.id) || {};\n\n const position = txt.position || styleObj.position || { x: 0, y: 0 };\n const font = txt.font || styleObj.font || {};\n const size = txt.size || styleObj.size || {};\n const alignment = txt.alignment || styleObj.alignment || {};\n const color = txt.color || styleObj.color;\n const fontDecoration = font.fontDecoration || [];\n\n const textDecoration = fontDecoration.includes('underline')\n ? 'underline'\n : (fontDecoration.includes('line-through') ? 'line-through' : undefined);\n\n const txtRotation = txt.rotation !== undefined ? txt.rotation : styleObj.rotation;\n\n return {\n id: txt.id || Math.random().toString(),\n type: 'text',\n x: slideIsStudio ? Number(position.x) : (position.x / canvaWidth) * 100,\n y: slideIsStudio ? Number(position.y) : (position.y / canvaHeight) * 100,\n width: size.width ? (slideIsStudio ? Number(size.width) : (size.width / canvaWidth) * 100) : undefined,\n height: size.height ? (slideIsStudio ? Number(size.height) : (size.height / canvaHeight) * 100) : undefined,\n rotation: txtRotation ?? 0,\n text: txt.text || txt.value || styleObj.text || styleObj.value || '',\n z: txt.z ?? styleObj.z ?? 1,\n styling: {\n color: parseColor(color) || '#000000',\n fontSize: font.fontSize ? getScaledFontStyle(font.fontSize, slideIsStudio) : undefined,\n fontFamily: font.fontFamily,\n fontStyle: font.fontStyle || (fontDecoration.includes('italic') ? 'italic' : 'normal'),\n fontWeight: font.fontWeight || (fontDecoration.includes('bold') ? 'bold' : 'normal'),\n textDecoration,\n lineHeight: txt.lineHeight !== undefined ? txt.lineHeight : styleObj.lineHeight,\n letterSpacing: (txt.letterSpacing !== undefined ? txt.letterSpacing : styleObj.letterSpacing) !== undefined\n ? `${txt.letterSpacing !== undefined ? txt.letterSpacing : styleObj.letterSpacing}px`\n : undefined,\n opacity: (txt.opacity !== undefined ? txt.opacity : styleObj.opacity) !== undefined\n ? Number(txt.opacity !== undefined ? txt.opacity : styleObj.opacity) / 100\n : undefined,\n textAlign: alignment.horizontalAlignment || 'left',\n verticalAlignment: alignment.verticalAlignment || 'top',\n },\n };\n });\n\n // 4. Map CTAs\n const displayCtas = ctas.map((cta: any) => {\n const stylingCtas = content?.styling?.ctas || [];\n const styleObj = stylingCtas.find((st: any) => st.id === cta.id) || {};\n\n const position = cta.position || styleObj.position || { x: 0, y: 0 };\n const size = cta.size || styleObj.size || {};\n const font = cta.font || styleObj.font || {};\n const fontDecoration = font.fontDecoration || [];\n\n const textDecoration = fontDecoration.includes('underline')\n ? 'underline'\n : (fontDecoration.includes('line-through') ? 'line-through' : undefined);\n\n const txtRotation = cta.rotation !== undefined ? cta.rotation : styleObj.rotation;\n\n return {\n id: cta.id || Math.random().toString(),\n type: 'cta',\n x: slideIsStudio ? Number(position.x) : (position.x / canvaWidth) * 100,\n y: slideIsStudio ? Number(position.y) : (position.y / canvaHeight) * 100,\n width: size.width ? (slideIsStudio ? Number(size.width) : (size.width / canvaWidth) * 100) : undefined,\n height: size.height ? (slideIsStudio ? Number(size.height) : (size.height / canvaHeight) * 100) : undefined,\n rotation: txtRotation ?? 0,\n text: cta.text || styleObj.text || 'Learn More',\n redirectUrl: cta.redirectUrl || styleObj.redirectUrl || cta.link || styleObj.link,\n ctaType: cta.type || styleObj.type || 'classic',\n url: cta.url || styleObj.url,\n z: cta.z ?? styleObj.z ?? 10,\n source: slideIsStudio ? 'studio' : 'dashboard',\n styling: {\n backgroundColor: parseBackground(cta.background || styleObj.background),\n textColor: parseColor(cta.textColor || styleObj.textColor) || '#FFFFFF',\n borderColor: parseColor(cta.borderColor || styleObj.borderColor) || 'transparent',\n borderWidth: cta.borderWidth !== undefined ? cta.borderWidth : styleObj.borderWidth,\n borderRadius: getScaledHeightStyle(cta.borderRadius !== undefined ? cta.borderRadius : styleObj.borderRadius, slideIsStudio),\n fontSize: font.fontSize ? getScaledFontStyle(font.fontSize, slideIsStudio) : undefined,\n fontFamily: font.fontFamily,\n fontStyle: font.fontStyle || (fontDecoration.includes('italic') ? 'italic' : 'normal'),\n fontWeight: font.fontWeight || (fontDecoration.includes('bold') ? 'bold' : 'normal'),\n textDecoration,\n pillH: styleObj.pillH,\n arrowAnimation: styleObj.arrowAnimation,\n arrowColor: parseColor(styleObj.arrowColor),\n arrowSize: styleObj.arrowSize,\n transparent: styleObj.transparent,\n },\n };\n });\n\n // Combine & Sort by Z index index layer mappings stack\n const displayItems = [...displayElements, ...displayInteractions, ...displayShopable, ...displayImages, ...displayText, ...displayCtas]\n .filter((item: any) => {\n if (!item.duration) return true;\n const { start, end } = item.duration;\n return elapsedTime >= start && elapsedTime <= end;\n })\n .sort((a: any, b: any) => (a.z ?? 0) - (b.z ?? 0));\n\n console.log(\"InteractiveOverlay Debug - content.ctas:\", ctas, \"displayCtas:\", displayCtas, \"displayItems:\", displayItems);\n\n const overlayStyle: React.CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 10,\n pointerEvents: 'none',\n overflow: 'hidden',\n containerType: 'size',\n };\n\n return (\n <div style={overlayStyle}>\n <style>{`\n @keyframes appstorys-fade-in {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n @keyframes appstorys-classic-in {\n 0% { opacity: 0; transform: scale(0.7); }\n 70% { opacity: 1; transform: scale(1.05); }\n 100% { opacity: 1; transform: scale(1); }\n }\n @keyframes appstorys-rotate-in {\n from { opacity: 0; transform: rotate(-20deg) scale(0.5); }\n to { opacity: 1; transform: rotate(0deg) scale(1); }\n }\n @keyframes appstorys-bounce-in {\n 0% { opacity: 0; transform: scale(0.3); }\n 50% { opacity: 1; transform: scale(1.1); }\n 70% { opacity: 1; transform: scale(0.95); }\n 100% { opacity: 1; transform: scale(1); }\n }\n `}</style>\n {displayItems.map((item: any) => {\n if (!item || typeof item !== 'object') return null;\n const typeStr = (item.type || '').toLowerCase();\n if (!typeStr) return null; // Ignore invalid element items\n\n return (\n <InteractiveItem\n key={item.id}\n data={item as StickerData}\n onInteraction={onInteraction}\n isEditing={isEditing}\n />\n );\n })}\n </div>\n );\n};","import React, { useState } from 'react';\n\ninterface PlayPauseButtonProps {\n isPaused: boolean;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n style?: React.CSSProperties;\n size?: number;\n}\n\nexport const PlayPauseButton: React.FC<PlayPauseButtonProps> = ({ \n isPaused, \n onPress, \n style, \n size = 36 \n}) => {\n const [isHovered, setIsHovered] = useState(false);\n\n return (\n <button\n onClick={onPress}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n background: isHovered ? 'rgba(255, 255, 255, 0.15)' : 'rgba(255, 255, 255, 0.08)',\n border: isHovered ? '1px solid white' : '1px solid rgba(255, 255, 255, 0.1)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '10px',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n padding: 0,\n outline: 'none',\n ...style,\n }}\n >\n {isPaused ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\">\n <path d=\"M5 3.867v16.266c0 .54.58.88 1.05.61l14.133-8.133c.46-.27.46-.94 0-1.21L6.05 3.257C5.58 2.987 5 3.327 5 3.867z\" />\n </svg>\n ) : (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n )}\n </button>\n );\n};\n\nexport default PlayPauseButton;\n","import React from 'react';\nimport { StorySlideCta } from '../../../types';\nimport { personalizeText } from '../../../core/personalization';\nimport { resolveFontFamily } from '../../../core/fontManager';\n\ninterface CtaProps {\n cta?: StorySlideCta | null;\n buttonText?: string;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\nconst mapAlignment = (alignment?: string) => {\n switch (alignment) {\n case \"left\": return \"flex-start\";\n case \"right\": return \"flex-end\";\n default: return \"center\";\n }\n};\n\nconst Cta: React.FC<CtaProps> = ({ cta, buttonText, onPress }) => {\n if (!cta || !buttonText || buttonText.trim() === '') {\n return null;\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n bottom: cta?.margin?.bottom,\n left: cta?.margin?.left,\n right: cta?.margin?.right,\n display: 'flex',\n justifyContent: mapAlignment(cta?.container?.alignment),\n width: '100%',\n pointerEvents: 'none',\n boxSizing: 'border-box',\n zIndex: 10,\n }}\n >\n <button\n style={{\n backgroundColor: cta?.container?.backgroundColor || '#F7921C',\n borderColor: cta?.container?.borderColor || 'transparent',\n borderWidth: cta?.container?.borderWidth ?? 0,\n borderStyle: cta?.container?.borderWidth ? 'solid' : 'none',\n borderTopRightRadius: cta?.cornerRadius?.topRight,\n borderTopLeftRadius: cta?.cornerRadius?.topLeft,\n borderBottomRightRadius: cta?.cornerRadius?.bottomRight,\n borderBottomLeftRadius: cta?.cornerRadius?.bottomLeft,\n height: cta?.container?.height || 42,\n width: cta?.container?.ctaFullWidth\n ? \"100%\"\n : cta?.container?.ctaWidth || \"auto\",\n justifyContent: \"center\",\n alignItems: \"center\",\n display: 'flex',\n cursor: 'pointer',\n outline: 'none',\n pointerEvents: 'auto',\n padding: '0 12px',\n boxSizing: 'border-box',\n }}\n onClick={onPress}\n >\n <span\n style={{\n color: cta?.text?.color || '#ffffff',\n fontSize: cta?.text?.fontSize || 14,\n fontFamily: resolveFontFamily(cta?.text?.fontFamily),\n fontWeight: cta?.text?.fontDecoration?.includes(\"bold\") ? \"bold\" : \"normal\",\n fontStyle: cta?.text?.fontDecoration?.includes(\"italic\") ? \"italic\" : \"normal\",\n textDecorationLine: cta?.text?.fontDecoration?.includes(\"underline\") ? \"underline\" : \"none\",\n textAlign: \"center\",\n }}\n >\n {personalizeText(buttonText)}\n </span>\n </button>\n </div>\n );\n};\n\nexport default Cta;","import React from 'react';\nimport { PipButtonConfig } from '../../Pip/types';\n\ninterface SoundButtonProps {\n config: PipButtonConfig | null;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n style?: React.CSSProperties;\n ignoreSizeAndMargin?: boolean;\n enabled?: boolean;\n type: 'mute' | 'unmute';\n}\n\nexport const SoundButton: React.FC<SoundButtonProps> = ({\n config,\n onPress,\n ignoreSizeAndMargin = false,\n enabled,\n style,\n type,\n}) => {\n if (!config || !enabled) {\n return null;\n }\n\n const {\n size: backendSize = 18,\n margin,\n color,\n image,\n selectedStyle,\n } = config;\n\n const size = ignoreSizeAndMargin ? 40 : backendSize;\n\n // Safe margin access with correct defaults\n const marginTop = ignoreSizeAndMargin ? 0 : (margin?.top ?? 0);\n const marginBottom = ignoreSizeAndMargin ? 0 : (margin?.bottom ?? 0);\n const marginLeft = ignoreSizeAndMargin ? 0 : (margin?.left ?? 0);\n const marginRight = ignoreSizeAndMargin ? 0 : (margin?.right ?? 0);\n\n const containerStyle: React.CSSProperties = {\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n width: size,\n height: size,\n backgroundColor: color?.fill || 'transparent',\n borderColor: color?.stroke || 'transparent',\n borderWidth: size * 0.05,\n borderRadius: '50%',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 1000000,\n display: 'flex',\n ...(ignoreSizeAndMargin\n ? {}\n : {\n marginTop: config.margin?.top ?? 0,\n marginRight: config.margin?.right ?? 0,\n marginBottom: config.margin?.bottom ?? 0,\n marginLeft: config.margin?.left ?? 0,\n }),\n ...style,\n };\n\n const renderDefaultIcon = () => {\n const stroke = color?.cross || '#ffffff';\n if (type === 'mute') {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polygon points=\"4,10 8,10 13,6 13,18 8,14 4,14\" fill=\"none\" stroke={stroke} strokeWidth=\"2.2\" strokeLinejoin=\"round\" />\n <line x1=\"16\" y1=\"8\" x2=\"21\" y2=\"16\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <line x1=\"21\" y1=\"8\" x2=\"16\" y2=\"16\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n </svg>\n );\n } else {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"70%\" height=\"70%\" aria-hidden>\n <polygon points=\"4,10 8,10 13,6 13,18 8,14 4,14\" fill=\"none\" stroke={stroke} strokeWidth=\"2.2\" strokeLinejoin=\"round\" />\n <path d=\"M16 10 Q18 12 16 14\" fill=\"none\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <path d=\"M18 8 Q22 12 18 16\" fill=\"none\" stroke={stroke} strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n };\n\n return (\n <button\n onClick={onPress}\n style={{\n ...containerStyle,\n border: containerStyle.borderColor ? `${containerStyle.borderWidth}px solid ${containerStyle.borderColor as string}` : 'none',\n padding: 0,\n cursor: 'pointer',\n outline: 'none',\n }}\n title={selectedStyle || ''}\n >\n {image && image.trim() !== '' ? (\n <img\n src={image}\n style={{ width: size, height: size, objectFit: 'contain' }}\n alt={type}\n />\n ) : (\n renderDefaultIcon()\n )}\n </button>\n );\n};","import React from 'react';\n\nexport interface ShareButtonConfig {\n color: {\n cross: string;\n fill: string;\n stroke: string;\n };\n enabled: boolean;\n image: string;\n margin: {\n bottom: number;\n left: number;\n right: number;\n top: number;\n };\n selectedStyle?: string;\n size: number;\n}\n\ninterface ShareButtonProps {\n config: ShareButtonConfig | null;\n onPress: (event: React.MouseEvent<HTMLButtonElement>) => void;\n style?: React.CSSProperties;\n ignoreSizeAndMargin?: boolean;\n}\n\nconst ShareButton: React.FC<ShareButtonProps> = ({ config, onPress, ignoreSizeAndMargin = false, style }) => {\n if (!config || config.enabled === false) {\n return null;\n }\n\n const {\n size: backendSize = 18,\n margin,\n color,\n image,\n selectedStyle,\n } = config;\n\n const size = ignoreSizeAndMargin ? 40 : backendSize;\n\n const containerStyle: React.CSSProperties = {\n marginTop: ignoreSizeAndMargin ? 0 : (margin?.top ?? 0),\n marginBottom: ignoreSizeAndMargin ? 0 : (margin?.bottom ?? 0),\n marginLeft: ignoreSizeAndMargin ? 0 : (margin?.left ?? 0),\n marginRight: ignoreSizeAndMargin ? 0 : (margin?.right ?? 0),\n width: size,\n height: size,\n backgroundColor: color?.fill || 'transparent',\n borderColor: color?.stroke || 'transparent',\n borderWidth: size * 0.05,\n borderRadius: '50%',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 1000000,\n position: 'absolute',\n display: 'flex',\n padding: 0,\n cursor: 'pointer',\n outline: 'none',\n borderStyle: color?.stroke ? 'solid' : 'none',\n ...style,\n };\n\n const renderDefaultIcon = () => {\n const stroke = color?.cross || '#ffffff';\n return (\n <svg viewBox=\"0 0 24 24\" width=\"60%\" height=\"60%\" fill=\"none\" stroke={stroke} strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <circle cx=\"18\" cy=\"5\" r=\"3\" />\n <circle cx=\"6\" cy=\"12\" r=\"3\" />\n <circle cx=\"18\" cy=\"19\" r=\"3\" />\n <line x1=\"8.59\" y1=\"13.51\" x2=\"15.42\" y2=\"17.49\" />\n <line x1=\"15.41\" y1=\"6.51\" x2=\"8.59\" y2=\"10.49\" />\n </svg>\n );\n };\n\n return (\n <button\n onClick={onPress}\n style={containerStyle}\n title={selectedStyle || ''}\n >\n {image && image.trim() !== '' ? (\n <img\n src={image}\n style={{ width: size, height: size, objectFit: 'contain' }}\n alt=\"share\"\n />\n ) : (\n renderDefaultIcon()\n )}\n </button>\n );\n};\n\nexport default ShareButton;","import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { CampaignWidget } from '../../types';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport useViewportTracking from '../../hooks/useViewportTracking';\nimport { resolveTarget } from '../../core/resolveTarget';\n\ninterface WidgetProps {\n position?: string;\n}\n\n/**\n * Simple web widget component mirroring RN Widgets.tsx implementation\n * - Accepts optional position prop\n * - Fetches single campaign via useCampaigns hook\n * - Renders carousel with auto-advance (full) or manual scroll (half)\n * - Portals into host element if position target found\n */\nexport const Widget: React.FC<WidgetProps> = ({ position }) => {\n const hookData = useCampaigns<CampaignWidget>('WID', { position });\n const campaigns = useAppStorysStore((state) => state.campaigns);\n const allCampaigns = useAppStorysStore((state) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state) => state.currentScreen);\n\n const normalizeScreen = (value?: string | null): string => (value || '').trim().toLowerCase();\n\n const data = hookData ?? ((): CampaignWidget | undefined => {\n const screen = normalizeScreen(currentScreen);\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign) => {\n const item = campaign as CampaignWidget;\n if (item.campaign_type !== 'WID') return false;\n if (position && item.position !== position) return false;\n const hasTrigger = Boolean((item as any).trigger_event ?? (item as any).trigger);\n const displayTriggerReady = (item as any).display_trigger !== false && !hasTrigger;\n const matchesScreen = !normalizeScreen(item.screen) || normalizeScreen(item.screen) === screen;\n return displayTriggerReady && matchesScreen;\n }) as CampaignWidget | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignWidget;\n } catch {\n return found;\n }\n })();\n const [activeIndex, setActiveIndex] = useState(0);\n const containerRef = useRef<HTMLDivElement>(null);\n const autoAdvanceRef = useRef<ReturnType<typeof setInterval> | null>(null);\n // Derived values (must be declared unconditionally so hooks stay stable)\n const details = data?.details || ({} as any);\n const images = (details.widget_images || []) as any[];\n const styling = details.styling || {};\n const widgetType = details.type || 'full';\n const isHalf = widgetType === 'half';\n\n // Track per-image impressions only when widget is visible in viewport\n const trackedImpressionsRef = useRef<string[]>([]);\n const isInViewportRef = useRef(false);\n\n // Viewport tracking: set flag and track first image when widget enters view\n const trackFirstImpression = useCallback(() => {\n isInViewportRef.current = true;\n const firstImage = images[activeIndex];\n if (firstImage?.id) trackImpression(firstImage.id);\n }, [images, activeIndex]); // eslint-disable-line\n const viewportRef = useViewportTracking(trackFirstImpression);\n\n const trackImpression = (widgetImageId?: string) => {\n if (!data?.id || !widgetImageId) return;\n if (!isInViewportRef.current) return; // gate: only track if in viewport\n if (trackedImpressionsRef.current.includes(widgetImageId)) return;\n trackedImpressionsRef.current.push(widgetImageId);\n void trackEvent('viewed', data.id, { widget_image: widgetImageId });\n };\n\n // Auto-advance full widgets every 5 seconds\n useEffect(() => {\n if (widgetType === 'full' && images.length > 1) {\n autoAdvanceRef.current = setInterval(() => {\n setActiveIndex((prev) => {\n const next = prev + 1;\n return next >= images.length ? 0 : next;\n });\n }, 5000);\n\n return () => {\n if (autoAdvanceRef.current) {\n clearInterval(autoAdvanceRef.current as any);\n }\n };\n }\n return undefined;\n }, [widgetType, images.length]);\n\n const handleClick = (imageId: string, link: string) => {\n if (data?.id) void trackEvent('clicked', data.id, { widget_image: imageId });\n if (link) {\n // Try reveal flow for internal campaign links first\n if (!link.startsWith('http')) {\n try {\n const revealed = revealCampaignFromLink(link);\n if (revealed) return;\n } catch (err) {\n console.warn('[Widget] revealCampaignFromLink error', err);\n }\n console.log('[Widget] Internal link:', link);\n return;\n }\n\n window.open(link, '_blank');\n }\n };\n\n const handleScroll = () => {\n if (containerRef.current && isHalf) {\n const { scrollLeft, offsetWidth } = containerRef.current;\n const itemWidth = (offsetWidth / 2) + 12;\n const index = Math.round(scrollLeft / itemWidth);\n setActiveIndex(index);\n }\n };\n\n // For full widgets: track impression when active slide changes\n useEffect(() => {\n if (!data?.id || widgetType !== 'full' || images.length === 0) return;\n const img = images[activeIndex];\n if (img && img.id) trackImpression(img.id);\n }, [activeIndex, data?.id, images, widgetType]);\n\n // For half widgets: track impressions based on visible area (50% coverage)\n useEffect(() => {\n if (!data?.id || !containerRef.current || !isHalf) return;\n\n const el = containerRef.current;\n const checkVisibility = () => {\n const { scrollLeft, offsetWidth } = el;\n const itemWidth = (offsetWidth / 2) + 12;\n images.forEach((img: any, idx: number) => {\n const itemLeft = idx * itemWidth;\n const itemRight = itemLeft + itemWidth;\n const viewLeft = scrollLeft;\n const viewRight = scrollLeft + offsetWidth;\n const overlap = Math.max(0, Math.min(itemRight, viewRight) - Math.max(itemLeft, viewLeft));\n if (overlap / itemWidth >= 0.5) {\n trackImpression(img.id);\n }\n });\n };\n\n // initial check\n checkVisibility();\n // listen for scroll events\n el.addEventListener('scroll', checkVisibility);\n return () => el.removeEventListener('scroll', checkVisibility);\n }, [data?.id, isHalf, images]);\n\n // Container styles\n const containerStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'row',\n flexWrap: isHalf ? 'nowrap' : 'wrap',\n gap: '12px',\n width: '100%',\n height: isHalf && details.height ? `${details.height}px` : 'auto',\n marginTop: styling.topMargin ? `${styling.topMargin}px` : '0px',\n marginBottom: styling.bottomMargin ? `${styling.bottomMargin}px` : '0px',\n marginLeft: styling.leftMargin ? `${styling.leftMargin}px` : '0px',\n marginRight: styling.rightMargin ? `${styling.rightMargin}px` : '0px',\n boxSizing: 'border-box',\n overflowX: isHalf ? 'auto' : 'hidden',\n overflowY: 'hidden',\n scrollSnapType: isHalf ? 'x mandatory' : undefined,\n msOverflowStyle: 'none',\n scrollbarWidth: 'none',\n };\n\n // Item styles\n const getItemStyle = (index: number): React.CSSProperties => ({\n flex: isHalf ? '0 0 calc(50% - 6px)' : '0 0 100%',\n height: isHalf && details.height ? `${details.height}px` : 'auto',\n cursor: 'pointer',\n position: 'relative',\n overflow: 'hidden',\n borderRadius: styling.borderRadius ? `${styling.borderRadius}px` : '0px',\n borderTopLeftRadius: styling.topLeftRadius ? `${styling.topLeftRadius}px` : undefined,\n borderTopRightRadius: styling.topRightRadius ? `${styling.topRightRadius}px` : undefined,\n borderBottomLeftRadius: styling.bottomLeftRadius ? `${styling.bottomLeftRadius}px` : undefined,\n borderBottomRightRadius: styling.bottomRightRadius ? `${styling.bottomRightRadius}px` : undefined,\n boxShadow: '0 4px 12px rgba(0,0,0,0.08)',\n scrollSnapAlign: 'start',\n });\n\n // Render content\n const content = (\n <div style={{ width: '100%', position: 'relative' }}>\n <style>{`\n .widget-scroll-container::-webkit-scrollbar {\n display: none;\n }\n `}</style>\n\n {/* Carousel/grid container */}\n <div\n ref={(el) => { (containerRef as any).current = el; viewportRef(el as HTMLElement); }}\n className=\"widget-scroll-container\"\n style={containerStyle}\n onScroll={handleScroll}\n >\n {isHalf\n ? // Half: show all images (2 per row with horizontal scroll)\n images.map((img: any, idx: number) => (\n <div key={img.id} style={getItemStyle(idx)}>\n <img\n src={img.image}\n alt=\"widget\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n display: 'block',\n }}\n onClick={() => handleClick(img.id, img.link)}\n />\n </div>\n ))\n : // Full: show only current slide (auto-advances)\n images.length > 0 && (\n <div key={`slide-${activeIndex}`} style={getItemStyle(0)}>\n <img\n src={images[activeIndex].image}\n alt=\"widget\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n display: 'block',\n }}\n onClick={() => handleClick(images[activeIndex].id, images[activeIndex].link)}\n />\n </div>\n )}\n </div>\n\n {/* Dots indicator for full widgets */}\n {widgetType === 'full' && images.length > 1 && (\n <div style={{\n display: 'flex',\n justifyContent: 'center',\n gap: '6px',\n marginTop: '8px',\n width: '100%'\n }}>\n {images.map((_: any, i: number) => (\n <div\n key={i}\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: i === activeIndex ? '#333' : '#ccc',\n transition: 'background-color 0.2s ease',\n }}\n />\n ))}\n </div>\n )}\n </div>\n );\n\n // Try to find host element if position is declared (mirror RN behavior)\n let target: Element | null = null;\n if (data?.position) {\n const key = String(data.position || '').replace(/^widget_/, '');\n target = resolveTarget(key);\n\n if (target) {\n console.log('[Widget] Portal target found for campaign', data?.id);\n } else {\n console.log('[Widget] No portal target found for position:', data?.position, 'rendering inline for campaign:', data?.id);\n }\n }\n\n // Portal into host if found, otherwise render inline\n if (target) {\n return createPortal(content, target);\n }\n\n return content;\n};\n\nexport default Widget;\n","import { useEffect, useRef } from 'react';\n\n/**\n * Viewport-based `viewed` tracking hook.\n *\n * Fires `onVisible()` only once when the observed element enters the viewport\n * with at least `threshold` (default 50%) of it visible.\n *\n * This ensures `viewed` analytics events are NOT sent for campaigns that are\n * below the fold or otherwise outside the user's visible screen, mirroring\n * native viewport-based impression tracking.\n *\n * @param onVisible - callback to run when element enters viewport\n * @param threshold - fraction of element that must be visible (0–1, default 0.5)\n */\nexport default function useViewportTracking(\n onVisible: () => void,\n threshold = 0.5\n): React.RefCallback<HTMLElement> {\n const onVisibleRef = useRef(onVisible);\n const hasTrackedRef = useRef(false);\n const elementRef = useRef<HTMLElement | null>(null);\n const observerRef = useRef<IntersectionObserver | null>(null);\n\n // Always keep callback ref fresh without re-subscribing observer\n useEffect(() => {\n onVisibleRef.current = onVisible;\n }, [onVisible]);\n\n const refCallback: React.RefCallback<HTMLElement> = (el) => {\n // Disconnect existing observer if element changes\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n elementRef.current = el;\n hasTrackedRef.current = false; // reset on campaign data change\n\n if (!el) {\n // Element unmounted or ref cleaned up, do nothing\n return;\n }\n\n if (typeof IntersectionObserver === 'undefined') {\n // Fallback: browsers without IntersectionObserver fire immediately\n onVisibleRef.current();\n return;\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n observerRef.current = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n \n if (entry.isIntersecting && !hasTrackedRef.current) {\n // Require the element to stay in viewport for 500ms to avoid false\n // positives from layout shifts during initial page load\n if (!timeoutId) {\n timeoutId = setTimeout(() => {\n hasTrackedRef.current = true;\n onVisibleRef.current();\n observerRef.current?.disconnect();\n timeoutId = null;\n }, 500);\n }\n } else {\n // If it leaves viewport before 500ms, cancel the tracking\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n },\n { threshold }\n );\n\n observerRef.current.observe(el);\n };\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n observerRef.current?.disconnect();\n };\n }, []);\n\n return refCallback;\n}\n","const warnedDuplicates = new Set<string>();\n\nfunction isDev(): boolean {\n try {\n // Avoid referencing the bare `process` identifier: this package has no\n // @types/node dependency, so accessing it directly fails type-checking.\n const env = (globalThis as any)?.process?.env?.NODE_ENV;\n return env !== 'production';\n } catch {\n return true;\n }\n}\n\nfunction warnIfDuplicate(id: string, selector: string, matchCount: number) {\n if (!isDev() || matchCount <= 1) return;\n const key = `${selector}::${id}`;\n if (warnedDuplicates.has(key)) return;\n warnedDuplicates.add(key);\n console.warn(\n `AppStorys: Found ${matchCount} elements matching target \"${id}\" (selector \"${selector}\"). ` +\n `The first one in document order will be used. Target identifiers should be unique per screen.`\n );\n}\n\n/**\n * Resolves an AppStorys target identifier to a single DOM element.\n * Resolution order: [data-as-id] -> #id -> [data-id] -> .class -> [data-widget]\n * This is the single source of truth for target resolution across Tooltip,\n * Widget, and CaptureService so the fallback chain can't drift between them.\n */\nexport function resolveTarget(id: string): HTMLElement | null {\n if (!id) return null;\n\n const attributeSelectors: string[] = [\n `[data-as-id=\"${id}\"]`,\n `[data-id=\"${id}\"]`,\n `[data-widget=\"${id}\"]`,\n ];\n\n for (const selector of attributeSelectors) {\n try {\n const matches = document.querySelectorAll(selector);\n if (matches.length > 0) {\n warnIfDuplicate(id, selector, matches.length);\n return matches[0] as HTMLElement;\n }\n } catch {\n // malformed selector (unlikely for attribute selectors) - try the next one\n }\n }\n\n // getElementById tolerates ids that aren't valid CSS identifiers (dots, colons, etc.),\n // unlike a raw `#id` selector, so it's used directly rather than via querySelector.\n const byId = document.getElementById(id);\n if (byId) return byId;\n\n try {\n const classSelector = `.${CSS && CSS.escape ? CSS.escape(id) : id}`;\n const matches = document.querySelectorAll(classSelector);\n if (matches.length > 0) {\n warnIfDuplicate(id, classSelector, matches.length);\n return matches[0] as HTMLElement;\n }\n } catch {\n // id isn't a valid class name fragment - nothing more to try\n }\n\n return null;\n}\n\nexport default resolveTarget;\n","import React, { useEffect, useLayoutEffect, useMemo, useRef, useState, useCallback } from \"react\";\nimport useCampaigns from \"../../hooks/useCampaigns\";\nimport trackEvent from \"../../core/trackEvent\";\nimport useAppStorysStore from \"../../core/store\";\nimport { BaseCampaign } from \"../../types\";\nimport { resolveFontFamily } from \"../../core/fontManager\";\nimport useViewportTracking from \"../../hooks/useViewportTracking\";\nimport { resolveTarget } from \"../../core/resolveTarget\";\n\n\nimport { CampaignTooltip, TooltipItem, TooltipStyling } from \"../../types\";\n\nconst normalizeScreen = (value?: string | null): string => (value || \"\").trim().toLowerCase();\n\nexport const Tooltip: React.FC = () => {\n const hookData = useCampaigns<CampaignTooltip>(\"TTP\");\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n\n const [currentStep, setCurrentStep] = useState(0);\n const [isDismissed, setIsDismissed] = useState(false);\n const [targetRect, setTargetRect] = useState<DOMRect | null>(null);\n const [tooltipSize, setTooltipSize] = useState({ width: 0, height: 0 });\n\n const tooltipRef = useRef<HTMLDivElement>(null);\n const observerRef = useRef<MutationObserver | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n\n const data = useMemo(() => {\n if (hookData) return hookData;\n\n const screen = normalizeScreen(currentScreen);\n const findFromList = (source: any[]) => source.find((campaign) => {\n const item = campaign as BaseCampaign;\n const isTooltip = item.campaign_type === \"TTP\" || item.campaign_type === \"TLTP\";\n const matchesScreen = !normalizeScreen(item.screen) || normalizeScreen(item.screen) === screen;\n const hasTrigger = Boolean((item as any).trigger_event ?? (item as any).trigger);\n const displayTriggerReady = (item as any).display_trigger !== false && !hasTrigger;\n return isTooltip && matchesScreen && displayTriggerReady;\n }) as CampaignTooltip | undefined;\n\n return findFromList(campaigns) ?? findFromList(allCampaigns);\n }, [hookData, campaigns, allCampaigns, currentScreen]);\n\n const tooltips = useMemo(() => {\n if (data?.details?.tooltips && Array.isArray(data.details.tooltips)) {\n return [...data.details.tooltips].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n }\n\n // Support for single step fully flat campaigns\n if (data?.details?.target || data?.details?.titleText) {\n return [{ ...data.details, _id: data.id } as TooltipItem];\n }\n\n return [];\n }, [data]);\n\n const currentTooltip = tooltips[currentStep];\n\n useEffect(() => {\n // Intentionally no-op here: viewed should be emitted when tooltip is actually shown\n // (i.e. when target element is measured and tooltip is displayed). Native emits\n // `viewed` from the overlay show path with `tooltip_id` metadata.\n }, [data]);\n\n // Track `viewed` when the tooltip enters the viewport\n const viewedTooltipsRef = useRef<Set<string>>(new Set());\n const trackViewed = useCallback(() => {\n if (!data || !currentTooltip || isDismissed || !sdkVisible) return;\n\n try {\n const tooltipId = (currentTooltip as any)._id || (currentTooltip as any).id || undefined;\n const key = String(data.id || '') + '::' + String(tooltipId || '');\n if (!viewedTooltipsRef.current.has(key)) {\n viewedTooltipsRef.current.add(key);\n void trackEvent('viewed', data.id, { tooltip_id: tooltipId });\n }\n } catch (e) {\n // ignore\n }\n }, [data, currentTooltip, isDismissed, sdkVisible]);\n const viewportRef = useViewportTracking(trackViewed);\n\n\n // Find target element and get rect\n useEffect(() => {\n if (!currentTooltip?.target || isDismissed) return;\n\n setTargetRect(null);\n\n const findTarget = (scroll = false) => {\n const targetId = currentTooltip.target;\n if (!targetId) return null;\n\n const el = resolveTarget(targetId);\n\n if (el) {\n setTargetRect(el.getBoundingClientRect());\n if (scroll) {\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n return el;\n }\n return null;\n };\n\n // Track the target's own size (font/image load, responsive CSS, content\n // expansion) so the tooltip repositions even when neither the window nor\n // any scroll container fires an event.\n const observeResize = (el: Element | null) => {\n resizeObserverRef.current?.disconnect();\n resizeObserverRef.current = null;\n if (!el || typeof ResizeObserver === 'undefined') return;\n resizeObserverRef.current = new ResizeObserver(() => {\n setTargetRect(el.getBoundingClientRect());\n });\n resizeObserverRef.current.observe(el);\n };\n\n // Initial check\n const el = findTarget(true);\n observeResize(el);\n\n // Setup MutationObserver to watch for element appearing\n if (!el) {\n observerRef.current = new MutationObserver(() => {\n const found = findTarget(true);\n if (found) {\n observerRef.current?.disconnect();\n observeResize(found);\n }\n });\n observerRef.current.observe(document.body, { childList: true, subtree: true });\n }\n\n // Resize and scroll listener.\n // `capture: true` is required so scroll events from nested/inner scroll\n // containers are seen here too — non-window `scroll` events don't bubble,\n // but capture-phase listeners on an ancestor still receive them.\n const handleResizeOrScroll = () => {\n const targetEl = findTarget(false);\n if (targetEl) {\n setTargetRect(targetEl.getBoundingClientRect());\n }\n };\n\n window.addEventListener(\"resize\", handleResizeOrScroll);\n window.addEventListener(\"scroll\", handleResizeOrScroll, { passive: true, capture: true });\n\n return () => {\n observerRef.current?.disconnect();\n resizeObserverRef.current?.disconnect();\n window.removeEventListener(\"resize\", handleResizeOrScroll);\n window.removeEventListener(\"scroll\", handleResizeOrScroll, { capture: true });\n };\n }, [currentTooltip, isDismissed, currentStep]);\n\n // Measure tooltip content\n useLayoutEffect(() => {\n if (tooltipRef.current && targetRect) {\n const { width, height } = tooltipRef.current.getBoundingClientRect();\n setTooltipSize({ width, height });\n }\n }, [currentTooltip, targetRect]);\n\n if (!data || !currentTooltip || isDismissed || !sdkVisible || !targetRect) return null;\n\n const styling = currentTooltip.styling || {};\n const appearance = styling.appearance || {};\n const colors = appearance.colors || {};\n const cta = styling.cta || {};\n const ctaContainer = cta.container || {};\n const ctaCorner = cta.cornerRadius || {};\n const ctaText = cta.text || {};\n\n // Mirror native: a tooltip is an \"image tooltip\" only when both dimensions\n // are configured. In that case the container is sized to that exact box\n // (clamped to the viewport) and the image covers it edge-to-edge, so the\n // container's backgroundColor never bleeds through around the image.\n const isImageTooltip = !!(appearance.imageDimensions?.width && appearance.imageDimensions?.height);\n let fixedImageWidth: number | undefined;\n let fixedImageHeight: number | undefined;\n if (isImageTooltip) {\n const rawWidth = appearance.imageDimensions!.width!;\n const rawHeight = appearance.imageDimensions!.height!;\n const maxViewportWidth = typeof window !== 'undefined' ? window.innerWidth * 0.9 : rawWidth;\n fixedImageWidth = Math.min(rawWidth, maxViewportWidth);\n fixedImageHeight = fixedImageWidth === rawWidth ? rawHeight : Math.round(rawHeight * (fixedImageWidth / rawWidth));\n }\n\n let arrowPos = currentTooltip.arrowPosition;\n if (!arrowPos && currentTooltip.position) {\n if (currentTooltip.position === \"left\") arrowPos = \"right\";\n else if (currentTooltip.position === \"right\") arrowPos = \"left\";\n else if (currentTooltip.position === \"top\") arrowPos = \"bottom\";\n else if (currentTooltip.position === \"bottom\") arrowPos = \"top\";\n }\n if (!arrowPos) {\n arrowPos = \"left\";\n }\n const arrowStyle = appearance.arrowStyle || { width: 6, height: 12 };\n const arrowSize = arrowStyle.width || 6; // fallback\n\n const absoluteTop = targetRect.top + window.scrollY;\n const absoluteLeft = targetRect.left + window.scrollX;\n\n let tooltipLeft = 0;\n let tooltipTop = 0;\n\n // Offset gap between target and tooltip (excluding arrow itself)\n const offsetGap = 8;\n\n if (arrowPos === \"left\") {\n tooltipLeft = absoluteLeft + targetRect.width + offsetGap;\n tooltipTop = absoluteTop + (targetRect.height / 2) - (tooltipSize.height / 2);\n } else if (arrowPos === \"right\") {\n tooltipLeft = absoluteLeft - tooltipSize.width - offsetGap;\n tooltipTop = absoluteTop + (targetRect.height / 2) - (tooltipSize.height / 2);\n } else if (arrowPos === \"top\") {\n tooltipTop = absoluteTop + targetRect.height + offsetGap;\n tooltipLeft = absoluteLeft + (targetRect.width / 2) - (tooltipSize.width / 2);\n } else if (arrowPos === \"bottom\") {\n tooltipTop = absoluteTop - tooltipSize.height - offsetGap;\n tooltipLeft = absoluteLeft + (targetRect.width / 2) - (tooltipSize.width / 2);\n }\n\n // Bounds checking to prevent cutting off at document edge\n const safeMargin = 8;\n const docHeight = typeof document !== 'undefined' ? document.documentElement.scrollHeight : window.innerHeight;\n const docWidth = typeof document !== 'undefined' ? document.documentElement.scrollWidth : window.innerWidth;\n\n if (tooltipSize.height > 0) {\n tooltipTop = Math.max(safeMargin, Math.min(docHeight - tooltipSize.height - safeMargin, tooltipTop));\n }\n if (tooltipSize.width > 0) {\n tooltipLeft = Math.max(safeMargin, Math.min(docWidth - tooltipSize.width - safeMargin, tooltipLeft));\n }\n\n const handleNext = () => {\n const targetLink = currentTooltip.link || currentTooltip.url;\n\n // Mirror native: emit `clicked` with tooltip identifier before action\n try {\n const tooltipId = (currentTooltip as any)._id || (currentTooltip as any).id || undefined;\n if (data?.id) {\n void trackEvent('clicked', data.id, { tooltip_id: tooltipId });\n }\n } catch (e) {\n // ignore tracking errors\n }\n\n // Mirror native: a CTA click always advances (or finishes on the last\n // step) regardless of `clickAction` — RN doesn't read that field at all.\n // Opening the link and advancing are independent, not either/or.\n if (currentStep < tooltips.length - 1) {\n setCurrentStep((prev: number) => prev + 1);\n if (targetLink) {\n window.open(targetLink, \"_blank\");\n }\n } else {\n setIsDismissed(true);\n if (targetLink) {\n window.open(targetLink, \"_blank\");\n }\n }\n };\n\n const handleBackdropClick = () => {\n if (!currentTooltip.enableBackdrop) return;\n\n // Mirror native: backdrop tap advances the sequence the same way a CTA\n // tap does (RN's onClose maps to the same onTooltipClosed() as the CTA\n // path), rather than hard-dismissing the whole multi-step tour early.\n if (currentStep < tooltips.length - 1) {\n setCurrentStep((prev: number) => prev + 1);\n } else {\n setIsDismissed(true);\n }\n };\n\n return (\n <>\n {currentTooltip.enableBackdrop && (\n <div\n style={{\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: colors.backdrop || \"rgba(0, 0, 0, 0.7)\",\n opacity: appearance.backdropOpacity ? appearance.backdropOpacity / 100 : 0.7,\n zIndex: 10000,\n }}\n onClick={handleBackdropClick}\n />\n )}\n\n <div\n ref={(el) => { (tooltipRef as any).current = el; viewportRef(el as HTMLElement); }}\n style={{\n position: \"absolute\",\n top: tooltipTop,\n left: tooltipLeft,\n zIndex: 10001,\n backgroundColor: colors.tooltip || \"#FE6B35\",\n padding: isImageTooltip ? 0 : `${appearance.padding?.top ?? 8}px ${appearance.padding?.right ?? 8}px ${appearance.padding?.bottom ?? 8}px ${appearance.padding?.left ?? 8}px`,\n borderRadius: `${appearance.cornerRadius?.topLeft ?? 12}px ${appearance.cornerRadius?.topRight ?? 12}px ${appearance.cornerRadius?.bottomRight ?? 12}px ${appearance.cornerRadius?.bottomLeft ?? 12}px`,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.15)\",\n width: isImageTooltip ? fixedImageWidth : undefined,\n height: isImageTooltip ? fixedImageHeight : undefined,\n maxWidth: isImageTooltip ? fixedImageWidth : 300,\n minWidth: isImageTooltip ? undefined : 200,\n transition: \"top 0.2s ease, left 0.2s ease\",\n cursor: !currentTooltip.ctaText ? \"pointer\" : \"default\",\n }}\n onClick={(e) => {\n if ((e.target as HTMLElement).tagName === 'BUTTON') return;\n if (!currentTooltip.ctaText) {\n handleNext();\n }\n }}\n >\n <div\n style={{\n position: \"absolute\",\n width: 0,\n height: 0,\n borderStyle: \"solid\",\n ...(arrowPos === \"left\" && {\n left: -offsetGap,\n top: Math.max(12, Math.min(tooltipSize.height - arrowSize * 2 - 12, absoluteTop + (targetRect.height / 2) - tooltipTop - arrowSize)),\n borderWidth: `${arrowSize}px ${offsetGap}px ${arrowSize}px 0`,\n borderColor: `transparent ${colors.arrow || colors.tooltip || \"#FE6B35\"} transparent transparent`,\n }),\n ...(arrowPos === \"right\" && {\n right: -offsetGap,\n top: Math.max(12, Math.min(tooltipSize.height - arrowSize * 2 - 12, absoluteTop + (targetRect.height / 2) - tooltipTop - arrowSize)),\n borderWidth: `${arrowSize}px 0 ${arrowSize}px ${offsetGap}px`,\n borderColor: `transparent transparent transparent ${colors.arrow || colors.tooltip || \"#FE6B35\"}`,\n }),\n ...(arrowPos === \"top\" && {\n top: -offsetGap,\n left: Math.max(12, Math.min(tooltipSize.width - arrowSize * 2 - 12, absoluteLeft + (targetRect.width / 2) - tooltipLeft - arrowSize)),\n borderWidth: `0 ${arrowSize}px ${offsetGap}px ${arrowSize}px`,\n borderColor: `transparent transparent ${colors.arrow || colors.tooltip || \"#FE6B35\"} transparent`,\n }),\n ...(arrowPos === \"bottom\" && {\n bottom: -offsetGap,\n left: Math.max(12, Math.min(tooltipSize.width - arrowSize * 2 - 12, absoluteLeft + (targetRect.width / 2) - tooltipLeft - arrowSize)),\n borderWidth: `${offsetGap}px ${arrowSize}px 0 ${arrowSize}px`,\n borderColor: `${colors.arrow || colors.tooltip || \"#FE6B35\"} transparent transparent transparent`,\n }),\n }}\n />\n\n {currentTooltip.url && (\n isImageTooltip ? (\n // Cropping lives on this inner wrapper, never on the outer\n // container the arrow is also a child of — otherwise the arrow\n // (deliberately positioned outside the box, pointing at the\n // target) gets clipped away along with the image.\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n borderRadius: `${appearance.cornerRadius?.topLeft ?? 12}px ${appearance.cornerRadius?.topRight ?? 12}px ${appearance.cornerRadius?.bottomRight ?? 12}px ${appearance.cornerRadius?.bottomLeft ?? 12}px`,\n }}\n >\n <img\n src={currentTooltip.url}\n alt=\"tooltip media\"\n style={{ width: \"100%\", height: \"100%\", display: \"block\", objectFit: \"cover\" }}\n />\n </div>\n ) : (\n <img\n src={currentTooltip.url}\n alt=\"tooltip media\"\n style={{ width: \"100%\", borderRadius: 6, marginBottom: 8, display: \"block\", objectFit: \"cover\" }}\n />\n )\n )}\n\n {(currentTooltip.titleText || currentTooltip.subtitleText || currentTooltip.ctaText) && (\n <div\n style={\n isImageTooltip\n ? { padding: `${appearance.padding?.top ?? 8}px ${appearance.padding?.right ?? 8}px ${appearance.padding?.bottom ?? 8}px ${appearance.padding?.left ?? 8}px` }\n : undefined\n }\n >\n {currentTooltip.titleText && (\n <div\n style={{\n color: styling.title?.color || \"#ffffff\",\n fontFamily: resolveFontFamily(styling.title?.fontFamily) || \"Arial\",\n fontSize: styling.title?.fontSize || 14,\n textAlign: (styling.title?.textAlign as any) || \"center\",\n marginBottom: styling.title?.margin?.bottom ?? 4,\n marginTop: styling.title?.margin?.top ?? 0,\n marginLeft: styling.title?.margin?.left ?? 0,\n marginRight: styling.title?.margin?.right ?? 0,\n fontWeight: styling.title?.fontDecoration?.includes(\"bold\") ? \"bold\" : 600,\n fontStyle: styling.title?.fontDecoration?.includes(\"italic\") ? \"italic\" : \"normal\",\n textDecoration: styling.title?.fontDecoration?.includes(\"underline\") ? \"underline\" : \"none\",\n }}\n >\n {currentTooltip.titleText}\n </div>\n )}\n\n {currentTooltip.subtitleText && (\n <div\n style={{\n color: styling.subTitle?.color || \"#ffffff\",\n fontFamily: resolveFontFamily(styling.subTitle?.fontFamily) || \"Arial\",\n fontSize: styling.subTitle?.fontSize || 12,\n textAlign: (styling.subTitle?.textAlign as any) || \"center\",\n marginBottom: styling.subTitle?.margin?.bottom ?? 8,\n marginTop: styling.subTitle?.margin?.top ?? 0,\n marginLeft: styling.subTitle?.margin?.left ?? 0,\n marginRight: styling.subTitle?.margin?.right ?? 0,\n fontWeight: styling.subTitle?.fontDecoration?.includes(\"bold\") ? \"bold\" : \"normal\",\n fontStyle: styling.subTitle?.fontDecoration?.includes(\"italic\") ? \"italic\" : \"normal\",\n textDecoration: styling.subTitle?.fontDecoration?.includes(\"underline\") ? \"underline\" : \"none\",\n }}\n >\n {currentTooltip.subtitleText}\n </div>\n )}\n\n {currentTooltip.ctaText && (\n <div\n style={{\n display: \"flex\",\n justifyContent: ctaContainer.alignment === \"right\" ? \"flex-end\" : ctaContainer.alignment === \"left\" ? \"flex-start\" : \"center\",\n marginTop: 8,\n }}\n >\n <button\n onClick={handleNext}\n style={{\n width: ctaContainer.ctaFullWidth ? \"100%\" : ctaContainer.ctaWidth || \"auto\",\n height: ctaContainer.height || 35,\n background: ctaContainer.backgroundColor || \"#F7921C\",\n color: ctaText.color || \"#ffffff\",\n border: `${ctaContainer.borderWidth || 0}px solid ${ctaContainer.borderColor || \"transparent\"}`,\n borderRadius: `${ctaCorner.topLeft ?? 7}px ${ctaCorner.topRight ?? 7}px ${ctaCorner.bottomRight ?? 7}px ${ctaCorner.bottomLeft ?? 7}px`,\n fontSize: ctaText.fontSize || 14,\n fontFamily: resolveFontFamily(ctaText.fontFamily) || \"Arial\",\n fontWeight: ctaText.fontDecoration?.includes(\"bold\") ? \"bold\" : \"normal\",\n fontStyle: ctaText.fontDecoration?.includes(\"italic\") ? \"italic\" : \"normal\",\n textDecoration: ctaText.fontDecoration?.includes(\"underline\") ? \"underline\" : \"none\",\n cursor: \"pointer\",\n padding: \"0 12px\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {currentTooltip.ctaText}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n </>\n );\n};\n\nexport default Tooltip;\n","import React, { useEffect, useState, useRef } from 'react';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport { resolveFontFamily } from '../../core/fontManager';\nimport { CampaignBottomSheet, BottomSheetElement } from '../../types';\nimport CrossButton from '../common/CommonElements/CrossButton';\n\nexport const BottomSheet: React.FC = () => {\n const hookData = useCampaigns<CampaignBottomSheet>('BTS');\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n\n const data = hookData ?? ((): CampaignBottomSheet | undefined => {\n const screen = (currentScreen || '').trim().toLowerCase();\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign: any) => {\n if (!campaign) return false;\n if (campaign.campaign_type !== 'BTS') return false;\n const hasTrigger = Boolean(campaign.trigger_event ?? campaign.trigger);\n // keep display-trigger campaigns available only when not trigger-driven\n const displayTriggerReady = (campaign as any).display_trigger !== false && !hasTrigger;\n if (!displayTriggerReady) return false;\n const cs = (campaign.screen || '').trim().toLowerCase();\n return !cs || cs === screen;\n }) as CampaignBottomSheet | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignBottomSheet;\n } catch {\n return found;\n }\n })();\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n const [isDismissed, setIsDismissed] = useState(false);\n\n const trackedViewRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (data?.id && trackedViewRef.current !== data.id) {\n trackedViewRef.current = data.id;\n setIsDismissed(false);\n // Match RN: send generic `viewed` event for campaigns\n void trackEvent('viewed', data.id);\n }\n }, [data?.id]);\n\n const removeTrackedEvent = (eventKey: string) => {\n try {\n const state = useAppStorysStore.getState();\n const tracked = state.trackedEvents || [];\n const next = tracked.filter((e: string) => e !== eventKey);\n state.setTrackedEvents(next);\n } catch (e) {\n // ignore\n }\n };\n\n if (!data || isDismissed || !sdkVisible) return null;\n\n const { details } = data;\n const elements = details.elements || [];\n const sortedElements = [...elements].sort((a, b) => (a.order || 0) - (b.order || 0));\n\n // Determine opacity: if it's high (>1), treat as percentage\n let opacity = details.backdropOpacity ?? 0.5;\n if (opacity > 1) {\n opacity = opacity / 100;\n }\n\n const renderElement = (element: BottomSheetElement) => {\n switch (element.type) {\n case 'image': {\n const imgStyle: React.CSSProperties = {\n width: '100%',\n display: 'block',\n objectFit: 'contain',\n backgroundColor: element.imageBackgroundColor || 'transparent',\n paddingBottom: element.paddingBottom ?? 0,\n paddingLeft: element.paddingLeft ?? 0,\n paddingRight: element.paddingRight ?? 0,\n paddingTop: element.paddingTop ?? 0,\n cursor: element.imageLink ? 'pointer' : 'default',\n };\n return (\n <div key={element.id} style={{ textAlign: element.alignment || 'left', width: '100%' }}>\n {element.url && (\n <img \n src={element.url} \n alt=\"\" \n style={imgStyle} \n onClick={() => {\n if (!element.imageLink) return;\n if (data?.id) void trackEvent('clicked', data.id);\n try {\n const link = String(element.imageLink || '').trim();\n if (link && !link.startsWith('http')) {\n const revealed = revealCampaignFromLink(link);\n if (revealed) return;\n }\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n try {\n window.open(element.imageLink, '_blank');\n } catch (err) {\n // ignore\n }\n }}\n />\n )}\n </div>\n );\n }\n\n case 'cta': {\n const ctaData = element.cta || {};\n const container = ctaData.container || {};\n const cornerRadius = ctaData.cornerRadius || {};\n const margin = ctaData.margin || {};\n const textStyle = ctaData.text || {};\n\n return (\n <div \n key={element.id}\n style={{\n display: 'flex',\n justifyContent: container.alignment === 'center' ? 'center' : container.alignment === 'right' ? 'flex-end' : 'flex-start',\n width: '100%',\n marginTop: margin.top ?? 0,\n marginBottom: margin.bottom ?? 0,\n marginLeft: margin.left ?? 0,\n marginRight: margin.right ?? 0,\n }}\n >\n <button\n style={{\n width: container.ctaFullWidth ? '100%' : container.ctaWidth || 'auto',\n height: container.height || 45,\n backgroundColor: container.ctaBoxColor || container.backgroundColor || '#FE6B35',\n color: textStyle.color || '#ffffff',\n border: `${container.borderWidth || 0}px solid ${container.borderColor || 'transparent'}`,\n borderRadius: `${cornerRadius.topLeft ?? 12}px ${cornerRadius.topRight ?? 12}px ${cornerRadius.bottomRight ?? 12}px ${cornerRadius.bottomLeft ?? 12}px`,\n fontSize: textStyle.fontSize || 14,\n fontFamily: resolveFontFamily(textStyle.fontFamily) || 'Arial',\n fontWeight: textStyle.fontDecoration?.includes('bold') ? 'bold' : 'normal',\n fontStyle: textStyle.fontDecoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: textStyle.fontDecoration?.includes('underline') ? 'underline' : 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 16px',\n }}\n onClick={() => {\n const link = element.ctaLink || element.url;\n if (!link) return;\n if (data?.id) void trackEvent('clicked', data.id);\n try {\n const l = String(link || '').trim();\n if (l && !l.startsWith('http')) {\n const revealed = revealCampaignFromLink(l);\n if (revealed) return;\n }\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n try {\n window.open(link, '_blank');\n } catch (err) {\n // ignore\n }\n }}\n >\n {element.ctaText || 'Button'}\n </button>\n </div>\n );\n }\n\n case 'body': {\n const titleStyle = element.titleFontStyle || {};\n const descStyle = element.descriptionFontStyle || {};\n \n return (\n <div \n key={element.id}\n style={{\n width: '100%',\n backgroundColor: element.bodyBackgroundColor || 'transparent',\n marginTop: element.marginTop ?? 0,\n marginBottom: element.marginBottom ?? 20,\n marginLeft: element.marginLeft ?? 4,\n marginRight: element.marginRight ?? 4,\n }}\n >\n {element.titleText && (\n <div style={{\n color: titleStyle.colour || '#000000',\n fontSize: titleStyle.fontSize ? `${titleStyle.fontSize}px` : element.titleFontSize ? `${element.titleFontSize}px` : '16px',\n fontFamily: resolveFontFamily(titleStyle.fontFamily) || 'inherit',\n textAlign: titleStyle.alignment || 'left',\n lineHeight: element.titleLineHeight || 1.2,\n fontWeight: titleStyle.decoration?.includes('bold') ? 'bold' : '600',\n fontStyle: titleStyle.decoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: titleStyle.decoration?.includes('underline') ? 'underline' : 'none',\n marginBottom: element.spacingBetweenTitleDesc ?? 4,\n }}>\n {element.titleText}\n </div>\n )}\n \n {element.descriptionText && (\n <div style={{\n color: descStyle.colour || '#000000',\n fontSize: descStyle.fontSize ? `${descStyle.fontSize}px` : element.descriptionFontSize ? `${element.descriptionFontSize}px` : '14px',\n fontFamily: resolveFontFamily(descStyle.fontFamily) || 'inherit',\n textAlign: descStyle.alignment || 'left',\n lineHeight: element.descriptionLineHeight || 1.5,\n fontWeight: descStyle.decoration?.includes('bold') ? 'bold' : 'normal',\n fontStyle: descStyle.decoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: descStyle.decoration?.includes('underline') ? 'underline' : 'none',\n }}>\n {element.descriptionText}\n </div>\n )}\n </div>\n );\n }\n\n default:\n return null;\n }\n };\n\n return (\n <>\n <div \n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: details.backdropColor || 'rgba(0,0,0,0.5)',\n opacity: opacity,\n zIndex: 999998,\n transition: 'opacity 0.3s ease',\n }}\n onClick={() => {\n if (data?.id) removeTrackedEvent(`viaAppStorys${data.id}`);\n setIsDismissed(true);\n }}\n />\n <div \n style={{\n position: 'fixed',\n bottom: 0,\n left: '50%',\n transform: 'translateX(-50%)',\n width: '100%',\n maxWidth: '500px', // Responsive safety\n backgroundColor: details.backgroundColor || '#FFFFFF',\n borderTopLeftRadius: `${details.cornerRadius?.topLeft ?? 16}px`,\n borderTopRightRadius: `${details.cornerRadius?.topRight ?? 16}px`,\n borderBottomLeftRadius: `${details.cornerRadius?.bottomLeft ?? 0}px`,\n borderBottomRightRadius: `${details.cornerRadius?.bottomRight ?? 0}px`,\n zIndex: 999999,\n padding: '24px 16px',\n boxShadow: '0 -4px 16px rgba(0,0,0,0.15)',\n maxHeight: '85vh',\n overflowY: 'auto',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n transition: 'transform 0.3s ease-out',\n }}\n >\n <div style={{\n width: '40px',\n height: '5px',\n backgroundColor: '#E0E0E0',\n borderRadius: '2.5px',\n marginBottom: '16px',\n cursor: 'pointer'\n }} onClick={() => setIsDismissed(true)} />\n\n {details.crossButton?.enabled && (\n <CrossButton \n config={details.crossButton}\n onPress={() => {\n if (data?.id) removeTrackedEvent(`viaAppStorys${data.id}`);\n setIsDismissed(true);\n }}\n style={{\n top: details.crossButton?.margin?.top ?? 12,\n right: details.crossButton?.margin?.right ?? 12,\n }}\n />\n )}\n \n <div style={{ width: '100%', display: 'flex', flexDirection: 'column', gap: '12px' }}>\n {sortedElements.map(renderElement)}\n </div>\n </div>\n </>\n );\n};\n\nexport default BottomSheet;\n","import React, { useEffect, useMemo, useState, useRef } from 'react';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport CrossButton from '../common/CommonElements/CrossButton';\nimport { CampaignCsat, CsatCampaignDetails, CsatSpacing, CsatTextStyle } from '../../types';\nimport { resolveFontFamily } from '../../core/fontManager';\nimport * as LottieModule from 'lottie-react';\n\nconst Lottie =\n (LottieModule as any).default?.default ??\n (LottieModule as any).default ??\n (LottieModule as any).Lottie ??\n (LottieModule as any);\n\nconst FIVE_STAR_MAX = 5;\nconst LOW_RATING_CUTOFF = 3;\n\nfunction asSpacingValue(value?: number): string | undefined {\n if (value == null) return undefined;\n return `${value}px`;\n}\n\nfunction spacingToStyle(spacing?: CsatSpacing): React.CSSProperties {\n return {\n marginTop: asSpacingValue(spacing?.top),\n marginRight: asSpacingValue(spacing?.right),\n marginBottom: asSpacingValue(spacing?.bottom),\n marginLeft: asSpacingValue(spacing?.left),\n };\n}\n\nfunction applyFontFamily(fontFamily?: string): string | undefined {\n return resolveFontFamily(fontFamily);\n}\n\nfunction textStyleToCss(textStyle?: CsatTextStyle): React.CSSProperties {\n if (!textStyle) return {};\n\n return {\n color: textStyle.color,\n fontSize: textStyle.fontSize,\n fontFamily: applyFontFamily(textStyle.fontFamily),\n textAlign: textStyle.textAlign as React.CSSProperties['textAlign'],\n fontWeight: textStyle.fontDecoration?.includes('bold') ? 'bold' : undefined,\n fontStyle: textStyle.fontDecoration?.includes('italic') ? 'italic' : undefined,\n textDecoration: textStyle.fontDecoration?.includes('underline') ? 'underline' : undefined,\n };\n}\n\nfunction getCornerRadius(cornerRadius?: { topLeft?: number; topRight?: number; bottomRight?: number; bottomLeft?: number }): string {\n return `${cornerRadius?.topLeft ?? 8}px ${cornerRadius?.topRight ?? 8}px ${cornerRadius?.bottomRight ?? 8}px ${cornerRadius?.bottomLeft ?? 8}px`;\n}\n\nfunction getAlignment(alignment?: string): React.CSSProperties['justifyContent'] {\n if (alignment === 'right') return 'flex-end';\n if (alignment === 'left') return 'flex-start';\n return 'center';\n}\n\nfunction getRatingType(details: CsatCampaignDetails): 'star' | 'number' | 'emoji' {\n const ratingType = details.styling?.rating?.ratingType;\n if (ratingType === 'number' || ratingType === 'emoji' || ratingType === 'star') return ratingType;\n return 'star';\n}\n\nfunction getEmojiChoices(details: CsatCampaignDetails): string[] {\n const configured = details.styling?.rating?.emoji as any;\n \n let rawItems: any[] = [];\n \n if (Array.isArray(configured)) {\n rawItems = configured;\n } else if (configured && typeof configured === 'object') {\n if (Array.isArray(configured.values)) {\n rawItems = configured.values;\n } else {\n rawItems = Object.values(configured);\n }\n } else if (typeof configured === 'string' && configured.trim()) {\n rawItems = configured.split(',');\n }\n\n const parsed = rawItems.map((item: any) => {\n if (typeof item === 'string') return item.trim();\n if (item && typeof item === 'object') {\n const val = item.emoji || item.value || item.text || item.icon || item.name || '';\n if (typeof val === 'string') return val.trim();\n }\n return '';\n }).filter(Boolean);\n\n if (parsed.length > 0) {\n return parsed;\n }\n\n return ['😠', '😕', '😐', '🙂', '😍'];\n}\n\nfunction getNumberChoices(details: CsatCampaignDetails): number[] {\n // Force a 5-point numeric scale (1–5) regardless of backend config.\n // This matches the requested UI and avoids rendering 0–10 style scales.\n return Array.from({ length: 5 }, (_, index) => index + 1);\n}\n\nfunction asNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value;\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value);\n if (Number.isFinite(parsed) && parsed >= 0) return parsed;\n }\n return undefined;\n}\n\nfunction getNumberRatingGap(details: CsatCampaignDetails): number {\n const rating = (details.styling?.rating as Record<string, unknown> | undefined) || undefined;\n const directCandidates = [\n rating?.['numberSpacing'],\n rating?.['numberGap'],\n rating?.['number_spacing'],\n rating?.['number_gap'],\n rating?.['spacingBetweenNumbers'],\n rating?.['spaceBetweenNumbers'],\n rating?.['numberOptionsSpacing'],\n ];\n\n for (const candidate of directCandidates) {\n const maybe = asNonNegativeNumber(candidate);\n if (maybe != null) return maybe;\n }\n\n const numberConfig = rating?.['number'];\n if (numberConfig && typeof numberConfig === 'object') {\n const obj = numberConfig as Record<string, unknown>;\n const nestedCandidates = [obj['spacing'], obj['gap'], obj['optionsSpacing'], obj['numberSpacing'], obj['numberGap']];\n for (const candidate of nestedCandidates) {\n const maybe = asNonNegativeNumber(candidate);\n if (maybe != null) return maybe;\n }\n }\n\n return 8;\n}\n\nfunction getRatingMax(details: CsatCampaignDetails): number {\n const ratingType = getRatingType(details);\n\n if (ratingType === 'emoji') return Math.max(1, getEmojiChoices(details).length);\n if (ratingType === 'number') {\n const choices = getNumberChoices(details);\n return Math.max(1, choices.length);\n }\n\n return FIVE_STAR_MAX;\n}\n\nconst StarIcon: React.FC<{ fill: string; stroke: string }> = ({ fill, stroke }) => (\n <svg viewBox=\"0 0 24 24\" width=\"22\" height=\"22\" aria-hidden>\n <path\n d=\"M12 2.25l2.91 5.89 6.5.95-4.7 4.58 1.11 6.46L12 17.03 6.18 20.13l1.11-6.46-4.7-4.58 6.5-.95L12 2.25z\"\n fill={fill}\n stroke={stroke}\n strokeWidth=\"1.4\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\ninterface FormContentProps {\n details: CsatCampaignDetails;\n appearance?: { backgroundColor?: string };\n rating: number;\n selectedOptions: string[];\n comments: string;\n isHighRating: boolean;\n feedbackOptions: string[];\n onRate: (value: number) => void;\n onToggleOption: (option: string) => void;\n onCommentChange: (value: string) => void;\n onInlineSubmit: () => void;\n canSubmit: boolean;\n}\n\nconst CsatFormContent: React.FC<FormContentProps> = ({\n details,\n appearance,\n rating,\n selectedOptions,\n comments,\n isHighRating,\n feedbackOptions,\n onRate,\n onToggleOption,\n onCommentChange,\n onInlineSubmit,\n canSubmit,\n}) => {\n const styling = details.styling || {};\n const feedbackPage = styling.feedbackPage || {};\n const ratingStyle = styling.rating || {};\n const initialFeedback = styling.initialFeedback || {};\n const submitCta = feedbackPage.submitButton?.cta;\n const ratingType = getRatingType(details);\n const numberChoices = ratingType === 'number' ? getNumberChoices(details) : [];\n const emojiChoices = ratingType === 'emoji' ? getEmojiChoices(details) : [];\n\n const numberGap = ratingType === 'number' ? getNumberRatingGap(details) : 8;\n\n const selectedStarConfig = isHighRating ? ratingStyle.star?.high : ratingStyle.star?.low;\n\n return (\n <>\n <div style={spacingToStyle(initialFeedback.title?.margin)}>\n <div\n style={{\n ...(textStyleToCss(initialFeedback.title?.textStyle)),\n color: initialFeedback.title?.textStyle?.color || '#101828',\n fontSize: initialFeedback.title?.textStyle?.fontSize || 20,\n lineHeight: 1.3,\n }}\n >\n {details.title || 'How was your experience?'}\n </div>\n </div>\n\n <div style={spacingToStyle(initialFeedback.subtitle?.margin)}>\n <div\n style={{\n ...(textStyleToCss(initialFeedback.subtitle?.textStyle)),\n color: initialFeedback.subtitle?.textStyle?.color || '#4b5563',\n fontSize: initialFeedback.subtitle?.textStyle?.fontSize || 14,\n lineHeight: 1.4,\n }}\n >\n {details.description_text || 'Your feedback helps us improve your experience.'}\n </div>\n </div>\n\n <div style={{ marginTop: 8, display: 'flex', justifyContent: 'center', gap: ratingType === 'number' ? numberGap : 8, flexWrap: 'wrap' }}>\n {ratingType === 'star' && Array.from({ length: FIVE_STAR_MAX }, (_, index) => {\n const value = index + 1;\n const isSelected = value <= rating;\n const starContainerStyle = isSelected\n ? selectedStarConfig?.stylingContainer\n : ratingStyle.star?.unselected?.stylingContainer;\n const starStyle = isSelected\n ? selectedStarConfig?.stylingStar\n : ratingStyle.star?.unselected?.stylingStar;\n\n return (\n <button\n key={value}\n onClick={() => onRate(value)}\n style={{\n border: `${starContainerStyle?.borderWidth ?? 1}px solid ${starContainerStyle?.border || '#d1d5db'}`,\n background: starContainerStyle?.background || '#ffffff',\n borderRadius: 10,\n width: 44,\n height: 44,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n padding: 0,\n }}\n aria-label={`Rate ${value} out of ${FIVE_STAR_MAX}`}\n >\n <StarIcon\n fill={starStyle?.background || (isSelected ? '#f59e0b' : '#e5e7eb')}\n stroke={starStyle?.border || (isSelected ? '#d97706' : '#9ca3af')}\n />\n </button>\n );\n })}\n\n {ratingType === 'number' && numberChoices.map((value, index) => {\n const selected = value === rating;\n return (\n <button\n key={`${value}-${index}`}\n onClick={() => onRate(value)}\n style={{\n border: `1px solid ${selected ? '#1d4ed8' : '#d1d5db'}`,\n background: selected ? '#dbeafe' : '#ffffff',\n color: selected ? '#1d4ed8' : '#111827',\n borderRadius: 8,\n minWidth: 36,\n height: 36,\n padding: '0 10px',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n fontWeight: 600,\n }}\n aria-label={`Rate ${value}`}\n >\n {value}\n </button>\n );\n })}\n\n {ratingType === 'emoji' && emojiChoices.map((emoji, index) => {\n const value = index + 1;\n const selected = value === rating;\n const emojiConfig = (ratingStyle.emoji as any);\n const styleState = selected ? emojiConfig?.selected : emojiConfig?.unselected;\n const containerStyle = styleState?.stylingContainer;\n \n return (\n <button\n key={`${emoji}-${index}`}\n onClick={() => onRate(value)}\n style={{\n border: `${containerStyle?.borderWidth ?? 1}px solid ${containerStyle?.border || (selected ? '#1d4ed8' : '#d1d5db')}`,\n background: containerStyle?.fill || containerStyle?.background || (selected ? '#dbeafe' : '#ffffff'),\n borderRadius: (ratingStyle as any).cornerRadius ? getCornerRadius((ratingStyle as any).cornerRadius) : '999px',\n width: 44,\n height: 44,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n fontSize: 22,\n }}\n aria-label={`Emoji rating ${index + 1}`}\n >\n {emoji}\n </button>\n );\n })}\n </div>\n\n {rating > 0 && (\n <div style={{ marginTop: 6, textAlign: 'center', color: '#374151', fontSize: 14 }}>\n {isHighRating ? (details.highStarText || ratingStyle.highRatingSubtitle) : (details.lowStarText || ratingStyle.lowRatingSubtitle)}\n </div>\n )}\n\n {rating > 0 && rating <= LOW_RATING_CUTOFF && (\n <>\n {feedbackOptions.length > 0 && (\n <div\n style={{\n ...spacingToStyle(feedbackPage.options?.margin),\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'stretch',\n gap: feedbackPage.options?.optionsSpacing ?? 8,\n width: '100%',\n }}\n >\n {feedbackOptions.map((option) => {\n const isActive = selectedOptions.includes(option);\n const styleSource = isActive ? feedbackPage.options?.selectedOptions : feedbackPage.options?.nonSelectedOptions;\n\n return (\n <button\n key={option}\n onClick={() => onToggleOption(option)}\n style={{\n border: `${styleSource?.borderWidth ?? 1}px solid ${styleSource?.colors?.border || '#d1d5db'}`,\n background: styleSource?.colors?.background || '#f9fafb',\n color: styleSource?.colors?.text || '#111827',\n width: '100%',\n height: feedbackPage.options?.optionsHeight || 38,\n borderRadius: getCornerRadius(feedbackPage.options?.cornerRadius),\n padding: '0 14px',\n cursor: 'pointer',\n textAlign: 'center',\n ...(textStyleToCss(styleSource?.textStyle)),\n }}\n >\n {option}\n </button>\n );\n })}\n </div>\n )}\n\n <textarea\n value={comments}\n onChange={(event) => onCommentChange(event.target.value)}\n placeholder={feedbackPage.additionalComments?.placeholder || 'Tell us what we can improve'}\n style={{\n width: '100%',\n boxSizing: 'border-box',\n minHeight: 56,\n height: 56,\n maxHeight: 64,\n marginTop: 8,\n resize: 'none',\n overflowY: 'auto',\n border: `${feedbackPage.additionalComments?.borderWidth ?? 1}px solid ${feedbackPage.additionalComments?.colors?.border || '#d1d5db'}`,\n background: feedbackPage.additionalComments?.colors?.background || '#ffffff',\n color: feedbackPage.additionalComments?.colors?.text || '#111827',\n borderRadius: 8,\n padding: '12px',\n ...(textStyleToCss(feedbackPage.additionalComments?.textStyle)),\n }}\n />\n\n <div\n style={{\n position: 'sticky',\n bottom: 0,\n marginTop: 8,\n paddingTop: 6,\n paddingBottom: 6,\n background: appearance?.backgroundColor || '#2f6ef5',\n display: 'flex',\n justifyContent: 'center',\n }}\n >\n <button\n onClick={() => onInlineSubmit()}\n disabled={!canSubmit}\n style={{\n width: Math.max(140, Math.min(asNonNegativeNumber(submitCta?.container?.ctaWidth) ?? 180, 220)),\n maxWidth: '100%',\n minHeight: 30,\n height: Math.max(30, Math.min(Number(submitCta?.container?.height) || 34, 34)),\n border: `${submitCta?.container?.borderWidth ?? 1}px solid ${submitCta?.container?.borderColor || '#ff7a00'}`,\n background: submitCta?.container?.backgroundColor || '#ff2bc2',\n color: submitCta?.text?.color || '#ffffff',\n borderRadius: getCornerRadius(submitCta?.cornerRadius),\n fontFamily: applyFontFamily(submitCta?.text?.fontFamily),\n fontSize: Math.min(Number(submitCta?.text?.fontSize) || 14, 14),\n fontWeight: submitCta?.text?.fontDecoration?.includes('bold') ? 'bold' : 600,\n cursor: canSubmit ? 'pointer' : 'not-allowed',\n opacity: canSubmit ? 1 : 0.65,\n padding: '0 12px',\n }}\n >\n {feedbackPage.submitButton?.text || 'Submit'}\n </button>\n </div>\n </>\n )}\n\n </>\n );\n};\n\ninterface ThankYouContentProps {\n details: CsatCampaignDetails;\n isHighRating: boolean;\n onDone: () => void;\n}\n\nconst CsatThankYouContent: React.FC<ThankYouContentProps> = ({ details, isHighRating, onDone }) => {\n const styling = details.styling || {};\n const thankyouPage = styling.thankyouPage || {};\n const ratingStyle = styling.rating || {};\n const doneAlign = getAlignment(thankyouPage.doneButton?.cta?.container?.alignment);\n const [lottieData, setLottieData] = useState<any>(null);\n\n const isLottie = details.thankyouImage?.endsWith('.json');\n\n useEffect(() => {\n if (isLottie && details.thankyouImage) {\n fetch(details.thankyouImage)\n .then((res) => res.json())\n .then((json) => setLottieData(json))\n .catch((err) => console.error('Error loading Lottie:', err));\n }\n }, [details.thankyouImage, isLottie]);\n\n return (\n <>\n {details.thankyouImage && (\n <div style={{ display: 'flex', justifyContent: 'center', marginTop: 6 }}>\n {isLottie ? (\n lottieData ? (\n <Lottie\n animationData={lottieData}\n loop={true}\n style={{\n width: thankyouPage.imageStyle?.width || 80,\n height: thankyouPage.imageStyle?.height || 80,\n }}\n />\n ) : (\n <div style={{ width: thankyouPage.imageStyle?.width || 80, height: thankyouPage.imageStyle?.height || 80 }} />\n )\n ) : (\n <img\n src={details.thankyouImage}\n alt=\"thank you\"\n style={{\n width: thankyouPage.imageStyle?.width || 80,\n height: thankyouPage.imageStyle?.height || 80,\n objectFit: 'cover',\n borderRadius: 8,\n }}\n />\n )}\n </div>\n )}\n\n <div style={{ ...spacingToStyle(thankyouPage.title?.margin), textAlign: 'center' }}>\n <div\n style={{\n ...(textStyleToCss(thankyouPage.title?.textStyle)),\n color: thankyouPage.title?.textStyle?.color || '#111827',\n fontSize: thankyouPage.title?.textStyle?.fontSize || 20,\n fontWeight: thankyouPage.title?.textStyle?.fontDecoration?.includes('bold') ? 'bold' : 600,\n }}\n >\n {details.thankyouText ?? (isHighRating ? ratingStyle.highRatingTitle : ratingStyle.lowRatingTitle) ?? 'Thank you for your feedback'}\n </div>\n </div>\n\n <div style={{ ...spacingToStyle(thankyouPage.subtitle?.margin), textAlign: 'center' }}>\n <div\n style={{\n ...(textStyleToCss(thankyouPage.subtitle?.textStyle)),\n color: thankyouPage.subtitle?.textStyle?.color || '#4b5563',\n fontSize: thankyouPage.subtitle?.textStyle?.fontSize || 14,\n }}\n >\n {details.thankyouDescription ?? (isHighRating ? ratingStyle.highRatingSubtitle : ratingStyle.lowRatingSubtitle) ?? 'We appreciate your time.'}\n </div>\n </div>\n\n <div\n style={{\n marginTop: thankyouPage.doneButton?.cta?.margin?.top ?? 14,\n marginBottom: thankyouPage.doneButton?.cta?.margin?.bottom ?? 0,\n marginLeft: thankyouPage.doneButton?.cta?.margin?.left ?? 0,\n marginRight: thankyouPage.doneButton?.cta?.margin?.right ?? 0,\n display: 'flex',\n justifyContent: doneAlign,\n }}\n >\n <button\n onClick={onDone}\n style={{\n width: thankyouPage.doneButton?.cta?.container?.ctaFullWidth ? '100%' : thankyouPage.doneButton?.cta?.container?.ctaWidth || 'auto',\n height: thankyouPage.doneButton?.cta?.container?.height || 45,\n border: `${thankyouPage.doneButton?.cta?.container?.borderWidth ?? 0}px solid ${thankyouPage.doneButton?.cta?.container?.borderColor || 'transparent'}`,\n background: thankyouPage.doneButton?.cta?.container?.backgroundColor || '#111827',\n color: thankyouPage.doneButton?.cta?.text?.color || '#ffffff',\n borderRadius: getCornerRadius(thankyouPage.doneButton?.cta?.cornerRadius),\n fontFamily: applyFontFamily(thankyouPage.doneButton?.cta?.text?.fontFamily),\n fontSize: thankyouPage.doneButton?.cta?.text?.fontSize || 16,\n fontWeight: thankyouPage.doneButton?.cta?.text?.fontDecoration?.includes('bold') ? 'bold' : 500,\n cursor: 'pointer',\n padding: '0 16px',\n }}\n >\n {thankyouPage.doneButton?.text || (isHighRating ? 'Rate Now' : 'Done')}\n </button>\n </div>\n </>\n );\n};\n\nexport const Csat: React.FC = () => {\n const hookData = useCampaigns<CampaignCsat>('CSAT');\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n\n const data = hookData ?? ((): CampaignCsat | undefined => {\n const screen = (currentScreen || '').trim().toLowerCase();\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign: any) => {\n if (!campaign) return false;\n if (campaign.campaign_type !== 'CSAT') return false;\n const hasTrigger = Boolean(campaign.trigger_event ?? campaign.trigger);\n const displayTriggerReady = (campaign as any).display_trigger !== false && !hasTrigger;\n if (!displayTriggerReady) return false;\n const cs = (campaign.screen || '').trim().toLowerCase();\n return !cs || cs === screen;\n }) as CampaignCsat | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignCsat;\n } catch {\n return found;\n }\n })();\n\n const [isDismissed, setIsDismissed] = useState(false);\n const [canDisplay, setCanDisplay] = useState(false);\n const [rating, setRating] = useState(0);\n const [selectedOptions, setSelectedOptions] = useState<string[]>([]);\n const [comments, setComments] = useState('');\n const [isSubmitted, setIsSubmitted] = useState(false);\n\n const trackedViewRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!data?.id) return;\n if (trackedViewRef.current === data.id) return;\n trackedViewRef.current = data.id;\n\n setIsDismissed(false);\n setCanDisplay(false);\n setRating(0);\n setSelectedOptions([]);\n setComments('');\n setIsSubmitted(false);\n\n const delay = data.details?.styling?.appearance?.displayDelay ?? 0;\n const timeoutId = globalThis.setTimeout(() => {\n setCanDisplay(true);\n void trackEvent('viewed', data.id);\n }, Math.max(0, delay) * 1000);\n\n return () => globalThis.clearTimeout(timeoutId);\n }, [data?.id]);\n\n const feedbackOptions = useMemo(() => {\n const source = data?.details?.feedback_option || {};\n return Object.keys(source)\n .sort((a, b) => a.localeCompare(b))\n .map((key) => source[key])\n .filter(Boolean);\n }, [data]);\n\n if (!data || !sdkVisible || isDismissed || !canDisplay) return null;\n\n const details = data.details;\n const styling = details.styling || {};\n const appearance = styling.appearance || {};\n\n const isHighRating = rating > LOW_RATING_CUTOFF;\n\n const configuredWidth = Number(details.width ?? 80);\n const compactCardWidth = Math.max(660, Math.min(1080, configuredWidth * 10));\n\n const handleToggleOption = (option: string) => {\n setSelectedOptions((prev) => (prev.includes(option) ? prev.filter((item) => item !== option) : [...prev, option]));\n };\n\n const handleSubmit = async (override?: { rating?: number; options?: string[]; comments?: string }) => {\n const ratingValue = override?.rating ?? rating;\n if (ratingValue < 1) return;\n setIsSubmitted(true);\n\n const campaignId = details.id || data.id;\n const selectedOption = (override?.options ?? selectedOptions)[0] || \"\";\n const additionalComments = override?.comments ?? comments ?? \"\";\n\n void trackEvent('csat captured', campaignId, {\n starCount: ratingValue,\n selectedOption: selectedOption,\n additionalComments: additionalComments,\n });\n };\n\n const handleRate = (value: number) => {\n setRating(value);\n if (value > LOW_RATING_CUTOFF) {\n setSelectedOptions([]);\n setComments('');\n // Mirror RN: show thanks after 1s and send `csat captured` with RN keys\n const campaignId = details.id || data?.id;\n setTimeout(() => {\n setIsSubmitted(true);\n try {\n void trackEvent('csat captured', campaignId, {\n starCount: value,\n selectedOption: \"\",\n additionalComments: \"\",\n });\n } catch (e) {\n console.warn('Error sending csat captured', e);\n }\n }, 1000);\n }\n };\n\n const handleDone = () => {\n if (isHighRating && details.link) {\n const campaignId = (data && data.id) || undefined;\n try {\n if (campaignId) void trackEvent('clicked', campaignId);\n } catch (err) {\n // ignore track errors\n }\n\n try {\n const link = String(details.link || '').trim();\n if (link && !link.startsWith('http')) {\n const revealed = revealCampaignFromLink(link);\n if (revealed) {\n setIsDismissed(true);\n return;\n }\n }\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n try {\n globalThis.open(details.link, '_blank');\n } catch (err) {\n // ignore\n }\n }\n\n setIsDismissed(true);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n right: `${appearance.margin?.right || 20}px`,\n bottom: `${appearance.margin?.bottom || 20}px`,\n zIndex: 999999,\n pointerEvents: 'none',\n }}\n >\n <div\n style={{\n position: 'relative',\n width: 'min(450px, calc(100vw - 32px))',\n maxHeight: '85vh',\n overflow: 'visible',\n backgroundColor: appearance.backgroundColor || '#2f6ef5',\n borderRadius: `${appearance.borderRadius ?? 12}px`,\n boxSizing: 'border-box',\n paddingTop: '8px',\n paddingRight: asSpacingValue(appearance.padding?.right) || '12px',\n paddingBottom: '4px',\n paddingLeft: asSpacingValue(appearance.padding?.left) || '12px',\n pointerEvents: 'auto',\n boxShadow: '0 14px 36px rgba(0, 0, 0, 0.25)',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <style>\n {`\n .appstorys-csat-scroll {\n scrollbar-width: none; /* Firefox */\n -ms-overflow-style: none; /* IE/Edge */\n }\n .appstorys-csat-scroll::-webkit-scrollbar {\n width: 0;\n height: 0;\n display: none; /* Chrome/Safari */\n }\n `}\n </style>\n\n {styling.crossButton?.enabled && (\n <CrossButton\n config={styling.crossButton}\n onPress={() => setIsDismissed(true)}\n style={{\n top: styling.crossButton?.margin?.top ?? 10,\n right: styling.crossButton?.margin?.right ?? 10,\n }}\n />\n )}\n\n <div\n className=\"appstorys-csat-scroll\"\n style={{\n flex: 1,\n minHeight: 0,\n overflowY: 'auto',\n paddingBottom: 4,\n }}\n >\n {isSubmitted ? (\n <CsatThankYouContent\n details={details}\n isHighRating={isHighRating}\n onDone={handleDone}\n />\n ) : (\n <CsatFormContent\n details={details}\n rating={rating}\n selectedOptions={selectedOptions}\n comments={comments}\n isHighRating={isHighRating}\n feedbackOptions={feedbackOptions}\n onRate={handleRate}\n onToggleOption={handleToggleOption}\n onCommentChange={setComments}\n onInlineSubmit={handleSubmit}\n canSubmit={rating >= 1}\n appearance={appearance}\n />\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default Csat;\n","import React, { useEffect, useMemo, useState, useRef } from 'react';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport trackEvent from '../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../core/campaignHelpers';\nimport CrossButton from '../common/CommonElements/CrossButton';\nimport { CampaignSurvey, SurveyCampaignDetails, SurveySlide, SurveyTextStyle } from '../../types';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport { resolveFontFamily } from '../../core/fontManager';\nimport * as LottieModule from 'lottie-react';\n\nconst Lottie =\n (LottieModule as any).default?.default ??\n (LottieModule as any).default ??\n (LottieModule as any).Lottie ??\n (LottieModule as any);\n\nfunction asSpacingValue(value?: number): string | undefined {\n if (value == null) return undefined;\n return `${value}px`;\n}\n\nfunction applyFontFamily(fontFamily?: string): string | undefined {\n return resolveFontFamily(fontFamily);\n}\n\nfunction textStyleToCss(textStyle?: SurveyTextStyle): React.CSSProperties {\n if (!textStyle) return {};\n\n return {\n color: textStyle.color,\n fontSize: textStyle.fontSize,\n fontFamily: applyFontFamily(textStyle.fontFamily),\n textAlign: textStyle.textAlign as React.CSSProperties['textAlign'],\n fontWeight: textStyle.fontDecoration?.includes('bold') ? 'bold' : undefined,\n fontStyle: textStyle.fontDecoration?.includes('italic') ? 'italic' : undefined,\n textDecoration: textStyle.fontDecoration?.includes('underline') ? 'underline' : undefined,\n };\n}\n\nfunction marginToStyle(margin?: SurveyTextStyle['margin']): React.CSSProperties {\n return {\n marginTop: asSpacingValue(margin?.top),\n marginRight: asSpacingValue(margin?.right),\n marginBottom: asSpacingValue(margin?.bottom),\n marginLeft: asSpacingValue(margin?.left),\n };\n}\n\nfunction getCornerRadius(cornerRadius?: { topLeft?: number; topRight?: number; bottomRight?: number; bottomLeft?: number }): string {\n return `${cornerRadius?.topLeft ?? 12}px ${cornerRadius?.topRight ?? 12}px ${cornerRadius?.bottomRight ?? cornerRadius?.topRight ?? 12}px ${cornerRadius?.bottomLeft ?? cornerRadius?.topLeft ?? 12}px`;\n}\n\nfunction getAlignment(alignment?: string): React.CSSProperties['justifyContent'] {\n if (alignment === 'right') return 'flex-end';\n if (alignment === 'left') return 'flex-start';\n return 'center';\n}\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction hexToRgba(hex: string, alpha: number): string {\n const raw = (hex || '').trim().replace('#', '');\n if (raw.length === 3) {\n const r = Number.parseInt(raw[0] + raw[0], 16);\n const g = Number.parseInt(raw[1] + raw[1], 16);\n const b = Number.parseInt(raw[2] + raw[2], 16);\n return `rgba(${r}, ${g}, ${b}, ${clamp01(alpha)})`;\n }\n\n if (raw.length === 6) {\n const r = Number.parseInt(raw.slice(0, 2), 16);\n const g = Number.parseInt(raw.slice(2, 4), 16);\n const b = Number.parseInt(raw.slice(4, 6), 16);\n return `rgba(${r}, ${g}, ${b}, ${clamp01(alpha)})`;\n }\n\n return `rgba(0, 0, 0, ${clamp01(alpha)})`;\n}\n\nfunction normalizeBackdropOpacity(opacity?: number): number {\n if (opacity == null) return 0.4;\n const value = Number(opacity);\n if (!Number.isFinite(value)) return 0.4;\n if (value > 1) return clamp01(value / 100);\n return clamp01(value);\n}\n\nfunction getOrderedSlides(details: SurveyCampaignDetails): SurveySlide[] {\n const slides = details.slides || [];\n return [...slides].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n}\n\n/**\n * Resolves a Dashboard `redirectTo` value to a navigation action.\n *\n * The Dashboard stores human-readable labels, not slide UUIDs:\n * \"Question N\" → surveySlides[N - 1] (0-based index)\n * \"Thank You Page\" / \"thank-you\" → the existing thank-you screen\n *\n * Fallbacks are included for UUID-based ids (legacy) and numeric order values.\n */\ntype LogicAction =\n | { action: 'jump'; targetIndex: number }\n | { action: 'thankyou' }\n | { action: 'none' };\n\nfunction resolveRedirectDestination(redirectTo: string, slides: SurveySlide[]): LogicAction {\n const trimmed = redirectTo.trim();\n if (!trimmed) return { action: 'none' };\n\n // ── Thank You variants ──────────────────────────────────────────────────────\n // Dashboard sends \"Thank You Page\"; also accept the legacy sentinel \"thank-you\"\n const compact = trimmed.toLowerCase().replace(/[\\s_-]+/g, '');\n if (compact === 'thankyou' || compact === 'thankyoupage') {\n return { action: 'thankyou' };\n }\n\n // ── \"Question N\" label ───────────────────────────────────────────────────────\n // Dashboard dropdown entries: \"Question 1\", \"Question 2\", …\n const questionMatch = /^question\\s+(\\d+)$/i.exec(trimmed);\n if (questionMatch) {\n const n = parseInt(questionMatch[1], 10);\n const targetIndex = n - 1; // 1-based label → 0-based index\n if (targetIndex >= 0 && targetIndex < slides.length) {\n return { action: 'jump', targetIndex };\n }\n return { action: 'none' }; // out-of-range question number\n }\n\n // ── Legacy: slide id (UUID) ──────────────────────────────────────────────────\n const byId = slides.findIndex((s) => s.id === trimmed);\n if (byId !== -1) {\n return { action: 'jump', targetIndex: byId };\n }\n\n // ── Legacy: numeric order value ─────────────────────────────────────────────\n const orderNum = Number(trimmed);\n if (Number.isFinite(orderNum) && orderNum > 0) {\n const byOrder = slides.findIndex((s) => s.order === orderNum);\n if (byOrder !== -1) {\n return { action: 'jump', targetIndex: byOrder };\n }\n }\n\n return { action: 'none' };\n}\n\nfunction getOrderedOptions(slide?: SurveySlide): string[] {\n const options = slide?.options || {};\n const keys = Object.keys(options);\n\n const parseIndex = (key: string): number | undefined => {\n const match = /(\\d+)/.exec(key);\n if (!match) return undefined;\n const parsed = Number(match[1]);\n return Number.isFinite(parsed) ? parsed : undefined;\n };\n\n keys.sort((a, b) => {\n const ai = parseIndex(a);\n const bi = parseIndex(b);\n\n if (ai != null && bi != null) return ai - bi;\n if (ai != null) return -1;\n if (bi != null) return 1;\n return a.localeCompare(b);\n });\n\n return keys\n .map((key) => options[key])\n .filter((value): value is string => typeof value === 'string' && value.trim().length > 0);\n}\n\nfunction getBulletLabel(optionListStyle: string | undefined, index: number): string | null {\n if (!optionListStyle) return null;\n\n if (optionListStyle === 'alphabet') {\n const start = 'a'.codePointAt(0) ?? 97; // lowercase 'a'\n return String.fromCodePoint(start + (index % 26)) + '.';\n }\n\n if (optionListStyle === 'number') {\n return String(index + 1) + '.';\n }\n\n if (optionListStyle === 'roman') {\n const romanNumerals = ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix', 'x', 'xi', 'xii', 'xiii', 'xiv', 'xv'];\n return (romanNumerals[index] || String(index + 1)) + '.';\n }\n\n return null;\n}\n\nfunction asNonNegativeNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value;\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value);\n if (Number.isFinite(parsed) && parsed >= 0) return parsed;\n }\n return undefined;\n}\n\nfunction getBorderWidthFromTextStyle(textStyle?: SurveyTextStyle): number {\n return asNonNegativeNumber(textStyle?.borderwidth) ?? 1;\n}\n\ninterface SurveyResponsesMap {\n [slideId: string]: {\n options?: string[];\n comment?: string;\n };\n}\n\ninterface SurveyFormContentProps {\n details: SurveyCampaignDetails;\n slide: SurveySlide;\n appearance?: SurveyCampaignDetails['styling'] extends { appearance?: infer A } ? A : any;\n selectedOptions: string[];\n comment: string;\n onSelectOption: (option: string) => void;\n onCommentChange: (value: string) => void;\n onSubmit: () => void;\n canSubmit: boolean;\n}\n\nconst SurveyFormContent: React.FC<SurveyFormContentProps> = ({\n details,\n slide,\n appearance,\n selectedOptions,\n comment,\n onSelectOption,\n onCommentChange,\n onSubmit,\n canSubmit,\n}) => {\n const styling = details.styling || {};\n const optionsStyle = styling.options || {};\n const cta = styling.cta;\n\n const options = useMemo(() => getOrderedOptions(slide), [slide]);\n const optionRowGap = optionsStyle.optionsSpacing ?? 8;\n const bulletGap = optionsStyle.bulletSpacing ?? 10;\n const optionHeight = optionsStyle.optionsHeight ?? 44;\n\n const ctaAlign = getAlignment(cta?.container?.alignment);\n\n return (\n <>\n <div style={marginToStyle(styling.title?.textStyle?.margin)}>\n <div\n style={{\n ...(textStyleToCss(styling.title?.textStyle)),\n color: styling.title?.textStyle?.color || '#111827',\n fontSize: styling.title?.textStyle?.fontSize || 20,\n lineHeight: 1.3,\n fontWeight: styling.title?.textStyle?.fontDecoration?.includes('bold') ? 'bold' : 700,\n }}\n >\n {slide.title || slide.question || details.name || 'Survey'}\n </div>\n </div>\n\n {(slide.subtitle || styling.subtitle?.textStyle) && (\n <div style={marginToStyle(styling.subtitle?.textStyle?.margin)}>\n <div\n style={{\n ...(textStyleToCss(styling.subtitle?.textStyle)),\n color: styling.subtitle?.textStyle?.color || '#6b7280',\n fontSize: styling.subtitle?.textStyle?.fontSize || 14,\n lineHeight: 1.35,\n }}\n >\n {slide.subtitle || ''}\n </div>\n </div>\n )}\n\n {options.length > 0 && (() => {\n // When additionalComment is enabled, the Dashboard appends \"Others\" as an extra\n // selectable option. We use a sentinel value to identify it without polluting the\n // payload options object.\n const OTHERS_SENTINEL = '__others__';\n const othersLabel = slide.additionalComment?.placeholder?.trim() || 'Others';\n const allOptions: Array<{ value: string; label: string }> = options.map((o) => ({ value: o, label: o }));\n if (slide.additionalComment?.enabled) {\n allOptions.push({ value: OTHERS_SENTINEL, label: othersLabel });\n }\n const isOthersSelected = selectedOptions.includes(OTHERS_SENTINEL);\n\n return (\n <>\n <div\n style={{\n marginTop: 10,\n display: 'flex',\n flexDirection: 'column',\n gap: optionRowGap,\n }}\n >\n {allOptions.map(({ value, label }, index) => {\n const isActive = selectedOptions.includes(value);\n const styleSource = isActive ? optionsStyle.selectedOptions : optionsStyle.nonSelectedOptions;\n const borderWidth = getBorderWidthFromTextStyle(styleSource?.textStyle);\n const bulletLabel = getBulletLabel(optionsStyle.optionListStyle, index);\n\n const listStyle = optionsStyle.optionListStyle;\n const isBulleted = listStyle === 'bulleted';\n const isTextIndicator = listStyle === 'number' || listStyle === 'alphabet' || listStyle === 'roman';\n\n return (\n <button\n key={`${value}-${index}`}\n onClick={() => onSelectOption(value)}\n style={{\n width: '100%',\n boxSizing: 'border-box',\n height: optionHeight,\n borderRadius: getCornerRadius(optionsStyle.cornerRadius),\n border: `${borderWidth}px solid ${styleSource?.colors?.border || '#e5e7eb'}`,\n background: styleSource?.colors?.background || '#ffffff',\n color: styleSource?.colors?.text || '#111827',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: bulletGap,\n paddingLeft: 14,\n paddingRight: 14,\n textAlign: 'left',\n ...(textStyleToCss(styleSource?.textStyle)),\n }}\n aria-pressed={isActive}\n >\n {isBulleted ? (\n <span\n aria-hidden\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n border: `2px solid ${styleSource?.colors?.text || '#111827'}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n {isActive && (\n <span\n style={{\n width: 10,\n height: 10,\n borderRadius: '50%',\n backgroundColor: styleSource?.colors?.text || '#111827',\n }}\n />\n )}\n </span>\n ) : isTextIndicator ? (\n <span\n aria-hidden\n style={{\n fontSize: 16,\n fontWeight: 600,\n color: styleSource?.colors?.text || '#111827',\n marginRight: 2,\n }}\n >\n {bulletLabel}\n </span>\n ) : null}\n\n <span style={{ flex: 1, minWidth: 0 }}>{label}</span>\n </button>\n );\n })}\n </div>\n\n {isOthersSelected && (\n <textarea\n value={comment}\n onChange={(event) => onCommentChange(event.target.value)}\n placeholder={slide.additionalComment?.placeholder || 'Type your response...'}\n style={{\n marginTop: 10,\n width: '100%',\n boxSizing: 'border-box',\n minHeight: 72,\n resize: 'none',\n overflowY: 'auto',\n border: `${getBorderWidthFromTextStyle(optionsStyle.additionalComments?.textStyle)}px solid ${optionsStyle.additionalComments?.colors?.border || '#e5e7eb'}`,\n background: optionsStyle.additionalComments?.colors?.background || '#ffffff',\n color: optionsStyle.additionalComments?.colors?.text || '#111827',\n borderRadius: getCornerRadius(optionsStyle.cornerRadius),\n padding: '12px',\n ...(textStyleToCss(optionsStyle.additionalComments?.textStyle)),\n }}\n />\n )}\n </>\n );\n })()\n }\n\n <div\n style={{\n position: 'sticky',\n bottom: 0,\n marginTop: 12,\n paddingTop: 10,\n paddingBottom: 6,\n background: appearance?.backgroundColor || '#ffffff',\n }}\n >\n <div\n style={{\n marginTop: cta?.margin?.top ?? 0,\n marginBottom: cta?.margin?.bottom ?? 0,\n marginLeft: cta?.margin?.left ?? 0,\n marginRight: cta?.margin?.right ?? 0,\n display: 'flex',\n justifyContent: ctaAlign,\n }}\n >\n <button\n onClick={onSubmit}\n disabled={!canSubmit}\n style={{\n width: cta?.container?.ctaFullWidth ? '100%' : (cta?.container?.ctaWidth ?? '100%'),\n height: cta?.container?.height ?? 44,\n border: `${cta?.container?.borderWidth ?? 0}px solid ${cta?.container?.borderColor || 'transparent'}`,\n background: cta?.container?.backgroundColor || '#111827',\n color: cta?.text?.color || '#ffffff',\n borderRadius: getCornerRadius(cta?.cornerRadius),\n fontFamily: applyFontFamily(cta?.text?.fontFamily),\n fontSize: cta?.text?.fontSize || 14,\n fontWeight: cta?.text?.fontDecoration?.includes('bold') ? 'bold' : 600,\n cursor: canSubmit ? 'pointer' : 'not-allowed',\n opacity: canSubmit ? 1 : 0.6,\n padding: '0 16px',\n }}\n >\n {slide.submitButtonText || 'Submit'}\n </button>\n </div>\n </div>\n </>\n );\n};\n\ninterface SurveyThankYouContentProps {\n details: SurveyCampaignDetails;\n onDone: () => void;\n}\n\nconst SurveyThankYouContent: React.FC<SurveyThankYouContentProps> = ({ details, onDone }) => {\n const styling = details.styling || {};\n const thankyouPage = styling.thankyouPage || {};\n\n const cta = thankyouPage.cta;\n const ctaAlign = getAlignment(cta?.container?.alignment);\n\n // Detect lottie by file extension — same pattern used by CSAT\n const isLottie = details.thankYouImage?.endsWith('.json');\n const [lottieData, setLottieData] = useState<any>(null);\n\n useEffect(() => {\n if (isLottie && details.thankYouImage) {\n fetch(details.thankYouImage)\n .then((res) => res.json())\n .then((json) => setLottieData(json))\n .catch((err) => console.error('AppStorys Survey: Error loading Thank You Lottie:', err));\n } else {\n setLottieData(null);\n }\n }, [details.thankYouImage, isLottie]);\n\n return (\n <>\n {details.thankYouImage && (\n <div style={{ display: 'flex', justifyContent: 'center', marginTop: 8 }}>\n {isLottie ? (\n lottieData ? (\n <Lottie\n animationData={lottieData}\n loop={true}\n style={{\n width: thankyouPage.imageStyle?.width || 80,\n height: thankyouPage.imageStyle?.height || 80,\n }}\n />\n ) : (\n // placeholder while lottie JSON is loading\n <div style={{ width: thankyouPage.imageStyle?.width || 80, height: thankyouPage.imageStyle?.height || 80 }} />\n )\n ) : (\n <img\n src={details.thankYouImage}\n alt=\"thank you\"\n style={{\n width: thankyouPage.imageStyle?.width || 80,\n height: thankyouPage.imageStyle?.height || 80,\n objectFit: 'cover',\n borderRadius: 10,\n }}\n />\n )}\n </div>\n )}\n\n <div style={{ ...marginToStyle(thankyouPage.title?.textStyle?.margin) }}>\n <div\n style={{\n ...(textStyleToCss(thankyouPage.title?.textStyle)),\n color: thankyouPage.title?.textStyle?.color || '#111827',\n fontSize: thankyouPage.title?.textStyle?.fontSize || 20,\n lineHeight: 1.3,\n fontWeight: thankyouPage.title?.textStyle?.fontDecoration?.includes('bold') ? 'bold' : 700,\n }}\n >\n {details.thankYouTitle || 'Thank you'}\n </div>\n </div>\n\n <div style={{ ...marginToStyle(thankyouPage.subtitle?.textStyle?.margin) }}>\n <div\n style={{\n ...(textStyleToCss(thankyouPage.subtitle?.textStyle)),\n color: thankyouPage.subtitle?.textStyle?.color || '#6b7280',\n fontSize: thankyouPage.subtitle?.textStyle?.fontSize || 14,\n lineHeight: 1.35,\n }}\n >\n {details.thankYouText || ''}\n </div>\n </div>\n\n {(details.thankYouButtonText || cta) && (\n <div\n style={{\n marginTop: cta?.margin?.top ?? 14,\n marginBottom: cta?.margin?.bottom ?? 0,\n marginLeft: cta?.margin?.left ?? 0,\n marginRight: cta?.margin?.right ?? 0,\n display: 'flex',\n justifyContent: ctaAlign,\n }}\n >\n <button\n onClick={onDone}\n style={{\n width: cta?.container?.ctaFullWidth ? '100%' : (cta?.container?.ctaWidth ?? 'auto'),\n height: cta?.container?.height ?? 40,\n border: `${cta?.container?.borderWidth ?? 0}px solid ${cta?.container?.borderColor || 'transparent'}`,\n background: cta?.container?.backgroundColor || '#111827',\n color: cta?.text?.color || '#ffffff',\n borderRadius: getCornerRadius(cta?.cornerRadius),\n fontFamily: applyFontFamily(cta?.text?.fontFamily),\n fontSize: cta?.text?.fontSize || 14,\n fontWeight: cta?.text?.fontDecoration?.includes('bold') ? 'bold' : 600,\n cursor: 'pointer',\n padding: '0 16px',\n }}\n >\n {details.thankYouButtonText || 'Done'}\n </button>\n </div>\n )}\n </>\n );\n};\n\nexport const Survey: React.FC = () => {\n const hookData = useCampaigns<CampaignSurvey>('SUR');\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n\n const data = hookData ?? ((): CampaignSurvey | undefined => {\n const screen = (currentScreen || '').trim().toLowerCase();\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign: any) => {\n if (!campaign) return false;\n if (campaign.campaign_type !== 'SUR') return false;\n const hasTrigger = Boolean(campaign.trigger_event ?? campaign.trigger);\n const displayTriggerReady = (campaign as any).display_trigger !== false && !hasTrigger;\n if (!displayTriggerReady) return false;\n const cs = (campaign.screen || '').trim().toLowerCase();\n return !cs || cs === screen;\n }) as CampaignSurvey | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignSurvey;\n } catch {\n return found;\n }\n })();\n\n const [isDismissed, setIsDismissed] = useState(false);\n const [canDisplay, setCanDisplay] = useState(false);\n const [currentIndex, setCurrentIndex] = useState(0);\n const [selectedOptions, setSelectedOptions] = useState<string[]>([]);\n const [comment, setComment] = useState('');\n const [responses, setResponses] = useState<SurveyResponsesMap>({});\n const [isSubmitted, setIsSubmitted] = useState(false);\n\n const trackedViewRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!data?.id) return;\n if (trackedViewRef.current === data.id) return;\n trackedViewRef.current = data.id;\n\n setIsDismissed(false);\n setCanDisplay(false);\n setCurrentIndex(0);\n setSelectedOptions([]);\n setComment('');\n setResponses({});\n setIsSubmitted(false);\n\n const delay = data.details?.styling?.appearance?.displayDelay ?? 0;\n const timeoutId = globalThis.setTimeout(() => {\n setCanDisplay(true);\n // Include survey identifiers in initial view event so backend can map impressions\n const surveyId = data.details?.id;\n const orderedSlides = getOrderedSlides(data.details);\n const firstSlideId = orderedSlides.length > 0 ? orderedSlides[0].id : undefined;\n void trackEvent('viewed', data.id, {\n survey_id: surveyId,\n slide_id: firstSlideId,\n });\n }, Math.max(0, delay) * 1000);\n\n return () => globalThis.clearTimeout(timeoutId);\n }, [data?.id]);\n\n const slides = useMemo(() => (data ? getOrderedSlides(data.details) : []), [data]);\n const slide = slides[currentIndex];\n\n useEffect(() => {\n if (!slide) return;\n const existing = responses[slide.id];\n setSelectedOptions(existing?.options ?? []);\n setComment(existing?.comment ?? '');\n }, [slide?.id]);\n\n if (!data || !sdkVisible || isDismissed || !canDisplay) return null;\n\n const details: SurveyCampaignDetails = data.details;\n const styling = details.styling || {};\n const appearance = styling.appearance || {};\n\n const backdropColor = appearance.backdropColor || '#000000';\n const backdropOpacity = normalizeBackdropOpacity(appearance.backdropOpacity);\n\n // Multi-select is enabled by default (matches mobile app behavior).\n // A future payload field can explicitly disable it (e.g. multipleSelection: false).\n const isMultiSelectEnabled = (slide as any)?.multipleSelection !== false &&\n (slide as any)?.isMultiSelect !== false &&\n (styling.options as any)?.multipleSelection !== false;\n\n const handleSelectOption = (option: string) => {\n if (isMultiSelectEnabled) {\n setSelectedOptions((prev) =>\n prev.includes(option) ? prev.filter((o) => o !== option) : [...prev, option]\n );\n } else {\n setSelectedOptions((prev) => (prev[0] === option ? [] : [option]));\n }\n };\n\n const submitSurvey = async (finalResponses: SurveyResponsesMap, finalSlideId: string) => {\n const responsesArray = slides.map((s) => ({\n slide_id: s.id,\n order: s.order,\n title: s.title,\n question: s.question,\n selected_options: finalResponses[s.id]?.options,\n comment: finalResponses[s.id]?.comment,\n }));\n\n // Use top-level campaign id for capture payload (campaign_id)\n const campaignId = data.id;\n\n // Mirror RN: include selected options and any 'other' text in metadata\n // Map selected option values back to their option keys (option1, option2, ...)\n const selectedOptionsKeys: string[] = [];\n for (const s of slides) {\n const selectedValues = finalResponses[s.id]?.options || [];\n for (const val of selectedValues) {\n const optionEntry = Object.entries(s.options || {}).find(([, v]) => String(v) === String(val));\n if (optionEntry) selectedOptionsKeys.push(optionEntry[0]);\n }\n }\n const otherText = responsesArray.map(r => r.comment).filter(Boolean as any).join(' || ') || \"\";\n\n // Send survey identifiers and captured answers (match native `survey captured`)\n const captureCampaignId = details.id || campaignId;\n void trackEvent('survey captured', captureCampaignId, {\n survey_id: details.id,\n slide_id: finalSlideId,\n selected_options: selectedOptionsKeys,\n otherText,\n });\n\n const shouldShowThankYou = styling.content?.isThankyouPage !== false;\n if (shouldShowThankYou) {\n setIsSubmitted(true);\n } else {\n setIsDismissed(true);\n }\n };\n\n const handleSubmitCurrent = async () => {\n if (!slide) return;\n if (selectedOptions.length === 0) return;\n\n const nextResponses: SurveyResponsesMap = {\n ...responses,\n [slide.id]: {\n options: selectedOptions,\n comment,\n },\n };\n\n setResponses(nextResponses);\n\n // map the selected option values to their keys\n const optionKeys: string[] = [];\n if (slide.options) {\n for (const selectedOption of selectedOptions) {\n const found = Object.entries(slide.options).find(([, val]) => String(val) === String(selectedOption));\n if (found) optionKeys.push(found[0]);\n }\n }\n\n // Send a capture event for the current slide (mirror RN per-slide capture behavior)\n try {\n const campaignId = data.id;\n // Per-slide capture: use native `survey captured` with details.id as campaign id\n const perSlideCampaignId = details.id || campaignId;\n void trackEvent('survey captured', perSlideCampaignId, {\n survey_id: details.id,\n slide_id: slide.id,\n selected_options: optionKeys,\n otherText: comment || \"\",\n });\n } catch (e) {\n console.warn('Error sending per-slide survey captured', e);\n }\n\n // ── Evaluate Logic rules ────────────────────────────────────────────────\n // Dashboard `selectOption` contains option keys (e.g. \"option 2\").\n // `optionKeys` holds the keys reverse-mapped from the selected display values,\n // so matching against optionKeys covers the normal single/multi-select path.\n // The __others__ sentinel is checked separately against the Dashboard key \"others\".\n const isOthersSelected = selectedOptions.includes('__others__');\n let logicAction: LogicAction = { action: 'none' };\n\n for (const rule of (slide.logic || [])) {\n const ruleOptions = rule.selectOption || [];\n if (ruleOptions.length === 0) continue;\n\n const keyMatch = ruleOptions.some((opt) => optionKeys.includes(opt));\n const valueMatch = ruleOptions.some((opt) => selectedOptions.includes(opt));\n const othersMatch =\n isOthersSelected &&\n ruleOptions.some((opt) => opt === 'others' || opt === '__others__');\n\n if (!keyMatch && !valueMatch && !othersMatch) continue;\n\n // First matching rule wins; resolve the destination label → action\n if (rule.redirectTo) {\n const resolved = resolveRedirectDestination(rule.redirectTo, slides);\n if (resolved.action !== 'none') {\n logicAction = resolved;\n break;\n }\n }\n }\n // ── End Logic evaluation ────────────────────────────────────────────────\n\n if (logicAction.action === 'thankyou') {\n await submitSurvey(nextResponses, slide.id);\n return;\n }\n\n if (logicAction.action === 'jump') {\n setCurrentIndex(logicAction.targetIndex);\n return;\n }\n\n // No logic rule matched — normal sequential navigation\n const isLastSlide = currentIndex >= slides.length - 1;\n if (isLastSlide) {\n await submitSurvey(nextResponses, slide.id);\n return;\n }\n\n setCurrentIndex((prev) => Math.min(prev + 1, slides.length - 1));\n };\n\n const handleDone = () => {\n const config = details.thankYouButtonConfig;\n if (config?.enabled && config.redirectUrl) {\n try {\n const redirect = String(config.redirectUrl || '').trim();\n if (redirect && !redirect.startsWith('http')) {\n const revealed = revealCampaignFromLink(redirect);\n if (revealed) {\n setIsDismissed(true);\n return;\n }\n }\n } catch (err) {\n console.warn('revealCampaignFromLink error', err);\n }\n\n try {\n globalThis.open(config.redirectUrl, '_blank');\n } catch (err) {\n // ignore\n }\n }\n setIsDismissed(true);\n };\n\n const handleDismiss = async () => {\n try {\n const campaignId = data?.id;\n const surveyId = details?.id;\n const slideId = slide?.id;\n await trackEvent('SurveyDismissed', campaignId, {\n survey_id: surveyId,\n slide_id: slideId,\n });\n } catch (err) {\n console.warn('Error sending SurveyDismissed', err);\n } finally {\n setIsDismissed(true);\n }\n };\n\n if (!slide) return null;\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 999999,\n display: 'flex',\n justifyContent: 'flex-end',\n alignItems: 'flex-end',\n padding: 12,\n pointerEvents: 'none',\n }}\n >\n <div\n aria-hidden\n style={{\n position: 'absolute',\n inset: 0,\n background: hexToRgba(backdropColor, backdropOpacity),\n }}\n />\n\n <div\n style={{\n position: 'relative',\n width: 'min(420px, 92vw)',\n maxWidth: '92vw',\n minWidth: '320px',\n maxHeight: '80vh',\n overflow: 'hidden',\n backgroundColor: appearance.backgroundColor || '#ffffff',\n borderRadius: getCornerRadius(appearance.cornerRadius),\n boxSizing: 'border-box',\n paddingTop: 14,\n paddingRight: 16,\n paddingBottom: 10,\n paddingLeft: 16,\n pointerEvents: 'auto',\n boxShadow: '0 14px 36px rgba(0, 0, 0, 0.25)',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <style>\n {`\n .appstorys-survey-scroll {\n scrollbar-width: none; /* Firefox */\n -ms-overflow-style: none; /* IE/Edge */\n }\n .appstorys-survey-scroll::-webkit-scrollbar {\n width: 0;\n height: 0;\n display: none; /* Chrome/Safari */\n }\n `}\n </style>\n\n {styling.crossButton?.enabled && (\n <CrossButton\n config={styling.crossButton}\n onPress={handleDismiss}\n style={{\n top: styling.crossButton?.margin?.top ?? 10,\n right: styling.crossButton?.margin?.right ?? 10,\n }}\n />\n )}\n\n <div\n className=\"appstorys-survey-scroll\"\n style={{\n flex: 1,\n minHeight: 0,\n overflowY: 'auto',\n paddingRight: 2,\n }}\n >\n {isSubmitted ? (\n <SurveyThankYouContent details={details} onDone={handleDone} />\n ) : (\n <SurveyFormContent\n details={details}\n slide={slide}\n appearance={appearance}\n selectedOptions={selectedOptions}\n comment={comment}\n onSelectOption={handleSelectOption}\n onCommentChange={setComment}\n onSubmit={handleSubmitCurrent}\n canSubmit={selectedOptions.length > 0}\n />\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default Survey;\n","import React, { useEffect, useState, useRef } from 'react';\nimport useCampaigns from '../../hooks/useCampaigns';\nimport useAppStorysStore from '../../core/store';\nimport { resolveCampaignVariant } from '../../core/variantResolver';\nimport trackEvent from '../../core/trackEvent';\nimport { CampaignModal } from '../../types';\nimport { ModalWithCta } from './components/ModalWithCta';\nimport { MediaOnlyModal } from './components/MediaOnlyModal';\n\nexport const Modal: React.FC = () => {\n const hookData = useCampaigns<CampaignModal>('MOD');\n const campaigns = useAppStorysStore((state: any) => state.campaigns);\n const allCampaigns = useAppStorysStore((state: any) => state.allCampaigns);\n const currentScreen = useAppStorysStore((state: any) => state.currentScreen);\n\n const data = hookData ?? ((): CampaignModal | undefined => {\n const screen = (currentScreen || '').trim().toLowerCase();\n const found = [...(campaigns || []), ...(allCampaigns || [])].find((campaign: any) => {\n if (!campaign) return false;\n if (campaign.campaign_type !== 'MOD') return false;\n const hasTrigger = Boolean(campaign.trigger_event ?? campaign.trigger);\n const displayTriggerReady = (campaign as any).display_trigger !== false && !hasTrigger;\n if (!displayTriggerReady) return false;\n const cs = (campaign.screen || '').trim().toLowerCase();\n return !cs || cs === screen;\n }) as CampaignModal | undefined;\n\n if (!found) return undefined;\n try {\n return resolveCampaignVariant(found) as CampaignModal;\n } catch {\n return found;\n }\n })();\n\n const sdkVisible = useAppStorysStore((state: any) => state.isVisible);\n const [isDismissed, setIsDismissed] = useState(false);\n\n const trackedViewRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (data?.id && trackedViewRef.current !== data.id) {\n trackedViewRef.current = data.id;\n setIsDismissed(false);\n const variantId = (data as any)._variantId || (data.details as any)?.id;\n const metadata = variantId ? { variant_id: variantId } : undefined;\n void trackEvent('viewed', data.id, metadata);\n }\n }, [data?.id]);\n\n const removeTrackedEvent = (eventKey: string) => {\n try {\n const state = useAppStorysStore.getState();\n const tracked = state.trackedEvents || [];\n const next = tracked.filter((e: string) => e !== eventKey);\n state.setTrackedEvents(next);\n } catch {\n // ignore\n }\n };\n\n if (!data || isDismissed || !sdkVisible) return null;\n\n const handleDismiss = () => {\n if (data?.id) removeTrackedEvent(`viaAppStorys${data.id}`);\n setIsDismissed(true);\n };\n\n const modalType = data.details?.modal_type || data.details?.modals?.[0]?.modal_type || '';\n const isMediaModal = modalType === 'full-page-modal' || modalType === 'media-only-modal';\n\n if (isMediaModal) {\n return <MediaOnlyModal campaign={data} onDismiss={handleDismiss} />;\n }\n return <ModalWithCta campaign={data} onDismiss={handleDismiss} />;\n};\n\nexport default Modal;\n","import React, { useEffect, useState, useRef } from 'react';\nimport { resolveFontFamily } from '../../../core/fontManager';\nimport { personalizeText } from '../../../core/personalization';\nimport trackEvent from '../../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../../core/campaignHelpers';\nimport CrossButton from '../../common/CommonElements/CrossButton';\nimport {\n CampaignModal,\n ModalItem,\n ModalCtaRedirection,\n ModalCtaStyle,\n} from '../../../types';\nimport { SoundButton } from '../../common/CommonElements/SoundButton';\nimport * as LottieModule from 'lottie-react';\n\nconst Lottie =\n (LottieModule as any).default?.default ??\n (LottieModule as any).default ??\n (LottieModule as any).Lottie ??\n (LottieModule as any);\n\ninterface ModalWithCtaProps {\n campaign: CampaignModal;\n onDismiss: () => void;\n}\n\nconst mapTextAlign = (align?: string): React.CSSProperties['textAlign'] => {\n if (!align) return undefined;\n const a = align.trim().toLowerCase();\n if (a === 'middle') return 'center';\n if (a === 'left' || a === 'right' || a === 'center' || a === 'justify') {\n return a as any;\n }\n return undefined;\n};\n\nconst handleCtaRedirection = (\n redirection: ModalCtaRedirection | undefined,\n campaignId?: string,\n campaign?: CampaignModal,\n) => {\n if (!redirection) return;\n if (campaignId) {\n const variantId = (campaign as any)?._variantId || (campaign?.details as any)?.id;\n const metadata = variantId ? { variant_id: variantId } : undefined;\n void trackEvent('clicked', campaignId, metadata);\n }\n\n const url = (redirection.url || '').trim();\n const value = (redirection.value || '').trim();\n\n if (value && !value.startsWith('http')) {\n try {\n const revealed = revealCampaignFromLink(value);\n if (revealed) return;\n } catch {\n // ignore\n }\n }\n\n if (url) {\n try {\n window.open(url, '_blank');\n } catch {\n // ignore\n }\n return;\n }\n\n if (value) {\n try {\n window.open(value, '_blank');\n } catch {\n // ignore\n }\n }\n};\n\nexport const ModalWithCta: React.FC<ModalWithCtaProps> = ({ campaign, onDismiss }) => {\n const [windowWidth, setWindowWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : 1024);\n const [lottieData, setLottieData] = useState<any>(null);\n const [isMuted, setIsMuted] = useState(true);\n const videoRef = useRef<HTMLVideoElement | null>(null);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const handleResize = () => setWindowWidth(window.innerWidth);\n window.addEventListener('resize', handleResize);\n \n // Prevent background scrolling while Modal is open\n const originalOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n \n return () => {\n window.removeEventListener('resize', handleResize);\n document.body.style.overflow = originalOverflow;\n };\n }, []);\n\n const { details } = campaign;\n const modalItem = details?.modals?.[0];\n\n const content = modalItem?.content || {};\n const styling = modalItem?.styling || {};\n\n const chooseMediaType = content?.chooseMediaType || modalItem?.chooseMediaType;\n const mediaType = chooseMediaType?.type;\n const mediaUrl = chooseMediaType?.url;\n\n useEffect(() => {\n if (mediaType === 'lottie' && mediaUrl) {\n setLottieData(null);\n fetch(mediaUrl)\n .then(res => res.json())\n .then(json => setLottieData(json))\n .catch(err => console.error('Error fetching Lottie in ModalWithCta:', err));\n } else {\n setLottieData(null);\n }\n }, [mediaType, mediaUrl]);\n\n // Sync muted state to video element\n useEffect(() => {\n if (videoRef.current) {\n videoRef.current.muted = isMuted;\n }\n }, [isMuted]);\n\n // Attempt unmuted autoplay; fall back to muted if browser blocks it\n useEffect(() => {\n const video = videoRef.current;\n if (!video || mediaType !== 'video') return;\n \n video.muted = false;\n const playPromise = video.play();\n if (playPromise !== undefined) {\n playPromise\n .then(() => {\n setIsMuted(false);\n })\n .catch(() => {\n video.muted = true;\n setIsMuted(true);\n video.play().catch(() => {});\n });\n }\n }, [mediaUrl, mediaType]);\n\n if (!modalItem) return null;\n\n const appearance = styling.appearance || {};\n const crossButton = styling.crossButton;\n\n // Backdrop\n const backdropColor = appearance.backdrop?.color || 'rgba(0, 0, 0, 0.4)';\n const backdropOpacity = (appearance.backdrop?.opacity !== undefined && appearance.backdrop?.opacity !== null)\n ? (appearance.backdrop.opacity > 1 ? appearance.backdrop.opacity / 100 : appearance.backdrop.opacity)\n : 0;\n const enableBackdrop = appearance.enableBackdrop !== false;\n\n // Modal dimensions (responsive and scaled 40% on desktop)\n const baseWidth = (appearance.dimension?.width !== undefined && appearance.dimension?.width !== null && appearance.dimension.width > 0)\n ? appearance.dimension.width\n : 300;\n const isDesktop = windowWidth >= 768;\n const scaledWidth = isDesktop ? baseWidth * 1.4 : baseWidth;\n const modalWidth = Math.min(scaledWidth, windowWidth * 0.9);\n\n const cornerRadius = appearance.cornerRadius || {};\n const backgroundColor = appearance.backgroundColor || '#FFFFFF';\n\n // Title & Subtitle\n const titleText = content.titleText || '';\n const subtitleText = content.subtitleText || '';\n\n // CTAs\n const primaryCtaText = content.primaryCtaText || '';\n const secondaryCtaText = content.secondaryCtaText || '';\n const primaryCtaRedirection = content.primaryCtaRedirection;\n const secondaryCtaRedirection = content.secondaryCtaRedirection;\n\n const titleStyle = styling.title || {};\n const subTitleStyle = styling.subTitle || {};\n const primaryCtaStyle = styling.primaryCta || {};\n const secondaryCtaStyle = styling.secondaryCta || {};\n\n const renderCtaButton = (\n text: string,\n ctaStyling: ModalCtaStyle | undefined,\n redirection: ModalCtaRedirection | undefined,\n isSideBySide: boolean = false,\n ) => {\n if (!text || text.trim() === '') return null;\n\n const container = ctaStyling?.container || {};\n const cr = ctaStyling?.cornerRadius || {};\n const margin = ctaStyling?.margin || {};\n const textStyle = ctaStyling?.text || {};\n\n const getJustify = (alignment?: string) => {\n if (alignment === 'left') return 'flex-start';\n if (alignment === 'right') return 'flex-end';\n return 'center';\n };\n\n const baseCtaWidth = container.ctaWidth;\n const scaledCtaWidth = isDesktop && baseCtaWidth ? baseCtaWidth * 1.4 : baseCtaWidth;\n const baseCtaHeight = container.height || 40;\n const buttonHeight = isDesktop ? baseCtaHeight * 1.2 : baseCtaHeight;\n\n const topLeftRadius = (cr.topLeft !== undefined && cr.topLeft >= 0) ? cr.topLeft : 8;\n const topRightRadius = (cr.topRight !== undefined && cr.topRight >= 0) ? cr.topRight : 8;\n const bottomRightRadius = (cr.bottomRight !== undefined && cr.bottomRight >= 0) ? cr.bottomRight : 8;\n const bottomLeftRadius = (cr.bottomLeft !== undefined && cr.bottomLeft >= 0) ? cr.bottomLeft : 8;\n\n return (\n <div\n style={{\n display: 'flex',\n justifyContent: getJustify(container.alignment),\n width: isSideBySide ? 'auto' : '100%',\n flex: isSideBySide ? 1 : undefined,\n marginTop: (margin.top !== undefined && margin.top >= 0) ? margin.top : 0,\n marginBottom: (margin.bottom !== undefined && margin.bottom >= 0) ? margin.bottom : 0,\n marginLeft: (margin.left !== undefined && margin.left >= 0) ? margin.left : 0,\n marginRight: (margin.right !== undefined && margin.right >= 0) ? margin.right : 0,\n boxSizing: 'border-box',\n }}\n >\n <button\n style={{\n width: (isSideBySide || container.ctaFullWidth) ? '100%' : (scaledCtaWidth ? `${scaledCtaWidth}px` : 'auto'),\n height: buttonHeight,\n backgroundColor: container.backgroundColor || '#FE6B35',\n color: textStyle.color || '#FFFFFF',\n border: `${container.borderWidth || 0}px solid ${container.borderColor || 'transparent'}`,\n borderRadius: `${topLeftRadius}px ${topRightRadius}px ${bottomRightRadius}px ${bottomLeftRadius}px`,\n fontSize: textStyle.fontSize || 14,\n fontFamily: resolveFontFamily(textStyle.fontFamily) || 'Arial',\n fontWeight: textStyle.fontDecoration?.includes('bold') ? 'bold' : 'normal',\n fontStyle: textStyle.fontDecoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: textStyle.fontDecoration?.includes('underline') ? 'underline' : 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 16px',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n onClick={() => handleCtaRedirection(redirection, campaign?.id, campaign)}\n >\n {personalizeText(text)}\n </button>\n </div>\n );\n };\n\n return (\n <>\n {/* Hidden-scrollbar styles injected once */}\n <style>{`\n .appstorys-modal-scroll::-webkit-scrollbar { display: none; }\n .appstorys-modal-scroll { scrollbar-width: none; }\n `}</style>\n {/* Interaction Lock / Backdrop */}\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: enableBackdrop ? backdropColor : 'transparent',\n opacity: enableBackdrop ? backdropOpacity : 1,\n zIndex: 999998,\n transition: 'opacity 0.3s ease',\n }}\n />\n\n {/* Outer Modal Wrapper — overflow: visible so CrossButton can extend outside */}\n <div\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: modalWidth,\n maxWidth: '95vw',\n zIndex: 999999,\n overflow: 'visible',\n }}\n >\n {/* Cross Button — anchored to outer wrapper, never clipped */}\n {(crossButton?.enabled ?? true) && (\n <CrossButton\n config={crossButton || { enabled: true }}\n onPress={(e) => {\n if (e && typeof e.stopPropagation === 'function') {\n e.stopPropagation();\n }\n onDismiss();\n }}\n style={{\n position: 'absolute',\n zIndex: 10000000,\n top: (crossButton?.margin?.top !== undefined && crossButton.margin?.top >= 0) ? crossButton.margin.top : 8,\n right: (crossButton?.margin?.right !== undefined && crossButton.margin?.right >= 0) ? crossButton.margin.right : 8,\n }}\n />\n )}\n\n {/* Inner Modal Content — owns border-radius, background, shadow */}\n <div\n style={{\n width: '100%',\n backgroundColor: backgroundColor,\n borderTopLeftRadius: (cornerRadius.topLeft !== undefined && cornerRadius.topLeft >= 0) ? cornerRadius.topLeft : 0,\n borderTopRightRadius: (cornerRadius.topRight !== undefined && cornerRadius.topRight >= 0) ? cornerRadius.topRight : 0,\n borderBottomLeftRadius: (cornerRadius.bottomLeft !== undefined && cornerRadius.bottomLeft >= 0) ? cornerRadius.bottomLeft : 0,\n borderBottomRightRadius: (cornerRadius.bottomRight !== undefined && cornerRadius.bottomRight >= 0) ? cornerRadius.bottomRight : 0,\n overflow: 'hidden',\n boxShadow: '0 8px 32px rgba(0,0,0,0.25)',\n display: 'flex',\n flexDirection: 'column',\n maxHeight: '90vh',\n }}\n >\n {/* Scrollable content area — media + title + subtitle */}\n <div\n className=\"appstorys-modal-scroll\"\n style={{\n flex: 1,\n overflowY: 'auto',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n minHeight: 0,\n }}\n >\n\n {/* Media (Image / Video / Lottie) */}\n {mediaUrl && (mediaType === 'image' || !mediaType) && (\n <img\n src={mediaUrl}\n alt=\"\"\n style={{\n width: '100%',\n display: 'block',\n // No explicit height — browser preserves intrinsic aspect ratio\n }}\n />\n )}\n {mediaUrl && mediaType === 'video' && (\n <div style={{ position: 'relative', width: '100%' }}>\n <video\n ref={videoRef}\n src={mediaUrl}\n autoPlay\n loop\n muted={isMuted}\n playsInline\n controls={false}\n style={{\n width: '100%',\n display: 'block',\n // No explicit height — browser preserves intrinsic aspect ratio\n }}\n />\n {/* Sound Toggle Button — inside position:relative wrapper so absolute offset is correct */}\n <SoundButton\n config={{\n size: 32,\n color: { cross: '#ffffff', fill: 'rgba(0,0,0,0.45)', stroke: 'transparent' },\n margin: { top: 0, bottom: 0, left: 0, right: 0 },\n image: '',\n }}\n onPress={(e) => {\n e.stopPropagation();\n setIsMuted((prev) => !prev);\n }}\n type={isMuted ? 'mute' : 'unmute'}\n enabled={true}\n style={{\n position: 'absolute',\n zIndex: 10000000,\n bottom: 12,\n left: 12,\n borderRadius: '50%',\n }}\n />\n </div>\n )}\n\n {mediaUrl && mediaType === 'lottie' && lottieData && (() => {\n // Derive proportional height from Lottie composition dimensions\n const lottieW = lottieData.w as number | undefined;\n const lottieH = lottieData.h as number | undefined;\n const lottieAspect = (lottieW && lottieH && lottieW > 0) ? lottieH / lottieW : undefined;\n const lottiePixelWidth = modalWidth;\n const lottiePixelHeight = lottieAspect ? Math.round(lottiePixelWidth * lottieAspect) : undefined;\n return (\n <Lottie\n animationData={lottieData}\n loop={true}\n autoplay={true}\n style={{\n width: lottiePixelWidth,\n height: lottiePixelHeight,\n display: 'block',\n }}\n />\n );\n })()}\n\n {/* Title */}\n {titleText.trim() !== '' && (\n <div\n style={{\n width: '100%',\n padding: '12px 16px 0 16px',\n color: titleStyle.color || '#000000',\n fontSize: titleStyle.fontSize || 26,\n fontFamily: resolveFontFamily(titleStyle.fontFamily) || 'Helvetica',\n fontWeight: titleStyle.fontDecoration?.includes('bold') ? 'bold' : '600',\n fontStyle: titleStyle.fontDecoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: titleStyle.fontDecoration?.includes('underline') ? 'underline' : 'none',\n textAlign: mapTextAlign(titleStyle.textAlign) || 'center',\n boxSizing: 'border-box',\n }}\n >\n {personalizeText(titleText)}\n </div>\n )}\n\n {/* Subtitle */}\n {subtitleText.trim() !== '' && (\n <div\n style={{\n width: '100%',\n padding: '4px 16px 0 16px',\n color: subTitleStyle.color || '#000000',\n fontSize: subTitleStyle.fontSize || 20,\n fontFamily: resolveFontFamily(subTitleStyle.fontFamily) || 'Helvetica',\n fontWeight: subTitleStyle.fontDecoration?.includes('bold') ? 'bold' : 'normal',\n fontStyle: subTitleStyle.fontDecoration?.includes('italic') ? 'italic' : 'normal',\n textDecoration: subTitleStyle.fontDecoration?.includes('underline') ? 'underline' : 'none',\n textAlign: mapTextAlign(subTitleStyle.textAlign) || 'center',\n boxSizing: 'border-box',\n }}\n >\n {personalizeText(subtitleText)}\n </div>\n )}\n\n </div>{/* end scrollable content area */}\n\n {/* CTA Footer — flex-shrink:0 so it never scrolls away */}\n {(primaryCtaText.trim() !== '' || secondaryCtaText.trim() !== '') && (\n <div\n style={{\n flexShrink: 0,\n width: '100%',\n padding: '0 12px 12px 12px',\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: (primaryCtaText.trim() !== '' && secondaryCtaText.trim() !== '') ? 'row' : 'column',\n gap: '8px',\n justifyContent: 'center',\n }}\n >\n {renderCtaButton(\n primaryCtaText,\n primaryCtaStyle,\n primaryCtaRedirection,\n primaryCtaText.trim() !== '' && secondaryCtaText.trim() !== ''\n )}\n {renderCtaButton(\n secondaryCtaText,\n secondaryCtaStyle,\n secondaryCtaRedirection,\n primaryCtaText.trim() !== '' && secondaryCtaText.trim() !== ''\n )}\n </div>\n )}\n </div>{/* end inner modal content */}\n </div>{/* end outer modal wrapper */}\n </>\n );\n};\n","import React, { useEffect, useState, useRef } from 'react';\nimport { resolveFontFamily } from '../../../core/fontManager';\nimport { personalizeText } from '../../../core/personalization';\nimport trackEvent from '../../../core/trackEvent';\nimport { revealCampaignFromLink } from '../../../core/campaignHelpers';\nimport CrossButton from '../../common/CommonElements/CrossButton';\nimport { CampaignModal } from '../../../types';\nimport { SoundButton } from '../../common/CommonElements/SoundButton';\nimport * as LottieModule from 'lottie-react';\n\nconst Lottie =\n (LottieModule as any).default?.default ??\n (LottieModule as any).default ??\n (LottieModule as any).Lottie ??\n (LottieModule as any);\n\ninterface MediaOnlyModalProps {\n campaign: CampaignModal;\n onDismiss: () => void;\n}\n\nconst handleRedirection = (\n redirection: any,\n campaignId?: string,\n campaign?: CampaignModal,\n) => {\n if (!redirection) return;\n if (campaignId) {\n const variantId = (campaign as any)?._variantId || (campaign?.details as any)?.id;\n const metadata = variantId ? { variant_id: variantId } : undefined;\n void trackEvent('clicked', campaignId, metadata);\n }\n\n const url = (redirection.url || '').trim();\n const value = (redirection.value || '').trim();\n\n if (value && !value.startsWith('http')) {\n try {\n const revealed = revealCampaignFromLink(value);\n if (revealed) return;\n } catch {\n // ignore\n }\n }\n\n if (url) {\n try {\n window.open(url, '_blank');\n } catch {\n // ignore\n }\n return;\n }\n\n if (value) {\n try {\n window.open(value, '_blank');\n } catch {\n // ignore\n }\n }\n};\n\nexport const MediaOnlyModal: React.FC<MediaOnlyModalProps> = ({ campaign, onDismiss }) => {\n const [windowWidth, setWindowWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : 1024);\n const [lottieData, setLottieData] = useState<any>(null);\n const [isMuted, setIsMuted] = useState(true);\n const videoRef = useRef<HTMLVideoElement | null>(null);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const handleResize = () => setWindowWidth(window.innerWidth);\n window.addEventListener('resize', handleResize);\n \n // Prevent background scrolling while Modal is open\n const originalOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n \n return () => {\n window.removeEventListener('resize', handleResize);\n document.body.style.overflow = originalOverflow;\n };\n }, []);\n\n const { details } = campaign;\n const modalItem = details?.modals?.[0];\n\n const chooseMediaType = modalItem?.chooseMediaType;\n const styling = modalItem?.styling || {};\n const redirection = modalItem?.redirection;\n\n const mediaType = chooseMediaType?.type;\n const mediaUrl = chooseMediaType?.url;\n\n useEffect(() => {\n if (mediaType === 'lottie' && mediaUrl) {\n setLottieData(null);\n fetch(mediaUrl)\n .then(res => res.json())\n .then(json => setLottieData(json))\n .catch(err => console.error('Error fetching Lottie in MediaOnlyModal:', err));\n } else {\n setLottieData(null);\n }\n }, [mediaType, mediaUrl]);\n\n // Sync muted state to video element\n useEffect(() => {\n if (videoRef.current) {\n videoRef.current.muted = isMuted;\n }\n }, [isMuted]);\n\n // Attempt unmuted autoplay; fall back to muted if browser blocks it\n useEffect(() => {\n const video = videoRef.current;\n if (!video || mediaType !== 'video') return;\n \n video.muted = false;\n const playPromise = video.play();\n if (playPromise !== undefined) {\n playPromise\n .then(() => {\n setIsMuted(false);\n })\n .catch(() => {\n video.muted = true;\n setIsMuted(true);\n video.play().catch(() => {});\n });\n }\n }, [mediaUrl, mediaType]);\n\n if (!modalItem || !chooseMediaType || !mediaUrl) return null;\n\n const appearance = styling.appearance || {};\n const crossButton = styling.crossButton;\n\n // Backdrop\n const backdropColor = appearance.backdrop?.color || 'rgba(0, 0, 0, 0.4)';\n const backdropOpacity = (appearance.backdrop?.opacity !== undefined && appearance.backdrop?.opacity !== null)\n ? (appearance.backdrop.opacity > 1 ? appearance.backdrop.opacity / 100 : appearance.backdrop.opacity)\n : 0;\n const enableBackdrop = appearance.enableBackdrop !== false;\n\n // Modal dimensions (responsive and scaled 40% on desktop)\n const baseWidth = (appearance.dimension?.width !== undefined && appearance.dimension?.width !== null && appearance.dimension.width > 0)\n ? appearance.dimension.width\n : 300;\n const isDesktop = windowWidth >= 768;\n const scaledWidth = isDesktop ? baseWidth * 1.4 : baseWidth;\n const modalWidth = Math.min(scaledWidth, windowWidth * 0.9);\n\n const cornerRadius = appearance.cornerRadius || {};\n const backgroundColor = appearance.backgroundColor || (mediaType === 'lottie' ? 'transparent' : '#FFFFFF');\n\n return (\n <>\n {/* Hidden-scrollbar styles injected once */}\n <style>{`\n .appstorys-media-modal-scroll::-webkit-scrollbar { display: none; }\n .appstorys-media-modal-scroll { scrollbar-width: none; }\n `}</style>\n \n {/* Interaction Lock / Backdrop */}\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: enableBackdrop ? backdropColor : 'transparent',\n opacity: enableBackdrop ? backdropOpacity : 1,\n zIndex: 999998,\n transition: 'opacity 0.3s ease',\n }}\n />\n\n {/* Outer Modal Wrapper — overflow: visible so CrossButton can extend outside */}\n <div\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: modalWidth,\n maxWidth: '95vw',\n zIndex: 999999,\n overflow: 'visible',\n }}\n >\n {/* Cross Button - anchored to outer wrapper, never clipped */}\n {(crossButton?.enabled ?? true) && (\n <CrossButton\n config={crossButton || { enabled: true }}\n onPress={(e) => {\n if (e && typeof e.stopPropagation === 'function') {\n e.stopPropagation();\n }\n onDismiss();\n }}\n style={{\n position: 'absolute',\n zIndex: 10000000,\n top: (crossButton?.margin?.top !== undefined && crossButton.margin?.top >= 0) ? crossButton.margin.top : 8,\n right: (crossButton?.margin?.right !== undefined && crossButton.margin?.right >= 0) ? crossButton.margin.right : 8,\n }}\n />\n )}\n\n {/* Inner Modal Content — owns border-radius, background, shadow, and scrolling */}\n <div\n className=\"appstorys-media-modal-scroll\"\n style={{\n width: '100%',\n backgroundColor: backgroundColor,\n borderTopLeftRadius: (cornerRadius.topLeft !== undefined && cornerRadius.topLeft >= 0) ? cornerRadius.topLeft : 0,\n borderTopRightRadius: (cornerRadius.topRight !== undefined && cornerRadius.topRight >= 0) ? cornerRadius.topRight : 0,\n borderBottomLeftRadius: (cornerRadius.bottomLeft !== undefined && cornerRadius.bottomLeft >= 0) ? cornerRadius.bottomLeft : 0,\n borderBottomRightRadius: (cornerRadius.bottomRight !== undefined && cornerRadius.bottomRight >= 0) ? cornerRadius.bottomRight : 0,\n overflow: 'hidden',\n boxShadow: backgroundColor === 'transparent' ? 'none' : '0 8px 32px rgba(0,0,0,0.25)',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n maxHeight: '90vh',\n overflowY: 'auto',\n }}\n >\n {/* Media (Image / Video / Lottie) with Clickable Redirect */}\n <div\n onClick={() => handleRedirection(redirection, campaign?.id, campaign)}\n style={{ width: '100%', cursor: redirection ? 'pointer' : 'default', minHeight: 0 }}\n >\n {mediaUrl && (mediaType === 'image' || !mediaType) && (\n <img\n src={mediaUrl}\n alt=\"\"\n style={{\n width: '100%',\n display: 'block',\n // No explicit height — browser preserves intrinsic aspect ratio\n }}\n />\n )}\n {mediaUrl && mediaType === 'video' && (\n <div style={{ position: 'relative', width: '100%' }}>\n <video\n ref={videoRef}\n src={mediaUrl}\n autoPlay\n loop\n muted={isMuted}\n playsInline\n controls={false}\n style={{\n width: '100%',\n display: 'block',\n // No explicit height — browser preserves intrinsic aspect ratio\n }}\n />\n {/* Sound Toggle Button — inside position:relative wrapper so absolute offset is correct */}\n <SoundButton\n config={{\n size: 32,\n color: { cross: '#ffffff', fill: 'rgba(0,0,0,0.45)', stroke: 'transparent' },\n margin: { top: 0, bottom: 0, left: 0, right: 0 },\n image: '',\n }}\n onPress={(e) => {\n e.stopPropagation();\n setIsMuted((prev) => !prev);\n }}\n type={isMuted ? 'mute' : 'unmute'}\n enabled={true}\n style={{\n position: 'absolute',\n zIndex: 10000000,\n bottom: 12,\n left: 12,\n borderRadius: '50%',\n }}\n />\n </div>\n )}\n {mediaUrl && mediaType === 'lottie' && lottieData && (() => {\n // Derive proportional height from Lottie composition dimensions\n const lottieW = lottieData.w as number | undefined;\n const lottieH = lottieData.h as number | undefined;\n const lottieAspect = (lottieW && lottieH && lottieW > 0) ? lottieH / lottieW : undefined;\n const lottiePixelWidth = modalWidth;\n const lottiePixelHeight = lottieAspect ? Math.round(lottiePixelWidth * lottieAspect) : undefined;\n return (\n <Lottie\n animationData={lottieData}\n loop={true}\n autoplay={true}\n style={{\n width: lottiePixelWidth,\n height: lottiePixelHeight,\n display: 'block',\n }}\n />\n );\n })()}\n </div>\n </div>\n </div>\n </>\n );\n};\n","import React from 'react';\n\nexport interface TrackableProps {\n /**\n * AppStorys target identifier. Exposed to the DOM as `data-as-id` so the\n * resolver can find it, measure it, and attach tooltips/campaigns to it —\n * regardless of whether the wrapped component forwards custom props to\n * its own root DOM node.\n */\n id: string;\n children: React.ReactNode;\n}\n\n/**\n * Wraps any child (native element or custom component) in a zero-layout-impact\n * marker element carrying `data-as-id`. Use this when you can't or don't want\n * to add `id`/`data-as-id` directly to a component's rendered DOM node, e.g.\n * a third-party component or one that doesn't spread extra props onto its root:\n *\n * <Trackable id=\"checkout-button\">\n * <SomeThirdPartyButton>Checkout</SomeThirdPartyButton>\n * </Trackable>\n */\nexport const Trackable: React.FC<TrackableProps> = ({ id, children }) => {\n return (\n <div data-as-id={id} style={{ display: 'contents' }}>\n {children}\n </div>\n );\n};\n\nexport default Trackable;\n"],"mappings":"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","names":["WebStorage","init_storage","__esmMin","key","value","getUserId","useAppStorysStore","getAccessToken","WebStorage","getVariantId","campaignId","id","import_zustand","store_default","init_store","__esmMin","init_storage","set","campaigns","version","userId","appId","accountId","currentScreen","attributes","trackedEvents","trackedEventMetadata","isVisible","isAnonymousUser","variantMappings","personalizationData","enabled","baseUrl","trackingUrl","getDeviceInfo","error","init_getDeviceInfo","__esmMin","verifyAccount","accountId","appId","userId","requestBody","WebStorage","DEVICE_INFO_SENT_KEY","deviceInfo","getDeviceInfo","baseUrl","store_default","response","data","access_token","refresh_token","error","init_verifyAccount","__esmMin","init_storage","init_getDeviceInfo","init_store","identifyWidgetPositions","screenName","positionList","accessToken","getAccessToken","endpoint","resp","err","init_identifyWidgetPositions","__esmMin","init_store","normalizeWidgetId","id","extractPositionsFromCampaigns","all","store_default","positions","c","d","v","p","mapServerPositionsToDOM","screenName","mapped","pos","key","selectors","el","sel","rect","frame","CaptureService","ensureList","layoutData","buildFormData","userId","children","blob","form","safeScreenName","filename","file","e","init_CaptureService","__esmMin","init_store","init_verifyAccount","init_identifyWidgetPositions","enabled","s","list","idx","l","enrichedFrame","info","elements","screenWidth","screenHeight","foundIds","positionList","resolve","win","reject","script","loadErr","canvas","b","err","stream","video","ctx","t","accessToken","getAccessToken","getUserId","state","verifyAccount","endpoint","body","resp","newToken","text","positionsToSend","normalized","identifyWidgetPositions","name","screenCapture_exports","__export","mountScreenCaptureButton","injectStyles","style","createButton","btn","state","store_default","debugForce","originalText","screenName","CaptureService","err","init_screenCapture","__esmMin","init_store","init_CaptureService","e","s","token","len","masked","parts","payload","exp","now","index_exports","__export","instance","Banner","BottomSheet","Csat_default","Floater_default","Modal","Pip","SdkState","Story","Survey_default","Tooltip_default","Trackable","Widget","getCampaignVariantId","getVariantId","hasVariants","personalizeText","resolveCampaignVariant","selectVariantByWeight","__toCommonJS","SdkState","import_react","LottieModule","init_store","import_react","init_store","init_store","STORAGE_KEY_VARIANTS","inMemoryVariantCache","simpleHash","str","hash","i","char","loadStoredMappings","raw","persistVariantMapping","campaignId","variantId","state","store_default","current","stored","getVariantId","fromStore","hasVariants","campaign","v","selectVariantByWeight","variants","keys","activeKeys","key","eligibleKeys","totalWeight","sum","userId","seed","roll","w","resolveCampaignVariant","c","variantDetails","mergedDetails","getCampaignVariantId","BACK_PRESS_SENTINEL","normalizeScreenName","screen","isScreenMatch","campaignScreen","currentScreen","normalizedCampaignScreen","normalizedCurrentScreen","compareValues","actual","operator","expected","numActual","numExpected","useNumeric","matchesEventConditions","event_config","metadataList","realConditions","c","meta","condition","isTriggerEventSatisfied","campaign","trackedEvents","trackedEventMetadata","t","trigger_event","id","isBackPressCampaignReady","campaigns","store_default","te","event","useCampaigns","campaignType","options","state","allCampaigns","variantMappings","matchCampaign","list","resolveCampaignVariant","init_store","init_getDeviceInfo","init_storage","init_store","init_verifyAccount","OFFLINE_QUEUE_KEY","getQueue","existing","WebStorage","saveQueue","queue","getBackoffDelay","retryCount","shouldRetryRequest","request","lastAttempt","backoffDelay","validateCredentials","state","store_default","verifyAccount","handleAuthError","onSuccess","newToken","handleCriticalError","addToQueue","flushQueue","newQueue","req","res","r","sendOrQueue","trackEvent","event","campaignId","metadata","accessToken","getAccessToken","state","store_default","excludedEvents","trackedEvents","updatedEvents","e","currentMeta","existing","finalMetadata","deviceInfo","getDeviceInfo","variantId","getVariantId","body","getUserId","trackingUrl","sendOrQueue","error","init_store","revealCampaignFromLink","link","s","store_default","all","existing","normalizedLink","referenced","cid","details","detailsCampaign","revealed","idx","existingItem","next","import_jsx_runtime","CrossButton","config","onPress","style","ignoreSizeAndMargin","backendSize","margin","color","image","selectedStyle","safeSize","size","marginTop","marginBottom","marginLeft","marginRight","containerStyle","renderDefaultIcon","stroke","e","CrossButton_default","import_jsx_runtime","Lottie","LottieModule","Banner","data","useCampaigns","sdkVisible","store_default","state","isDismissed","setIsDismissed","lottieData","setLottieData","aspectRatio","setAspectRatio","containerRef","containerWidth","setContainerWidth","trackedViewRef","trackEvent","res","json","err","updateWidth","details","styling","calculatedHeight","_h","_ow","_oh","calculatedWidth","bannerWidthPx","bannerHeightPx","marginRight","marginBottom","outerStyle","innerStyle","mediaStyle","handleClose","e","revealCampaignFromLink","LottieComp","CrossButton_default","import_react","init_store","isRemoteFontUrl","value","v","fontNameFromUrl","url","filename","ensureStyleTag","fontName","id","style","cache","doLoad","entry","FontFaceCtor","face","cb","err","FontManager","existing","resolve","first","name","resolveFontFamily","fontFamily","collectFontUrls","input","urls","visited","walk","item","key","preloadFontsFromCampaigns","campaigns","c","u","import_jsx_runtime","normalizeScreen","value","parseNumber","fallback","parsed","isExpandableEnabled","normalized","PipIcon","iconType","color","stroke","IconButton","config","imageOverride","onClick","iconSize","buttonSize","margin","imageUrl","iconColor","fillColor","strokeColor","e","Pip","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","sdkVisible","isClosed","setIsClosed","isExpanded","setIsExpanded","isMuted","setIsMuted","isDragging","setIsDragging","dragPosition","setDragPosition","dragOffsetRef","videoRef","dragStartRef","didDragRef","data","screen","findFromList","source","campaign","item","isPip","matchesScreen","hasTrigger","displayTriggerReady","found","resolveCampaignVariant","stableData","details","defaultSoundSetting","trackEvent","onMouseMove","event","dx","dy","nextX","nextY","onMouseUp","styling","appearance","configuredWidth","configuredHeight","miniWidth","miniHeight","ctaContainer","ctaText","hasCta","ctaHeight","expandedExtraHeight","bottomPadding","topPadding","videoSource","position","isMovable","soundEnabled","closeEnabled","expandablePipRaw","expandEnabled","closeConfig","expandConfig","soundConfig","toggleExpand","prev","next","wrapperStyle","onWrapperMouseDown","rect","handleOpenLink","link","s","all","existing","referenced","c","revealed","idx","existingItem","resolveFontFamily","import_react","import_lottie_react","init_store","import_jsx_runtime","toNumber","value","fallback","parsed","normalizeScreen","MEDIA_BUCKET_HOST","resolveLottieCandidateUrls","url","isDevServer","proxyUrl","isLikelyLottieJson","candidate","FloaterLottieErrorBoundary","React","props","Floater","lottieData","setLottieData","lottieUrls","setLottieUrls","lottieFailed","setLottieFailed","lottieLoading","setLottieLoading","lottieContainerRef","lottieAnimationRef","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","sdkVisible","viewedKeyRef","data","found","campaign","item","hasTrigger","resolveCampaignVariant","campaignId","mappedVariantId","hasVariants","viewKey","trackEvent","lottieSource","candidateUrls","lottie","cancelled","activeAnimation","cleanupCurrent","tryLoadByPath","paths","index","animation","details","styling","position","positionStyle","floaterStyle","handleClick","link","all","existing","referenced","c","cid","detailsCampaign","revealed","idx","existingItem","next","err","canRenderLottie","canRenderImage","canRenderLoadingPlaceholder","Floater_default","init_store","normalizeScreenName","screen","isScreenMatch","campaign","screenName","campaignScreen","currentScreen","trackScreen","state","store_default","accessToken","getAccessToken","accountId","baseUrl","response","getUserId","data","variantMappings","variant","allCampaigns","eligibleCampaignIds","foundCampaigns","foundCampaignIds","c","missingCampaignIds","id","missingCampaigns","fallbackResponse","eligibleCampaigns","displayTriggeredCampaigns","hasTrigger","mergedCampaigns","seenCampaignIds","error","init_verifyAccount","init_store","init_getDeviceInfo","setUserProperties","attributes","accessToken","getAccessToken","userId","getUserId","state","store_default","finalMetadata","deviceInfo","getDeviceInfo","bodyData","baseUrl","sendOrQueue","error","init_store","personalizeText","text","personalizationData","store_default","replacePlaceholdersWithFallback","regex","_","variableName","fallbackValue","trimmedVariable","trimmedFallback","init_storage","init_store","STORAGE_KEY_CAMPAIGNS","STORAGE_KEY_ETAG","STORAGE_KEY_VERSION","fetchAllCampaigns","accountId","screenName","isLocalDev","url","cachedData","WebStorage","cachedEtag","cachedVersion","headers","response","newEtag","responseData","version","campaigns","effectiveScreenName","accessToken","getAccessToken","userId","getUserId","trackResp","trackData","possibleScreen","s","store_default","err","userIdFromResp","fallbackResponse","fallbackData","error","normalize","current","campaign","init_store","init_store","reconcileAnonymousUser","anonymousUserId","identifiedUserId","accessToken","getAccessToken","state","store_default","requestBody","baseUrl","response","errorText","error","init_store","ExitIntentManager","isBackPressCampaignReady","state","store_default","trackedEvents","BACK_PRESS_SENTINEL","exitIntentManager","init_store","VisibilityManager","isVisible","state","store_default","visibilityManager","init_storage","ANONYMOUS_USER_KEY","generateAnonymousUserId","currentTimeMs","browserName","getOrCreateAnonymousUserId","storedUserId","WebStorage","newUserId","error","clearAnonymousUserId","getStoredAnonymousUserId","injectStyles","style","makePill","text","pill","ensureRelative","el","node","computed","matches","sel","idx","target","existing","err","import_react","init_store","import_react","LottieModule","import_jsx_runtime","Lottie","StoryThumbnail","src","alt","style","size","lottieData","setLottieData","lottieFailed","setLottieFailed","res","json","err","baseStyle","LottieComp","import_jsx_runtime","StoryGroupItem","story","isViewed","onClick","styling","size","ringWidth","ringColor","nameColor","cornerRadius","borderRadiusStr","imgBorderRadiusStr","StoryThumbnail","resolveFontFamily","import_jsx_runtime","StoryList","stories","viewedStories","onStoryClick","a","b","story","index","StoryGroupItem","import_react","init_store","parseColor","val","parsed","parseBackground","bg","color","direction","from","to","stops","cssDir","stopStr","s","rawOffset","offsetStr","str","num","getAnimationStyles","anim","type","duration","toCSSValue","defaultUnit","import_react","import_jsx_runtime","PollSticker","data","onInteraction","isEditing","selectedOptionId","setSelectedOptionId","React","isHorizontal","defaults","styling","containerStyle","toCSSValue","questionStyle","optionsContainerStyle","optionStyle","options","getOptionPercentage","optionId","option","o","total","sum","hexToRgba","hex","opacity","cleaned","char","r","g","b","getFillColor","isActive","colorObj","color","handleOptionClick","index","percentage","isVoted","buttonBgColor","e","import_react","import_jsx_runtime","QuizSticker","data","onInteraction","isEditing","selectedOptionId","setSelectedOptionId","defaults","styling","cardPadding","toCSSValue","questionFontSize","isOptionFontSizeString","optionFontSize","optionRadius","borderColor","labelSizeCSS","labelBorderWidthCSS","labelFontSizeCSS","optionGapCSS","optionPaddingCSS","bodyGapCSS","containerStyle","questionStyle","optionStyle","labelStyle","bodyStyle","handleOptionClick","optionId","alphabet","options","option","index","label","isSelected","isCorrect","currentOptionStyle","currentLabelStyle","import_react","import_jsx_runtime","CountdownSticker","data","timeLeft","setTimeLeft","calculateTime","difference","days","hours","minutes","seconds","timer","styling","display","rawDigitSize","isDigitSizeString","digitSizeCSS","labelFontSizeCSS","toCSSValue","boxHeightCSS","boxMinWidthCSS","boxRadiusCSS","gridGapCSS","separatorSizeCSS","containerStyle","titleStyle","timerGridStyle","segmentStyle","digitGroupStyle","boxStyle","labelStyle","separatorStyle","renderDigitGroup","value","label","digit","i","items","shownCount","import_react","import_jsx_runtime","PromoCodeSticker","data","onInteraction","copied","setCopied","handleCopy","e","styling","ticketPillStyle","import_react","import_jsx_runtime","ReactionSticker","data","onInteraction","isEditing","defaults","emojis","hasVoted","setHasVoted","counts","setCounts","initialCounts","savedEmoji","emoji","baseCount","handleReactionClick","index","prev","formatCount","num","containerStyle","bubbleStyle","emojiStyle","countStyle","idx","countVal","import_react","import_jsx_runtime","RatingSticker","data","onInteraction","isEditing","maxRating","currentRating","val","setVal","saved","sliderTrackRef","isDragging","setIsDragging","hasSelected","setHasSelected","particles","setParticles","defaults","styling","containerStyle","toCSSValue","titleStyle","trackStyle","percentage","fillStyle","emojiSize","isEmojiSizeString","emojiSizeCSS","thumbStyle","handleDrag","clientX","rect","offsetX","ratio","computedVal","onMouseDown","e","onTouchStart","triggerConfetti","newParticles","_","i","onMouseMove","onMouseUp","onTouchMove","particle","distance","radian","tx","ty","import_react","import_jsx_runtime","QuestionSticker","data","onInteraction","isEditing","value","setValue","hasSubmitted","setHasSubmitted","defaults","styling","containerStyle","toCSSValue","questionStyle","inputContainerStyle","inputStyle","sendButtonStyle","handleChange","e","handleSend","import_react","import_jsx_runtime","ImageQuizSticker","data","onInteraction","isEditing","selectedOptionId","setSelectedOptionId","defaults","styling","paddingCSS","toCSSValue","borderRadiusCSS","containerStyle","questionStyle","gridStyle","optionStyle","handleOptionClick","optionId","placeholderImg","options","option","isSelected","isCorrect","currentOptionStyle","e","import_react","import_react","import_jsx_runtime","ShopableModal","product","styling","onClose","onAddToCart","selectedSize","setSelectedSize","selectedColorIndex","setSelectedColorIndex","quantity","setQuantity","isSuccess","setIsSuccess","isVisible","setIsVisible","attributes","colors","sizes","imageUrls","description","handleAddToCart","item","url","error","handleDismiss","buttonBg","buttonFg","titleFg","priceFg","mrpFg","titleWeight","priceWeight","mrpWeight","overlayStyle","backdropStyle","sheetStyle","dragHandleStyle","buttonBaseStyle","headerStyle","closeButtonStyle","scrollContentStyle","gallerySectionStyle","i","toCSSValue","sectionStyle","sectionTitleStyle","color","size","bottomBarStyle","stepperStyle","stepperBtnStyle","q","availability","isOutOfStock","import_jsx_runtime","ShopableSticker","data","onInteraction","isEditing","products","styling","isModalOpen","setIsModalOpen","selectedProduct","setSelectedProduct","handleProductClick","e","product","url","error","handleAddToCart","item","containerStyle","cardStyle","toCSSValue","imageContainerStyle","contentContainerStyle","ShopableModal","import_jsx_runtime","InteractiveItem","data","onInteraction","isEditing","defaults","x","y","width","rotation","wrapperStyle","animationStyle","renderSticker","PollSticker","QuizSticker","RatingSticker","QuestionSticker","ImageQuizSticker","CountdownSticker","PromoCodeSticker","ReactionSticker","ShopableSticker","textStyle","vAlign","hAlign","toCSSValue","resolveFontFamily","ctaStyle","e","borderRadius","text","isSwipeUp","buttonStyle","containerStyle","arrowContainerStyle","arrowHeight","import_jsx_runtime","getEditorSource","item","content","editorSource","normalizeOptions","options","isCorrect","option","index","optionId","optionLabel","optionText","key","value","optionValue","normalizeReactionEmojis","data","emoji","normalizeElementType","type","normalized","getPromoCode","custom","codeVal","getCountdownTarget","combined","InteractiveOverlay","onInteraction","isEditing","elapsedTime","canva","canvaWidth","canvaHeight","scale_factor","elements","images","texts","ctas","interactions","shopableContent","shopableIds","s","shopableStyling","slideIsStudio","getScaledHeightStyle","val","isStudioLocal","num","getScaledFontStyle","displayElements","style","source","isStudio","position","size","rawX","rawY","rawW","rawH","x_percent","y_percent","width_percent","height_percent","baseData","parseBackground","getAnimationStyles","normalizedOpts","parseColor","colors","rawOptionFontSize","emojisArray","displayInteractions","typeStr","posX","posY","sizeW","sizeH","displayShopable","matchedStyling","inlineStyling","styling","rawCardBorderRadius","rawCardRadiusPercent","rawHeight","radiusFromPercent","resolvedCardBorderRadius","resolvedCardBorderRadiusPx","isProductType","itemsSource","p","sourceData","attr","currentPrice","oldPrice","colorVal","sizeVal","sizes","consolidatedAttributes","displayImages","img","displayText","txt","styleObj","st","font","alignment","color","fontDecoration","textDecoration","txtRotation","displayCtas","cta","displayItems","start","end","b","InteractiveItem","import_react","import_jsx_runtime","PlayPauseButton","isPaused","onPress","style","size","isHovered","setIsHovered","PlayPauseButton_default","import_jsx_runtime","mapAlignment","alignment","Cta","cta","buttonText","onPress","resolveFontFamily","personalizeText","Cta_default","import_jsx_runtime","SoundButton","config","onPress","ignoreSizeAndMargin","enabled","style","type","backendSize","margin","color","image","selectedStyle","size","marginTop","marginBottom","marginLeft","marginRight","containerStyle","renderDefaultIcon","stroke","import_jsx_runtime","ShareButton","config","onPress","ignoreSizeAndMargin","style","backendSize","margin","color","image","selectedStyle","size","containerStyle","renderDefaultIcon","stroke","ShareButton_default","import_jsx_runtime","SIDE_CARD_SCALE","ANIM_DURATION","EASING_OUTGOING","EASING_INCOMING","getRoleTransform","role","cardWidth","sideCardOffset","farSideCardOffset","SIDE_CARD_SCALE","StoryVideo","src","isActive","isAnimating","isMuted","onLoadedData","activeVideoRef","objectFit","localRef","React","VIEWED_SLIDES_KEY","CLICKED_INTERACTIONS_KEY","hasViewedSlide","slideId","data","parsed","markSlideAsViewed","hasClickedInteraction","interactionId","markInteractionAsClicked","StoryOverlay","stories","activeStoryIndex","dataId","viewedStories","setViewedStories","onNextStory","onPrevStory","onClose","activeSlideIndex","setActiveSlideIndex","progress","setProgress","setIsMuted","videoLoaded","setVideoLoaded","isPaused","setIsPaused","showShortcuts","setShowShortcuts","showToast","setShowToast","viewportSize","setViewportSize","isDesktop","setIsDesktop","setIsAnimating","outgoingIndex","setOutgoingIndex","incomingIndex","setIncomingIndex","direction","setDirection","isGroupAnimating","setIsGroupAnimating","groupAnimPhase","setGroupAnimPhase","groupDir","setGroupDir","handleResize","progressTimerRef","clickStartTimeRef","lastTrackedSlideId","currentStory","currentSlide","currentSlideStyling","slideEditorSource","slideIsStudio","slideBgImage","slideCtaText","slideCtaLink","slideVideo","currentCanva","canvaRatio","headerFooterReserved","availHeight","availWidth","computedCardHeight","CARD_HEIGHT","CARD_WIDTH","handleShare","shareData","trackEvent","handleKeyDown","e","handleNextSlide","handlePrevSlide","prev","slideTime","isVideo","triggerSlideTransition","dir","targetIndex","updated","triggerGroupTransition","getGroupAnimStyle","handleMouseDownNav","handleMouseUpNav","handleVideoLoad","handleClickCTA","slide","styling","editorSource","link","clickId","handleOverlayInteraction","interactionData","type","questionId","pollId","quizId","optionId","value","stickerId","redirectUrl","interaction_type","interaction_id","selected","state","store_default","userId","trackingUrl","accessToken","getAccessToken","bodyMetadata","err","toggleMute","crossConfig","soundConfig","ctaStyling","getSlideRole","idx","backdropStyle","centerCardBaseStyle","sideCardStyle","slidesToRender","acc","_","renderSet","StoryThumbnail","displayIndex","fillWidth","ShareButton_default","SoundButton","PlayPauseButton_default","key","label","CrossButton_default","a","b","index","roleStyle","slideStyling","isStudio","bgImage","video","bgColor","parseBackground","slideCtaTextLocal","slideCtaLinkLocal","mediaSizing","containerStyles","InteractiveOverlay","Cta_default","isCurrent","import_jsx_runtime","Story","data","useCampaigns","sdkVisible","store_default","state","activeStoryIndex","setActiveStoryIndex","viewedStories","setViewedStories","saved","e","trackEvent","handleStoryClick","index","handleNextStory","handlePrevStory","StoryList","StoryOverlay","import_react","import_react_dom","init_store","import_react","useViewportTracking","onVisible","threshold","onVisibleRef","hasTrackedRef","elementRef","observerRef","refCallback","el","timeoutId","entries","warnedDuplicates","isDev","warnIfDuplicate","id","selector","matchCount","key","resolveTarget","attributeSelectors","matches","byId","classSelector","import_jsx_runtime","Widget","position","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","normalizeScreen","value","data","screen","found","campaign","item","hasTrigger","displayTriggerReady","matchesScreen","resolveCampaignVariant","activeIndex","setActiveIndex","containerRef","autoAdvanceRef","details","images","styling","widgetType","isHalf","trackedImpressionsRef","isInViewportRef","trackFirstImpression","firstImage","trackImpression","viewportRef","useViewportTracking","widgetImageId","trackEvent","prev","next","handleClick","imageId","link","revealCampaignFromLink","err","handleScroll","scrollLeft","offsetWidth","itemWidth","index","img","el","checkVisibility","idx","itemLeft","itemRight","viewLeft","viewRight","containerStyle","getItemStyle","content","_","i","target","key","resolveTarget","import_react","init_store","import_jsx_runtime","normalizeScreen","value","Tooltip","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","sdkVisible","currentStep","setCurrentStep","isDismissed","setIsDismissed","targetRect","setTargetRect","tooltipSize","setTooltipSize","tooltipRef","observerRef","resizeObserverRef","data","screen","findFromList","source","campaign","item","isTooltip","matchesScreen","hasTrigger","displayTriggerReady","tooltips","a","b","currentTooltip","viewedTooltipsRef","trackViewed","tooltipId","key","trackEvent","viewportRef","useViewportTracking","findTarget","scroll","targetId","el","resolveTarget","observeResize","found","handleResizeOrScroll","targetEl","width","height","styling","appearance","colors","cta","ctaContainer","ctaCorner","ctaText","isImageTooltip","fixedImageWidth","fixedImageHeight","rawWidth","rawHeight","maxViewportWidth","arrowPos","arrowSize","absoluteTop","absoluteLeft","tooltipLeft","tooltipTop","offsetGap","safeMargin","docHeight","docWidth","handleNext","targetLink","prev","handleBackdropClick","e","resolveFontFamily","Tooltip_default","import_react","init_store","import_jsx_runtime","BottomSheet","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","data","screen","found","campaign","hasTrigger","cs","resolveCampaignVariant","sdkVisible","isDismissed","setIsDismissed","trackedViewRef","trackEvent","removeTrackedEvent","eventKey","next","e","details","sortedElements","a","b","opacity","renderElement","element","imgStyle","link","revealCampaignFromLink","err","ctaData","container","cornerRadius","margin","textStyle","resolveFontFamily","l","titleStyle","descStyle","CrossButton_default","import_react","init_store","LottieModule","import_jsx_runtime","Lottie","FIVE_STAR_MAX","LOW_RATING_CUTOFF","asSpacingValue","value","spacingToStyle","spacing","applyFontFamily","fontFamily","resolveFontFamily","textStyleToCss","textStyle","getCornerRadius","cornerRadius","getAlignment","alignment","getRatingType","details","ratingType","getEmojiChoices","configured","rawItems","parsed","item","val","getNumberChoices","_","index","asNonNegativeNumber","getNumberRatingGap","rating","directCandidates","candidate","maybe","numberConfig","obj","nestedCandidates","StarIcon","fill","stroke","CsatFormContent","details","appearance","rating","selectedOptions","comments","isHighRating","feedbackOptions","onRate","onToggleOption","onCommentChange","onInlineSubmit","canSubmit","styling","feedbackPage","ratingStyle","initialFeedback","submitCta","ratingType","getRatingType","numberChoices","getNumberChoices","emojiChoices","getEmojiChoices","numberGap","getNumberRatingGap","selectedStarConfig","spacingToStyle","textStyleToCss","FIVE_STAR_MAX","_","index","value","isSelected","starContainerStyle","starStyle","selected","emoji","emojiConfig","containerStyle","getCornerRadius","LOW_RATING_CUTOFF","option","styleSource","event","asNonNegativeNumber","applyFontFamily","CsatThankYouContent","onDone","thankyouPage","doneAlign","getAlignment","lottieData","setLottieData","isLottie","res","json","err","Lottie","Csat","hookData","useCampaigns","sdkVisible","store_default","state","campaigns","allCampaigns","currentScreen","data","screen","found","campaign","hasTrigger","cs","resolveCampaignVariant","isDismissed","setIsDismissed","canDisplay","setCanDisplay","setRating","setSelectedOptions","setComments","isSubmitted","setIsSubmitted","trackedViewRef","delay","timeoutId","trackEvent","source","a","b","key","configuredWidth","compactCardWidth","handleToggleOption","prev","item","handleSubmit","override","ratingValue","campaignId","selectedOption","additionalComments","handleRate","e","handleDone","link","revealCampaignFromLink","asSpacingValue","CrossButton_default","Csat_default","import_react","init_store","LottieModule","import_jsx_runtime","Lottie","asSpacingValue","value","applyFontFamily","fontFamily","resolveFontFamily","textStyleToCss","textStyle","marginToStyle","margin","getCornerRadius","cornerRadius","getAlignment","alignment","clamp01","hexToRgba","hex","alpha","raw","r","g","b","normalizeBackdropOpacity","opacity","getOrderedSlides","details","a","resolveRedirectDestination","redirectTo","slides","trimmed","compact","questionMatch","targetIndex","byId","s","orderNum","byOrder","getOrderedOptions","slide","options","keys","parseIndex","key","match","parsed","ai","bi","getBulletLabel","optionListStyle","index","start","asNonNegativeNumber","getBorderWidthFromTextStyle","SurveyFormContent","appearance","selectedOptions","comment","onSelectOption","onCommentChange","onSubmit","canSubmit","styling","optionsStyle","cta","optionRowGap","bulletGap","optionHeight","ctaAlign","OTHERS_SENTINEL","othersLabel","allOptions","o","isOthersSelected","label","isActive","styleSource","borderWidth","bulletLabel","listStyle","isBulleted","isTextIndicator","event","SurveyThankYouContent","onDone","thankyouPage","isLottie","lottieData","setLottieData","res","json","err","Survey","hookData","useCampaigns","sdkVisible","store_default","state","campaigns","allCampaigns","currentScreen","data","screen","found","campaign","hasTrigger","cs","resolveCampaignVariant","isDismissed","setIsDismissed","canDisplay","setCanDisplay","currentIndex","setCurrentIndex","setSelectedOptions","setComment","responses","setResponses","isSubmitted","setIsSubmitted","trackedViewRef","delay","timeoutId","surveyId","orderedSlides","firstSlideId","trackEvent","existing","backdropColor","backdropOpacity","isMultiSelectEnabled","handleSelectOption","option","prev","submitSurvey","finalResponses","finalSlideId","responsesArray","campaignId","selectedOptionsKeys","selectedValues","val","optionEntry","v","otherText","captureCampaignId","handleSubmitCurrent","nextResponses","optionKeys","selectedOption","perSlideCampaignId","e","logicAction","rule","ruleOptions","keyMatch","opt","valueMatch","othersMatch","resolved","handleDone","config","redirect","revealCampaignFromLink","handleDismiss","slideId","CrossButton_default","Survey_default","import_react","init_store","import_react","LottieModule","import_jsx_runtime","Lottie","mapTextAlign","align","a","handleCtaRedirection","redirection","campaignId","campaign","variantId","trackEvent","url","value","revealCampaignFromLink","ModalWithCta","onDismiss","windowWidth","setWindowWidth","lottieData","setLottieData","isMuted","setIsMuted","videoRef","handleResize","originalOverflow","details","modalItem","content","styling","chooseMediaType","mediaType","mediaUrl","res","json","err","video","playPromise","appearance","crossButton","backdropColor","backdropOpacity","enableBackdrop","baseWidth","isDesktop","scaledWidth","modalWidth","cornerRadius","backgroundColor","titleText","subtitleText","primaryCtaText","secondaryCtaText","primaryCtaRedirection","secondaryCtaRedirection","titleStyle","subTitleStyle","primaryCtaStyle","secondaryCtaStyle","renderCtaButton","text","ctaStyling","isSideBySide","container","cr","margin","textStyle","getJustify","alignment","baseCtaWidth","scaledCtaWidth","baseCtaHeight","buttonHeight","topLeftRadius","topRightRadius","bottomRightRadius","bottomLeftRadius","resolveFontFamily","personalizeText","CrossButton_default","e","SoundButton","prev","lottieW","lottieH","lottieAspect","lottiePixelWidth","lottiePixelHeight","import_react","LottieModule","import_jsx_runtime","Lottie","handleRedirection","redirection","campaignId","campaign","variantId","trackEvent","url","value","revealCampaignFromLink","MediaOnlyModal","onDismiss","windowWidth","setWindowWidth","lottieData","setLottieData","isMuted","setIsMuted","videoRef","handleResize","originalOverflow","details","modalItem","chooseMediaType","styling","mediaType","mediaUrl","res","json","err","video","playPromise","appearance","crossButton","backdropColor","backdropOpacity","enableBackdrop","baseWidth","scaledWidth","modalWidth","cornerRadius","backgroundColor","CrossButton_default","e","SoundButton","prev","lottieW","lottieH","lottieAspect","lottiePixelWidth","lottiePixelHeight","import_jsx_runtime","Modal","hookData","useCampaigns","campaigns","store_default","state","allCampaigns","currentScreen","data","screen","found","campaign","hasTrigger","cs","resolveCampaignVariant","sdkVisible","isDismissed","setIsDismissed","trackedViewRef","variantId","metadata","trackEvent","removeTrackedEvent","eventKey","next","e","handleDismiss","modalType","MediaOnlyModal","ModalWithCta","import_jsx_runtime","Trackable","id","children","AppStorys","options","appId","accountId","userId","state","store_default","finalUserId","isAnonymous","getOrCreateAnonymousUserId","storedAnonymousUserId","getStoredAnonymousUserId","verifyAccount","reconcileAnonymousUser","clearAnonymousUserId","accessToken","getAccessToken","usersBase","resp","data","s","val","err","campaigns","version","fetchAllCampaigns","preloadFontsFromCampaigns","exitIntentManager","visibilityManager","e","anonymousUserId","identifiedUserId","error","screenName","trackScreen","event","campaignId","metadata","trackEvent","attributes","setUserProperties","link","revealCampaignFromLink","isVisible","startTime","resolve","text","personalizeText","instance"]}