@shaimaababiker/embed 0.1.3 → 0.1.5

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/widget.tsx","../src/ApolloProvider.tsx","../src/ChatbotClient.tsx","../src/lib/startNewChat.ts","../src/graphql/queries.ts","../src/ui/Avatar.tsx","../src/ui/Messages.tsx","../src/ui/ChatMotion.tsx","../src/ui/form.tsx","../src/lib/utils.ts","../src/ui/label.tsx","../src/ui/input.tsx","../src/ui/button.tsx"],"sourcesContent":["'use client';\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { ApolloProvider } from '@apollo/client';\nimport { createApolloClient } from './ApolloProvider';\nimport ChatbotClient from './ChatbotClient';\n\nexport type AssistlyChatProps = {\n chatbotId: number;\n /** Origin of the Assistly deployment that hosts the chat API, e.g. https://chatbot-xi-rose-68.vercel.app */\n origin: string;\n /** Optional brand color for accents */\n primaryColor?: string;\n /** Fires when the chat panel has mounted and is ready to receive input */\n onReady?: () => void;\n /** Fires if the chat fails to mount */\n onError?: (err: Error) => void;\n};\n\n/**\n * Embeddable Assistly chat panel. Renders the full chat UI (intake form +\n * active chat) inside whatever container the customer places it in. Talks\n * directly to the Assistly API at `${origin}/api/...` — no iframe, no\n * cross-origin cookie issues.\n */\nexport default function AssistlyChat({\n chatbotId,\n origin,\n primaryColor,\n onReady,\n onError,\n}: AssistlyChatProps) {\n const client = useMemo(() => createApolloClient(origin), [origin]);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n onReady?.();\n try {\n // Reserved for future telemetry.\n } catch (err) {\n onError?.(err as Error);\n }\n }, [onReady, onError]);\n\n if (!mounted) return null;\n\n return (\n <ApolloProvider client={client}>\n <div\n style={{\n width: '100%',\n height: '100%',\n minHeight: 400,\n display: 'flex',\n flexDirection: 'column',\n // CSS custom property so consumers can theme accents without prop-drilling.\n ...(primaryColor ? ({ '--assistly-primary': primaryColor } as React.CSSProperties) : null),\n }}\n >\n <ChatbotClient id={String(chatbotId)} chatbotName=\"Assistant\" origin={origin} />\n </div>\n </ApolloProvider>\n );\n}\n","'use client';\n\nimport { ApolloClient, InMemoryCache, createHttpLink, type DefaultOptions } from '@apollo/client';\n\nconst defaultOptions: DefaultOptions = {\n watchQuery: { fetchPolicy: 'no-cache', errorPolicy: 'all' },\n query: { fetchPolicy: 'no-cache', errorPolicy: 'all' },\n mutate: { fetchPolicy: 'no-cache', errorPolicy: 'all' },\n};\n\nexport function createApolloClient(origin: string): ApolloClient<unknown> {\n const baseUrl = origin.replace(/\\/$/, '');\n return new ApolloClient({\n link: createHttpLink({ uri: `${baseUrl}/api/graphql` }),\n cache: new InMemoryCache(),\n defaultOptions,\n });\n}\n","'use client';\n\nimport { useEffect, useState } from \"react\";\nimport { useQuery } from \"@apollo/client\";\nimport { z } from \"zod\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from '@hookform/resolvers/zod';\n\nimport {\n Message,\n MessagesbyChatSessionIdResponse,\n MessagesbyChatSessionIdResponseVariables,\n} from \"./types\";\nimport startNewChat from \"./lib/startNewChat\";\nimport { GET_MESSEGES_BY_CHAT_SESSION_ID } from \"./graphql/queries\";\nimport Avatar from \"./ui/Avatar\";\nimport Messages from \"./ui/Messages\";\nimport { FormControl, FormField, FormItem, Form, } from \"./ui/form\";\nimport { Input } from \"./ui/input\";\nimport { Button } from \"./ui/button\";\n\ntype ChatbotClientProps = {\n id: string;\n chatbotName: string;\n origin: string;\n};\n\nconst formSchema = z.object({\n message: z.string().min(3, 'Your Message is too short!'),\n});\n\nfunction ChatbotClient({ id, chatbotName, origin }: ChatbotClientProps) {\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [onboardingStep, setOnboardingStep] = useState(1);\n const [chatId, setChatId] = useState(0);\n const [loading, setLoading] = useState(false);\n const [message, setMessage] = useState<Message[]>([\n {\n id: -1,\n content: `Hi there! I'm ${chatbotName}. I'd love to help you out, but first, could you tell me your name?`,\n sender: 'ai',\n created_at: new Date().toISOString(),\n chat_session_id: 0,\n }\n ]);\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n message: ''\n }\n });\n\n const { data } = useQuery<MessagesbyChatSessionIdResponse, MessagesbyChatSessionIdResponseVariables>(\n GET_MESSEGES_BY_CHAT_SESSION_ID,\n {\n variables: { chat_session_id: chatId },\n skip: !chatId\n }\n );\n\n useEffect(() => {\n if (data && onboardingStep === 3) {\n const chatSession = data.chat_sessions as any;\n const dbMessages = chatSession.messages || [];\n setMessage((prev) => {\n const existingIds = new Set(prev.map((m) => m.id));\n const newMessages = dbMessages.filter((m: Message) => !existingIds.has(m.id));\n return [...prev, ...newMessages];\n });\n }\n }, [data, onboardingStep]);\n\n async function onsubmit(values: z.infer<typeof formSchema>) {\n const { message: formMessage } = values;\n form.reset();\n\n if (onboardingStep === 1) {\n if (!formMessage.trim()) return;\n\n const userMsg: Message = {\n id: Date.now(),\n content: formMessage,\n chat_session_id: 0,\n sender: 'user',\n created_at: new Date().toISOString(),\n };\n\n const aiMsg: Message = {\n id: Date.now() + 1,\n content: `It's a pleasure to meet you, ${formMessage}! Just one more thing—what's your email address so we can stay connected?`,\n chat_session_id: 0,\n sender: 'ai',\n created_at: new Date().toISOString(),\n };\n\n setName(formMessage);\n setOnboardingStep(2);\n setMessage((prev) => [...prev, userMsg, aiMsg]);\n return;\n }\n\n if (onboardingStep === 2) {\n if (!formMessage.trim()) return;\n\n const isValidEmail = (email: string) => {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n };\n\n if (!isValidEmail(formMessage.trim())) {\n setMessage((prev) => [\n ...prev,\n {\n id: Date.now() + 1,\n content: \"Please enter a valid email address so we can continue.\",\n chat_session_id: 0,\n sender: 'ai',\n created_at: new Date().toISOString(),\n },\n ]);\n return;\n }\n const userMsg: Message = {\n id: Date.now(),\n content: formMessage,\n chat_session_id: 0,\n sender: 'user',\n created_at: new Date().toISOString(),\n };\n\n setMessage((prev) => [...prev, userMsg]);\n setLoading(true);\n\n try {\n const finalEmail = formMessage;\n setEmail(finalEmail);\n const newChatId = await startNewChat(origin, name, finalEmail, Number(id));\n setChatId(newChatId);\n setOnboardingStep(3);\n\n } catch (error) {\n console.error('Error starting chat:', error);\n setMessage((prev) => [...prev, {\n id: Date.now() + 1,\n content: \"Sorry, I had trouble setting up your session. Could you please try entering your email again?\",\n chat_session_id: 0,\n sender: 'ai',\n created_at: new Date().toISOString(),\n }]);\n } finally {\n setLoading(false);\n }\n return;\n }\n\n if (!chatId) return;\n\n const userMessage: Message = {\n id: Date.now(),\n content: formMessage,\n chat_session_id: chatId,\n sender: 'user',\n created_at: new Date().toISOString(),\n };\n\n const loadingMessage: Message = {\n id: Date.now() + 1,\n content: 'Thinking...',\n chat_session_id: chatId,\n created_at: new Date().toISOString(),\n sender: 'ai',\n };\n setMessage((prevMessages) => [...prevMessages, userMessage, loadingMessage]);\n\n try {\n const baseUrl = origin.replace(/\\/$/, '');\n const response = await fetch(`${baseUrl}/api/send-message`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name: name,\n chat_session_id: chatId,\n chabot_id: Number(id),\n content: formMessage,\n created_at: new Date().toISOString(),\n })\n });\n const result = await response.json();\n setMessage((prevMessages) =>\n prevMessages.map((msg) =>\n msg.id === loadingMessage.id ? { ...msg, content: result.content, id: result.id } : msg\n )\n );\n } catch (error) {\n console.error('Error Sending Message:', error);\n }\n }\n\n return (\n <div className=\"fixed inset-0 flex flex-col bg-gray-50 text-slate-900 md:p-6 md:pb-0\">\n <div className=\"flex flex-col w-full max-w-3xl mx-auto flex-1 overflow-hidden md:rounded-t-2xl border border-gray-200 bg-white relative\">\n <div className=\"border-b border-gray-100 bg-white py-3 px-4 md:py-6 md:px-8 flex items-center justify-between shrink-0\">\n <div className=\"flex items-center space-x-3 md:space-x-4 min-w-0\">\n <div className=\"relative shrink-0\">\n <Avatar\n seed={chatbotName ?? 'default-seed'}\n className=\"w-9 h-9 md:w-10 md:h-10 bg-gray-100 rounded-full border border-gray-200\"\n />\n <div className=\"absolute bottom-0 right-0 w-2.5 h-2.5 bg-emerald-500 border-2 border-white rounded-full\"></div>\n </div>\n <div className=\"min-w-0\">\n <h1 className=\"truncate text-sm md:text-base font-semibold text-slate-900\">\n {chatbotName || 'Assistant'}\n </h1>\n <p className=\"text-xs text-slate-400 flex items-center gap-1.5\">\n <span className=\"w-2 h-2 bg-emerald-500 rounded-full\"></span>\n Online\n </p>\n </div>\n </div>\n <div className=\"hidden sm:block text-[11px] font-medium text-slate-400 bg-gray-50 px-2 py-1 rounded-md border border-gray-100\">\n Secure Session\n </div>\n </div>\n\n <div className=\"flex-1 relative bg-white pb-32 md:pb-36 overflow-y-auto\">\n <Messages messages={message} chatbotName={chatbotName || ''} />\n </div>\n\n <div className=\"absolute bottom-0 w-full bg-white p-3 md:p-6 border-t border-gray-100\">\n <Form {...form}>\n <form\n className=\"relative flex items-center gap-2 md:gap-3 max-w-4xl mx-auto\"\n onSubmit={form.handleSubmit(onsubmit)}\n >\n <div className=\"relative flex-1\">\n <FormField\n control={form.control}\n name=\"message\"\n render={({ field }) => (\n <FormItem className=\"flex-1\">\n <FormControl>\n <Input\n {...field}\n placeholder={onboardingStep === 1 ? \"Your name...\" : onboardingStep === 2 ? \"Your email...\" : \"Type a message...\"}\n className=\"p-3 md:p-5 rounded-xl bg-gray-50 border-gray-200 text-slate-900 placeholder:text-slate-400 focus:ring-2 focus:ring-slate-200 focus:border-slate-300 transition-all\"\n />\n </FormControl>\n </FormItem>\n )}\n />\n </div>\n <Button\n type=\"submit\"\n disabled={form.formState.isSubmitting || !form.formState.isValid || loading}\n className=\"h-12 w-12 md:h-16 md:w-16 rounded-xl bg-slate-900 text-white hover:bg-slate-800 transition-all shrink-0\"\n >\n {loading ? (\n <div className=\"h-6 w-6 md:h-8 md:w-8 border-2 border-white border-t-transparent rounded-full animate-spin\" />\n ) : (\n <p className=\"cursor-pointer text-sm md:text-base\">Send</p>)}\n </Button>\n </form>\n </Form>\n </div>\n </div>\n </div>\n );\n}\n\nexport default ChatbotClient;\n","async function startNewChat(\n origin: string,\n guestName: string,\n guestEmail: string,\n chatbotId: number,\n): Promise<number> {\n const baseUrl = origin.replace(/\\/$/, '');\n const response = await fetch(`${baseUrl}/api/start-chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name: guestName,\n email: guestEmail,\n chatbot_id: chatbotId,\n }),\n });\n\n if (!response.ok) {\n const payload = await response.json().catch(() => null);\n const message =\n payload?.error ?? `Failed to start chat (${response.status})`;\n throw new Error(message);\n }\n\n const data = await response.json();\n if (typeof data?.chat_session_id !== 'number') {\n throw new Error('Server returned an invalid response');\n }\n return data.chat_session_id;\n}\n\nexport default startNewChat;\n","import { gql } from \"@apollo/client\";\n\nexport const GET_MESSEGES_BY_CHAT_SESSION_ID = gql`\n query GetMessagesByChatSessionId($chat_session_id: Int!) {\n chat_sessions(id: $chat_session_id) {\n created_at\n id\n messages {\n id\n sender\n content\n created_at\n }\n }\n }\n`;\n","import React from 'react'\nimport { rings } from '@dicebear/collection'\nimport { createAvatar } from '@dicebear/core'\n\n/**\n * Browser-safe base64 encoder. Avoids `Buffer` because the embed is shipped\n * to non-Node consumers where `Buffer` is not defined.\n */\nfunction utf8ToBase64(input: string): string {\n const bytes = new TextEncoder().encode(input);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nfunction Avatar({ seed, className }: { seed: string; className?: string }) {\n const avatar = createAvatar(rings, { seed });\n const svg = avatar.toString();\n const dataUrl = `data:image/svg+xml;base64,${utf8ToBase64(svg)}`;\n\n return (\n <div>\n <img src={dataUrl} alt=\"Avatar\" width={80} height={80} className={className} />\n </div>\n );\n}\n\nexport default Avatar;\n","'use client'\n\nimport { Message } from \"../types\"\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport Avatar from \"./Avatar\";\nimport { UserCircle } from \"lucide-react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { AiBubble, UserBubble, FourDotWave } from \"./ChatMotion\";\n\n/* -------------------------------------------------------------------------- */\n/* Small helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction formatTime(iso: string) {\n try {\n const d = new Date(iso);\n return d.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n } catch {\n return \"\";\n }\n}\n\nfunction TypewriterMarkdown({ text, isFresh, components, onType }: { text: string, isFresh: boolean, components: any, onType?: () => void }) {\n const [displayedText, setDisplayedText] = useState(\"\");\n const [index, setIndex] = useState(0);\n\n useEffect(() => {\n setDisplayedText(\"\");\n setIndex(0);\n }, [text]);\n\n useEffect(() => {\n if (isFresh && text && index < text.length) {\n const timeout = setTimeout(() => {\n setDisplayedText((prev) => prev + text[index]);\n setIndex((prev) => prev + 1);\n if (onType) onType();\n }, 15);\n return () => clearTimeout(timeout);\n } else if (!isFresh) {\n setDisplayedText(text || \"\");\n }\n }, [index, text, isFresh]);\n\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={components}\n >\n {isFresh ? displayedText : text}\n </ReactMarkdown>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------------- */\n\nfunction Messages({ messages, chatbotName, logoUrl, isReviewPage = false }: { messages: Message[], chatbotName: string, logoUrl?: string, isReviewPage?: boolean }) {\n const ref = useRef<HTMLDivElement>(null);\n const [hoveredId, setHoveredId] = useState<number | string | null>(null);\n\n const scrollToBottom = (smooth = true) => {\n if (ref.current) {\n ref.current.scrollIntoView({ behavior: smooth ? \"smooth\" : \"auto\", block: \"end\" });\n }\n };\n\n useEffect(() => {\n scrollToBottom();\n }, [messages]);\n\n const [isClient, setIsClient] = useState(false);\n\n useEffect(() => {\n setIsClient(true);\n }, []);\n\n const markdownComponents = {\n ul: ({ node, ...props }: any) => (<ul className=\"list-disc list-inside ml-5 mb-3\" {...props} />),\n ol: ({ node, ...props }: any) => (<ol className=\"list-decimal list-inside ml-5 mb-3\" {...props} />),\n h1: ({ node, ...props }: any) => (<h1 className=\"text-2xl font-bold mb-3 font-display\" {...props} />),\n h2: ({ node, ...props }: any) => (<h2 className=\"text-xl font-bold mb-3 font-display\" {...props} />),\n h3: ({ node, ...props }: any) => (<h3 className=\"text-lg font-bold mb-3 font-display\" {...props} />),\n table: ({ node, ...props }: any) => (<table className=\"table-auto mb-3 w-full border-separate border-2 rounded-sm border-spacing-4\" style={{ borderColor: \"rgba(26,20,15,0.18)\" }} {...props} />),\n th: ({ node, ...props }: any) => (<th className=\"text-left underline\" {...props} />),\n p: ({ node, ...props }: any) => (<p className=\"whitespace-pre-wrap mb-3 last:mb-0 leading-relaxed\" {...props} />),\n a: ({ node, ...props }: any) => (<a className=\"hover:underline font-semibold\" style={{ color: \"#c45d4f\" }} rel=\"noopener noreferrer\" target=\"_blank\" {...props} />),\n code: ({ node, ...props }: any) => (\n <code\n className=\"px-1.5 py-0.5 rounded font-mono text-[13px]\"\n style={{ background: \"rgba(26,20,15,0.10)\" }}\n {...props}\n />\n ),\n };\n\n return (\n <div className=\"flex flex-1 flex-col space-y-7 py-8 px-5 md:px-10 bg-transparent rounded-lg scroll-smooth \">\n {messages.map((message, index) => {\n const isSender = message.sender !== \"user\";\n const isThinking = message.content === \"\" || message.content === \"Thinking...\";\n const isFresh = index === messages.length - 1;\n const showMeta = hoveredId === message.id || isReviewPage;\n\n return (\n <div\n key={message.id || index}\n onMouseEnter={() => setHoveredId(message.id)}\n onMouseLeave={() => setHoveredId(null)}\n className={`chat ${isSender ? \"chat-start\" : \"chat-end\"} relative group overflow-hidden`}\n >\n {isReviewPage && (\n <p className=\"absolute -bottom-5 text-xs text-gray-300\">\n sent {new Date(message.created_at).toLocaleString()}\n </p>\n )}\n\n {isFresh && (\n <span\n aria-hidden\n className=\"ring-out pointer-events-none absolute -inset-2 rounded-[26px]\"\n />\n )}\n\n <div className={`chat-image avatar w-10 ${!isSender && \"mr-4\"}`}>\n {logoUrl ? (\n <img\n src={logoUrl}\n alt={chatbotName || \"Chatbot logo\"}\n width={48}\n height={48}\n className=\"h-12 w-12 rounded-full border object-cover\"\n style={{ borderColor: \"var(--hairline)\" }}\n />\n ) : isSender ? (\n <div\n className=\"border h-12 w-12 rounded-full bg-white overflow-hidden\"\n style={{ borderColor: \"var(--hairline)\" }}\n >\n <Avatar seed={chatbotName} className=\"h-12 w-12\" />\n </div>\n ) : (\n <div className=\"h-12 w-12 rounded-full grid place-items-center\" style={{ background: \"rgba(244,234,215,0.06)\" }}>\n <UserCircle className=\"text-[var(--brass-2)]\" />\n </div>\n )}\n </div>\n\n {isSender ? (\n <AiBubble\n springIn={isFresh}\n typing={isThinking}\n className=\"chat-bubble relative rounded-2xl px-4 py-3 max-w-[80%] font-body text-[15px] leading-relaxed\"\n style={isThinking ? {} : { border: \"1px solid rgba(224,176,112,0.18)\" }}\n >\n {isThinking ? (\n <div className=\"flex items-center gap-3 py-1\" style={{ color: \"#1e1e1e\" }}>\n <FourDotWave />\n <span className=\"font-mono text-[10px] uppercase tracking-[0.25em] opacity-70\">\n Thinking...\n </span>\n </div>\n ) : (\n <TypewriterMarkdown\n text={message.content}\n isFresh={isFresh}\n components={markdownComponents}\n onType={() => scrollToBottom(false)}\n />\n )}\n </AiBubble>\n ) : (\n <UserBubble\n springIn={isFresh}\n className=\"chat-bubble relative rounded-2xl px-4 py-3 max-w-[80%] font-body text-[15px] leading-relaxed\"\n style={{\n background: \"#e9e3e3ff\",\n color: \"#1e1e1e\",\n border: \"1px solid rgba(231, 228, 224, 0.22)\",\n }}\n >\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={markdownComponents}\n >\n {message.content}\n </ReactMarkdown>\n </UserBubble>\n )}\n\n <div\n className={`mt-1.5 px-1 flex items-center gap-2 font-mono text-[10px] uppercase tracking-[0.2em] transition-opacity duration-200 ${showMeta ? \"opacity-100\" : \"opacity-0\"\n }`}\n style={{ color: \"var(--muted-2)\" }}\n >\n <span>{isSender ? chatbotName || \"assistant\" : \"you\"}</span>\n <span className=\"w-1 h-1 rounded-full\" style={{ background: \"var(--muted-2)\" }} />\n <span>{formatTime(message.created_at)}</span>\n </div>\n </div>\n );\n })}\n <div ref={ref} />\n </div>\n );\n}\n\nexport default Messages;\n","'use client';\n\n/**\n * Re-usable Google-inspired motion primitives for the chat surface.\n *\n * 1. <FluidAura /> — full-bleed Gemini-style gradient mesh + SVG turbulence.\n * 2. <FourDotWave /> — 4 colored dots bouncing in a wave.\n * 3. <AiBubble /> — springy entrance + slow-shifting gradient background.\n *\n * All animations are pure CSS; no external libraries.\n */\n\nimport React from \"react\";\n\n/* -------------------------------------------------------------------------- */\n/* 1. Fluid Aura */\n/* -------------------------------------------------------------------------- */\n\nexport function FluidAura({ className = \"\" }: { className?: string }) {\n return (\n <div\n className={`pointer-events-none absolute inset-0 overflow-hidden ${className}`}\n aria-hidden\n >\n {/* The moving gradient mesh. Two layers offset for parallax effect. */}\n <div className=\"absolute inset-0 [filter:url(#auraDisplace)]\">\n <div className=\"aura-mesh aura-mesh-a\" />\n <div className=\"aura-mesh aura-mesh-b\" />\n </div>\n\n {/* SVG turbulence filter — gives the gradient the liquid ripple effect */}\n <svg className=\"absolute h-0 w-0\" aria-hidden focusable=\"false\">\n <defs>\n <filter id=\"auraDisplace\">\n <feTurbulence\n type=\"fractalNoise\"\n baseFrequency=\"0.012 0.018\"\n numOctaves=\"2\"\n seed=\"7\"\n >\n <animate\n attributeName=\"baseFrequency\"\n dur=\"22s\"\n values=\"0.012 0.018; 0.022 0.028; 0.012 0.018\"\n repeatCount=\"indefinite\"\n />\n </feTurbulence>\n <feDisplacementMap in=\"SourceGraphic\" scale=\"120\" />\n </filter>\n </defs>\n </svg>\n\n {/* Local styles — kept here so the component is self-contained. */}\n <style>{`\n .aura-mesh {\n position: absolute;\n inset: -25%;\n background: radial-gradient(\n circle at 20% 30%,\n rgba(66, 133, 244, 0.55) 0%,\n transparent 45%\n ),\n radial-gradient(\n circle at 80% 20%,\n rgba(155, 81, 224, 0.5) 0%,\n transparent 45%\n ),\n radial-gradient(\n circle at 70% 80%,\n rgba(234, 67, 53, 0.45) 0%,\n transparent 45%\n ),\n radial-gradient(\n circle at 25% 85%,\n rgba(251, 188, 5, 0.45) 0%,\n transparent 45%\n );\n will-change: transform;\n }\n .aura-mesh-a {\n animation: auraDrift1 18s ease-in-out infinite alternate;\n }\n .aura-mesh-b {\n animation: auraDrift2 24s ease-in-out infinite alternate;\n mix-blend-mode: screen;\n opacity: 0.7;\n }\n @keyframes auraDrift1 {\n from { transform: translate3d(-4%, -3%, 0) scale(1.05); }\n to { transform: translate3d(6%, 4%, 0) scale(1.15); }\n }\n @keyframes auraDrift2 {\n from { transform: translate3d(5%, 3%, 0) scale(1.10); }\n to { transform: translate3d(-5%, -4%, 0) scale(1.20); }\n }\n `}</style>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* 2. Four-Dot Voice Wave */\n/* -------------------------------------------------------------------------- */\n\nexport function FourDotWave({ className = \"\" }: { className?: string }) {\n const dots = [\n { color: \"#8a2a2a\", delay: \"0s\" }, // oxblood\n { color: \"#c89a5b\", delay: \"0.12s\" }, // brass\n { color: \"#5a6b3b\", delay: \"0.24s\" }, // moss\n { color: \"#2c5b5e\", delay: \"0.36s\" }, // teal\n ];\n return (\n <span className={`inline-flex items-center gap-1.5 ${className}`} aria-label=\"Loading\">\n {dots.map((d, i) => (\n <span\n key={i}\n className=\"dot-wave\"\n style={{ backgroundColor: d.color, animationDelay: d.delay }}\n />\n ))}\n <style>{`\n .dot-wave {\n display: inline-block;\n width: 7px;\n height: 7px;\n border-radius: 9999px;\n will-change: transform;\n animation: dotBounce 1.1s cubic-bezier(0.45, 0, 0.55, 1) infinite;\n }\n @keyframes dotBounce {\n 0%, 60%, 100% { transform: translate3d(0, 0, 0); }\n 30% { transform: translate3d(0, -6px, 0); }\n }\n `}</style>\n </span>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* 3. Springy chat bubble with shifting gradient */\n/* -------------------------------------------------------------------------- */\n\nexport function AiBubble({\n children,\n className = \"\",\n springIn = true,\n style,\n typing = false,\n}: {\n children: React.ReactNode;\n className?: string;\n springIn?: boolean;\n style?: React.CSSProperties;\n typing?: boolean;\n}) {\n return (\n <div\n className={`ai-bubble ${springIn ? \"ai-bubble-in\" : \"\"} ${typing ? \"ai-typing\" : \"\"} ${className}`}\n style={style}\n >\n {children}\n <style>{`\n .ai-bubble {\n position: relative;\n transform-origin: bottom left;\n color: #1e1e1e;\n background: linear-gradient(\n 135deg,\n #eef2ff 0%,\n #f5f3ff 35%,\n #ecfeff 70%,\n #eef2ff 100%\n );\n background-size: 250% 250%;\n will-change: transform, background-position, box-shadow;\n transition: box-shadow 220ms ease, background 220ms ease;\n }\n .ai-bubble-in {\n animation: aiSpring 620ms cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n }\n /* Typing state: vibrant purple gradient with glow */\n .ai-typing {\n background: linear-gradient(135deg, #7c3aed 0%, #6d28d9 35%, #8b5cf6 70%, #7c3aed 100%);\n background-size: 200% 200%;\n animation: aiTypingShift 4.5s ease-in-out infinite;\n box-shadow: 0 12px 36px rgba(124,58,237,0.20), 0 1px 0 rgba(255,255,255,0.05) inset;\n color: #fff;\n border-color: rgba(255,255,255,0.08);\n }\n @keyframes aiSpring {\n 0% { transform: scale(0.4) translate3d(0, 12px, 0); opacity: 0; }\n 60% { transform: scale(1.04) translate3d(0, -2px, 0); opacity: 1; }\n 100% { transform: scale(1) translate3d(0, 0, 0); opacity: 1; }\n }\n @keyframes aiTypingShift {\n 0% { background-position: 0% 50%; filter: drop-shadow(0 0 0 rgba(124,58,237,0)); }\n 50% { background-position: 100% 50%; filter: drop-shadow(0 18px 48px rgba(124,58,237,0.18)); }\n 100% { background-position: 0% 50%; filter: drop-shadow(0 0 0 rgba(124,58,237,0)); }\n }\n `}</style>\n </div>\n );\n}\n\nexport function UserBubble({\n children,\n className = \"\",\n springIn = true,\n style,\n}: {\n children: React.ReactNode;\n className?: string;\n springIn?: boolean;\n style?: React.CSSProperties;\n}) {\n return (\n <div\n className={`user-bubble ${springIn ? \"user-bubble-in\" : \"\"} ${className}`}\n style={style}\n >\n {children}\n <style>{`\n .user-bubble {\n position: relative;\n transform-origin: bottom right;\n background: #111113;\n color: #ffffff;\n will-change: transform;\n }\n .user-bubble-in {\n animation: userSpring 520ms cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n }\n @keyframes userSpring {\n 0% { transform: scale(0.4) translate3d(0, 12px, 0); opacity: 0; }\n 60% { transform: scale(1.04) translate3d(0, -2px, 0); opacity: 1; }\n 100% { transform: scale(1) translate3d(0, 0, 0); opacity: 1; }\n }\n `}</style>\n </div>\n );\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport {\n Controller,\n FormProvider,\n useFormContext,\n useFormState,\n type ControllerProps,\n type FieldPath,\n type FieldValues,\n} from \"react-hook-form\"\n\nimport { cn } from \"../lib/utils\"\nimport { Label } from \"./label\"\n\nconst Form = FormProvider\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n name: TName\n}\n\nconst FormFieldContext = React.createContext<FormFieldContextValue>(\n {} as FormFieldContextValue\n)\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n ...props\n}: ControllerProps<TFieldValues, TName>) => {\n return (\n <FormFieldContext.Provider value={{ name: props.name }}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n )\n}\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext)\n const itemContext = React.useContext(FormItemContext)\n const { getFieldState } = useFormContext()\n const formState = useFormState({ name: fieldContext.name })\n const fieldState = getFieldState(fieldContext.name, formState)\n\n if (!fieldContext) {\n throw new Error(\"useFormField should be used within <FormField>\")\n }\n\n const { id } = itemContext\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n }\n}\n\ntype FormItemContextValue = {\n id: string\n}\n\nconst FormItemContext = React.createContext<FormItemContextValue>(\n {} as FormItemContextValue\n)\n\nfunction FormItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const id = React.useId()\n\n return (\n <FormItemContext.Provider value={{ id }}>\n <div\n data-slot=\"form-item\"\n className={cn(\"grid gap-2\", className)}\n {...props}\n />\n </FormItemContext.Provider>\n )\n}\n\nfunction FormLabel({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n const { error, formItemId } = useFormField()\n\n return (\n <Label\n data-slot=\"form-label\"\n data-error={!!error}\n className={cn(\"data-[error=true]:text-destructive\", className)}\n htmlFor={formItemId}\n {...props}\n />\n )\n}\n\nfunction FormControl({ ...props }: React.ComponentProps<typeof Slot>) {\n const { error, formItemId, formDescriptionId, formMessageId } = useFormField()\n\n return (\n <Slot\n data-slot=\"form-control\"\n id={formItemId}\n aria-describedby={\n !error\n ? `${formDescriptionId}`\n : `${formDescriptionId} ${formMessageId}`\n }\n aria-invalid={!!error}\n {...props}\n />\n )\n}\n\nfunction FormDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n const { formDescriptionId } = useFormField()\n\n return (\n <p\n data-slot=\"form-description\"\n id={formDescriptionId}\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction FormMessage({ className, ...props }: React.ComponentProps<\"p\">) {\n const { error, formMessageId } = useFormField()\n const body = error ? String(error?.message ?? \"\") : props.children\n\n if (!body) {\n return null\n }\n\n return (\n <p\n data-slot=\"form-message\"\n id={formMessageId}\n className={cn(\"text-destructive text-sm\", className)}\n {...props}\n >\n {body}\n </p>\n )\n}\n\nexport {\n useFormField,\n Form,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n FormField,\n}\n","import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n","import * as React from \"react\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40\",\n outline:\n \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-3\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,SAAgB,aAAAA,YAAW,SAAS,YAAAC,iBAAgB;AACpD,SAAS,sBAAsB;;;ACD/B,SAAS,cAAc,eAAe,sBAA2C;AAEjF,IAAM,iBAAiC;AAAA,EACrC,YAAY,EAAE,aAAa,YAAY,aAAa,MAAM;AAAA,EAC1D,OAAO,EAAE,aAAa,YAAY,aAAa,MAAM;AAAA,EACrD,QAAQ,EAAE,aAAa,YAAY,aAAa,MAAM;AACxD;AAEO,SAAS,mBAAmB,QAAuC;AACxE,QAAM,UAAU,OAAO,QAAQ,OAAO,EAAE;AACxC,SAAO,IAAI,aAAa;AAAA,IACtB,MAAM,eAAe,EAAE,KAAK,GAAG,OAAO,eAAe,CAAC;AAAA,IACtD,OAAO,IAAI,cAAc;AAAA,IACzB;AAAA,EACF,CAAC;AACH;;;ACfA,SAAS,aAAAC,YAAW,YAAAC,iBAAgB;AACpC,SAAS,gBAAgB;AACzB,SAAS,SAAS;AAClB,SAAS,eAAe;AACxB,SAAS,mBAAmB;;;ACN5B,eAAe,aACb,QACA,WACA,YACA,WACiB;AALnB;AAME,QAAM,UAAU,OAAO,QAAQ,OAAO,EAAE;AACxC,QAAM,WAAW,MAAM,MAAM,GAAG,OAAO,mBAAmB;AAAA,IACxD,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,OAAO;AAAA,MACP,YAAY;AAAA,IACd,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,UAAU,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AACtD,UAAM,WACJ,wCAAS,UAAT,YAAkB,yBAAyB,SAAS,MAAM;AAC5D,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,MAAI,QAAO,6BAAM,qBAAoB,UAAU;AAC7C,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AACA,SAAO,KAAK;AACd;AAEA,IAAO,uBAAQ;;;AC/Bf,SAAS,WAAW;AAEb,IAAM,kCAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACD/C,SAAS,aAAa;AACtB,SAAS,oBAAoB;AAsBvB;AAhBN,SAAS,aAAa,OAAuB;AAC3C,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK;AAC5C,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EACxC;AACA,SAAO,KAAK,MAAM;AACpB;AAEA,SAAS,OAAO,EAAE,MAAM,UAAU,GAAyC;AACzE,QAAM,SAAS,aAAa,OAAO,EAAE,KAAK,CAAC;AAC3C,QAAM,MAAM,OAAO,SAAS;AAC5B,QAAM,UAAU,6BAA6B,aAAa,GAAG,CAAC;AAE9D,SACE,oBAAC,SACC,8BAAC,SAAI,KAAK,SAAS,KAAI,UAAS,OAAO,IAAI,QAAQ,IAAI,WAAsB,GAC/E;AAEJ;AAEA,IAAO,iBAAQ;;;AC1Bf,OAAO,mBAAmB;AAC1B,OAAO,eAAe;AAEtB,SAAS,kBAAkB;AAC3B,SAAgB,WAAW,QAAQ,gBAAgB;;;ACkB7C,SACE,OAAAC,MADF;AA+EC,SAAS,YAAY,EAAE,YAAY,GAAG,GAA2B;AACtE,QAAM,OAAO;AAAA,IACX,EAAE,OAAO,WAAW,OAAO,KAAK;AAAA;AAAA,IAChC,EAAE,OAAO,WAAW,OAAO,QAAQ;AAAA;AAAA,IACnC,EAAE,OAAO,WAAW,OAAO,QAAQ;AAAA;AAAA,IACnC,EAAE,OAAO,WAAW,OAAO,QAAQ;AAAA;AAAA,EACrC;AACA,SACE,qBAAC,UAAK,WAAW,oCAAoC,SAAS,IAAI,cAAW,WAC1E;AAAA,SAAK,IAAI,CAAC,GAAG,MACZ,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QACV,OAAO,EAAE,iBAAiB,EAAE,OAAO,gBAAgB,EAAE,MAAM;AAAA;AAAA,MAFtD;AAAA,IAGP,CACD;AAAA,IACD,gBAAAA,KAAC,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAaN;AAAA,KACJ;AAEJ;AAMO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA,YAAY;AAAA,EACZ,WAAW;AAAA,EACX;AAAA,EACA,SAAS;AACX,GAMG;AACD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,aAAa,WAAW,iBAAiB,EAAE,IAAI,SAAS,cAAc,EAAE,IAAI,SAAS;AAAA,MAChG;AAAA,MAEC;AAAA;AAAA,QACD,gBAAAA,KAAC,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAsCN;AAAA;AAAA;AAAA,EACJ;AAEJ;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,YAAY;AAAA,EACZ,WAAW;AAAA,EACX;AACF,GAKG;AACD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,eAAe,WAAW,mBAAmB,EAAE,IAAI,SAAS;AAAA,MACvE;AAAA,MAEC;AAAA;AAAA,QACD,gBAAAA,KAAC,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAgBN;AAAA;AAAA;AAAA,EACJ;AAEJ;;;ADlMI,gBAAAC,MAoEU,QAAAC,aApEV;AAhCJ,SAAS,WAAW,KAAa;AAC/B,MAAI;AACF,UAAM,IAAI,IAAI,KAAK,GAAG;AACtB,WAAO,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,WAAW,QAAQ,UAAU,CAAC;AAAA,EACxE,SAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,mBAAmB,EAAE,MAAM,SAAS,YAAY,OAAO,GAA6E;AAC3I,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,EAAE;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,CAAC;AAEpC,YAAU,MAAM;AACd,qBAAiB,EAAE;AACnB,aAAS,CAAC;AAAA,EACZ,GAAG,CAAC,IAAI,CAAC;AAET,YAAU,MAAM;AACd,QAAI,WAAW,QAAQ,QAAQ,KAAK,QAAQ;AAC1C,YAAM,UAAU,WAAW,MAAM;AAC/B,yBAAiB,CAAC,SAAS,OAAO,KAAK,KAAK,CAAC;AAC7C,iBAAS,CAAC,SAAS,OAAO,CAAC;AAC3B,YAAI,OAAQ,QAAO;AAAA,MACrB,GAAG,EAAE;AACL,aAAO,MAAM,aAAa,OAAO;AAAA,IACnC,WAAW,CAAC,SAAS;AACnB,uBAAiB,QAAQ,EAAE;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,OAAO,MAAM,OAAO,CAAC;AAEzB,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,eAAe,CAAC,SAAS;AAAA,MACzB;AAAA,MAEC,oBAAU,gBAAgB;AAAA;AAAA,EAC7B;AAEJ;AAMA,SAAS,SAAS,EAAE,UAAU,aAAa,SAAS,eAAe,MAAM,GAA2F;AAClK,QAAM,MAAM,OAAuB,IAAI;AACvC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAiC,IAAI;AAEvE,QAAM,iBAAiB,CAAC,SAAS,SAAS;AACxC,QAAI,IAAI,SAAS;AACf,UAAI,QAAQ,eAAe,EAAE,UAAU,SAAS,WAAW,QAAQ,OAAO,MAAM,CAAC;AAAA,IACnF;AAAA,EACF;AAEA,YAAU,MAAM;AACd,mBAAe;AAAA,EACjB,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,gBAAY,IAAI;AAAA,EAClB,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB;AAAA,IACzB,IAAI,CAAC,OAAyB;AAAzB,mBAAE,OAhFX,IAgFS,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,uBAAG,WAAU,qCAAsC,MAAO;AAAA;AAAA,IAC7F,IAAI,CAAC,OAAyB;AAAzB,mBAAE,OAjFX,IAiFS,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,uBAAG,WAAU,wCAAyC,MAAO;AAAA;AAAA,IAChG,IAAI,CAAC,OAAyB;AAAzB,mBAAE,OAlFX,IAkFS,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,uBAAG,WAAU,0CAA2C,MAAO;AAAA;AAAA,IAClG,IAAI,CAAC,OAAyB;AAAzB,mBAAE,OAnFX,IAmFS,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,uBAAG,WAAU,yCAA0C,MAAO;AAAA;AAAA,IACjG,IAAI,CAAC,OAAyB;AAAzB,mBAAE,OApFX,IAoFS,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,uBAAG,WAAU,yCAA0C,MAAO;AAAA;AAAA,IACjG,OAAO,CAAC,OAAyB;AAAzB,mBAAE,OArFd,IAqFY,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,0BAAM,WAAU,+EAA8E,OAAO,EAAE,aAAa,sBAAsB,KAAO,MAAO;AAAA;AAAA,IAC9L,IAAI,CAAC,OAAyB;AAAzB,mBAAE,OAtFX,IAsFS,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,uBAAG,WAAU,yBAA0B,MAAO;AAAA;AAAA,IACjF,GAAG,CAAC,OAAyB;AAAzB,mBAAE,OAvFV,IAuFQ,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,sBAAE,WAAU,wDAAyD,MAAO;AAAA;AAAA,IAC9G,GAAG,CAAC,OAAyB;AAAzB,mBAAE,OAxFV,IAwFQ,IAAW,kBAAX,IAAW,CAAT;AAA2B,6BAAAA,KAAC,sBAAE,WAAU,iCAAgC,OAAO,EAAE,OAAO,UAAU,GAAG,KAAI,uBAAsB,QAAO,YAAa,MAAO;AAAA;AAAA,IAChK,MAAM,CAAC,OAAyB;AAAzB,mBAAE,OAzFb,IAyFW,IAAW,kBAAX,IAAW,CAAT;AACP,6BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,YAAY,sBAAsB;AAAA,WACvC;AAAA,MACN;AAAA;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,WAAU,8FACZ;AAAA,aAAS,IAAI,CAAC,SAAS,UAAU;AAChC,YAAM,WAAW,QAAQ,WAAW;AACpC,YAAM,aAAa,QAAQ,YAAY,MAAM,QAAQ,YAAY;AACjE,YAAM,UAAU,UAAU,SAAS,SAAS;AAC5C,YAAM,WAAW,cAAc,QAAQ,MAAM;AAE7C,aACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,cAAc,MAAM,aAAa,QAAQ,EAAE;AAAA,UAC3C,cAAc,MAAM,aAAa,IAAI;AAAA,UACrC,WAAW,QAAQ,WAAW,eAAe,UAAU;AAAA,UAEtD;AAAA,4BACC,gBAAAA,MAAC,OAAE,WAAU,4CAA2C;AAAA;AAAA,cAChD,IAAI,KAAK,QAAQ,UAAU,EAAE,eAAe;AAAA,eACpD;AAAA,YAGD,WACC,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,eAAW;AAAA,gBACX,WAAU;AAAA;AAAA,YACZ;AAAA,YAGF,gBAAAA,KAAC,SAAI,WAAW,0BAA0B,CAAC,YAAY,MAAM,IAC1D,oBACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK;AAAA,gBACL,KAAK,eAAe;AAAA,gBACpB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,WAAU;AAAA,gBACV,OAAO,EAAE,aAAa,kBAAkB;AAAA;AAAA,YAC1C,IACE,WACF,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,aAAa,kBAAkB;AAAA,gBAExC,0BAAAA,KAAC,kBAAO,MAAM,aAAa,WAAU,aAAY;AAAA;AAAA,YACnD,IAEA,gBAAAA,KAAC,SAAI,WAAU,kDAAiD,OAAO,EAAE,YAAY,yBAAyB,GAC5G,0BAAAA,KAAC,cAAW,WAAU,yBAAwB,GAChD,GAEJ;AAAA,YAEC,WACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,UAAU;AAAA,gBACV,QAAQ;AAAA,gBACR,WAAU;AAAA,gBACV,OAAO,aAAa,CAAC,IAAI,EAAE,QAAQ,mCAAmC;AAAA,gBAErE,uBACC,gBAAAC,MAAC,SAAI,WAAU,gCAA+B,OAAO,EAAE,OAAO,UAAU,GACtE;AAAA,kCAAAD,KAAC,eAAY;AAAA,kBACb,gBAAAA,KAAC,UAAK,WAAU,gEAA+D,yBAE/E;AAAA,mBACF,IAEA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAM,QAAQ;AAAA,oBACd;AAAA,oBACA,YAAY;AAAA,oBACZ,QAAQ,MAAM,eAAe,KAAK;AAAA;AAAA,gBACpC;AAAA;AAAA,YAEJ,IAEA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,UAAU;AAAA,gBACV,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,YAAY;AAAA,kBACZ,OAAO;AAAA,kBACP,QAAQ;AAAA,gBACV;AAAA,gBAEA,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,eAAe,CAAC,SAAS;AAAA,oBACzB,YAAY;AAAA,oBAEX,kBAAQ;AAAA;AAAA,gBACX;AAAA;AAAA,YACF;AAAA,YAGF,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBACC,WAAW,yHAAyH,WAAW,gBAAgB,WAC7J;AAAA,gBACF,OAAO,EAAE,OAAO,iBAAiB;AAAA,gBAEjC;AAAA,kCAAAD,KAAC,UAAM,qBAAW,eAAe,cAAc,OAAM;AAAA,kBACrD,gBAAAA,KAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,YAAY,iBAAiB,GAAG;AAAA,kBAChF,gBAAAA,KAAC,UAAM,qBAAW,QAAQ,UAAU,GAAE;AAAA;AAAA;AAAA,YACxC;AAAA;AAAA;AAAA,QA5FK,QAAQ,MAAM;AAAA,MA6FrB;AAAA,IAEJ,CAAC;AAAA,IACD,gBAAAA,KAAC,SAAI,KAAU;AAAA,KACjB;AAEJ;AAEA,IAAO,mBAAQ;;;AE/Mf,YAAYE,YAAW;AAEvB,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;;;ACbP,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACFA,YAAY,oBAAoB;AAS5B,gBAAAC,YAAA;;;AF2BE,gBAAAC,YAAA;AArBN,IAAM,OAAO;AASb,IAAM,mBAAyB;AAAA,EAC7B,CAAC;AACH;AAEA,IAAM,YAAY,CAGhB,OAE0C;AAF1C,MACG,kBADH,IACG;AAEH,SACE,gBAAAA,KAAC,iBAAiB,UAAjB,EAA0B,OAAO,EAAE,MAAM,MAAM,KAAK,GACnD,0BAAAA,KAAC,+BAAe,MAAO,GACzB;AAEJ;AAEA,IAAM,eAAe,MAAM;AACzB,QAAM,eAAqB,kBAAW,gBAAgB;AACtD,QAAM,cAAoB,kBAAW,eAAe;AACpD,QAAM,EAAE,cAAc,IAAI,eAAe;AACzC,QAAM,YAAY,aAAa,EAAE,MAAM,aAAa,KAAK,CAAC;AAC1D,QAAM,aAAa,cAAc,aAAa,MAAM,SAAS;AAE7D,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,QAAM,EAAE,GAAG,IAAI;AAEf,SAAO;AAAA,IACL;AAAA,IACA,MAAM,aAAa;AAAA,IACnB,YAAY,GAAG,EAAE;AAAA,IACjB,mBAAmB,GAAG,EAAE;AAAA,IACxB,eAAe,GAAG,EAAE;AAAA,KACjB;AAEP;AAMA,IAAM,kBAAwB;AAAA,EAC5B,CAAC;AACH;AAEA,SAAS,SAAS,IAAsD;AAAtD,eAAE,YA3EpB,IA2EkB,IAAgB,kBAAhB,IAAgB,CAAd;AAClB,QAAM,KAAW,aAAM;AAEvB,SACE,gBAAAA,KAAC,gBAAgB,UAAhB,EAAyB,OAAO,EAAE,GAAG,GACpC,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,cAAc,SAAS;AAAA,OACjC;AAAA,EACN,GACF;AAEJ;AAmBA,SAAS,YAAY,IAAiD;AAAjD,MAAK,kBAAL,IAAK;AACxB,QAAM,EAAE,OAAO,YAAY,mBAAmB,cAAc,IAAI,aAAa;AAE7E,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,IAAI;AAAA,MACJ,oBACE,CAAC,QACG,GAAG,iBAAiB,KACpB,GAAG,iBAAiB,IAAI,aAAa;AAAA,MAE3C,gBAAc,CAAC,CAAC;AAAA,OACZ;AAAA,EACN;AAEJ;;;AGpHI,gBAAAC,YAAA;AAFJ,SAAS,MAAM,IAA8D;AAA9D,eAAE,aAAW,KAJ5B,IAIe,IAAsB,kBAAtB,IAAsB,CAApB,aAAW;AAC1B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,OACI;AAAA,EACN;AAEJ;;;ACjBA,SAAS,QAAAC,aAAY;AACrB,SAAS,WAA8B;AA+CnC,gBAAAC,YAAA;AA3CJ,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,aACE;AAAA,QACF,SACE;AAAA,QACF,WACE;AAAA,QACF,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,OAAO,IASX;AATW,eACd;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EAxCZ,IAoCgB,IAKX,kBALW,IAKX;AAAA,IAJH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAMA,QAAM,OAAO,UAAUC,QAAO;AAE9B,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,SAAS,MAAM,UAAU,CAAC,CAAC;AAAA,OACtD;AAAA,EACN;AAEJ;;;AVqJY,SACE,OAAAE,MADF,QAAAC,aAAA;AAjLZ,IAAM,aAAa,EAAE,OAAO;AAAA,EAC1B,SAAS,EAAE,OAAO,EAAE,IAAI,GAAG,4BAA4B;AACzD,CAAC;AAED,SAAS,cAAc,EAAE,IAAI,aAAa,OAAO,GAAuB;AACtE,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAS,EAAE;AACnC,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,EAAE;AACrC,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,CAAC;AACtD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,CAAC;AACtC,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAoB;AAAA,IAChD;AAAA,MACE,IAAI;AAAA,MACJ,SAAS,iBAAiB,WAAW;AAAA,MACrC,QAAQ;AAAA,MACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnC,iBAAiB;AAAA,IACnB;AAAA,EACF,CAAC;AAED,QAAM,OAAO,QAAoC;AAAA,IAC/C,UAAU,YAAY,UAAU;AAAA,IAChC,eAAe;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,QAAM,EAAE,KAAK,IAAI;AAAA,IACf;AAAA,IACA;AAAA,MACE,WAAW,EAAE,iBAAiB,OAAO;AAAA,MACrC,MAAM,CAAC;AAAA,IACT;AAAA,EACF;AAEA,EAAAC,WAAU,MAAM;AACd,QAAI,QAAQ,mBAAmB,GAAG;AAChC,YAAM,cAAc,KAAK;AACzB,YAAM,aAAa,YAAY,YAAY,CAAC;AAC5C,iBAAW,CAAC,SAAS;AACnB,cAAM,cAAc,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACjD,cAAM,cAAc,WAAW,OAAO,CAAC,MAAe,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;AAC5E,eAAO,CAAC,GAAG,MAAM,GAAG,WAAW;AAAA,MACjC,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,MAAM,cAAc,CAAC;AAEzB,iBAAe,SAAS,QAAoC;AAC1D,UAAM,EAAE,SAAS,YAAY,IAAI;AACjC,SAAK,MAAM;AAEX,QAAI,mBAAmB,GAAG;AACxB,UAAI,CAAC,YAAY,KAAK,EAAG;AAEzB,YAAM,UAAmB;AAAA,QACvB,IAAI,KAAK,IAAI;AAAA,QACb,SAAS;AAAA,QACT,iBAAiB;AAAA,QACjB,QAAQ;AAAA,QACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC;AAEA,YAAM,QAAiB;AAAA,QACrB,IAAI,KAAK,IAAI,IAAI;AAAA,QACjB,SAAS,gCAAgC,WAAW;AAAA,QACpD,iBAAiB;AAAA,QACjB,QAAQ;AAAA,QACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC;AAEA,cAAQ,WAAW;AACnB,wBAAkB,CAAC;AACnB,iBAAW,CAAC,SAAS,CAAC,GAAG,MAAM,SAAS,KAAK,CAAC;AAC9C;AAAA,IACF;AAEA,QAAI,mBAAmB,GAAG;AACxB,UAAI,CAAC,YAAY,KAAK,EAAG;AAEzB,YAAM,eAAe,CAACC,WAAkB;AACtC,eAAO,6BAA6B,KAAKA,MAAK;AAAA,MAChD;AAEA,UAAI,CAAC,aAAa,YAAY,KAAK,CAAC,GAAG;AACrC,mBAAW,CAAC,SAAS;AAAA,UACnB,GAAG;AAAA,UACH;AAAA,YACE,IAAI,KAAK,IAAI,IAAI;AAAA,YACjB,SAAS;AAAA,YACT,iBAAiB;AAAA,YACjB,QAAQ;AAAA,YACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,UACrC;AAAA,QACF,CAAC;AACD;AAAA,MACF;AACA,YAAM,UAAmB;AAAA,QACvB,IAAI,KAAK,IAAI;AAAA,QACb,SAAS;AAAA,QACT,iBAAiB;AAAA,QACjB,QAAQ;AAAA,QACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC;AAEA,iBAAW,CAAC,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC;AACvC,iBAAW,IAAI;AAEf,UAAI;AACF,cAAM,aAAa;AACnB,iBAAS,UAAU;AACnB,cAAM,YAAY,MAAM,qBAAa,QAAQ,MAAM,YAAY,OAAO,EAAE,CAAC;AACzE,kBAAU,SAAS;AACnB,0BAAkB,CAAC;AAAA,MAErB,SAAS,OAAO;AACd,gBAAQ,MAAM,wBAAwB,KAAK;AAC3C,mBAAW,CAAC,SAAS,CAAC,GAAG,MAAM;AAAA,UAC7B,IAAI,KAAK,IAAI,IAAI;AAAA,UACjB,SAAS;AAAA,UACT,iBAAiB;AAAA,UACjB,QAAQ;AAAA,UACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrC,CAAC,CAAC;AAAA,MACJ,UAAE;AACA,mBAAW,KAAK;AAAA,MAClB;AACA;AAAA,IACF;AAEA,QAAI,CAAC,OAAQ;AAEb,UAAM,cAAuB;AAAA,MAC3B,IAAI,KAAK,IAAI;AAAA,MACb,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC;AAEA,UAAM,iBAA0B;AAAA,MAC9B,IAAI,KAAK,IAAI,IAAI;AAAA,MACjB,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnC,QAAQ;AAAA,IACV;AACA,eAAW,CAAC,iBAAiB,CAAC,GAAG,cAAc,aAAa,cAAc,CAAC;AAE3E,QAAI;AACF,YAAM,UAAU,OAAO,QAAQ,OAAO,EAAE;AACxC,YAAM,WAAW,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,QAC1D,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA,iBAAiB;AAAA,UACjB,WAAW,OAAO,EAAE;AAAA,UACpB,SAAS;AAAA,UACT,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrC,CAAC;AAAA,MACH,CAAC;AACD,YAAM,SAAS,MAAM,SAAS,KAAK;AACnC;AAAA,QAAW,CAAC,iBACV,aAAa;AAAA,UAAI,CAAC,QAChB,IAAI,OAAO,eAAe,KAAK,iCAAK,MAAL,EAAU,SAAS,OAAO,SAAS,IAAI,OAAO,GAAG,KAAI;AAAA,QACtF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,0BAA0B,KAAK;AAAA,IAC/C;AAAA,EACF;AAEA,SACE,gBAAAJ,KAAC,SAAI,WAAU,wEACb,0BAAAC,MAAC,SAAI,WAAU,2HACb;AAAA,oBAAAA,MAAC,SAAI,WAAU,0GACb;AAAA,sBAAAA,MAAC,SAAI,WAAU,oDACb;AAAA,wBAAAA,MAAC,SAAI,WAAU,qBACb;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,oCAAe;AAAA,cACrB,WAAU;AAAA;AAAA,UACZ;AAAA,UACA,gBAAAA,KAAC,SAAI,WAAU,2FAA0F;AAAA,WAC3G;AAAA,QACA,gBAAAC,MAAC,SAAI,WAAU,WACb;AAAA,0BAAAD,KAAC,QAAG,WAAU,8DACX,yBAAe,aAClB;AAAA,UACA,gBAAAC,MAAC,OAAE,WAAU,oDACX;AAAA,4BAAAD,KAAC,UAAK,WAAU,uCAAsC;AAAA,YAAO;AAAA,aAE/D;AAAA,WACF;AAAA,SACF;AAAA,MACA,gBAAAA,KAAC,SAAI,WAAU,iHAAgH,4BAE/H;AAAA,OACF;AAAA,IAEA,gBAAAA,KAAC,SAAI,WAAU,2DACb,0BAAAA,KAAC,oBAAS,UAAU,SAAS,aAAa,eAAe,IAAI,GAC/D;AAAA,IAEA,gBAAAA,KAAC,SAAI,WAAU,yEACb,0BAAAA,KAAC,uCAAS,OAAT,EACC,0BAAAC;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,UAAU,KAAK,aAAa,QAAQ;AAAA,QAEpC;AAAA,0BAAAD,KAAC,SAAI,WAAU,mBACb,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS,KAAK;AAAA,cACd,MAAK;AAAA,cACL,QAAQ,CAAC,EAAE,MAAM,MACf,gBAAAA,KAAC,YAAS,WAAU,UAClB,0BAAAA,KAAC,eACC,0BAAAA;AAAA,gBAAC;AAAA,iDACK,QADL;AAAA,kBAEC,aAAa,mBAAmB,IAAI,iBAAiB,mBAAmB,IAAI,kBAAkB;AAAA,kBAC9F,WAAU;AAAA;AAAA,cACZ,GACF,GACF;AAAA;AAAA,UAEJ,GACF;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,UAAU,KAAK,UAAU,gBAAgB,CAAC,KAAK,UAAU,WAAW;AAAA,cACpE,WAAU;AAAA,cAET,oBACC,gBAAAA,KAAC,SAAI,WAAU,8FAA6F,IAE5G,gBAAAA,KAAC,OAAE,WAAU,uCAAsC,kBAAI;AAAA;AAAA,UAC3D;AAAA;AAAA;AAAA,IACF,IACF,GACF;AAAA,KACF,GACF;AAEJ;AAEA,IAAO,wBAAQ;;;AFnNP,gBAAAK,YAAA;AAnCO,SAAR,aAA8B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,SAAS,QAAQ,MAAM,mBAAmB,MAAM,GAAG,CAAC,MAAM,CAAC;AACjE,QAAM,CAAC,SAAS,UAAU,IAAIC,UAAS,KAAK;AAE5C,EAAAC,WAAU,MAAM;AACd,eAAW,IAAI;AACf;AACA,QAAI;AAAA,IAEJ,SAAS,KAAK;AACZ,yCAAU;AAAA,IACZ;AAAA,EACF,GAAG,CAAC,SAAS,OAAO,CAAC;AAErB,MAAI,CAAC,QAAS,QAAO;AAErB,SACE,gBAAAF,KAAC,kBAAe,QACd,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,SAAS;AAAA,QACT,eAAe;AAAA,SAEX,eAAgB,EAAE,sBAAsB,aAAa,IAA4B;AAAA,MAGvF,0BAAAA,KAAC,yBAAc,IAAI,OAAO,SAAS,GAAG,aAAY,aAAY,QAAgB;AAAA;AAAA,EAChF,GACF;AAEJ;","names":["useEffect","useState","useEffect","useState","jsx","jsx","jsx","jsxs","React","jsx","jsx","jsx","jsx","Slot","jsx","Slot","jsx","jsxs","useState","useEffect","email","jsx","useState","useEffect"]}
1
+ {"version":3,"sources":["../src/widget.tsx","../src/ApolloProvider.tsx","../src/ChatbotClient.tsx","../src/lib/startNewChat.ts","../src/graphql/queries.ts","../src/ui/Messages.tsx","../src/ui/form.tsx","../src/lib/utils.ts","../src/ui/label.tsx","../src/ui/input.tsx","../src/lib/injectStyles.ts","../src/styles.tokens","../src/lib/styles.ts"],"sourcesContent":["'use client';\n\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { ApolloProvider } from '@apollo/client';\nimport { createApolloClient } from './ApolloProvider';\nimport ChatbotClient from './ChatbotClient';\nimport { ensureAssistlyFonts, ensureAssistlyStyles } from './lib/injectStyles';\nimport assistlyCss from './lib/styles';\n\nexport type AssistlyChatProps = {\n chatbotId: number;\n /** Origin of the Assistly deployment that hosts the chat API, e.g. https://chatbot-xi-rose-68.vercel.app */\n origin: string;\n /** Optional brand color for accents (tints the brass accent + online dot) */\n primaryColor?: string;\n /** Fires when the chat panel has mounted and is ready to receive input */\n onReady?: () => void;\n /** Fires if the chat fails to mount */\n onError?: (err: Error) => void;\n};\n\n/**\n * Embeddable Assistly chat panel. Renders the full chat UI (intake form +\n * active chat) inside whatever container the customer places it in. Talks\n * directly to the Assistly API at `${origin}/api/...` — no iframe, no\n * cross-origin cookie issues.\n *\n * Styling is inlined into the published JS bundle (esbuild `text` loader\n * at build time, injected into <head> on mount). Consumers only need:\n *\n * import { AssistlyChat } from '@shaimaababiker/embed';\n *\n * Theme tokens are exposed as CSS variables on the root wrapper, e.g.\n * `--assistly-brass`, `--assistly-ink`, `--assistly-paper`, so the host\n * page can override them at any ancestor level.\n */\nexport default function AssistlyChat({\n chatbotId,\n origin,\n primaryColor,\n onReady,\n onError,\n}: AssistlyChatProps) {\n const client = useMemo(() => createApolloClient(origin), [origin]);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n try {\n ensureAssistlyStyles(assistlyCss);\n ensureAssistlyFonts();\n setMounted(true);\n onReady?.();\n } catch (err) {\n onError?.(err as Error);\n }\n }, [onReady, onError]);\n\n if (!mounted) return null;\n\n const themeVars: React.CSSProperties = primaryColor\n ? ({\n ['--assistly-brass' as any]: primaryColor,\n ['--assistly-primary' as any]: primaryColor,\n } as React.CSSProperties)\n : {};\n\n return (\n <ApolloProvider client={client}>\n <div\n className=\"assistly-root\"\n style={{\n width: '100%',\n height: '100%',\n minHeight: 520,\n display: 'flex',\n flexDirection: 'column',\n position: 'relative',\n background: 'var(--assistly-paper)',\n color: 'var(--assistly-ink)',\n ...themeVars,\n }}\n >\n <ChatbotClient id={String(chatbotId)} chatbotName=\"Assistant\" origin={origin} />\n </div>\n </ApolloProvider>\n );\n}\n","'use client';\n\nimport { ApolloClient, InMemoryCache, createHttpLink, type DefaultOptions } from '@apollo/client';\n\nconst defaultOptions: DefaultOptions = {\n watchQuery: { fetchPolicy: 'no-cache', errorPolicy: 'all' },\n query: { fetchPolicy: 'no-cache', errorPolicy: 'all' },\n mutate: { fetchPolicy: 'no-cache', errorPolicy: 'all' },\n};\n\nexport function createApolloClient(origin: string): ApolloClient<unknown> {\n const baseUrl = origin.replace(/\\/$/, '');\n return new ApolloClient({\n link: createHttpLink({ uri: `${baseUrl}/api/graphql` }),\n cache: new InMemoryCache(),\n defaultOptions,\n });\n}\n","'use client';\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { useQuery } from \"@apollo/client\";\nimport { z } from \"zod\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Send, ShieldCheck, ArrowUpRight } from \"lucide-react\";\n\nimport {\n Message,\n MessagesbyChatSessionIdResponse,\n MessagesbyChatSessionIdResponseVariables,\n} from \"./types\";\nimport startNewChat from \"./lib/startNewChat\";\nimport { GET_MESSEGES_BY_CHAT_SESSION_ID } from \"./graphql/queries\";\nimport Messages from \"./ui/Messages\";\nimport { FormControl, FormField, FormItem, Form } from \"./ui/form\";\nimport { Input } from \"./ui/input\";\n\ntype ChatbotClientProps = {\n id: string;\n chatbotName: string;\n origin: string;\n};\n\nconst formSchema = z.object({\n message: z.string().min(3, 'Your Message is too short!'),\n});\n\nfunction ChatbotClient({ id, chatbotName, origin }: ChatbotClientProps) {\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [onboardingStep, setOnboardingStep] = useState(1);\n const [chatId, setChatId] = useState(0);\n const [loading, setLoading] = useState(false);\n const [message, setMessage] = useState<Message[]>([\n {\n id: -1,\n content: `Hi there — I'm ${chatbotName}. I'd love to help, but first, what's your name?`,\n sender: 'ai',\n created_at: new Date().toISOString(),\n chat_session_id: 0,\n }\n ]);\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: { message: '' },\n mode: 'onChange',\n });\n\n const { data } = useQuery<MessagesbyChatSessionIdResponse, MessagesbyChatSessionIdResponseVariables>(\n GET_MESSEGES_BY_CHAT_SESSION_ID,\n { variables: { chat_session_id: chatId }, skip: !chatId }\n );\n\n useEffect(() => {\n if (data && onboardingStep === 3) {\n const chatSession = data.chat_sessions as any;\n const dbMessages = chatSession.messages || [];\n setMessage((prev) => {\n const existingIds = new Set(prev.map((m) => m.id));\n const newMessages = dbMessages.filter((m: Message) => !existingIds.has(m.id));\n return [...prev, ...newMessages];\n });\n }\n }, [data, onboardingStep]);\n\n async function onsubmit(values: z.infer<typeof formSchema>) {\n const { message: formMessage } = values;\n form.reset();\n\n if (onboardingStep === 1) {\n if (!formMessage.trim()) return;\n const userMsg: Message = {\n id: Date.now(),\n content: formMessage,\n chat_session_id: 0,\n sender: 'user',\n created_at: new Date().toISOString(),\n };\n const aiMsg: Message = {\n id: Date.now() + 1,\n content: `Lovely to meet you, ${formMessage}. One more thing — what's your email so we can stay in touch?`,\n chat_session_id: 0,\n sender: 'ai',\n created_at: new Date().toISOString(),\n };\n setName(formMessage);\n setOnboardingStep(2);\n setMessage((prev) => [...prev, userMsg, aiMsg]);\n return;\n }\n\n if (onboardingStep === 2) {\n if (!formMessage.trim()) return;\n const isValidEmail = (email: string) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n if (!isValidEmail(formMessage.trim())) {\n setMessage((prev) => [\n ...prev,\n {\n id: Date.now() + 1,\n content: \"That email doesn't look quite right — could you double-check it?\",\n chat_session_id: 0,\n sender: 'ai',\n created_at: new Date().toISOString(),\n },\n ]);\n return;\n }\n const userMsg: Message = {\n id: Date.now(),\n content: formMessage,\n chat_session_id: 0,\n sender: 'user',\n created_at: new Date().toISOString(),\n };\n setMessage((prev) => [...prev, userMsg]);\n setLoading(true);\n try {\n const newChatId = await startNewChat(origin, name, formMessage, Number(id));\n setEmail(formMessage);\n setChatId(newChatId);\n setOnboardingStep(3);\n } catch (error) {\n console.error('Error starting chat:', error);\n setMessage((prev) => [...prev, {\n id: Date.now() + 1,\n content: \"Sorry — I had trouble setting up your session. Mind entering your email again?\",\n chat_session_id: 0,\n sender: 'ai',\n created_at: new Date().toISOString(),\n }]);\n } finally {\n setLoading(false);\n }\n return;\n }\n\n if (!chatId) return;\n const userMessage: Message = {\n id: Date.now(),\n content: formMessage,\n chat_session_id: chatId,\n sender: 'user',\n created_at: new Date().toISOString(),\n };\n const loadingMessage: Message = {\n id: Date.now() + 1,\n content: 'Thinking...',\n chat_session_id: chatId,\n created_at: new Date().toISOString(),\n sender: 'ai',\n };\n setMessage((prevMessages) => [...prevMessages, userMessage, loadingMessage]);\n\n try {\n const baseUrl = origin.replace(/\\/$/, '');\n const response = await fetch(`${baseUrl}/api/send-message`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name,\n chat_session_id: chatId,\n chabot_id: Number(id),\n content: formMessage,\n created_at: new Date().toISOString(),\n }),\n });\n const result = await response.json();\n setMessage((prevMessages) =>\n prevMessages.map((msg) =>\n msg.id === loadingMessage.id ? { ...msg, content: result.content, id: result.id } : msg\n )\n );\n } catch (error) {\n console.error('Error Sending Message:', error);\n }\n }\n\n /* ------------------------------------------------------------------ */\n /* Layout */\n /* ------------------------------------------------------------------ */\n return (\n <div\n style={{\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n height: '100%',\n minHeight: 520,\n background: 'var(--assistly-paper)',\n color: 'var(--assistly-ink)',\n overflow: 'hidden',\n }}\n >\n <div className=\"assistly-grain\" />\n\n {/* ======================= HEADER ======================= */}\n <header\n style={{\n position: 'relative',\n zIndex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '18px 24px',\n background: 'var(--assistly-paper)',\n borderBottom: '1px solid var(--assistly-hairline)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 14, minWidth: 0 }}>\n <div\n style={{\n position: 'relative',\n width: 44,\n height: 44,\n borderRadius: '50%',\n background: 'var(--assistly-paper-2)',\n border: '1px solid var(--assistly-hairline-strong)',\n display: 'grid',\n placeItems: 'center',\n flexShrink: 0,\n }}\n aria-hidden\n >\n <span\n style={{\n fontFamily: 'Fraunces, Georgia, serif',\n fontSize: 19,\n fontWeight: 500,\n color: 'var(--assistly-ink)',\n letterSpacing: '-0.02em',\n }}\n >\n {chatbotName.charAt(0).toUpperCase()}\n </span>\n <span\n style={{\n position: 'absolute',\n right: -1,\n bottom: -1,\n width: 12,\n height: 12,\n borderRadius: '50%',\n background: '#5a8c5a',\n border: '2px solid var(--assistly-paper)',\n }}\n />\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', minWidth: 0 }}>\n <span\n className=\"assistly-font-display\"\n style={{\n fontSize: 17,\n lineHeight: 1.1,\n color: 'var(--assistly-ink)',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {chatbotName}\n </span>\n <span\n className=\"assistly-font-mono\"\n style={{\n fontSize: 10,\n marginTop: 4,\n letterSpacing: '0.18em',\n textTransform: 'uppercase',\n color: 'var(--assistly-ink-mute)',\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n }}\n >\n <span\n style={{\n width: 6,\n height: 6,\n borderRadius: '50%',\n background: '#5a8c5a',\n display: 'inline-block',\n }}\n />\n Online · replies in seconds\n </span>\n </div>\n </div>\n\n <div\n className=\"assistly-font-mono\"\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 10px',\n fontSize: 10,\n letterSpacing: '0.16em',\n textTransform: 'uppercase',\n color: 'var(--assistly-ink-soft)',\n background: 'var(--assistly-paper-2)',\n border: '1px solid var(--assistly-hairline)',\n borderRadius: 999,\n }}\n >\n <ShieldCheck size={12} strokeWidth={1.6} style={{ color: 'var(--assistly-brass)' }} />\n Secure\n </div>\n </header>\n\n {/* ======================= MESSAGES ======================= */}\n <main\n className=\"assistly-scroll\"\n style={{\n position: 'relative',\n zIndex: 1,\n flex: 1,\n overflowY: 'auto',\n padding: '28px 20px 24px',\n background: 'transparent',\n }}\n >\n <div\n style={{\n maxWidth: 760,\n margin: '0 auto',\n display: 'flex',\n flexDirection: 'column',\n gap: 18,\n }}\n >\n <Messages messages={message} chatbotName={chatbotName} />\n </div>\n </main>\n\n {/* ======================= INPUT ======================= */}\n <footer\n style={{\n position: 'relative',\n zIndex: 1,\n padding: '16px 20px 22px',\n background: 'linear-gradient(180deg, rgba(245,241,232,0) 0%, var(--assistly-paper) 30%)',\n borderTop: '1px solid var(--assistly-hairline)',\n }}\n >\n <Form {...form}>\n <form\n onSubmit={form.handleSubmit(onsubmit)}\n style={{\n maxWidth: 760,\n margin: '0 auto',\n display: 'flex',\n alignItems: 'flex-end',\n gap: 10,\n }}\n >\n <FormField\n control={form.control}\n name=\"message\"\n render={({ field }) => (\n <FormItem style={{ flex: 1, margin: 0 }}>\n <FormControl>\n <div\n style={{\n position: 'relative',\n background: '#fffefb',\n border: '1px solid var(--assistly-hairline-strong)',\n borderRadius: 14,\n boxShadow: '0 1px 0 rgba(26,20,15,0.02), 0 6px 18px rgba(26,20,15,0.04)',\n transition: 'border-color 180ms ease, box-shadow 180ms ease',\n }}\n >\n <Input\n {...field}\n placeholder={\n onboardingStep === 1\n ? 'Your name…'\n : onboardingStep === 2\n ? 'Your email…'\n : 'Write a message…'\n }\n style={{\n width: '100%',\n padding: '14px 16px',\n fontSize: 15,\n lineHeight: 1.5,\n color: 'var(--assistly-ink)',\n background: 'transparent',\n border: 'none',\n outline: 'none',\n fontFamily: 'inherit',\n borderRadius: 14,\n }}\n onFocus={(e) => {\n const wrap = e.currentTarget.parentElement as HTMLElement;\n wrap.style.borderColor = 'var(--assistly-brass)';\n wrap.style.boxShadow = '0 0 0 3px rgba(184,137,58,0.18), 0 6px 18px rgba(26,20,15,0.04)';\n }}\n onBlur={(e) => {\n const wrap = e.currentTarget.parentElement as HTMLElement;\n wrap.style.borderColor = 'var(--assistly-hairline-strong)';\n wrap.style.boxShadow = '0 1px 0 rgba(26,20,15,0.02), 0 6px 18px rgba(26,20,15,0.04)';\n }}\n />\n </div>\n </FormControl>\n </FormItem>\n )}\n />\n\n <button\n type=\"submit\"\n disabled={form.formState.isSubmitting || !form.formState.isValid || loading}\n className=\"assistly-send\"\n aria-label=\"Send message\"\n style={{\n width: 52,\n height: 52,\n borderRadius: 14,\n border: 'none',\n cursor: 'pointer',\n display: 'grid',\n placeItems: 'center',\n flexShrink: 0,\n }}\n >\n {loading ? (\n <span\n style={{\n width: 18,\n height: 18,\n border: '2px solid rgba(245,241,232,0.35)',\n borderTopColor: 'var(--assistly-paper)',\n borderRadius: '50%',\n animation: 'assistly-spin 0.9s linear infinite',\n display: 'inline-block',\n }}\n />\n ) : (\n <Send size={18} strokeWidth={2} />\n )}\n </button>\n </form>\n </Form>\n <span\n className=\"assistly-font-mono\"\n style={{\n display: 'block',\n maxWidth: 760,\n margin: '10px auto 0',\n fontSize: 10,\n letterSpacing: '0.16em',\n textTransform: 'uppercase',\n color: 'var(--assistly-ink-mute)',\n textAlign: 'center',\n }}\n >\n <ArrowUpRight size={10} strokeWidth={1.8} style={{ verticalAlign: '-1px', marginRight: 4 }} />\n Powered by Assistly\n </span>\n <style>{`@keyframes assistly-spin { to { transform: rotate(360deg); } }`}</style>\n </footer>\n </div>\n );\n}\n\nexport default ChatbotClient;\n","async function startNewChat(\n origin: string,\n guestName: string,\n guestEmail: string,\n chatbotId: number,\n): Promise<number> {\n const baseUrl = origin.replace(/\\/$/, '');\n const response = await fetch(`${baseUrl}/api/start-chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name: guestName,\n email: guestEmail,\n chatbot_id: chatbotId,\n }),\n });\n\n if (!response.ok) {\n const payload = await response.json().catch(() => null);\n const message =\n payload?.error ?? `Failed to start chat (${response.status})`;\n throw new Error(message);\n }\n\n const data = await response.json();\n if (typeof data?.chat_session_id !== 'number') {\n throw new Error('Server returned an invalid response');\n }\n return data.chat_session_id;\n}\n\nexport default startNewChat;\n","import { gql } from \"@apollo/client\";\n\nexport const GET_MESSEGES_BY_CHAT_SESSION_ID = gql`\n query GetMessagesByChatSessionId($chat_session_id: Int!) {\n chat_sessions(id: $chat_session_id) {\n created_at\n id\n messages {\n id\n sender\n content\n created_at\n }\n }\n }\n`;\n","'use client';\n\nimport { Message } from \"../types\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { UserCircle } from \"lucide-react\";\nimport React, { useEffect, useRef, useState } from \"react\";\n\n/* -------------------------------------------------------------------------- */\n/* Small helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction formatTime(iso: string) {\n try {\n const d = new Date(iso);\n return d.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n } catch {\n return \"\";\n }\n}\n\nfunction TypewriterMarkdown({\n text,\n isFresh,\n components,\n onType,\n}: {\n text: string;\n isFresh: boolean;\n components: any;\n onType?: () => void;\n}) {\n const [displayedText, setDisplayedText] = useState(\"\");\n const [index, setIndex] = useState(0);\n\n useEffect(() => {\n setDisplayedText(\"\");\n setIndex(0);\n }, [text]);\n\n useEffect(() => {\n if (isFresh && text && index < text.length) {\n const timeout = setTimeout(() => {\n setDisplayedText((prev) => prev + text[index]);\n setIndex((prev) => prev + 1);\n if (onType) onType();\n }, 14);\n return () => clearTimeout(timeout);\n } else if (!isFresh) {\n setDisplayedText(text || \"\");\n }\n }, [index, text, isFresh]);\n\n const showCaret = isFresh && index < text.length;\n return (\n <span className={showCaret ? 'assistly-caret' : undefined}>\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>\n {isFresh ? displayedText : text}\n </ReactMarkdown>\n </span>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------------- */\n\nfunction Messages({\n messages,\n chatbotName,\n isReviewPage = false,\n}: {\n messages: Message[];\n chatbotName: string;\n isReviewPage?: boolean;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const [hoveredId, setHoveredId] = useState<number | string | null>(null);\n\n const scrollToBottom = (smooth = true) => {\n if (ref.current) {\n ref.current.scrollIntoView({ behavior: smooth ? \"smooth\" : \"auto\", block: \"end\" });\n }\n };\n\n useEffect(() => {\n scrollToBottom();\n }, [messages]);\n\n const markdownComponents = {\n ul: ({ node, ...props }: any) => <ul {...props} />,\n ol: ({ node, ...props }: any) => <ol {...props} />,\n a: ({ node, ...props }: any) => <a rel=\"noopener noreferrer\" target=\"_blank\" {...props} />,\n };\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>\n {messages.map((message, index) => {\n const isSender = message.sender !== \"user\";\n const isThinking = message.content === \"\" || message.content === \"Thinking...\";\n const isFresh = index === messages.length - 1;\n const showMeta = hoveredId === message.id || isReviewPage;\n\n return (\n <div\n key={message.id || index}\n onMouseEnter={() => setHoveredId(message.id)}\n onMouseLeave={() => setHoveredId(null)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: isSender ? 'flex-start' : 'flex-end',\n maxWidth: '100%',\n }}\n >\n {/* ----- Header row: avatar + name + meta ----- */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n marginBottom: 8,\n padding: isSender ? '0 4px' : '0 4px',\n flexDirection: isSender ? 'row' : 'row-reverse',\n }}\n >\n <div\n style={{\n width: 26,\n height: 26,\n borderRadius: '50%',\n background: isSender\n ? 'var(--assistly-paper-2)'\n : 'var(--assistly-ink)',\n color: isSender ? 'var(--assistly-ink)' : 'var(--assistly-paper)',\n border: '1px solid var(--assistly-hairline-strong)',\n display: 'grid',\n placeItems: 'center',\n flexShrink: 0,\n }}\n aria-hidden\n >\n {isSender ? (\n <span\n style={{\n fontFamily: 'Fraunces, Georgia, serif',\n fontSize: 13,\n fontWeight: 600,\n lineHeight: 1,\n }}\n >\n {chatbotName.charAt(0).toUpperCase()}\n </span>\n ) : (\n <UserCircle size={14} strokeWidth={1.6} />\n )}\n </div>\n <div\n className=\"assistly-font-mono\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 10,\n letterSpacing: '0.18em',\n textTransform: 'uppercase',\n color: 'var(--assistly-ink-mute)',\n }}\n >\n <span style={{ color: 'var(--assistly-ink-soft)', fontWeight: 500 }}>\n {isSender ? chatbotName || 'assistant' : 'you'}\n </span>\n <span\n style={{\n width: 3,\n height: 3,\n borderRadius: '50%',\n background: 'var(--assistly-ink-mute)',\n opacity: showMeta ? 1 : 0,\n transition: 'opacity 200ms',\n }}\n />\n <span style={{ opacity: showMeta ? 1 : 0, transition: 'opacity 200ms' }}>\n {formatTime(message.created_at)}\n </span>\n </div>\n </div>\n\n {/* ----- Bubble ----- */}\n <div\n className={`${isSender ? 'assistly-bubble-in' : ''}`}\n style={{\n position: 'relative',\n maxWidth: 'min(82%, 640px)',\n padding: '12px 16px',\n borderRadius: isSender ? '4px 16px 16px 16px' : '16px 4px 16px 16px',\n background: isSender ? '#fffefb' : 'var(--assistly-ink)',\n color: isSender ? 'var(--assistly-ink)' : 'var(--assistly-paper)',\n border: isSender\n ? '1px solid var(--assistly-hairline-strong)'\n : '1px solid var(--assistly-ink)',\n boxShadow: isSender\n ? '0 1px 0 rgba(26,20,15,0.02), 0 8px 24px rgba(26,20,15,0.05)'\n : '0 1px 0 rgba(255,255,255,0.04) inset, 0 8px 24px rgba(26,20,15,0.18)',\n fontSize: 15,\n lineHeight: 1.6,\n }}\n >\n {isThinking ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '2px 0',\n minHeight: 22,\n }}\n >\n <span className=\"assistly-dot\" />\n <span className=\"assistly-dot\" />\n <span className=\"assistly-dot\" />\n <span className=\"assistly-dot\" />\n <span\n className=\"assistly-font-mono\"\n style={{\n marginLeft: 4,\n fontSize: 10,\n letterSpacing: '0.22em',\n textTransform: 'uppercase',\n color: 'var(--assistly-ink-mute)',\n }}\n >\n Thinking…\n </span>\n </div>\n ) : isSender ? (\n <div className=\"assistly-prose\">\n <TypewriterMarkdown\n text={message.content}\n isFresh={isFresh}\n components={markdownComponents}\n onType={() => scrollToBottom(false)}\n />\n </div>\n ) : (\n <div className=\"assistly-prose\">\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={markdownComponents}>\n {message.content}\n </ReactMarkdown>\n </div>\n )}\n </div>\n </div>\n );\n })}\n <div ref={ref} />\n </div>\n );\n}\n\nexport default Messages;\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport {\n Controller,\n FormProvider,\n useFormContext,\n useFormState,\n type ControllerProps,\n type FieldPath,\n type FieldValues,\n} from \"react-hook-form\"\n\nimport { cn } from \"../lib/utils\"\nimport { Label } from \"./label\"\n\nconst Form = FormProvider\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n name: TName\n}\n\nconst FormFieldContext = React.createContext<FormFieldContextValue>(\n {} as FormFieldContextValue\n)\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n ...props\n}: ControllerProps<TFieldValues, TName>) => {\n return (\n <FormFieldContext.Provider value={{ name: props.name }}>\n <Controller {...props} />\n </FormFieldContext.Provider>\n )\n}\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext)\n const itemContext = React.useContext(FormItemContext)\n const { getFieldState } = useFormContext()\n const formState = useFormState({ name: fieldContext.name })\n const fieldState = getFieldState(fieldContext.name, formState)\n\n if (!fieldContext) {\n throw new Error(\"useFormField should be used within <FormField>\")\n }\n\n const { id } = itemContext\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n }\n}\n\ntype FormItemContextValue = {\n id: string\n}\n\nconst FormItemContext = React.createContext<FormItemContextValue>(\n {} as FormItemContextValue\n)\n\nfunction FormItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const id = React.useId()\n\n return (\n <FormItemContext.Provider value={{ id }}>\n <div\n data-slot=\"form-item\"\n className={cn(\"grid gap-2\", className)}\n {...props}\n />\n </FormItemContext.Provider>\n )\n}\n\nfunction FormLabel({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n const { error, formItemId } = useFormField()\n\n return (\n <Label\n data-slot=\"form-label\"\n data-error={!!error}\n className={cn(\"data-[error=true]:text-destructive\", className)}\n htmlFor={formItemId}\n {...props}\n />\n )\n}\n\nfunction FormControl({ ...props }: React.ComponentProps<typeof Slot>) {\n const { error, formItemId, formDescriptionId, formMessageId } = useFormField()\n\n return (\n <Slot\n data-slot=\"form-control\"\n id={formItemId}\n aria-describedby={\n !error\n ? `${formDescriptionId}`\n : `${formDescriptionId} ${formMessageId}`\n }\n aria-invalid={!!error}\n {...props}\n />\n )\n}\n\nfunction FormDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n const { formDescriptionId } = useFormField()\n\n return (\n <p\n data-slot=\"form-description\"\n id={formDescriptionId}\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction FormMessage({ className, ...props }: React.ComponentProps<\"p\">) {\n const { error, formMessageId } = useFormField()\n const body = error ? String(error?.message ?? \"\") : props.children\n\n if (!body) {\n return null\n }\n\n return (\n <p\n data-slot=\"form-message\"\n id={formMessageId}\n className={cn(\"text-destructive text-sm\", className)}\n {...props}\n >\n {body}\n </p>\n )\n}\n\nexport {\n useFormField,\n Form,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n FormField,\n}\n","import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n","import * as React from \"react\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n","/* Styles are injected once per page. We hash the CSS string and key the\n * <style> tag with `data-assistly-style=\"<hash>\"` so HMR and multiple\n * mounts don't duplicate it. */\n\nlet injected = false;\nlet injectedHash: string | null = null;\n\nfunction hashCss(css: string): string {\n let h = 5381;\n for (let i = 0; i < css.length; i++) {\n h = ((h << 5) + h) ^ css.charCodeAt(i);\n }\n return (h >>> 0).toString(36);\n}\n\nexport function ensureAssistlyStyles(css: string): void {\n if (typeof document === 'undefined') return;\n const h = hashCss(css);\n if (injected && injectedHash === h) return;\n injected = true;\n injectedHash = h;\n\n document.querySelectorAll('style[data-assistly-style]').forEach((el) => el.remove());\n\n const style = document.createElement('style');\n style.setAttribute('data-assistly-style', h);\n style.textContent = css;\n document.head.appendChild(style);\n}\n\n/** Test-only: clear the dedup state so a fresh <style> tag is created\n * on the next call. Do not use in production. */\nexport function __resetAssistlyStylesForTests(): void {\n injected = false;\n injectedHash = null;\n}\n\nlet fontsInjected = false;\nconst FONT_HREF =\n 'https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap';\n\nexport function ensureAssistlyFonts(): void {\n if (typeof document === 'undefined') return;\n if (fontsInjected) return;\n if (document.querySelector('link[data-assistly-fonts]')) {\n fontsInjected = true;\n return;\n }\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = FONT_HREF;\n link.setAttribute('data-assistly-fonts', 'true');\n document.head.appendChild(link);\n fontsInjected = true;\n}\n","/* Assistly embed — base styles\n * ------------------------------------------------------------\n * This file is compiled at build time and injected into the\n * consumer page on mount. It defines the design tokens the\n * React components reference (shadcn-style + custom palette)\n * so the widget renders identically regardless of the host\n * app's Tailwind/theme configuration.\n */\n\n:root {\n /* --- Paper & ink palette --------------------------------- */\n --assistly-paper: #f5f1e8; /* warm bone */\n --assistly-paper-2: #efe9dc; /* slightly deeper bone */\n --assistly-ink: #1a140f; /* near-black, warm */\n --assistly-ink-soft: #3a322a; /* secondary text */\n --assistly-ink-mute: #7a7166; /* tertiary / meta */\n --assistly-hairline: rgba(26, 20, 15, 0.12);\n --assistly-hairline-strong: rgba(26, 20, 15, 0.22);\n\n /* --- Brass accent --------------------------------------- */\n --assistly-brass: #b8893a;\n --assistly-brass-soft: #d4ad6a;\n\n /* --- shadcn aliases consumed by button/input ------------- */\n --background: var(--assistly-paper);\n --foreground: var(--assistly-ink);\n --primary: var(--assistly-ink);\n --primary-foreground: #f5f1e8;\n --secondary: var(--assistly-paper-2);\n --secondary-foreground: var(--assistly-ink);\n --muted: var(--assistly-paper-2);\n --muted-foreground: var(--assistly-ink-mute);\n --accent: var(--assistly-brass-soft);\n --accent-foreground: var(--assistly-ink);\n --destructive: #8a2a2a;\n --border: var(--assistly-hairline-strong);\n --input: var(--assistly-hairline-strong);\n --ring: var(--assistly-brass);\n\n /* --- Component-specific aliases ------------------------- */\n --hairline: var(--assistly-hairline);\n --brass-2: var(--assistly-brass);\n --muted-2: var(--assistly-ink-mute);\n --assistly-primary: var(--assistly-ink);\n}\n\n/* --- Reset inside the widget ----------------------------- */\n.assistly-root,\n.assistly-root * {\n box-sizing: border-box;\n}\n\n.assistly-root {\n font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;\n color: var(--assistly-ink);\n line-height: 1.55;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n}\n\n.assistly-font-display {\n font-family: 'Fraunces', 'Cormorant Garamond', 'Playfair Display', Georgia, serif;\n font-weight: 500;\n letter-spacing: -0.01em;\n font-feature-settings: \"ss01\", \"ss02\";\n}\n\n.assistly-font-mono {\n font-family: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;\n font-feature-settings: \"ss01\", \"cv11\";\n}\n\n/* --- Paper grain overlay --------------------------------- */\n.assistly-grain {\n position: absolute;\n inset: 0;\n pointer-events: none;\n opacity: 0.35;\n mix-blend-mode: multiply;\n background-image: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.10 0 0 0 0 0.08 0 0 0 0 0.06 0 0 0 0.08 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>\");\n}\n\n/* --- Scrollbar ------------------------------------------- */\n.assistly-scroll::-webkit-scrollbar {\n width: 6px;\n}\n.assistly-scroll::-webkit-scrollbar-track {\n background: transparent;\n}\n.assistly-scroll::-webkit-scrollbar-thumb {\n background: var(--assistly-hairline-strong);\n border-radius: 999px;\n}\n.assistly-scroll::-webkit-scrollbar-thumb:hover {\n background: var(--assistly-ink-mute);\n}\n\n/* --- Typing indicator ------------------------------------ */\n.assistly-dot {\n display: inline-block;\n width: 6px;\n height: 6px;\n border-radius: 999px;\n background: var(--assistly-brass);\n animation: assistly-bounce 1.1s cubic-bezier(0.45, 0, 0.55, 1) infinite;\n}\n.assistly-dot:nth-child(2) { animation-delay: 0.12s; background: var(--assistly-ink-soft); }\n.assistly-dot:nth-child(3) { animation-delay: 0.24s; background: var(--assistly-brass-soft); }\n.assistly-dot:nth-child(4) { animation-delay: 0.36s; background: var(--assistly-ink-mute); }\n\n@keyframes assistly-bounce {\n 0%, 60%, 100% { transform: translate3d(0, 0, 0); }\n 30% { transform: translate3d(0, -5px, 0); }\n}\n\n/* --- Bubble entrance ------------------------------------- */\n.assistly-bubble-in {\n animation: assistly-spring 520ms cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n}\n@keyframes assistly-spring {\n 0% { transform: scale(0.94) translate3d(0, 6px, 0); opacity: 0; }\n 60% { transform: scale(1.015) translate3d(0, -1px, 0); opacity: 1; }\n 100% { transform: scale(1) translate3d(0, 0, 0); opacity: 1; }\n}\n\n/* --- Status pulse ---------------------------------------- */\n.assistly-pulse {\n position: relative;\n}\n.assistly-pulse::after {\n content: '';\n position: absolute;\n inset: -3px;\n border-radius: 999px;\n background: #5a8c5a;\n opacity: 0.35;\n animation: assistly-pulse 2.4s ease-out infinite;\n}\n@keyframes assistly-pulse {\n 0% { transform: scale(0.6); opacity: 0.45; }\n 100% { transform: scale(2.2); opacity: 0; }\n}\n\n/* --- Send button hover ----------------------------------- */\n.assistly-send {\n position: relative;\n background: var(--assistly-ink);\n color: var(--assistly-paper);\n transition: transform 180ms ease, background 180ms ease, box-shadow 180ms ease;\n box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset, 0 4px 14px rgba(26,20,15,0.18);\n}\n.assistly-send:hover:not(:disabled) {\n background: var(--assistly-ink-soft);\n transform: translateY(-1px);\n box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset, 0 8px 22px rgba(26,20,15,0.24);\n}\n.assistly-send:active:not(:disabled) {\n transform: translateY(0);\n box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset, 0 2px 8px rgba(26,20,15,0.18);\n}\n.assistly-send:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* --- Markdown content ------------------------------------ */\n.assistly-prose p {\n margin: 0 0 0.6em 0;\n white-space: pre-wrap;\n}\n.assistly-prose p:last-child { margin-bottom: 0; }\n.assistly-prose ul, .assistly-prose ol {\n margin: 0.4em 0 0.6em 1.1em;\n}\n.assistly-prose li { margin-bottom: 0.25em; }\n.assistly-prose code {\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.88em;\n padding: 0.1em 0.35em;\n background: rgba(26, 20, 15, 0.07);\n border-radius: 3px;\n}\n.assistly-prose a {\n color: var(--assistly-brass);\n text-decoration: underline;\n text-underline-offset: 2px;\n font-weight: 500;\n}\n.assistly-prose a:hover { color: var(--assistly-ink); }\n.assistly-prose h1, .assistly-prose h2, .assistly-prose h3 {\n font-family: 'Fraunces', Georgia, serif;\n font-weight: 600;\n margin: 0.6em 0 0.3em 0;\n letter-spacing: -0.01em;\n}\n.assistly-prose h1 { font-size: 1.25em; }\n.assistly-prose h2 { font-size: 1.1em; }\n.assistly-prose h3 { font-size: 1em; }\n.assistly-prose strong { font-weight: 600; }\n\n/* --- Caret for streaming --------------------------------- */\n.assistly-caret::after {\n content: '▍';\n display: inline-block;\n margin-left: 1px;\n color: var(--assistly-brass);\n animation: assistly-blink 1s steps(1) infinite;\n}\n@keyframes assistly-blink {\n 50% { opacity: 0; }\n}\n","/* Imports the raw CSS text as a string at build time. The file uses a\n * custom .tokens extension (not .css) so tsup's postcss plugin never\n * sees it, and esbuild's `text` loader (configured in tsup.config.ts)\n * inlines the file contents as a default-exported string. The CSS is\n * then injected at runtime by `ensureAssistlyStyles` in injectStyles.ts. */\nimport styles from '../styles.tokens';\nexport default styles as string;\n"],"mappings":"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","names":["useEffect","useState","useEffect","useState","React","jsx","jsx","jsx","jsx","jsx","jsxs","useState","useEffect","email","styles_default","jsx","useState","useEffect","styles_default"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaimaababiker/embed",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Embeddable Assistly chatbot as a React component. Drop-in replacement for the iframe-based embed.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,34 +17,40 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "build": "tsup",
20
- "dev": "tsup --watch"
20
+ "dev": "tsup --watch",
21
+ "test": "vitest run"
21
22
  },
22
23
  "peerDependencies": {
23
- "react": "^18.0.0 || ^19.0.0",
24
- "react-dom": "^18.0.0 || ^19.0.0",
25
- "react-markdown": "^10.1.0",
26
- "remark-gfm": "^4.0.1",
27
- "lucide-react": "^0.570.0",
28
24
  "@dicebear/collection": "^9.3.1",
29
25
  "@dicebear/core": "^9.3.1",
26
+ "@hookform/resolvers": "^5.2.2",
30
27
  "@radix-ui/react-label": "^2.1.8",
31
28
  "@radix-ui/react-slot": "^1.2.4",
32
29
  "class-variance-authority": "^0.7.1",
33
30
  "clsx": "^2.1.1",
34
- "tailwind-merge": "^3.4.1",
31
+ "lucide-react": "^0.570.0",
32
+ "react": "^18.0.0 || ^19.0.0",
33
+ "react-dom": "^18.0.0 || ^19.0.0",
35
34
  "react-hook-form": "^7.71.1",
36
- "@hookform/resolvers": "^5.2.2",
35
+ "react-markdown": "^10.1.0",
36
+ "remark-gfm": "^4.0.1",
37
+ "tailwind-merge": "^3.4.1",
37
38
  "zod": "^4.3.6"
38
39
  },
39
40
  "dependencies": {
40
- "@apollo/client": "^3.8.10"
41
+ "@apollo/client": "^3.8.10",
42
+ "@gsap/react": "^2.1.2",
43
+ "gsap": "^3.15.0"
41
44
  },
42
45
  "devDependencies": {
46
+ "@testing-library/react": "^16.1.0",
43
47
  "@types/react": "^19.2.14",
44
48
  "@types/react-dom": "^19.2.3",
49
+ "jsdom": "^25.0.1",
45
50
  "react": "^19.2.4",
46
51
  "react-dom": "^19.2.4",
47
52
  "tsup": "^8.3.5",
48
- "typescript": "^5.9.3"
53
+ "typescript": "^5.9.3",
54
+ "vitest": "^2.1.5"
49
55
  }
50
56
  }