@burdenoff/website-sdk 2026.720.2 → 2026.720.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.
Files changed (59) hide show
  1. package/dist/client/index.d.mts +1 -1
  2. package/dist/client/index.d.ts +1 -1
  3. package/dist/client/index.js +68 -20
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/client/index.mjs +68 -20
  6. package/dist/client/index.mjs.map +1 -1
  7. package/dist/components/contact.js +68 -20
  8. package/dist/components/contact.js.map +1 -1
  9. package/dist/components/contact.mjs +68 -20
  10. package/dist/components/contact.mjs.map +1 -1
  11. package/dist/components/newsletter.js +68 -20
  12. package/dist/components/newsletter.js.map +1 -1
  13. package/dist/components/newsletter.mjs +68 -20
  14. package/dist/components/newsletter.mjs.map +1 -1
  15. package/dist/components/partners.js +68 -20
  16. package/dist/components/partners.js.map +1 -1
  17. package/dist/components/partners.mjs +68 -20
  18. package/dist/components/partners.mjs.map +1 -1
  19. package/dist/components/pricing.js +68 -20
  20. package/dist/components/pricing.js.map +1 -1
  21. package/dist/components/pricing.mjs +68 -20
  22. package/dist/components/pricing.mjs.map +1 -1
  23. package/dist/components/resource-links.js +68 -20
  24. package/dist/components/resource-links.js.map +1 -1
  25. package/dist/components/resource-links.mjs +68 -20
  26. package/dist/components/resource-links.mjs.map +1 -1
  27. package/dist/components/social-links.js +68 -20
  28. package/dist/components/social-links.js.map +1 -1
  29. package/dist/components/social-links.mjs +68 -20
  30. package/dist/components/social-links.mjs.map +1 -1
  31. package/dist/components/unsubscribe.js +68 -20
  32. package/dist/components/unsubscribe.js.map +1 -1
  33. package/dist/components/unsubscribe.mjs +68 -20
  34. package/dist/components/unsubscribe.mjs.map +1 -1
  35. package/dist/components/waitlist.js +68 -20
  36. package/dist/components/waitlist.js.map +1 -1
  37. package/dist/components/waitlist.mjs +68 -20
  38. package/dist/components/waitlist.mjs.map +1 -1
  39. package/dist/content/index.js +68 -20
  40. package/dist/content/index.js.map +1 -1
  41. package/dist/content/index.mjs +68 -20
  42. package/dist/content/index.mjs.map +1 -1
  43. package/dist/index.d.mts +1 -1
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.js +68 -20
  46. package/dist/index.js.map +1 -1
  47. package/dist/index.mjs +68 -20
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/product/index.js +68 -20
  50. package/dist/product/index.js.map +1 -1
  51. package/dist/product/index.mjs +68 -20
  52. package/dist/product/index.mjs.map +1 -1
  53. package/dist/{provider-D7Rij9UM.d.mts → provider-DBAnqeTv.d.mts} +24 -0
  54. package/dist/{provider-D7Rij9UM.d.ts → provider-DBAnqeTv.d.ts} +24 -0
  55. package/dist/store/index.js +68 -20
  56. package/dist/store/index.js.map +1 -1
  57. package/dist/store/index.mjs +68 -20
  58. package/dist/store/index.mjs.map +1 -1
  59. package/package.json +1 -1
@@ -99,9 +99,23 @@ var _WebSDKClient = class _WebSDKClient {
99
99
  * Execute a GraphQL mutation
100
100
  */
101
101
  async mutate(mutation, variables) {
102
- return this.request(mutation, variables);
102
+ return this.request(mutation, variables, false);
103
103
  }
104
- async request(query, variables) {
104
+ /** HTTP statuses worth another attempt — transient server/edge conditions. */
105
+ static isRetriableStatus(status) {
106
+ return status === 429 || status === 408 || status >= 500 && status < 600;
107
+ }
108
+ static sleep(ms) {
109
+ return new Promise((resolve) => setTimeout(resolve, ms));
110
+ }
111
+ /**
112
+ * Perform the HTTP call with a hard timeout. Every outcome resolves to a
113
+ * GraphQLResponse — callers never hang, so a UI's `loading` state always
114
+ * settles into data or a renderable error.
115
+ */
116
+ async attempt(query, variables, timeoutMs) {
117
+ const controller = new AbortController();
118
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
105
119
  try {
106
120
  const response = await fetch(this.config.gatewayUrl, {
107
121
  method: "POST",
@@ -110,7 +124,8 @@ var _WebSDKClient = class _WebSDKClient {
110
124
  "x-product-id": this.config.productId,
111
125
  ...this.config.headers
112
126
  },
113
- body: JSON.stringify({ query, variables })
127
+ body: JSON.stringify({ query, variables }),
128
+ signal: controller.signal
114
129
  });
115
130
  if (!response.ok) {
116
131
  console.error(
@@ -119,34 +134,67 @@ var _WebSDKClient = class _WebSDKClient {
119
134
  response.statusText
120
135
  );
121
136
  return {
122
- errors: [
123
- {
124
- message: `HTTP ${response.status}: ${response.statusText}`,
125
- extensions: { code: `HTTP_${response.status}` }
126
- }
127
- ]
137
+ res: {
138
+ errors: [
139
+ {
140
+ message: `HTTP ${response.status}: ${response.statusText}`,
141
+ extensions: { code: `HTTP_${response.status}` }
142
+ }
143
+ ]
144
+ },
145
+ retriable: _WebSDKClient.isRetriableStatus(response.status)
128
146
  };
129
147
  }
130
- return await response.json();
148
+ return {
149
+ res: await response.json(),
150
+ retriable: false
151
+ };
131
152
  } catch (error) {
132
- console.error(
133
- "[WebSDK] Network error",
134
- error instanceof Error ? error.message : "unknown error"
135
- );
153
+ const aborted = error instanceof Error && (error.name === "AbortError" || controller.signal.aborted);
154
+ const message = aborted ? `Request timed out after ${timeoutMs}ms` : error instanceof Error ? error.message : "Network error";
155
+ console.error("[WebSDK] Network error", message);
136
156
  return {
137
- errors: [
138
- {
139
- message: error instanceof Error ? error.message : "Network error",
140
- extensions: { code: "NETWORK_ERROR" }
141
- }
142
- ]
157
+ res: {
158
+ errors: [
159
+ {
160
+ message,
161
+ extensions: { code: aborted ? "TIMEOUT" : "NETWORK_ERROR" }
162
+ }
163
+ ]
164
+ },
165
+ // Transport-level failures are worth one more try; a genuine outage
166
+ // just fails twice quickly and still renders an error state.
167
+ retriable: true
143
168
  };
169
+ } finally {
170
+ clearTimeout(timer);
171
+ }
172
+ }
173
+ async request(query, variables, retry = true) {
174
+ const timeoutMs = this.config.timeoutMs ?? _WebSDKClient.DEFAULT_TIMEOUT_MS;
175
+ const maxRetries = retry ? this.config.maxRetries ?? _WebSDKClient.DEFAULT_MAX_RETRIES : 0;
176
+ let last;
177
+ for (let i = 0; i <= maxRetries; i++) {
178
+ const { res, retriable } = await this.attempt(
179
+ query,
180
+ variables,
181
+ timeoutMs
182
+ );
183
+ if (!retriable || i === maxRetries) return res;
184
+ last = res;
185
+ await _WebSDKClient.sleep(
186
+ _WebSDKClient.RETRY_BASE_DELAY_MS * (i + 1) + Math.random() * 200
187
+ );
144
188
  }
189
+ return last;
145
190
  }
146
191
  };
147
192
  __publicField(_WebSDKClient, "CACHE_TTL", 5 * 60 * 1e3);
148
193
  // 5 minutes
149
194
  __publicField(_WebSDKClient, "MAX_CACHE_ENTRIES", 100);
195
+ __publicField(_WebSDKClient, "DEFAULT_TIMEOUT_MS", 12e3);
196
+ __publicField(_WebSDKClient, "DEFAULT_MAX_RETRIES", 1);
197
+ __publicField(_WebSDKClient, "RETRY_BASE_DELAY_MS", 400);
150
198
  var WebSDKContext = createContext(null);
151
199
  function useWebSDK() {
152
200
  const client = useContext(WebSDKContext);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/client/security.ts","../../src/client/graphql-client.ts","../../src/client/provider.tsx","../../src/seo/page-head.tsx","../../src/utils/cn.ts","../../src/ui/button.tsx","../../src/components/pricing.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"pricing.mjs","sourcesContent":["const LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\"]);\nconst RESERVED_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"x-actor-id\",\n \"x-actor-type\",\n \"x-consent-granted-by\",\n \"x-consent-scope\",\n \"x-consent-granted-at\",\n \"x-consent-expires-at\",\n]);\n\nexport function validateGatewayUrl(value: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n throw new Error(\"Gateway URL must be a valid absolute URL\");\n }\n\n if (url.protocol === \"https:\") {\n return url.toString();\n }\n\n if (\n url.protocol === \"http:\" &&\n LOOPBACK_HOSTS.has(url.hostname.toLowerCase())\n ) {\n return url.toString();\n }\n\n throw new Error(\"Gateway URL must use HTTPS unless it targets localhost\");\n}\n\nexport function sanitizeHeaders(\n headers?: Record<string, string>,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n\n return Object.fromEntries(\n Object.entries(headers).filter(\n ([key]) => !RESERVED_HEADERS.has(key.toLowerCase()),\n ),\n );\n}\n","/**\n * Lightweight GraphQL client for the Burdenoff Web SDK.\n * Uses native fetch - zero external dependencies.\n * All calls are unauthenticated (public gateway operations only).\n */\n\nimport { sanitizeHeaders, validateGatewayUrl } from \"./security\";\n\nexport interface WebSDKClientConfig {\n /** Global public gateway URL (e.g. \"https://api.burdenoff.com/global/graphql\") */\n gatewayUrl: string;\n /** Platform product ID for scoping operations */\n productId: string;\n /** Product slug (used for public product queries) */\n productSlug?: string;\n /** reCAPTCHA site key (if not fetched from product config) */\n recaptchaSiteKey?: string;\n /** Rybbit analytics site ID */\n rybbitSiteId?: string;\n /** Custom headers to include in all requests */\n headers?: Record<string, string>;\n}\n\nexport interface GraphQLResponse<T = Record<string, unknown>> {\n data?: T;\n errors?: Array<{\n message: string;\n locations?: Array<{ line: number; column: number }>;\n path?: Array<string | number>;\n extensions?: Record<string, unknown>;\n }>;\n}\n\nexport class WebSDKClient {\n private config: WebSDKClientConfig;\n private queryCache = new Map<\n string,\n { data: GraphQLResponse<unknown>; ts: number }\n >();\n private inflight = new Map<string, Promise<GraphQLResponse<unknown>>>();\n private static CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n private static MAX_CACHE_ENTRIES = 100;\n\n constructor(config: WebSDKClientConfig) {\n this.config = {\n ...config,\n gatewayUrl: validateGatewayUrl(config.gatewayUrl),\n headers: sanitizeHeaders(config.headers),\n };\n }\n\n getConfig(): WebSDKClientConfig {\n return this.config;\n }\n\n /**\n * Execute a GraphQL query (with deduplication and caching)\n */\n async query<T = Record<string, unknown>>(\n query: string,\n variables?: Record<string, unknown>,\n ): Promise<GraphQLResponse<T>> {\n const cacheKey = JSON.stringify({ query, variables });\n\n // Return cached response if still valid, evict if expired\n const cached = this.queryCache.get(cacheKey);\n if (cached) {\n if (Date.now() - cached.ts < WebSDKClient.CACHE_TTL) {\n return cached.data as GraphQLResponse<T>;\n }\n this.queryCache.delete(cacheKey);\n }\n\n // Deduplicate: if same query is already in-flight, reuse the promise\n const existing = this.inflight.get(cacheKey);\n if (existing) {\n return existing as Promise<GraphQLResponse<T>>;\n }\n\n const promise = this.request<T>(query, variables)\n .then((result) => {\n // Cache successful responses only\n if (result.data && !result.errors?.length) {\n if (this.queryCache.size >= WebSDKClient.MAX_CACHE_ENTRIES) {\n const oldestEntry = this.queryCache.keys().next().value;\n if (oldestEntry) {\n this.queryCache.delete(oldestEntry);\n }\n }\n this.queryCache.set(cacheKey, { data: result, ts: Date.now() });\n }\n return result;\n })\n .finally(() => {\n this.inflight.delete(cacheKey);\n });\n\n this.inflight.set(cacheKey, promise);\n return promise;\n }\n\n /**\n * Execute a GraphQL mutation\n */\n async mutate<T = Record<string, unknown>>(\n mutation: string,\n variables?: Record<string, unknown>,\n ): Promise<GraphQLResponse<T>> {\n return this.request<T>(mutation, variables);\n }\n\n private async request<T>(\n query: string,\n variables?: Record<string, unknown>,\n ): Promise<GraphQLResponse<T>> {\n try {\n const response = await fetch(this.config.gatewayUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-product-id\": this.config.productId,\n ...this.config.headers,\n },\n body: JSON.stringify({ query, variables }),\n });\n\n if (!response.ok) {\n console.error(\n \"[WebSDK] GraphQL request failed\",\n response.status,\n response.statusText,\n );\n return {\n errors: [\n {\n message: `HTTP ${response.status}: ${response.statusText}`,\n extensions: { code: `HTTP_${response.status}` },\n },\n ],\n };\n }\n\n return (await response.json()) as GraphQLResponse<T>;\n } catch (error) {\n console.error(\n \"[WebSDK] Network error\",\n error instanceof Error ? error.message : \"unknown error\",\n );\n return {\n errors: [\n {\n message: error instanceof Error ? error.message : \"Network error\",\n extensions: { code: \"NETWORK_ERROR\" },\n },\n ],\n };\n }\n }\n}\n","/**\n * React context provider for the Web SDK client.\n * Wraps the application with WebSDKClient configuration.\n */\n\"use client\";\n\nimport { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport { resolveGatewayUrl } from \"./gateway-resolver\";\nimport { WebSDKClient, type WebSDKClientConfig } from \"./graphql-client\";\n\nconst WebSDKContext = createContext<WebSDKClient | null>(null);\n\nexport interface WebSDKProviderProps {\n /** SDK client configuration */\n config: WebSDKClientConfig;\n /** Child components */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes the WebSDKClient available to all child components.\n *\n * @example\n * ```tsx\n * <WebSDKProvider config={{\n * gatewayUrl: \"https://api.burdenoff.com/global/graphql\",\n * productId: \"your-product-id\",\n * productSlug: \"your-product\",\n * }}>\n * <App />\n * </WebSDKProvider>\n * ```\n */\nexport function WebSDKProvider({ config, children }: WebSDKProviderProps) {\n const client = useMemo(() => {\n const resolvedConfig = {\n ...config,\n gatewayUrl: resolveGatewayUrl(config.gatewayUrl),\n };\n return new WebSDKClient(resolvedConfig);\n }, [config]);\n\n return (\n <WebSDKContext.Provider value={client}>{children}</WebSDKContext.Provider>\n );\n}\n\n/**\n * Hook to access the WebSDKClient instance.\n * Must be used within a WebSDKProvider.\n */\nexport function useWebSDK(): WebSDKClient {\n const client = useContext(WebSDKContext);\n if (!client) {\n throw new Error(\"useWebSDK must be used within a WebSDKProvider\");\n }\n return client;\n}\n\n/**\n * Hook to access the SDK configuration.\n * Useful for components that need config values like productId, recaptchaSiteKey, etc.\n */\nexport function useWebSDKConfig(): WebSDKClientConfig {\n const client = useWebSDK();\n return client.getConfig();\n}\n","/**\n * PageHead Component\n * Manages dynamic meta tags for SEO optimization on a per-page basis.\n * Supports JSON-LD structured data, Open Graph, Twitter Cards, favicons, and robots directives.\n *\n * @example\n * ```tsx\n * <PageHead\n * title=\"About Us\"\n * description=\"Learn about our mission and team\"\n * productName=\"MyProduct\"\n * keywords=\"about, team, mission\"\n * image=\"/og-about.png\"\n * url=\"https://myproduct.com/about\"\n * favicon=\"/favicon.ico\"\n * robots=\"index, follow\"\n * locale=\"en_US\"\n * twitterHandle=\"@burdenoff\"\n * themeColor=\"#1a1a2e\"\n * structuredData={{\n * \"@context\": \"https://schema.org\",\n * \"@type\": \"WebPage\",\n * name: \"About Us\",\n * }}\n * />\n * ```\n */\n\nimport { Helmet } from \"react-helmet-async\";\n\nexport interface PageHeadProps {\n /** Page title */\n title: string;\n /** Meta description */\n description?: string;\n /** Product/brand name (appended to title) */\n productName?: string;\n /** SEO keywords */\n keywords?: string;\n /** Open Graph image URL */\n image?: string;\n /** Page canonical URL */\n url?: string;\n /** Favicon URL */\n favicon?: string;\n /** Robots directive (e.g., \"index, follow\") */\n robots?: string;\n /** Open Graph locale (e.g., \"en_US\") */\n locale?: string;\n /** Twitter handle (e.g., \"@burdenoff\") */\n twitterHandle?: string;\n /** Theme color for mobile browsers */\n themeColor?: string;\n /** JSON-LD structured data objects */\n structuredData?: Record<string, unknown> | Array<Record<string, unknown>>;\n /** Additional meta tags */\n additionalMeta?: Array<{\n name?: string;\n property?: string;\n content: string;\n }>;\n}\n\nexport function PageHead({\n title,\n description,\n productName,\n keywords,\n image,\n url,\n favicon,\n robots = \"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\",\n locale = \"en_US\",\n twitterHandle,\n themeColor = \"#000000\",\n structuredData,\n additionalMeta,\n}: PageHeadProps) {\n const fullTitle =\n productName && !title.includes(productName)\n ? `${title} | ${productName}`\n : title;\n\n const fullImageUrl =\n image && !image.startsWith(\"http\") && url\n ? `${url.replace(/\\/$/, \"\")}${image}`\n : image;\n\n // Normalize structured data to an array\n const structuredDataItems: Array<Record<string, unknown>> = structuredData\n ? Array.isArray(structuredData)\n ? structuredData\n : [structuredData]\n : [];\n\n return (\n <Helmet>\n {/* Primary Meta Tags */}\n <title>{fullTitle}</title>\n <meta name=\"title\" content={fullTitle} />\n {description && <meta name=\"description\" content={description} />}\n {keywords && <meta name=\"keywords\" content={keywords} />}\n <meta name=\"author\" content=\"Burdenoff Consultancy Services Pvt Ltd\" />\n <meta name=\"robots\" content={robots} />\n\n {/* Canonical URL */}\n {url && <link rel=\"canonical\" href={url} />}\n\n {/* Favicon */}\n {favicon && <link rel=\"icon\" href={favicon} />}\n\n {/* Open Graph / Facebook */}\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:title\" content={fullTitle} />\n {description && <meta property=\"og:description\" content={description} />}\n {fullImageUrl && <meta property=\"og:image\" content={fullImageUrl} />}\n {url && <meta property=\"og:url\" content={url} />}\n <meta property=\"og:locale\" content={locale} />\n {productName && <meta property=\"og:site_name\" content={productName} />}\n\n {/* Twitter Card */}\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\n <meta name=\"twitter:title\" content={fullTitle} />\n {description && <meta name=\"twitter:description\" content={description} />}\n {fullImageUrl && <meta name=\"twitter:image\" content={fullImageUrl} />}\n {twitterHandle && <meta name=\"twitter:creator\" content={twitterHandle} />}\n\n {/* Theme Color */}\n <meta name=\"theme-color\" content={themeColor} />\n\n {/* JSON-LD Structured Data */}\n {structuredDataItems.map((data, index) => (\n <script key={`ld-${index}`} type=\"application/ld+json\">\n {JSON.stringify(data)}\n </script>\n ))}\n\n {/* Additional Meta Tags */}\n {additionalMeta?.map((meta, index) => (\n <meta\n key={`meta-${index}`}\n {...(meta.name ? { name: meta.name } : {})}\n {...(meta.property ? { property: meta.property } : {})}\n content={meta.content}\n />\n ))}\n </Helmet>\n );\n}\n","/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../utils/cn\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","/**\n * Pricing Component\n * GraphQL-powered pricing component with quota-based features and monthly/yearly toggle\n *\n * @example\n * ```tsx\n * import { PricingPage, PricingSection } from '@burdenoff/website-sdk/components/pricing'\n *\n * // Full page with hero\n * <PricingPage\n * productName=\"BigConsole\"\n * productId=\"bigconsole-123\"\n * appLoginUrl=\"https://app.bigconsole.com/login\"\n * contactUrl=\"/contact\"\n * fallbackFeatures={{\n * basic: ['Up to 5 dashboards', '10 data sources'],\n * professional: ['Unlimited dashboards', 'API access'],\n * enterprise: ['Everything in Professional', 'Dedicated support']\n * }}\n * />\n *\n * // Embeddable section\n * <PricingSection {...props} id=\"pricing\" className=\"bg-muted/30\" />\n * ```\n */\n\n\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\n\n// ============================================================================\n// GRAPHQL QUERY\n// ============================================================================\n\nconst GET_PLANS_QUERY = `\n query GetPublicPlans($productId: String!) {\n publicPlans(productId: $productId) {\n id\n name\n price\n currency\n currencyPrices\n duration\n features {\n id\n quotaId\n quota {\n id\n name\n limits\n }\n }\n isActive\n productID\n createdAt\n }\n }\n`;\n\n// ============================================================================\n// TYPES & INTERFACES\n// ============================================================================\n\ninterface PlanFeature {\n id: string;\n quotaId?: string | null;\n quota?: {\n id: string;\n name: string;\n limits?: unknown;\n } | null;\n}\n\ninterface GatewayPlan {\n id: string;\n name: string;\n price: number;\n currency: string;\n currencyPrices?: Record<string, number> | null;\n duration: string;\n features: PlanFeature[];\n isActive: boolean;\n productID?: string | null;\n createdAt: string;\n}\n\ninterface GetPlansResponse {\n publicPlans: GatewayPlan[];\n}\n\nexport interface PlanCard {\n id: string;\n name: string;\n price: number;\n currency: string;\n currencyPrices?: Record<string, number> | null;\n duration: string;\n features: Array<{\n id: string;\n quotaId?: string | null;\n quota?: {\n id: string;\n name: string;\n limits?: unknown;\n } | null;\n }>;\n isActive: boolean;\n productID?: string | null;\n}\n\ninterface CurrencyConfig {\n code: string;\n symbol: string;\n position: \"prefix\" | \"suffix\";\n}\n\ninterface PlanMetadata {\n tier: \"basic\" | \"professional\" | \"enterprise\";\n displayName: string;\n defaultDescription: string;\n popular: boolean;\n ctaText: string;\n ctaType: \"signup\" | \"contact\";\n /**\n * Curated feature bullets for this specific plan. When provided, these win\n * over the tier-based `fallbackFeatures` and the raw quota list — letting a\n * consumer differentiate plans that share a tier keyword (e.g. Free vs Hobby,\n * Pro vs Team) with concise, accurate copy.\n */\n features?: string[];\n}\n\nexport interface PricingProps {\n /**\n * Product name (used in branding and SEO)\n */\n productName?: string;\n /**\n * Product ID for GraphQL query (falls back to WebSDKConfig.productId)\n */\n productId?: string;\n /**\n * App login URL for signup CTA\n */\n appLoginUrl: string;\n /**\n * Contact page URL for enterprise CTA\n * @default '/contact'\n */\n contactUrl?: string;\n /**\n * Supported currencies\n */\n currencies?: Record<string, CurrencyConfig>;\n /**\n * Billing interval display text\n */\n billingIntervals?: Record<string, string>;\n /**\n * Plan metadata (tier info, CTA text, etc.)\n */\n planMetadata?: Record<string, Partial<PlanMetadata>>;\n /**\n * Fallback features when API doesn't provide them or is unavailable\n */\n fallbackFeatures?: {\n basic?: string[];\n professional?: string[];\n enterprise?: string[];\n };\n /**\n * Enable audience tabs (Individual / Enterprise).\n * When enabled, shows a two-level tab system.\n * @default false\n */\n showAudienceTabs?: boolean;\n /**\n * Enterprise plans to show when Enterprise tab is selected.\n * Each entry defines a static plan card (not fetched from API).\n */\n enterprisePlans?: Array<{\n name: string;\n subtitle: string;\n price: string;\n period: string;\n note?: string;\n button: string;\n buttonLink: string;\n popular: boolean;\n badge?: string;\n features: string[];\n }>;\n /**\n * Enterprise section heading\n * @default 'Enterprise Solutions'\n */\n enterpriseHeading?: string;\n /**\n * Enterprise section subtitle\n */\n enterpriseSubtitle?: string;\n /**\n * Hero section heading (for PricingPage)\n * @default 'Simple, Transparent Pricing'\n */\n heroHeading?: string;\n /**\n * Hero section subtitle (for PricingPage)\n * @default \"Choose the plan that's right for you. No hidden fees, no surprises.\"\n */\n heroSubtitle?: string;\n /**\n * Section heading (for PricingSection)\n * @default 'Pricing Plans'\n */\n sectionHeading?: string;\n /**\n * Section subtitle (for PricingSection)\n * @default 'Choose the perfect plan for your needs'\n */\n sectionSubtitle?: string;\n /**\n * Custom CSS class\n */\n className?: string;\n /**\n * Section ID for anchor links\n */\n id?: string;\n /**\n * SEO: Page title (optional, for PricingPage)\n */\n seoTitle?: string;\n /**\n * SEO: Page description (optional, for PricingPage)\n */\n seoDescription?: string;\n /**\n * SEO: Keywords (optional, for PricingPage)\n */\n seoKeywords?: string;\n /**\n * SEO: OG Image URL (optional, for PricingPage)\n */\n seoImage?: string;\n /**\n * SEO: Canonical URL (optional, for PricingPage)\n */\n seoUrl?: string;\n}\n\n// ============================================================================\n// SERVICE FUNCTIONS\n// ============================================================================\n\n/**\n * Format price for display with currency symbol\n */\nfunction formatPrice(\n price: number,\n currencyCode: string = \"USD\",\n currencies?: Record<string, CurrencyConfig>,\n): string {\n const defaultCurrencies: Record<string, CurrencyConfig> = {\n USD: { code: \"USD\", symbol: \"$\", position: \"prefix\" },\n EUR: { code: \"EUR\", symbol: \"\\u20AC\", position: \"prefix\" },\n GBP: { code: \"GBP\", symbol: \"\\u00A3\", position: \"prefix\" },\n INR: { code: \"INR\", symbol: \"\\u20B9\", position: \"prefix\" },\n };\n\n const currencyMap = currencies || defaultCurrencies;\n const currency: CurrencyConfig = currencyMap[currencyCode] || {\n code: currencyCode,\n symbol: currencyCode,\n position: \"prefix\",\n };\n\n const formattedNumber = price % 1 === 0 ? price.toString() : price.toFixed(2);\n\n return currency.position === \"prefix\"\n ? `${currency.symbol}${formattedNumber}`\n : `${formattedNumber}${currency.symbol}`;\n}\n\n/**\n * Format billing interval for display\n */\nfunction formatInterval(\n duration: string,\n billingIntervals?: Record<string, string>,\n): string {\n const defaultIntervals: Record<string, string> = {\n monthly: \"/month\",\n yearly: \"/year\",\n };\n\n const intervals = billingIntervals || defaultIntervals;\n return intervals[duration] || `/${duration}`;\n}\n\n/**\n * Detect if a plan belongs to the enterprise audience based on name.\n * Plans with \"team\", \"business\", or \"enterprise\" in the name are enterprise.\n */\nfunction isEnterprisePlan(planName: string): boolean {\n const name = planName.toLowerCase();\n return (\n name.includes(\"team\") ||\n name.includes(\"business\") ||\n name.includes(\"enterprise\")\n );\n}\n\n/**\n * Detect plan tier from plan name\n */\nfunction detectPlanTier(\n planName: string,\n): \"basic\" | \"professional\" | \"enterprise\" | null {\n const name = planName.toLowerCase();\n\n if (\n name.includes(\"free\") ||\n name.includes(\"basic\") ||\n name.includes(\"starter\") ||\n name.includes(\"hobby\")\n ) {\n return \"basic\";\n } else if (\n name.includes(\"pro\") ||\n name.includes(\"professional\") ||\n name.includes(\"premium\") ||\n name.includes(\"team\")\n ) {\n return \"professional\";\n } else if (name.includes(\"enterprise\") || name.includes(\"business\")) {\n return \"enterprise\";\n }\n\n return null;\n}\n\n/**\n * Get features for a specific plan tier from fallback config\n */\nfunction getFallbackFeaturesForTier(\n tier: \"basic\" | \"professional\" | \"enterprise\",\n fallbackFeatures?: {\n basic?: string[];\n professional?: string[];\n enterprise?: string[];\n },\n): string[] {\n return [...(fallbackFeatures?.[tier] || [])];\n}\n\n/**\n * Get metadata for a plan by name\n */\nfunction getMetadataForPlan(\n planName: string,\n planMetadata?: Record<string, Partial<PlanMetadata>>,\n): PlanMetadata {\n const normalizedName = planName.toLowerCase();\n\n // Try exact match first\n if (planMetadata?.[normalizedName]) {\n const meta = planMetadata[normalizedName];\n return {\n tier: meta.tier || \"basic\",\n displayName: meta.displayName || planName,\n defaultDescription: meta.defaultDescription || \"Choose this plan\",\n popular: meta.popular ?? false,\n ctaText: meta.ctaText || \"Get Started\",\n ctaType: meta.ctaType || \"signup\",\n features: meta.features,\n };\n }\n\n // Try tier detection\n const tier = detectPlanTier(planName);\n if (tier) {\n return {\n tier,\n displayName: planName,\n defaultDescription: \"Choose this plan\",\n popular: tier === \"professional\",\n ctaText: tier === \"enterprise\" ? \"Contact Sales\" : \"Get Started\",\n ctaType: tier === \"enterprise\" ? \"contact\" : \"signup\",\n };\n }\n\n // Fallback\n return {\n tier: \"basic\",\n displayName: planName,\n defaultDescription: \"Choose this plan\",\n popular: false,\n ctaText: \"Get Started\",\n ctaType: \"signup\",\n };\n}\n\n/**\n * Transform quota limits to a human-readable feature string\n */\n/**\n * Derive a human-readable label from a dotted quota name.\n * e.g. \"vibecontrols.workspaces.count\" → \"Workspaces\"\n * \"vibecontrols.storage.bytes\" → \"Storage\"\n */\nfunction humanizeQuotaName(name: string): string {\n const parts = name.split(\".\");\n // Use the second-to-last segment (the resource), or fall back to the last\n const resource =\n parts.length >= 3 ? parts[parts.length - 2]! : parts[parts.length - 1]!;\n // Capitalize and replace hyphens/underscores with spaces\n return resource\n .replace(/[-_]/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction transformQuotaToFeature(quota: {\n id: string;\n name: string;\n limits?: unknown;\n}): string {\n const { name, limits } = quota;\n\n if (!limits || typeof limits !== \"object\") {\n return humanizeQuotaName(name);\n }\n\n const limitsObj = limits as Record<string, unknown>;\n const value = limitsObj.value;\n const unit = limitsObj.unit;\n const type = limitsObj.type;\n const description = limitsObj.description;\n\n // Use explicit description if provided\n if (typeof description === \"string\" && description) {\n if (type === \"number\" && typeof value === \"number\") {\n return `${value.toLocaleString()} ${description}`;\n }\n return description;\n }\n\n // Use unit if provided\n if (typeof unit === \"string\" && unit) {\n if (typeof value === \"number\") {\n return `${value.toLocaleString()} ${unit}`;\n }\n return `${unit}`;\n }\n\n // Derive label from quota name\n const label = humanizeQuotaName(name);\n\n if (type === \"boolean\") {\n return label;\n }\n\n if (typeof value === \"number\") {\n return `${value.toLocaleString()} ${label}`;\n }\n\n return label;\n}\n\n/**\n * Extract display features from a plan's feature list\n */\nfunction extractDisplayFeatures(\n features: PlanFeature[],\n planName: string,\n fallbackFeatures?: {\n basic?: string[];\n professional?: string[];\n enterprise?: string[];\n },\n): string[] {\n // Prefer curated fallback features when available — they are concise\n // and differentiated per tier, unlike raw quota dumps\n const tier = detectPlanTier(planName);\n if (tier) {\n const tierFeatures = getFallbackFeaturesForTier(tier, fallbackFeatures);\n if (tierFeatures.length > 0) {\n return tierFeatures;\n }\n }\n\n // No fallback: transform quota features from API\n const quotaFeatures = features\n .filter((f) => f.quota)\n .map((f) => transformQuotaToFeature(f.quota!));\n\n if (quotaFeatures.length > 0) {\n return quotaFeatures;\n }\n\n return [];\n}\n\n// ============================================================================\n// UI CARD TYPE (internal)\n// ============================================================================\n\ninterface DisplayPlanCard {\n id: string;\n name: string;\n description: string;\n price: string;\n priceRaw: number;\n interval: string;\n duration: string;\n features: string[];\n popular: boolean;\n ctaText: string;\n ctaLink: string;\n tier: \"basic\" | \"professional\" | \"enterprise\" | null;\n}\n\n/**\n * Transform a GatewayPlan into a display card\n */\nfunction transformToDisplayCard(\n plan: GatewayPlan,\n props: PricingProps,\n): DisplayPlanCard {\n const metadata = getMetadataForPlan(plan.name, props.planMetadata);\n\n const formattedPrice = formatPrice(\n plan.price,\n plan.currency,\n props.currencies,\n );\n const interval = formatInterval(plan.duration, props.billingIntervals);\n\n // A curated per-plan list (via planMetadata) wins over the tier fallback and\n // the raw quota dump — this is how Free/Hobby and Pro/Team get distinct copy.\n const features =\n metadata.features && metadata.features.length > 0\n ? metadata.features\n : extractDisplayFeatures(\n plan.features,\n plan.name,\n props.fallbackFeatures,\n );\n\n const contactUrl = props.contactUrl || \"/contact\";\n const ctaLink =\n metadata.ctaType === \"contact\" ? contactUrl : props.appLoginUrl;\n\n return {\n id: plan.id,\n name: plan.name,\n description: metadata.defaultDescription,\n price: formattedPrice,\n priceRaw: plan.price,\n interval,\n duration: plan.duration,\n features,\n popular: metadata.popular,\n ctaText: metadata.ctaText,\n ctaLink,\n tier: metadata.tier,\n };\n}\n\n// ============================================================================\n// REACT COMPONENTS\n// ============================================================================\n\n/**\n * Pricing Section Component - Embeddable\n */\nexport function PricingSection(props: PricingProps) {\n const {\n sectionHeading = \"Pricing Plans\",\n sectionSubtitle = \"Choose the perfect plan for your needs\",\n id,\n className = \"\",\n } = props;\n\n const client = useWebSDK();\n const config = useWebSDKConfig();\n\n const resolvedProductId = props.productId || config.productId;\n\n const [allPlans, setAllPlans] = useState<DisplayPlanCard[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [billingCycle, setBillingCycle] = useState<\"monthly\" | \"yearly\">(\n \"monthly\",\n );\n const [audience, setAudience] = useState<\"individual\" | \"enterprise\">(\n \"individual\",\n );\n\n useEffect(() => {\n let cancelled = false;\n\n async function loadPlans() {\n try {\n setLoading(true);\n\n const response = await client.query<GetPlansResponse>(GET_PLANS_QUERY, {\n productId: resolvedProductId,\n });\n\n if (cancelled) return;\n\n if (response.errors && response.errors.length > 0) {\n throw new Error(response.errors[0]!.message);\n }\n\n if (!response.data?.publicPlans) {\n throw new Error(\"No plans data received\");\n }\n\n // Server already filters by productId — just filter active, transform, sort\n const cards = response.data.publicPlans\n .filter((plan) => plan.isActive)\n .map((plan) => transformToDisplayCard(plan, props))\n .sort((a, b) => a.priceRaw - b.priceRaw);\n\n setAllPlans(cards);\n setError(null);\n } catch (err) {\n if (cancelled) return;\n console.error(\"Failed to load plans:\", err);\n setError(\"Unable to load pricing information. Please try again later.\");\n } finally {\n if (!cancelled) {\n setLoading(false);\n }\n }\n }\n\n loadPlans();\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- props is destructured, actual deps are client + productId\n }, [client, resolvedProductId]);\n\n // Split plans by audience (individual vs enterprise) based on plan name\n const individualAllPlans = allPlans.filter((p) => !isEnterprisePlan(p.name));\n const enterpriseApiPlans = allPlans.filter((p) => isEnterprisePlan(p.name));\n\n // Filter individual plans by billing cycle\n const individualPlans = individualAllPlans.filter((plan) =>\n billingCycle === \"monthly\"\n ? plan.duration === \"monthly\"\n : plan.duration === \"yearly\",\n );\n\n // Enterprise plans from API (show all — no billing cycle filter since enterprise is typically monthly)\n const enterpriseCards: DisplayPlanCard[] = enterpriseApiPlans.map((p) => {\n // Mark $0 enterprise plans as \"Custom\" pricing with Contact Sales CTA\n if (p.priceRaw === 0 && p.name.toLowerCase().includes(\"enterprise\")) {\n return {\n ...p,\n price: \"Custom\",\n interval: \"\",\n ctaText: \"Contact Sales\",\n ctaLink: props.contactUrl || \"/contact\",\n };\n }\n return p;\n });\n\n // Use API enterprise plans if available, otherwise fall back to static prop, otherwise use built-in default\n const hasApiEnterprisePlans = enterpriseCards.length > 0;\n const defaultEnterpriseCard: Record<string, unknown> = {\n name: \"Enterprise\",\n subtitle: \"For organizations that need more\",\n description: \"For organizations that need more\",\n price: \"Custom\",\n period: \"\",\n interval: \"\",\n button: \"Contact Sales\",\n buttonLink: props.contactUrl || \"/contact\",\n ctaText: \"Contact Sales\",\n ctaLink: props.contactUrl || \"/contact\",\n popular: false,\n features: props.fallbackFeatures?.enterprise || [\n \"Unlimited everything\",\n \"SSO & SAML\",\n \"Audit logs\",\n \"Dedicated support\",\n \"Self-hosted option\",\n ],\n };\n const resolvedEnterprisePlans = hasApiEnterprisePlans\n ? (enterpriseCards as unknown as Record<string, unknown>[])\n : props.enterprisePlans\n ? (props.enterprisePlans as unknown as Record<string, unknown>[])\n : [defaultEnterpriseCard];\n\n // Determine which plans to show based on audience\n const plans =\n props.showAudienceTabs && audience === \"enterprise\"\n ? [] // Enterprise uses separate rendering\n : individualPlans;\n\n if (loading) {\n return (\n <section id={id} className={`py-12 sm:py-16 md:py-20 ${className}`}>\n <div className=\"container mx-auto px-4 sm:px-6\">\n <div className=\"text-center mb-8 sm:mb-12\">\n {sectionHeading ? (\n <h2 className=\"text-2xl sm:text-3xl md:text-4xl font-bold mb-3 sm:mb-4\">\n {sectionHeading}\n </h2>\n ) : (\n // Visually hidden but DOM-present heading so axe's heading-order\n // rule still sees an h2 between the consumer's hero h1 and the\n // h3 plan-card titles. See `getMetadataForPlan` for why a falsy\n // sectionHeading is the canonical \"no visible heading\" signal.\n <h2 className=\"sr-only\">Pricing</h2>\n )}\n <p className=\"text-muted-foreground text-sm sm:text-base md:text-lg\">\n Loading pricing information...\n </p>\n </div>\n <div className=\"grid md:grid-cols-3 gap-6 sm:gap-8\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"bg-card border rounded-lg p-6 animate-pulse\"\n >\n <div className=\"h-6 bg-muted rounded w-1/2 mb-4\"></div>\n <div className=\"h-4 bg-muted rounded w-3/4 mb-6\"></div>\n <div className=\"h-10 bg-muted rounded w-1/3 mb-6\"></div>\n <div className=\"space-y-3 mb-6\">\n {[1, 2, 3, 4].map((j) => (\n <div key={j} className=\"h-4 bg-muted rounded\"></div>\n ))}\n </div>\n <div className=\"h-10 bg-muted rounded\"></div>\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n }\n\n if (error && plans.length === 0) {\n return (\n <section id={id} className={`py-12 sm:py-16 md:py-20 ${className}`}>\n <div className=\"container mx-auto px-4 sm:px-6\">\n <div className=\"text-center\">\n {sectionHeading ? (\n <h2 className=\"text-2xl sm:text-3xl md:text-4xl font-bold mb-4\">\n {sectionHeading}\n </h2>\n ) : (\n <h2 className=\"sr-only\">Pricing</h2>\n )}\n <p className=\"text-muted-foreground mb-8\">{error}</p>\n <Button onClick={() => window.location.reload()}>Retry</Button>\n </div>\n </div>\n </section>\n );\n }\n\n return (\n <section id={id} className={`py-12 sm:py-16 md:py-20 ${className}`}>\n <div className=\"container mx-auto px-4 sm:px-6\">\n <div className=\"text-center mb-8 sm:mb-12\">\n {sectionHeading ? (\n <h2 className=\"text-2xl sm:text-3xl md:text-4xl font-bold mb-3 sm:mb-4\">\n {sectionHeading}\n </h2>\n ) : (\n <h2 className=\"sr-only\">Pricing</h2>\n )}\n <p className=\"text-muted-foreground text-sm sm:text-base md:text-lg mb-6\">\n {sectionSubtitle}\n </p>\n\n {/* Audience Toggle (Individual / Enterprise) */}\n {props.showAudienceTabs && (\n <div className=\"flex justify-center mb-4\">\n <div className=\"inline-flex items-center bg-muted p-1.5 rounded-xl\">\n <button\n type=\"button\"\n onClick={() => setAudience(\"individual\")}\n className={`px-6 sm:px-8 py-2.5 rounded-lg text-sm font-semibold transition-all ${\n audience === \"individual\"\n ? \"bg-background shadow-sm text-foreground\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Individual\n </button>\n <button\n type=\"button\"\n onClick={() => setAudience(\"enterprise\")}\n className={`px-6 sm:px-8 py-2.5 rounded-lg text-sm font-semibold transition-all ${\n audience === \"enterprise\"\n ? \"bg-background shadow-sm text-foreground\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Enterprise\n </button>\n </div>\n </div>\n )}\n\n {/* Billing Cycle Toggle — only for Individual */}\n {(audience === \"individual\" || !props.showAudienceTabs) && (\n <div className=\"flex justify-center\">\n <div className=\"inline-flex items-center bg-muted/60 p-1.5 rounded-xl\">\n <button\n type=\"button\"\n onClick={() => setBillingCycle(\"monthly\")}\n className={`px-5 sm:px-6 py-2 rounded-lg text-sm font-medium transition-all ${\n billingCycle === \"monthly\"\n ? \"bg-background shadow-sm text-foreground\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Monthly\n </button>\n <button\n type=\"button\"\n onClick={() => setBillingCycle(\"yearly\")}\n className={`px-5 sm:px-6 py-2 rounded-lg text-sm font-medium transition-all ${\n billingCycle === \"yearly\"\n ? \"bg-background shadow-sm text-foreground\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Yearly\n </button>\n </div>\n </div>\n )}\n </div>\n\n {/* Enterprise Intro — only when Enterprise is selected */}\n {props.showAudienceTabs && audience === \"enterprise\" && (\n <div className=\"mx-auto max-w-3xl text-center mb-8\">\n <h3 className=\"text-xl sm:text-2xl font-bold text-foreground\">\n {props.enterpriseHeading || \"Enterprise Solutions\"}\n </h3>\n <p className=\"mt-3 text-muted-foreground\">\n {props.enterpriseSubtitle ||\n \"Built for teams, agencies, and organizations that need advanced collaboration, security, support, and scale.\"}\n </p>\n </div>\n )}\n\n <div className=\"grid md:grid-cols-3 gap-6 sm:gap-8 max-w-6xl mx-auto items-stretch\">\n {props.showAudienceTabs && audience === \"enterprise\"\n ? /* Enterprise cards — from API, static prop, or built-in default */\n resolvedEnterprisePlans.map((ep) => {\n // Normalize fields — API uses description/ctaText/ctaLink/interval, static prop uses subtitle/button/buttonLink/period\n const subtitle = (ep.subtitle ||\n ep.description ||\n \"\") as string;\n const btnText = (ep.button ||\n ep.ctaText ||\n \"Get Started\") as string;\n const btnLink = (ep.buttonLink ||\n ep.ctaLink ||\n props.appLoginUrl) as string;\n const period = (ep.period || ep.interval || \"\") as string;\n const note = (ep.note || \"\") as string;\n const badge = (ep.badge || \"\") as string;\n const isPopular = ep.popular as boolean;\n const features = (ep.features || []) as string[];\n const price = String(ep.price);\n\n return (\n <div\n key={ep.name as string}\n className={`bg-card rounded-xl p-6 sm:p-8 transition-all duration-300 flex flex-col ${\n isPopular\n ? \"border-2 border-primary shadow-xl ring-1 ring-primary/20\"\n : \"border hover:shadow-lg hover:border-primary/50\"\n }`}\n >\n <div className=\"text-center mb-6\">\n {isPopular && badge && (\n <span className=\"inline-block bg-primary text-primary-foreground px-4 py-1 rounded-full text-xs font-semibold mb-3\">\n {badge}\n </span>\n )}\n <h3 className=\"text-xl sm:text-2xl font-bold mb-2\">\n {ep.name as string}\n </h3>\n <p className=\"text-muted-foreground text-sm\">\n {subtitle}\n </p>\n </div>\n\n <div className=\"text-center mb-2\">\n {price === \"Custom\" ? (\n <span className=\"text-3xl sm:text-4xl font-bold\">\n Custom\n </span>\n ) : (\n <div className=\"flex items-baseline justify-center gap-1\">\n <span className=\"text-4xl sm:text-5xl font-extrabold\">\n {price}\n </span>\n <span className=\"text-muted-foreground text-lg\">\n {period}\n </span>\n </div>\n )}\n {note && (\n <p className=\"mt-2 text-sm font-medium text-primary\">\n {note}\n </p>\n )}\n </div>\n\n <ul className=\"space-y-3 mb-8 mt-6 flex-1\">\n {features.map((feature) => (\n <li\n key={feature}\n className=\"text-sm flex items-start gap-2\"\n >\n <span className=\"text-primary mt-0.5 flex-shrink-0\">\n &#10003;\n </span>\n <span>{feature}</span>\n </li>\n ))}\n </ul>\n\n {btnLink.startsWith(\"/\") ? (\n <Button\n className=\"w-full h-11\"\n variant={isPopular ? \"default\" : \"outline\"}\n size=\"lg\"\n asChild\n >\n <a\n href={btnLink}\n onClick={() =>\n window.scrollTo({ top: 0, behavior: \"smooth\" })\n }\n >\n {btnText}\n </a>\n </Button>\n ) : (\n <Button\n className=\"w-full h-11\"\n variant={isPopular ? \"default\" : \"outline\"}\n size=\"lg\"\n asChild\n >\n <a\n href={btnLink}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {btnText}\n </a>\n </Button>\n )}\n </div>\n );\n })\n : /* Individual API-fetched cards */\n plans.map((plan) => (\n <div\n key={plan.id}\n className={`bg-card rounded-xl p-6 sm:p-8 transition-all duration-300 flex flex-col ${\n plan.popular\n ? \"border-2 border-primary shadow-xl ring-1 ring-primary/20\"\n : \"border hover:shadow-lg hover:border-primary/50\"\n }`}\n >\n <div className=\"text-center mb-6\">\n {plan.popular && (\n <span className=\"inline-block bg-primary text-primary-foreground px-4 py-1 rounded-full text-xs font-semibold mb-3\">\n Most Popular\n </span>\n )}\n <h3 className=\"text-xl sm:text-2xl font-bold mb-2\">\n {plan.name}\n </h3>\n <p className=\"text-muted-foreground text-sm\">\n {plan.description}\n </p>\n </div>\n\n <div className=\"text-center mb-8\">\n {plan.price === \"Custom\" ? (\n <span className=\"text-3xl sm:text-4xl font-bold\">\n Custom\n </span>\n ) : (\n <div className=\"flex items-baseline justify-center gap-1\">\n <span className=\"text-4xl sm:text-5xl font-bold\">\n {plan.price}\n </span>\n <span className=\"text-muted-foreground text-lg\">\n {plan.interval}\n </span>\n </div>\n )}\n </div>\n\n <ul className=\"space-y-3 mb-8 flex-1\">\n {plan.features.map((feature, index) => (\n <li\n key={index}\n className=\"text-sm flex items-start gap-2\"\n >\n <span className=\"text-primary mt-0.5 flex-shrink-0\">\n &#10003;\n </span>\n <span>{feature}</span>\n </li>\n ))}\n </ul>\n\n {plan.ctaLink.startsWith(\"/\") ? (\n <Button\n className=\"w-full h-11\"\n variant={plan.popular ? \"default\" : \"outline\"}\n size=\"lg\"\n asChild\n >\n <a\n href={plan.ctaLink}\n onClick={() =>\n window.scrollTo({ top: 0, behavior: \"smooth\" })\n }\n >\n {plan.ctaText}\n </a>\n </Button>\n ) : (\n <Button\n className=\"w-full h-11\"\n variant={plan.popular ? \"default\" : \"outline\"}\n size=\"lg\"\n asChild\n >\n <a\n href={plan.ctaLink}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {plan.ctaText}\n </a>\n </Button>\n )}\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n}\n\n/**\n * Pricing Page Component - Full Page with Hero\n */\nexport function PricingPage(props: PricingProps) {\n const {\n productName,\n heroHeading = \"Simple, Transparent Pricing\",\n heroSubtitle = \"Choose the plan that's right for you. No hidden fees, no surprises.\",\n seoTitle,\n seoDescription,\n seoKeywords,\n seoImage,\n seoUrl,\n } = props;\n\n return (\n <div className=\"w-full\">\n {/* SEO Meta Tags */}\n {seoTitle && (\n <PageHead\n title={seoTitle}\n description={seoDescription || heroSubtitle}\n productName={productName}\n keywords={seoKeywords}\n image={seoImage}\n url={seoUrl}\n />\n )}\n\n {/* Hero Section */}\n <section className=\"bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center max-w-3xl mx-auto\">\n <h1 className=\"text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6\">\n {heroHeading}\n </h1>\n <p className=\"text-lg sm:text-xl text-muted-foreground leading-relaxed\">\n {heroSubtitle}\n </p>\n </div>\n </div>\n </section>\n\n {/* Pricing Section */}\n <PricingSection {...props} />\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../src/client/security.ts","../../src/client/graphql-client.ts","../../src/client/provider.tsx","../../src/seo/page-head.tsx","../../src/utils/cn.ts","../../src/ui/button.tsx","../../src/components/pricing.tsx"],"names":["jsx","jsxs"],"mappings":";;;;;;;;;;;;;;AAAA,IAAM,iCAAiB,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,WAAA,EAAa,KAAK,CAAC,CAAA;AAChE,IAAM,gBAAA,uBAAuB,GAAA,CAAI;AAAA,EAC/B,eAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,iBAAA;AAAA,EACA,sBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEM,SAAS,mBAAmB,KAAA,EAAuB;AACxD,EAAA,IAAI,GAAA;AAEJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAI,IAAI,KAAK,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,MAAM,0CAA0C,CAAA;AAAA,EAC5D;AAEA,EAAA,IAAI,GAAA,CAAI,aAAa,QAAA,EAAU;AAC7B,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAEA,EAAA,IACE,GAAA,CAAI,aAAa,OAAA,IACjB,cAAA,CAAe,IAAI,GAAA,CAAI,QAAA,CAAS,WAAA,EAAa,CAAA,EAC7C;AACA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAEA,EAAA,MAAM,IAAI,MAAM,wDAAwD,CAAA;AAC1E;AAEO,SAAS,gBACd,OAAA,EACoC;AACpC,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AAErB,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,CAAE,MAAA;AAAA,MACtB,CAAC,CAAC,GAAG,CAAA,KAAM,CAAC,gBAAA,CAAiB,GAAA,CAAI,GAAA,CAAI,WAAA,EAAa;AAAA;AACpD,GACF;AACF;;;ACAO,IAAM,aAAA,GAAN,MAAM,aAAA,CAAa;AAAA,EAaxB,YAAY,MAAA,EAA4B;AAZxC,IAAA,aAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,YAAA,sBAAiB,GAAA,EAGvB,CAAA;AACF,IAAA,aAAA,CAAA,IAAA,EAAQ,UAAA,sBAAe,GAAA,EAA+C,CAAA;AAQpE,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,GAAG,MAAA;AAAA,MACH,UAAA,EAAY,kBAAA,CAAmB,MAAA,CAAO,UAAU,CAAA;AAAA,MAChD,OAAA,EAAS,eAAA,CAAgB,MAAA,CAAO,OAAO;AAAA,KACzC;AAAA,EACF;AAAA,EAEA,SAAA,GAAgC;AAC9B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,CACJ,KAAA,EACA,SAAA,EAC6B;AAC7B,IAAA,MAAM,WAAW,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,WAAW,CAAA;AAGpD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAQ,CAAA;AAC3C,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAI,KAAK,GAAA,EAAI,GAAI,MAAA,CAAO,EAAA,GAAK,cAAa,SAAA,EAAW;AACnD,QAAA,OAAO,MAAA,CAAO,IAAA;AAAA,MAChB;AACA,MAAA,IAAA,CAAK,UAAA,CAAW,OAAO,QAAQ,CAAA;AAAA,IACjC;AAGA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA;AAC3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAO,QAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,KAAK,OAAA,CAAW,KAAA,EAAO,SAAS,CAAA,CAC7C,IAAA,CAAK,CAAC,MAAA,KAAW;AAEhB,MAAA,IAAI,MAAA,CAAO,IAAA,IAAQ,CAAC,MAAA,CAAO,QAAQ,MAAA,EAAQ;AACzC,QAAA,IAAI,IAAA,CAAK,UAAA,CAAW,IAAA,IAAQ,aAAA,CAAa,iBAAA,EAAmB;AAC1D,UAAA,MAAM,cAAc,IAAA,CAAK,UAAA,CAAW,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AAClD,UAAA,IAAI,WAAA,EAAa;AACf,YAAA,IAAA,CAAK,UAAA,CAAW,OAAO,WAAW,CAAA;AAAA,UACpC;AAAA,QACF;AACA,QAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,EAAU,EAAE,IAAA,EAAM,QAAQ,EAAA,EAAI,IAAA,CAAK,GAAA,EAAI,EAAG,CAAA;AAAA,MAChE;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAA,CAAK,QAAA,CAAS,OAAO,QAAQ,CAAA;AAAA,IAC/B,CAAC,CAAA;AAEH,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,QAAA,EAAU,OAAO,CAAA;AACnC,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,QAAA,EACA,SAAA,EAC6B;AAG7B,IAAA,OAAO,IAAA,CAAK,OAAA,CAAW,QAAA,EAAU,SAAA,EAAW,KAAK,CAAA;AAAA,EACnD;AAAA;AAAA,EAGA,OAAe,kBAAkB,MAAA,EAAyB;AACxD,IAAA,OAAO,WAAW,GAAA,IAAO,MAAA,KAAW,GAAA,IAAQ,MAAA,IAAU,OAAO,MAAA,GAAS,GAAA;AAAA,EACxE;AAAA,EAEA,OAAe,MAAM,EAAA,EAA2B;AAC9C,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,OAAA,CACZ,KAAA,EACA,SAAA,EACA,SAAA,EAC0D;AAC1D,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,UAAA,CAAW,KAAA,IAAS,SAAS,CAAA;AAC5D,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA,CAAK,OAAO,UAAA,EAAY;AAAA,QACnD,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,cAAA,EAAgB,KAAK,MAAA,CAAO,SAAA;AAAA,UAC5B,GAAG,KAAK,MAAA,CAAO;AAAA,SACjB;AAAA,QACA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,WAAW,CAAA;AAAA,QACzC,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN,iCAAA;AAAA,UACA,QAAA,CAAS,MAAA;AAAA,UACT,QAAA,CAAS;AAAA,SACX;AACA,QAAA,OAAO;AAAA,UACL,GAAA,EAAK;AAAA,YACH,MAAA,EAAQ;AAAA,cACN;AAAA,gBACE,SAAS,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA,CAAA;AAAA,gBACxD,YAAY,EAAE,IAAA,EAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAA;AAAG;AAChD;AACF,WACF;AAAA,UACA,SAAA,EAAW,aAAA,CAAa,iBAAA,CAAkB,QAAA,CAAS,MAAM;AAAA,SAC3D;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,GAAA,EAAM,MAAM,QAAA,CAAS,IAAA,EAAK;AAAA,QAC1B,SAAA,EAAW;AAAA,OACb;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,UACJ,KAAA,YAAiB,KAAA,KAChB,MAAM,IAAA,KAAS,YAAA,IAAgB,WAAW,MAAA,CAAO,OAAA,CAAA;AACpD,MAAA,MAAM,OAAA,GAAU,UACZ,CAAA,wBAAA,EAA2B,SAAS,OACpC,KAAA,YAAiB,KAAA,GACf,MAAM,OAAA,GACN,eAAA;AACN,MAAA,OAAA,CAAQ,KAAA,CAAM,0BAA0B,OAAO,CAAA;AAC/C,MAAA,OAAO;AAAA,QACL,GAAA,EAAK;AAAA,UACH,MAAA,EAAQ;AAAA,YACN;AAAA,cACE,OAAA;AAAA,cACA,UAAA,EAAY,EAAE,IAAA,EAAM,OAAA,GAAU,YAAY,eAAA;AAAgB;AAC5D;AACF,SACF;AAAA;AAAA;AAAA,QAGA,SAAA,EAAW;AAAA,OACb;AAAA,IACF,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,OAAA,CACZ,KAAA,EACA,SAAA,EACA,QAAQ,IAAA,EACqB;AAC7B,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,CAAO,SAAA,IAAa,aAAA,CAAa,kBAAA;AACxD,IAAA,MAAM,aAAa,KAAA,GACd,IAAA,CAAK,MAAA,CAAO,UAAA,IAAc,cAAa,mBAAA,GACxC,CAAA;AAEJ,IAAA,IAAI,IAAA;AACJ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,UAAA,EAAY,CAAA,EAAA,EAAK;AACpC,MAAA,MAAM,EAAE,GAAA,EAAK,SAAA,EAAU,GAAI,MAAM,IAAA,CAAK,OAAA;AAAA,QACpC,KAAA;AAAA,QACA,SAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,IAAI,CAAC,SAAA,IAAa,CAAA,KAAM,UAAA,EAAY,OAAO,GAAA;AAC3C,MAAA,IAAA,GAAO,GAAA;AAEP,MAAA,MAAM,aAAA,CAAa,KAAA;AAAA,QACjB,cAAa,mBAAA,IAAuB,CAAA,GAAI,CAAA,CAAA,GAAK,IAAA,CAAK,QAAO,GAAI;AAAA,OAC/D;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;AA1LE,aAAA,CAPW,aAAA,EAOI,WAAA,EAAY,CAAA,GAAI,EAAA,GAAK,GAAA,CAAA;AAAA;AACpC,aAAA,CARW,eAQI,mBAAA,EAAoB,GAAA,CAAA;AACnC,aAAA,CATW,eASI,oBAAA,EAAqB,IAAA,CAAA;AACpC,aAAA,CAVW,eAUI,qBAAA,EAAsB,CAAA,CAAA;AACrC,aAAA,CAXW,eAWI,qBAAA,EAAsB,GAAA,CAAA;AC5CvC,IAAM,aAAA,GAAgB,cAAmC,IAAI,CAAA;AAyCtD,SAAS,SAAA,GAA0B;AACxC,EAAA,MAAM,MAAA,GAAS,WAAW,aAAa,CAAA;AACvC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EAClE;AACA,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,eAAA,GAAsC;AACpD,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,OAAO,OAAO,SAAA,EAAU;AAC1B;ACLO,SAAS,QAAA,CAAS;AAAA,EACvB,KAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA,GAAS,8EAAA;AAAA,EACT,MAAA,GAAS,OAAA;AAAA,EACT,aAAA;AAAA,EACA,UAAA,GAAa,SAAA;AAAA,EACb,cAAA;AAAA,EACA;AACF,CAAA,EAAkB;AAChB,EAAA,MAAM,SAAA,GACJ,WAAA,IAAe,CAAC,KAAA,CAAM,QAAA,CAAS,WAAW,CAAA,GACtC,CAAA,EAAG,KAAK,CAAA,GAAA,EAAM,WAAW,CAAA,CAAA,GACzB,KAAA;AAEN,EAAA,MAAM,eACJ,KAAA,IAAS,CAAC,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA,IAAK,GAAA,GAClC,CAAA,EAAG,GAAA,CAAI,QAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,EAAG,KAAK,CAAA,CAAA,GACjC,KAAA;AAGN,EAAA,MAAM,mBAAA,GAAsD,cAAA,GACxD,KAAA,CAAM,OAAA,CAAQ,cAAc,IAC1B,cAAA,GACA,CAAC,cAAc,CAAA,GACjB,EAAC;AAEL,EAAA,4BACG,MAAA,EAAA,EAEC,QAAA,EAAA;AAAA,oBAAAA,GAAAA,CAAC,WAAO,QAAA,EAAA,SAAA,EAAU,CAAA;AAAA,oBAClBA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,OAAA,EAAQ,SAAS,SAAA,EAAW,CAAA;AAAA,IACtC,+BAAeA,GAAAA,CAAC,UAAK,IAAA,EAAK,aAAA,EAAc,SAAS,WAAA,EAAa,CAAA;AAAA,IAC9D,4BAAYA,GAAAA,CAAC,UAAK,IAAA,EAAK,UAAA,EAAW,SAAS,QAAA,EAAU,CAAA;AAAA,oBACtDA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,QAAA,EAAS,SAAQ,wCAAA,EAAyC,CAAA;AAAA,oBACrEA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,QAAA,EAAS,SAAS,MAAA,EAAQ,CAAA;AAAA,IAGpC,uBAAOA,GAAAA,CAAC,UAAK,GAAA,EAAI,WAAA,EAAY,MAAM,GAAA,EAAK,CAAA;AAAA,IAGxC,2BAAWA,GAAAA,CAAC,UAAK,GAAA,EAAI,MAAA,EAAO,MAAM,OAAA,EAAS,CAAA;AAAA,oBAG5CA,GAAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAS,SAAA,EAAU,SAAQ,SAAA,EAAU,CAAA;AAAA,oBAC3CA,GAAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAS,UAAA,EAAW,SAAS,SAAA,EAAW,CAAA;AAAA,IAC7C,+BAAeA,GAAAA,CAAC,UAAK,QAAA,EAAS,gBAAA,EAAiB,SAAS,WAAA,EAAa,CAAA;AAAA,IACrE,gCAAgBA,GAAAA,CAAC,UAAK,QAAA,EAAS,UAAA,EAAW,SAAS,YAAA,EAAc,CAAA;AAAA,IACjE,uBAAOA,GAAAA,CAAC,UAAK,QAAA,EAAS,QAAA,EAAS,SAAS,GAAA,EAAK,CAAA;AAAA,oBAC9CA,GAAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAS,WAAA,EAAY,SAAS,MAAA,EAAQ,CAAA;AAAA,IAC3C,+BAAeA,GAAAA,CAAC,UAAK,QAAA,EAAS,cAAA,EAAe,SAAS,WAAA,EAAa,CAAA;AAAA,oBAGpEA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,cAAA,EAAe,SAAQ,qBAAA,EAAsB,CAAA;AAAA,oBACxDA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,eAAA,EAAgB,SAAS,SAAA,EAAW,CAAA;AAAA,IAC9C,+BAAeA,GAAAA,CAAC,UAAK,IAAA,EAAK,qBAAA,EAAsB,SAAS,WAAA,EAAa,CAAA;AAAA,IACtE,gCAAgBA,GAAAA,CAAC,UAAK,IAAA,EAAK,eAAA,EAAgB,SAAS,YAAA,EAAc,CAAA;AAAA,IAClE,iCAAiBA,GAAAA,CAAC,UAAK,IAAA,EAAK,iBAAA,EAAkB,SAAS,aAAA,EAAe,CAAA;AAAA,oBAGvEA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,aAAA,EAAc,SAAS,UAAA,EAAY,CAAA;AAAA,IAG7C,oBAAoB,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,qBAC9BA,GAAAA,CAAC,QAAA,EAAA,EAA2B,IAAA,EAAK,qBAAA,EAC9B,eAAK,SAAA,CAAU,IAAI,KADT,CAAA,GAAA,EAAM,KAAK,EAExB,CACD,CAAA;AAAA,IAGA,cAAA,EAAgB,GAAA,CAAI,CAAC,IAAA,EAAM,0BAC1BA,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QAEE,GAAI,KAAK,IAAA,GAAO,EAAE,MAAM,IAAA,CAAK,IAAA,KAAS,EAAC;AAAA,QACvC,GAAI,KAAK,QAAA,GAAW,EAAE,UAAU,IAAA,CAAK,QAAA,KAAa,EAAC;AAAA,QACpD,SAAS,IAAA,CAAK;AAAA,OAAA;AAAA,MAHT,QAAQ,KAAK,CAAA;AAAA,KAKrB;AAAA,GAAA,EACH,CAAA;AAEJ;ACjIO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACdA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,uSAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,+DAAA;AAAA,QACF,WAAA,EACE,8EAAA;AAAA,QACF,OAAA,EACE,0FAAA;AAAA,QACF,SAAA,EACE,wEAAA;AAAA,QACF,KAAA,EAAO,8CAAA;AAAA,QACP,IAAA,EAAM;AAAA,OACR;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,eAAA;AAAA,QACT,EAAA,EAAI,6BAAA;AAAA,QACJ,EAAA,EAAI,sBAAA;AAAA,QACJ,IAAA,EAAM;AAAA;AACR,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ,CAAA;AASA,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,OAAA,EAAS,IAAA,EAAM,UAAU,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAChE,IAAA,MAAM,IAAA,GAAO,UAAU,IAAA,GAAO,QAAA;AAC9B,IAAA,uBACEA,GAAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,QAC1D,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF,CAAA;AACA,MAAA,CAAO,WAAA,GAAc,QAAA;AClBrB,IAAM,eAAA,GAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAgOxB,SAAS,WAAA,CACP,KAAA,EACA,YAAA,GAAuB,KAAA,EACvB,UAAA,EACQ;AACR,EAAA,MAAM,iBAAA,GAAoD;AAAA,IACxD,KAAK,EAAE,IAAA,EAAM,OAAO,MAAA,EAAQ,GAAA,EAAK,UAAU,QAAA,EAAS;AAAA,IACpD,KAAK,EAAE,IAAA,EAAM,OAAO,MAAA,EAAQ,QAAA,EAAU,UAAU,QAAA,EAAS;AAAA,IACzD,KAAK,EAAE,IAAA,EAAM,OAAO,MAAA,EAAQ,MAAA,EAAU,UAAU,QAAA,EAAS;AAAA,IACzD,KAAK,EAAE,IAAA,EAAM,OAAO,MAAA,EAAQ,QAAA,EAAU,UAAU,QAAA;AAAS,GAC3D;AAEA,EAAA,MAAM,cAAc,UAAA,IAAc,iBAAA;AAClC,EAAA,MAAM,QAAA,GAA2B,WAAA,CAAY,YAAY,CAAA,IAAK;AAAA,IAE5D,MAAA,EAAQ,YAAA;AAAA,IACR,QAAA,EAAU;AAAA,GACZ;AAEA,EAAA,MAAM,eAAA,GAAkB,QAAQ,CAAA,KAAM,CAAA,GAAI,MAAM,QAAA,EAAS,GAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAE5E,EAAA,OAAO,QAAA,CAAS,QAAA,KAAa,QAAA,GACzB,CAAA,EAAG,QAAA,CAAS,MAAM,CAAA,EAAG,eAAe,CAAA,CAAA,GACpC,CAAA,EAAG,eAAe,CAAA,EAAG,SAAS,MAAM,CAAA,CAAA;AAC1C;AAKA,SAAS,cAAA,CACP,UACA,gBAAA,EACQ;AACR,EAAA,MAAM,gBAAA,GAA2C;AAAA,IAC/C,OAAA,EAAS,QAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAEA,EAAA,MAAM,YAAY,gBAAA,IAAoB,gBAAA;AACtC,EAAA,OAAO,SAAA,CAAU,QAAQ,CAAA,IAAK,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA;AAC5C;AAMA,SAAS,iBAAiB,QAAA,EAA2B;AACnD,EAAA,MAAM,IAAA,GAAO,SAAS,WAAA,EAAY;AAClC,EAAA,OACE,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,IACpB,IAAA,CAAK,SAAS,UAAU,CAAA,IACxB,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA;AAE9B;AAKA,SAAS,eACP,QAAA,EACgD;AAChD,EAAA,MAAM,IAAA,GAAO,SAAS,WAAA,EAAY;AAElC,EAAA,IACE,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,IACpB,KAAK,QAAA,CAAS,OAAO,CAAA,IACrB,IAAA,CAAK,SAAS,SAAS,CAAA,IACvB,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EACrB;AACA,IAAA,OAAO,OAAA;AAAA,EACT,WACE,IAAA,CAAK,QAAA,CAAS,KAAK,CAAA,IACnB,KAAK,QAAA,CAAS,cAAc,CAAA,IAC5B,IAAA,CAAK,SAAS,SAAS,CAAA,IACvB,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EACpB;AACA,IAAA,OAAO,cAAA;AAAA,EACT,CAAA,MAAA,IAAW,KAAK,QAAA,CAAS,YAAY,KAAK,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,EAAG;AACnE,IAAA,OAAO,YAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA;AACT;AAKA,SAAS,0BAAA,CACP,MACA,gBAAA,EAKU;AACV,EAAA,OAAO,CAAC,GAAI,gBAAA,GAAmB,IAAI,CAAA,IAAK,EAAG,CAAA;AAC7C;AAKA,SAAS,kBAAA,CACP,UACA,YAAA,EACc;AACd,EAAA,MAAM,cAAA,GAAiB,SAAS,WAAA,EAAY;AAG5C,EAAA,IAAI,YAAA,GAAe,cAAc,CAAA,EAAG;AAClC,IAAA,MAAM,IAAA,GAAO,aAAa,cAAc,CAAA;AACxC,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,KAAK,IAAA,IAAQ,OAAA;AAAA,MACnB,WAAA,EAAa,KAAK,WAAA,IAAe,QAAA;AAAA,MACjC,kBAAA,EAAoB,KAAK,kBAAA,IAAsB,kBAAA;AAAA,MAC/C,OAAA,EAAS,KAAK,OAAA,IAAW,KAAA;AAAA,MACzB,OAAA,EAAS,KAAK,OAAA,IAAW,aAAA;AAAA,MACzB,OAAA,EAAS,KAAK,OAAA,IAAW,QAAA;AAAA,MACzB,UAAU,IAAA,CAAK;AAAA,KACjB;AAAA,EACF;AAGA,EAAA,MAAM,IAAA,GAAO,eAAe,QAAQ,CAAA;AACpC,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,WAAA,EAAa,QAAA;AAAA,MACb,kBAAA,EAAoB,kBAAA;AAAA,MACpB,SAAS,IAAA,KAAS,cAAA;AAAA,MAClB,OAAA,EAAS,IAAA,KAAS,YAAA,GAAe,eAAA,GAAkB,aAAA;AAAA,MACnD,OAAA,EAAS,IAAA,KAAS,YAAA,GAAe,SAAA,GAAY;AAAA,KAC/C;AAAA,EACF;AAGA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,OAAA;AAAA,IACN,WAAA,EAAa,QAAA;AAAA,IACb,kBAAA,EAAoB,kBAAA;AAAA,IACpB,OAAA,EAAS,KAAA;AAAA,IACT,OAAA,EAAS,aAAA;AAAA,IACT,OAAA,EAAS;AAAA,GACX;AACF;AAUA,SAAS,kBAAkB,IAAA,EAAsB;AAC/C,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAE5B,EAAA,MAAM,QAAA,GACJ,KAAA,CAAM,MAAA,IAAU,CAAA,GAAI,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,GAAK,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAEvE,EAAA,OAAO,QAAA,CACJ,OAAA,CAAQ,OAAA,EAAS,GAAG,CAAA,CACpB,OAAA,CAAQ,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAA;AAC5C;AAEA,SAAS,wBAAwB,KAAA,EAItB;AACT,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAO,GAAI,KAAA;AAEzB,EAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACzC,IAAA,OAAO,kBAAkB,IAAI,CAAA;AAAA,EAC/B;AAEA,EAAA,MAAM,SAAA,GAAY,MAAA;AAClB,EAAA,MAAM,QAAQ,SAAA,CAAU,KAAA;AACxB,EAAA,MAAM,OAAO,SAAA,CAAU,IAAA;AACvB,EAAA,MAAM,OAAO,SAAA,CAAU,IAAA;AACvB,EAAA,MAAM,cAAc,SAAA,CAAU,WAAA;AAG9B,EAAA,IAAI,OAAO,WAAA,KAAgB,QAAA,IAAY,WAAA,EAAa;AAClD,IAAA,IAAI,IAAA,KAAS,QAAA,IAAY,OAAO,KAAA,KAAU,QAAA,EAAU;AAClD,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,cAAA,EAAgB,IAAI,WAAW,CAAA,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,WAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,EAAM;AACpC,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,OAAO,CAAA,EAAG,KAAA,CAAM,cAAA,EAAgB,IAAI,IAAI,CAAA,CAAA;AAAA,IAC1C;AACA,IAAA,OAAO,GAAG,IAAI,CAAA,CAAA;AAAA,EAChB;AAGA,EAAA,MAAM,KAAA,GAAQ,kBAAkB,IAAI,CAAA;AAEpC,EAAA,IAAI,SAAS,SAAA,EAAW;AACtB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,CAAA,EAAG,KAAA,CAAM,cAAA,EAAgB,IAAI,KAAK,CAAA,CAAA;AAAA,EAC3C;AAEA,EAAA,OAAO,KAAA;AACT;AAKA,SAAS,sBAAA,CACP,QAAA,EACA,QAAA,EACA,gBAAA,EAKU;AAGV,EAAA,MAAM,IAAA,GAAO,eAAe,QAAQ,CAAA;AACpC,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,MAAM,YAAA,GAAe,0BAAA,CAA2B,IAAA,EAAM,gBAAgB,CAAA;AACtE,IAAA,IAAI,YAAA,CAAa,SAAS,CAAA,EAAG;AAC3B,MAAA,OAAO,YAAA;AAAA,IACT;AAAA,EACF;AAGA,EAAA,MAAM,aAAA,GAAgB,QAAA,CACnB,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,KAAK,CAAA,CACrB,GAAA,CAAI,CAAC,CAAA,KAAM,uBAAA,CAAwB,CAAA,CAAE,KAAM,CAAC,CAAA;AAE/C,EAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,IAAA,OAAO,aAAA;AAAA,EACT;AAEA,EAAA,OAAO,EAAC;AACV;AAwBA,SAAS,sBAAA,CACP,MACA,KAAA,EACiB;AACjB,EAAA,MAAM,QAAA,GAAW,kBAAA,CAAmB,IAAA,CAAK,IAAA,EAAM,MAAM,YAAY,CAAA;AAEjE,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IACrB,IAAA,CAAK,KAAA;AAAA,IACL,IAAA,CAAK,QAAA;AAAA,IACL,KAAA,CAAM;AAAA,GACR;AACA,EAAA,MAAM,QAAA,GAAW,cAAA,CAAe,IAAA,CAAK,QAAA,EAAU,MAAM,gBAAgB,CAAA;AAIrE,EAAA,MAAM,QAAA,GACJ,SAAS,QAAA,IAAY,QAAA,CAAS,SAAS,MAAA,GAAS,CAAA,GAC5C,SAAS,QAAA,GACT,sBAAA;AAAA,IACE,IAAA,CAAK,QAAA;AAAA,IACL,IAAA,CAAK,IAAA;AAAA,IACL,KAAA,CAAM;AAAA,GACR;AAEN,EAAA,MAAM,UAAA,GAAa,MAAM,UAAA,IAAc,UAAA;AACvC,EAAA,MAAM,OAAA,GACJ,QAAA,CAAS,OAAA,KAAY,SAAA,GAAY,aAAa,KAAA,CAAM,WAAA;AAEtD,EAAA,OAAO;AAAA,IACL,IAAI,IAAA,CAAK,EAAA;AAAA,IACT,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,aAAa,QAAA,CAAS,kBAAA;AAAA,IACtB,KAAA,EAAO,cAAA;AAAA,IACP,UAAU,IAAA,CAAK,KAAA;AAAA,IACf,QAAA;AAAA,IACA,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,QAAA;AAAA,IACA,SAAS,QAAA,CAAS,OAAA;AAAA,IAClB,SAAS,QAAA,CAAS,OAAA;AAAA,IAClB,OAAA;AAAA,IACA,MAAM,QAAA,CAAS;AAAA,GACjB;AACF;AASO,SAAS,eAAe,KAAA,EAAqB;AAClD,EAAA,MAAM;AAAA,IACJ,cAAA,GAAiB,eAAA;AAAA,IACjB,eAAA,GAAkB,wCAAA;AAAA,IAClB,EAAA;AAAA,IACA,SAAA,GAAY;AAAA,GACd,GAAI,KAAA;AAEJ,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,SAAS,eAAA,EAAgB;AAE/B,EAAA,MAAM,iBAAA,GAAoB,KAAA,CAAM,SAAA,IAAa,MAAA,CAAO,SAAA;AAEpD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAAA,CAA4B,EAAE,CAAA;AAC9D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,QAAA;AAAA,IACtC;AAAA,GACF;AACA,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAAA;AAAA,IAC9B;AAAA,GACF;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAA,eAAe,SAAA,GAAY;AACzB,MAAA,IAAI;AACF,QAAA,UAAA,CAAW,IAAI,CAAA;AAEf,QAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,KAAA,CAAwB,eAAA,EAAiB;AAAA,UACrE,SAAA,EAAW;AAAA,SACZ,CAAA;AAED,QAAA,IAAI,SAAA,EAAW;AAEf,QAAA,IAAI,QAAA,CAAS,MAAA,IAAU,QAAA,CAAS,MAAA,CAAO,SAAS,CAAA,EAAG;AACjD,UAAA,MAAM,IAAI,KAAA,CAAM,QAAA,CAAS,MAAA,CAAO,CAAC,EAAG,OAAO,CAAA;AAAA,QAC7C;AAEA,QAAA,IAAI,CAAC,QAAA,CAAS,IAAA,EAAM,WAAA,EAAa;AAC/B,UAAA,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAAA,QAC1C;AAGA,QAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,WAAA,CACzB,MAAA,CAAO,CAAC,IAAA,KAAS,IAAA,CAAK,QAAQ,CAAA,CAC9B,GAAA,CAAI,CAAC,SAAS,sBAAA,CAAuB,IAAA,EAAM,KAAK,CAAC,CAAA,CACjD,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAQ,CAAA;AAEzC,QAAA,WAAA,CAAY,KAAK,CAAA;AACjB,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MACf,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,SAAA,EAAW;AACf,QAAA,OAAA,CAAQ,KAAA,CAAM,yBAAyB,GAAG,CAAA;AAC1C,QAAA,QAAA,CAAS,6DAA6D,CAAA;AAAA,MACxE,CAAA,SAAE;AACA,QAAA,IAAI,CAAC,SAAA,EAAW;AACd,UAAA,UAAA,CAAW,KAAK,CAAA;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,IAAA,SAAA,EAAU;AAEV,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EAEF,CAAA,EAAG,CAAC,MAAA,EAAQ,iBAAiB,CAAC,CAAA;AAG9B,EAAA,MAAM,kBAAA,GAAqB,SAAS,MAAA,CAAO,CAAC,MAAM,CAAC,gBAAA,CAAiB,CAAA,CAAE,IAAI,CAAC,CAAA;AAC3E,EAAA,MAAM,kBAAA,GAAqB,SAAS,MAAA,CAAO,CAAC,MAAM,gBAAA,CAAiB,CAAA,CAAE,IAAI,CAAC,CAAA;AAG1E,EAAA,MAAM,kBAAkB,kBAAA,CAAmB,MAAA;AAAA,IAAO,CAAC,SACjD,YAAA,KAAiB,SAAA,GACb,KAAK,QAAA,KAAa,SAAA,GAClB,KAAK,QAAA,KAAa;AAAA,GACxB;AAGA,EAAA,MAAM,eAAA,GAAqC,kBAAA,CAAmB,GAAA,CAAI,CAAC,CAAA,KAAM;AAEvE,IAAA,IAAI,CAAA,CAAE,aAAa,CAAA,IAAK,CAAA,CAAE,KAAK,WAAA,EAAY,CAAE,QAAA,CAAS,YAAY,CAAA,EAAG;AACnE,MAAA,OAAO;AAAA,QACL,GAAG,CAAA;AAAA,QACH,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,EAAA;AAAA,QACV,OAAA,EAAS,eAAA;AAAA,QACT,OAAA,EAAS,MAAM,UAAA,IAAc;AAAA,OAC/B;AAAA,IACF;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AAGD,EAAA,MAAM,qBAAA,GAAwB,gBAAgB,MAAA,GAAS,CAAA;AACvD,EAAA,MAAM,qBAAA,GAAiD;AAAA,IACrD,IAAA,EAAM,YAAA;AAAA,IACN,QAAA,EAAU,kCAAA;AAAA,IACV,WAAA,EAAa,kCAAA;AAAA,IACb,KAAA,EAAO,QAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,QAAA,EAAU,EAAA;AAAA,IACV,MAAA,EAAQ,eAAA;AAAA,IACR,UAAA,EAAY,MAAM,UAAA,IAAc,UAAA;AAAA,IAChC,OAAA,EAAS,eAAA;AAAA,IACT,OAAA,EAAS,MAAM,UAAA,IAAc,UAAA;AAAA,IAC7B,OAAA,EAAS,KAAA;AAAA,IACT,QAAA,EAAU,KAAA,CAAM,gBAAA,EAAkB,UAAA,IAAc;AAAA,MAC9C,sBAAA;AAAA,MACA,YAAA;AAAA,MACA,YAAA;AAAA,MACA,mBAAA;AAAA,MACA;AAAA;AACF,GACF;AACA,EAAA,MAAM,uBAAA,GAA0B,wBAC3B,eAAA,GACD,KAAA,CAAM,kBACH,KAAA,CAAM,eAAA,GACP,CAAC,qBAAqB,CAAA;AAG5B,EAAA,MAAM,QACJ,KAAA,CAAM,gBAAA,IAAoB,QAAA,KAAa,YAAA,GACnC,EAAC,GACD,eAAA;AAEN,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,uBACEA,GAAAA,CAAC,SAAA,EAAA,EAAQ,EAAA,EAAQ,SAAA,EAAW,CAAA,wBAAA,EAA2B,SAAS,CAAA,CAAA,EAC9D,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA;AAAA,QAAA,cAAA,mBACCD,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,2DACX,QAAA,EAAA,cAAA,EACH,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,WAAU,QAAA,EAAA,SAAA,EAAO;AAAA,SAAA;AAAA,wBAEjCA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,yDAAwD,QAAA,EAAA,gCAAA,EAErE;AAAA,OAAA,EACF,CAAA;AAAA,sBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACZ,QAAA,EAAA,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,sBACdC,IAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAU,6CAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAAD,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iCAAA,EAAkC,CAAA;AAAA,4BACjDA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iCAAA,EAAkC,CAAA;AAAA,4BACjDA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kCAAA,EAAmC,CAAA;AAAA,4BAClDA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBACZ,QAAA,EAAA,CAAC,CAAA,EAAG,GAAG,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,sBACjBA,GAAAA,CAAC,SAAY,SAAA,EAAU,sBAAA,EAAA,EAAb,CAAoC,CAC/C,CAAA,EACH,CAAA;AAAA,4BACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EAAwB;AAAA;AAAA,SAAA;AAAA,QAXlC;AAAA,OAaR,CAAA,EACH;AAAA,KAAA,EACF,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,KAAA,IAAS,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC/B,IAAA,uBACEA,GAAAA,CAAC,SAAA,EAAA,EAAQ,EAAA,EAAQ,SAAA,EAAW,2BAA2B,SAAS,CAAA,CAAA,EAC9D,QAAA,kBAAAA,GAAAA,CAAC,SAAI,SAAA,EAAU,gCAAA,EACb,0BAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,aAAA,EACZ,QAAA,EAAA;AAAA,MAAA,cAAA,mBACCD,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,iDAAA,EACX,QAAA,EAAA,cAAA,EACH,CAAA,mBAEAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,sBAEjCA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,8BAA8B,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,sBACjDA,IAAC,MAAA,EAAA,EAAO,OAAA,EAAS,MAAM,MAAA,CAAO,QAAA,CAAS,MAAA,EAAO,EAAG,QAAA,EAAA,OAAA,EAAK;AAAA,KAAA,EACxD,GACF,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACEA,GAAAA,CAAC,SAAA,EAAA,EAAQ,EAAA,EAAQ,SAAA,EAAW,CAAA,wBAAA,EAA2B,SAAS,CAAA,CAAA,EAC9D,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA;AAAA,MAAA,cAAA,mBACCD,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,yDAAA,EACX,QAAA,EAAA,cAAA,EACH,CAAA,mBAEAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,sBAEjCA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,8DACV,QAAA,EAAA,eAAA,EACH,CAAA;AAAA,MAGC,KAAA,CAAM,gBAAA,oBACLA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAA,EACb,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oDAAA,EACb,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,WAAA,CAAY,YAAY,CAAA;AAAA,YACvC,SAAA,EAAW,CAAA,oEAAA,EACT,QAAA,KAAa,YAAA,GACT,4CACA,6CACN,CAAA,CAAA;AAAA,YACD,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,WAAA,CAAY,YAAY,CAAA;AAAA,YACvC,SAAA,EAAW,CAAA,oEAAA,EACT,QAAA,KAAa,YAAA,GACT,4CACA,6CACN,CAAA,CAAA;AAAA,YACD,QAAA,EAAA;AAAA;AAAA;AAED,OAAA,EACF,CAAA,EACF,CAAA;AAAA,MAAA,CAIA,QAAA,KAAa,YAAA,IAAgB,CAAC,KAAA,CAAM,qCACpCA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uDAAA,EACb,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,eAAA,CAAgB,SAAS,CAAA;AAAA,YACxC,SAAA,EAAW,CAAA,gEAAA,EACT,YAAA,KAAiB,SAAA,GACb,4CACA,6CACN,CAAA,CAAA;AAAA,YACD,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,wBACAA,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,eAAA,CAAgB,QAAQ,CAAA;AAAA,YACvC,SAAA,EAAW,CAAA,gEAAA,EACT,YAAA,KAAiB,QAAA,GACb,4CACA,6CACN,CAAA,CAAA;AAAA,YACD,QAAA,EAAA;AAAA;AAAA;AAED,OAAA,EACF,CAAA,EACF;AAAA,KAAA,EAEJ,CAAA;AAAA,IAGC,KAAA,CAAM,oBAAoB,QAAA,KAAa,YAAA,oBACtCC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,oCAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,IAAC,IAAA,EAAA,EAAG,SAAA,EAAU,+CAAA,EACX,QAAA,EAAA,KAAA,CAAM,qBAAqB,sBAAA,EAC9B,CAAA;AAAA,sBACAA,GAAAA,CAAC,GAAA,EAAA,EAAE,WAAU,4BAAA,EACV,QAAA,EAAA,KAAA,CAAM,sBACL,8GAAA,EACJ;AAAA,KAAA,EACF,CAAA;AAAA,oBAGFA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,oEAAA,EACZ,QAAA,EAAA,KAAA,CAAM,oBAAoB,QAAA,KAAa,YAAA;AAAA;AAAA,MAEpC,uBAAA,CAAwB,GAAA,CAAI,CAAC,EAAA,KAAO;AAElC,QAAA,MAAM,QAAA,GAAY,EAAA,CAAG,QAAA,IACnB,EAAA,CAAG,WAAA,IACH,EAAA;AACF,QAAA,MAAM,OAAA,GAAW,EAAA,CAAG,MAAA,IAClB,EAAA,CAAG,OAAA,IACH,aAAA;AACF,QAAA,MAAM,OAAA,GAAW,EAAA,CAAG,UAAA,IAClB,EAAA,CAAG,WACH,KAAA,CAAM,WAAA;AACR,QAAA,MAAM,MAAA,GAAU,EAAA,CAAG,MAAA,IAAU,EAAA,CAAG,QAAA,IAAY,EAAA;AAC5C,QAAA,MAAM,IAAA,GAAQ,GAAG,IAAA,IAAQ,EAAA;AACzB,QAAA,MAAM,KAAA,GAAS,GAAG,KAAA,IAAS,EAAA;AAC3B,QAAA,MAAM,YAAY,EAAA,CAAG,OAAA;AACrB,QAAA,MAAM,QAAA,GAAY,EAAA,CAAG,QAAA,IAAY,EAAC;AAClC,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,EAAA,CAAG,KAAK,CAAA;AAE7B,QAAA,uBACEC,IAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEC,SAAA,EAAW,CAAA,wEAAA,EACT,SAAA,GACI,0DAAA,GACA,gDACN,CAAA,CAAA;AAAA,YAEA,QAAA,EAAA;AAAA,8BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACZ,QAAA,EAAA;AAAA,gBAAA,SAAA,IAAa,yBACZD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qGACb,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,gCAEFA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,oCAAA,EACX,aAAG,IAAA,EACN,CAAA;AAAA,gCACAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,iCACV,QAAA,EAAA,QAAA,EACH;AAAA,eAAA,EACF,CAAA;AAAA,8BAEAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACZ,QAAA,EAAA;AAAA,gBAAA,KAAA,KAAU,QAAA,mBACTD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EAAiC,QAAA,EAAA,QAAA,EAEjD,CAAA,mBAEAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0CAAA,EACb,QAAA,EAAA;AAAA,kCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAA,EACb,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,kCACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCACb,QAAA,EAAA,MAAA,EACH;AAAA,iBAAA,EACF,CAAA;AAAA,gBAED,wBACCA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,yCACV,QAAA,EAAA,IAAA,EACH;AAAA,eAAA,EAEJ,CAAA;AAAA,8BAEAA,IAAC,IAAA,EAAA,EAAG,SAAA,EAAU,8BACX,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,qBACbC,IAAAA;AAAA,gBAAC,IAAA;AAAA,gBAAA;AAAA,kBAEC,SAAA,EAAU,gCAAA;AAAA,kBAEV,QAAA,EAAA;AAAA,oCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAoC,QAAA,EAAA,QAAA,EAEpD,CAAA;AAAA,oCACAA,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,OAAA,EAAQ;AAAA;AAAA,iBAAA;AAAA,gBANV;AAAA,eAQR,CAAA,EACH,CAAA;AAAA,cAEC,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,mBACrBA,GAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,aAAA;AAAA,kBACV,OAAA,EAAS,YAAY,SAAA,GAAY,SAAA;AAAA,kBACjC,IAAA,EAAK,IAAA;AAAA,kBACL,OAAA,EAAO,IAAA;AAAA,kBAEP,QAAA,kBAAAA,GAAAA;AAAA,oBAAC,GAAA;AAAA,oBAAA;AAAA,sBACC,IAAA,EAAM,OAAA;AAAA,sBACN,OAAA,EAAS,MACP,MAAA,CAAO,QAAA,CAAS,EAAE,GAAA,EAAK,CAAA,EAAG,QAAA,EAAU,QAAA,EAAU,CAAA;AAAA,sBAG/C,QAAA,EAAA;AAAA;AAAA;AACH;AAAA,kCAGFA,GAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,aAAA;AAAA,kBACV,OAAA,EAAS,YAAY,SAAA,GAAY,SAAA;AAAA,kBACjC,IAAA,EAAK,IAAA;AAAA,kBACL,OAAA,EAAO,IAAA;AAAA,kBAEP,QAAA,kBAAAA,GAAAA;AAAA,oBAAC,GAAA;AAAA,oBAAA;AAAA,sBACC,IAAA,EAAM,OAAA;AAAA,sBACN,MAAA,EAAO,QAAA;AAAA,sBACP,GAAA,EAAI,qBAAA;AAAA,sBAEH,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AACF;AAAA,WAAA;AAAA,UAvFG,EAAA,CAAG;AAAA,SAyFV;AAAA,MAEJ,CAAC;AAAA;AAAA;AAAA,MAED,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,qBACTC,IAAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAW,CAAA,wEAAA,EACT,IAAA,CAAK,OAAA,GACD,6DACA,gDACN,CAAA,CAAA;AAAA,UAEA,QAAA,EAAA;AAAA,4BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACZ,QAAA,EAAA;AAAA,cAAA,IAAA,CAAK,2BACJD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qGAAoG,QAAA,EAAA,cAAA,EAEpH,CAAA;AAAA,8BAEFA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,oCAAA,EACX,eAAK,IAAA,EACR,CAAA;AAAA,8BACAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,+BAAA,EACV,eAAK,WAAA,EACR;AAAA,aAAA,EACF,CAAA;AAAA,4BAEAA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,kBAAA,EACZ,QAAA,EAAA,IAAA,CAAK,UAAU,QAAA,mBACdA,IAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCAAiC,QAAA,EAAA,QAAA,EAEjD,CAAA,mBAEAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0CAAA,EACb,QAAA,EAAA;AAAA,8BAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EACb,eAAK,KAAA,EACR,CAAA;AAAA,8BACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+BAAA,EACb,eAAK,QAAA,EACR;AAAA,aAAA,EACF,CAAA,EAEJ,CAAA;AAAA,4BAEAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,uBAAA,EACX,QAAA,EAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,EAAS,KAAA,qBAC3BC,IAAAA;AAAA,cAAC,IAAA;AAAA,cAAA;AAAA,gBAEC,SAAA,EAAU,gCAAA;AAAA,gBAEV,QAAA,EAAA;AAAA,kCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAoC,QAAA,EAAA,QAAA,EAEpD,CAAA;AAAA,kCACAA,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,OAAA,EAAQ;AAAA;AAAA,eAAA;AAAA,cANV;AAAA,aAQR,CAAA,EACH,CAAA;AAAA,YAEC,IAAA,CAAK,OAAA,CAAQ,UAAA,CAAW,GAAG,oBAC1BA,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,aAAA;AAAA,gBACV,OAAA,EAAS,IAAA,CAAK,OAAA,GAAU,SAAA,GAAY,SAAA;AAAA,gBACpC,IAAA,EAAK,IAAA;AAAA,gBACL,OAAA,EAAO,IAAA;AAAA,gBAEP,QAAA,kBAAAA,GAAAA;AAAA,kBAAC,GAAA;AAAA,kBAAA;AAAA,oBACC,MAAM,IAAA,CAAK,OAAA;AAAA,oBACX,OAAA,EAAS,MACP,MAAA,CAAO,QAAA,CAAS,EAAE,GAAA,EAAK,CAAA,EAAG,QAAA,EAAU,QAAA,EAAU,CAAA;AAAA,oBAG/C,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR;AAAA,gCAGFA,GAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,aAAA;AAAA,gBACV,OAAA,EAAS,IAAA,CAAK,OAAA,GAAU,SAAA,GAAY,SAAA;AAAA,gBACpC,IAAA,EAAK,IAAA;AAAA,gBACL,OAAA,EAAO,IAAA;AAAA,gBAEP,QAAA,kBAAAA,GAAAA;AAAA,kBAAC,GAAA;AAAA,kBAAA;AAAA,oBACC,MAAM,IAAA,CAAK,OAAA;AAAA,oBACX,MAAA,EAAO,QAAA;AAAA,oBACP,GAAA,EAAI,qBAAA;AAAA,oBAEH,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR;AAAA;AACF;AAAA,SAAA;AAAA,QAlFG,IAAA,CAAK;AAAA,OAqFb;AAAA,KAAA,EACP;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;AAKO,SAAS,YAAY,KAAA,EAAqB;AAC/C,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,WAAA,GAAc,6BAAA;AAAA,IACd,YAAA,GAAe,qEAAA;AAAA,IACf,QAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF,GAAI,KAAA;AAEJ,EAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,QAAA,EAEZ,QAAA,EAAA;AAAA,IAAA,QAAA,oBACCD,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,QAAA;AAAA,QACP,aAAa,cAAA,IAAkB,YAAA;AAAA,QAC/B,WAAA;AAAA,QACA,QAAA,EAAU,WAAA;AAAA,QACV,KAAA,EAAO,QAAA;AAAA,QACP,GAAA,EAAK;AAAA;AAAA,KACP;AAAA,oBAIFA,GAAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,iFACjB,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAA,EACb,QAAA,kBAAAC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,+BAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,yDAAA,EACX,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,sBACAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,4DACV,QAAA,EAAA,YAAA,EACH;AAAA,KAAA,EACF,GACF,CAAA,EACF,CAAA;AAAA,oBAGAA,GAAAA,CAAC,cAAA,EAAA,EAAgB,GAAG,KAAA,EAAO;AAAA,GAAA,EAC7B,CAAA;AAEJ","file":"pricing.mjs","sourcesContent":["const LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\"]);\nconst RESERVED_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"x-actor-id\",\n \"x-actor-type\",\n \"x-consent-granted-by\",\n \"x-consent-scope\",\n \"x-consent-granted-at\",\n \"x-consent-expires-at\",\n]);\n\nexport function validateGatewayUrl(value: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n throw new Error(\"Gateway URL must be a valid absolute URL\");\n }\n\n if (url.protocol === \"https:\") {\n return url.toString();\n }\n\n if (\n url.protocol === \"http:\" &&\n LOOPBACK_HOSTS.has(url.hostname.toLowerCase())\n ) {\n return url.toString();\n }\n\n throw new Error(\"Gateway URL must use HTTPS unless it targets localhost\");\n}\n\nexport function sanitizeHeaders(\n headers?: Record<string, string>,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n\n return Object.fromEntries(\n Object.entries(headers).filter(\n ([key]) => !RESERVED_HEADERS.has(key.toLowerCase()),\n ),\n );\n}\n","/**\n * Lightweight GraphQL client for the Burdenoff Web SDK.\n * Uses native fetch - zero external dependencies.\n * All calls are unauthenticated (public gateway operations only).\n */\n\nimport { sanitizeHeaders, validateGatewayUrl } from \"./security\";\n\nexport interface WebSDKClientConfig {\n /** Global public gateway URL (e.g. \"https://api.burdenoff.com/global/graphql\") */\n gatewayUrl: string;\n /** Platform product ID for scoping operations */\n productId: string;\n /** Product slug (used for public product queries) */\n productSlug?: string;\n /** reCAPTCHA site key (if not fetched from product config) */\n recaptchaSiteKey?: string;\n /** Rybbit analytics site ID */\n rybbitSiteId?: string;\n /** Custom headers to include in all requests */\n headers?: Record<string, string>;\n /**\n * Per-request timeout in ms. Kept below the gateway's operation timeout so a\n * stalled request surfaces as an error the UI can render, instead of leaving\n * a page stuck on loading skeletons forever. Default 12000.\n */\n timeoutMs?: number;\n /**\n * Extra attempts for transient failures (timeout / network / 5xx / 429) on\n * QUERIES ONLY. Mutations are never retried — a retried contact-form or\n * waitlist submit would double-submit. Default 1 (2 attempts total).\n */\n maxRetries?: number;\n}\n\nexport interface GraphQLResponse<T = Record<string, unknown>> {\n data?: T;\n errors?: Array<{\n message: string;\n locations?: Array<{ line: number; column: number }>;\n path?: Array<string | number>;\n extensions?: Record<string, unknown>;\n }>;\n}\n\nexport class WebSDKClient {\n private config: WebSDKClientConfig;\n private queryCache = new Map<\n string,\n { data: GraphQLResponse<unknown>; ts: number }\n >();\n private inflight = new Map<string, Promise<GraphQLResponse<unknown>>>();\n private static CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n private static MAX_CACHE_ENTRIES = 100;\n private static DEFAULT_TIMEOUT_MS = 12_000;\n private static DEFAULT_MAX_RETRIES = 1;\n private static RETRY_BASE_DELAY_MS = 400;\n\n constructor(config: WebSDKClientConfig) {\n this.config = {\n ...config,\n gatewayUrl: validateGatewayUrl(config.gatewayUrl),\n headers: sanitizeHeaders(config.headers),\n };\n }\n\n getConfig(): WebSDKClientConfig {\n return this.config;\n }\n\n /**\n * Execute a GraphQL query (with deduplication and caching)\n */\n async query<T = Record<string, unknown>>(\n query: string,\n variables?: Record<string, unknown>,\n ): Promise<GraphQLResponse<T>> {\n const cacheKey = JSON.stringify({ query, variables });\n\n // Return cached response if still valid, evict if expired\n const cached = this.queryCache.get(cacheKey);\n if (cached) {\n if (Date.now() - cached.ts < WebSDKClient.CACHE_TTL) {\n return cached.data as GraphQLResponse<T>;\n }\n this.queryCache.delete(cacheKey);\n }\n\n // Deduplicate: if same query is already in-flight, reuse the promise\n const existing = this.inflight.get(cacheKey);\n if (existing) {\n return existing as Promise<GraphQLResponse<T>>;\n }\n\n const promise = this.request<T>(query, variables)\n .then((result) => {\n // Cache successful responses only\n if (result.data && !result.errors?.length) {\n if (this.queryCache.size >= WebSDKClient.MAX_CACHE_ENTRIES) {\n const oldestEntry = this.queryCache.keys().next().value;\n if (oldestEntry) {\n this.queryCache.delete(oldestEntry);\n }\n }\n this.queryCache.set(cacheKey, { data: result, ts: Date.now() });\n }\n return result;\n })\n .finally(() => {\n this.inflight.delete(cacheKey);\n });\n\n this.inflight.set(cacheKey, promise);\n return promise;\n }\n\n /**\n * Execute a GraphQL mutation\n */\n async mutate<T = Record<string, unknown>>(\n mutation: string,\n variables?: Record<string, unknown>,\n ): Promise<GraphQLResponse<T>> {\n // retry=false: a retried mutation could double-submit (contact form,\n // waitlist signup, order). Only the timeout applies here.\n return this.request<T>(mutation, variables, false);\n }\n\n /** HTTP statuses worth another attempt — transient server/edge conditions. */\n private static isRetriableStatus(status: number): boolean {\n return status === 429 || status === 408 || (status >= 500 && status < 600);\n }\n\n private static sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Perform the HTTP call with a hard timeout. Every outcome resolves to a\n * GraphQLResponse — callers never hang, so a UI's `loading` state always\n * settles into data or a renderable error.\n */\n private async attempt<T>(\n query: string,\n variables: Record<string, unknown> | undefined,\n timeoutMs: number,\n ): Promise<{ res: GraphQLResponse<T>; retriable: boolean }> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(this.config.gatewayUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-product-id\": this.config.productId,\n ...this.config.headers,\n },\n body: JSON.stringify({ query, variables }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n console.error(\n \"[WebSDK] GraphQL request failed\",\n response.status,\n response.statusText,\n );\n return {\n res: {\n errors: [\n {\n message: `HTTP ${response.status}: ${response.statusText}`,\n extensions: { code: `HTTP_${response.status}` },\n },\n ],\n },\n retriable: WebSDKClient.isRetriableStatus(response.status),\n };\n }\n\n return {\n res: (await response.json()) as GraphQLResponse<T>,\n retriable: false,\n };\n } catch (error) {\n const aborted =\n error instanceof Error &&\n (error.name === \"AbortError\" || controller.signal.aborted);\n const message = aborted\n ? `Request timed out after ${timeoutMs}ms`\n : error instanceof Error\n ? error.message\n : \"Network error\";\n console.error(\"[WebSDK] Network error\", message);\n return {\n res: {\n errors: [\n {\n message,\n extensions: { code: aborted ? \"TIMEOUT\" : \"NETWORK_ERROR\" },\n },\n ],\n },\n // Transport-level failures are worth one more try; a genuine outage\n // just fails twice quickly and still renders an error state.\n retriable: true,\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async request<T>(\n query: string,\n variables?: Record<string, unknown>,\n retry = true,\n ): Promise<GraphQLResponse<T>> {\n const timeoutMs = this.config.timeoutMs ?? WebSDKClient.DEFAULT_TIMEOUT_MS;\n const maxRetries = retry\n ? (this.config.maxRetries ?? WebSDKClient.DEFAULT_MAX_RETRIES)\n : 0;\n\n let last: GraphQLResponse<T> | undefined;\n for (let i = 0; i <= maxRetries; i++) {\n const { res, retriable } = await this.attempt<T>(\n query,\n variables,\n timeoutMs,\n );\n if (!retriable || i === maxRetries) return res;\n last = res;\n // Small backoff with jitter so a burst of clients doesn't retry in lockstep.\n await WebSDKClient.sleep(\n WebSDKClient.RETRY_BASE_DELAY_MS * (i + 1) + Math.random() * 200,\n );\n }\n return last as GraphQLResponse<T>;\n }\n}\n","/**\n * React context provider for the Web SDK client.\n * Wraps the application with WebSDKClient configuration.\n */\n\"use client\";\n\nimport { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport { resolveGatewayUrl } from \"./gateway-resolver\";\nimport { WebSDKClient, type WebSDKClientConfig } from \"./graphql-client\";\n\nconst WebSDKContext = createContext<WebSDKClient | null>(null);\n\nexport interface WebSDKProviderProps {\n /** SDK client configuration */\n config: WebSDKClientConfig;\n /** Child components */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes the WebSDKClient available to all child components.\n *\n * @example\n * ```tsx\n * <WebSDKProvider config={{\n * gatewayUrl: \"https://api.burdenoff.com/global/graphql\",\n * productId: \"your-product-id\",\n * productSlug: \"your-product\",\n * }}>\n * <App />\n * </WebSDKProvider>\n * ```\n */\nexport function WebSDKProvider({ config, children }: WebSDKProviderProps) {\n const client = useMemo(() => {\n const resolvedConfig = {\n ...config,\n gatewayUrl: resolveGatewayUrl(config.gatewayUrl),\n };\n return new WebSDKClient(resolvedConfig);\n }, [config]);\n\n return (\n <WebSDKContext.Provider value={client}>{children}</WebSDKContext.Provider>\n );\n}\n\n/**\n * Hook to access the WebSDKClient instance.\n * Must be used within a WebSDKProvider.\n */\nexport function useWebSDK(): WebSDKClient {\n const client = useContext(WebSDKContext);\n if (!client) {\n throw new Error(\"useWebSDK must be used within a WebSDKProvider\");\n }\n return client;\n}\n\n/**\n * Hook to access the SDK configuration.\n * Useful for components that need config values like productId, recaptchaSiteKey, etc.\n */\nexport function useWebSDKConfig(): WebSDKClientConfig {\n const client = useWebSDK();\n return client.getConfig();\n}\n","/**\n * PageHead Component\n * Manages dynamic meta tags for SEO optimization on a per-page basis.\n * Supports JSON-LD structured data, Open Graph, Twitter Cards, favicons, and robots directives.\n *\n * @example\n * ```tsx\n * <PageHead\n * title=\"About Us\"\n * description=\"Learn about our mission and team\"\n * productName=\"MyProduct\"\n * keywords=\"about, team, mission\"\n * image=\"/og-about.png\"\n * url=\"https://myproduct.com/about\"\n * favicon=\"/favicon.ico\"\n * robots=\"index, follow\"\n * locale=\"en_US\"\n * twitterHandle=\"@burdenoff\"\n * themeColor=\"#1a1a2e\"\n * structuredData={{\n * \"@context\": \"https://schema.org\",\n * \"@type\": \"WebPage\",\n * name: \"About Us\",\n * }}\n * />\n * ```\n */\n\nimport { Helmet } from \"react-helmet-async\";\n\nexport interface PageHeadProps {\n /** Page title */\n title: string;\n /** Meta description */\n description?: string;\n /** Product/brand name (appended to title) */\n productName?: string;\n /** SEO keywords */\n keywords?: string;\n /** Open Graph image URL */\n image?: string;\n /** Page canonical URL */\n url?: string;\n /** Favicon URL */\n favicon?: string;\n /** Robots directive (e.g., \"index, follow\") */\n robots?: string;\n /** Open Graph locale (e.g., \"en_US\") */\n locale?: string;\n /** Twitter handle (e.g., \"@burdenoff\") */\n twitterHandle?: string;\n /** Theme color for mobile browsers */\n themeColor?: string;\n /** JSON-LD structured data objects */\n structuredData?: Record<string, unknown> | Array<Record<string, unknown>>;\n /** Additional meta tags */\n additionalMeta?: Array<{\n name?: string;\n property?: string;\n content: string;\n }>;\n}\n\nexport function PageHead({\n title,\n description,\n productName,\n keywords,\n image,\n url,\n favicon,\n robots = \"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\",\n locale = \"en_US\",\n twitterHandle,\n themeColor = \"#000000\",\n structuredData,\n additionalMeta,\n}: PageHeadProps) {\n const fullTitle =\n productName && !title.includes(productName)\n ? `${title} | ${productName}`\n : title;\n\n const fullImageUrl =\n image && !image.startsWith(\"http\") && url\n ? `${url.replace(/\\/$/, \"\")}${image}`\n : image;\n\n // Normalize structured data to an array\n const structuredDataItems: Array<Record<string, unknown>> = structuredData\n ? Array.isArray(structuredData)\n ? structuredData\n : [structuredData]\n : [];\n\n return (\n <Helmet>\n {/* Primary Meta Tags */}\n <title>{fullTitle}</title>\n <meta name=\"title\" content={fullTitle} />\n {description && <meta name=\"description\" content={description} />}\n {keywords && <meta name=\"keywords\" content={keywords} />}\n <meta name=\"author\" content=\"Burdenoff Consultancy Services Pvt Ltd\" />\n <meta name=\"robots\" content={robots} />\n\n {/* Canonical URL */}\n {url && <link rel=\"canonical\" href={url} />}\n\n {/* Favicon */}\n {favicon && <link rel=\"icon\" href={favicon} />}\n\n {/* Open Graph / Facebook */}\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:title\" content={fullTitle} />\n {description && <meta property=\"og:description\" content={description} />}\n {fullImageUrl && <meta property=\"og:image\" content={fullImageUrl} />}\n {url && <meta property=\"og:url\" content={url} />}\n <meta property=\"og:locale\" content={locale} />\n {productName && <meta property=\"og:site_name\" content={productName} />}\n\n {/* Twitter Card */}\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\n <meta name=\"twitter:title\" content={fullTitle} />\n {description && <meta name=\"twitter:description\" content={description} />}\n {fullImageUrl && <meta name=\"twitter:image\" content={fullImageUrl} />}\n {twitterHandle && <meta name=\"twitter:creator\" content={twitterHandle} />}\n\n {/* Theme Color */}\n <meta name=\"theme-color\" content={themeColor} />\n\n {/* JSON-LD Structured Data */}\n {structuredDataItems.map((data, index) => (\n <script key={`ld-${index}`} type=\"application/ld+json\">\n {JSON.stringify(data)}\n </script>\n ))}\n\n {/* Additional Meta Tags */}\n {additionalMeta?.map((meta, index) => (\n <meta\n key={`meta-${index}`}\n {...(meta.name ? { name: meta.name } : {})}\n {...(meta.property ? { property: meta.property } : {})}\n content={meta.content}\n />\n ))}\n </Helmet>\n );\n}\n","/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../utils/cn\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","/**\n * Pricing Component\n * GraphQL-powered pricing component with quota-based features and monthly/yearly toggle\n *\n * @example\n * ```tsx\n * import { PricingPage, PricingSection } from '@burdenoff/website-sdk/components/pricing'\n *\n * // Full page with hero\n * <PricingPage\n * productName=\"BigConsole\"\n * productId=\"bigconsole-123\"\n * appLoginUrl=\"https://app.bigconsole.com/login\"\n * contactUrl=\"/contact\"\n * fallbackFeatures={{\n * basic: ['Up to 5 dashboards', '10 data sources'],\n * professional: ['Unlimited dashboards', 'API access'],\n * enterprise: ['Everything in Professional', 'Dedicated support']\n * }}\n * />\n *\n * // Embeddable section\n * <PricingSection {...props} id=\"pricing\" className=\"bg-muted/30\" />\n * ```\n */\n\n\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\n\n// ============================================================================\n// GRAPHQL QUERY\n// ============================================================================\n\nconst GET_PLANS_QUERY = `\n query GetPublicPlans($productId: String!) {\n publicPlans(productId: $productId) {\n id\n name\n price\n currency\n currencyPrices\n duration\n features {\n id\n quotaId\n quota {\n id\n name\n limits\n }\n }\n isActive\n productID\n createdAt\n }\n }\n`;\n\n// ============================================================================\n// TYPES & INTERFACES\n// ============================================================================\n\ninterface PlanFeature {\n id: string;\n quotaId?: string | null;\n quota?: {\n id: string;\n name: string;\n limits?: unknown;\n } | null;\n}\n\ninterface GatewayPlan {\n id: string;\n name: string;\n price: number;\n currency: string;\n currencyPrices?: Record<string, number> | null;\n duration: string;\n features: PlanFeature[];\n isActive: boolean;\n productID?: string | null;\n createdAt: string;\n}\n\ninterface GetPlansResponse {\n publicPlans: GatewayPlan[];\n}\n\nexport interface PlanCard {\n id: string;\n name: string;\n price: number;\n currency: string;\n currencyPrices?: Record<string, number> | null;\n duration: string;\n features: Array<{\n id: string;\n quotaId?: string | null;\n quota?: {\n id: string;\n name: string;\n limits?: unknown;\n } | null;\n }>;\n isActive: boolean;\n productID?: string | null;\n}\n\ninterface CurrencyConfig {\n code: string;\n symbol: string;\n position: \"prefix\" | \"suffix\";\n}\n\ninterface PlanMetadata {\n tier: \"basic\" | \"professional\" | \"enterprise\";\n displayName: string;\n defaultDescription: string;\n popular: boolean;\n ctaText: string;\n ctaType: \"signup\" | \"contact\";\n /**\n * Curated feature bullets for this specific plan. When provided, these win\n * over the tier-based `fallbackFeatures` and the raw quota list — letting a\n * consumer differentiate plans that share a tier keyword (e.g. Free vs Hobby,\n * Pro vs Team) with concise, accurate copy.\n */\n features?: string[];\n}\n\nexport interface PricingProps {\n /**\n * Product name (used in branding and SEO)\n */\n productName?: string;\n /**\n * Product ID for GraphQL query (falls back to WebSDKConfig.productId)\n */\n productId?: string;\n /**\n * App login URL for signup CTA\n */\n appLoginUrl: string;\n /**\n * Contact page URL for enterprise CTA\n * @default '/contact'\n */\n contactUrl?: string;\n /**\n * Supported currencies\n */\n currencies?: Record<string, CurrencyConfig>;\n /**\n * Billing interval display text\n */\n billingIntervals?: Record<string, string>;\n /**\n * Plan metadata (tier info, CTA text, etc.)\n */\n planMetadata?: Record<string, Partial<PlanMetadata>>;\n /**\n * Fallback features when API doesn't provide them or is unavailable\n */\n fallbackFeatures?: {\n basic?: string[];\n professional?: string[];\n enterprise?: string[];\n };\n /**\n * Enable audience tabs (Individual / Enterprise).\n * When enabled, shows a two-level tab system.\n * @default false\n */\n showAudienceTabs?: boolean;\n /**\n * Enterprise plans to show when Enterprise tab is selected.\n * Each entry defines a static plan card (not fetched from API).\n */\n enterprisePlans?: Array<{\n name: string;\n subtitle: string;\n price: string;\n period: string;\n note?: string;\n button: string;\n buttonLink: string;\n popular: boolean;\n badge?: string;\n features: string[];\n }>;\n /**\n * Enterprise section heading\n * @default 'Enterprise Solutions'\n */\n enterpriseHeading?: string;\n /**\n * Enterprise section subtitle\n */\n enterpriseSubtitle?: string;\n /**\n * Hero section heading (for PricingPage)\n * @default 'Simple, Transparent Pricing'\n */\n heroHeading?: string;\n /**\n * Hero section subtitle (for PricingPage)\n * @default \"Choose the plan that's right for you. No hidden fees, no surprises.\"\n */\n heroSubtitle?: string;\n /**\n * Section heading (for PricingSection)\n * @default 'Pricing Plans'\n */\n sectionHeading?: string;\n /**\n * Section subtitle (for PricingSection)\n * @default 'Choose the perfect plan for your needs'\n */\n sectionSubtitle?: string;\n /**\n * Custom CSS class\n */\n className?: string;\n /**\n * Section ID for anchor links\n */\n id?: string;\n /**\n * SEO: Page title (optional, for PricingPage)\n */\n seoTitle?: string;\n /**\n * SEO: Page description (optional, for PricingPage)\n */\n seoDescription?: string;\n /**\n * SEO: Keywords (optional, for PricingPage)\n */\n seoKeywords?: string;\n /**\n * SEO: OG Image URL (optional, for PricingPage)\n */\n seoImage?: string;\n /**\n * SEO: Canonical URL (optional, for PricingPage)\n */\n seoUrl?: string;\n}\n\n// ============================================================================\n// SERVICE FUNCTIONS\n// ============================================================================\n\n/**\n * Format price for display with currency symbol\n */\nfunction formatPrice(\n price: number,\n currencyCode: string = \"USD\",\n currencies?: Record<string, CurrencyConfig>,\n): string {\n const defaultCurrencies: Record<string, CurrencyConfig> = {\n USD: { code: \"USD\", symbol: \"$\", position: \"prefix\" },\n EUR: { code: \"EUR\", symbol: \"\\u20AC\", position: \"prefix\" },\n GBP: { code: \"GBP\", symbol: \"\\u00A3\", position: \"prefix\" },\n INR: { code: \"INR\", symbol: \"\\u20B9\", position: \"prefix\" },\n };\n\n const currencyMap = currencies || defaultCurrencies;\n const currency: CurrencyConfig = currencyMap[currencyCode] || {\n code: currencyCode,\n symbol: currencyCode,\n position: \"prefix\",\n };\n\n const formattedNumber = price % 1 === 0 ? price.toString() : price.toFixed(2);\n\n return currency.position === \"prefix\"\n ? `${currency.symbol}${formattedNumber}`\n : `${formattedNumber}${currency.symbol}`;\n}\n\n/**\n * Format billing interval for display\n */\nfunction formatInterval(\n duration: string,\n billingIntervals?: Record<string, string>,\n): string {\n const defaultIntervals: Record<string, string> = {\n monthly: \"/month\",\n yearly: \"/year\",\n };\n\n const intervals = billingIntervals || defaultIntervals;\n return intervals[duration] || `/${duration}`;\n}\n\n/**\n * Detect if a plan belongs to the enterprise audience based on name.\n * Plans with \"team\", \"business\", or \"enterprise\" in the name are enterprise.\n */\nfunction isEnterprisePlan(planName: string): boolean {\n const name = planName.toLowerCase();\n return (\n name.includes(\"team\") ||\n name.includes(\"business\") ||\n name.includes(\"enterprise\")\n );\n}\n\n/**\n * Detect plan tier from plan name\n */\nfunction detectPlanTier(\n planName: string,\n): \"basic\" | \"professional\" | \"enterprise\" | null {\n const name = planName.toLowerCase();\n\n if (\n name.includes(\"free\") ||\n name.includes(\"basic\") ||\n name.includes(\"starter\") ||\n name.includes(\"hobby\")\n ) {\n return \"basic\";\n } else if (\n name.includes(\"pro\") ||\n name.includes(\"professional\") ||\n name.includes(\"premium\") ||\n name.includes(\"team\")\n ) {\n return \"professional\";\n } else if (name.includes(\"enterprise\") || name.includes(\"business\")) {\n return \"enterprise\";\n }\n\n return null;\n}\n\n/**\n * Get features for a specific plan tier from fallback config\n */\nfunction getFallbackFeaturesForTier(\n tier: \"basic\" | \"professional\" | \"enterprise\",\n fallbackFeatures?: {\n basic?: string[];\n professional?: string[];\n enterprise?: string[];\n },\n): string[] {\n return [...(fallbackFeatures?.[tier] || [])];\n}\n\n/**\n * Get metadata for a plan by name\n */\nfunction getMetadataForPlan(\n planName: string,\n planMetadata?: Record<string, Partial<PlanMetadata>>,\n): PlanMetadata {\n const normalizedName = planName.toLowerCase();\n\n // Try exact match first\n if (planMetadata?.[normalizedName]) {\n const meta = planMetadata[normalizedName];\n return {\n tier: meta.tier || \"basic\",\n displayName: meta.displayName || planName,\n defaultDescription: meta.defaultDescription || \"Choose this plan\",\n popular: meta.popular ?? false,\n ctaText: meta.ctaText || \"Get Started\",\n ctaType: meta.ctaType || \"signup\",\n features: meta.features,\n };\n }\n\n // Try tier detection\n const tier = detectPlanTier(planName);\n if (tier) {\n return {\n tier,\n displayName: planName,\n defaultDescription: \"Choose this plan\",\n popular: tier === \"professional\",\n ctaText: tier === \"enterprise\" ? \"Contact Sales\" : \"Get Started\",\n ctaType: tier === \"enterprise\" ? \"contact\" : \"signup\",\n };\n }\n\n // Fallback\n return {\n tier: \"basic\",\n displayName: planName,\n defaultDescription: \"Choose this plan\",\n popular: false,\n ctaText: \"Get Started\",\n ctaType: \"signup\",\n };\n}\n\n/**\n * Transform quota limits to a human-readable feature string\n */\n/**\n * Derive a human-readable label from a dotted quota name.\n * e.g. \"vibecontrols.workspaces.count\" → \"Workspaces\"\n * \"vibecontrols.storage.bytes\" → \"Storage\"\n */\nfunction humanizeQuotaName(name: string): string {\n const parts = name.split(\".\");\n // Use the second-to-last segment (the resource), or fall back to the last\n const resource =\n parts.length >= 3 ? parts[parts.length - 2]! : parts[parts.length - 1]!;\n // Capitalize and replace hyphens/underscores with spaces\n return resource\n .replace(/[-_]/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction transformQuotaToFeature(quota: {\n id: string;\n name: string;\n limits?: unknown;\n}): string {\n const { name, limits } = quota;\n\n if (!limits || typeof limits !== \"object\") {\n return humanizeQuotaName(name);\n }\n\n const limitsObj = limits as Record<string, unknown>;\n const value = limitsObj.value;\n const unit = limitsObj.unit;\n const type = limitsObj.type;\n const description = limitsObj.description;\n\n // Use explicit description if provided\n if (typeof description === \"string\" && description) {\n if (type === \"number\" && typeof value === \"number\") {\n return `${value.toLocaleString()} ${description}`;\n }\n return description;\n }\n\n // Use unit if provided\n if (typeof unit === \"string\" && unit) {\n if (typeof value === \"number\") {\n return `${value.toLocaleString()} ${unit}`;\n }\n return `${unit}`;\n }\n\n // Derive label from quota name\n const label = humanizeQuotaName(name);\n\n if (type === \"boolean\") {\n return label;\n }\n\n if (typeof value === \"number\") {\n return `${value.toLocaleString()} ${label}`;\n }\n\n return label;\n}\n\n/**\n * Extract display features from a plan's feature list\n */\nfunction extractDisplayFeatures(\n features: PlanFeature[],\n planName: string,\n fallbackFeatures?: {\n basic?: string[];\n professional?: string[];\n enterprise?: string[];\n },\n): string[] {\n // Prefer curated fallback features when available — they are concise\n // and differentiated per tier, unlike raw quota dumps\n const tier = detectPlanTier(planName);\n if (tier) {\n const tierFeatures = getFallbackFeaturesForTier(tier, fallbackFeatures);\n if (tierFeatures.length > 0) {\n return tierFeatures;\n }\n }\n\n // No fallback: transform quota features from API\n const quotaFeatures = features\n .filter((f) => f.quota)\n .map((f) => transformQuotaToFeature(f.quota!));\n\n if (quotaFeatures.length > 0) {\n return quotaFeatures;\n }\n\n return [];\n}\n\n// ============================================================================\n// UI CARD TYPE (internal)\n// ============================================================================\n\ninterface DisplayPlanCard {\n id: string;\n name: string;\n description: string;\n price: string;\n priceRaw: number;\n interval: string;\n duration: string;\n features: string[];\n popular: boolean;\n ctaText: string;\n ctaLink: string;\n tier: \"basic\" | \"professional\" | \"enterprise\" | null;\n}\n\n/**\n * Transform a GatewayPlan into a display card\n */\nfunction transformToDisplayCard(\n plan: GatewayPlan,\n props: PricingProps,\n): DisplayPlanCard {\n const metadata = getMetadataForPlan(plan.name, props.planMetadata);\n\n const formattedPrice = formatPrice(\n plan.price,\n plan.currency,\n props.currencies,\n );\n const interval = formatInterval(plan.duration, props.billingIntervals);\n\n // A curated per-plan list (via planMetadata) wins over the tier fallback and\n // the raw quota dump — this is how Free/Hobby and Pro/Team get distinct copy.\n const features =\n metadata.features && metadata.features.length > 0\n ? metadata.features\n : extractDisplayFeatures(\n plan.features,\n plan.name,\n props.fallbackFeatures,\n );\n\n const contactUrl = props.contactUrl || \"/contact\";\n const ctaLink =\n metadata.ctaType === \"contact\" ? contactUrl : props.appLoginUrl;\n\n return {\n id: plan.id,\n name: plan.name,\n description: metadata.defaultDescription,\n price: formattedPrice,\n priceRaw: plan.price,\n interval,\n duration: plan.duration,\n features,\n popular: metadata.popular,\n ctaText: metadata.ctaText,\n ctaLink,\n tier: metadata.tier,\n };\n}\n\n// ============================================================================\n// REACT COMPONENTS\n// ============================================================================\n\n/**\n * Pricing Section Component - Embeddable\n */\nexport function PricingSection(props: PricingProps) {\n const {\n sectionHeading = \"Pricing Plans\",\n sectionSubtitle = \"Choose the perfect plan for your needs\",\n id,\n className = \"\",\n } = props;\n\n const client = useWebSDK();\n const config = useWebSDKConfig();\n\n const resolvedProductId = props.productId || config.productId;\n\n const [allPlans, setAllPlans] = useState<DisplayPlanCard[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [billingCycle, setBillingCycle] = useState<\"monthly\" | \"yearly\">(\n \"monthly\",\n );\n const [audience, setAudience] = useState<\"individual\" | \"enterprise\">(\n \"individual\",\n );\n\n useEffect(() => {\n let cancelled = false;\n\n async function loadPlans() {\n try {\n setLoading(true);\n\n const response = await client.query<GetPlansResponse>(GET_PLANS_QUERY, {\n productId: resolvedProductId,\n });\n\n if (cancelled) return;\n\n if (response.errors && response.errors.length > 0) {\n throw new Error(response.errors[0]!.message);\n }\n\n if (!response.data?.publicPlans) {\n throw new Error(\"No plans data received\");\n }\n\n // Server already filters by productId — just filter active, transform, sort\n const cards = response.data.publicPlans\n .filter((plan) => plan.isActive)\n .map((plan) => transformToDisplayCard(plan, props))\n .sort((a, b) => a.priceRaw - b.priceRaw);\n\n setAllPlans(cards);\n setError(null);\n } catch (err) {\n if (cancelled) return;\n console.error(\"Failed to load plans:\", err);\n setError(\"Unable to load pricing information. Please try again later.\");\n } finally {\n if (!cancelled) {\n setLoading(false);\n }\n }\n }\n\n loadPlans();\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- props is destructured, actual deps are client + productId\n }, [client, resolvedProductId]);\n\n // Split plans by audience (individual vs enterprise) based on plan name\n const individualAllPlans = allPlans.filter((p) => !isEnterprisePlan(p.name));\n const enterpriseApiPlans = allPlans.filter((p) => isEnterprisePlan(p.name));\n\n // Filter individual plans by billing cycle\n const individualPlans = individualAllPlans.filter((plan) =>\n billingCycle === \"monthly\"\n ? plan.duration === \"monthly\"\n : plan.duration === \"yearly\",\n );\n\n // Enterprise plans from API (show all — no billing cycle filter since enterprise is typically monthly)\n const enterpriseCards: DisplayPlanCard[] = enterpriseApiPlans.map((p) => {\n // Mark $0 enterprise plans as \"Custom\" pricing with Contact Sales CTA\n if (p.priceRaw === 0 && p.name.toLowerCase().includes(\"enterprise\")) {\n return {\n ...p,\n price: \"Custom\",\n interval: \"\",\n ctaText: \"Contact Sales\",\n ctaLink: props.contactUrl || \"/contact\",\n };\n }\n return p;\n });\n\n // Use API enterprise plans if available, otherwise fall back to static prop, otherwise use built-in default\n const hasApiEnterprisePlans = enterpriseCards.length > 0;\n const defaultEnterpriseCard: Record<string, unknown> = {\n name: \"Enterprise\",\n subtitle: \"For organizations that need more\",\n description: \"For organizations that need more\",\n price: \"Custom\",\n period: \"\",\n interval: \"\",\n button: \"Contact Sales\",\n buttonLink: props.contactUrl || \"/contact\",\n ctaText: \"Contact Sales\",\n ctaLink: props.contactUrl || \"/contact\",\n popular: false,\n features: props.fallbackFeatures?.enterprise || [\n \"Unlimited everything\",\n \"SSO & SAML\",\n \"Audit logs\",\n \"Dedicated support\",\n \"Self-hosted option\",\n ],\n };\n const resolvedEnterprisePlans = hasApiEnterprisePlans\n ? (enterpriseCards as unknown as Record<string, unknown>[])\n : props.enterprisePlans\n ? (props.enterprisePlans as unknown as Record<string, unknown>[])\n : [defaultEnterpriseCard];\n\n // Determine which plans to show based on audience\n const plans =\n props.showAudienceTabs && audience === \"enterprise\"\n ? [] // Enterprise uses separate rendering\n : individualPlans;\n\n if (loading) {\n return (\n <section id={id} className={`py-12 sm:py-16 md:py-20 ${className}`}>\n <div className=\"container mx-auto px-4 sm:px-6\">\n <div className=\"text-center mb-8 sm:mb-12\">\n {sectionHeading ? (\n <h2 className=\"text-2xl sm:text-3xl md:text-4xl font-bold mb-3 sm:mb-4\">\n {sectionHeading}\n </h2>\n ) : (\n // Visually hidden but DOM-present heading so axe's heading-order\n // rule still sees an h2 between the consumer's hero h1 and the\n // h3 plan-card titles. See `getMetadataForPlan` for why a falsy\n // sectionHeading is the canonical \"no visible heading\" signal.\n <h2 className=\"sr-only\">Pricing</h2>\n )}\n <p className=\"text-muted-foreground text-sm sm:text-base md:text-lg\">\n Loading pricing information...\n </p>\n </div>\n <div className=\"grid md:grid-cols-3 gap-6 sm:gap-8\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"bg-card border rounded-lg p-6 animate-pulse\"\n >\n <div className=\"h-6 bg-muted rounded w-1/2 mb-4\"></div>\n <div className=\"h-4 bg-muted rounded w-3/4 mb-6\"></div>\n <div className=\"h-10 bg-muted rounded w-1/3 mb-6\"></div>\n <div className=\"space-y-3 mb-6\">\n {[1, 2, 3, 4].map((j) => (\n <div key={j} className=\"h-4 bg-muted rounded\"></div>\n ))}\n </div>\n <div className=\"h-10 bg-muted rounded\"></div>\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n }\n\n if (error && plans.length === 0) {\n return (\n <section id={id} className={`py-12 sm:py-16 md:py-20 ${className}`}>\n <div className=\"container mx-auto px-4 sm:px-6\">\n <div className=\"text-center\">\n {sectionHeading ? (\n <h2 className=\"text-2xl sm:text-3xl md:text-4xl font-bold mb-4\">\n {sectionHeading}\n </h2>\n ) : (\n <h2 className=\"sr-only\">Pricing</h2>\n )}\n <p className=\"text-muted-foreground mb-8\">{error}</p>\n <Button onClick={() => window.location.reload()}>Retry</Button>\n </div>\n </div>\n </section>\n );\n }\n\n return (\n <section id={id} className={`py-12 sm:py-16 md:py-20 ${className}`}>\n <div className=\"container mx-auto px-4 sm:px-6\">\n <div className=\"text-center mb-8 sm:mb-12\">\n {sectionHeading ? (\n <h2 className=\"text-2xl sm:text-3xl md:text-4xl font-bold mb-3 sm:mb-4\">\n {sectionHeading}\n </h2>\n ) : (\n <h2 className=\"sr-only\">Pricing</h2>\n )}\n <p className=\"text-muted-foreground text-sm sm:text-base md:text-lg mb-6\">\n {sectionSubtitle}\n </p>\n\n {/* Audience Toggle (Individual / Enterprise) */}\n {props.showAudienceTabs && (\n <div className=\"flex justify-center mb-4\">\n <div className=\"inline-flex items-center bg-muted p-1.5 rounded-xl\">\n <button\n type=\"button\"\n onClick={() => setAudience(\"individual\")}\n className={`px-6 sm:px-8 py-2.5 rounded-lg text-sm font-semibold transition-all ${\n audience === \"individual\"\n ? \"bg-background shadow-sm text-foreground\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Individual\n </button>\n <button\n type=\"button\"\n onClick={() => setAudience(\"enterprise\")}\n className={`px-6 sm:px-8 py-2.5 rounded-lg text-sm font-semibold transition-all ${\n audience === \"enterprise\"\n ? \"bg-background shadow-sm text-foreground\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Enterprise\n </button>\n </div>\n </div>\n )}\n\n {/* Billing Cycle Toggle — only for Individual */}\n {(audience === \"individual\" || !props.showAudienceTabs) && (\n <div className=\"flex justify-center\">\n <div className=\"inline-flex items-center bg-muted/60 p-1.5 rounded-xl\">\n <button\n type=\"button\"\n onClick={() => setBillingCycle(\"monthly\")}\n className={`px-5 sm:px-6 py-2 rounded-lg text-sm font-medium transition-all ${\n billingCycle === \"monthly\"\n ? \"bg-background shadow-sm text-foreground\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Monthly\n </button>\n <button\n type=\"button\"\n onClick={() => setBillingCycle(\"yearly\")}\n className={`px-5 sm:px-6 py-2 rounded-lg text-sm font-medium transition-all ${\n billingCycle === \"yearly\"\n ? \"bg-background shadow-sm text-foreground\"\n : \"text-muted-foreground hover:text-foreground\"\n }`}\n >\n Yearly\n </button>\n </div>\n </div>\n )}\n </div>\n\n {/* Enterprise Intro — only when Enterprise is selected */}\n {props.showAudienceTabs && audience === \"enterprise\" && (\n <div className=\"mx-auto max-w-3xl text-center mb-8\">\n <h3 className=\"text-xl sm:text-2xl font-bold text-foreground\">\n {props.enterpriseHeading || \"Enterprise Solutions\"}\n </h3>\n <p className=\"mt-3 text-muted-foreground\">\n {props.enterpriseSubtitle ||\n \"Built for teams, agencies, and organizations that need advanced collaboration, security, support, and scale.\"}\n </p>\n </div>\n )}\n\n <div className=\"grid md:grid-cols-3 gap-6 sm:gap-8 max-w-6xl mx-auto items-stretch\">\n {props.showAudienceTabs && audience === \"enterprise\"\n ? /* Enterprise cards — from API, static prop, or built-in default */\n resolvedEnterprisePlans.map((ep) => {\n // Normalize fields — API uses description/ctaText/ctaLink/interval, static prop uses subtitle/button/buttonLink/period\n const subtitle = (ep.subtitle ||\n ep.description ||\n \"\") as string;\n const btnText = (ep.button ||\n ep.ctaText ||\n \"Get Started\") as string;\n const btnLink = (ep.buttonLink ||\n ep.ctaLink ||\n props.appLoginUrl) as string;\n const period = (ep.period || ep.interval || \"\") as string;\n const note = (ep.note || \"\") as string;\n const badge = (ep.badge || \"\") as string;\n const isPopular = ep.popular as boolean;\n const features = (ep.features || []) as string[];\n const price = String(ep.price);\n\n return (\n <div\n key={ep.name as string}\n className={`bg-card rounded-xl p-6 sm:p-8 transition-all duration-300 flex flex-col ${\n isPopular\n ? \"border-2 border-primary shadow-xl ring-1 ring-primary/20\"\n : \"border hover:shadow-lg hover:border-primary/50\"\n }`}\n >\n <div className=\"text-center mb-6\">\n {isPopular && badge && (\n <span className=\"inline-block bg-primary text-primary-foreground px-4 py-1 rounded-full text-xs font-semibold mb-3\">\n {badge}\n </span>\n )}\n <h3 className=\"text-xl sm:text-2xl font-bold mb-2\">\n {ep.name as string}\n </h3>\n <p className=\"text-muted-foreground text-sm\">\n {subtitle}\n </p>\n </div>\n\n <div className=\"text-center mb-2\">\n {price === \"Custom\" ? (\n <span className=\"text-3xl sm:text-4xl font-bold\">\n Custom\n </span>\n ) : (\n <div className=\"flex items-baseline justify-center gap-1\">\n <span className=\"text-4xl sm:text-5xl font-extrabold\">\n {price}\n </span>\n <span className=\"text-muted-foreground text-lg\">\n {period}\n </span>\n </div>\n )}\n {note && (\n <p className=\"mt-2 text-sm font-medium text-primary\">\n {note}\n </p>\n )}\n </div>\n\n <ul className=\"space-y-3 mb-8 mt-6 flex-1\">\n {features.map((feature) => (\n <li\n key={feature}\n className=\"text-sm flex items-start gap-2\"\n >\n <span className=\"text-primary mt-0.5 flex-shrink-0\">\n &#10003;\n </span>\n <span>{feature}</span>\n </li>\n ))}\n </ul>\n\n {btnLink.startsWith(\"/\") ? (\n <Button\n className=\"w-full h-11\"\n variant={isPopular ? \"default\" : \"outline\"}\n size=\"lg\"\n asChild\n >\n <a\n href={btnLink}\n onClick={() =>\n window.scrollTo({ top: 0, behavior: \"smooth\" })\n }\n >\n {btnText}\n </a>\n </Button>\n ) : (\n <Button\n className=\"w-full h-11\"\n variant={isPopular ? \"default\" : \"outline\"}\n size=\"lg\"\n asChild\n >\n <a\n href={btnLink}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {btnText}\n </a>\n </Button>\n )}\n </div>\n );\n })\n : /* Individual API-fetched cards */\n plans.map((plan) => (\n <div\n key={plan.id}\n className={`bg-card rounded-xl p-6 sm:p-8 transition-all duration-300 flex flex-col ${\n plan.popular\n ? \"border-2 border-primary shadow-xl ring-1 ring-primary/20\"\n : \"border hover:shadow-lg hover:border-primary/50\"\n }`}\n >\n <div className=\"text-center mb-6\">\n {plan.popular && (\n <span className=\"inline-block bg-primary text-primary-foreground px-4 py-1 rounded-full text-xs font-semibold mb-3\">\n Most Popular\n </span>\n )}\n <h3 className=\"text-xl sm:text-2xl font-bold mb-2\">\n {plan.name}\n </h3>\n <p className=\"text-muted-foreground text-sm\">\n {plan.description}\n </p>\n </div>\n\n <div className=\"text-center mb-8\">\n {plan.price === \"Custom\" ? (\n <span className=\"text-3xl sm:text-4xl font-bold\">\n Custom\n </span>\n ) : (\n <div className=\"flex items-baseline justify-center gap-1\">\n <span className=\"text-4xl sm:text-5xl font-bold\">\n {plan.price}\n </span>\n <span className=\"text-muted-foreground text-lg\">\n {plan.interval}\n </span>\n </div>\n )}\n </div>\n\n <ul className=\"space-y-3 mb-8 flex-1\">\n {plan.features.map((feature, index) => (\n <li\n key={index}\n className=\"text-sm flex items-start gap-2\"\n >\n <span className=\"text-primary mt-0.5 flex-shrink-0\">\n &#10003;\n </span>\n <span>{feature}</span>\n </li>\n ))}\n </ul>\n\n {plan.ctaLink.startsWith(\"/\") ? (\n <Button\n className=\"w-full h-11\"\n variant={plan.popular ? \"default\" : \"outline\"}\n size=\"lg\"\n asChild\n >\n <a\n href={plan.ctaLink}\n onClick={() =>\n window.scrollTo({ top: 0, behavior: \"smooth\" })\n }\n >\n {plan.ctaText}\n </a>\n </Button>\n ) : (\n <Button\n className=\"w-full h-11\"\n variant={plan.popular ? \"default\" : \"outline\"}\n size=\"lg\"\n asChild\n >\n <a\n href={plan.ctaLink}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {plan.ctaText}\n </a>\n </Button>\n )}\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n}\n\n/**\n * Pricing Page Component - Full Page with Hero\n */\nexport function PricingPage(props: PricingProps) {\n const {\n productName,\n heroHeading = \"Simple, Transparent Pricing\",\n heroSubtitle = \"Choose the plan that's right for you. No hidden fees, no surprises.\",\n seoTitle,\n seoDescription,\n seoKeywords,\n seoImage,\n seoUrl,\n } = props;\n\n return (\n <div className=\"w-full\">\n {/* SEO Meta Tags */}\n {seoTitle && (\n <PageHead\n title={seoTitle}\n description={seoDescription || heroSubtitle}\n productName={productName}\n keywords={seoKeywords}\n image={seoImage}\n url={seoUrl}\n />\n )}\n\n {/* Hero Section */}\n <section className=\"bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center max-w-3xl mx-auto\">\n <h1 className=\"text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6\">\n {heroHeading}\n </h1>\n <p className=\"text-lg sm:text-xl text-muted-foreground leading-relaxed\">\n {heroSubtitle}\n </p>\n </div>\n </div>\n </section>\n\n {/* Pricing Section */}\n <PricingSection {...props} />\n </div>\n );\n}\n"]}