@graph8/sdk 0.5.0 → 0.5.3
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.d.mts +57 -2
- package/dist/index.d.ts +57 -2
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +56 -1
- package/dist/react.d.ts +56 -1
- package/dist/react.js +3 -1
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +3 -1
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react.tsx","../src/core.ts","../src/forms.ts","../src/utils.ts","../src/visitors.ts","../src/copilot.ts","../src/chat.ts","../src/calendar.ts","../src/enrich.ts","../src/sequences.ts","../src/campaigns.ts","../src/integrations.ts","../src/signals.ts","../src/analytics.ts","../src/voice.ts","../src/pages.ts","../src/webhooks.ts","../src/contacts.ts","../src/companies.ts","../src/lists.ts","../src/notes.ts","../src/tasks.ts","../src/fields.ts","../src/deals.ts","../src/inbox.ts","../src/quotes.ts","../src/pipelines.ts","../src/workflows.ts","../src/skills.ts","../src/intent.ts","../src/studio.ts","../src/meetings.ts"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, useEffect, type ReactNode } from \"react\";\nimport { g8 } from \"./core\";\nimport type { G8Config } from \"./types\";\n\nconst G8Context = createContext(g8);\n\ninterface G8ProviderProps {\n /** Your graph8 write key */\n writeKey: string;\n /** Tracking host (default: https://t.graph8.com) */\n host?: string;\n /** Additional config options */\n config?: Partial<Omit<G8Config, \"writeKey\" | \"host\">>;\n children: ReactNode;\n}\n\n/**\n * graph8 React provider. Initializes the SDK once and provides it to all children.\n *\n * Usage:\n * import { G8Provider } from '@graph8/js/react';\n *\n * <G8Provider writeKey=\"your_write_key\">\n * <App />\n * </G8Provider>\n */\nexport const G8Provider = ({\n writeKey,\n host,\n config,\n children,\n}: G8ProviderProps) => {\n useEffect(() => {\n if (!g8.initialized) {\n g8.init({ writeKey, host, ...config });\n }\n }, [writeKey, host, config]);\n\n return <G8Context.Provider value={g8}>{children}</G8Context.Provider>;\n};\n\n/**\n * Hook to access the graph8 SDK from any component.\n *\n * Usage:\n * const { track, identify, page, forms } = useG8();\n * track('button_click', { button: 'cta' });\n */\nexport const useG8 = () => {\n const client = useContext(G8Context);\n return {\n /** Track a custom event */\n track: client.track.bind(client),\n /** Identify a user */\n identify: client.identify.bind(client),\n /** Track a page view */\n page: client.page.bind(client),\n /** Clear user identity */\n reset: client.reset.bind(client),\n /** Progressive form helpers */\n forms: client.forms,\n /** Raw g8 client instance */\n g8: client,\n };\n};\n","import { jitsuAnalytics } from \"@jitsu/js\";\nimport type { AnalyticsInterface } from \"@jitsu/js\";\nimport type { G8Config, TrackProperties, IdentifyProperties } from \"./types\";\nimport { createFormsClient } from \"./forms\";\nimport { createVisitorsClient } from \"./visitors\";\nimport { createCopilotClient } from \"./copilot\";\nimport { createChatClient } from \"./chat\";\nimport { createCalendarClient } from \"./calendar\";\nimport { createEnrichClient } from \"./enrich\";\nimport { createSequencesClient } from \"./sequences\";\nimport { createCampaignsClient } from \"./campaigns\";\nimport { createIntegrationsClient } from \"./integrations\";\nimport { createSignalsClient } from \"./signals\";\nimport { createAnalyticsClient } from \"./analytics\";\nimport { createVoiceClient } from \"./voice\";\nimport { createPagesClient } from \"./pages\";\nimport { createWebhooksClient } from \"./webhooks\";\nimport { createContactsClient } from \"./contacts\";\nimport { createCompaniesClient } from \"./companies\";\nimport { createListsClient } from \"./lists\";\nimport { createNotesClient } from \"./notes\";\nimport { createTasksClient } from \"./tasks\";\nimport { createFieldsClient } from \"./fields\";\nimport { createDealsClient } from \"./deals\";\nimport { createInboxClient } from \"./inbox\";\nimport { createQuotesClient } from \"./quotes\";\nimport { createPipelinesClient } from \"./pipelines\";\nimport { createWorkflowsClient } from \"./workflows\";\nimport { createSkillsClient } from \"./skills\";\nimport { createIntentClient } from \"./intent\";\nimport { createStudioClient } from \"./studio\";\nimport { createMeetingsClient } from \"./meetings\";\nimport { isServer } from \"./utils\";\n\nconst DEFAULT_HOST = \"https://t.graph8.com\";\nconst DEFAULT_API = \"https://be.graph8.com\";\n\n/**\n * graph8 SDK client.\n *\n * Handles event tracking, identity, and progressive forms.\n *\n * Usage:\n * import { g8 } from '@graph8/js';\n * g8.init({ writeKey: 'your_write_key' });\n * g8.track('page_view', { page: '/pricing' });\n * g8.identify('user@acme.com', { name: 'John', company: 'Acme' });\n */\nclass G8 {\n /** @internal */ client: AnalyticsInterface | null = null;\n /** @internal */ config: G8Config | null = null;\n /** @internal */ _forms: ReturnType<typeof createFormsClient> | null = null;\n /** @internal */ _visitors: ReturnType<typeof createVisitorsClient> | null = null;\n /** @internal */ _copilot: ReturnType<typeof createCopilotClient> | null = null;\n /** @internal */ _chat: ReturnType<typeof createChatClient> | null = null;\n /** @internal */ _calendar: ReturnType<typeof createCalendarClient> | null = null;\n /** @internal */ _enrich: ReturnType<typeof createEnrichClient> | null = null;\n /** @internal */ _sequences: ReturnType<typeof createSequencesClient> | null = null;\n /** @internal */ _campaigns: ReturnType<typeof createCampaignsClient> | null = null;\n /** @internal */ _integrations: ReturnType<typeof createIntegrationsClient> | null = null;\n /** @internal */ _signals: ReturnType<typeof createSignalsClient> | null = null;\n /** @internal */ _analytics: ReturnType<typeof createAnalyticsClient> | null = null;\n /** @internal */ _voice: ReturnType<typeof createVoiceClient> | null = null;\n /** @internal */ _pages: ReturnType<typeof createPagesClient> | null = null;\n /** @internal */ _webhooks: ReturnType<typeof createWebhooksClient> | null = null;\n /** @internal */ _contacts: ReturnType<typeof createContactsClient> | null = null;\n /** @internal */ _companies: ReturnType<typeof createCompaniesClient> | null = null;\n /** @internal */ _lists: ReturnType<typeof createListsClient> | null = null;\n /** @internal */ _notes: ReturnType<typeof createNotesClient> | null = null;\n /** @internal */ _tasks: ReturnType<typeof createTasksClient> | null = null;\n /** @internal */ _fields: ReturnType<typeof createFieldsClient> | null = null;\n /** @internal */ _deals: ReturnType<typeof createDealsClient> | null = null;\n /** @internal */ _inbox: ReturnType<typeof createInboxClient> | null = null;\n /** @internal */ _quotes: ReturnType<typeof createQuotesClient> | null = null;\n /** @internal */ _pipelines: ReturnType<typeof createPipelinesClient> | null = null;\n /** @internal */ _workflows: ReturnType<typeof createWorkflowsClient> | null = null;\n /** @internal */ _skills: ReturnType<typeof createSkillsClient> | null = null;\n /** @internal */ _intent: ReturnType<typeof createIntentClient> | null = null;\n /** @internal */ _studio: ReturnType<typeof createStudioClient> | null = null;\n /** @internal */ _meetings: ReturnType<typeof createMeetingsClient> | null = null;\n\n /**\n * Initialize the graph8 SDK. Must be called before any other method.\n * Safe to call on the server (SSR) - becomes a no-op for tracking.\n */\n init(config: G8Config): void {\n this.config = config;\n\n if (!isServer) {\n this.client = jitsuAnalytics({\n host: config.host || DEFAULT_HOST,\n writeKey: config.writeKey || \"\",\n debug: config.debug,\n });\n }\n\n const apiUrl = config.apiUrl || DEFAULT_API;\n const writeKey = config.writeKey || \"\";\n const apiKey = config.apiKey || \"\";\n\n // Public (write key) clients\n if (writeKey) {\n this._forms = createFormsClient(writeKey, apiUrl);\n this._visitors = createVisitorsClient(writeKey, apiUrl);\n this._copilot = createCopilotClient(writeKey, apiUrl);\n this._chat = createChatClient(writeKey, apiUrl);\n this._calendar = createCalendarClient(apiUrl);\n this._signals = createSignalsClient(writeKey, false, apiUrl);\n }\n\n // Private (API key) clients\n if (apiKey) {\n this._enrich = createEnrichClient(apiKey, apiUrl);\n this._sequences = createSequencesClient(apiKey, apiUrl);\n this._campaigns = createCampaignsClient(apiKey, apiUrl);\n this._integrations = createIntegrationsClient(apiKey, apiUrl);\n this._analytics = createAnalyticsClient(apiKey, apiUrl);\n this._voice = createVoiceClient(apiKey, apiUrl);\n this._pages = createPagesClient(apiKey, apiUrl);\n this._webhooks = createWebhooksClient(apiKey, apiUrl);\n this._contacts = createContactsClient(apiKey, apiUrl);\n this._companies = createCompaniesClient(apiKey, apiUrl);\n this._lists = createListsClient(apiKey, apiUrl);\n this._notes = createNotesClient(apiKey, apiUrl);\n this._tasks = createTasksClient(apiKey, apiUrl);\n this._fields = createFieldsClient(apiKey, apiUrl);\n this._deals = createDealsClient(apiKey, apiUrl);\n this._inbox = createInboxClient(apiKey, apiUrl);\n this._quotes = createQuotesClient(apiKey, apiUrl);\n this._pipelines = createPipelinesClient(apiKey, apiUrl);\n this._workflows = createWorkflowsClient(apiKey, apiUrl);\n this._skills = createSkillsClient(apiKey, apiUrl);\n this._intent = createIntentClient(apiKey, apiUrl);\n this._studio = createStudioClient(apiKey, apiUrl);\n this._meetings = createMeetingsClient(apiKey, apiUrl);\n // Override signals with API key version for full access\n this._signals = createSignalsClient(apiKey, true, apiUrl);\n }\n }\n\n // -- Core tracking (via Jitsu) --\n\n /** Track a custom event. */\n track(event: string, properties?: TrackProperties): void { this.client?.track(event, properties); }\n\n /** Identify a user with properties. */\n identify(userId: string, properties?: IdentifyProperties): void { this.client?.identify(userId, properties); }\n\n /** Track a page view. */\n page(properties?: TrackProperties): void { this.client?.page(properties); }\n\n /** Clear user identity (on logout). */\n reset(): void { this.client?.reset(); }\n\n // -- Module accessors --\n\n /** Progressive form helpers. */\n get forms() { this._assertInit(); return this._forms!; }\n\n /** Visitor intelligence - IP to company, engagement scoring. */\n get visitors() { this._assertInit(); return this._visitors!; }\n\n /** AI copilot widget. */\n get copilot() { this._assertInit(); return this._copilot!; }\n\n /** Webchat widget. */\n get chat() { this._assertInit(); return this._chat!; }\n\n /** Calendar and booking. */\n get calendar() { this._assertInit(); return this._calendar!; }\n\n /** Enrichment API (requires API key). */\n get enrich() { this._assertKey(\"enrich\"); return this._enrich!; }\n\n /** Sequences (requires API key). */\n get sequences() { this._assertKey(\"sequences\"); return this._sequences!; }\n\n /** Campaigns (requires API key). */\n get campaigns() { this._assertKey(\"campaigns\"); return this._campaigns!; }\n\n /** CRM integrations (requires API key). */\n get integrations() { this._assertKey(\"integrations\"); return this._integrations!; }\n\n /** Intent signals. */\n get signals() { this._assertInit(); return this._signals!; }\n\n /** Analytics (requires API key). */\n get analytics() { this._assertKey(\"analytics\"); return this._analytics!; }\n\n /** Voice AI (requires API key). */\n get voice() { this._assertKey(\"voice\"); return this._voice!; }\n\n /** Landing pages (requires API key). */\n get pages() { this._assertKey(\"pages\"); return this._pages!; }\n\n /** Webhook event listeners (requires API key). */\n get webhooks() { this._assertKey(\"webhooks\"); return this._webhooks!; }\n\n /** Contacts CRUD (requires API key). */\n get contacts() { this._assertKey(\"contacts\"); return this._contacts!; }\n\n /** Companies CRUD (requires API key). */\n get companies() { this._assertKey(\"companies\"); return this._companies!; }\n\n /** Lists management (requires API key). */\n get lists() { this._assertKey(\"lists\"); return this._lists!; }\n\n /** Notes on contacts (requires API key). */\n get notes() { this._assertKey(\"notes\"); return this._notes!; }\n\n /** Tasks on contacts (requires API key). */\n get tasks() { this._assertKey(\"tasks\"); return this._tasks!; }\n\n /** Custom fields management (requires API key). */\n get fields() { this._assertKey(\"fields\"); return this._fields!; }\n\n /** Deals and pipelines (requires API key). */\n get deals() { this._assertKey(\"deals\"); return this._deals!; }\n\n /** Multi-channel inbox — read + reply across email, SMS, LinkedIn (requires API key). */\n get inbox() { this._assertKey(\"inbox\"); return this._inbox!; }\n\n /** Quote-to-cash: draft, send, sign, payment-link quotes (requires API key). */\n get quotes() { this._assertKey(\"quotes\"); return this._quotes!; }\n\n /** Stage Checklist v2 pipelines: workflow stages with evidence + scripts (requires API key). */\n get pipelines() { this._assertKey(\"pipelines\"); return this._pipelines!; }\n\n /** Workflow builder — multi-node automation graphs with execution lifecycle (requires API key). */\n get workflows() { this._assertKey(\"workflows\"); return this._workflows!; }\n\n /** Skill authoring — LLM and API building blocks that workflows compose (requires API key). */\n get skills() { this._assertKey(\"skills\"); return this._skills!; }\n\n /** Intent tracking — keyword groups, page visitors, account-level intent (requires API key). */\n get intent() { this._assertKey(\"intent\"); return this._intent!; }\n\n /** Studio context — ICPs, personas, brand briefs, intelligence, AI research reports (requires API key). */\n get studio() { this._assertKey(\"studio\"); return this._studio!; }\n\n /** Meetings — read scheduled, completed, cancelled meetings with transcripts + AI analysis (requires API key). */\n get meetings() { this._assertKey(\"meetings\"); return this._meetings!; }\n\n /** Whether the SDK has been initialized. */\n get initialized(): boolean { return this.config !== null; }\n\n /** @internal */\n _assertInit(): void {\n if (!this.config) throw new Error(\"g8.init() must be called first\");\n }\n\n /** @internal */\n _assertKey(module: string): void {\n this._assertInit();\n if (!this.config!.apiKey) throw new Error(`g8.${module} requires an API key. Use g8.init({ apiKey: '...' })`);\n }\n}\n\n/** Singleton g8 client instance. */\nexport const g8 = new G8();\n","import type { EnrichLookupResult } from \"./types\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\n/**\n * Progressive form enrichment - checks what fields graph8 already knows\n * about a contact so your form can skip those fields.\n *\n * Calls POST /api/v1/public/enrich/lookup (authenticated via write key).\n */\nexport const createFormsClient = (writeKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n\n return {\n /**\n * Look up known fields for an email address.\n *\n * Use this in progressive forms: after the user enters their email,\n * check what graph8 already knows and only show missing fields.\n */\n async lookup(email: string): Promise<EnrichLookupResult> {\n const resp = await fetch(`${baseUrl}/api/v1/public/enrich/lookup`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Write-Key\": writeKey,\n },\n body: JSON.stringify({ email }),\n });\n\n if (!resp.ok) {\n return { found: false, known_fields: {}, missing_fields: [] };\n }\n\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","/** Check if running on the server (SSR). */\nexport const isServer = typeof window === \"undefined\";\n\n/** Safely get the window object (returns undefined on server). */\nexport const getWindow = (): Window | undefined =>\n isServer ? undefined : window;\n","import type { G8Config } from \"./types\";\nimport { isServer } from \"./utils\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface VisitorCompany {\n company_name: string | null;\n company_domain: string | null;\n industry: string | null;\n employee_count: string | null;\n city: string | null;\n country: string | null;\n confidence: number;\n}\n\nexport interface VisitorScore {\n engagement: number;\n intent: \"low\" | \"medium\" | \"high\";\n signals: string[];\n}\n\ntype IntentCallback = (visitor: VisitorCompany & VisitorScore) => void;\n\n/**\n * Visitor intelligence - identify anonymous visitors by IP → company.\n *\n * Requires write key auth. Works client-side only.\n */\nexport const createVisitorsClient = (writeKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n let intentInterval: ReturnType<typeof setInterval> | null = null;\n\n const headers = () => ({\n \"Content-Type\": \"application/json\",\n \"X-Write-Key\": writeKey,\n });\n\n return {\n /** Identify the current visitor's company from their IP address. */\n async identify(): Promise<VisitorCompany> {\n if (isServer) return { company_name: null, company_domain: null, industry: null, employee_count: null, city: null, country: null, confidence: 0 };\n\n const resp = await fetch(`${baseUrl}/api/v1/public/visitors/company`, { headers: headers() });\n if (!resp.ok) return { company_name: null, company_domain: null, industry: null, employee_count: null, city: null, country: null, confidence: 0 };\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get engagement score for the current visitor. */\n async score(): Promise<VisitorScore> {\n if (isServer) return { engagement: 0, intent: \"low\", signals: [] };\n\n const resp = await fetch(`${baseUrl}/api/v1/public/visitors/score`, { headers: headers() });\n if (!resp.ok) return { engagement: 0, intent: \"low\", signals: [] };\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Listen for visitors matching an intent level. Polls every 30 seconds. */\n onIntent(level: \"low\" | \"medium\" | \"high\", callback: IntentCallback): () => void {\n if (isServer) return () => {};\n\n const check = async () => {\n try {\n const [company, scoreData] = await Promise.all([\n this.identify(),\n this.score(),\n ]);\n if (scoreData.intent === level || (level === \"medium\" && scoreData.intent === \"high\")) {\n callback({ ...company, ...scoreData });\n }\n } catch { /* silent */ }\n };\n\n check();\n intentInterval = setInterval(check, 30_000);\n\n return () => {\n if (intentInterval) clearInterval(intentInterval);\n };\n },\n };\n};\n","import { isServer } from \"./utils\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface CopilotConfig {\n /** Initial greeting message */\n greeting?: string;\n /** Context passed to the AI */\n context?: Record<string, unknown>;\n /** Widget position */\n position?: \"bottom-right\" | \"bottom-left\";\n /** Widget theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n}\n\ntype CopilotEvent = \"message\" | \"tool_used\" | \"open\" | \"close\" | \"error\";\ntype CopilotCallback = (data: Record<string, unknown>) => void;\ntype ActionHandler = (params: Record<string, unknown>) => void | Promise<void>;\n\n/**\n * Copilot - embeddable AI assistant with org knowledge base access.\n *\n * Client-side (write key) for the widget embed.\n */\nexport const createCopilotClient = (writeKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const listeners: Map<CopilotEvent, CopilotCallback[]> = new Map();\n const actions: Map<string, ActionHandler> = new Map();\n let widgetEl: HTMLElement | null = null;\n\n const emit = (event: CopilotEvent, data: Record<string, unknown> = {}) => {\n listeners.get(event)?.forEach((cb) => cb(data));\n };\n\n return {\n /** Open the copilot widget. */\n open(config?: CopilotConfig): void {\n if (isServer) return;\n\n // Remove existing widget if any\n if (widgetEl) widgetEl.remove();\n\n const position = config?.position || \"bottom-right\";\n const posStyle = position === \"bottom-left\" ? \"left:16px;\" : \"right:16px;\";\n\n const iframe = document.createElement(\"iframe\");\n iframe.src = `${baseUrl}/copilot/embed?write_key=${writeKey}&theme=${config?.theme || \"auto\"}`;\n iframe.style.cssText = `position:fixed;bottom:16px;${posStyle}width:400px;height:600px;border:none;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,0.15);z-index:99998;`;\n iframe.id = \"g8-copilot-widget\";\n\n document.body.appendChild(iframe);\n widgetEl = iframe;\n emit(\"open\");\n },\n\n /** Send a message to the copilot programmatically. */\n async ask(message: string): Promise<string> {\n const resp = await fetch(`${baseUrl}/api/v1/public/copilot/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"X-Write-Key\": writeKey },\n body: JSON.stringify({ message }),\n });\n if (!resp.ok) return \"Sorry, I could not process that request.\";\n const data = await resp.json();\n return data.response || data.data?.response || \"\";\n },\n\n /** Register a custom action the copilot can trigger. */\n registerAction(name: string, handler: ActionHandler): void {\n actions.set(name, handler);\n },\n\n /** Listen for copilot events. */\n on(event: CopilotEvent, callback: CopilotCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n },\n\n /** Close the copilot widget. */\n close(): void {\n if (widgetEl) {\n widgetEl.remove();\n widgetEl = null;\n emit(\"close\");\n }\n },\n };\n};\n","import { isServer } from \"./utils\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface ChatConfig {\n /** Agent ID to connect to */\n agentId?: string;\n /** Pre-filled first message */\n message?: string;\n /** Widget position */\n position?: \"bottom-right\" | \"bottom-left\";\n /** Widget theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Custom greeting */\n greeting?: string;\n /** Custom avatar URL */\n avatar?: string;\n}\n\ntype ChatEvent = \"message\" | \"human_transfer\" | \"open\" | \"close\" | \"error\";\ntype ChatCallback = (data: Record<string, unknown>) => void;\n\n/**\n * Webchat - live chat + AI chat embedded in any app.\n *\n * Uses WebSocket connection to the voice/chat agent backend.\n * Public - no API key needed (org/agent IDs are in the config).\n */\nexport const createChatClient = (writeKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const listeners: Map<ChatEvent, ChatCallback[]> = new Map();\n let widgetEl: HTMLElement | null = null;\n let ws: WebSocket | null = null;\n\n const emit = (event: ChatEvent, data: Record<string, unknown> = {}) => {\n listeners.get(event)?.forEach((cb) => cb(data));\n };\n\n return {\n /** Open the chat widget. */\n open(config?: ChatConfig): void {\n if (isServer) return;\n\n if (widgetEl) widgetEl.remove();\n\n const position = config?.position || \"bottom-right\";\n const posStyle = position === \"bottom-left\" ? \"left:16px;\" : \"right:16px;\";\n\n const iframe = document.createElement(\"iframe\");\n iframe.src = `${baseUrl}/webchat/embed?write_key=${writeKey}&theme=${config?.theme || \"auto\"}`;\n iframe.style.cssText = `position:fixed;bottom:16px;${posStyle}width:380px;height:560px;border:none;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,0.15);z-index:99997;`;\n iframe.id = \"g8-chat-widget\";\n\n document.body.appendChild(iframe);\n widgetEl = iframe;\n emit(\"open\");\n },\n\n /** Send a message. */\n send(message: string): void {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: \"message\", content: message }));\n }\n },\n\n /** Listen for chat events. */\n on(event: ChatEvent, callback: ChatCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n },\n\n /** Configure the chat appearance. */\n configure(config: Partial<ChatConfig>): void {\n // Send config to iframe via postMessage\n if (widgetEl && widgetEl instanceof HTMLIFrameElement) {\n widgetEl.contentWindow?.postMessage({ type: \"g8_chat_config\", config }, \"*\");\n }\n },\n\n /** Close the chat widget. */\n close(): void {\n if (ws) { ws.close(); ws = null; }\n if (widgetEl) { widgetEl.remove(); widgetEl = null; }\n emit(\"close\");\n },\n };\n};\n","import { isServer } from \"./utils\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface CalendarConfig {\n /** Event type slug (e.g. \"demo-30min\") */\n eventType: string;\n /** Username of the host */\n username: string;\n /** Pre-fill attendee info */\n prefill?: { name?: string; email?: string; notes?: string };\n}\n\nexport interface TimeSlot {\n start: string;\n end: string;\n available: boolean;\n}\n\nexport interface Booking {\n uid: string;\n confirmation_url: string;\n start_time: string;\n end_time: string;\n}\n\nexport interface BookingRequest {\n event_type_id: number;\n slot: string;\n attendee: { name: string; email: string; notes?: string };\n}\n\ntype CalendarEvent = \"booked\" | \"cancelled\" | \"slot_selected\";\ntype CalendarCallback = (data: Record<string, unknown>) => void;\n\n/**\n * Calendar and booking - show scheduling widgets, get slots, book meetings.\n *\n * Public endpoints - no API key needed.\n */\nexport const createCalendarClient = (apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const listeners: Map<CalendarEvent, CalendarCallback[]> = new Map();\n\n return {\n /** Show a booking modal overlay. */\n show(config: CalendarConfig): void {\n if (isServer) return;\n\n const url = `${baseUrl}/appointments/${config.username}/${config.eventType}`;\n const params = new URLSearchParams();\n if (config.prefill?.name) params.set(\"name\", config.prefill.name);\n if (config.prefill?.email) params.set(\"email\", config.prefill.email);\n\n const iframe = document.createElement(\"iframe\");\n iframe.src = `${url}?${params.toString()}`;\n iframe.style.cssText = \"position:fixed;top:0;left:0;width:100%;height:100%;border:none;z-index:99999;background:rgba(0,0,0,0.5);\";\n iframe.id = \"g8-calendar-modal\";\n document.body.appendChild(iframe);\n\n // Close on escape\n const onKey = (e: KeyboardEvent) => { if (e.key === \"Escape\") { iframe.remove(); document.removeEventListener(\"keydown\", onKey); } };\n document.addEventListener(\"keydown\", onKey);\n },\n\n /** Embed booking widget inline in a container element. */\n embed(selector: string, config: CalendarConfig): void {\n if (isServer) return;\n\n const container = document.querySelector(selector);\n if (!container) return;\n\n const url = `${baseUrl}/appointments/${config.username}/${config.eventType}`;\n const iframe = document.createElement(\"iframe\");\n iframe.src = url;\n iframe.style.cssText = \"width:100%;min-height:600px;border:none;border-radius:8px;\";\n container.appendChild(iframe);\n },\n\n /** Get available time slots for an event type. */\n async slots(username: string, eventSlug: string, range: { start: string; end: string }): Promise<TimeSlot[]> {\n const params = new URLSearchParams({\n start_date: range.start,\n end_date: range.end,\n });\n const resp = await fetch(`${baseUrl}/appointments/public/slots?username=${username}&event_slug=${eventSlug}&${params.toString()}`);\n if (!resp.ok) return [];\n const data = await resp.json();\n return data.slots || data.data || [];\n },\n\n /** Book a meeting programmatically. */\n async book(request: BookingRequest): Promise<Booking | null> {\n const resp = await fetch(`${baseUrl}/appointments/public/bookings`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n if (!resp.ok) return null;\n const data = await resp.json();\n const emit = listeners.get(\"booked\");\n if (emit) emit.forEach((cb) => cb(data));\n return data;\n },\n\n /** Listen for calendar events. */\n on(event: CalendarEvent, callback: CalendarCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface PersonEnrichment {\n found: boolean;\n confidence: number;\n data: Record<string, unknown>;\n}\n\nexport interface CompanyEnrichment {\n found: boolean;\n confidence: number;\n data: Record<string, unknown>;\n}\n\nexport interface EmailVerification {\n email: string;\n valid: boolean;\n deliverable: boolean;\n catch_all: boolean;\n}\n\nexport interface SearchFilter {\n field: string;\n operator: \"any_of\" | \"contains\" | \"all_of\" | \"none_of\" | \"is_empty\" | \"is_not_empty\" | \"between\" | \"exists\";\n value: unknown;\n}\n\nexport interface SearchResults {\n contacts: Record<string, unknown>[];\n total: number;\n page: number;\n}\n\n/**\n * Enrichment API - person/company lookup, email verification, prospecting search.\n *\n * Requires API key (server-side only). Credits charged per call.\n */\nexport const createEnrichClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n\n const headers = () => ({\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n });\n\n return {\n /** Look up a person by email, LinkedIn, or name + company. Costs 1 credit. */\n async person(params: {\n email?: string;\n linkedin_url?: string;\n first_name?: string;\n last_name?: string;\n company_domain?: string;\n }): Promise<PersonEnrichment> {\n const resp = await fetch(`${baseUrl}/api/v1/enrichment/lookup/person`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Look up a company by domain or name. Costs 1 credit. */\n async company(params: { domain?: string; name?: string }): Promise<CompanyEnrichment> {\n const resp = await fetch(`${baseUrl}/api/v1/enrichment/lookup/company`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Verify an email address. Costs 1 credit. */\n async verifyEmail(email: string): Promise<EmailVerification> {\n const resp = await fetch(`${baseUrl}/api/v1/enrichment/verify-email`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ email }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Search 300M+ contacts with filters. Credits charged per result. */\n async search(filters: SearchFilter[], page = 1, limit = 25): Promise<SearchResults> {\n const resp = await fetch(`${baseUrl}/api/v1/search/contacts`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ filters, page, limit }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n// -- Existing types (preserved for backwards compat) --\n\nexport interface Sequence {\n id: string;\n name: string;\n status: string;\n step_count: number | null;\n contact_count: number | null;\n}\n\nexport interface AddToSequenceConfig {\n sequenceId: string;\n contactIds: number[];\n listId: number;\n}\n\n// -- New (0.4.0) types --\n\nexport interface SequenceListItem {\n id: string;\n name: string | null;\n status: string | null;\n user_email: string | null;\n step_count: number | null;\n contact_count: number | null;\n sequence_kind: string | null;\n associated_list_id: number | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface SequenceListParams {\n page?: number;\n limit?: number;\n /** Filter by sequence status (e.g. \"live\", \"draft\", \"paused\"). */\n status?: string;\n}\n\nexport interface SequenceDetail {\n id: string;\n name: string | null;\n description: string | null;\n status: string | null;\n user_email: string | null;\n associated_list_id: number | null;\n finish_on_reply: boolean;\n send_in_same_thread: boolean;\n wait_for_new_contacts: boolean;\n paused_at: string | null;\n resumed_at: string | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface SequenceContactItem {\n id: string | null;\n contact_id: number | null;\n state: string | null;\n current_step_order: number | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface SequenceContactsParams {\n page?: number;\n limit?: number;\n /** Filter by contact state (e.g. \"active\", \"completed\", \"replied\"). */\n state?: string;\n}\n\nexport interface SequenceActionResult {\n sequence_id: string;\n status: string;\n contacts_affected: number;\n}\n\n/**\n * Step type. Note: LinkedIn flows use \"HEYREACH\" — there is no \"LINKEDIN\" step type.\n * Server is case-insensitive on input but stores uppercase.\n */\nexport type SequenceStepType =\n | \"EMAIL\"\n | \"PHONE\"\n | \"SMS\"\n | \"WHATSAPP\"\n | \"HEYREACH\"\n | \"MANUAL_DIALER\";\n\nexport type SequenceStepInputType =\n | \"ON_DEMAND\"\n | \"MANUAL_TEMPLATE\"\n | \"AI_GENERATED_TEMPLATE\";\n\nexport interface SequenceStepConfig {\n step_order: number;\n step_type: SequenceStepType | string;\n /** Defaults to \"ON_DEMAND\". */\n input_type?: SequenceStepInputType | string;\n /** Wait time before this step in seconds. Defaults to 0. */\n time_interval?: number;\n /** Template body, AI prompt, or other step-type-specific config. */\n step_data?: Record<string, unknown>;\n}\n\nexport interface SequenceChannelConfig {\n channel_id: number;\n channel_value: string;\n channel_type: string;\n channel_data?: Record<string, unknown>;\n}\n\nexport interface SequenceCreateParams {\n name: string;\n user_email: string;\n description?: string;\n finish_on_reply?: boolean;\n send_in_same_thread?: boolean;\n wait_for_new_contacts?: boolean;\n associated_list_id?: number;\n steps?: SequenceStepConfig[];\n channels?: SequenceChannelConfig[];\n campaign_id?: string;\n}\n\nexport interface SequenceCreateResult {\n id: string;\n name: string;\n status: string;\n created_at: string | null;\n}\n\nexport interface SequenceUpdateParams {\n name?: string;\n description?: string;\n is_shared?: boolean;\n finish_on_reply?: boolean;\n send_in_same_thread?: boolean;\n wait_for_new_contacts?: boolean;\n schedule_id?: string;\n appointment_id?: number;\n}\n\nexport interface SequenceStepUpdateParams {\n step_data?: Record<string, unknown>;\n time_interval?: number;\n step_type?: SequenceStepType | string;\n input_type?: SequenceStepInputType | string;\n}\n\nexport interface SequencePreviewStep {\n id: string;\n step_order: number;\n step_type: string;\n input_type: string;\n time_interval: number | null;\n step_data: Record<string, unknown> | null;\n}\n\nexport interface SequencePreviewChannel {\n id: string;\n channel_id: number | null;\n channel_value: string | null;\n channel_type: string | null;\n}\n\nexport interface SequencePreview {\n id: string;\n name: string | null;\n status: string | null;\n description: string | null;\n steps: SequencePreviewStep[];\n channels: SequencePreviewChannel[];\n}\n\nexport interface SequenceAnalytics {\n overview: Record<string, unknown>;\n performance: Record<string, unknown>;\n engagement: Record<string, unknown>;\n timeline: Record<string, unknown>[];\n contact_distribution: Record<string, unknown>;\n step_breakdown: Record<string, unknown>[];\n step_creation_methods: Record<string, unknown>[];\n sender_distribution: Record<string, unknown>[];\n}\n\nexport interface PaginationMeta {\n page: number;\n limit: number;\n total: number;\n has_next: boolean;\n}\n\n/**\n * Sequences API — list, create, run, pause, update, analyze multi-channel sequences.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/sequences\n * POST /api/v1/sequences\n * GET /api/v1/sequences/{sequence_id}\n * PATCH /api/v1/sequences/{sequence_id}\n * DELETE /api/v1/sequences/{sequence_id}\n * GET /api/v1/sequences/{sequence_id}/contacts\n * POST /api/v1/sequences/{sequence_id}/contacts\n * POST /api/v1/sequences/{sequence_id}/run\n * POST /api/v1/sequences/{sequence_id}/pause\n * POST /api/v1/sequences/{sequence_id}/resume\n * PATCH /api/v1/sequences/{sequence_id}/steps/{step_id}\n * GET /api/v1/sequences/{sequence_id}/preview\n * GET /api/v1/sequences/{sequence_id}/analytics\n */\nexport const createSequencesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n // -- Overloads on list() preserve backwards compat with v0.3.0's positional signature --\n\n async function list(): Promise<SequenceListItem[]>;\n async function list(page: number, limit?: number): Promise<SequenceListItem[]>;\n async function list(params: SequenceListParams): Promise<SequenceListItem[]>;\n async function list(\n pageOrParams?: number | SequenceListParams,\n limit?: number,\n ): Promise<SequenceListItem[]> {\n let params: SequenceListParams;\n if (typeof pageOrParams === \"number\") {\n params = { page: pageOrParams, limit: limit ?? 50 };\n } else {\n params = pageOrParams ?? {};\n }\n const resp = await fetch(`${baseUrl}/api/v1/sequences${toQuery(params)}`, { headers: headers() });\n const data = await resp.json();\n return (data.data || data) as SequenceListItem[];\n }\n\n return {\n /** List sequences with pagination + optional status filter. */\n list,\n\n /** Get full sequence details by ID. */\n async get(sequenceId: string): Promise<SequenceDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List contacts enrolled in a sequence. Filter by state (e.g. \"active\", \"replied\"). */\n async contacts(\n sequenceId: string,\n params: SequenceContactsParams = {},\n ): Promise<{ data: SequenceContactItem[]; pagination?: PaginationMeta }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/sequences/${sequenceId}/contacts${toQuery(params)}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Add contacts to a sequence (V2 queuing). Live or drafted sequences only. */\n async add(config: AddToSequenceConfig): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${config.sequenceId}/contacts`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ contact_ids: config.contactIds, list_id: config.listId }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a new sequence with optional steps + channels. */\n async create(payload: SequenceCreateParams): Promise<SequenceCreateResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(payload),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update sequence metadata. Rejected (409) if sequence is in a transitional status. */\n async update(sequenceId: string, fields: SequenceUpdateParams): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a single step within a sequence. */\n async updateStep(\n sequenceId: string,\n stepId: string,\n fields: SequenceStepUpdateParams,\n ): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/steps/${stepId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Soft-delete (archive) a sequence. */\n async delete(sequenceId: string): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Run/start a DRAFTED sequence (V2 orchestration). */\n async run(sequenceId: string): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/run`, {\n method: \"POST\",\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Pause a live sequence. */\n async pause(sequenceId: string): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/pause`, {\n method: \"POST\",\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Resume a paused sequence. */\n async resume(sequenceId: string): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/resume`, {\n method: \"POST\",\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Read-only sequence preview with all steps + channels (no enrollment). */\n async preview(sequenceId: string): Promise<SequencePreview> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/preview`, {\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Comprehensive analytics for a sequence. */\n async analytics(sequenceId: string): Promise<SequenceAnalytics> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/analytics`, {\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Campaign {\n id: string;\n name: string;\n slug: string;\n status: string;\n category: string | null;\n goal: string | null;\n target_persona: string | null;\n}\n\nexport interface CampaignCreateConfig {\n name: string;\n category?: string;\n brief?: string;\n core_concept?: string;\n primary_hook?: string;\n target_persona?: string;\n goal?: string;\n}\n\nexport interface CampaignStats {\n sent: number;\n opened: number;\n replied: number;\n meetings: number;\n}\n\n/**\n * Campaigns - create, manage, launch campaigns. Requires API key (server-side).\n */\nexport const createCampaignsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n async list(page = 1, limit = 50): Promise<Campaign[]> {\n const resp = await fetch(`${baseUrl}/api/v1/campaigns?page=${page}&limit=${limit}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n async get(campaignId: string): Promise<Campaign> {\n const resp = await fetch(`${baseUrl}/api/v1/campaigns/${campaignId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n async create(config: CampaignCreateConfig): Promise<Campaign> {\n const resp = await fetch(`${baseUrl}/api/v1/campaigns`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify(config),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n async launch(campaignId: string): Promise<void> {\n await fetch(`${baseUrl}/api/v1/campaigns/${campaignId}/launch`, {\n method: \"POST\", headers: headers(),\n });\n },\n\n async stats(campaignId: string): Promise<CampaignStats> {\n const resp = await fetch(`${baseUrl}/api/v1/campaigns/${campaignId}/stats`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Integration {\n id: string;\n provider: string;\n status: string;\n connected_at: string | null;\n}\n\n/**\n * Integrations - connect CRM platforms, trigger syncs. Requires API key (server-side).\n */\nexport const createIntegrationsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n async list(): Promise<Integration[]> {\n const resp = await fetch(`${baseUrl}/api/v1/integrations`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n async connect(provider: string, config?: Record<string, unknown>): Promise<void> {\n await fetch(`${baseUrl}/api/v1/integrations/connect`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify({ provider, ...config }),\n });\n },\n\n async sync(provider: string, config?: { direction?: \"inbound\" | \"outbound\" | \"bidirectional\" }): Promise<void> {\n await fetch(`${baseUrl}/api/v1/integrations/sync`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify({ provider, ...config }),\n });\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface IntentSignals {\n domain: string;\n score: number;\n intent: \"low\" | \"medium\" | \"high\";\n signals: string[];\n last_seen: string | null;\n}\n\n/**\n * Intent signals - company-level buying signals. Write key for public, API key for full access.\n */\nexport const createSignalsClient = (key: string, isApiKey: boolean, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n\n const headers = (): Record<string, string> => isApiKey\n ? { \"Content-Type\": \"application/json\", \"Authorization\": `Bearer ${key}` }\n : { \"Content-Type\": \"application/json\", \"X-Write-Key\": key };\n\n const endpoint = isApiKey ? \"/api/v1/signals/company\" : \"/api/v1/public/signals/company\";\n\n return {\n /** Get intent signals for a specific company domain. */\n async company(domain: string): Promise<IntentSignals> {\n const resp = await fetch(`${baseUrl}${endpoint}?domain=${encodeURIComponent(domain)}`, { headers: headers() });\n if (!resp.ok) return { domain, score: 0, intent: \"low\", signals: [], last_seen: null };\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Stream intent signals - calls callback every 30s with latest data. */\n stream(domains: string[], callback: (signals: IntentSignals[]) => void): () => void {\n const check = async () => {\n try {\n const results = await Promise.all(domains.map((d) => this.company(d)));\n callback(results);\n } catch { /* silent */ }\n };\n\n check();\n const interval = setInterval(check, 30_000);\n return () => clearInterval(interval);\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface AnalyticsOverview {\n visitors: number;\n contacts_created: number;\n emails_sent: number;\n emails_opened: number;\n replies: number;\n meetings_booked: number;\n period: string;\n}\n\n/**\n * Analytics - dashboard data and metrics. Requires API key (server-side).\n */\nexport const createAnalyticsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n async overview(config?: { period?: string; metrics?: string[] }): Promise<AnalyticsOverview> {\n const params = new URLSearchParams();\n if (config?.period) params.set(\"period\", config.period);\n const resp = await fetch(`${baseUrl}/api/v1/analytics/overview?${params.toString()}`, { headers: headers() });\n if (!resp.ok) return { visitors: 0, contacts_created: 0, emails_sent: 0, emails_opened: 0, replies: 0, meetings_booked: 0, period: config?.period || \"30d\" };\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n// -- Existing (preview) types — preserved for backwards compat with v0.3.0 --\n\nexport interface VoiceSession {\n id: string;\n status: string;\n agent: string;\n started_at: string;\n}\n\nexport interface CallAnalysis {\n duration_seconds: number;\n sentiment: \"positive\" | \"neutral\" | \"negative\";\n summary: string;\n next_steps: string[];\n objections: string[];\n transcript: Array<{ speaker: string; text: string; timestamp: number }>;\n}\n\ntype VoiceEvent = \"connected\" | \"transcription\" | \"ended\" | \"error\";\ntype VoiceCallback = (data: Record<string, unknown>) => void;\n\n// -- New (0.4.0) dialer types — backed by /api/v1/voice/dialer/* --\n\nexport interface VoicePagination {\n total_items: number;\n total_pages: number;\n current_page: number;\n page_size: number;\n}\n\nexport interface DialerSessionSummary {\n session_id: string;\n status: string | null;\n user_id: string | null;\n user_email: string | null;\n org_id: string | null;\n from_phone: string | null;\n campaign_id: string | null;\n campaign_builder_campaign_id: string | null;\n name: string | null;\n session_metadata: Record<string, unknown> | null;\n total_calls: number | null;\n created_at: string | null;\n updated_at: string | null;\n contact_ids: unknown[];\n}\n\nexport interface DialerSessionsListResult {\n sessions: DialerSessionSummary[];\n pagination: VoicePagination;\n}\n\nexport interface DialerSessionsListParams {\n page?: number;\n /** Default 50, max 200. */\n page_size?: number;\n /** Comma-separated status list (e.g. \"ACTIVE,PAUSED\"). */\n status?: string;\n user_email?: string;\n /** Substring search on session name. */\n name?: string;\n campaign_id?: string;\n list_id?: string;\n list_name?: string;\n /** ISO 8601 timestamp. */\n date_from?: string;\n /** ISO 8601 timestamp. */\n date_to?: string;\n sort_by?: string;\n /** Default \"desc\". */\n sort_order?: \"asc\" | \"desc\";\n}\n\nexport interface DialerStatsParams {\n session_id?: string;\n user_email?: string;\n /** YYYY-MM-DD. */\n date_from?: string;\n /** YYYY-MM-DD. */\n date_to?: string;\n /** Default \"DAILY\". */\n aggregation?: \"DAILY\" | \"TOTAL\";\n}\n\nexport interface DialerReportFilters {\n session_id: string | null;\n user_email: string | null;\n org_id: string | null;\n date_from: string | null;\n date_to: string | null;\n aggregation: string | null;\n}\n\nexport interface DialerReportMetric {\n date: string | null;\n sdr_name: string | null;\n org_id: string | null;\n list_title: string | null;\n total_dials: number;\n total_connections: number;\n connection_rate: number;\n total_voicemails: number;\n voicemail_rate: number;\n talk_time_minutes: number;\n avg_call_duration_minutes: number;\n dispositions: Record<string, unknown> | null;\n success_rate: number;\n unique_sessions: number;\n avg_calls_per_session: number;\n redial_count: number;\n redial_success_rate: number | null;\n peak_calling_hour: number | null;\n total_callbacks: number;\n}\n\nexport interface DialerStatsResult {\n filters: DialerReportFilters;\n metrics: DialerReportMetric[];\n summary: DialerReportMetric | null;\n}\n\nexport interface DialerNumberInfo {\n number: string;\n /** Default \"ai\". */\n inbound_type: string;\n /** Default \"twilio\". */\n telephony_provider: string;\n calls_today: number;\n calls_7d: number;\n connect_rate_7d: number;\n is_valid: boolean;\n daily_limit: number;\n assigned_to: string | null;\n created_at: string | null;\n}\n\nexport interface DialerNumbersListResult {\n numbers: DialerNumberInfo[];\n}\n\nexport interface MissedCallback {\n id: string | number | null;\n caller_phone: string | null;\n inbound_number: string | null;\n first_name: string | null;\n last_name: string | null;\n email: string | null;\n contact_id: string | number | null;\n parallel_session_id: string | null;\n created_at: string | null;\n call_duration: number | null;\n is_callback: boolean;\n}\n\nexport interface MissedCallbacksResult {\n missed_callbacks: MissedCallback[];\n count: number;\n}\n\nexport interface CallGradingResult {\n room_name: string;\n /** \"ready\" or \"pending\". */\n status: string;\n grading: Record<string, unknown> | null;\n reviewed: boolean;\n reviewed_at: string | null;\n}\n\nexport interface DialerAgentSummary {\n agent_id: string;\n agent_name: string | null;\n /** \"SDR\", etc. */\n role: string | null;\n agent_status: string | null;\n /** \"agent\" or \"twin\". */\n entity_type: string | null;\n description: string | null;\n phone: string | null;\n is_template: boolean;\n}\n\nexport interface DialerAgentsListResult {\n agents: DialerAgentSummary[];\n total_count: number;\n}\n\nexport interface DialerAgentsListParams {\n /** e.g. \"SDR\". */\n role?: string;\n agent_status?: string;\n /** \"agent\" or \"twin\". */\n entity_type?: \"agent\" | \"twin\";\n /** Substring filter on name/description. */\n search?: string;\n}\n\nexport interface DialerSessionCreateParams {\n /** 1-200 chars. */\n name: string;\n /** Org's dialer phone (E.164, 9-16 chars). */\n from_phone: string;\n /** Contact list ID (stored in session metadata). */\n list_id?: string;\n /** Display title for the source list. */\n list_title?: string;\n /** V2 agent UUID. */\n agent_id?: string;\n /** V1 fallback name. Defaults to \"default_agent\". */\n agent_name?: string;\n /** \"agent\" or \"twin\". */\n entity_type?: \"agent\" | \"twin\";\n /** Campaign Builder UUID. */\n studio_campaign_id?: string;\n /** IANA timezone (e.g. \"America/New_York\"). */\n user_timezone?: string;\n /** Per-session voicemail-skip override. null/omit = use SDR default. */\n skip_voicemails?: boolean;\n}\n\nexport interface DialerSessionCreateResult {\n session_id: string;\n status: string;\n name: string | null;\n org_id: string | null;\n user_id: string | null;\n user_email: string | null;\n from_phone: string | null;\n session_metadata: Record<string, unknown> | null;\n total_calls: number;\n created_at: string | null;\n message: string | null;\n}\n\n/** \"ACTIVE\" resumes, \"PAUSED\" pauses, \"COMPLETED\" stops. \"FAILED\" is rejected. */\nexport type DialerSessionStatus = \"ACTIVE\" | \"PAUSED\" | \"COMPLETED\";\n\nexport interface DialerSessionStatusUpdateResult {\n session_id: string;\n status: string;\n message: string | null;\n name: string | null;\n org_id: string | null;\n user_id: string | null;\n user_email: string | null;\n from_phone: string | null;\n session_metadata: Record<string, unknown> | null;\n total_calls: number;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface DialerSessionResumeResult extends DialerSessionStatusUpdateResult {\n /** Contacts actually placed in this batch (voice caps at 4). */\n dialed_count: number;\n}\n\n/**\n * Voice AI — start AI voice calls, get transcriptions and analysis.\n * Plus full parallel-dialer session control via the `dialer` namespace.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/voice/dialer/sessions\n * POST /api/v1/voice/dialer/sessions\n * PATCH /api/v1/voice/dialer/sessions/{session_id}/status\n * POST /api/v1/voice/dialer/sessions/{session_id}/resume\n * GET /api/v1/voice/dialer/stats\n * GET /api/v1/voice/dialer/numbers\n * GET /api/v1/voice/dialer/missed-callbacks\n * GET /api/v1/voice/dialer/calls/{room_name}/grading\n * GET /api/v1/voice/dialer/agents\n */\nexport const createVoiceClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n const listeners: Map<VoiceEvent, VoiceCallback[]> = new Map();\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n const dialer = {\n /** List parallel-dialer sessions with filters + pagination. */\n async listSessions(params: DialerSessionsListParams = {}): Promise<DialerSessionsListResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/sessions${toQuery(params)}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a parallel-dialer session in PAUSED state. SDR opens UI to start dialing. */\n async createSession(payload: DialerSessionCreateParams): Promise<DialerSessionCreateResult> {\n const resp = await fetch(`${baseUrl}/api/v1/voice/dialer/sessions`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(payload),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Pause / resume / stop a dialer session via status flip. */\n async updateSessionStatus(\n sessionId: string,\n status: DialerSessionStatus,\n ): Promise<DialerSessionStatusUpdateResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/sessions/${sessionId}/status`,\n {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify({ status }),\n },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /**\n * Resume a PAUSED dialer session. Auto-fetches the next batch from the source list,\n * filters already-called + phoneless rows, and forwards to voice's start-session.\n * @param maxContacts 1-4 (voice caps parallel dialing at 4). Default 4.\n */\n async resumeSession(sessionId: string, maxContacts = 4): Promise<DialerSessionResumeResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/sessions/${sessionId}/resume`,\n {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ max_contacts: maxContacts }),\n },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Aggregated dialer analytics (daily breakdown or total). */\n async stats(params: DialerStatsParams = {}): Promise<DialerStatsResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/stats${toQuery(params)}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List dialer-eligible phone numbers with 7-day stats + daily limits. */\n async numbers(userEmail?: string): Promise<DialerNumbersListResult> {\n const params = userEmail ? { user_email: userEmail } : {};\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/numbers${toQuery(params)}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List missed inbound callbacks with caller / contact info. */\n async missedCallbacks(limit = 50): Promise<MissedCallbacksResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/missed-callbacks${toQuery({ limit })}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** AI grading for a single dialer call (returns \"pending\" while in progress). */\n async callGrading(roomName: string): Promise<CallGradingResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls/${encodeURIComponent(roomName)}/grading`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List voice agents available for dialer sessions (capped at 100; no pagination). */\n async agents(params: DialerAgentsListParams = {}): Promise<DialerAgentsListResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/agents${toQuery(params)}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Fetch the full transcript for a single dialer call. */\n async callTranscript(roomName: string): Promise<{ data: { status: string; transcript: Array<{ speaker: string; text: string; timestamp: number }> } }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls/${encodeURIComponent(roomName)}/transcript`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** List dialer calls — pass `contact_id` or `user_email` to scope. */\n async listCalls(params: { contact_id?: number; user_email?: string; campaign_id?: string; date_from?: string; date_to?: string; limit?: number; page?: number } = {}): Promise<{ data: Array<Record<string, unknown>>; pagination?: VoicePagination }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls${toQuery(params)}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Convenience: list calls for a single contact. */\n async listCallsForContact(contactId: number, extra: { limit?: number } = {}): Promise<{ data: Array<Record<string, unknown>> }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls${toQuery({ contact_id: contactId, ...extra })}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Convenience: list calls placed by a specific SDR. */\n async listCallsForSdr(userEmail: string, extra: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: Array<Record<string, unknown>> }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls${toQuery({ user_email: userEmail, ...extra })}`,\n { headers: headers() },\n );\n return resp.json();\n },\n };\n\n return {\n /**\n * Start an AI voice session.\n * @deprecated Preview surface — for parallel-dialer flows use `voice.dialer.createSession()`.\n */\n async start(config: { agent?: string; contactId?: number; context?: Record<string, unknown> }): Promise<VoiceSession> {\n const resp = await fetch(`${baseUrl}/api/v1/voice/sessions`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify(config),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /**\n * Get call analysis for a completed session.\n * @deprecated Preview surface — for dialer-call grading use `voice.dialer.callGrading(roomName)`.\n */\n async analysis(sessionId: string): Promise<CallAnalysis> {\n const resp = await fetch(`${baseUrl}/api/v1/voice/sessions/${sessionId}/analysis`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Listen for voice events. */\n on(event: VoiceEvent, callback: VoiceCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n },\n\n /** Parallel-dialer session control + analytics. */\n dialer,\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface LandingPage {\n id: string;\n title: string;\n slug: string;\n status: string;\n published_url: string | null;\n}\n\n/**\n * Landing pages - clone, create, publish. Requires API key (server-side).\n */\nexport const createPagesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n /** Clone a landing page from any URL. */\n async clone(url: string): Promise<LandingPage> {\n const resp = await fetch(`${baseUrl}/api/v1/landing-pages/clone-url`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify({ url }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a landing page from a template. */\n async create(config: { template?: string; title?: string; content?: Record<string, unknown> }): Promise<LandingPage> {\n const resp = await fetch(`${baseUrl}/api/v1/landing-pages`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify(config),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Publish a landing page to CDN. */\n async publish(pageId: string): Promise<{ url: string }> {\n const resp = await fetch(`${baseUrl}/api/v1/landing-pages/${pageId}/publish`, {\n method: \"POST\", headers: headers(),\n });\n const data = await resp.json();\n return { url: data.published_url || data.data?.published_url || \"\" };\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport type WebhookEvent =\n | \"reply_received\"\n | \"meeting_booked\"\n | \"contact_enriched\"\n | \"contact_created\"\n | \"sequence_completed\"\n | \"sequence_replied\"\n | \"campaign_launched\"\n | \"form_submitted\"\n | \"visitor_identified\";\n\ntype WebhookCallback = (data: Record<string, unknown>) => void;\n\n/**\n * Webhooks - listen for graph8 events. Requires API key (server-side).\n *\n * For client-side real-time events, use g8.visitors.onIntent() or g8.chat.on() instead.\n */\nexport const createWebhooksClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n const listeners: Map<WebhookEvent, WebhookCallback[]> = new Map();\n let polling = false;\n let pollInterval: ReturnType<typeof setInterval> | null = null;\n\n return {\n /** Register a listener for a webhook event. Starts polling automatically. */\n on(event: WebhookEvent, callback: WebhookCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n\n // Start polling if not already\n if (!polling) {\n polling = true;\n pollInterval = setInterval(async () => {\n try {\n const resp = await fetch(`${baseUrl}/api/v1/webhooks/events?since=30s`, { headers: headers() });\n if (!resp.ok) return;\n const data = await resp.json();\n const events = data.data || data || [];\n for (const evt of events) {\n const cbs = listeners.get(evt.type as WebhookEvent);\n if (cbs) cbs.forEach((cb) => cb(evt));\n }\n } catch { /* silent */ }\n }, 30_000);\n }\n },\n\n /** Stop all webhook polling. */\n stop(): void {\n if (pollInterval) clearInterval(pollInterval);\n polling = false;\n listeners.clear();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Contact {\n id: number;\n first_name: string | null;\n last_name: string | null;\n work_email: string | null;\n job_title: string | null;\n seniority_level: string | null;\n company_name: string | null;\n company_domain: string | null;\n linkedin_url: string | null;\n direct_phone: string | null;\n mobile_phone: string | null;\n city: string | null;\n state: string | null;\n country: string | null;\n}\n\nexport interface ContactListParams {\n page?: number;\n limit?: number;\n email?: string;\n name?: string;\n job_title?: string;\n seniority_level?: string;\n company_name?: string;\n country?: string;\n list_id?: number;\n}\n\nexport interface ContactCreateParams {\n work_email: string;\n first_name?: string;\n last_name?: string;\n job_title?: string;\n company_domain?: string;\n linkedin_url?: string;\n direct_phone?: string;\n mobile_phone?: string;\n city?: string;\n state?: string;\n country?: string;\n list_id?: number;\n}\n\nexport interface ContactUpdateParams {\n first_name?: string;\n last_name?: string;\n work_email?: string;\n job_title?: string;\n company_domain?: string;\n linkedin_url?: string;\n direct_phone?: string;\n mobile_phone?: string;\n city?: string;\n state?: string;\n country?: string;\n}\n\n/** A column definition on contacts (base or custom). */\nexport interface ContactColumn {\n id: number | null;\n title: string;\n data_type: string;\n name: string | null;\n /** Stringified list_id when list-scoped, otherwise null/empty for global. */\n object_id: string | null;\n is_global: boolean;\n}\n\nexport interface ContactColumnCreateParams {\n title: string;\n /** Email of the user creating the column. Required by the backend (audit). */\n created_by: string;\n /** \"text\" (default) — additional types may be added later. */\n data_type?: string;\n /** If set, the column is list-specific. Omit for org-wide global column. */\n list_id?: number;\n}\n\n/**\n * Contacts API - full CRUD for CRM contacts. Requires API key (server-side).\n */\nexport const createContactsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List contacts with optional filters. */\n async list(params: ContactListParams = {}): Promise<{ data: Contact[]; total: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a single contact by ID. */\n async get(contactId: number): Promise<Contact> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a new contact. */\n async create(contact: ContactCreateParams): Promise<Contact> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(contact),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a contact (partial). */\n async update(contactId: number, fields: ContactUpdateParams): Promise<{ updated: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n return resp.json();\n },\n\n /** Delete a contact (soft-delete). */\n async delete(contactId: number): Promise<{ deleted: boolean }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** List custom contact columns. Pass listId to include list-specific columns. */\n async listColumns(listId?: number): Promise<{ data: ContactColumn[] }> {\n const qs = listId != null ? `?list_id=${listId}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/contacts/columns${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a custom contact column. Global if list_id is omitted, list-scoped otherwise. */\n async createColumn(params: ContactColumnCreateParams): Promise<ContactColumn> {\n const body = {\n title: params.title,\n data_type: params.data_type || \"text\",\n list_id: params.list_id ?? null,\n created_by: params.created_by,\n };\n const resp = await fetch(`${baseUrl}/api/v1/contacts/columns/create`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Company {\n id: number;\n name: string | null;\n domain: string | null;\n industry: string | null;\n employee_count: number | null;\n revenue: number | null;\n founded_year: number | null;\n description: string | null;\n linkedin_url: string | null;\n country: string | null;\n state: string | null;\n city: string | null;\n}\n\nexport interface CompanyListParams {\n page?: number;\n limit?: number;\n domain?: string;\n industry?: string;\n name?: string;\n country?: string;\n}\n\nexport interface CompanyUpdateParams {\n name?: string;\n domain?: string;\n industry?: string;\n description?: string;\n linkedin_url?: string;\n country?: string;\n state?: string;\n city?: string;\n}\n\nexport interface CompanyContact {\n id: number;\n first_name: string | null;\n last_name: string | null;\n work_email: string | null;\n job_title: string | null;\n}\n\n/** A column definition on companies (base or custom). */\nexport interface CompanyColumn {\n id: number | null;\n title: string;\n data_type: string;\n name: string | null;\n /** Stringified list_id when list-scoped, otherwise null/empty for global. */\n object_id: string | null;\n is_global: boolean;\n}\n\nexport interface CompanyColumnCreateParams {\n title: string;\n /** Email of the user creating the column. Required by the backend (audit). */\n created_by: string;\n /** \"text\" (default) — additional types may be added later. */\n data_type?: string;\n /** If set, the column is list-specific. Omit for org-wide global column. */\n list_id?: number;\n}\n\n/**\n * Companies API - search and manage CRM companies. Requires API key (server-side).\n */\nexport const createCompaniesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List companies with optional filters. */\n async list(params: CompanyListParams = {}): Promise<{ data: Company[]; total: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a single company by ID. */\n async get(companyId: number): Promise<Company> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get contacts belonging to a company. */\n async contacts(companyId: number, limit = 50, offset = 0): Promise<{ data: CompanyContact[]; total: number }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/companies/${companyId}/contacts?limit=${limit}&offset=${offset}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Update a company (partial). */\n async update(companyId: number, fields: CompanyUpdateParams): Promise<{ updated: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n return resp.json();\n },\n\n /** Delete a company (soft-delete). */\n async delete(companyId: number): Promise<{ deleted: boolean }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** List custom company columns. Pass listId to include list-specific columns. */\n async listColumns(listId?: number): Promise<{ data: CompanyColumn[] }> {\n const qs = listId != null ? `?list_id=${listId}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/companies/columns${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a custom company column. Global if list_id is omitted, list-scoped otherwise. */\n async createColumn(params: CompanyColumnCreateParams): Promise<CompanyColumn> {\n const body = {\n title: params.title,\n data_type: params.data_type || \"text\",\n list_id: params.list_id ?? null,\n created_by: params.created_by,\n };\n const resp = await fetch(`${baseUrl}/api/v1/companies/columns/create`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface ContactList {\n id: number;\n title: string;\n type: \"contacts\" | \"companies\";\n contact_count: number | null;\n created_at: string | null;\n}\n\nexport interface ListContact {\n id: number;\n first_name: string | null;\n last_name: string | null;\n work_email: string | null;\n job_title: string | null;\n company_name: string | null;\n}\n\n/**\n * Lists API - manage contact and company lists. Requires API key (server-side).\n */\nexport const createListsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n /** List all lists. */\n async list(page = 1, limit = 50): Promise<{ data: ContactList[]; total: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/lists?page=${page}&limit=${limit}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a new list. */\n async create(title: string, type: \"contacts\" | \"companies\" = \"contacts\"): Promise<ContactList> {\n const resp = await fetch(`${baseUrl}/api/v1/lists`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ title, type }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a list (soft-delete). */\n async delete(listId: number): Promise<{ deleted: boolean }> {\n const resp = await fetch(`${baseUrl}/api/v1/lists/${listId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Get contacts in a list. */\n async contacts(listId: number, page = 1, limit = 50): Promise<{ data: ListContact[]; total: number }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/lists/${listId}/contacts?page=${page}&limit=${limit}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Add contacts to a list. */\n async addContacts(listId: number, contactIds: number[]): Promise<{ added: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/lists/${listId}/contacts`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ contact_ids: contactIds }),\n });\n return resp.json();\n },\n\n /** Remove contacts from a list. */\n async removeContacts(listId: number, contactIds: number[]): Promise<{ removed: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/lists/${listId}/contacts`, {\n method: \"DELETE\",\n headers: headers(),\n body: JSON.stringify({ contact_ids: contactIds }),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Note {\n id: string;\n entity_type: string;\n entity_id: string;\n content: string;\n created_by: string | null;\n created_by_name: string | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\n/**\n * Notes API - CRUD for notes attached to contacts. Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/contacts/{contact_id}/notes\n * POST /api/v1/contacts/{contact_id}/notes\n * PATCH /api/v1/notes/{note_id}\n * DELETE /api/v1/notes/{note_id}\n */\nexport const createNotesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n /** List all notes on a contact. */\n async list(contactId: number): Promise<{ data: Note[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/notes`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a note on a contact. */\n async create(contactId: number, content: string): Promise<Note> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/notes`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ content }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a note's content. */\n async update(noteId: string, content: string): Promise<Note> {\n const resp = await fetch(`${baseUrl}/api/v1/notes/${noteId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify({ content }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a note. */\n async delete(noteId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/notes/${noteId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Task {\n id: string;\n entity_type: string | null;\n entity_id: string | null;\n title: string;\n description: string | null;\n due_date: string | null;\n assignee_id: string | null;\n assignee_name: string | null;\n /** \"open\" | \"completed\" (other values may appear if the backend adds states later) */\n status: string | null;\n /** 0=none, 1=urgent, 2=high, 3=normal, 4=low */\n priority: number | null;\n task_type: string | null;\n created_by: string | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface TaskCreateParams {\n title: string;\n description?: string;\n /** ISO 8601 date string. */\n due_date?: string;\n assignee_id?: string;\n /** 0=none, 1=urgent, 2=high, 3=normal, 4=low */\n priority?: number;\n}\n\nexport interface TaskUpdateParams {\n title?: string;\n description?: string;\n due_date?: string;\n assignee_id?: string;\n /** \"open\" | \"completed\" */\n status?: string;\n priority?: number;\n}\n\nexport interface TaskListParams {\n /** \"open\" | \"completed\" */\n status?: string;\n /** 0-4 */\n priority?: number;\n assignee_id?: string;\n /** Substring search on title. */\n search?: string;\n}\n\n/**\n * Tasks API - CRUD for tasks attached to contacts. Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/contacts/{contact_id}/tasks\n * GET /api/v1/tasks\n * POST /api/v1/contacts/{contact_id}/tasks\n * PATCH /api/v1/tasks/{task_id}\n * DELETE /api/v1/tasks/{task_id}\n */\nexport const createTasksClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List tasks on a single contact. Optional status filter (\"open\" | \"completed\"). */\n async listForContact(contactId: number, status?: string): Promise<{ data: Task[] }> {\n const qs = status ? `?status=${encodeURIComponent(status)}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/tasks${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** List all tasks org-wide with optional filters. */\n async list(params: TaskListParams = {}): Promise<{ data: Task[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/tasks${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a task on a contact. */\n async create(contactId: number, task: TaskCreateParams): Promise<Task> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/tasks`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(task),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a task (partial). */\n async update(taskId: string, fields: TaskUpdateParams): Promise<Task> {\n const resp = await fetch(`${baseUrl}/api/v1/tasks/${taskId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a task. */\n async delete(taskId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/tasks/${taskId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n/** A field (column) definition on contacts or companies — base or custom. */\nexport interface Field {\n id: number | null;\n title: string;\n /** Internal column name (slug). */\n name: string | null;\n /** Currently only \"text\" is supported; other types may be added later. */\n data_type: string;\n /** True if available org-wide, false if list-specific. */\n is_global: boolean;\n}\n\n/** Created custom field (column). */\nexport interface CreatedField {\n id: number;\n title: string;\n data_type: string;\n name: string;\n list_id: number | null;\n is_global: boolean;\n}\n\nexport interface FieldCreateParams {\n title: string;\n /** \"contacts\" or \"companies\". Defaults to \"contacts\" on the backend. */\n entity?: \"contacts\" | \"companies\";\n /** \"text\" (default) — additional types may be added later. */\n data_type?: string;\n /** If set, the field is list-specific. Omit for org-wide global field. */\n list_id?: number;\n}\n\nexport interface FieldDeleteParams {\n entity?: \"contacts\" | \"companies\";\n /**\n * Optional list scope guard. If provided, the column must belong to this\n * list or the request returns 404. Use this to prevent accidentally\n * deleting a column on a different list in the same org.\n */\n list_id?: number;\n}\n\nexport interface SetFieldValueParams {\n /** Contact ID (entity='contacts') or company ID (entity='companies'). */\n record_id: number;\n /** Value to write. Pass null/undefined to clear the field. */\n value?: string | null;\n entity?: \"contacts\" | \"companies\";\n}\n\n/**\n * Fields API - manage custom fields (columns) on contacts and companies.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/fields — list contact fields\n * GET /api/v1/fields/companies — list company fields\n * POST /api/v1/fields — create a custom field\n * DELETE /api/v1/fields/{column_id} — delete a custom field\n * PATCH /api/v1/fields/{column_id}/values — set value on a single record\n */\nexport const createFieldsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List contact fields (base + custom). Pass listId to include list-specific custom fields. */\n async listContactFields(listId?: number): Promise<{ data: Field[] }> {\n const qs = listId != null ? `?list_id=${listId}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/fields${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** List company fields (base + custom). Pass listId to include list-specific custom fields. */\n async listCompanyFields(listId?: number): Promise<{ data: Field[] }> {\n const qs = listId != null ? `?list_id=${listId}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/fields/companies${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a custom field on contacts (default) or companies. */\n async create(params: FieldCreateParams): Promise<CreatedField> {\n const body = {\n title: params.title,\n data_type: params.data_type || \"text\",\n list_id: params.list_id ?? null,\n entity: params.entity || \"contacts\",\n };\n const resp = await fetch(`${baseUrl}/api/v1/fields`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a custom field (soft-delete). Pass list_id to scope-guard against cross-list deletion. */\n async delete(columnId: number, params: FieldDeleteParams = {}): Promise<{ data: { column_id: number; deleted: boolean } }> {\n const queryParams: Record<string, string | number> = { entity: params.entity || \"contacts\" };\n if (params.list_id != null) queryParams.list_id = params.list_id;\n const resp = await fetch(`${baseUrl}/api/v1/fields/${columnId}${toQuery(queryParams)}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Set a custom field value on a single contact or company row. Pass value=null to clear. */\n async setValue(\n columnId: number,\n params: SetFieldValueParams,\n ): Promise<{ data: { column_id: number; record_id: number; updated: boolean } }> {\n const body = {\n record_id: params.record_id,\n value: params.value ?? null,\n entity: params.entity || \"contacts\",\n };\n const resp = await fetch(`${baseUrl}/api/v1/fields/${columnId}/values`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Deal {\n id: string | null;\n name: string | null;\n description: string | null;\n amount: number | null;\n currency: string | null;\n stage_id: string | null;\n stage_name: string | null;\n pipeline_id: string | null;\n /** Linked company ID (mashup_company_id), if any. */\n company_id: number | string | null;\n owner_id: string | null;\n /** ISO 8601 date. */\n close_date: string | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface DealCreateParams {\n name: string;\n /** Linked company ID. */\n company_id?: number;\n description?: string;\n amount?: number;\n /** Default: \"USD\". */\n currency?: string;\n /** Stage ID from the org's pipelines. Defaults to first stage of default pipeline if omitted. */\n stage_id?: string;\n /** Pipeline ID. Defaults to org's default pipeline if omitted. */\n pipeline_id?: string;\n /** ISO 8601 close date. */\n close_date?: string;\n}\n\nexport interface DealUpdateParams {\n name?: string;\n description?: string;\n amount?: number;\n currency?: string;\n stage_id?: string;\n /** ISO 8601 close date. */\n close_date?: string;\n}\n\nexport interface DealListParams {\n page?: number;\n limit?: number;\n stage_id?: string;\n pipeline_id?: string;\n /** Substring search on deal name. */\n search?: string;\n}\n\nexport interface PipelineStage {\n id: string;\n name: string;\n probability: number | null;\n position: number | null;\n stage_type: string | null;\n color: string | null;\n required_elements: string[];\n recommended_elements: string[];\n channel_scripts: Record<string, string>;\n}\n\nexport interface Pipeline {\n id: string;\n name: string;\n is_default: boolean;\n stages: PipelineStage[];\n}\n\n/** Trimmed deal shape returned by /contacts/{id}/deals and /companies/{id}/deals. */\nexport interface ContactDeal {\n deal_id: string | null;\n name: string | null;\n stage: string | null;\n value: number | null;\n currency: string | null;\n role: string | null;\n pipeline_id: string | null;\n close_date: string | null;\n owner_id: string | null;\n created_at: string | null;\n}\n\nexport interface PaginationMeta {\n page: number;\n limit: number;\n total: number;\n has_next: boolean;\n}\n\n/**\n * Deals API - CRUD for deals + pipelines. Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/deals/pipelines\n * GET /api/v1/deals\n * POST /api/v1/deals\n * GET /api/v1/deals/{deal_id}\n * PATCH /api/v1/deals/{deal_id}\n * DELETE /api/v1/deals/{deal_id}\n * GET /api/v1/contacts/{contact_id}/deals\n * GET /api/v1/companies/{company_id}/deals\n */\nexport const createDealsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List all deal pipelines and their stages. */\n async pipelines(): Promise<{ data: Pipeline[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/deals/pipelines`, { headers: headers() });\n return resp.json();\n },\n\n /** List deals org-wide with optional filters and pagination. */\n async list(params: DealListParams = {}): Promise<{ data: Deal[]; pagination?: PaginationMeta }> {\n const resp = await fetch(`${baseUrl}/api/v1/deals${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a new deal. */\n async create(deal: DealCreateParams): Promise<Deal> {\n const resp = await fetch(`${baseUrl}/api/v1/deals`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(deal),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get a single deal by ID. */\n async get(dealId: string): Promise<Deal> {\n const resp = await fetch(`${baseUrl}/api/v1/deals/${dealId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a deal (partial). */\n async update(dealId: string, fields: DealUpdateParams): Promise<Deal> {\n const resp = await fetch(`${baseUrl}/api/v1/deals/${dealId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a deal. */\n async delete(dealId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/deals/${dealId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Get all deals associated with a contact. */\n async forContact(contactId: number): Promise<{ data: ContactDeal[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/deals`, { headers: headers() });\n return resp.json();\n },\n\n /** Get all deals associated with a company. */\n async forCompany(companyId: number): Promise<{ data: ContactDeal[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}/deals`, { headers: headers() });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n/**\n * Inbox channel — `email`, `sms`, or `linkedin` (HeyReach internally).\n * Defaults to `email` on routes that accept this as a query param.\n */\nexport type InboxChannel = \"email\" | \"sms\" | \"linkedin\";\n\nexport interface InboxContact {\n name?: string | null;\n email?: string | null;\n company?: string | null;\n [key: string]: unknown;\n}\n\nexport interface InboxTag {\n id: string;\n name: string;\n}\n\nexport interface InboxAssignee {\n email: string;\n name?: string | null;\n [key: string]: unknown;\n}\n\nexport interface InboxMessage {\n message_id: string | null;\n from_address: string | null;\n to_addresses: string[];\n content: string | null;\n /** \"USER\", \"AI\", or \"OTHER\". */\n responder: string | null;\n date: string | null;\n is_draft: boolean;\n}\n\nexport interface InboxThread {\n id: string;\n /** \"email\", \"sms\", or \"linkedin\". */\n channel: string;\n subject: string | null;\n contact: InboxContact | null;\n messages: InboxMessage[];\n /** \"open\", \"responded\", \"ai_responded\", etc. */\n status: string | null;\n tags: InboxTag[];\n assignees: InboxAssignee[];\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface InboxListParams {\n channel?: InboxChannel;\n sequence_id?: string;\n /** Filter by thread status (e.g. \"open\", \"responded\", \"ai_responded\"). */\n status?: string;\n /** Filter by assignee email. */\n assignee?: string;\n /** Filter by tag ID. */\n tag?: string;\n page?: number;\n /** Default 50, max 100. */\n page_size?: number;\n}\n\nexport interface InboxAssignResult {\n assigned: boolean;\n assignee: string;\n count: number;\n [key: string]: unknown;\n}\n\nexport interface InboxTagResult {\n tagged: boolean;\n tag_count: number;\n [key: string]: unknown;\n}\n\nexport interface InboxDraft {\n /** HTML body. */\n content: string;\n /** Plain-text alternative, if available. */\n plain_content: string | null;\n /** Credits charged for AI generation. */\n credits_charged: number;\n}\n\nexport interface InboxSendParams {\n body: string;\n channel: InboxChannel;\n subject?: string;\n /** Recipient override — email, phone, or LinkedIn ID. */\n to?: string;\n /** Sender override — mailbox email, Twilio number, or LinkedIn account ID. */\n from_address?: string;\n}\n\nexport interface InboxSendResult {\n message_id: string | null;\n status: string;\n channel: string;\n}\n\n/**\n * Inbox API — read + reply to multi-channel inbox threads (email, SMS, LinkedIn/HeyReach).\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/inbox\n * GET /api/v1/inbox/{reply_id}\n * POST /api/v1/inbox/{reply_id}/assign\n * POST /api/v1/inbox/{reply_id}/tag\n * GET /api/v1/inbox/{reply_id}/draft (charges credits, 402 on insufficient balance)\n * POST /api/v1/inbox/{reply_id}/send\n */\nexport const createInboxClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List inbox threads across email, SMS, and LinkedIn. */\n async list(params: InboxListParams = {}): Promise<{ data: InboxThread[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/inbox${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a single inbox thread. Defaults to email channel. */\n async get(replyId: string, channel: InboxChannel = \"email\"): Promise<InboxThread> {\n const resp = await fetch(\n `${baseUrl}/api/v1/inbox/${replyId}${toQuery({ channel })}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Assign a user to an inbox thread. */\n async assign(\n replyId: string,\n assigneeEmail: string,\n channel: InboxChannel = \"email\",\n ): Promise<InboxAssignResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/inbox/${replyId}/assign${toQuery({ channel })}`,\n {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ assignee_email: assigneeEmail }),\n },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Attach tag IDs to an inbox thread. */\n async tag(\n replyId: string,\n tagIds: string[],\n channel: InboxChannel = \"email\",\n ): Promise<InboxTagResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/inbox/${replyId}/tag${toQuery({ channel })}`,\n {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ tag_ids: tagIds }),\n },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /**\n * Generate an AI draft reply for a thread.\n * Charges credits — server returns 402 if balance is insufficient.\n */\n async draft(replyId: string, channel: InboxChannel = \"email\"): Promise<InboxDraft> {\n const resp = await fetch(\n `${baseUrl}/api/v1/inbox/${replyId}/draft${toQuery({ channel })}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Send a reply through email, SMS, or LinkedIn. */\n async send(replyId: string, payload: InboxSendParams): Promise<InboxSendResult> {\n const resp = await fetch(`${baseUrl}/api/v1/inbox/${replyId}/send`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(payload),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface QuoteLineItem {\n product_id?: string | null;\n name?: string | null;\n description?: string | null;\n quantity: number;\n unit_price: number;\n currency?: string | null;\n recurring?: boolean | null;\n}\n\nexport type QuoteStatus =\n | \"draft\"\n | \"sent\"\n | \"signed\"\n | \"declined\"\n | \"expired\"\n | \"void\";\n\nexport interface QuoteSummary {\n id: string;\n name: string | null;\n status: QuoteStatus;\n total: number | null;\n currency: string | null;\n contact_id: number | null;\n company_id: number | null;\n expires_at: string | null;\n created_at: string | null;\n updated_at: string | null;\n signing_url: string | null;\n payment_link_url: string | null;\n}\n\nexport interface QuoteDetail extends QuoteSummary {\n line_items: QuoteLineItem[];\n notes: string | null;\n recipient_email: string | null;\n signed_at: string | null;\n sent_at: string | null;\n}\n\nexport interface QuoteCreateParams {\n contact_id?: number;\n company_id?: number;\n line_items: QuoteLineItem[];\n currency?: string;\n notes?: string;\n /** ISO 8601 timestamp. */\n expires_at?: string;\n name?: string;\n}\n\nexport interface QuoteUpdateParams {\n line_items?: QuoteLineItem[];\n notes?: string;\n expires_at?: string;\n name?: string;\n}\n\nexport interface QuoteSendParams {\n recipient_email: string;\n /** Whether to attach the signing link. Defaults to true. */\n send_signing_link?: boolean;\n}\n\nexport interface QuoteListParams {\n status?: QuoteStatus;\n contact_id?: number;\n company_id?: number;\n page?: number;\n limit?: number;\n}\n\nexport interface QuotableProduct {\n id: string;\n name: string;\n description: string | null;\n unit_price: number;\n currency: string;\n recurring: boolean;\n}\n\nexport interface QuoteSettings {\n default_currency: string;\n default_tax_rate: number | null;\n payment_providers: string[];\n logo_url: string | null;\n signature_required: boolean;\n}\n\nexport interface PaginationMeta {\n page: number;\n limit: number;\n total: number;\n has_next: boolean;\n}\n\n/**\n * Quotes API - quote-to-cash lifecycle. Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/quotes\n * GET /api/v1/quotes/{id}\n * POST /api/v1/quotes\n * PUT /api/v1/quotes/{id}\n * DELETE /api/v1/quotes/{id}\n * POST /api/v1/quotes/{id}/duplicate\n * POST /api/v1/quotes/{id}/edit-as-draft\n * POST /api/v1/quotes/{id}/send\n * GET /api/v1/quotable-products\n * GET /api/v1/quote-settings\n * GET /api/v1/contacts/{contact_id}/quotes\n * GET /api/v1/companies/{company_id}/quotes\n */\nexport const createQuotesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List quotes org-wide with optional filters and pagination. */\n async list(params: QuoteListParams = {}): Promise<{ data: QuoteSummary[]; pagination?: PaginationMeta }> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get full details for a single quote. */\n async get(quoteId: string): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a new quote from line items. */\n async create(quote: QuoteCreateParams): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(quote),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a draft quote (line items, expiry, notes). */\n async update(quoteId: string, fields: QuoteUpdateParams): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a draft quote (irreversible). */\n async delete(quoteId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Duplicate an existing quote (all line items copied into a new draft). */\n async duplicate(quoteId: string): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/duplicate`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Convert a signed / sent quote back to editable draft state. */\n async editAsDraft(quoteId: string): Promise<{ data: { id: string; status: string } }> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/edit-as-draft`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Send a quote to its recipient via email (with signature + optional payment link). */\n async send(quoteId: string, params: QuoteSendParams): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/send`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List products available for line items. */\n async products(): Promise<{ data: QuotableProduct[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/quotable-products`, { headers: headers() });\n return resp.json();\n },\n\n /** Get org-level quote settings (currency, tax rate, payment providers, logo). */\n async settings(): Promise<QuoteSettings> {\n const resp = await fetch(`${baseUrl}/api/v1/quote-settings`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get all quotes associated with a contact. */\n async forContact(contactId: number): Promise<{ data: QuoteSummary[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/quotes`, { headers: headers() });\n return resp.json();\n },\n\n /** Get all quotes associated with a company. */\n async forCompany(companyId: number): Promise<{ data: QuoteSummary[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}/quotes`, { headers: headers() });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n/**\n * Stage Checklist v2 pipelines. A \"pipeline\" here is a multi-stage workflow\n * (with evidence requirements and per-channel scripts) that lives parallel\n * to deal pipelines. Use `g8.deals.pipelines()` for deal-pipeline reads.\n */\nexport interface StagePipelineStage {\n id: string;\n name: string;\n position: number;\n /** Evidence keys that must be collected before the stage can be marked done. */\n required_elements: string[];\n /** Evidence keys that are recommended but not enforced. */\n recommended_elements: string[];\n /** Channel-specific scripts (call, email, linkedin, etc.). */\n channel_scripts: Record<string, string>;\n color: string | null;\n stage_type: string | null;\n}\n\nexport interface StagePipeline {\n id: string;\n name: string;\n target: string | null;\n is_default: boolean;\n stages: StagePipelineStage[];\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface StagePipelineCreateParams {\n name: string;\n target?: string;\n /** If true, creates an empty pipeline (no default stages). */\n blank?: boolean;\n}\n\nexport interface StagePipelineUpdateParams {\n name?: string;\n target?: string;\n}\n\nexport interface StageCreateParams {\n name: string;\n position?: number;\n required_elements?: string[];\n recommended_elements?: string[];\n channel_scripts?: Record<string, string>;\n color?: string;\n stage_type?: string;\n}\n\nexport interface StageUpdateParams {\n name?: string;\n position?: number;\n required_elements?: string[];\n recommended_elements?: string[];\n channel_scripts?: Record<string, string>;\n color?: string;\n}\n\nexport interface EvidenceKey {\n key: string;\n label: string;\n description: string;\n category: string;\n}\n\nexport interface PipelineSuggestion {\n suggestion_id: string;\n name: string;\n target: string;\n stages: Array<{ name: string; required_elements: string[]; channel_scripts: Record<string, string> }>;\n rationale: string;\n}\n\n/**\n * Stage Checklist Pipelines API - workflow pipelines with evidence + scripts.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/pipelines\n * GET /api/v1/pipelines/{id}\n * GET /api/v1/pipelines/evidence-library\n * POST /api/v1/pipelines\n * PUT /api/v1/pipelines/{id}\n * DELETE /api/v1/pipelines/{id}\n * POST /api/v1/pipelines/{id}/stages\n * PUT /api/v1/pipelines/{id}/stages/{stage_id}\n * DELETE /api/v1/pipelines/{id}/stages/{stage_id}\n * PUT /api/v1/pipelines/{id}/stages/reorder\n * POST /api/v1/pipelines/suggest\n * POST /api/v1/pipelines/from-suggestion\n */\nexport const createPipelinesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n /** List all stage-checklist pipelines with stages, evidence, scripts. */\n async list(): Promise<{ data: StagePipeline[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a single pipeline by ID. */\n async get(pipelineId: string): Promise<StagePipeline> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get the canonical evidence-key library (used when defining stages). */\n async evidenceLibrary(): Promise<{ data: EvidenceKey[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/evidence-library`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a new pipeline. Defaults to a templated set of stages; pass blank=true for empty. */\n async create(params: StagePipelineCreateParams): Promise<StagePipeline> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update pipeline metadata (name, target). */\n async update(pipelineId: string, fields: StagePipelineUpdateParams): Promise<StagePipeline> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a pipeline. Only allowed when no deals reference it. */\n async delete(pipelineId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Add a new stage to a pipeline. */\n async createStage(pipelineId: string, stage: StageCreateParams): Promise<StagePipelineStage> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(stage),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a stage (evidence, scripts, position). */\n async updateStage(pipelineId: string, stageId: string, fields: StageUpdateParams): Promise<StagePipelineStage> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/${stageId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Reorder stages within a pipeline (pass full ordered list of stage IDs). */\n async reorderStages(pipelineId: string, stageIds: string[]): Promise<{ data: StagePipelineStage[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/reorder`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify({ stage_ids: stageIds }),\n });\n return resp.json();\n },\n\n /** Delete a stage from a pipeline. */\n async deleteStage(pipelineId: string, stageId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/${stageId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Get an AI-suggested pipeline based on org context (brand, ICP, messaging). */\n async suggest(): Promise<{ data: PipelineSuggestion }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/suggest`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Create a real pipeline from an AI suggestion (optionally with overrides). */\n async fromSuggestion(\n suggestionId: string,\n overrides?: Partial<{ name: string; target: string }>,\n ): Promise<StagePipeline> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/from-suggestion`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ suggestion_id: suggestionId, ...(overrides || {}) }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface WorkflowNode {\n id: string;\n type: string;\n config: Record<string, unknown>;\n position?: { x: number; y: number };\n /** Mapping from this node's output to the next node's input. */\n input_mappings?: Record<string, string>;\n}\n\nexport interface WorkflowConnection {\n from_node_id: string;\n to_node_id: string;\n condition?: string | null;\n}\n\nexport interface WorkflowConfig {\n nodes: WorkflowNode[];\n connections: WorkflowConnection[];\n trigger?: Record<string, unknown> | null;\n}\n\nexport interface Workflow {\n id: string;\n name: string;\n description: string | null;\n config: WorkflowConfig;\n trigger_config: Record<string, unknown> | null;\n is_active: boolean;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface WorkflowCreateParams {\n name: string;\n description?: string;\n config?: WorkflowConfig;\n trigger_config?: Record<string, unknown>;\n}\n\nexport interface WorkflowUpdateParams {\n name?: string;\n description?: string;\n config?: WorkflowConfig;\n trigger_config?: Record<string, unknown>;\n is_active?: boolean;\n}\n\nexport interface WorkflowExecution {\n id: string;\n workflow_id: string;\n status: \"pending\" | \"running\" | \"paused\" | \"completed\" | \"failed\" | \"stopped\";\n trigger_payload: Record<string, unknown>;\n outputs: Record<string, unknown>;\n error: string | null;\n started_at: string | null;\n ended_at: string | null;\n}\n\nexport interface NodeTypeSchema {\n type: string;\n label: string;\n description: string;\n config_schema: Record<string, unknown>;\n output_schema: Record<string, unknown>;\n}\n\nexport interface WorkflowListParams {\n page?: number;\n limit?: number;\n is_active?: boolean;\n search?: string;\n}\n\n/**\n * Workflows API - automation workflows with nodes, connections, and execution lifecycle.\n * Requires API key (server-side).\n *\n * The graph8 workflow surface treats the whole workflow definition as a single\n * record updated via `update()` — there are no per-node CRUD endpoints. To edit\n * nodes or connections, fetch the workflow, mutate `config.nodes` / `config.connections`,\n * and PUT it back.\n *\n * Backed by:\n * GET /api/v1/workflows\n * GET /api/v1/workflows/{id}\n * POST /api/v1/workflows\n * PUT /api/v1/workflows/{id}\n * DELETE /api/v1/workflows/{id}\n * POST /api/v1/workflows/validate\n * POST /api/v1/workflows/{id}/execute\n * GET /api/v1/workflows/executions/{exec_id}\n * POST /api/v1/workflows/executions/{exec_id}/pause\n * POST /api/v1/workflows/executions/{exec_id}/resume\n * POST /api/v1/workflows/executions/{exec_id}/stop\n * GET /api/v1/workflows/{id}/trigger-status\n * POST /api/v1/workflows/{id}/trigger-reset\n * GET /api/v1/workflows/node-types/schema\n * GET /api/v1/workflows/integrations/slack/users|channels\n * GET /api/v1/workflows/integrations/roam/users|groups\n * GET /api/v1/workflows/mcp-servers\n * GET /api/v1/workflows/dispositions\n * GET /api/v1/workflows/forms/{form_id}/fields\n */\nexport const createWorkflowsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List workflows org-wide. */\n async list(params: WorkflowListParams = {}): Promise<{ data: Workflow[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get full workflow definition (nodes, connections, trigger, execution state). */\n async get(workflowId: string): Promise<Workflow> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a new workflow. */\n async create(params: WorkflowCreateParams): Promise<Workflow> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /**\n * Update a workflow. Pass the full `config` (nodes + connections) to edit\n * the graph — node-level CRUD is performed client-side by mutating the\n * config and submitting the updated record.\n */\n async update(workflowId: string, fields: WorkflowUpdateParams): Promise<Workflow> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a workflow. */\n async delete(workflowId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Validate a workflow definition (orphans, dangling connections, required fields). */\n async validate(workflow: { config: WorkflowConfig; trigger_config?: Record<string, unknown> }): Promise<{\n data: { valid: boolean; errors: Array<{ node_id?: string; field?: string; message: string }> };\n }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/validate`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(workflow),\n });\n return resp.json();\n },\n\n /** Execute a workflow immediately with a trigger payload. */\n async execute(workflowId: string, triggerPayload: Record<string, unknown> = {}): Promise<WorkflowExecution> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/execute`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ trigger_payload: triggerPayload }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get the status + output of a workflow execution. */\n async getExecution(executionId: string): Promise<WorkflowExecution> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Pause an in-flight execution. */\n async pauseExecution(executionId: string): Promise<{ data: { paused: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/pause`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Resume a paused execution. */\n async resumeExecution(executionId: string): Promise<{ data: { resumed: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/resume`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Stop an execution (terminal state — cannot resume). */\n async stopExecution(executionId: string): Promise<{ data: { stopped: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/stop`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Get the status of a workflow's external trigger (e.g. \"waiting for webhook\"). */\n async getTriggerStatus(workflowId: string): Promise<{ data: { status: string; details: Record<string, unknown> } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/trigger-status`, { headers: headers() });\n return resp.json();\n },\n\n /** Reset the trigger cursor (e.g. for event-stream triggers — resume from beginning). */\n async resetTrigger(workflowId: string): Promise<{ data: { reset: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/trigger-reset`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /**\n * List available node types with schemas. Pass a `type` param to fetch one type's full schema.\n */\n async nodeTypes(params: { type?: string } = {}): Promise<{ data: NodeTypeSchema[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/node-types/schema${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Slack workspace users (for Slack action recipients). */\n async listSlackUsers(): Promise<{ data: Array<{ id: string; name: string; email: string | null }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/slack/users`, { headers: headers() });\n return resp.json();\n },\n\n /** Slack channels. */\n async listSlackChannels(): Promise<{ data: Array<{ id: string; name: string; is_private: boolean }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/slack/channels`, { headers: headers() });\n return resp.json();\n },\n\n /** Roam (Copilot chat) users. */\n async listRoamUsers(): Promise<{ data: Array<{ id: string; name: string; email: string | null }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/roam/users`, { headers: headers() });\n return resp.json();\n },\n\n /** Roam (Copilot chat) groups. */\n async listRoamGroups(): Promise<{ data: Array<{ id: string; name: string }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/roam/groups`, { headers: headers() });\n return resp.json();\n },\n\n /** Available MCP servers (for Agent-node integrations). */\n async listMcpServers(): Promise<{ data: Array<{ id: string; name: string; url: string }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/mcp-servers`, { headers: headers() });\n return resp.json();\n },\n\n /** Available call dispositions (voice workflow nodes). */\n async listDispositions(): Promise<{ data: Array<{ id: string; label: string }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/dispositions`, { headers: headers() });\n return resp.json();\n },\n\n /** Form field schema for form-trigger nodes. */\n async listFormFields(formId: string): Promise<{ data: Array<{ name: string; type: string; required: boolean }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/forms/${formId}/fields`, { headers: headers() });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport type SkillType = \"llm\" | \"api\";\n\nexport interface SkillInputField {\n name: string;\n type: string;\n required: boolean;\n description?: string;\n}\n\nexport interface Skill {\n id: string;\n title: string;\n description: string | null;\n type: SkillType;\n /** Only present on `type=llm`. */\n prompt?: string;\n /** Only present on `type=llm`. */\n model?: string;\n /** Only present on `type=api`. */\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n /** Only present on `type=api`. */\n url?: string;\n /** Only present on `type=api`. */\n headers?: Record<string, string>;\n /** Only present on `type=api`. */\n body_template?: string;\n input_schema: { fields: SkillInputField[] };\n output_schema: Record<string, unknown> | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface SkillCreateLLMParams {\n title: string;\n description?: string;\n prompt: string;\n model: string;\n input_schema: { fields: SkillInputField[] };\n output_schema?: Record<string, unknown>;\n}\n\nexport interface SkillCreateAPIParams {\n title: string;\n description?: string;\n method: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n url: string;\n headers?: Record<string, string>;\n body_template?: string;\n response_mapping?: Record<string, string>;\n input_schema: { fields: SkillInputField[] };\n}\n\nexport interface SkillUpdateLLMParams {\n title?: string;\n description?: string;\n prompt?: string;\n model?: string;\n input_schema?: { fields: SkillInputField[] };\n output_schema?: Record<string, unknown>;\n}\n\nexport interface SkillUpdateAPIParams {\n title?: string;\n description?: string;\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n url?: string;\n headers?: Record<string, string>;\n body_template?: string;\n response_mapping?: Record<string, string>;\n input_schema?: { fields: SkillInputField[] };\n}\n\nexport interface SkillTemplate {\n id: string;\n title: string;\n description: string;\n type: SkillType;\n use_cases: string[];\n}\n\nexport interface SkillListParams {\n page?: number;\n limit?: number;\n type?: SkillType;\n search?: string;\n}\n\n/**\n * Skills API - LLM and API building blocks that workflows compose into runs.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/skills\n * GET /api/v1/skills/{id}\n * GET /api/v1/skills/{id}/variables\n * GET /api/v1/skills/models\n * GET /api/v1/skills/templates\n * POST /api/v1/skills (both llm + api types via `type` field)\n * POST /api/v1/skills/from-template\n * POST /api/v1/skills/from-node\n * PUT /api/v1/skills/{id}\n * DELETE /api/v1/skills/{id}\n * POST /api/v1/skills/validate\n * POST /api/v1/skills/{id}/execute\n */\nexport const createSkillsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List skills. */\n async list(params: SkillListParams = {}): Promise<{ data: Skill[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a skill by ID. */\n async get(skillId: string): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get the variables required by a skill (extracted from prompt or body template). */\n async getVariables(skillId: string): Promise<{ data: SkillInputField[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}/variables`, { headers: headers() });\n return resp.json();\n },\n\n /** List available LLM models. */\n async listModels(): Promise<{ data: Array<{ id: string; label: string; provider: string }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/models`, { headers: headers() });\n return resp.json();\n },\n\n /** List skill templates. */\n async listTemplates(params: { type?: SkillType } = {}): Promise<{ data: SkillTemplate[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/templates${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create an LLM skill (prompt + model + schemas). */\n async createLLM(params: SkillCreateLLMParams): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ ...params, type: \"llm\" }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create an API skill (HTTP request wrapper). */\n async createAPI(params: SkillCreateAPIParams): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ ...params, type: \"api\" }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a skill from a built-in template. */\n async createFromTemplate(params: { title: string; template_id: string; overrides?: Record<string, unknown> }): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/from-template`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Lift a workflow node into a reusable skill. */\n async createFromNode(params: {\n title: string;\n description?: string;\n node_id: string;\n input_mapping?: Record<string, string>;\n output_mapping?: Record<string, string>;\n }): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/from-node`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update an LLM skill. */\n async updateLLM(skillId: string, fields: SkillUpdateLLMParams): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify({ ...fields, type: \"llm\" }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update an API skill. */\n async updateAPI(skillId: string, fields: SkillUpdateAPIParams): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify({ ...fields, type: \"api\" }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a skill (irreversible if in-use workflows exist). */\n async delete(skillId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Validate a skill definition (without saving). */\n async validate(skill: Partial<Skill>): Promise<{ data: { valid: boolean; errors: string[] } }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/validate`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(skill),\n });\n return resp.json();\n },\n\n /** Execute a skill immediately with an input payload (test / preview). */\n async execute(skillId: string, inputPayload: Record<string, unknown>): Promise<{\n data: { output: Record<string, unknown>; latency_ms: number; tokens?: number; error: string | null };\n }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}/execute`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(inputPayload),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface IntentKeyword {\n id: string;\n keyword: string;\n domain: string | null;\n include_patterns: string[];\n exclude_patterns: string[];\n page_count: number;\n visitor_count: number;\n company_count: number;\n contact_count: number;\n created_at: string | null;\n}\n\nexport interface IntentPage {\n url: string;\n title: string | null;\n keyword: string | null;\n domain: string;\n visitor_count: number;\n last_seen: string | null;\n}\n\nexport interface IntentVisitor {\n visitor_id: string;\n company_domain: string | null;\n company_name: string | null;\n page_url: string;\n first_seen: string | null;\n last_seen: string | null;\n visit_count: number;\n}\n\nexport interface IntentCompany {\n domain: string;\n name: string | null;\n industry: string | null;\n employee_count: string | null;\n visit_count: number;\n last_seen: string | null;\n}\n\nexport interface IntentContact {\n contact_id: number | null;\n email: string | null;\n full_name: string | null;\n company: string | null;\n job_title: string | null;\n last_seen: string | null;\n}\n\nexport interface IntentStats {\n total_keywords: number;\n total_pages: number;\n total_visitors_30d: number;\n total_companies_30d: number;\n}\n\n/**\n * Intent + visitor tracking. Distinct from `g8.signals` (which is summary scoring) —\n * this module exposes keyword tracking, page-level visitor data, and account-level\n * intent signals from your own site (or from competitor URLs you've added).\n *\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/intent/stats\n * POST /api/v1/intent/keywords/list\n * POST /api/v1/intent/keywords/create-from-domain\n * DELETE /api/v1/intent/keywords/{keyword_id}\n * POST /api/v1/intent/keywords/{keyword_id}/companies\n * POST /api/v1/intent/keywords/{keyword_id}/contacts\n * POST /api/v1/intent/keywords/{keyword_id}/urls\n * POST /api/v1/intent/pages-by-domain\n * POST /api/v1/intent/pages/search\n * POST /api/v1/intent/pages/visitors\n * POST /api/v1/intent/pages/contacts\n * POST /api/v1/intent/pages/visitor-counts\n * POST /intent-search/url-companies (note: bare host, no /api/v1 prefix)\n */\nexport const createIntentClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const get = async (path: string) => {\n const resp = await fetch(`${baseUrl}/api/v1${path}`, { headers: headers() });\n return resp.json();\n };\n const post = async (path: string, body: Record<string, unknown> = {}) => {\n const resp = await fetch(`${baseUrl}/api/v1${path}`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n return resp.json();\n };\n const del = async (path: string) => {\n const resp = await fetch(`${baseUrl}/api/v1${path}`, { method: \"DELETE\", headers: headers() });\n return resp.json();\n };\n\n return {\n /** Org-level intent stats (totals over the last 30 days). */\n async stats(): Promise<{ data: IntentStats }> {\n return get(\"/intent/stats\");\n },\n\n /** List tracked keywords with optional pagination. */\n async listKeywords(params: { page?: number; limit?: number; search?: string } = {}): Promise<{ data: IntentKeyword[] }> {\n return post(\"/intent/keywords/list\", params);\n },\n\n /** Create a keyword group from a domain (auto-tracks all pages). */\n async createFromDomain(domain: string): Promise<{ data: IntentKeyword }> {\n return post(\"/intent/keywords/create-from-domain\", { domain });\n },\n\n /** Stop tracking a keyword (irreversible — historical data is retained). */\n async deleteKeyword(keywordId: string): Promise<{ data: { deleted: boolean } }> {\n return del(`/intent/keywords/${keywordId}`);\n },\n\n /** Companies showing interest in a tracked keyword. */\n async keywordCompanies(keywordId: string, params: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: IntentCompany[] }> {\n return post(`/intent/keywords/${keywordId}/companies`, params);\n },\n\n /** Contacts showing interest in a tracked keyword. */\n async keywordContacts(keywordId: string, params: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: IntentContact[] }> {\n return post(`/intent/keywords/${keywordId}/contacts`, params);\n },\n\n /** URLs associated with a keyword (pages visitors landed on while interested). */\n async keywordUrls(keywordId: string, params: { limit?: number } = {}): Promise<{ data: IntentPage[] }> {\n return post(`/intent/keywords/${keywordId}/urls`, params);\n },\n\n /** Pages tracked on a specific domain. */\n async pagesByDomain(domain: string, params: { limit?: number } = {}): Promise<{ data: IntentPage[] }> {\n return post(\"/intent/pages-by-domain\", { domain, ...params });\n },\n\n /** Search tracked pages by URL fragment or keyword. */\n async searchPages(query: string, params: { limit?: number } = {}): Promise<{ data: IntentPage[] }> {\n return post(\"/intent/pages/search\", { query, ...params });\n },\n\n /** Get visitor records for a specific page URL. */\n async pageVisitors(pageUrl: string, params: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: IntentVisitor[] }> {\n return post(\"/intent/pages/visitors\", { url: pageUrl, ...params });\n },\n\n /** Get contacts who visited a specific page URL. */\n async pageContacts(pageUrl: string, params: { limit?: number } = {}): Promise<{ data: IntentContact[] }> {\n return post(\"/intent/pages/contacts\", { url: pageUrl, ...params });\n },\n\n /** Visitor count aggregates by page (pass an array of URLs). */\n async pageVisitorCounts(urls: string[]): Promise<{ data: Array<{ url: string; visitor_count: number }> }> {\n return post(\"/intent/pages/visitor-counts\", { urls });\n },\n\n /**\n * Find companies whose users visited a specific URL (intent search).\n *\n * Note: this endpoint lives at the bare host (no `/api/v1` prefix), unlike the rest\n * of the intent surface — we call it directly here instead of through the shared `post()` helper.\n */\n async urlCompanies(url: string, params: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: IntentCompany[] }> {\n const resp = await fetch(`${baseUrl}/intent-search/url-companies`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ url, ...params }),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface GlobalContextDocument {\n id: string;\n category: string;\n title: string;\n content: string;\n metadata: Record<string, unknown> | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface Persona {\n id: string;\n name: string;\n description: string | null;\n status: string;\n pain_points: string[];\n goals: string[];\n channels: string[];\n created_at: string | null;\n}\n\nexport interface ICP {\n id: string;\n name: string;\n description: string | null;\n status: string;\n industry: string[] | null;\n employee_count_min: number | null;\n employee_count_max: number | null;\n revenue_min: number | null;\n revenue_max: number | null;\n countries: string[] | null;\n created_at: string | null;\n}\n\nexport interface IntelligenceData {\n id: string;\n source_type: string;\n url: string | null;\n title: string | null;\n content_summary: string | null;\n collected_at: string | null;\n}\n\nexport interface ResearchReport {\n id: string;\n category: \"buyer_psychology\" | \"competitive_teardown\" | \"gtm_channel\" | \"industry_analyst\" | \"review_sentiment\" | \"voice_of_customer\";\n title: string;\n summary: string | null;\n created_at: string | null;\n}\n\n/**\n * Studio context — org-level intelligence documents. The 44-doc engine that\n * powers campaign ideation: brand brief, value props, messaging house, ICPs,\n * personas, intelligence (scrapes + enrichment), and AI research reports.\n *\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/global-context/documents\n * GET /api/v1/icps\n * GET /api/v1/personas\n * GET /api/v1/intelligence-data\n * GET /api/v1/research-reports\n */\nexport const createStudioClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n const get = async (path: string, params: object = {}) => {\n const resp = await fetch(`${baseUrl}/api/v1${path}${toQuery(params)}`, { headers: headers() });\n return resp.json();\n };\n\n return {\n /** Org-level Studio documents (brand_brief, value_props, messaging_house, etc.). */\n async globalContext(params: { category?: string; limit?: number } = {}): Promise<{ data: GlobalContextDocument[] }> {\n return get(\"/global-context/documents\", params);\n },\n\n /** ICP definitions. */\n async icps(params: { status?: string; limit?: number } = {}): Promise<{ data: ICP[] }> {\n return get(\"/icps\", params);\n },\n\n /** Buyer persona definitions. */\n async personas(params: { status?: string; limit?: number } = {}): Promise<{ data: Persona[] }> {\n return get(\"/personas\", params);\n },\n\n /** Intelligence data (website scrapes, enrichment, competitor research). */\n async intelligenceData(params: { source_type?: string; limit?: number } = {}): Promise<{ data: IntelligenceData[] }> {\n return get(\"/intelligence-data\", params);\n },\n\n /** AI research reports (buyer psychology, competitive teardown, GTM channel, etc.). */\n async researchReports(params: { category?: string; limit?: number } = {}): Promise<{ data: ResearchReport[] }> {\n return get(\"/research-reports\", params);\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface MeetingAttendee {\n name: string | null;\n email: string;\n role: \"host\" | \"prospect\" | \"guest\" | string;\n contact_id?: number | null;\n}\n\nexport interface MeetingTranscriptLine {\n speaker: string;\n text: string;\n timestamp: number;\n}\n\nexport interface MeetingAnalysis {\n sentiment: \"positive\" | \"neutral\" | \"negative\";\n summary: string;\n next_steps: string[];\n objections: string[];\n talk_listen_ratio: number | null;\n}\n\nexport interface MeetingSummary {\n id: string;\n status: \"scheduled\" | \"completed\" | \"cancelled\" | \"no_show\";\n event_type: string | null;\n scheduled_at: string;\n duration_minutes: number;\n attendees: MeetingAttendee[];\n contact_id: number | null;\n conferencing_provider: string | null;\n conferencing_url: string | null;\n recording_url: string | null;\n created_at: string;\n}\n\nexport interface MeetingDetail extends MeetingSummary {\n transcript: MeetingTranscriptLine[] | null;\n analysis: MeetingAnalysis | null;\n}\n\nexport interface MeetingListParams {\n status?: \"scheduled\" | \"completed\" | \"cancelled\" | \"no_show\";\n date_from?: string;\n date_to?: string;\n attendee_id?: string;\n event_type?: string;\n contact_id?: number;\n page?: number;\n limit?: number;\n}\n\n/**\n * Meetings API - read-only access to scheduled, completed, and cancelled meetings.\n * Booking happens via `g8.calendar.*` (write-key safe, browser only) — this surface\n * is for reading meeting records, transcripts, and AI analysis.\n *\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/inbox/meetings\n * GET /api/v1/inbox/meetings/{meeting_id}\n */\nexport const createMeetingsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List meetings with optional filters. Returns summary rows without transcript / analysis. */\n async list(params: MeetingListParams = {}): Promise<{ data: MeetingSummary[]; pagination?: { page: number; limit: number; total: number; has_next: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/inbox/meetings${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get full meeting detail including transcript + AI analysis (transcript available 1-5 min after meeting ends). */\n async get(meetingId: string): Promise<MeetingDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/inbox/meetings/${meetingId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n"],"mappings":";;;AAEA,SAAS,eAAe,YAAY,iBAAiC;;;ACFrE,SAAS,sBAAsB;;;ACE/B,IAAM,cAAc;AAQb,IAAM,oBAAoB,CAAC,UAAkB,WAAoB;AACtE,QAAM,UAAU,UAAU;AAE1B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOL,MAAM,OAAO,OAA4C;AACvD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gCAAgC;AAAA,QACjE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe;AAAA,QACjB;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,MAChC,CAAC;AAED,UAAI,CAAC,KAAK,IAAI;AACZ,eAAO,EAAE,OAAO,OAAO,cAAc,CAAC,GAAG,gBAAgB,CAAC,EAAE;AAAA,MAC9D;AAEA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;ACrCO,IAAM,WAAW,OAAO,WAAW;;;ACE1C,IAAMA,eAAc;AAyBb,IAAM,uBAAuB,CAAC,UAAkB,WAAoB;AACzE,QAAM,UAAU,UAAUA;AAC1B,MAAI,iBAAwD;AAE5D,QAAM,UAAU,OAAO;AAAA,IACrB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,WAAoC;AACxC,UAAI,SAAU,QAAO,EAAE,cAAc,MAAM,gBAAgB,MAAM,UAAU,MAAM,gBAAgB,MAAM,MAAM,MAAM,SAAS,MAAM,YAAY,EAAE;AAEhJ,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,mCAAmC,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5F,UAAI,CAAC,KAAK,GAAI,QAAO,EAAE,cAAc,MAAM,gBAAgB,MAAM,UAAU,MAAM,gBAAgB,MAAM,MAAM,MAAM,SAAS,MAAM,YAAY,EAAE;AAChJ,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,QAA+B;AACnC,UAAI,SAAU,QAAO,EAAE,YAAY,GAAG,QAAQ,OAAO,SAAS,CAAC,EAAE;AAEjE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iCAAiC,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC1F,UAAI,CAAC,KAAK,GAAI,QAAO,EAAE,YAAY,GAAG,QAAQ,OAAO,SAAS,CAAC,EAAE;AACjE,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,SAAS,OAAkC,UAAsC;AAC/E,UAAI,SAAU,QAAO,MAAM;AAAA,MAAC;AAE5B,YAAM,QAAQ,YAAY;AACxB,YAAI;AACF,gBAAM,CAAC,SAAS,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,YAC7C,KAAK,SAAS;AAAA,YACd,KAAK,MAAM;AAAA,UACb,CAAC;AACD,cAAI,UAAU,WAAW,SAAU,UAAU,YAAY,UAAU,WAAW,QAAS;AACrF,qBAAS,EAAE,GAAG,SAAS,GAAG,UAAU,CAAC;AAAA,UACvC;AAAA,QACF,QAAQ;AAAA,QAAe;AAAA,MACzB;AAEA,YAAM;AACN,uBAAiB,YAAY,OAAO,GAAM;AAE1C,aAAO,MAAM;AACX,YAAI,eAAgB,eAAc,cAAc;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AACF;;;AChFA,IAAMC,eAAc;AAsBb,IAAM,sBAAsB,CAAC,UAAkB,WAAoB;AACxE,QAAM,UAAU,UAAUA;AAC1B,QAAM,YAAkD,oBAAI,IAAI;AAChE,QAAM,UAAsC,oBAAI,IAAI;AACpD,MAAI,WAA+B;AAEnC,QAAM,OAAO,CAAC,OAAqB,OAAgC,CAAC,MAAM;AACxE,cAAU,IAAI,KAAK,GAAG,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;AAAA,EAChD;AAEA,SAAO;AAAA;AAAA,IAEL,KAAK,QAA8B;AACjC,UAAI,SAAU;AAGd,UAAI,SAAU,UAAS,OAAO;AAE9B,YAAM,WAAW,QAAQ,YAAY;AACrC,YAAM,WAAW,aAAa,gBAAgB,eAAe;AAE7D,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,MAAM,GAAG,OAAO,4BAA4B,QAAQ,UAAU,QAAQ,SAAS,MAAM;AAC5F,aAAO,MAAM,UAAU,8BAA8B,QAAQ;AAC7D,aAAO,KAAK;AAEZ,eAAS,KAAK,YAAY,MAAM;AAChC,iBAAW;AACX,WAAK,MAAM;AAAA,IACb;AAAA;AAAA,IAGA,MAAM,IAAI,SAAkC;AAC1C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,+BAA+B;AAAA,QAChE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oBAAoB,eAAe,SAAS;AAAA,QACvE,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,MAClC,CAAC;AACD,UAAI,CAAC,KAAK,GAAI,QAAO;AACrB,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,YAAY,KAAK,MAAM,YAAY;AAAA,IACjD;AAAA;AAAA,IAGA,eAAe,MAAc,SAA8B;AACzD,cAAQ,IAAI,MAAM,OAAO;AAAA,IAC3B;AAAA;AAAA,IAGA,GAAG,OAAqB,UAAiC;AACvD,UAAI,CAAC,UAAU,IAAI,KAAK,EAAG,WAAU,IAAI,OAAO,CAAC,CAAC;AAClD,gBAAU,IAAI,KAAK,EAAG,KAAK,QAAQ;AAAA,IACrC;AAAA;AAAA,IAGA,QAAc;AACZ,UAAI,UAAU;AACZ,iBAAS,OAAO;AAChB,mBAAW;AACX,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;;;ACrFA,IAAMC,eAAc;AA0Bb,IAAM,mBAAmB,CAAC,UAAkB,WAAoB;AACrE,QAAM,UAAU,UAAUA;AAC1B,QAAM,YAA4C,oBAAI,IAAI;AAC1D,MAAI,WAA+B;AACnC,MAAI,KAAuB;AAE3B,QAAM,OAAO,CAAC,OAAkB,OAAgC,CAAC,MAAM;AACrE,cAAU,IAAI,KAAK,GAAG,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;AAAA,EAChD;AAEA,SAAO;AAAA;AAAA,IAEL,KAAK,QAA2B;AAC9B,UAAI,SAAU;AAEd,UAAI,SAAU,UAAS,OAAO;AAE9B,YAAM,WAAW,QAAQ,YAAY;AACrC,YAAM,WAAW,aAAa,gBAAgB,eAAe;AAE7D,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,MAAM,GAAG,OAAO,4BAA4B,QAAQ,UAAU,QAAQ,SAAS,MAAM;AAC5F,aAAO,MAAM,UAAU,8BAA8B,QAAQ;AAC7D,aAAO,KAAK;AAEZ,eAAS,KAAK,YAAY,MAAM;AAChC,iBAAW;AACX,WAAK,MAAM;AAAA,IACb;AAAA;AAAA,IAGA,KAAK,SAAuB;AAC1B,UAAI,MAAM,GAAG,eAAe,UAAU,MAAM;AAC1C,WAAG,KAAK,KAAK,UAAU,EAAE,MAAM,WAAW,SAAS,QAAQ,CAAC,CAAC;AAAA,MAC/D;AAAA,IACF;AAAA;AAAA,IAGA,GAAG,OAAkB,UAA8B;AACjD,UAAI,CAAC,UAAU,IAAI,KAAK,EAAG,WAAU,IAAI,OAAO,CAAC,CAAC;AAClD,gBAAU,IAAI,KAAK,EAAG,KAAK,QAAQ;AAAA,IACrC;AAAA;AAAA,IAGA,UAAU,QAAmC;AAE3C,UAAI,YAAY,oBAAoB,mBAAmB;AACrD,iBAAS,eAAe,YAAY,EAAE,MAAM,kBAAkB,OAAO,GAAG,GAAG;AAAA,MAC7E;AAAA,IACF;AAAA;AAAA,IAGA,QAAc;AACZ,UAAI,IAAI;AAAE,WAAG,MAAM;AAAG,aAAK;AAAA,MAAM;AACjC,UAAI,UAAU;AAAE,iBAAS,OAAO;AAAG,mBAAW;AAAA,MAAM;AACpD,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AACF;;;ACpFA,IAAMC,eAAc;AAsCb,IAAM,uBAAuB,CAAC,WAAoB;AACvD,QAAM,UAAU,UAAUA;AAC1B,QAAM,YAAoD,oBAAI,IAAI;AAElE,SAAO;AAAA;AAAA,IAEL,KAAK,QAA8B;AACjC,UAAI,SAAU;AAEd,YAAM,MAAM,GAAG,OAAO,iBAAiB,OAAO,QAAQ,IAAI,OAAO,SAAS;AAC1E,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,OAAO,SAAS,KAAM,QAAO,IAAI,QAAQ,OAAO,QAAQ,IAAI;AAChE,UAAI,OAAO,SAAS,MAAO,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK;AAEnE,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,MAAM,GAAG,GAAG,IAAI,OAAO,SAAS,CAAC;AACxC,aAAO,MAAM,UAAU;AACvB,aAAO,KAAK;AACZ,eAAS,KAAK,YAAY,MAAM;AAGhC,YAAM,QAAQ,CAAC,MAAqB;AAAE,YAAI,EAAE,QAAQ,UAAU;AAAE,iBAAO,OAAO;AAAG,mBAAS,oBAAoB,WAAW,KAAK;AAAA,QAAG;AAAA,MAAE;AACnI,eAAS,iBAAiB,WAAW,KAAK;AAAA,IAC5C;AAAA;AAAA,IAGA,MAAM,UAAkB,QAA8B;AACpD,UAAI,SAAU;AAEd,YAAM,YAAY,SAAS,cAAc,QAAQ;AACjD,UAAI,CAAC,UAAW;AAEhB,YAAM,MAAM,GAAG,OAAO,iBAAiB,OAAO,QAAQ,IAAI,OAAO,SAAS;AAC1E,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,MAAM;AACb,aAAO,MAAM,UAAU;AACvB,gBAAU,YAAY,MAAM;AAAA,IAC9B;AAAA;AAAA,IAGA,MAAM,MAAM,UAAkB,WAAmB,OAA4D;AAC3G,YAAM,SAAS,IAAI,gBAAgB;AAAA,QACjC,YAAY,MAAM;AAAA,QAClB,UAAU,MAAM;AAAA,MAClB,CAAC;AACD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,uCAAuC,QAAQ,eAAe,SAAS,IAAI,OAAO,SAAS,CAAC,EAAE;AACjI,UAAI,CAAC,KAAK,GAAI,QAAO,CAAC;AACtB,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,SAAS,KAAK,QAAQ,CAAC;AAAA,IACrC;AAAA;AAAA,IAGA,MAAM,KAAK,SAAkD;AAC3D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iCAAiC;AAAA,QAClE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AACD,UAAI,CAAC,KAAK,GAAI,QAAO;AACrB,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,YAAM,OAAO,UAAU,IAAI,QAAQ;AACnC,UAAI,KAAM,MAAK,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;AACvC,aAAO;AAAA,IACT;AAAA;AAAA,IAGA,GAAG,OAAsB,UAAkC;AACzD,UAAI,CAAC,UAAU,IAAI,KAAK,EAAG,WAAU,IAAI,OAAO,CAAC,CAAC;AAClD,gBAAU,IAAI,KAAK,EAAG,KAAK,QAAQ;AAAA,IACrC;AAAA,EACF;AACF;;;AC/GA,IAAMC,eAAc;AAsCb,IAAM,qBAAqB,CAAC,QAAgB,WAAoB;AACrE,QAAM,UAAU,UAAUA;AAE1B,QAAM,UAAU,OAAO;AAAA,IACrB,gBAAgB;AAAA,IAChB,eAAe,UAAU,MAAM;AAAA,EACjC;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,OAAO,QAMiB;AAC5B,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oCAAoC;AAAA,QACrE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,QAAQ,QAAwE;AACpF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qCAAqC;AAAA,QACtE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,YAAY,OAA2C;AAC3D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,mCAAmC;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,MAChC,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,SAAyB,OAAO,GAAG,QAAQ,IAA4B;AAClF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,2BAA2B;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,SAAS,MAAM,MAAM,CAAC;AAAA,MAC/C,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;ACjGA,IAAMC,eAAc;AAqNb,IAAM,wBAAwB,CAAC,QAAgB,WAAoB;AACxE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAOA,iBAAe,KACb,cACA,OAC6B;AAC7B,QAAI;AACJ,QAAI,OAAO,iBAAiB,UAAU;AACpC,eAAS,EAAE,MAAM,cAAc,OAAO,SAAS,GAAG;AAAA,IACpD,OAAO;AACL,eAAS,gBAAgB,CAAC;AAAA,IAC5B;AACA,UAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAChG,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,WAAQ,KAAK,QAAQ;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL;AAAA;AAAA,IAGA,MAAM,IAAI,YAA6C;AACrD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5F,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,SACJ,YACA,SAAiC,CAAC,GACqC;AACvE,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,qBAAqB,UAAU,YAAY,QAAQ,MAAM,CAAC;AAAA,QACpE,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,QAA4D;AACpE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,OAAO,UAAU,aAAa;AAAA,QACpF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,aAAa,OAAO,YAAY,SAAS,OAAO,OAAO,CAAC;AAAA,MACjF,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,SAA8D;AACzE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,QACtD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,YAAoB,QAA6D;AAC5F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,WACJ,YACA,QACA,QAC+B;AAC/B,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,UAAU,MAAM,IAAI;AAAA,QACpF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,YAAmD;AAC9D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,IAAI,YAAmD;AAC3D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,QAAQ;AAAA,QACxE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,MAAM,YAAmD;AAC7D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,UAAU;AAAA,QAC1E,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,YAAmD;AAC9D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,WAAW;AAAA,QAC3E,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,QAAQ,YAA8C;AAC1D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,YAAY;AAAA,QAC5E,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,UAAU,YAAgD;AAC9D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,cAAc;AAAA,QAC9E,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;ACvXA,IAAMC,eAAc;AAgCb,IAAM,wBAAwB,CAAC,QAAgB,WAAoB;AACxE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,SAAO;AAAA,IACL,MAAM,KAAK,OAAO,GAAG,QAAQ,IAAyB;AACpD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,0BAA0B,IAAI,UAAU,KAAK,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC1G,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,IAEA,MAAM,IAAI,YAAuC;AAC/C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5F,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,IAEA,MAAM,OAAO,QAAiD;AAC5D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,QACtD,QAAQ;AAAA,QAAQ,SAAS,QAAQ;AAAA,QACjC,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,IAEA,MAAM,OAAO,YAAmC;AAC9C,YAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,WAAW;AAAA,QAC9D,QAAQ;AAAA,QAAQ,SAAS,QAAQ;AAAA,MACnC,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,MAAM,YAA4C;AACtD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,UAAU,EAAE,SAAS,QAAQ,EAAE,CAAC;AAClG,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;ACtEA,IAAMC,eAAc;AAYb,IAAM,2BAA2B,CAAC,QAAgB,WAAoB;AAC3E,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,SAAO;AAAA,IACL,MAAM,OAA+B;AACnC,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,wBAAwB,EAAE,SAAS,QAAQ,EAAE,CAAC;AACjF,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,IAEA,MAAM,QAAQ,UAAkB,QAAiD;AAC/E,YAAM,MAAM,GAAG,OAAO,gCAAgC;AAAA,QACpD,QAAQ;AAAA,QAAQ,SAAS,QAAQ;AAAA,QACjC,MAAM,KAAK,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;AAAA,MAC9C,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,KAAK,UAAkB,QAAkF;AAC7G,YAAM,MAAM,GAAG,OAAO,6BAA6B;AAAA,QACjD,QAAQ;AAAA,QAAQ,SAAS,QAAQ;AAAA,QACjC,MAAM,KAAK,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;AAAA,MAC9C,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACrCA,IAAMC,gBAAc;AAab,IAAM,sBAAsB,CAAC,KAAa,UAAmB,WAAoB;AACtF,QAAM,UAAU,UAAUA;AAE1B,QAAM,UAAU,MAA8B,WAC1C,EAAE,gBAAgB,oBAAoB,iBAAiB,UAAU,GAAG,GAAG,IACvE,EAAE,gBAAgB,oBAAoB,eAAe,IAAI;AAE7D,QAAM,WAAW,WAAW,4BAA4B;AAExD,SAAO;AAAA;AAAA,IAEL,MAAM,QAAQ,QAAwC;AACpD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,WAAW,mBAAmB,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC7G,UAAI,CAAC,KAAK,GAAI,QAAO,EAAE,QAAQ,OAAO,GAAG,QAAQ,OAAO,SAAS,CAAC,GAAG,WAAW,KAAK;AACrF,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,OAAO,SAAmB,UAA0D;AAClF,YAAM,QAAQ,YAAY;AACxB,YAAI;AACF,gBAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC;AACrE,mBAAS,OAAO;AAAA,QAClB,QAAQ;AAAA,QAAe;AAAA,MACzB;AAEA,YAAM;AACN,YAAM,WAAW,YAAY,OAAO,GAAM;AAC1C,aAAO,MAAM,cAAc,QAAQ;AAAA,IACrC;AAAA,EACF;AACF;;;AC7CA,IAAMC,gBAAc;AAeb,IAAM,wBAAwB,CAAC,QAAgB,WAAoB;AACxE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,SAAO;AAAA,IACL,MAAM,SAAS,QAA8E;AAC3F,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,QAAQ,OAAQ,QAAO,IAAI,UAAU,OAAO,MAAM;AACtD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,8BAA8B,OAAO,SAAS,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5G,UAAI,CAAC,KAAK,GAAI,QAAO,EAAE,UAAU,GAAG,kBAAkB,GAAG,aAAa,GAAG,eAAe,GAAG,SAAS,GAAG,iBAAiB,GAAG,QAAQ,QAAQ,UAAU,MAAM;AAC3J,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;AC7BA,IAAMC,gBAAc;AAkRb,IAAM,oBAAoB,CAAC,QAAgB,WAAoB;AACpE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAC/F,QAAM,YAA8C,oBAAI,IAAI;AAE5D,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,QAAM,SAAS;AAAA;AAAA,IAEb,MAAM,aAAa,SAAmC,CAAC,GAAsC;AAC3F,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,gCAAgC,QAAQ,MAAM,CAAC;AAAA,QACzD,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,cAAc,SAAwE;AAC1F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iCAAiC;AAAA,QAClE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,oBACJ,WACA,QAC0C;AAC1C,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,iCAAiC,SAAS;AAAA,QACpD;AAAA,UACE,QAAQ;AAAA,UACR,SAAS,QAAQ;AAAA,UACjB,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC;AAAA,QACjC;AAAA,MACF;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,MAAM,cAAc,WAAmB,cAAc,GAAuC;AAC1F,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,iCAAiC,SAAS;AAAA,QACpD;AAAA,UACE,QAAQ;AAAA,UACR,SAAS,QAAQ;AAAA,UACjB,MAAM,KAAK,UAAU,EAAE,cAAc,YAAY,CAAC;AAAA,QACpD;AAAA,MACF;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,MAAM,SAA4B,CAAC,GAA+B;AACtE,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,6BAA6B,QAAQ,MAAM,CAAC;AAAA,QACtD,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,QAAQ,WAAsD;AAClE,YAAM,SAAS,YAAY,EAAE,YAAY,UAAU,IAAI,CAAC;AACxD,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,+BAA+B,QAAQ,MAAM,CAAC;AAAA,QACxD,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,gBAAgB,QAAQ,IAAoC;AAChE,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,wCAAwC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAAA,QACpE,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,YAAY,UAA8C;AAC9D,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,8BAA8B,mBAAmB,QAAQ,CAAC;AAAA,QACpE,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,SAAiC,CAAC,GAAoC;AACjF,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,8BAA8B,QAAQ,MAAM,CAAC;AAAA,QACvD,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,eAAe,UAAkI;AACrJ,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,8BAA8B,mBAAmB,QAAQ,CAAC;AAAA,QACpE,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,UAAU,SAAkJ,CAAC,GAAoF;AACrP,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,6BAA6B,QAAQ,MAAM,CAAC;AAAA,QACtD,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,oBAAoB,WAAmB,QAA4B,CAAC,GAAsD;AAC9H,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,6BAA6B,QAAQ,EAAE,YAAY,WAAW,GAAG,MAAM,CAAC,CAAC;AAAA,QACnF,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,gBAAgB,WAAmB,QAAkE,CAAC,GAAsD;AAChK,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,6BAA6B,QAAQ,EAAE,YAAY,WAAW,GAAG,MAAM,CAAC,CAAC;AAAA,QACnF,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKL,MAAM,MAAM,QAA0G;AACpH,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,0BAA0B;AAAA,QAC3D,QAAQ;AAAA,QAAQ,SAAS,QAAQ;AAAA,QACjC,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,SAAS,WAA0C;AACvD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,0BAA0B,SAAS,aAAa,EAAE,SAAS,QAAQ,EAAE,CAAC;AACzG,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,GAAG,OAAmB,UAA+B;AACnD,UAAI,CAAC,UAAU,IAAI,KAAK,EAAG,WAAU,IAAI,OAAO,CAAC,CAAC;AAClD,gBAAU,IAAI,KAAK,EAAG,KAAK,QAAQ;AAAA,IACrC;AAAA;AAAA,IAGA;AAAA,EACF;AACF;;;ACldA,IAAMC,gBAAc;AAab,IAAM,oBAAoB,CAAC,QAAgB,WAAoB;AACpE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,SAAO;AAAA;AAAA,IAEL,MAAM,MAAM,KAAmC;AAC7C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,mCAAmC;AAAA,QACpE,QAAQ;AAAA,QAAQ,SAAS,QAAQ;AAAA,QACjC,MAAM,KAAK,UAAU,EAAE,IAAI,CAAC;AAAA,MAC9B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAwG;AACnH,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,yBAAyB;AAAA,QAC1D,QAAQ;AAAA,QAAQ,SAAS,QAAQ;AAAA,QACjC,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,QAAQ,QAA0C;AACtD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,yBAAyB,MAAM,YAAY;AAAA,QAC5E,QAAQ;AAAA,QAAQ,SAAS,QAAQ;AAAA,MACnC,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,EAAE,KAAK,KAAK,iBAAiB,KAAK,MAAM,iBAAiB,GAAG;AAAA,IACrE;AAAA,EACF;AACF;;;AC/CA,IAAMC,gBAAc;AAoBb,IAAM,uBAAuB,CAAC,QAAgB,WAAoB;AACvE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAC/F,QAAM,YAAkD,oBAAI,IAAI;AAChE,MAAI,UAAU;AACd,MAAI,eAAsD;AAE1D,SAAO;AAAA;AAAA,IAEL,GAAG,OAAqB,UAAiC;AACvD,UAAI,CAAC,UAAU,IAAI,KAAK,EAAG,WAAU,IAAI,OAAO,CAAC,CAAC;AAClD,gBAAU,IAAI,KAAK,EAAG,KAAK,QAAQ;AAGnC,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,uBAAe,YAAY,YAAY;AACrC,cAAI;AACF,kBAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qCAAqC,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC9F,gBAAI,CAAC,KAAK,GAAI;AACd,kBAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,kBAAM,SAAS,KAAK,QAAQ,QAAQ,CAAC;AACrC,uBAAW,OAAO,QAAQ;AACxB,oBAAM,MAAM,UAAU,IAAI,IAAI,IAAoB;AAClD,kBAAI,IAAK,KAAI,QAAQ,CAAC,OAAO,GAAG,GAAG,CAAC;AAAA,YACtC;AAAA,UACF,QAAQ;AAAA,UAAe;AAAA,QACzB,GAAG,GAAM;AAAA,MACX;AAAA,IACF;AAAA;AAAA,IAGA,OAAa;AACX,UAAI,aAAc,eAAc,YAAY;AAC5C,gBAAU;AACV,gBAAU,MAAM;AAAA,IAClB;AAAA,EACF;AACF;;;AC1DA,IAAMC,gBAAc;AAoFb,IAAM,uBAAuB,CAAC,QAAgB,WAAoB;AACvE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,SAA4B,CAAC,GAAgD;AACtF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,mBAAmB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC/F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,WAAqC;AAC7C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC1F,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,SAAgD;AAC3D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB;AAAA,QACrD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,WAAmB,QAA2D;AACzF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,IAAI;AAAA,QAClE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,WAAkD;AAC7D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,IAAI;AAAA,QAClE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,YAAY,QAAqD;AACrE,YAAM,KAAK,UAAU,OAAO,YAAY,MAAM,KAAK;AACnD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,2BAA2B,EAAE,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC1F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,aAAa,QAA2D;AAC5E,YAAM,OAAO;AAAA,QACX,OAAO,OAAO;AAAA,QACd,WAAW,OAAO,aAAa;AAAA,QAC/B,SAAS,OAAO,WAAW;AAAA,QAC3B,YAAY,OAAO;AAAA,MACrB;AACA,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,mCAAmC;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;ACrKA,IAAMC,gBAAc;AAqEb,IAAM,wBAAwB,CAAC,QAAgB,WAAoB;AACxE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,SAA4B,CAAC,GAAgD;AACtF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAChG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,WAAqC;AAC7C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,SAAS,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC3F,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,SAAS,WAAmB,QAAQ,IAAI,SAAS,GAAuD;AAC5G,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,qBAAqB,SAAS,mBAAmB,KAAK,WAAW,MAAM;AAAA,QACjF,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,WAAmB,QAA2D;AACzF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,SAAS,IAAI;AAAA,QACnE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,WAAkD;AAC7D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,SAAS,IAAI;AAAA,QACnE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,YAAY,QAAqD;AACrE,YAAM,KAAK,UAAU,OAAO,YAAY,MAAM,KAAK;AACnD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,4BAA4B,EAAE,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC3F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,aAAa,QAA2D;AAC5E,YAAM,OAAO;AAAA,QACX,OAAO,OAAO;AAAA,QACd,WAAW,OAAO,aAAa;AAAA,QAC/B,SAAS,OAAO,WAAW;AAAA,QAC3B,YAAY,OAAO;AAAA,MACrB;AACA,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oCAAoC;AAAA,QACrE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;ACpJA,IAAMC,gBAAc;AAsBb,IAAM,oBAAoB,CAAC,QAAgB,WAAoB;AACpE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,OAAO,GAAG,QAAQ,IAAqD;AAChF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,sBAAsB,IAAI,UAAU,KAAK,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACtG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,OAAe,OAAiC,YAAkC;AAC7F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB;AAAA,QAClD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,MACtC,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAA+C;AAC1D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,IAAI;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,SAAS,QAAgB,OAAO,GAAG,QAAQ,IAAqD;AACpG,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,iBAAiB,MAAM,kBAAkB,IAAI,UAAU,KAAK;AAAA,QACtE,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,YAAY,QAAgB,YAAkD;AAClF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,aAAa;AAAA,QACrE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,aAAa,WAAW,CAAC;AAAA,MAClD,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,eAAe,QAAgB,YAAoD;AACvF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,aAAa;AAAA,QACrE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,aAAa,WAAW,CAAC;AAAA,MAClD,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;AClFA,IAAMC,gBAAc;AAsBb,IAAM,oBAAoB,CAAC,QAAgB,WAAoB;AACpE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,WAA8C;AACvD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,UAAU,EAAE,SAAS,QAAQ,EAAE,CAAC;AAChG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,WAAmB,SAAgC;AAC9D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,UAAU;AAAA,QACxE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,MAClC,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAgB,SAAgC;AAC3D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,IAAI;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,MAClC,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAyD;AACpE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,IAAI;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;AChEA,IAAMC,gBAAc;AA6Db,IAAM,oBAAoB,CAAC,QAAgB,WAAoB;AACpE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,eAAe,WAAmB,QAA4C;AAClF,YAAM,KAAK,SAAS,WAAW,mBAAmB,MAAM,CAAC,KAAK;AAC9D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,SAAS,EAAE,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACrG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,KAAK,SAAyB,CAAC,GAA8B;AACjE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gBAAgB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,WAAmB,MAAuC;AACrE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,UAAU;AAAA,QACxE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAgB,QAAyC;AACpE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,IAAI;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAyD;AACpE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,IAAI;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;ACvHA,IAAMC,gBAAc;AA+Db,IAAM,qBAAqB,CAAC,QAAgB,WAAoB;AACrE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,kBAAkB,QAA6C;AACnE,YAAM,KAAK,UAAU,OAAO,YAAY,MAAM,KAAK;AACnD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,EAAE,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAChF,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,kBAAkB,QAA6C;AACnE,YAAM,KAAK,UAAU,OAAO,YAAY,MAAM,KAAK;AACnD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,2BAA2B,EAAE,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC1F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAkD;AAC7D,YAAM,OAAO;AAAA,QACX,OAAO,OAAO;AAAA,QACd,WAAW,OAAO,aAAa;AAAA,QAC/B,SAAS,OAAO,WAAW;AAAA,QAC3B,QAAQ,OAAO,UAAU;AAAA,MAC3B;AACA,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB;AAAA,QACnD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,UAAkB,SAA4B,CAAC,GAA+D;AACzH,YAAM,cAA+C,EAAE,QAAQ,OAAO,UAAU,WAAW;AAC3F,UAAI,OAAO,WAAW,KAAM,aAAY,UAAU,OAAO;AACzD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,QAAQ,GAAG,QAAQ,WAAW,CAAC,IAAI;AAAA,QACtF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,SACJ,UACA,QAC+E;AAC/E,YAAM,OAAO;AAAA,QACX,WAAW,OAAO;AAAA,QAClB,OAAO,OAAO,SAAS;AAAA,QACvB,QAAQ,OAAO,UAAU;AAAA,MAC3B;AACA,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,QAAQ,WAAW;AAAA,QACtE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;ACzIA,IAAMC,gBAAc;AA4Gb,IAAM,oBAAoB,CAAC,QAAgB,WAAoB;AACpE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,YAA2C;AAC/C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,2BAA2B,EAAE,SAAS,QAAQ,EAAE,CAAC;AACpF,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,KAAK,SAAyB,CAAC,GAA2D;AAC9F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gBAAgB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,MAAuC;AAClD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB;AAAA,QAClD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,IAAI,QAA+B;AACvC,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACpF,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAgB,QAAyC;AACpE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,IAAI;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAyD;AACpE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,MAAM,IAAI;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,WAAW,WAAqD;AACpE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,UAAU,EAAE,SAAS,QAAQ,EAAE,CAAC;AAChG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,WAAW,WAAqD;AACpE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,SAAS,UAAU,EAAE,SAAS,QAAQ,EAAE,CAAC;AACjG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;ACxLA,IAAMC,gBAAc;AAoHb,IAAM,oBAAoB,CAAC,QAAgB,WAAoB;AACpE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,SAA0B,CAAC,GAAqC;AACzE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gBAAgB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,SAAiB,UAAwB,SAA+B;AAChF,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,iBAAiB,OAAO,GAAG,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAAA,QACzD,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OACJ,SACA,eACA,UAAwB,SACI;AAC5B,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,iBAAiB,OAAO,UAAU,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAAA,QAChE;AAAA,UACE,QAAQ;AAAA,UACR,SAAS,QAAQ;AAAA,UACjB,MAAM,KAAK,UAAU,EAAE,gBAAgB,cAAc,CAAC;AAAA,QACxD;AAAA,MACF;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,IACJ,SACA,QACA,UAAwB,SACC;AACzB,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,iBAAiB,OAAO,OAAO,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAAA,QAC7D;AAAA,UACE,QAAQ;AAAA,UACR,SAAS,QAAQ;AAAA,UACjB,MAAM,KAAK,UAAU,EAAE,SAAS,OAAO,CAAC;AAAA,QAC1C;AAAA,MACF;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,MAAM,SAAiB,UAAwB,SAA8B;AACjF,YAAM,OAAO,MAAM;AAAA,QACjB,GAAG,OAAO,iBAAiB,OAAO,SAAS,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAAA,QAC/D,EAAE,SAAS,QAAQ,EAAE;AAAA,MACvB;AACA,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,KAAK,SAAiB,SAAoD;AAC9E,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,OAAO,SAAS;AAAA,QAClE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;AC9MA,IAAMC,gBAAc;AAoHb,IAAM,qBAAqB,CAAC,QAAgB,WAAoB;AACrE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,SAA0B,CAAC,GAAmE;AACvG,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC7F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,SAAuC;AAC/C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACtF,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,OAAgD;AAC3D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB;AAAA,QACnD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,KAAK;AAAA,MAC5B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,SAAiB,QAAiD;AAC7E,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,IAAI;AAAA,QAC9D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,SAA0D;AACrE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,IAAI;AAAA,QAC9D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,UAAU,SAAuC;AACrD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,cAAc;AAAA,QACxE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,YAAY,SAAoE;AACpF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,kBAAkB;AAAA,QAC5E,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,KAAK,SAAiB,QAA+C;AACzE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,SAAS;AAAA,QACnE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,WAAiD;AACrD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,6BAA6B,EAAE,SAAS,QAAQ,EAAE,CAAC;AACtF,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,WAAmC;AACvC,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,0BAA0B,EAAE,SAAS,QAAQ,EAAE,CAAC;AACnF,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,WAAW,WAAsD;AACrE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,SAAS,WAAW,EAAE,SAAS,QAAQ,EAAE,CAAC;AACjG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,WAAW,WAAsD;AACrE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,SAAS,WAAW,EAAE,SAAS,QAAQ,EAAE,CAAC;AAClG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;ACvOA,IAAMC,gBAAc;AA+Fb,IAAM,wBAAwB,CAAC,QAAgB,WAAoB;AACxE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,SAAO;AAAA;AAAA,IAEL,MAAM,OAA2C;AAC/C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC9E,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,YAA4C;AACpD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5F,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,kBAAoD;AACxD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,sCAAsC,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC/F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,OAAO,QAA2D;AACtE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,QACtD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,YAAoB,QAA2D;AAC1F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,YAA6D;AACxE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,YAAY,YAAoB,OAAuD;AAC3F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,WAAW;AAAA,QAC3E,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,KAAK;AAAA,MAC5B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,YAAY,YAAoB,SAAiB,QAAwD;AAC7G,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,WAAW,OAAO,IAAI;AAAA,QACtF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,cAAc,YAAoB,UAA6D;AACnG,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,mBAAmB;AAAA,QACnF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,WAAW,SAAS,CAAC;AAAA,MAC9C,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,YAAY,YAAoB,SAA0D;AAC9F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,WAAW,OAAO,IAAI;AAAA,QACtF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,UAAiD;AACrD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,6BAA6B;AAAA,QAC9D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,eACJ,cACA,WACwB;AACxB,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qCAAqC;AAAA,QACtE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,eAAe,cAAc,GAAI,aAAa,CAAC,EAAG,CAAC;AAAA,MAC5E,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;ACvNA,IAAMC,gBAAc;AAyGb,IAAM,wBAAwB,CAAC,QAAgB,WAAoB;AACxE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,SAA6B,CAAC,GAAkC;AACzE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,oBAAoB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAChG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,YAAuC;AAC/C,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC5F,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,QAAiD;AAC5D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB;AAAA,QACtD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,MAAM,OAAO,YAAoB,QAAiD;AAChF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,YAA6D;AACxE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,IAAI;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,SAAS,UAEZ;AACD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,8BAA8B;AAAA,QAC/D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,QAAQ;AAAA,MAC/B,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,QAAQ,YAAoB,iBAA0C,CAAC,GAA+B;AAC1G,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,YAAY;AAAA,QAC5E,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,iBAAiB,eAAe,CAAC;AAAA,MAC1D,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,aAAa,aAAiD;AAClE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gCAAgC,WAAW,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACxG,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,eAAe,aAA6D;AAChF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gCAAgC,WAAW,UAAU;AAAA,QACtF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,gBAAgB,aAA8D;AAClF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gCAAgC,WAAW,WAAW;AAAA,QACvF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,cAAc,aAA8D;AAChF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gCAAgC,WAAW,SAAS;AAAA,QACrF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,iBAAiB,YAA6F;AAClH,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,mBAAmB,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC3G,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,aAAa,YAA2D;AAC5E,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,qBAAqB,UAAU,kBAAkB;AAAA,QAClF,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,UAAU,SAA4B,CAAC,GAAwC;AACnF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,sCAAsC,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAClH,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,iBAA+F;AACnG,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,8CAA8C,EAAE,SAAS,QAAQ,EAAE,CAAC;AACvG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,oBAAiG;AACrG,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iDAAiD,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC1G,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,gBAA8F;AAClG,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,6CAA6C,EAAE,SAAS,QAAQ,EAAE,CAAC;AACtG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,iBAAyE;AAC7E,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,8CAA8C,EAAE,SAAS,QAAQ,EAAE,CAAC;AACvG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,iBAAsF;AAC1F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iCAAiC,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC1F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,mBAA4E;AAChF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kCAAkC,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC3F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,eAAe,QAA6F;AAChH,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,2BAA2B,MAAM,WAAW,EAAE,SAAS,QAAQ,EAAE,CAAC;AACrG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;ACrSA,IAAMC,gBAAc;AA2Gb,IAAM,qBAAqB,CAAC,QAAgB,WAAoB;AACrE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,SAA0B,CAAC,GAA+B;AACnE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,iBAAiB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC7F,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,SAAiC;AACzC,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACtF,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,aAAa,SAAuD;AACxE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,cAAc,EAAE,SAAS,QAAQ,EAAE,CAAC;AAChG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,aAAwF;AAC5F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,yBAAyB,EAAE,SAAS,QAAQ,EAAE,CAAC;AAClF,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,cAAc,SAA+B,CAAC,GAAuC;AACzF,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,2BAA2B,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACvG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,UAAU,QAA8C;AAC5D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB;AAAA,QACnD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,GAAG,QAAQ,MAAM,MAAM,CAAC;AAAA,MACjD,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,UAAU,QAA8C;AAC5D,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB;AAAA,QACnD,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,GAAG,QAAQ,MAAM,MAAM,CAAC;AAAA,MACjD,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,mBAAmB,QAAqG;AAC5H,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gCAAgC;AAAA,QACjE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,eAAe,QAMF;AACjB,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,4BAA4B;AAAA,QAC7D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,UAAU,SAAiB,QAA8C;AAC7E,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,IAAI;AAAA,QAC9D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,GAAG,QAAQ,MAAM,MAAM,CAAC;AAAA,MACjD,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,UAAU,SAAiB,QAA8C;AAC7E,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,IAAI;AAAA,QAC9D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,GAAG,QAAQ,MAAM,MAAM,CAAC;AAAA,MACjD,CAAC;AACD,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA;AAAA,IAGA,MAAM,OAAO,SAA0D;AACrE,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,IAAI;AAAA,QAC9D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,MACnB,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,SAAS,OAAgF;AAC7F,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,2BAA2B;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,KAAK;AAAA,MAC5B,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,QAAQ,SAAiB,cAE5B;AACD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,kBAAkB,OAAO,YAAY;AAAA,QACtE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,YAAY;AAAA,MACnC,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;AC/PA,IAAMC,gBAAc;AAiFb,IAAM,qBAAqB,CAAC,QAAgB,WAAoB;AACrE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,MAAM,OAAO,SAAiB;AAClC,UAAM,OAAO,MAAM,MAAM,GAAG,OAAO,UAAU,IAAI,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC3E,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,QAAM,OAAO,OAAO,MAAc,OAAgC,CAAC,MAAM;AACvE,UAAM,OAAO,MAAM,MAAM,GAAG,OAAO,UAAU,IAAI,IAAI;AAAA,MACnD,QAAQ;AAAA,MACR,SAAS,QAAQ;AAAA,MACjB,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,QAAM,MAAM,OAAO,SAAiB;AAClC,UAAM,OAAO,MAAM,MAAM,GAAG,OAAO,UAAU,IAAI,IAAI,EAAE,QAAQ,UAAU,SAAS,QAAQ,EAAE,CAAC;AAC7F,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,QAAwC;AAC5C,aAAO,IAAI,eAAe;AAAA,IAC5B;AAAA;AAAA,IAGA,MAAM,aAAa,SAA6D,CAAC,GAAuC;AACtH,aAAO,KAAK,yBAAyB,MAAM;AAAA,IAC7C;AAAA;AAAA,IAGA,MAAM,iBAAiB,QAAkD;AACvE,aAAO,KAAK,uCAAuC,EAAE,OAAO,CAAC;AAAA,IAC/D;AAAA;AAAA,IAGA,MAAM,cAAc,WAA4D;AAC9E,aAAO,IAAI,oBAAoB,SAAS,EAAE;AAAA,IAC5C;AAAA;AAAA,IAGA,MAAM,iBAAiB,WAAmB,SAAmE,CAAC,GAAuC;AACnJ,aAAO,KAAK,oBAAoB,SAAS,cAAc,MAAM;AAAA,IAC/D;AAAA;AAAA,IAGA,MAAM,gBAAgB,WAAmB,SAAmE,CAAC,GAAuC;AAClJ,aAAO,KAAK,oBAAoB,SAAS,aAAa,MAAM;AAAA,IAC9D;AAAA;AAAA,IAGA,MAAM,YAAY,WAAmB,SAA6B,CAAC,GAAoC;AACrG,aAAO,KAAK,oBAAoB,SAAS,SAAS,MAAM;AAAA,IAC1D;AAAA;AAAA,IAGA,MAAM,cAAc,QAAgB,SAA6B,CAAC,GAAoC;AACpG,aAAO,KAAK,2BAA2B,EAAE,QAAQ,GAAG,OAAO,CAAC;AAAA,IAC9D;AAAA;AAAA,IAGA,MAAM,YAAY,OAAe,SAA6B,CAAC,GAAoC;AACjG,aAAO,KAAK,wBAAwB,EAAE,OAAO,GAAG,OAAO,CAAC;AAAA,IAC1D;AAAA;AAAA,IAGA,MAAM,aAAa,SAAiB,SAAmE,CAAC,GAAuC;AAC7I,aAAO,KAAK,0BAA0B,EAAE,KAAK,SAAS,GAAG,OAAO,CAAC;AAAA,IACnE;AAAA;AAAA,IAGA,MAAM,aAAa,SAAiB,SAA6B,CAAC,GAAuC;AACvG,aAAO,KAAK,0BAA0B,EAAE,KAAK,SAAS,GAAG,OAAO,CAAC;AAAA,IACnE;AAAA;AAAA,IAGA,MAAM,kBAAkB,MAAkF;AACxG,aAAO,KAAK,gCAAgC,EAAE,KAAK,CAAC;AAAA,IACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,MAAM,aAAa,KAAa,SAAmE,CAAC,GAAuC;AACzI,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,gCAAgC;AAAA,QACjE,QAAQ;AAAA,QACR,SAAS,QAAQ;AAAA,QACjB,MAAM,KAAK,UAAU,EAAE,KAAK,GAAG,OAAO,CAAC;AAAA,MACzC,CAAC;AACD,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;AClLA,IAAMC,gBAAc;AAoEb,IAAM,qBAAqB,CAAC,QAAgB,WAAoB;AACrE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,QAAM,MAAM,OAAO,MAAc,SAAiB,CAAC,MAAM;AACvD,UAAM,OAAO,MAAM,MAAM,GAAG,OAAO,UAAU,IAAI,GAAG,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAC7F,WAAO,KAAK,KAAK;AAAA,EACnB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,cAAc,SAAgD,CAAC,GAA+C;AAClH,aAAO,IAAI,6BAA6B,MAAM;AAAA,IAChD;AAAA;AAAA,IAGA,MAAM,KAAK,SAA8C,CAAC,GAA6B;AACrF,aAAO,IAAI,SAAS,MAAM;AAAA,IAC5B;AAAA;AAAA,IAGA,MAAM,SAAS,SAA8C,CAAC,GAAiC;AAC7F,aAAO,IAAI,aAAa,MAAM;AAAA,IAChC;AAAA;AAAA,IAGA,MAAM,iBAAiB,SAAmD,CAAC,GAA0C;AACnH,aAAO,IAAI,sBAAsB,MAAM;AAAA,IACzC;AAAA;AAAA,IAGA,MAAM,gBAAgB,SAAgD,CAAC,GAAwC;AAC7G,aAAO,IAAI,qBAAqB,MAAM;AAAA,IACxC;AAAA,EACF;AACF;;;AChHA,IAAMC,gBAAc;AAgEb,IAAM,uBAAuB,CAAC,QAAgB,WAAoB;AACvE,QAAM,UAAU,UAAUA;AAC1B,QAAM,UAAU,OAAO,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,MAAM,GAAG;AAE/F,QAAM,UAAU,CAAC,WAAmB;AAClC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC3C,UAAI,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,IAAI,IAAI,CAAC,KAAK;AAAA,EACvB;AAEA,SAAO;AAAA;AAAA,IAEL,MAAM,KAAK,SAA4B,CAAC,GAAwH;AAC9J,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,yBAAyB,QAAQ,MAAM,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AACrG,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA;AAAA,IAGA,MAAM,IAAI,WAA2C;AACnD,YAAM,OAAO,MAAM,MAAM,GAAG,OAAO,0BAA0B,SAAS,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;AAChG,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF;AACF;;;A9BzDA,IAAM,eAAe;AACrB,IAAMC,gBAAc;AAapB,IAAM,KAAN,MAAS;AAAA,EAAT;AACmB;AAAA,kBAAoC;AACpC;AAAA,kBAA0B;AAC1B;AAAA,kBAAsD;AACtD;AAAA,qBAA4D;AAC5D;AAAA,oBAA0D;AAC1D;AAAA,iBAAoD;AACpD;AAAA,qBAA4D;AAC5D;AAAA,mBAAwD;AACxD;AAAA,sBAA8D;AAC9D;AAAA,sBAA8D;AAC9D;AAAA,yBAAoE;AACpE;AAAA,oBAA0D;AAC1D;AAAA,sBAA8D;AAC9D;AAAA,kBAAsD;AACtD;AAAA,kBAAsD;AACtD;AAAA,qBAA4D;AAC5D;AAAA,qBAA4D;AAC5D;AAAA,sBAA8D;AAC9D;AAAA,kBAAsD;AACtD;AAAA,kBAAsD;AACtD;AAAA,kBAAsD;AACtD;AAAA,mBAAwD;AACxD;AAAA,kBAAsD;AACtD;AAAA,kBAAsD;AACtD;AAAA,mBAAwD;AACxD;AAAA,sBAA8D;AAC9D;AAAA,sBAA8D;AAC9D;AAAA,mBAAwD;AACxD;AAAA,mBAAwD;AACxD;AAAA,mBAAwD;AACxD;AAAA,qBAA4D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM7E,KAAK,QAAwB;AAC3B,SAAK,SAAS;AAEd,QAAI,CAAC,UAAU;AACb,WAAK,SAAS,eAAe;AAAA,QAC3B,MAAM,OAAO,QAAQ;AAAA,QACrB,UAAU,OAAO,YAAY;AAAA,QAC7B,OAAO,OAAO;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,OAAO,UAAUA;AAChC,UAAM,WAAW,OAAO,YAAY;AACpC,UAAM,SAAS,OAAO,UAAU;AAGhC,QAAI,UAAU;AACZ,WAAK,SAAS,kBAAkB,UAAU,MAAM;AAChD,WAAK,YAAY,qBAAqB,UAAU,MAAM;AACtD,WAAK,WAAW,oBAAoB,UAAU,MAAM;AACpD,WAAK,QAAQ,iBAAiB,UAAU,MAAM;AAC9C,WAAK,YAAY,qBAAqB,MAAM;AAC5C,WAAK,WAAW,oBAAoB,UAAU,OAAO,MAAM;AAAA,IAC7D;AAGA,QAAI,QAAQ;AACV,WAAK,UAAU,mBAAmB,QAAQ,MAAM;AAChD,WAAK,aAAa,sBAAsB,QAAQ,MAAM;AACtD,WAAK,aAAa,sBAAsB,QAAQ,MAAM;AACtD,WAAK,gBAAgB,yBAAyB,QAAQ,MAAM;AAC5D,WAAK,aAAa,sBAAsB,QAAQ,MAAM;AACtD,WAAK,SAAS,kBAAkB,QAAQ,MAAM;AAC9C,WAAK,SAAS,kBAAkB,QAAQ,MAAM;AAC9C,WAAK,YAAY,qBAAqB,QAAQ,MAAM;AACpD,WAAK,YAAY,qBAAqB,QAAQ,MAAM;AACpD,WAAK,aAAa,sBAAsB,QAAQ,MAAM;AACtD,WAAK,SAAS,kBAAkB,QAAQ,MAAM;AAC9C,WAAK,SAAS,kBAAkB,QAAQ,MAAM;AAC9C,WAAK,SAAS,kBAAkB,QAAQ,MAAM;AAC9C,WAAK,UAAU,mBAAmB,QAAQ,MAAM;AAChD,WAAK,SAAS,kBAAkB,QAAQ,MAAM;AAC9C,WAAK,SAAS,kBAAkB,QAAQ,MAAM;AAC9C,WAAK,UAAU,mBAAmB,QAAQ,MAAM;AAChD,WAAK,aAAa,sBAAsB,QAAQ,MAAM;AACtD,WAAK,aAAa,sBAAsB,QAAQ,MAAM;AACtD,WAAK,UAAU,mBAAmB,QAAQ,MAAM;AAChD,WAAK,UAAU,mBAAmB,QAAQ,MAAM;AAChD,WAAK,UAAU,mBAAmB,QAAQ,MAAM;AAChD,WAAK,YAAY,qBAAqB,QAAQ,MAAM;AAEpD,WAAK,WAAW,oBAAoB,QAAQ,MAAM,MAAM;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,MAAM,OAAe,YAAoC;AAAE,SAAK,QAAQ,MAAM,OAAO,UAAU;AAAA,EAAG;AAAA;AAAA,EAGlG,SAAS,QAAgB,YAAuC;AAAE,SAAK,QAAQ,SAAS,QAAQ,UAAU;AAAA,EAAG;AAAA;AAAA,EAG7G,KAAK,YAAoC;AAAE,SAAK,QAAQ,KAAK,UAAU;AAAA,EAAG;AAAA;AAAA,EAG1E,QAAc;AAAE,SAAK,QAAQ,MAAM;AAAA,EAAG;AAAA;AAAA;AAAA,EAKtC,IAAI,QAAQ;AAAE,SAAK,YAAY;AAAG,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAGvD,IAAI,WAAW;AAAE,SAAK,YAAY;AAAG,WAAO,KAAK;AAAA,EAAY;AAAA;AAAA,EAG7D,IAAI,UAAU;AAAE,SAAK,YAAY;AAAG,WAAO,KAAK;AAAA,EAAW;AAAA;AAAA,EAG3D,IAAI,OAAO;AAAE,SAAK,YAAY;AAAG,WAAO,KAAK;AAAA,EAAQ;AAAA;AAAA,EAGrD,IAAI,WAAW;AAAE,SAAK,YAAY;AAAG,WAAO,KAAK;AAAA,EAAY;AAAA;AAAA,EAG7D,IAAI,SAAS;AAAE,SAAK,WAAW,QAAQ;AAAG,WAAO,KAAK;AAAA,EAAU;AAAA;AAAA,EAGhE,IAAI,YAAY;AAAE,SAAK,WAAW,WAAW;AAAG,WAAO,KAAK;AAAA,EAAa;AAAA;AAAA,EAGzE,IAAI,YAAY;AAAE,SAAK,WAAW,WAAW;AAAG,WAAO,KAAK;AAAA,EAAa;AAAA;AAAA,EAGzE,IAAI,eAAe;AAAE,SAAK,WAAW,cAAc;AAAG,WAAO,KAAK;AAAA,EAAgB;AAAA;AAAA,EAGlF,IAAI,UAAU;AAAE,SAAK,YAAY;AAAG,WAAO,KAAK;AAAA,EAAW;AAAA;AAAA,EAG3D,IAAI,YAAY;AAAE,SAAK,WAAW,WAAW;AAAG,WAAO,KAAK;AAAA,EAAa;AAAA;AAAA,EAGzE,IAAI,QAAQ;AAAE,SAAK,WAAW,OAAO;AAAG,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAG7D,IAAI,QAAQ;AAAE,SAAK,WAAW,OAAO;AAAG,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAG7D,IAAI,WAAW;AAAE,SAAK,WAAW,UAAU;AAAG,WAAO,KAAK;AAAA,EAAY;AAAA;AAAA,EAGtE,IAAI,WAAW;AAAE,SAAK,WAAW,UAAU;AAAG,WAAO,KAAK;AAAA,EAAY;AAAA;AAAA,EAGtE,IAAI,YAAY;AAAE,SAAK,WAAW,WAAW;AAAG,WAAO,KAAK;AAAA,EAAa;AAAA;AAAA,EAGzE,IAAI,QAAQ;AAAE,SAAK,WAAW,OAAO;AAAG,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAG7D,IAAI,QAAQ;AAAE,SAAK,WAAW,OAAO;AAAG,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAG7D,IAAI,QAAQ;AAAE,SAAK,WAAW,OAAO;AAAG,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAG7D,IAAI,SAAS;AAAE,SAAK,WAAW,QAAQ;AAAG,WAAO,KAAK;AAAA,EAAU;AAAA;AAAA,EAGhE,IAAI,QAAQ;AAAE,SAAK,WAAW,OAAO;AAAG,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAG7D,IAAI,QAAQ;AAAE,SAAK,WAAW,OAAO;AAAG,WAAO,KAAK;AAAA,EAAS;AAAA;AAAA,EAG7D,IAAI,SAAS;AAAE,SAAK,WAAW,QAAQ;AAAG,WAAO,KAAK;AAAA,EAAU;AAAA;AAAA,EAGhE,IAAI,YAAY;AAAE,SAAK,WAAW,WAAW;AAAG,WAAO,KAAK;AAAA,EAAa;AAAA;AAAA,EAGzE,IAAI,YAAY;AAAE,SAAK,WAAW,WAAW;AAAG,WAAO,KAAK;AAAA,EAAa;AAAA;AAAA,EAGzE,IAAI,SAAS;AAAE,SAAK,WAAW,QAAQ;AAAG,WAAO,KAAK;AAAA,EAAU;AAAA;AAAA,EAGhE,IAAI,SAAS;AAAE,SAAK,WAAW,QAAQ;AAAG,WAAO,KAAK;AAAA,EAAU;AAAA;AAAA,EAGhE,IAAI,SAAS;AAAE,SAAK,WAAW,QAAQ;AAAG,WAAO,KAAK;AAAA,EAAU;AAAA;AAAA,EAGhE,IAAI,WAAW;AAAE,SAAK,WAAW,UAAU;AAAG,WAAO,KAAK;AAAA,EAAY;AAAA;AAAA,EAGtE,IAAI,cAAuB;AAAE,WAAO,KAAK,WAAW;AAAA,EAAM;AAAA;AAAA,EAG1D,cAAoB;AAClB,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,gCAAgC;AAAA,EACpE;AAAA;AAAA,EAGA,WAAW,QAAsB;AAC/B,SAAK,YAAY;AACjB,QAAI,CAAC,KAAK,OAAQ,OAAQ,OAAM,IAAI,MAAM,MAAM,MAAM,sDAAsD;AAAA,EAC9G;AACF;AAGO,IAAM,KAAK,IAAI,GAAG;;;AD3NhB;AAlCT,IAAM,YAAY,cAAc,EAAE;AAsB3B,IAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAuB;AACrB,YAAU,MAAM;AACd,QAAI,CAAC,GAAG,aAAa;AACnB,SAAG,KAAK,EAAE,UAAU,MAAM,GAAG,OAAO,CAAC;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,UAAU,MAAM,MAAM,CAAC;AAE3B,SAAO,oBAAC,UAAU,UAAV,EAAmB,OAAO,IAAK,UAAS;AAClD;AASO,IAAM,QAAQ,MAAM;AACzB,QAAM,SAAS,WAAW,SAAS;AACnC,SAAO;AAAA;AAAA,IAEL,OAAO,OAAO,MAAM,KAAK,MAAM;AAAA;AAAA,IAE/B,UAAU,OAAO,SAAS,KAAK,MAAM;AAAA;AAAA,IAErC,MAAM,OAAO,KAAK,KAAK,MAAM;AAAA;AAAA,IAE7B,OAAO,OAAO,MAAM,KAAK,MAAM;AAAA;AAAA,IAE/B,OAAO,OAAO;AAAA;AAAA,IAEd,IAAI;AAAA,EACN;AACF;","names":["DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API"]}
|
|
1
|
+
{"version":3,"sources":["../src/react.tsx","../src/core.ts","../src/forms.ts","../src/utils.ts","../src/visitors.ts","../src/copilot.ts","../src/chat.ts","../src/calendar.ts","../src/enrich.ts","../src/sequences.ts","../src/campaigns.ts","../src/integrations.ts","../src/signals.ts","../src/analytics.ts","../src/voice.ts","../src/pages.ts","../src/webhooks.ts","../src/contacts.ts","../src/companies.ts","../src/lists.ts","../src/notes.ts","../src/tasks.ts","../src/fields.ts","../src/deals.ts","../src/inbox.ts","../src/quotes.ts","../src/pipelines.ts","../src/workflows.ts","../src/skills.ts","../src/intent.ts","../src/studio.ts","../src/meetings.ts"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, useEffect, type ReactNode } from \"react\";\nimport { g8 } from \"./core\";\nimport type { G8Config } from \"./types\";\n\nconst G8Context = createContext(g8);\n\ninterface G8ProviderProps {\n /** Your graph8 write key */\n writeKey: string;\n /** Tracking host (default: https://t.graph8.com) */\n host?: string;\n /** Additional config options */\n config?: Partial<Omit<G8Config, \"writeKey\" | \"host\">>;\n children: ReactNode;\n}\n\n/**\n * graph8 React provider. Initializes the SDK once and provides it to all children.\n *\n * Usage:\n * import { G8Provider } from '@graph8/js/react';\n *\n * <G8Provider writeKey=\"your_write_key\">\n * <App />\n * </G8Provider>\n */\nexport const G8Provider = ({\n writeKey,\n host,\n config,\n children,\n}: G8ProviderProps) => {\n useEffect(() => {\n if (!g8.initialized) {\n g8.init({ writeKey, host, ...config });\n }\n }, [writeKey, host, config]);\n\n return <G8Context.Provider value={g8}>{children}</G8Context.Provider>;\n};\n\n/**\n * Hook to access the graph8 SDK from any component.\n *\n * Usage:\n * const { track, identify, page, forms } = useG8();\n * track('button_click', { button: 'cta' });\n */\nexport const useG8 = () => {\n const client = useContext(G8Context);\n return {\n /** Track a custom event */\n track: client.track.bind(client),\n /** Identify a user */\n identify: client.identify.bind(client),\n /** Track a page view */\n page: client.page.bind(client),\n /** Clear user identity */\n reset: client.reset.bind(client),\n /** Progressive form helpers */\n forms: client.forms,\n /** Raw g8 client instance */\n g8: client,\n };\n};\n","import { jitsuAnalytics } from \"@jitsu/js\";\nimport type { AnalyticsInterface } from \"@jitsu/js\";\nimport type { G8Config, TrackProperties, IdentifyProperties } from \"./types\";\nimport { createFormsClient } from \"./forms\";\nimport { createVisitorsClient } from \"./visitors\";\nimport { createCopilotClient } from \"./copilot\";\nimport { createChatClient } from \"./chat\";\nimport { createCalendarClient } from \"./calendar\";\nimport { createEnrichClient } from \"./enrich\";\nimport { createSequencesClient } from \"./sequences\";\nimport { createCampaignsClient } from \"./campaigns\";\nimport { createIntegrationsClient } from \"./integrations\";\nimport { createSignalsClient } from \"./signals\";\nimport { createAnalyticsClient } from \"./analytics\";\nimport { createVoiceClient } from \"./voice\";\nimport { createPagesClient } from \"./pages\";\nimport { createWebhooksClient } from \"./webhooks\";\nimport { createContactsClient } from \"./contacts\";\nimport { createCompaniesClient } from \"./companies\";\nimport { createListsClient } from \"./lists\";\nimport { createNotesClient } from \"./notes\";\nimport { createTasksClient } from \"./tasks\";\nimport { createFieldsClient } from \"./fields\";\nimport { createDealsClient } from \"./deals\";\nimport { createInboxClient } from \"./inbox\";\nimport { createQuotesClient } from \"./quotes\";\nimport { createPipelinesClient } from \"./pipelines\";\nimport { createWorkflowsClient } from \"./workflows\";\nimport { createSkillsClient } from \"./skills\";\nimport { createIntentClient } from \"./intent\";\nimport { createStudioClient } from \"./studio\";\nimport { createMeetingsClient } from \"./meetings\";\nimport { isServer } from \"./utils\";\n\nconst DEFAULT_HOST = \"https://t.graph8.com\";\nconst DEFAULT_API = \"https://be.graph8.com\";\n\n/**\n * graph8 SDK client.\n *\n * Handles event tracking, identity, and progressive forms.\n *\n * Usage:\n * import { g8 } from '@graph8/js';\n * g8.init({ writeKey: 'your_write_key' });\n * g8.track('page_view', { page: '/pricing' });\n * g8.identify('user@acme.com', { name: 'John', company: 'Acme' });\n */\nclass G8 {\n /** @internal */ client: AnalyticsInterface | null = null;\n /** @internal */ config: G8Config | null = null;\n /** @internal */ _forms: ReturnType<typeof createFormsClient> | null = null;\n /** @internal */ _visitors: ReturnType<typeof createVisitorsClient> | null = null;\n /** @internal */ _copilot: ReturnType<typeof createCopilotClient> | null = null;\n /** @internal */ _chat: ReturnType<typeof createChatClient> | null = null;\n /** @internal */ _calendar: ReturnType<typeof createCalendarClient> | null = null;\n /** @internal */ _enrich: ReturnType<typeof createEnrichClient> | null = null;\n /** @internal */ _sequences: ReturnType<typeof createSequencesClient> | null = null;\n /** @internal */ _campaigns: ReturnType<typeof createCampaignsClient> | null = null;\n /** @internal */ _integrations: ReturnType<typeof createIntegrationsClient> | null = null;\n /** @internal */ _signals: ReturnType<typeof createSignalsClient> | null = null;\n /** @internal */ _analytics: ReturnType<typeof createAnalyticsClient> | null = null;\n /** @internal */ _voice: ReturnType<typeof createVoiceClient> | null = null;\n /** @internal */ _pages: ReturnType<typeof createPagesClient> | null = null;\n /** @internal */ _webhooks: ReturnType<typeof createWebhooksClient> | null = null;\n /** @internal */ _contacts: ReturnType<typeof createContactsClient> | null = null;\n /** @internal */ _companies: ReturnType<typeof createCompaniesClient> | null = null;\n /** @internal */ _lists: ReturnType<typeof createListsClient> | null = null;\n /** @internal */ _notes: ReturnType<typeof createNotesClient> | null = null;\n /** @internal */ _tasks: ReturnType<typeof createTasksClient> | null = null;\n /** @internal */ _fields: ReturnType<typeof createFieldsClient> | null = null;\n /** @internal */ _deals: ReturnType<typeof createDealsClient> | null = null;\n /** @internal */ _inbox: ReturnType<typeof createInboxClient> | null = null;\n /** @internal */ _quotes: ReturnType<typeof createQuotesClient> | null = null;\n /** @internal */ _pipelines: ReturnType<typeof createPipelinesClient> | null = null;\n /** @internal */ _workflows: ReturnType<typeof createWorkflowsClient> | null = null;\n /** @internal */ _skills: ReturnType<typeof createSkillsClient> | null = null;\n /** @internal */ _intent: ReturnType<typeof createIntentClient> | null = null;\n /** @internal */ _studio: ReturnType<typeof createStudioClient> | null = null;\n /** @internal */ _meetings: ReturnType<typeof createMeetingsClient> | null = null;\n\n /**\n * Initialize the graph8 SDK. Must be called before any other method.\n * Safe to call on the server (SSR) - becomes a no-op for tracking.\n */\n init(config: G8Config): void {\n this.config = config;\n\n if (!isServer) {\n this.client = jitsuAnalytics({\n host: config.host || DEFAULT_HOST,\n writeKey: config.writeKey || \"\",\n debug: config.debug,\n });\n }\n\n const apiUrl = config.apiUrl || DEFAULT_API;\n const writeKey = config.writeKey || \"\";\n const apiKey = config.apiKey || \"\";\n\n // Public (write key) clients\n if (writeKey) {\n this._forms = createFormsClient(writeKey, apiUrl);\n this._visitors = createVisitorsClient(writeKey, apiUrl);\n this._copilot = createCopilotClient(writeKey, apiUrl);\n this._chat = createChatClient(writeKey, apiUrl);\n this._calendar = createCalendarClient(apiUrl);\n this._signals = createSignalsClient(writeKey, false, apiUrl);\n }\n\n // Private (API key) clients\n if (apiKey) {\n this._enrich = createEnrichClient(apiKey, apiUrl);\n this._sequences = createSequencesClient(apiKey, apiUrl);\n this._campaigns = createCampaignsClient(apiKey, apiUrl);\n this._integrations = createIntegrationsClient(apiKey, apiUrl);\n this._analytics = createAnalyticsClient(apiKey, apiUrl);\n this._voice = createVoiceClient(apiKey, apiUrl);\n this._pages = createPagesClient(apiKey, apiUrl);\n this._webhooks = createWebhooksClient(apiKey, apiUrl);\n this._contacts = createContactsClient(apiKey, apiUrl);\n this._companies = createCompaniesClient(apiKey, apiUrl);\n this._lists = createListsClient(apiKey, apiUrl);\n this._notes = createNotesClient(apiKey, apiUrl);\n this._tasks = createTasksClient(apiKey, apiUrl);\n this._fields = createFieldsClient(apiKey, apiUrl);\n this._deals = createDealsClient(apiKey, apiUrl);\n this._inbox = createInboxClient(apiKey, apiUrl);\n this._quotes = createQuotesClient(apiKey, apiUrl);\n this._pipelines = createPipelinesClient(apiKey, apiUrl);\n this._workflows = createWorkflowsClient(apiKey, apiUrl);\n this._skills = createSkillsClient(apiKey, apiUrl);\n this._intent = createIntentClient(apiKey, apiUrl);\n this._studio = createStudioClient(apiKey, apiUrl);\n this._meetings = createMeetingsClient(apiKey, apiUrl);\n // Override signals with API key version for full access\n this._signals = createSignalsClient(apiKey, true, apiUrl);\n }\n }\n\n // -- Core tracking (via Jitsu) --\n\n /** Track a custom event. */\n track(event: string, properties?: TrackProperties): void { this.client?.track(event, properties); }\n\n /** Identify a user with properties. */\n identify(userId: string, properties?: IdentifyProperties): void { this.client?.identify(userId, properties); }\n\n /** Track a page view. */\n page(properties?: TrackProperties): void { this.client?.page(properties); }\n\n /** Clear user identity (on logout). */\n reset(): void { this.client?.reset(); }\n\n // -- Module accessors --\n\n /** Progressive form helpers. */\n get forms() { this._assertInit(); return this._forms!; }\n\n /** Visitor intelligence - IP to company, engagement scoring. */\n get visitors() { this._assertInit(); return this._visitors!; }\n\n /** AI copilot widget. */\n get copilot() { this._assertInit(); return this._copilot!; }\n\n /** Webchat widget. */\n get chat() { this._assertInit(); return this._chat!; }\n\n /** Calendar and booking. */\n get calendar() { this._assertInit(); return this._calendar!; }\n\n /** Enrichment API (requires API key). */\n get enrich() { this._assertKey(\"enrich\"); return this._enrich!; }\n\n /** Sequences (requires API key). */\n get sequences() { this._assertKey(\"sequences\"); return this._sequences!; }\n\n /** Campaigns (requires API key). */\n get campaigns() { this._assertKey(\"campaigns\"); return this._campaigns!; }\n\n /** CRM integrations (requires API key). */\n get integrations() { this._assertKey(\"integrations\"); return this._integrations!; }\n\n /** Intent signals. */\n get signals() { this._assertInit(); return this._signals!; }\n\n /** Analytics (requires API key). */\n get analytics() { this._assertKey(\"analytics\"); return this._analytics!; }\n\n /** Voice AI (requires API key). */\n get voice() { this._assertKey(\"voice\"); return this._voice!; }\n\n /** Landing pages (requires API key). */\n get pages() { this._assertKey(\"pages\"); return this._pages!; }\n\n /** Webhook event listeners (requires API key). */\n get webhooks() { this._assertKey(\"webhooks\"); return this._webhooks!; }\n\n /** Contacts CRUD (requires API key). */\n get contacts() { this._assertKey(\"contacts\"); return this._contacts!; }\n\n /** Companies CRUD (requires API key). */\n get companies() { this._assertKey(\"companies\"); return this._companies!; }\n\n /** Lists management (requires API key). */\n get lists() { this._assertKey(\"lists\"); return this._lists!; }\n\n /** Notes on contacts (requires API key). */\n get notes() { this._assertKey(\"notes\"); return this._notes!; }\n\n /** Tasks on contacts (requires API key). */\n get tasks() { this._assertKey(\"tasks\"); return this._tasks!; }\n\n /** Custom fields management (requires API key). */\n get fields() { this._assertKey(\"fields\"); return this._fields!; }\n\n /** Deals and pipelines (requires API key). */\n get deals() { this._assertKey(\"deals\"); return this._deals!; }\n\n /** Multi-channel inbox — read + reply across email, SMS, LinkedIn (requires API key). */\n get inbox() { this._assertKey(\"inbox\"); return this._inbox!; }\n\n /** Quote-to-cash: draft, send, sign, payment-link quotes (requires API key). */\n get quotes() { this._assertKey(\"quotes\"); return this._quotes!; }\n\n /** Stage Checklist v2 pipelines: workflow stages with evidence + scripts (requires API key). */\n get pipelines() { this._assertKey(\"pipelines\"); return this._pipelines!; }\n\n /** Workflow builder — multi-node automation graphs with execution lifecycle (requires API key). */\n get workflows() { this._assertKey(\"workflows\"); return this._workflows!; }\n\n /** Skill authoring — LLM and API building blocks that workflows compose (requires API key). */\n get skills() { this._assertKey(\"skills\"); return this._skills!; }\n\n /** Intent tracking — keyword groups, page visitors, account-level intent (requires API key). */\n get intent() { this._assertKey(\"intent\"); return this._intent!; }\n\n /** Studio context — ICPs, personas, brand briefs, intelligence, AI research reports (requires API key). */\n get studio() { this._assertKey(\"studio\"); return this._studio!; }\n\n /** Meetings — read scheduled, completed, cancelled meetings with transcripts + AI analysis (requires API key). */\n get meetings() { this._assertKey(\"meetings\"); return this._meetings!; }\n\n /** Whether the SDK has been initialized. */\n get initialized(): boolean { return this.config !== null; }\n\n /** @internal */\n _assertInit(): void {\n if (!this.config) throw new Error(\"g8.init() must be called first\");\n }\n\n /** @internal */\n _assertKey(module: string): void {\n this._assertInit();\n if (!this.config!.apiKey) throw new Error(`g8.${module} requires an API key. Use g8.init({ apiKey: '...' })`);\n }\n}\n\n/** Singleton g8 client instance. */\nexport const g8 = new G8();\n","import type { EnrichLookupResult } from \"./types\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\n/**\n * Progressive form enrichment - checks what fields graph8 already knows\n * about a contact so your form can skip those fields.\n *\n * Calls POST /api/v1/public/enrich/lookup (authenticated via write key).\n */\nexport const createFormsClient = (writeKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n\n return {\n /**\n * Look up known fields for an email address.\n *\n * Use this in progressive forms: after the user enters their email,\n * check what graph8 already knows and only show missing fields.\n */\n async lookup(email: string): Promise<EnrichLookupResult> {\n const resp = await fetch(`${baseUrl}/api/v1/public/enrich/lookup`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Write-Key\": writeKey,\n },\n body: JSON.stringify({ email }),\n });\n\n if (!resp.ok) {\n return { found: false, known_fields: {}, missing_fields: [] };\n }\n\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","/** Check if running on the server (SSR). */\nexport const isServer = typeof window === \"undefined\";\n\n/** Safely get the window object (returns undefined on server). */\nexport const getWindow = (): Window | undefined =>\n isServer ? undefined : window;\n","import type { G8Config } from \"./types\";\nimport { isServer } from \"./utils\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface VisitorCompany {\n company_name: string | null;\n company_domain: string | null;\n industry: string | null;\n employee_count: string | null;\n city: string | null;\n country: string | null;\n confidence: number;\n}\n\nexport interface VisitorScore {\n engagement: number;\n intent: \"low\" | \"medium\" | \"high\";\n signals: string[];\n}\n\ntype IntentCallback = (visitor: VisitorCompany & VisitorScore) => void;\n\n/**\n * Visitor intelligence - identify anonymous visitors by IP → company.\n *\n * Requires write key auth. Works client-side only.\n */\nexport const createVisitorsClient = (writeKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n let intentInterval: ReturnType<typeof setInterval> | null = null;\n\n const headers = () => ({\n \"Content-Type\": \"application/json\",\n \"X-Write-Key\": writeKey,\n });\n\n return {\n /** Identify the current visitor's company from their IP address. */\n async identify(): Promise<VisitorCompany> {\n if (isServer) return { company_name: null, company_domain: null, industry: null, employee_count: null, city: null, country: null, confidence: 0 };\n\n const resp = await fetch(`${baseUrl}/api/v1/public/visitors/company`, { headers: headers() });\n if (!resp.ok) return { company_name: null, company_domain: null, industry: null, employee_count: null, city: null, country: null, confidence: 0 };\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get engagement score for the current visitor. */\n async score(): Promise<VisitorScore> {\n if (isServer) return { engagement: 0, intent: \"low\", signals: [] };\n\n const resp = await fetch(`${baseUrl}/api/v1/public/visitors/score`, { headers: headers() });\n if (!resp.ok) return { engagement: 0, intent: \"low\", signals: [] };\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Listen for visitors matching an intent level. Polls every 30 seconds. */\n onIntent(level: \"low\" | \"medium\" | \"high\", callback: IntentCallback): () => void {\n if (isServer) return () => {};\n\n const check = async () => {\n try {\n const [company, scoreData] = await Promise.all([\n this.identify(),\n this.score(),\n ]);\n if (scoreData.intent === level || (level === \"medium\" && scoreData.intent === \"high\")) {\n callback({ ...company, ...scoreData });\n }\n } catch { /* silent */ }\n };\n\n check();\n intentInterval = setInterval(check, 30_000);\n\n return () => {\n if (intentInterval) clearInterval(intentInterval);\n };\n },\n };\n};\n","import { isServer } from \"./utils\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface CopilotConfig {\n /** Initial greeting message */\n greeting?: string;\n /** Context passed to the AI */\n context?: Record<string, unknown>;\n /** Widget position */\n position?: \"bottom-right\" | \"bottom-left\";\n /** Widget theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n}\n\ntype CopilotEvent = \"message\" | \"tool_used\" | \"open\" | \"close\" | \"error\";\ntype CopilotCallback = (data: Record<string, unknown>) => void;\ntype ActionHandler = (params: Record<string, unknown>) => void | Promise<void>;\n\n/**\n * Copilot - embeddable AI assistant with org knowledge base access.\n *\n * Client-side (write key) for the widget embed.\n */\nexport const createCopilotClient = (writeKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const listeners: Map<CopilotEvent, CopilotCallback[]> = new Map();\n const actions: Map<string, ActionHandler> = new Map();\n let widgetEl: HTMLElement | null = null;\n\n const emit = (event: CopilotEvent, data: Record<string, unknown> = {}) => {\n listeners.get(event)?.forEach((cb) => cb(data));\n };\n\n return {\n /** Open the copilot widget. */\n open(config?: CopilotConfig): void {\n if (isServer) return;\n\n // Remove existing widget if any\n if (widgetEl) widgetEl.remove();\n\n const position = config?.position || \"bottom-right\";\n const posStyle = position === \"bottom-left\" ? \"left:16px;\" : \"right:16px;\";\n\n const iframe = document.createElement(\"iframe\");\n iframe.src = `${baseUrl}/copilot/embed?write_key=${writeKey}&theme=${config?.theme || \"auto\"}`;\n iframe.style.cssText = `position:fixed;bottom:16px;${posStyle}width:400px;height:600px;border:none;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,0.15);z-index:99998;`;\n iframe.id = \"g8-copilot-widget\";\n\n document.body.appendChild(iframe);\n widgetEl = iframe;\n emit(\"open\");\n },\n\n /** Send a message to the copilot programmatically. */\n async ask(message: string): Promise<string> {\n const resp = await fetch(`${baseUrl}/api/v1/public/copilot/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"X-Write-Key\": writeKey },\n body: JSON.stringify({ message }),\n });\n if (!resp.ok) return \"Sorry, I could not process that request.\";\n const data = await resp.json();\n return data.response || data.data?.response || \"\";\n },\n\n /** Register a custom action the copilot can trigger. */\n registerAction(name: string, handler: ActionHandler): void {\n actions.set(name, handler);\n },\n\n /** Listen for copilot events. */\n on(event: CopilotEvent, callback: CopilotCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n },\n\n /** Close the copilot widget. */\n close(): void {\n if (widgetEl) {\n widgetEl.remove();\n widgetEl = null;\n emit(\"close\");\n }\n },\n };\n};\n","import { isServer } from \"./utils\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface ChatConfig {\n /** Agent ID to connect to */\n agentId?: string;\n /** Pre-filled first message */\n message?: string;\n /** Widget position */\n position?: \"bottom-right\" | \"bottom-left\";\n /** Widget theme */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Custom greeting */\n greeting?: string;\n /** Custom avatar URL */\n avatar?: string;\n}\n\ntype ChatEvent = \"message\" | \"human_transfer\" | \"open\" | \"close\" | \"error\";\ntype ChatCallback = (data: Record<string, unknown>) => void;\n\n/**\n * Webchat - live chat + AI chat embedded in any app.\n *\n * Uses WebSocket connection to the voice/chat agent backend.\n * Public - no API key needed (org/agent IDs are in the config).\n */\nexport const createChatClient = (writeKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const listeners: Map<ChatEvent, ChatCallback[]> = new Map();\n let widgetEl: HTMLElement | null = null;\n let ws: WebSocket | null = null;\n\n const emit = (event: ChatEvent, data: Record<string, unknown> = {}) => {\n listeners.get(event)?.forEach((cb) => cb(data));\n };\n\n return {\n /** Open the chat widget. */\n open(config?: ChatConfig): void {\n if (isServer) return;\n\n if (widgetEl) widgetEl.remove();\n\n const position = config?.position || \"bottom-right\";\n const posStyle = position === \"bottom-left\" ? \"left:16px;\" : \"right:16px;\";\n\n const iframe = document.createElement(\"iframe\");\n iframe.src = `${baseUrl}/webchat/embed?write_key=${writeKey}&theme=${config?.theme || \"auto\"}`;\n iframe.style.cssText = `position:fixed;bottom:16px;${posStyle}width:380px;height:560px;border:none;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,0.15);z-index:99997;`;\n iframe.id = \"g8-chat-widget\";\n\n document.body.appendChild(iframe);\n widgetEl = iframe;\n emit(\"open\");\n },\n\n /** Send a message. */\n send(message: string): void {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({ type: \"message\", content: message }));\n }\n },\n\n /** Listen for chat events. */\n on(event: ChatEvent, callback: ChatCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n },\n\n /** Configure the chat appearance. */\n configure(config: Partial<ChatConfig>): void {\n // Send config to iframe via postMessage\n if (widgetEl && widgetEl instanceof HTMLIFrameElement) {\n widgetEl.contentWindow?.postMessage({ type: \"g8_chat_config\", config }, \"*\");\n }\n },\n\n /** Close the chat widget. */\n close(): void {\n if (ws) { ws.close(); ws = null; }\n if (widgetEl) { widgetEl.remove(); widgetEl = null; }\n emit(\"close\");\n },\n };\n};\n","import { isServer } from \"./utils\";\n\nconst DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface CalendarConfig {\n /** Event type slug (e.g. \"demo-30min\") */\n eventType: string;\n /** Username of the host */\n username: string;\n /** Pre-fill attendee info */\n prefill?: { name?: string; email?: string; notes?: string };\n}\n\nexport interface TimeSlot {\n start: string;\n end: string;\n available: boolean;\n}\n\nexport interface Booking {\n uid: string;\n confirmation_url: string;\n start_time: string;\n end_time: string;\n}\n\nexport interface BookingRequest {\n event_type_id: number;\n slot: string;\n attendee: { name: string; email: string; notes?: string };\n}\n\ntype CalendarEvent = \"booked\" | \"cancelled\" | \"slot_selected\";\ntype CalendarCallback = (data: Record<string, unknown>) => void;\n\n/**\n * Calendar and booking - show scheduling widgets, get slots, book meetings.\n *\n * Public endpoints - no API key needed.\n */\nexport const createCalendarClient = (apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const listeners: Map<CalendarEvent, CalendarCallback[]> = new Map();\n\n return {\n /** Show a booking modal overlay. */\n show(config: CalendarConfig): void {\n if (isServer) return;\n\n const url = `${baseUrl}/appointments/${config.username}/${config.eventType}`;\n const params = new URLSearchParams();\n if (config.prefill?.name) params.set(\"name\", config.prefill.name);\n if (config.prefill?.email) params.set(\"email\", config.prefill.email);\n\n const iframe = document.createElement(\"iframe\");\n iframe.src = `${url}?${params.toString()}`;\n iframe.style.cssText = \"position:fixed;top:0;left:0;width:100%;height:100%;border:none;z-index:99999;background:rgba(0,0,0,0.5);\";\n iframe.id = \"g8-calendar-modal\";\n document.body.appendChild(iframe);\n\n // Close on escape\n const onKey = (e: KeyboardEvent) => { if (e.key === \"Escape\") { iframe.remove(); document.removeEventListener(\"keydown\", onKey); } };\n document.addEventListener(\"keydown\", onKey);\n },\n\n /** Embed booking widget inline in a container element. */\n embed(selector: string, config: CalendarConfig): void {\n if (isServer) return;\n\n const container = document.querySelector(selector);\n if (!container) return;\n\n const url = `${baseUrl}/appointments/${config.username}/${config.eventType}`;\n const iframe = document.createElement(\"iframe\");\n iframe.src = url;\n iframe.style.cssText = \"width:100%;min-height:600px;border:none;border-radius:8px;\";\n container.appendChild(iframe);\n },\n\n /** Get available time slots for an event type. */\n async slots(username: string, eventSlug: string, range: { start: string; end: string }): Promise<TimeSlot[]> {\n const params = new URLSearchParams({\n start_date: range.start,\n end_date: range.end,\n });\n const resp = await fetch(`${baseUrl}/appointments/public/slots?username=${username}&event_slug=${eventSlug}&${params.toString()}`);\n if (!resp.ok) return [];\n const data = await resp.json();\n return data.slots || data.data || [];\n },\n\n /** Book a meeting programmatically. */\n async book(request: BookingRequest): Promise<Booking | null> {\n const resp = await fetch(`${baseUrl}/appointments/public/bookings`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n if (!resp.ok) return null;\n const data = await resp.json();\n const emit = listeners.get(\"booked\");\n if (emit) emit.forEach((cb) => cb(data));\n return data;\n },\n\n /** Listen for calendar events. */\n on(event: CalendarEvent, callback: CalendarCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface PersonEnrichment {\n found: boolean;\n confidence: number;\n data: Record<string, unknown>;\n}\n\nexport interface CompanyEnrichment {\n found: boolean;\n confidence: number;\n data: Record<string, unknown>;\n}\n\nexport interface EmailVerification {\n email: string;\n valid: boolean;\n deliverable: boolean;\n catch_all: boolean;\n}\n\nexport interface SearchFilter {\n field: string;\n operator: \"any_of\" | \"contains\" | \"all_of\" | \"none_of\" | \"is_empty\" | \"is_not_empty\" | \"between\" | \"exists\";\n value: unknown;\n}\n\nexport interface SearchResults {\n contacts: Record<string, unknown>[];\n total: number;\n page: number;\n}\n\n/**\n * Enrichment API - person/company lookup, email verification, prospecting search.\n *\n * Requires API key (server-side only). Credits charged per call.\n */\nexport const createEnrichClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n\n const headers = () => ({\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n });\n\n return {\n /** Look up a person by email, LinkedIn, or name + company. Costs 1 credit. */\n async person(params: {\n email?: string;\n linkedin_url?: string;\n first_name?: string;\n last_name?: string;\n company_domain?: string;\n }): Promise<PersonEnrichment> {\n const resp = await fetch(`${baseUrl}/api/v1/enrichment/lookup/person`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Look up a company by domain or name. Costs 1 credit. */\n async company(params: { domain?: string; name?: string }): Promise<CompanyEnrichment> {\n const resp = await fetch(`${baseUrl}/api/v1/enrichment/lookup/company`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Verify an email address. Costs 1 credit. */\n async verifyEmail(email: string): Promise<EmailVerification> {\n const resp = await fetch(`${baseUrl}/api/v1/enrichment/verify-email`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ email }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Search 300M+ contacts with filters. Credits charged per result. */\n async search(filters: SearchFilter[], page = 1, limit = 25): Promise<SearchResults> {\n const resp = await fetch(`${baseUrl}/api/v1/search/contacts`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ filters, page, limit }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n// -- Existing types (preserved for backwards compat) --\n\nexport interface Sequence {\n id: string;\n name: string;\n status: string;\n step_count: number | null;\n contact_count: number | null;\n}\n\nexport interface AddToSequenceConfig {\n sequenceId: string;\n contactIds: number[];\n listId: number;\n}\n\n// -- New (0.4.0) types --\n\nexport interface SequenceListItem {\n id: string;\n name: string | null;\n status: string | null;\n user_email: string | null;\n step_count: number | null;\n contact_count: number | null;\n sequence_kind: string | null;\n associated_list_id: number | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface SequenceListParams {\n page?: number;\n limit?: number;\n /** Filter by sequence status (e.g. \"live\", \"draft\", \"paused\"). */\n status?: string;\n /** Filter by sequence kind (\"cold_outbound\" or \"nurture\"). Omit to list all kinds. */\n sequence_kind?: SequenceKind;\n}\n\nexport interface SequenceDetail {\n id: string;\n name: string | null;\n description: string | null;\n status: string | null;\n user_email: string | null;\n associated_list_id: number | null;\n finish_on_reply: boolean;\n send_in_same_thread: boolean;\n wait_for_new_contacts: boolean;\n paused_at: string | null;\n resumed_at: string | null;\n /** Sequence kind. Immutable after creation. \"cold_outbound\" (default) or \"nurture\". */\n sequence_kind?: string | null;\n /** Pinned mailbox for nurture sequences; null for cold_outbound. Immutable. */\n pinned_mailbox_id?: number | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface SequenceContactItem {\n id: string | null;\n contact_id: number | null;\n state: string | null;\n current_step_order: number | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface SequenceContactsParams {\n page?: number;\n limit?: number;\n /** Filter by contact state (e.g. \"active\", \"completed\", \"replied\"). */\n state?: string;\n}\n\nexport interface SequenceActionResult {\n sequence_id: string;\n status: string;\n contacts_affected: number;\n}\n\n/**\n * Step type. Note: LinkedIn flows use \"HEYREACH\" — there is no \"LINKEDIN\" step type.\n * Server is case-insensitive on input but stores uppercase.\n */\nexport type SequenceStepType =\n | \"EMAIL\"\n | \"PHONE\"\n | \"SMS\"\n | \"WHATSAPP\"\n | \"HEYREACH\"\n | \"MANUAL_DIALER\";\n\nexport type SequenceStepInputType =\n | \"ON_DEMAND\"\n | \"MANUAL_TEMPLATE\"\n | \"AI_GENERATED_TEMPLATE\";\n\nexport interface SequenceStepConfig {\n step_order: number;\n step_type: SequenceStepType | string;\n /** Defaults to \"ON_DEMAND\". */\n input_type?: SequenceStepInputType | string;\n /** Wait time before this step in seconds. Defaults to 0. */\n time_interval?: number;\n /** Template body, AI prompt, or other step-type-specific config. */\n step_data?: Record<string, unknown>;\n}\n\nexport interface SequenceChannelConfig {\n channel_id: number;\n channel_value: string;\n channel_type: string;\n channel_data?: Record<string, unknown>;\n}\n\n/**\n * Sequence kind. A \"nurture\" is an ordinary sequence with `sequence_kind:\n * \"nurture\"` — same step types as cold outreach, but pinned to a single mailbox\n * with a higher daily email cap. There is no separate nurture client; create one\n * via `sequences.create({ sequence_kind: \"nurture\", pinned_mailbox_id })`.\n */\nexport type SequenceKind = \"cold_outbound\" | \"nurture\";\n\nexport interface SequenceCreateParams {\n name: string;\n user_email: string;\n description?: string;\n finish_on_reply?: boolean;\n send_in_same_thread?: boolean;\n wait_for_new_contacts?: boolean;\n associated_list_id?: number;\n steps?: SequenceStepConfig[];\n channels?: SequenceChannelConfig[];\n campaign_id?: string;\n /**\n * Sequence kind. Defaults to \"cold_outbound\" server-side. Immutable after\n * creation. \"nurture\" requires `pinned_mailbox_id` and is gated by the\n * ENABLE_NURTURE feature flag.\n */\n sequence_kind?: SequenceKind;\n /**\n * Mailbox to pin for a nurture sequence. Required when\n * `sequence_kind: \"nurture\"`; all email channels must use this mailbox.\n * Ignored for cold_outbound sequences.\n */\n pinned_mailbox_id?: number;\n}\n\nexport interface SequenceCreateResult {\n id: string;\n name: string;\n status: string;\n created_at: string | null;\n}\n\nexport interface SequenceUpdateParams {\n name?: string;\n description?: string;\n is_shared?: boolean;\n finish_on_reply?: boolean;\n send_in_same_thread?: boolean;\n wait_for_new_contacts?: boolean;\n schedule_id?: string;\n appointment_id?: number;\n}\n\nexport interface SequenceStepUpdateParams {\n step_data?: Record<string, unknown>;\n time_interval?: number;\n step_type?: SequenceStepType | string;\n input_type?: SequenceStepInputType | string;\n}\n\nexport interface SequencePreviewStep {\n id: string;\n step_order: number;\n step_type: string;\n input_type: string;\n time_interval: number | null;\n step_data: Record<string, unknown> | null;\n}\n\nexport interface SequencePreviewChannel {\n id: string;\n channel_id: number | null;\n channel_value: string | null;\n channel_type: string | null;\n}\n\nexport interface SequencePreview {\n id: string;\n name: string | null;\n status: string | null;\n description: string | null;\n steps: SequencePreviewStep[];\n channels: SequencePreviewChannel[];\n}\n\nexport interface SequenceAnalytics {\n overview: Record<string, unknown>;\n performance: Record<string, unknown>;\n engagement: Record<string, unknown>;\n timeline: Record<string, unknown>[];\n contact_distribution: Record<string, unknown>;\n step_breakdown: Record<string, unknown>[];\n step_creation_methods: Record<string, unknown>[];\n sender_distribution: Record<string, unknown>[];\n}\n\nexport interface PaginationMeta {\n page: number;\n limit: number;\n total: number;\n has_next: boolean;\n}\n\n/**\n * Sequences API — list, create, run, pause, update, analyze multi-channel sequences.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/sequences\n * POST /api/v1/sequences\n * GET /api/v1/sequences/{sequence_id}\n * PATCH /api/v1/sequences/{sequence_id}\n * DELETE /api/v1/sequences/{sequence_id}\n * GET /api/v1/sequences/{sequence_id}/contacts\n * POST /api/v1/sequences/{sequence_id}/contacts\n * POST /api/v1/sequences/{sequence_id}/run\n * POST /api/v1/sequences/{sequence_id}/pause\n * POST /api/v1/sequences/{sequence_id}/resume\n * PATCH /api/v1/sequences/{sequence_id}/steps/{step_id}\n * GET /api/v1/sequences/{sequence_id}/preview\n * GET /api/v1/sequences/{sequence_id}/analytics\n */\nexport const createSequencesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n // -- Overloads on list() preserve backwards compat with v0.3.0's positional signature --\n\n async function list(): Promise<SequenceListItem[]>;\n async function list(page: number, limit?: number): Promise<SequenceListItem[]>;\n async function list(params: SequenceListParams): Promise<SequenceListItem[]>;\n async function list(\n pageOrParams?: number | SequenceListParams,\n limit?: number,\n ): Promise<SequenceListItem[]> {\n let params: SequenceListParams;\n if (typeof pageOrParams === \"number\") {\n params = { page: pageOrParams, limit: limit ?? 50 };\n } else {\n params = pageOrParams ?? {};\n }\n const resp = await fetch(`${baseUrl}/api/v1/sequences${toQuery(params)}`, { headers: headers() });\n const data = await resp.json();\n return (data.data || data) as SequenceListItem[];\n }\n\n return {\n /** List sequences with pagination + optional status filter. */\n list,\n\n /** Get full sequence details by ID. */\n async get(sequenceId: string): Promise<SequenceDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List contacts enrolled in a sequence. Filter by state (e.g. \"active\", \"replied\"). */\n async contacts(\n sequenceId: string,\n params: SequenceContactsParams = {},\n ): Promise<{ data: SequenceContactItem[]; pagination?: PaginationMeta }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/sequences/${sequenceId}/contacts${toQuery(params)}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Add contacts to a sequence (V2 queuing). Live or drafted sequences only. */\n async add(config: AddToSequenceConfig): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${config.sequenceId}/contacts`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ contact_ids: config.contactIds, list_id: config.listId }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a new sequence with optional steps + channels. */\n async create(payload: SequenceCreateParams): Promise<SequenceCreateResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(payload),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update sequence metadata. Rejected (409) if sequence is in a transitional status. */\n async update(sequenceId: string, fields: SequenceUpdateParams): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a single step within a sequence. */\n async updateStep(\n sequenceId: string,\n stepId: string,\n fields: SequenceStepUpdateParams,\n ): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/steps/${stepId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Soft-delete (archive) a sequence. */\n async delete(sequenceId: string): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Run/start a DRAFTED sequence (V2 orchestration). */\n async run(sequenceId: string): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/run`, {\n method: \"POST\",\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Pause a live sequence. */\n async pause(sequenceId: string): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/pause`, {\n method: \"POST\",\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Resume a paused sequence. */\n async resume(sequenceId: string): Promise<SequenceActionResult> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/resume`, {\n method: \"POST\",\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Read-only sequence preview with all steps + channels (no enrollment). */\n async preview(sequenceId: string): Promise<SequencePreview> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/preview`, {\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Comprehensive analytics for a sequence. */\n async analytics(sequenceId: string): Promise<SequenceAnalytics> {\n const resp = await fetch(`${baseUrl}/api/v1/sequences/${sequenceId}/analytics`, {\n headers: headers(),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Campaign {\n id: string;\n name: string;\n slug: string;\n status: string;\n category: string | null;\n goal: string | null;\n target_persona: string | null;\n}\n\nexport interface CampaignCreateConfig {\n name: string;\n category?: string;\n brief?: string;\n core_concept?: string;\n primary_hook?: string;\n target_persona?: string;\n goal?: string;\n}\n\nexport interface CampaignStats {\n sent: number;\n opened: number;\n replied: number;\n meetings: number;\n}\n\n/**\n * Campaigns - create, manage, launch campaigns. Requires API key (server-side).\n */\nexport const createCampaignsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n async list(page = 1, limit = 50): Promise<Campaign[]> {\n const resp = await fetch(`${baseUrl}/api/v1/campaigns?page=${page}&limit=${limit}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n async get(campaignId: string): Promise<Campaign> {\n const resp = await fetch(`${baseUrl}/api/v1/campaigns/${campaignId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n async create(config: CampaignCreateConfig): Promise<Campaign> {\n const resp = await fetch(`${baseUrl}/api/v1/campaigns`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify(config),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n async launch(campaignId: string): Promise<void> {\n await fetch(`${baseUrl}/api/v1/campaigns/${campaignId}/launch`, {\n method: \"POST\", headers: headers(),\n });\n },\n\n async stats(campaignId: string): Promise<CampaignStats> {\n const resp = await fetch(`${baseUrl}/api/v1/campaigns/${campaignId}/stats`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Integration {\n id: string;\n provider: string;\n status: string;\n connected_at: string | null;\n}\n\n/**\n * Integrations - connect CRM platforms, trigger syncs. Requires API key (server-side).\n */\nexport const createIntegrationsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n async list(): Promise<Integration[]> {\n const resp = await fetch(`${baseUrl}/api/v1/integrations`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n async connect(provider: string, config?: Record<string, unknown>): Promise<void> {\n await fetch(`${baseUrl}/api/v1/integrations/connect`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify({ provider, ...config }),\n });\n },\n\n async sync(provider: string, config?: { direction?: \"inbound\" | \"outbound\" | \"bidirectional\" }): Promise<void> {\n await fetch(`${baseUrl}/api/v1/integrations/sync`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify({ provider, ...config }),\n });\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface IntentSignals {\n domain: string;\n score: number;\n intent: \"low\" | \"medium\" | \"high\";\n signals: string[];\n last_seen: string | null;\n}\n\n/**\n * Intent signals - company-level buying signals. Write key for public, API key for full access.\n */\nexport const createSignalsClient = (key: string, isApiKey: boolean, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n\n const headers = (): Record<string, string> => isApiKey\n ? { \"Content-Type\": \"application/json\", \"Authorization\": `Bearer ${key}` }\n : { \"Content-Type\": \"application/json\", \"X-Write-Key\": key };\n\n const endpoint = isApiKey ? \"/api/v1/signals/company\" : \"/api/v1/public/signals/company\";\n\n return {\n /** Get intent signals for a specific company domain. */\n async company(domain: string): Promise<IntentSignals> {\n const resp = await fetch(`${baseUrl}${endpoint}?domain=${encodeURIComponent(domain)}`, { headers: headers() });\n if (!resp.ok) return { domain, score: 0, intent: \"low\", signals: [], last_seen: null };\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Stream intent signals - calls callback every 30s with latest data. */\n stream(domains: string[], callback: (signals: IntentSignals[]) => void): () => void {\n const check = async () => {\n try {\n const results = await Promise.all(domains.map((d) => this.company(d)));\n callback(results);\n } catch { /* silent */ }\n };\n\n check();\n const interval = setInterval(check, 30_000);\n return () => clearInterval(interval);\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface AnalyticsOverview {\n visitors: number;\n contacts_created: number;\n emails_sent: number;\n emails_opened: number;\n replies: number;\n meetings_booked: number;\n period: string;\n}\n\n/**\n * Analytics - dashboard data and metrics. Requires API key (server-side).\n */\nexport const createAnalyticsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n async overview(config?: { period?: string; metrics?: string[] }): Promise<AnalyticsOverview> {\n const params = new URLSearchParams();\n if (config?.period) params.set(\"period\", config.period);\n const resp = await fetch(`${baseUrl}/api/v1/analytics/overview?${params.toString()}`, { headers: headers() });\n if (!resp.ok) return { visitors: 0, contacts_created: 0, emails_sent: 0, emails_opened: 0, replies: 0, meetings_booked: 0, period: config?.period || \"30d\" };\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n// -- Existing (preview) types — preserved for backwards compat with v0.3.0 --\n\nexport interface VoiceSession {\n id: string;\n status: string;\n agent: string;\n started_at: string;\n}\n\nexport interface CallAnalysis {\n duration_seconds: number;\n sentiment: \"positive\" | \"neutral\" | \"negative\";\n summary: string;\n next_steps: string[];\n objections: string[];\n transcript: Array<{ speaker: string; text: string; timestamp: number }>;\n}\n\ntype VoiceEvent = \"connected\" | \"transcription\" | \"ended\" | \"error\";\ntype VoiceCallback = (data: Record<string, unknown>) => void;\n\n// -- New (0.4.0) dialer types — backed by /api/v1/voice/dialer/* --\n\nexport interface VoicePagination {\n total_items: number;\n total_pages: number;\n current_page: number;\n page_size: number;\n}\n\nexport interface DialerSessionSummary {\n session_id: string;\n status: string | null;\n user_id: string | null;\n user_email: string | null;\n org_id: string | null;\n from_phone: string | null;\n campaign_id: string | null;\n campaign_builder_campaign_id: string | null;\n name: string | null;\n session_metadata: Record<string, unknown> | null;\n total_calls: number | null;\n created_at: string | null;\n updated_at: string | null;\n contact_ids: unknown[];\n}\n\nexport interface DialerSessionsListResult {\n sessions: DialerSessionSummary[];\n pagination: VoicePagination;\n}\n\nexport interface DialerSessionsListParams {\n page?: number;\n /** Default 50, max 200. */\n page_size?: number;\n /** Comma-separated status list (e.g. \"ACTIVE,PAUSED\"). */\n status?: string;\n user_email?: string;\n /** Substring search on session name. */\n name?: string;\n campaign_id?: string;\n list_id?: string;\n list_name?: string;\n /** ISO 8601 timestamp. */\n date_from?: string;\n /** ISO 8601 timestamp. */\n date_to?: string;\n sort_by?: string;\n /** Default \"desc\". */\n sort_order?: \"asc\" | \"desc\";\n}\n\nexport interface DialerStatsParams {\n session_id?: string;\n user_email?: string;\n /** YYYY-MM-DD. */\n date_from?: string;\n /** YYYY-MM-DD. */\n date_to?: string;\n /** Default \"DAILY\". */\n aggregation?: \"DAILY\" | \"TOTAL\";\n}\n\nexport interface DialerReportFilters {\n session_id: string | null;\n user_email: string | null;\n org_id: string | null;\n date_from: string | null;\n date_to: string | null;\n aggregation: string | null;\n}\n\nexport interface DialerReportMetric {\n date: string | null;\n sdr_name: string | null;\n org_id: string | null;\n list_title: string | null;\n total_dials: number;\n total_connections: number;\n connection_rate: number;\n total_voicemails: number;\n voicemail_rate: number;\n talk_time_minutes: number;\n avg_call_duration_minutes: number;\n dispositions: Record<string, unknown> | null;\n success_rate: number;\n unique_sessions: number;\n avg_calls_per_session: number;\n redial_count: number;\n redial_success_rate: number | null;\n peak_calling_hour: number | null;\n total_callbacks: number;\n}\n\nexport interface DialerStatsResult {\n filters: DialerReportFilters;\n metrics: DialerReportMetric[];\n summary: DialerReportMetric | null;\n}\n\nexport interface DialerNumberInfo {\n number: string;\n /** Default \"ai\". */\n inbound_type: string;\n /** Default \"twilio\". */\n telephony_provider: string;\n calls_today: number;\n calls_7d: number;\n connect_rate_7d: number;\n is_valid: boolean;\n daily_limit: number;\n assigned_to: string | null;\n created_at: string | null;\n}\n\nexport interface DialerNumbersListResult {\n numbers: DialerNumberInfo[];\n}\n\nexport interface MissedCallback {\n id: string | number | null;\n caller_phone: string | null;\n inbound_number: string | null;\n first_name: string | null;\n last_name: string | null;\n email: string | null;\n contact_id: string | number | null;\n parallel_session_id: string | null;\n created_at: string | null;\n call_duration: number | null;\n is_callback: boolean;\n}\n\nexport interface MissedCallbacksResult {\n missed_callbacks: MissedCallback[];\n count: number;\n}\n\nexport interface CallGradingResult {\n room_name: string;\n /** \"ready\" or \"pending\". */\n status: string;\n grading: Record<string, unknown> | null;\n reviewed: boolean;\n reviewed_at: string | null;\n}\n\nexport interface DialerAgentSummary {\n agent_id: string;\n agent_name: string | null;\n /** \"SDR\", etc. */\n role: string | null;\n agent_status: string | null;\n /** \"agent\" or \"twin\". */\n entity_type: string | null;\n description: string | null;\n phone: string | null;\n is_template: boolean;\n}\n\nexport interface DialerAgentsListResult {\n agents: DialerAgentSummary[];\n total_count: number;\n}\n\nexport interface DialerAgentsListParams {\n /** e.g. \"SDR\". */\n role?: string;\n agent_status?: string;\n /** \"agent\" or \"twin\". */\n entity_type?: \"agent\" | \"twin\";\n /** Substring filter on name/description. */\n search?: string;\n}\n\nexport interface DialerSessionCreateParams {\n /** 1-200 chars. */\n name: string;\n /** Org's dialer phone (E.164, 9-16 chars). */\n from_phone: string;\n /** Contact list ID (stored in session metadata). */\n list_id?: string;\n /** Display title for the source list. */\n list_title?: string;\n /** V2 agent UUID. */\n agent_id?: string;\n /** V1 fallback name. Defaults to \"default_agent\". */\n agent_name?: string;\n /** \"agent\" or \"twin\". */\n entity_type?: \"agent\" | \"twin\";\n /** Campaign Builder UUID. */\n studio_campaign_id?: string;\n /** IANA timezone (e.g. \"America/New_York\"). */\n user_timezone?: string;\n /** Per-session voicemail-skip override. null/omit = use SDR default. */\n skip_voicemails?: boolean;\n}\n\nexport interface DialerSessionCreateResult {\n session_id: string;\n status: string;\n name: string | null;\n org_id: string | null;\n user_id: string | null;\n user_email: string | null;\n from_phone: string | null;\n session_metadata: Record<string, unknown> | null;\n total_calls: number;\n created_at: string | null;\n message: string | null;\n}\n\n/** \"ACTIVE\" resumes, \"PAUSED\" pauses, \"COMPLETED\" stops. \"FAILED\" is rejected. */\nexport type DialerSessionStatus = \"ACTIVE\" | \"PAUSED\" | \"COMPLETED\";\n\nexport interface DialerSessionStatusUpdateResult {\n session_id: string;\n status: string;\n message: string | null;\n name: string | null;\n org_id: string | null;\n user_id: string | null;\n user_email: string | null;\n from_phone: string | null;\n session_metadata: Record<string, unknown> | null;\n total_calls: number;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface DialerSessionResumeResult extends DialerSessionStatusUpdateResult {\n /** Contacts actually placed in this batch (voice caps at 4). */\n dialed_count: number;\n}\n\n/**\n * Voice AI — start AI voice calls, get transcriptions and analysis.\n * Plus full parallel-dialer session control via the `dialer` namespace.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/voice/dialer/sessions\n * POST /api/v1/voice/dialer/sessions\n * PATCH /api/v1/voice/dialer/sessions/{session_id}/status\n * POST /api/v1/voice/dialer/sessions/{session_id}/resume\n * GET /api/v1/voice/dialer/stats\n * GET /api/v1/voice/dialer/numbers\n * GET /api/v1/voice/dialer/missed-callbacks\n * GET /api/v1/voice/dialer/calls/{room_name}/grading\n * GET /api/v1/voice/dialer/agents\n */\nexport const createVoiceClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n const listeners: Map<VoiceEvent, VoiceCallback[]> = new Map();\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n const dialer = {\n /** List parallel-dialer sessions with filters + pagination. */\n async listSessions(params: DialerSessionsListParams = {}): Promise<DialerSessionsListResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/sessions${toQuery(params)}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a parallel-dialer session in PAUSED state. SDR opens UI to start dialing. */\n async createSession(payload: DialerSessionCreateParams): Promise<DialerSessionCreateResult> {\n const resp = await fetch(`${baseUrl}/api/v1/voice/dialer/sessions`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(payload),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Pause / resume / stop a dialer session via status flip. */\n async updateSessionStatus(\n sessionId: string,\n status: DialerSessionStatus,\n ): Promise<DialerSessionStatusUpdateResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/sessions/${sessionId}/status`,\n {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify({ status }),\n },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /**\n * Resume a PAUSED dialer session. Auto-fetches the next batch from the source list,\n * filters already-called + phoneless rows, and forwards to voice's start-session.\n * @param maxContacts 1-4 (voice caps parallel dialing at 4). Default 4.\n */\n async resumeSession(sessionId: string, maxContacts = 4): Promise<DialerSessionResumeResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/sessions/${sessionId}/resume`,\n {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ max_contacts: maxContacts }),\n },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Aggregated dialer analytics (daily breakdown or total). */\n async stats(params: DialerStatsParams = {}): Promise<DialerStatsResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/stats${toQuery(params)}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List dialer-eligible phone numbers with 7-day stats + daily limits. */\n async numbers(userEmail?: string): Promise<DialerNumbersListResult> {\n const params = userEmail ? { user_email: userEmail } : {};\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/numbers${toQuery(params)}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List missed inbound callbacks with caller / contact info. */\n async missedCallbacks(limit = 50): Promise<MissedCallbacksResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/missed-callbacks${toQuery({ limit })}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** AI grading for a single dialer call (returns \"pending\" while in progress). */\n async callGrading(roomName: string): Promise<CallGradingResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls/${encodeURIComponent(roomName)}/grading`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List voice agents available for dialer sessions (capped at 100; no pagination). */\n async agents(params: DialerAgentsListParams = {}): Promise<DialerAgentsListResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/agents${toQuery(params)}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Fetch the full transcript for a single dialer call. */\n async callTranscript(roomName: string): Promise<{ data: { status: string; transcript: Array<{ speaker: string; text: string; timestamp: number }> } }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls/${encodeURIComponent(roomName)}/transcript`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** List dialer calls — pass `contact_id` or `user_email` to scope. */\n async listCalls(params: { contact_id?: number; user_email?: string; campaign_id?: string; date_from?: string; date_to?: string; limit?: number; page?: number } = {}): Promise<{ data: Array<Record<string, unknown>>; pagination?: VoicePagination }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls${toQuery(params)}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Convenience: list calls for a single contact. */\n async listCallsForContact(contactId: number, extra: { limit?: number } = {}): Promise<{ data: Array<Record<string, unknown>> }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls${toQuery({ contact_id: contactId, ...extra })}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Convenience: list calls placed by a specific SDR. */\n async listCallsForSdr(userEmail: string, extra: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: Array<Record<string, unknown>> }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/voice/dialer/calls${toQuery({ user_email: userEmail, ...extra })}`,\n { headers: headers() },\n );\n return resp.json();\n },\n };\n\n return {\n /**\n * Start an AI voice session.\n * @deprecated Preview surface — for parallel-dialer flows use `voice.dialer.createSession()`.\n */\n async start(config: { agent?: string; contactId?: number; context?: Record<string, unknown> }): Promise<VoiceSession> {\n const resp = await fetch(`${baseUrl}/api/v1/voice/sessions`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify(config),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /**\n * Get call analysis for a completed session.\n * @deprecated Preview surface — for dialer-call grading use `voice.dialer.callGrading(roomName)`.\n */\n async analysis(sessionId: string): Promise<CallAnalysis> {\n const resp = await fetch(`${baseUrl}/api/v1/voice/sessions/${sessionId}/analysis`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Listen for voice events. */\n on(event: VoiceEvent, callback: VoiceCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n },\n\n /** Parallel-dialer session control + analytics. */\n dialer,\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface LandingPage {\n id: string;\n title: string;\n slug: string;\n status: string;\n published_url: string | null;\n}\n\n/**\n * Landing pages - clone, create, publish. Requires API key (server-side).\n */\nexport const createPagesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n /** Clone a landing page from any URL. */\n async clone(url: string): Promise<LandingPage> {\n const resp = await fetch(`${baseUrl}/api/v1/landing-pages/clone-url`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify({ url }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a landing page from a template. */\n async create(config: { template?: string; title?: string; content?: Record<string, unknown> }): Promise<LandingPage> {\n const resp = await fetch(`${baseUrl}/api/v1/landing-pages`, {\n method: \"POST\", headers: headers(),\n body: JSON.stringify(config),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Publish a landing page to CDN. */\n async publish(pageId: string): Promise<{ url: string }> {\n const resp = await fetch(`${baseUrl}/api/v1/landing-pages/${pageId}/publish`, {\n method: \"POST\", headers: headers(),\n });\n const data = await resp.json();\n return { url: data.published_url || data.data?.published_url || \"\" };\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport type WebhookEvent =\n | \"reply_received\"\n | \"meeting_booked\"\n | \"contact_enriched\"\n | \"contact_created\"\n | \"sequence_completed\"\n | \"sequence_replied\"\n | \"campaign_launched\"\n | \"form_submitted\"\n | \"visitor_identified\";\n\ntype WebhookCallback = (data: Record<string, unknown>) => void;\n\n/**\n * Webhooks - listen for graph8 events. Requires API key (server-side).\n *\n * For client-side real-time events, use g8.visitors.onIntent() or g8.chat.on() instead.\n */\nexport const createWebhooksClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n const listeners: Map<WebhookEvent, WebhookCallback[]> = new Map();\n let polling = false;\n let pollInterval: ReturnType<typeof setInterval> | null = null;\n\n return {\n /** Register a listener for a webhook event. Starts polling automatically. */\n on(event: WebhookEvent, callback: WebhookCallback): void {\n if (!listeners.has(event)) listeners.set(event, []);\n listeners.get(event)!.push(callback);\n\n // Start polling if not already\n if (!polling) {\n polling = true;\n pollInterval = setInterval(async () => {\n try {\n const resp = await fetch(`${baseUrl}/api/v1/webhooks/events?since=30s`, { headers: headers() });\n if (!resp.ok) return;\n const data = await resp.json();\n const events = data.data || data || [];\n for (const evt of events) {\n const cbs = listeners.get(evt.type as WebhookEvent);\n if (cbs) cbs.forEach((cb) => cb(evt));\n }\n } catch { /* silent */ }\n }, 30_000);\n }\n },\n\n /** Stop all webhook polling. */\n stop(): void {\n if (pollInterval) clearInterval(pollInterval);\n polling = false;\n listeners.clear();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Contact {\n id: number;\n first_name: string | null;\n last_name: string | null;\n work_email: string | null;\n job_title: string | null;\n seniority_level: string | null;\n company_name: string | null;\n company_domain: string | null;\n linkedin_url: string | null;\n direct_phone: string | null;\n mobile_phone: string | null;\n city: string | null;\n state: string | null;\n country: string | null;\n}\n\nexport interface ContactListParams {\n page?: number;\n limit?: number;\n email?: string;\n name?: string;\n job_title?: string;\n seniority_level?: string;\n company_name?: string;\n country?: string;\n list_id?: number;\n}\n\nexport interface ContactCreateParams {\n work_email: string;\n first_name?: string;\n last_name?: string;\n job_title?: string;\n company_domain?: string;\n linkedin_url?: string;\n direct_phone?: string;\n mobile_phone?: string;\n city?: string;\n state?: string;\n country?: string;\n list_id?: number;\n}\n\nexport interface ContactUpdateParams {\n first_name?: string;\n last_name?: string;\n work_email?: string;\n job_title?: string;\n company_domain?: string;\n linkedin_url?: string;\n direct_phone?: string;\n mobile_phone?: string;\n city?: string;\n state?: string;\n country?: string;\n}\n\n/** A column definition on contacts (base or custom). */\nexport interface ContactColumn {\n id: number | null;\n title: string;\n data_type: string;\n name: string | null;\n /** Stringified list_id when list-scoped, otherwise null/empty for global. */\n object_id: string | null;\n is_global: boolean;\n}\n\nexport interface ContactColumnCreateParams {\n title: string;\n /** Email of the user creating the column. Required by the backend (audit). */\n created_by: string;\n /** \"text\" (default) — additional types may be added later. */\n data_type?: string;\n /** If set, the column is list-specific. Omit for org-wide global column. */\n list_id?: number;\n}\n\n/**\n * Contacts API - full CRUD for CRM contacts. Requires API key (server-side).\n */\nexport const createContactsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List contacts with optional filters. */\n async list(params: ContactListParams = {}): Promise<{ data: Contact[]; total: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a single contact by ID. */\n async get(contactId: number): Promise<Contact> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a new contact. */\n async create(contact: ContactCreateParams): Promise<Contact> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(contact),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a contact (partial). */\n async update(contactId: number, fields: ContactUpdateParams): Promise<{ updated: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n return resp.json();\n },\n\n /** Delete a contact (soft-delete). */\n async delete(contactId: number): Promise<{ deleted: boolean }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** List custom contact columns. Pass listId to include list-specific columns. */\n async listColumns(listId?: number): Promise<{ data: ContactColumn[] }> {\n const qs = listId != null ? `?list_id=${listId}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/contacts/columns${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a custom contact column. Global if list_id is omitted, list-scoped otherwise. */\n async createColumn(params: ContactColumnCreateParams): Promise<ContactColumn> {\n const body = {\n title: params.title,\n data_type: params.data_type || \"text\",\n list_id: params.list_id ?? null,\n created_by: params.created_by,\n };\n const resp = await fetch(`${baseUrl}/api/v1/contacts/columns/create`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Company {\n id: number;\n name: string | null;\n domain: string | null;\n industry: string | null;\n employee_count: number | null;\n revenue: number | null;\n founded_year: number | null;\n description: string | null;\n linkedin_url: string | null;\n country: string | null;\n state: string | null;\n city: string | null;\n}\n\nexport interface CompanyListParams {\n page?: number;\n limit?: number;\n domain?: string;\n industry?: string;\n name?: string;\n country?: string;\n}\n\nexport interface CompanyUpdateParams {\n name?: string;\n domain?: string;\n industry?: string;\n description?: string;\n linkedin_url?: string;\n country?: string;\n state?: string;\n city?: string;\n}\n\nexport interface CompanyContact {\n id: number;\n first_name: string | null;\n last_name: string | null;\n work_email: string | null;\n job_title: string | null;\n}\n\n/** A column definition on companies (base or custom). */\nexport interface CompanyColumn {\n id: number | null;\n title: string;\n data_type: string;\n name: string | null;\n /** Stringified list_id when list-scoped, otherwise null/empty for global. */\n object_id: string | null;\n is_global: boolean;\n}\n\nexport interface CompanyColumnCreateParams {\n title: string;\n /** Email of the user creating the column. Required by the backend (audit). */\n created_by: string;\n /** \"text\" (default) — additional types may be added later. */\n data_type?: string;\n /** If set, the column is list-specific. Omit for org-wide global column. */\n list_id?: number;\n}\n\n/**\n * Companies API - search and manage CRM companies. Requires API key (server-side).\n */\nexport const createCompaniesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List companies with optional filters. */\n async list(params: CompanyListParams = {}): Promise<{ data: Company[]; total: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a single company by ID. */\n async get(companyId: number): Promise<Company> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get contacts belonging to a company. */\n async contacts(companyId: number, limit = 50, offset = 0): Promise<{ data: CompanyContact[]; total: number }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/companies/${companyId}/contacts?limit=${limit}&offset=${offset}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Update a company (partial). */\n async update(companyId: number, fields: CompanyUpdateParams): Promise<{ updated: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n return resp.json();\n },\n\n /** Delete a company (soft-delete). */\n async delete(companyId: number): Promise<{ deleted: boolean }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** List custom company columns. Pass listId to include list-specific columns. */\n async listColumns(listId?: number): Promise<{ data: CompanyColumn[] }> {\n const qs = listId != null ? `?list_id=${listId}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/companies/columns${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a custom company column. Global if list_id is omitted, list-scoped otherwise. */\n async createColumn(params: CompanyColumnCreateParams): Promise<CompanyColumn> {\n const body = {\n title: params.title,\n data_type: params.data_type || \"text\",\n list_id: params.list_id ?? null,\n created_by: params.created_by,\n };\n const resp = await fetch(`${baseUrl}/api/v1/companies/columns/create`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface ContactList {\n id: number;\n title: string;\n type: \"contacts\" | \"companies\";\n contact_count: number | null;\n created_at: string | null;\n}\n\nexport interface ListContact {\n id: number;\n first_name: string | null;\n last_name: string | null;\n work_email: string | null;\n job_title: string | null;\n company_name: string | null;\n}\n\n/**\n * Lists API - manage contact and company lists. Requires API key (server-side).\n */\nexport const createListsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n /** List all lists. */\n async list(page = 1, limit = 50): Promise<{ data: ContactList[]; total: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/lists?page=${page}&limit=${limit}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a new list. */\n async create(title: string, type: \"contacts\" | \"companies\" = \"contacts\"): Promise<ContactList> {\n const resp = await fetch(`${baseUrl}/api/v1/lists`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ title, type }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a list (soft-delete). */\n async delete(listId: number): Promise<{ deleted: boolean }> {\n const resp = await fetch(`${baseUrl}/api/v1/lists/${listId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Get contacts in a list. */\n async contacts(listId: number, page = 1, limit = 50): Promise<{ data: ListContact[]; total: number }> {\n const resp = await fetch(\n `${baseUrl}/api/v1/lists/${listId}/contacts?page=${page}&limit=${limit}`,\n { headers: headers() },\n );\n return resp.json();\n },\n\n /** Add contacts to a list. */\n async addContacts(listId: number, contactIds: number[]): Promise<{ added: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/lists/${listId}/contacts`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ contact_ids: contactIds }),\n });\n return resp.json();\n },\n\n /** Remove contacts from a list. */\n async removeContacts(listId: number, contactIds: number[]): Promise<{ removed: number }> {\n const resp = await fetch(`${baseUrl}/api/v1/lists/${listId}/contacts`, {\n method: \"DELETE\",\n headers: headers(),\n body: JSON.stringify({ contact_ids: contactIds }),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Note {\n id: string;\n entity_type: string;\n entity_id: string;\n content: string;\n created_by: string | null;\n created_by_name: string | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\n/**\n * Notes API - CRUD for notes attached to contacts. Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/contacts/{contact_id}/notes\n * POST /api/v1/contacts/{contact_id}/notes\n * PATCH /api/v1/notes/{note_id}\n * DELETE /api/v1/notes/{note_id}\n */\nexport const createNotesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n /** List all notes on a contact. */\n async list(contactId: number): Promise<{ data: Note[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/notes`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a note on a contact. */\n async create(contactId: number, content: string): Promise<Note> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/notes`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ content }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a note's content. */\n async update(noteId: string, content: string): Promise<Note> {\n const resp = await fetch(`${baseUrl}/api/v1/notes/${noteId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify({ content }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a note. */\n async delete(noteId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/notes/${noteId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Task {\n id: string;\n entity_type: string | null;\n entity_id: string | null;\n title: string;\n description: string | null;\n due_date: string | null;\n assignee_id: string | null;\n assignee_name: string | null;\n /** \"open\" | \"completed\" (other values may appear if the backend adds states later) */\n status: string | null;\n /** 0=none, 1=urgent, 2=high, 3=normal, 4=low */\n priority: number | null;\n task_type: string | null;\n created_by: string | null;\n created_at: string | null;\n updated_at: string | null;\n /** Parent task UUID when this row is a subtask, else null. One level deep. */\n parent_task_id?: string | null;\n /** Sort position within the parent's subtasks. 0 when not a subtask. */\n subtask_sort_order?: number | null;\n /** Number of subtasks under this task (top-level rows only). */\n subtask_count?: number | null;\n /** Subset of subtask_count whose status is \"completed\". */\n completed_subtask_count?: number | null;\n}\n\nexport interface TaskCreateParams {\n title: string;\n description?: string;\n /** ISO 8601 date string. */\n due_date?: string;\n assignee_id?: string;\n /** 0=none, 1=urgent, 2=high, 3=normal, 4=low */\n priority?: number;\n /**\n * When set, the new task is created as a subtask of this parent. Parent\n * must exist and must not itself be a subtask (subtasks are one level\n * deep).\n */\n parent_task_id?: string;\n /**\n * Sort position within the parent's subtasks. Omit to append at the end.\n */\n subtask_sort_order?: number;\n}\n\nexport interface TaskUpdateParams {\n title?: string;\n description?: string;\n due_date?: string;\n assignee_id?: string;\n /** \"open\" | \"completed\" */\n status?: string;\n priority?: number;\n /**\n * Re-parent this task into a subtask of the given parent. Parent must\n * exist, must not itself be a subtask, and a task that already has\n * subtasks of its own cannot be demoted into a subtask.\n */\n parent_task_id?: string;\n /** Reorder within the parent's subtasks. Can be sent alone. */\n subtask_sort_order?: number;\n}\n\nexport interface TaskListParams {\n /** \"open\" | \"completed\" */\n status?: string;\n /** 0-4 */\n priority?: number;\n assignee_id?: string;\n /** Substring search on title. */\n search?: string;\n}\n\n/**\n * Tasks API - CRUD for tasks attached to contacts. Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/contacts/{contact_id}/tasks\n * GET /api/v1/tasks\n * POST /api/v1/contacts/{contact_id}/tasks\n * PATCH /api/v1/tasks/{task_id}\n * DELETE /api/v1/tasks/{task_id}\n */\nexport const createTasksClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List tasks on a single contact. Optional status filter (\"open\" | \"completed\"). */\n async listForContact(contactId: number, status?: string): Promise<{ data: Task[] }> {\n const qs = status ? `?status=${encodeURIComponent(status)}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/tasks${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** List all tasks org-wide with optional filters. */\n async list(params: TaskListParams = {}): Promise<{ data: Task[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/tasks${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a task on a contact. */\n async create(contactId: number, task: TaskCreateParams): Promise<Task> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/tasks`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(task),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a task (partial). */\n async update(taskId: string, fields: TaskUpdateParams): Promise<Task> {\n const resp = await fetch(`${baseUrl}/api/v1/tasks/${taskId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a task. */\n async delete(taskId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/tasks/${taskId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n/** A field (column) definition on contacts or companies — base or custom. */\nexport interface Field {\n id: number | null;\n title: string;\n /** Internal column name (slug). */\n name: string | null;\n /** Currently only \"text\" is supported; other types may be added later. */\n data_type: string;\n /** True if available org-wide, false if list-specific. */\n is_global: boolean;\n}\n\n/** Created custom field (column). */\nexport interface CreatedField {\n id: number;\n title: string;\n data_type: string;\n name: string;\n list_id: number | null;\n is_global: boolean;\n}\n\nexport interface FieldCreateParams {\n title: string;\n /** \"contacts\" or \"companies\". Defaults to \"contacts\" on the backend. */\n entity?: \"contacts\" | \"companies\";\n /** \"text\" (default) — additional types may be added later. */\n data_type?: string;\n /** If set, the field is list-specific. Omit for org-wide global field. */\n list_id?: number;\n}\n\nexport interface FieldDeleteParams {\n entity?: \"contacts\" | \"companies\";\n /**\n * Optional list scope guard. If provided, the column must belong to this\n * list or the request returns 404. Use this to prevent accidentally\n * deleting a column on a different list in the same org.\n */\n list_id?: number;\n}\n\nexport interface SetFieldValueParams {\n /** Contact ID (entity='contacts') or company ID (entity='companies'). */\n record_id: number;\n /** Value to write. Pass null/undefined to clear the field. */\n value?: string | null;\n entity?: \"contacts\" | \"companies\";\n}\n\n/**\n * Fields API - manage custom fields (columns) on contacts and companies.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/fields — list contact fields\n * GET /api/v1/fields/companies — list company fields\n * POST /api/v1/fields — create a custom field\n * DELETE /api/v1/fields/{column_id} — delete a custom field\n * PATCH /api/v1/fields/{column_id}/values — set value on a single record\n */\nexport const createFieldsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List contact fields (base + custom). Pass listId to include list-specific custom fields. */\n async listContactFields(listId?: number): Promise<{ data: Field[] }> {\n const qs = listId != null ? `?list_id=${listId}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/fields${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** List company fields (base + custom). Pass listId to include list-specific custom fields. */\n async listCompanyFields(listId?: number): Promise<{ data: Field[] }> {\n const qs = listId != null ? `?list_id=${listId}` : \"\";\n const resp = await fetch(`${baseUrl}/api/v1/fields/companies${qs}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a custom field on contacts (default) or companies. */\n async create(params: FieldCreateParams): Promise<CreatedField> {\n const body = {\n title: params.title,\n data_type: params.data_type || \"text\",\n list_id: params.list_id ?? null,\n entity: params.entity || \"contacts\",\n };\n const resp = await fetch(`${baseUrl}/api/v1/fields`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a custom field (soft-delete). Pass list_id to scope-guard against cross-list deletion. */\n async delete(columnId: number, params: FieldDeleteParams = {}): Promise<{ data: { column_id: number; deleted: boolean } }> {\n const queryParams: Record<string, string | number> = { entity: params.entity || \"contacts\" };\n if (params.list_id != null) queryParams.list_id = params.list_id;\n const resp = await fetch(`${baseUrl}/api/v1/fields/${columnId}${toQuery(queryParams)}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Set a custom field value on a single contact or company row. Pass value=null to clear. */\n async setValue(\n columnId: number,\n params: SetFieldValueParams,\n ): Promise<{ data: { column_id: number; record_id: number; updated: boolean } }> {\n const body = {\n record_id: params.record_id,\n value: params.value ?? null,\n entity: params.entity || \"contacts\",\n };\n const resp = await fetch(`${baseUrl}/api/v1/fields/${columnId}/values`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface Deal {\n id: string | null;\n name: string | null;\n description: string | null;\n amount: number | null;\n currency: string | null;\n stage_id: string | null;\n stage_name: string | null;\n pipeline_id: string | null;\n /** Linked company ID (mashup_company_id), if any. */\n company_id: number | string | null;\n owner_id: string | null;\n /** ISO 8601 date. */\n close_date: string | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface DealCreateParams {\n name: string;\n /** Linked company ID. */\n company_id?: number;\n description?: string;\n amount?: number;\n /** Default: \"USD\". */\n currency?: string;\n /** Stage ID from the org's pipelines. Defaults to first stage of default pipeline if omitted. */\n stage_id?: string;\n /** Pipeline ID. Defaults to org's default pipeline if omitted. */\n pipeline_id?: string;\n /** ISO 8601 close date. */\n close_date?: string;\n}\n\nexport interface DealUpdateParams {\n name?: string;\n description?: string;\n amount?: number;\n currency?: string;\n stage_id?: string;\n /** ISO 8601 close date. */\n close_date?: string;\n}\n\nexport interface DealListParams {\n page?: number;\n limit?: number;\n stage_id?: string;\n pipeline_id?: string;\n /** Substring search on deal name. */\n search?: string;\n}\n\nexport interface PipelineStage {\n id: string;\n name: string;\n probability: number | null;\n position: number | null;\n stage_type: string | null;\n color: string | null;\n required_elements: string[];\n recommended_elements: string[];\n channel_scripts: Record<string, string>;\n}\n\nexport interface Pipeline {\n id: string;\n name: string;\n is_default: boolean;\n stages: PipelineStage[];\n}\n\n/** Trimmed deal shape returned by /contacts/{id}/deals and /companies/{id}/deals. */\nexport interface ContactDeal {\n deal_id: string | null;\n name: string | null;\n stage: string | null;\n value: number | null;\n currency: string | null;\n role: string | null;\n pipeline_id: string | null;\n close_date: string | null;\n owner_id: string | null;\n created_at: string | null;\n}\n\nexport interface PaginationMeta {\n page: number;\n limit: number;\n total: number;\n has_next: boolean;\n}\n\n/**\n * Deals API - CRUD for deals + pipelines. Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/deals/pipelines\n * GET /api/v1/deals\n * POST /api/v1/deals\n * GET /api/v1/deals/{deal_id}\n * PATCH /api/v1/deals/{deal_id}\n * DELETE /api/v1/deals/{deal_id}\n * GET /api/v1/contacts/{contact_id}/deals\n * GET /api/v1/companies/{company_id}/deals\n */\nexport const createDealsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List all deal pipelines and their stages. */\n async pipelines(): Promise<{ data: Pipeline[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/deals/pipelines`, { headers: headers() });\n return resp.json();\n },\n\n /** List deals org-wide with optional filters and pagination. */\n async list(params: DealListParams = {}): Promise<{ data: Deal[]; pagination?: PaginationMeta }> {\n const resp = await fetch(`${baseUrl}/api/v1/deals${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a new deal. */\n async create(deal: DealCreateParams): Promise<Deal> {\n const resp = await fetch(`${baseUrl}/api/v1/deals`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(deal),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get a single deal by ID. */\n async get(dealId: string): Promise<Deal> {\n const resp = await fetch(`${baseUrl}/api/v1/deals/${dealId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a deal (partial). */\n async update(dealId: string, fields: DealUpdateParams): Promise<Deal> {\n const resp = await fetch(`${baseUrl}/api/v1/deals/${dealId}`, {\n method: \"PATCH\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a deal. */\n async delete(dealId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/deals/${dealId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Get all deals associated with a contact. */\n async forContact(contactId: number): Promise<{ data: ContactDeal[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/deals`, { headers: headers() });\n return resp.json();\n },\n\n /** Get all deals associated with a company. */\n async forCompany(companyId: number): Promise<{ data: ContactDeal[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}/deals`, { headers: headers() });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n/**\n * Inbox channel — `email`, `sms`, or `linkedin` (HeyReach internally).\n * Defaults to `email` on routes that accept this as a query param.\n */\nexport type InboxChannel = \"email\" | \"sms\" | \"linkedin\";\n\nexport interface InboxContact {\n name?: string | null;\n email?: string | null;\n company?: string | null;\n [key: string]: unknown;\n}\n\nexport interface InboxTag {\n id: string;\n name: string;\n}\n\nexport interface InboxAssignee {\n email: string;\n name?: string | null;\n [key: string]: unknown;\n}\n\nexport interface InboxMessage {\n message_id: string | null;\n from_address: string | null;\n to_addresses: string[];\n content: string | null;\n /** \"USER\", \"AI\", or \"OTHER\". */\n responder: string | null;\n date: string | null;\n is_draft: boolean;\n}\n\nexport interface InboxThread {\n id: string;\n /** \"email\", \"sms\", or \"linkedin\". */\n channel: string;\n subject: string | null;\n contact: InboxContact | null;\n messages: InboxMessage[];\n /** \"open\", \"responded\", \"ai_responded\", etc. */\n status: string | null;\n tags: InboxTag[];\n assignees: InboxAssignee[];\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface InboxListParams {\n channel?: InboxChannel;\n sequence_id?: string;\n /** Filter by thread status (e.g. \"open\", \"responded\", \"ai_responded\"). */\n status?: string;\n /** Filter by assignee email. */\n assignee?: string;\n /** Filter by tag ID. */\n tag?: string;\n page?: number;\n /** Default 50, max 100. */\n page_size?: number;\n}\n\nexport interface InboxAssignResult {\n assigned: boolean;\n assignee: string;\n count: number;\n [key: string]: unknown;\n}\n\nexport interface InboxTagResult {\n tagged: boolean;\n tag_count: number;\n [key: string]: unknown;\n}\n\nexport interface InboxDraft {\n /** HTML body. */\n content: string;\n /** Plain-text alternative, if available. */\n plain_content: string | null;\n /** Credits charged for AI generation. */\n credits_charged: number;\n}\n\nexport interface InboxSendParams {\n body: string;\n channel: InboxChannel;\n subject?: string;\n /** Recipient override — email, phone, or LinkedIn ID. */\n to?: string;\n /** Sender override — mailbox email, Twilio number, or LinkedIn account ID. */\n from_address?: string;\n}\n\nexport interface InboxSendResult {\n message_id: string | null;\n status: string;\n channel: string;\n}\n\n/**\n * Inbox API — read + reply to multi-channel inbox threads (email, SMS, LinkedIn/HeyReach).\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/inbox\n * GET /api/v1/inbox/{reply_id}\n * POST /api/v1/inbox/{reply_id}/assign\n * POST /api/v1/inbox/{reply_id}/tag\n * GET /api/v1/inbox/{reply_id}/draft (charges credits, 402 on insufficient balance)\n * POST /api/v1/inbox/{reply_id}/send\n */\nexport const createInboxClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List inbox threads across email, SMS, and LinkedIn. */\n async list(params: InboxListParams = {}): Promise<{ data: InboxThread[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/inbox${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a single inbox thread. Defaults to email channel. */\n async get(replyId: string, channel: InboxChannel = \"email\"): Promise<InboxThread> {\n const resp = await fetch(\n `${baseUrl}/api/v1/inbox/${replyId}${toQuery({ channel })}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Assign a user to an inbox thread. */\n async assign(\n replyId: string,\n assigneeEmail: string,\n channel: InboxChannel = \"email\",\n ): Promise<InboxAssignResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/inbox/${replyId}/assign${toQuery({ channel })}`,\n {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ assignee_email: assigneeEmail }),\n },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Attach tag IDs to an inbox thread. */\n async tag(\n replyId: string,\n tagIds: string[],\n channel: InboxChannel = \"email\",\n ): Promise<InboxTagResult> {\n const resp = await fetch(\n `${baseUrl}/api/v1/inbox/${replyId}/tag${toQuery({ channel })}`,\n {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ tag_ids: tagIds }),\n },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /**\n * Generate an AI draft reply for a thread.\n * Charges credits — server returns 402 if balance is insufficient.\n */\n async draft(replyId: string, channel: InboxChannel = \"email\"): Promise<InboxDraft> {\n const resp = await fetch(\n `${baseUrl}/api/v1/inbox/${replyId}/draft${toQuery({ channel })}`,\n { headers: headers() },\n );\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Send a reply through email, SMS, or LinkedIn. */\n async send(replyId: string, payload: InboxSendParams): Promise<InboxSendResult> {\n const resp = await fetch(`${baseUrl}/api/v1/inbox/${replyId}/send`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(payload),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface QuoteLineItem {\n product_id?: string | null;\n name?: string | null;\n description?: string | null;\n quantity: number;\n unit_price: number;\n currency?: string | null;\n recurring?: boolean | null;\n}\n\nexport type QuoteStatus =\n | \"draft\"\n | \"sent\"\n | \"signed\"\n | \"declined\"\n | \"expired\"\n | \"void\";\n\nexport interface QuoteSummary {\n id: string;\n name: string | null;\n status: QuoteStatus;\n total: number | null;\n currency: string | null;\n contact_id: number | null;\n company_id: number | null;\n expires_at: string | null;\n created_at: string | null;\n updated_at: string | null;\n signing_url: string | null;\n payment_link_url: string | null;\n}\n\nexport interface QuoteDetail extends QuoteSummary {\n line_items: QuoteLineItem[];\n notes: string | null;\n recipient_email: string | null;\n signed_at: string | null;\n sent_at: string | null;\n}\n\nexport interface QuoteCreateParams {\n contact_id?: number;\n company_id?: number;\n line_items: QuoteLineItem[];\n currency?: string;\n notes?: string;\n /** ISO 8601 timestamp. */\n expires_at?: string;\n name?: string;\n}\n\nexport interface QuoteUpdateParams {\n line_items?: QuoteLineItem[];\n notes?: string;\n expires_at?: string;\n name?: string;\n}\n\nexport interface QuoteSendParams {\n recipient_email: string;\n /** Whether to attach the signing link. Defaults to true. */\n send_signing_link?: boolean;\n}\n\nexport interface QuoteListParams {\n status?: QuoteStatus;\n contact_id?: number;\n company_id?: number;\n page?: number;\n limit?: number;\n}\n\nexport interface QuotableProduct {\n id: string;\n name: string;\n description: string | null;\n unit_price: number;\n currency: string;\n recurring: boolean;\n}\n\nexport interface QuoteSettings {\n default_currency: string;\n default_tax_rate: number | null;\n payment_providers: string[];\n logo_url: string | null;\n signature_required: boolean;\n}\n\nexport interface PaginationMeta {\n page: number;\n limit: number;\n total: number;\n has_next: boolean;\n}\n\n/**\n * Quotes API - quote-to-cash lifecycle. Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/quotes\n * GET /api/v1/quotes/{id}\n * POST /api/v1/quotes\n * PUT /api/v1/quotes/{id}\n * DELETE /api/v1/quotes/{id}\n * POST /api/v1/quotes/{id}/duplicate\n * POST /api/v1/quotes/{id}/edit-as-draft\n * POST /api/v1/quotes/{id}/send\n * GET /api/v1/quotable-products\n * GET /api/v1/quote-settings\n * GET /api/v1/contacts/{contact_id}/quotes\n * GET /api/v1/companies/{company_id}/quotes\n */\nexport const createQuotesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List quotes org-wide with optional filters and pagination. */\n async list(params: QuoteListParams = {}): Promise<{ data: QuoteSummary[]; pagination?: PaginationMeta }> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get full details for a single quote. */\n async get(quoteId: string): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a new quote from line items. */\n async create(quote: QuoteCreateParams): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(quote),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a draft quote (line items, expiry, notes). */\n async update(quoteId: string, fields: QuoteUpdateParams): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a draft quote (irreversible). */\n async delete(quoteId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Duplicate an existing quote (all line items copied into a new draft). */\n async duplicate(quoteId: string): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/duplicate`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Convert a signed / sent quote back to editable draft state. */\n async editAsDraft(quoteId: string): Promise<{ data: { id: string; status: string } }> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/edit-as-draft`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Send a quote to its recipient via email (with signature + optional payment link). */\n async send(quoteId: string, params: QuoteSendParams): Promise<QuoteDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/quotes/${quoteId}/send`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** List products available for line items. */\n async products(): Promise<{ data: QuotableProduct[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/quotable-products`, { headers: headers() });\n return resp.json();\n },\n\n /** Get org-level quote settings (currency, tax rate, payment providers, logo). */\n async settings(): Promise<QuoteSettings> {\n const resp = await fetch(`${baseUrl}/api/v1/quote-settings`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get all quotes associated with a contact. */\n async forContact(contactId: number): Promise<{ data: QuoteSummary[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/contacts/${contactId}/quotes`, { headers: headers() });\n return resp.json();\n },\n\n /** Get all quotes associated with a company. */\n async forCompany(companyId: number): Promise<{ data: QuoteSummary[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/companies/${companyId}/quotes`, { headers: headers() });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\n/**\n * Stage Checklist v2 pipelines. A \"pipeline\" here is a multi-stage workflow\n * (with evidence requirements and per-channel scripts) that lives parallel\n * to deal pipelines. Use `g8.deals.pipelines()` for deal-pipeline reads.\n */\nexport interface StagePipelineStage {\n id: string;\n name: string;\n position: number;\n /** Evidence keys that must be collected before the stage can be marked done. */\n required_elements: string[];\n /** Evidence keys that are recommended but not enforced. */\n recommended_elements: string[];\n /** Channel-specific scripts (call, email, linkedin, etc.). */\n channel_scripts: Record<string, string>;\n color: string | null;\n stage_type: string | null;\n}\n\nexport interface StagePipeline {\n id: string;\n name: string;\n target: string | null;\n is_default: boolean;\n stages: StagePipelineStage[];\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface StagePipelineCreateParams {\n name: string;\n target?: string;\n /** If true, creates an empty pipeline (no default stages). */\n blank?: boolean;\n}\n\nexport interface StagePipelineUpdateParams {\n name?: string;\n target?: string;\n}\n\nexport interface StageCreateParams {\n name: string;\n position?: number;\n required_elements?: string[];\n recommended_elements?: string[];\n channel_scripts?: Record<string, string>;\n color?: string;\n stage_type?: string;\n}\n\nexport interface StageUpdateParams {\n name?: string;\n position?: number;\n required_elements?: string[];\n recommended_elements?: string[];\n channel_scripts?: Record<string, string>;\n color?: string;\n}\n\nexport interface EvidenceKey {\n key: string;\n label: string;\n description: string;\n category: string;\n}\n\nexport interface PipelineSuggestion {\n suggestion_id: string;\n name: string;\n target: string;\n stages: Array<{ name: string; required_elements: string[]; channel_scripts: Record<string, string> }>;\n rationale: string;\n}\n\n/**\n * Stage Checklist Pipelines API - workflow pipelines with evidence + scripts.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/pipelines\n * GET /api/v1/pipelines/{id}\n * GET /api/v1/pipelines/evidence-library\n * POST /api/v1/pipelines\n * PUT /api/v1/pipelines/{id}\n * DELETE /api/v1/pipelines/{id}\n * POST /api/v1/pipelines/{id}/stages\n * PUT /api/v1/pipelines/{id}/stages/{stage_id}\n * DELETE /api/v1/pipelines/{id}/stages/{stage_id}\n * PUT /api/v1/pipelines/{id}/stages/reorder\n * POST /api/v1/pipelines/suggest\n * POST /api/v1/pipelines/from-suggestion\n */\nexport const createPipelinesClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n return {\n /** List all stage-checklist pipelines with stages, evidence, scripts. */\n async list(): Promise<{ data: StagePipeline[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a single pipeline by ID. */\n async get(pipelineId: string): Promise<StagePipeline> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get the canonical evidence-key library (used when defining stages). */\n async evidenceLibrary(): Promise<{ data: EvidenceKey[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/evidence-library`, { headers: headers() });\n return resp.json();\n },\n\n /** Create a new pipeline. Defaults to a templated set of stages; pass blank=true for empty. */\n async create(params: StagePipelineCreateParams): Promise<StagePipeline> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update pipeline metadata (name, target). */\n async update(pipelineId: string, fields: StagePipelineUpdateParams): Promise<StagePipeline> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a pipeline. Only allowed when no deals reference it. */\n async delete(pipelineId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Add a new stage to a pipeline. */\n async createStage(pipelineId: string, stage: StageCreateParams): Promise<StagePipelineStage> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(stage),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update a stage (evidence, scripts, position). */\n async updateStage(pipelineId: string, stageId: string, fields: StageUpdateParams): Promise<StagePipelineStage> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/${stageId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Reorder stages within a pipeline (pass full ordered list of stage IDs). */\n async reorderStages(pipelineId: string, stageIds: string[]): Promise<{ data: StagePipelineStage[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/reorder`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify({ stage_ids: stageIds }),\n });\n return resp.json();\n },\n\n /** Delete a stage from a pipeline. */\n async deleteStage(pipelineId: string, stageId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/${pipelineId}/stages/${stageId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Get an AI-suggested pipeline based on org context (brand, ICP, messaging). */\n async suggest(): Promise<{ data: PipelineSuggestion }> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/suggest`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Create a real pipeline from an AI suggestion (optionally with overrides). */\n async fromSuggestion(\n suggestionId: string,\n overrides?: Partial<{ name: string; target: string }>,\n ): Promise<StagePipeline> {\n const resp = await fetch(`${baseUrl}/api/v1/pipelines/from-suggestion`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ suggestion_id: suggestionId, ...(overrides || {}) }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface WorkflowNode {\n id: string;\n type: string;\n config: Record<string, unknown>;\n position?: { x: number; y: number };\n /** Mapping from this node's output to the next node's input. */\n input_mappings?: Record<string, string>;\n}\n\nexport interface WorkflowConnection {\n from_node_id: string;\n to_node_id: string;\n condition?: string | null;\n}\n\nexport interface WorkflowConfig {\n nodes: WorkflowNode[];\n connections: WorkflowConnection[];\n trigger?: Record<string, unknown> | null;\n}\n\nexport interface Workflow {\n id: string;\n name: string;\n description: string | null;\n config: WorkflowConfig;\n trigger_config: Record<string, unknown> | null;\n is_active: boolean;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface WorkflowCreateParams {\n name: string;\n description?: string;\n config?: WorkflowConfig;\n trigger_config?: Record<string, unknown>;\n}\n\nexport interface WorkflowUpdateParams {\n name?: string;\n description?: string;\n config?: WorkflowConfig;\n trigger_config?: Record<string, unknown>;\n is_active?: boolean;\n}\n\nexport interface WorkflowExecution {\n id: string;\n workflow_id: string;\n status: \"pending\" | \"running\" | \"paused\" | \"completed\" | \"failed\" | \"stopped\";\n trigger_payload: Record<string, unknown>;\n outputs: Record<string, unknown>;\n error: string | null;\n started_at: string | null;\n ended_at: string | null;\n}\n\nexport interface NodeTypeSchema {\n type: string;\n label: string;\n description: string;\n config_schema: Record<string, unknown>;\n output_schema: Record<string, unknown>;\n}\n\nexport interface WorkflowListParams {\n page?: number;\n limit?: number;\n is_active?: boolean;\n search?: string;\n}\n\n/**\n * Workflows API - automation workflows with nodes, connections, and execution lifecycle.\n * Requires API key (server-side).\n *\n * The graph8 workflow surface treats the whole workflow definition as a single\n * record updated via `update()` — there are no per-node CRUD endpoints. To edit\n * nodes or connections, fetch the workflow, mutate `config.nodes` / `config.connections`,\n * and PUT it back.\n *\n * Backed by:\n * GET /api/v1/workflows\n * GET /api/v1/workflows/{id}\n * POST /api/v1/workflows\n * PUT /api/v1/workflows/{id}\n * DELETE /api/v1/workflows/{id}\n * POST /api/v1/workflows/validate\n * POST /api/v1/workflows/{id}/execute\n * GET /api/v1/workflows/executions/{exec_id}\n * POST /api/v1/workflows/executions/{exec_id}/pause\n * POST /api/v1/workflows/executions/{exec_id}/resume\n * POST /api/v1/workflows/executions/{exec_id}/stop\n * GET /api/v1/workflows/{id}/trigger-status\n * POST /api/v1/workflows/{id}/trigger-reset\n * GET /api/v1/workflows/node-types/schema\n * GET /api/v1/workflows/integrations/slack/users|channels\n * GET /api/v1/workflows/integrations/roam/users|groups\n * GET /api/v1/workflows/mcp-servers\n * GET /api/v1/workflows/dispositions\n * GET /api/v1/workflows/forms/{form_id}/fields\n */\nexport const createWorkflowsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List workflows org-wide. */\n async list(params: WorkflowListParams = {}): Promise<{ data: Workflow[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get full workflow definition (nodes, connections, trigger, execution state). */\n async get(workflowId: string): Promise<Workflow> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a new workflow. */\n async create(params: WorkflowCreateParams): Promise<Workflow> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /**\n * Update a workflow. Pass the full `config` (nodes + connections) to edit\n * the graph — node-level CRUD is performed client-side by mutating the\n * config and submitting the updated record.\n */\n async update(workflowId: string, fields: WorkflowUpdateParams): Promise<Workflow> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify(fields),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a workflow. */\n async delete(workflowId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Validate a workflow definition (orphans, dangling connections, required fields). */\n async validate(workflow: { config: WorkflowConfig; trigger_config?: Record<string, unknown> }): Promise<{\n data: { valid: boolean; errors: Array<{ node_id?: string; field?: string; message: string }> };\n }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/validate`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(workflow),\n });\n return resp.json();\n },\n\n /** Execute a workflow immediately with a trigger payload. */\n async execute(workflowId: string, triggerPayload: Record<string, unknown> = {}): Promise<WorkflowExecution> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/execute`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ trigger_payload: triggerPayload }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get the status + output of a workflow execution. */\n async getExecution(executionId: string): Promise<WorkflowExecution> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Pause an in-flight execution. */\n async pauseExecution(executionId: string): Promise<{ data: { paused: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/pause`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Resume a paused execution. */\n async resumeExecution(executionId: string): Promise<{ data: { resumed: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/resume`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Stop an execution (terminal state — cannot resume). */\n async stopExecution(executionId: string): Promise<{ data: { stopped: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/executions/${executionId}/stop`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /** Get the status of a workflow's external trigger (e.g. \"waiting for webhook\"). */\n async getTriggerStatus(workflowId: string): Promise<{ data: { status: string; details: Record<string, unknown> } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/trigger-status`, { headers: headers() });\n return resp.json();\n },\n\n /** Reset the trigger cursor (e.g. for event-stream triggers — resume from beginning). */\n async resetTrigger(workflowId: string): Promise<{ data: { reset: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/${workflowId}/trigger-reset`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({}),\n });\n return resp.json();\n },\n\n /**\n * List available node types with schemas. Pass a `type` param to fetch one type's full schema.\n */\n async nodeTypes(params: { type?: string } = {}): Promise<{ data: NodeTypeSchema[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/node-types/schema${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Slack workspace users (for Slack action recipients). */\n async listSlackUsers(): Promise<{ data: Array<{ id: string; name: string; email: string | null }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/slack/users`, { headers: headers() });\n return resp.json();\n },\n\n /** Slack channels. */\n async listSlackChannels(): Promise<{ data: Array<{ id: string; name: string; is_private: boolean }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/slack/channels`, { headers: headers() });\n return resp.json();\n },\n\n /** Roam (Copilot chat) users. */\n async listRoamUsers(): Promise<{ data: Array<{ id: string; name: string; email: string | null }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/roam/users`, { headers: headers() });\n return resp.json();\n },\n\n /** Roam (Copilot chat) groups. */\n async listRoamGroups(): Promise<{ data: Array<{ id: string; name: string }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/integrations/roam/groups`, { headers: headers() });\n return resp.json();\n },\n\n /** Available MCP servers (for Agent-node integrations). */\n async listMcpServers(): Promise<{ data: Array<{ id: string; name: string; url: string }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/mcp-servers`, { headers: headers() });\n return resp.json();\n },\n\n /** Available call dispositions (voice workflow nodes). */\n async listDispositions(): Promise<{ data: Array<{ id: string; label: string }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/dispositions`, { headers: headers() });\n return resp.json();\n },\n\n /** Form field schema for form-trigger nodes. */\n async listFormFields(formId: string): Promise<{ data: Array<{ name: string; type: string; required: boolean }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/workflows/forms/${formId}/fields`, { headers: headers() });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport type SkillType = \"llm\" | \"api\";\n\nexport interface SkillInputField {\n name: string;\n type: string;\n required: boolean;\n description?: string;\n}\n\nexport interface Skill {\n id: string;\n title: string;\n description: string | null;\n type: SkillType;\n /** Only present on `type=llm`. */\n prompt?: string;\n /** Only present on `type=llm`. */\n model?: string;\n /** Only present on `type=api`. */\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n /** Only present on `type=api`. */\n url?: string;\n /** Only present on `type=api`. */\n headers?: Record<string, string>;\n /** Only present on `type=api`. */\n body_template?: string;\n input_schema: { fields: SkillInputField[] };\n output_schema: Record<string, unknown> | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface SkillCreateLLMParams {\n title: string;\n description?: string;\n prompt: string;\n model: string;\n input_schema: { fields: SkillInputField[] };\n output_schema?: Record<string, unknown>;\n}\n\nexport interface SkillCreateAPIParams {\n title: string;\n description?: string;\n method: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n url: string;\n headers?: Record<string, string>;\n body_template?: string;\n response_mapping?: Record<string, string>;\n input_schema: { fields: SkillInputField[] };\n}\n\nexport interface SkillUpdateLLMParams {\n title?: string;\n description?: string;\n prompt?: string;\n model?: string;\n input_schema?: { fields: SkillInputField[] };\n output_schema?: Record<string, unknown>;\n}\n\nexport interface SkillUpdateAPIParams {\n title?: string;\n description?: string;\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n url?: string;\n headers?: Record<string, string>;\n body_template?: string;\n response_mapping?: Record<string, string>;\n input_schema?: { fields: SkillInputField[] };\n}\n\nexport interface SkillTemplate {\n id: string;\n title: string;\n description: string;\n type: SkillType;\n use_cases: string[];\n}\n\nexport interface SkillListParams {\n page?: number;\n limit?: number;\n type?: SkillType;\n search?: string;\n}\n\n/**\n * Skills API - LLM and API building blocks that workflows compose into runs.\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/skills\n * GET /api/v1/skills/{id}\n * GET /api/v1/skills/{id}/variables\n * GET /api/v1/skills/models\n * GET /api/v1/skills/templates\n * POST /api/v1/skills (both llm + api types via `type` field)\n * POST /api/v1/skills/from-template\n * POST /api/v1/skills/from-node\n * PUT /api/v1/skills/{id}\n * DELETE /api/v1/skills/{id}\n * POST /api/v1/skills/validate\n * POST /api/v1/skills/{id}/execute\n */\nexport const createSkillsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List skills. */\n async list(params: SkillListParams = {}): Promise<{ data: Skill[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get a skill by ID. */\n async get(skillId: string): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Get the variables required by a skill (extracted from prompt or body template). */\n async getVariables(skillId: string): Promise<{ data: SkillInputField[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}/variables`, { headers: headers() });\n return resp.json();\n },\n\n /** List available LLM models. */\n async listModels(): Promise<{ data: Array<{ id: string; label: string; provider: string }> }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/models`, { headers: headers() });\n return resp.json();\n },\n\n /** List skill templates. */\n async listTemplates(params: { type?: SkillType } = {}): Promise<{ data: SkillTemplate[] }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/templates${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Create an LLM skill (prompt + model + schemas). */\n async createLLM(params: SkillCreateLLMParams): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ ...params, type: \"llm\" }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create an API skill (HTTP request wrapper). */\n async createAPI(params: SkillCreateAPIParams): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ ...params, type: \"api\" }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Create a skill from a built-in template. */\n async createFromTemplate(params: { title: string; template_id: string; overrides?: Record<string, unknown> }): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/from-template`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Lift a workflow node into a reusable skill. */\n async createFromNode(params: {\n title: string;\n description?: string;\n node_id: string;\n input_mapping?: Record<string, string>;\n output_mapping?: Record<string, string>;\n }): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/from-node`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(params),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update an LLM skill. */\n async updateLLM(skillId: string, fields: SkillUpdateLLMParams): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify({ ...fields, type: \"llm\" }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Update an API skill. */\n async updateAPI(skillId: string, fields: SkillUpdateAPIParams): Promise<Skill> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {\n method: \"PUT\",\n headers: headers(),\n body: JSON.stringify({ ...fields, type: \"api\" }),\n });\n const data = await resp.json();\n return data.data || data;\n },\n\n /** Delete a skill (irreversible if in-use workflows exist). */\n async delete(skillId: string): Promise<{ data: { deleted: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}`, {\n method: \"DELETE\",\n headers: headers(),\n });\n return resp.json();\n },\n\n /** Validate a skill definition (without saving). */\n async validate(skill: Partial<Skill>): Promise<{ data: { valid: boolean; errors: string[] } }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/validate`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(skill),\n });\n return resp.json();\n },\n\n /** Execute a skill immediately with an input payload (test / preview). */\n async execute(skillId: string, inputPayload: Record<string, unknown>): Promise<{\n data: { output: Record<string, unknown>; latency_ms: number; tokens?: number; error: string | null };\n }> {\n const resp = await fetch(`${baseUrl}/api/v1/skills/${skillId}/execute`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(inputPayload),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface IntentKeyword {\n id: string;\n keyword: string;\n domain: string | null;\n include_patterns: string[];\n exclude_patterns: string[];\n page_count: number;\n visitor_count: number;\n company_count: number;\n contact_count: number;\n created_at: string | null;\n}\n\nexport interface IntentPage {\n url: string;\n title: string | null;\n keyword: string | null;\n domain: string;\n visitor_count: number;\n last_seen: string | null;\n}\n\nexport interface IntentVisitor {\n visitor_id: string;\n company_domain: string | null;\n company_name: string | null;\n page_url: string;\n first_seen: string | null;\n last_seen: string | null;\n visit_count: number;\n}\n\nexport interface IntentCompany {\n domain: string;\n name: string | null;\n industry: string | null;\n employee_count: string | null;\n visit_count: number;\n last_seen: string | null;\n}\n\nexport interface IntentContact {\n contact_id: number | null;\n email: string | null;\n full_name: string | null;\n company: string | null;\n job_title: string | null;\n last_seen: string | null;\n}\n\nexport interface IntentStats {\n total_keywords: number;\n total_pages: number;\n total_visitors_30d: number;\n total_companies_30d: number;\n}\n\n/**\n * Intent + visitor tracking. Distinct from `g8.signals` (which is summary scoring) —\n * this module exposes keyword tracking, page-level visitor data, and account-level\n * intent signals from your own site (or from competitor URLs you've added).\n *\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/intent/stats\n * POST /api/v1/intent/keywords/list\n * POST /api/v1/intent/keywords/create-from-domain\n * DELETE /api/v1/intent/keywords/{keyword_id}\n * POST /api/v1/intent/keywords/{keyword_id}/companies\n * POST /api/v1/intent/keywords/{keyword_id}/contacts\n * POST /api/v1/intent/keywords/{keyword_id}/urls\n * POST /api/v1/intent/pages-by-domain\n * POST /api/v1/intent/pages/search\n * POST /api/v1/intent/pages/visitors\n * POST /api/v1/intent/pages/contacts\n * POST /api/v1/intent/pages/visitor-counts\n * POST /intent-search/url-companies (note: bare host, no /api/v1 prefix)\n */\nexport const createIntentClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const get = async (path: string) => {\n const resp = await fetch(`${baseUrl}/api/v1${path}`, { headers: headers() });\n return resp.json();\n };\n const post = async (path: string, body: Record<string, unknown> = {}) => {\n const resp = await fetch(`${baseUrl}/api/v1${path}`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify(body),\n });\n return resp.json();\n };\n const del = async (path: string) => {\n const resp = await fetch(`${baseUrl}/api/v1${path}`, { method: \"DELETE\", headers: headers() });\n return resp.json();\n };\n\n return {\n /** Org-level intent stats (totals over the last 30 days). */\n async stats(): Promise<{ data: IntentStats }> {\n return get(\"/intent/stats\");\n },\n\n /** List tracked keywords with optional pagination. */\n async listKeywords(params: { page?: number; limit?: number; search?: string } = {}): Promise<{ data: IntentKeyword[] }> {\n return post(\"/intent/keywords/list\", params);\n },\n\n /** Create a keyword group from a domain (auto-tracks all pages). */\n async createFromDomain(domain: string): Promise<{ data: IntentKeyword }> {\n return post(\"/intent/keywords/create-from-domain\", { domain });\n },\n\n /** Stop tracking a keyword (irreversible — historical data is retained). */\n async deleteKeyword(keywordId: string): Promise<{ data: { deleted: boolean } }> {\n return del(`/intent/keywords/${keywordId}`);\n },\n\n /** Companies showing interest in a tracked keyword. */\n async keywordCompanies(keywordId: string, params: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: IntentCompany[] }> {\n return post(`/intent/keywords/${keywordId}/companies`, params);\n },\n\n /** Contacts showing interest in a tracked keyword. */\n async keywordContacts(keywordId: string, params: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: IntentContact[] }> {\n return post(`/intent/keywords/${keywordId}/contacts`, params);\n },\n\n /** URLs associated with a keyword (pages visitors landed on while interested). */\n async keywordUrls(keywordId: string, params: { limit?: number } = {}): Promise<{ data: IntentPage[] }> {\n return post(`/intent/keywords/${keywordId}/urls`, params);\n },\n\n /** Pages tracked on a specific domain. */\n async pagesByDomain(domain: string, params: { limit?: number } = {}): Promise<{ data: IntentPage[] }> {\n return post(\"/intent/pages-by-domain\", { domain, ...params });\n },\n\n /** Search tracked pages by URL fragment or keyword. */\n async searchPages(query: string, params: { limit?: number } = {}): Promise<{ data: IntentPage[] }> {\n return post(\"/intent/pages/search\", { query, ...params });\n },\n\n /** Get visitor records for a specific page URL. */\n async pageVisitors(pageUrl: string, params: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: IntentVisitor[] }> {\n return post(\"/intent/pages/visitors\", { url: pageUrl, ...params });\n },\n\n /** Get contacts who visited a specific page URL. */\n async pageContacts(pageUrl: string, params: { limit?: number } = {}): Promise<{ data: IntentContact[] }> {\n return post(\"/intent/pages/contacts\", { url: pageUrl, ...params });\n },\n\n /** Visitor count aggregates by page (pass an array of URLs). */\n async pageVisitorCounts(urls: string[]): Promise<{ data: Array<{ url: string; visitor_count: number }> }> {\n return post(\"/intent/pages/visitor-counts\", { urls });\n },\n\n /**\n * Find companies whose users visited a specific URL (intent search).\n *\n * Note: this endpoint lives at the bare host (no `/api/v1` prefix), unlike the rest\n * of the intent surface — we call it directly here instead of through the shared `post()` helper.\n */\n async urlCompanies(url: string, params: { limit?: number; date_from?: string; date_to?: string } = {}): Promise<{ data: IntentCompany[] }> {\n const resp = await fetch(`${baseUrl}/intent-search/url-companies`, {\n method: \"POST\",\n headers: headers(),\n body: JSON.stringify({ url, ...params }),\n });\n return resp.json();\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface GlobalContextDocument {\n id: string;\n category: string;\n title: string;\n content: string;\n metadata: Record<string, unknown> | null;\n created_at: string | null;\n updated_at: string | null;\n}\n\nexport interface Persona {\n id: string;\n name: string;\n description: string | null;\n status: string;\n pain_points: string[];\n goals: string[];\n channels: string[];\n created_at: string | null;\n}\n\nexport interface ICP {\n id: string;\n name: string;\n description: string | null;\n status: string;\n industry: string[] | null;\n employee_count_min: number | null;\n employee_count_max: number | null;\n revenue_min: number | null;\n revenue_max: number | null;\n countries: string[] | null;\n created_at: string | null;\n}\n\nexport interface IntelligenceData {\n id: string;\n source_type: string;\n url: string | null;\n title: string | null;\n content_summary: string | null;\n collected_at: string | null;\n}\n\nexport interface ResearchReport {\n id: string;\n category: \"buyer_psychology\" | \"competitive_teardown\" | \"gtm_channel\" | \"industry_analyst\" | \"review_sentiment\" | \"voice_of_customer\";\n title: string;\n summary: string | null;\n created_at: string | null;\n}\n\n/**\n * Studio context — org-level intelligence documents. The 44-doc engine that\n * powers campaign ideation: brand brief, value props, messaging house, ICPs,\n * personas, intelligence (scrapes + enrichment), and AI research reports.\n *\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/global-context/documents\n * GET /api/v1/icps\n * GET /api/v1/personas\n * GET /api/v1/intelligence-data\n * GET /api/v1/research-reports\n */\nexport const createStudioClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n const get = async (path: string, params: object = {}) => {\n const resp = await fetch(`${baseUrl}/api/v1${path}${toQuery(params)}`, { headers: headers() });\n return resp.json();\n };\n\n return {\n /** Org-level Studio documents (brand_brief, value_props, messaging_house, etc.).\n * `include_content` defaults to true server-side, so each document includes\n * its `content` body unless you explicitly pass `include_content: false`. */\n async globalContext(\n params: { category?: string; limit?: number; include_content?: boolean } = {}\n ): Promise<{ data: GlobalContextDocument[] }> {\n return get(\"/global-context/documents\", params);\n },\n\n /** ICP definitions. */\n async icps(params: { status?: string; limit?: number } = {}): Promise<{ data: ICP[] }> {\n return get(\"/icps\", params);\n },\n\n /** Buyer persona definitions. */\n async personas(params: { status?: string; limit?: number } = {}): Promise<{ data: Persona[] }> {\n return get(\"/personas\", params);\n },\n\n /** Intelligence data (website scrapes, enrichment, competitor research). */\n async intelligenceData(params: { source_type?: string; limit?: number } = {}): Promise<{ data: IntelligenceData[] }> {\n return get(\"/intelligence-data\", params);\n },\n\n /** AI research reports (buyer psychology, competitive teardown, GTM channel, etc.). */\n async researchReports(params: { category?: string; limit?: number } = {}): Promise<{ data: ResearchReport[] }> {\n return get(\"/research-reports\", params);\n },\n };\n};\n","const DEFAULT_API = \"https://be.graph8.com\";\n\nexport interface MeetingAttendee {\n name: string | null;\n email: string;\n role: \"host\" | \"prospect\" | \"guest\" | string;\n contact_id?: number | null;\n}\n\nexport interface MeetingTranscriptLine {\n speaker: string;\n text: string;\n timestamp: number;\n}\n\nexport interface MeetingAnalysis {\n sentiment: \"positive\" | \"neutral\" | \"negative\";\n summary: string;\n next_steps: string[];\n objections: string[];\n talk_listen_ratio: number | null;\n}\n\nexport interface MeetingSummary {\n id: string;\n status: \"scheduled\" | \"completed\" | \"cancelled\" | \"no_show\";\n event_type: string | null;\n scheduled_at: string;\n duration_minutes: number;\n attendees: MeetingAttendee[];\n contact_id: number | null;\n conferencing_provider: string | null;\n conferencing_url: string | null;\n recording_url: string | null;\n created_at: string;\n}\n\nexport interface MeetingDetail extends MeetingSummary {\n transcript: MeetingTranscriptLine[] | null;\n analysis: MeetingAnalysis | null;\n}\n\nexport interface MeetingListParams {\n status?: \"scheduled\" | \"completed\" | \"cancelled\" | \"no_show\";\n date_from?: string;\n date_to?: string;\n attendee_id?: string;\n event_type?: string;\n contact_id?: number;\n page?: number;\n limit?: number;\n}\n\n/**\n * Meetings API - read-only access to scheduled, completed, and cancelled meetings.\n * Booking happens via `g8.calendar.*` (write-key safe, browser only) — this surface\n * is for reading meeting records, transcripts, and AI analysis.\n *\n * Requires API key (server-side).\n *\n * Backed by:\n * GET /api/v1/inbox/meetings\n * GET /api/v1/inbox/meetings/{meeting_id}\n */\nexport const createMeetingsClient = (apiKey: string, apiUrl?: string) => {\n const baseUrl = apiUrl || DEFAULT_API;\n const headers = () => ({ \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` });\n\n const toQuery = (params: object) => {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v != null) qs.set(k, String(v));\n }\n const s = qs.toString();\n return s ? `?${s}` : \"\";\n };\n\n return {\n /** List meetings with optional filters. Returns summary rows without transcript / analysis. */\n async list(params: MeetingListParams = {}): Promise<{ data: MeetingSummary[]; pagination?: { page: number; limit: number; total: number; has_next: boolean } }> {\n const resp = await fetch(`${baseUrl}/api/v1/inbox/meetings${toQuery(params)}`, { headers: headers() });\n return resp.json();\n },\n\n /** Get full meeting detail including transcript + AI analysis (transcript available 1-5 min after meeting ends). */\n async get(meetingId: string): Promise<MeetingDetail> {\n const resp = await fetch(`${baseUrl}/api/v1/inbox/meetings/${meetingId}`, { headers: headers() });\n const data = await resp.json();\n return data.data || data;\n },\n };\n};\n"],"mappings":"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","names":["DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API","DEFAULT_API"]}
|