{"version":3,"file":"MySiteWidget-Dc5AcxFW.mjs","names":[],"sources":["../../widgets/src/hooks/use-mysite.preview.ts","../../widgets/src/hooks/use-mysite.ts","../../widgets/src/widgets/MySiteWidget.tsx"],"sourcesContent":["import type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport const PREVIEW_DATA: MySiteData = {\n  url: \"https://mysite.example.com\",\n  views: 1248,\n  leads: 43,\n  userName: \"Jane\",\n};\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-mysite.preview\";\nimport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { MySiteData } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport function useMySite(): UseQueryResult<MySiteData, Error> {\n  const widgetsApi = useWidgetsApi();\n  const { isPreview } = useWidgetPreviewContext();\n  const { baseUrl } = useDataSourceRegistryConfig();\n\n  return useQuery({\n    queryKey: [\n      \"portal-widget-use\",\n      \"mysite\",\n      isPreview ? \"preview\" : baseUrl,\n    ] as const,\n    queryFn: ({ signal }) => widgetsApi.fetchMySite(signal),\n    enabled: !isPreview,\n    ...(isPreview && { placeholderData: PREVIEW_DATA }),\n  });\n}\n","import {\n  useCallback,\n  useEffect,\n  useLayoutEffect,\n  useMemo,\n  useRef,\n  useState,\n  type ComponentProps,\n  type CSSProperties,\n} from \"react\";\nimport type React from \"react\";\nimport type {\n  BackgroundValue,\n  BorderRadiusOptions,\n  ColorOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { getBorderRadiusField, getColorField } from \"../core/fields\";\nimport { useMySite, type MySiteData } from \"../hooks/use-mysite\";\nimport { ErrorState } from \"../components/error-state\";\nimport { QRCodeSVG } from \"qrcode.react\";\nimport { ArrowUpRight, Check, Copy, Globe } from \"lucide-react\";\n\ntype MySiteWidgetProps = ComponentProps<\"div\"> & {\n  // Design\n  background?: BackgroundValue;\n  textColor?: ColorOptions;\n  accentColor?: ColorOptions;\n  borderRadius?: BorderRadiusOptions;\n\n  // Display toggles\n  showPreview?: boolean;\n  showAnalytics?: boolean;\n  showLiveBadge?: boolean;\n  showQR?: boolean;\n\n  // Builder-only props must not be forwarded to the root DOM element.\n  editMode?: boolean;\n  isSelected?: boolean;\n};\n\nconst formatCompactNumber = (n: number | undefined): string => {\n  const value = n ?? 0;\n  if (value < 1000) return value.toLocaleString();\n  if (value < 10_000) return `${(value / 1000).toFixed(1)}k`;\n  if (value < 1_000_000) return `${Math.round(value / 1000)}k`;\n  return `${(value / 1_000_000).toFixed(1)}m`;\n};\n\nconst splitUrl = (url: string): { prefix: string; path: string } => {\n  try {\n    const parsed = new URL(url);\n    return {\n      prefix: `${parsed.protocol}//${parsed.host}`,\n      path:\n        `${parsed.pathname}${parsed.search}${parsed.hash}`.replace(\n          /^\\/$/,\n          \"\",\n        ) || \"\",\n    };\n  } catch {\n    return { prefix: \"\", path: url };\n  }\n};\n\nexport function MySiteWidget({\n  background = { type: \"solid\", color: \"background\" },\n  textColor = \"foreground\",\n  accentColor = \"primary\",\n  borderRadius = \"xl\",\n\n  showPreview = true,\n  showAnalytics = true,\n  showLiveBadge = true,\n  showQR = true,\n\n  className,\n  editMode: _editMode,\n  isSelected: _isSelected,\n  ...props\n}: MySiteWidgetProps): React.JSX.Element | null {\n  const { copyState, markCopied } = useTimedCopyState(1600);\n  const { rootRef: widgetRootRef, isWide } = useIsContainerWide(720);\n  const {\n    frameRef: previewFrameRef,\n    scale,\n    iframeHeight,\n  } = useScaledIframePreview({\n    viewportWidth: 1280,\n    minIframeHeight: 500,\n  });\n  const backgroundColor = background.color || \"background\";\n  const backgroundImage =\n    (background.resource?.image_url || background.resource?.imageUrl) &&\n    background.type === \"image\"\n      ? `url(${background.resource.image_url || background.resource.imageUrl})`\n      : \"none\";\n\n  const { data: mySite, isLoading, isError } = useMySite();\n  const { isPreview } = useWidgetPreviewContext();\n  const realMySite = useRealMySiteData(mySite, isPreview);\n  const { hasRealSite, url, views, leads } = realMySite;\n  const { previewUrl, hostLabel, urlPrefix, urlPath } =\n    useMySiteDisplayUrls(url);\n  // `iframeRef` is shared between the dashboard-layout and card-layout\n  // iframes below. This is safe because `showDashboardLayout` makes the two\n  // branches mutually exclusive — only one iframe is ever in the DOM at a\n  // time. If a future refactor renders both simultaneously (e.g. an\n  // animated transition), each iframe will need its own ref.\n  const { iframeRef, handleIframeLoad } = useIframeNavigationLock(previewUrl);\n  const showDashboardLayout = isWide && hasRealSite;\n  const showStats = showAnalytics && hasRealSite;\n  const showFooter = hasRealSite;\n\n  const handleCopy = async () => {\n    if (!url) return;\n    try {\n      await navigator.clipboard.writeText(url);\n      markCopied();\n    } catch (error) {\n      console.error(\"Failed to copy MySite URL:\", error);\n    }\n  };\n\n  if (!isLoading && !isError && !isPreview && !hasRealSite) {\n    return null;\n  }\n\n  // Hairline divider color — subtle, theme-aware\n  const divider: CSSProperties = {\n    borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n  };\n\n  return (\n    <div\n      ref={widgetRootRef}\n      className={`@container relative overflow-hidden rounded-${borderRadius} bg-${backgroundColor} text-${textColor} ${className ?? \"\"}`}\n      style={{\n        backgroundImage,\n        boxShadow: `0 1px 2px rgba(15,23,42,0.04), 0 20px 40px -24px rgba(15,23,42,0.16), inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 7%, transparent)`,\n      }}\n      {...props}\n    >\n      {isLoading ? (\n        <MySiteSkeleton\n          textColor={textColor}\n          accentColor={accentColor}\n          borderRadius={borderRadius}\n        />\n      ) : isError ? (\n        <div className=\"p-6\">\n          <ErrorState />\n        </div>\n      ) : showDashboardLayout ? (\n        <div className=\"flex items-stretch\">\n          {/* Left: site preview */}\n          {showPreview && (\n            <div\n              className=\"relative isolate shrink-0 bg-white\"\n              style={{\n                width: \"45%\",\n                borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n              }}\n            >\n              <div\n                ref={previewFrameRef}\n                className=\"relative h-full w-full overflow-hidden bg-white\"\n              >\n                <iframe\n                  ref={iframeRef}\n                  className=\"absolute top-0 left-0 origin-top-left bg-white\"\n                  src={previewUrl}\n                  title={`${hostLabel} preview`}\n                  loading=\"lazy\"\n                  tabIndex={-1}\n                  // allow-scripts + allow-same-origin is a known sandbox escape\n                  // hatch: if iframe and parent share an origin, scripts can\n                  // strip the sandbox attribute. Safe here because mysite is\n                  // hosted on a different origin than portal.\n                  sandbox=\"allow-scripts allow-same-origin\"\n                  onLoad={handleIframeLoad}\n                  style={{\n                    width: \"1280px\",\n                    height: `${iframeHeight}px`,\n                    transform: `scale(${scale})`,\n                  }}\n                />\n                <div\n                  aria-hidden=\"true\"\n                  className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n                  style={{\n                    background:\n                      \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n                  }}\n                />\n              </div>\n\n              {showLiveBadge && (\n                <div className=\"absolute top-4 left-4\">\n                  <span\n                    className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2.5 py-1 text-[10px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n                    style={{\n                      boxShadow:\n                        \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n                    }}\n                  >\n                    <span\n                      aria-hidden=\"true\"\n                      className={`bg-${accentColor} size-1.5 rounded-full`}\n                    />\n                    Live\n                  </span>\n                </div>\n              )}\n            </div>\n          )}\n\n          {/* Right: dashboard column */}\n          <div className=\"flex min-w-0 flex-1 flex-col gap-3.5 p-5 sm:p-6\">\n            <div>\n              <span\n                className={`text-[10px] font-bold tracking-[0.2em] uppercase text-${textColor}/55`}\n              >\n                Your Storefront\n              </span>\n              <h2\n                className={`mt-1 text-[22px] leading-[1.1] font-bold tracking-[-0.02em] text-${textColor}`}\n              >\n                You&rsquo;re live\n              </h2>\n            </div>\n\n            {hasRealSite && (\n              <button\n                type=\"button\"\n                onClick={handleCopy}\n                aria-label={\n                  copyState === \"copied\"\n                    ? \"Copied to clipboard\"\n                    : \"Copy site link\"\n                }\n                className={`group/copy flex items-center gap-2.5 rounded-${borderRadius} px-3 py-2 text-[13px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n                style={{\n                  boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n                }}\n              >\n                <Globe className={`size-3.5 shrink-0 text-${textColor}/55`} />\n                <span\n                  className={`min-w-0 flex-1 truncate text-left font-semibold tabular-nums text-${textColor}`}\n                >\n                  {hostLabel}\n                  {urlPath}\n                </span>\n                <span\n                  className={`flex size-7 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor} text-${backgroundColor}`}`}\n                >\n                  {copyState === \"copied\" ? (\n                    <Check className=\"size-3\" />\n                  ) : (\n                    <Copy className=\"size-3\" />\n                  )}\n                </span>\n              </button>\n            )}\n\n            {showStats && (\n              <>\n                <div\n                  style={{\n                    borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n                  }}\n                />\n                <div className=\"grid grid-cols-2 gap-4\">\n                  <div>\n                    <div\n                      className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n                    >\n                      Visitors\n                    </div>\n                    <div\n                      className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n                    >\n                      {formatCompactNumber(views)}\n                    </div>\n                  </div>\n                  <div>\n                    <div\n                      className={`text-[10px] font-bold tracking-[0.18em] uppercase text-${textColor}/55`}\n                    >\n                      Leads\n                    </div>\n                    <div\n                      className={`mt-1 text-[32px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n                    >\n                      {formatCompactNumber(leads)}\n                    </div>\n                  </div>\n                </div>\n              </>\n            )}\n\n            {hasRealSite && (\n              <a\n                href={url}\n                target=\"_blank\"\n                rel=\"noopener noreferrer\"\n                className={`group/visit mt-auto inline-flex items-center justify-between gap-2 rounded-${borderRadius} bg-${accentColor} px-4 py-3 text-[13px] font-bold text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_12px_28px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n              >\n                <span>Open the live site</span>\n                <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n              </a>\n            )}\n          </div>\n        </div>\n      ) : (\n        <div className=\"flex flex-col\">\n          {/* Card body: site preview — flush to the top of the card */}\n          {showPreview && (hasRealSite || isPreview) && (\n            <div className=\"relative isolate bg-white\">\n              <div\n                ref={previewFrameRef}\n                className=\"relative aspect-[16/10] w-full overflow-hidden bg-white\"\n              >\n                {isPreview || !hasRealSite ? (\n                  <MySitePreviewPlaceholder hostLabel={hostLabel} />\n                ) : (\n                  <iframe\n                    ref={iframeRef}\n                    className=\"absolute top-0 left-0 origin-top-left bg-white\"\n                    src={previewUrl}\n                    title={`${hostLabel} preview`}\n                    loading=\"lazy\"\n                    tabIndex={-1}\n                    sandbox=\"allow-scripts allow-same-origin\"\n                    onLoad={handleIframeLoad}\n                    style={{\n                      width: \"1280px\",\n                      height: `${iframeHeight}px`,\n                      transform: `scale(${scale})`,\n                    }}\n                  />\n                )}\n                {/* Very subtle top-edge sheen for polish */}\n                <div\n                  aria-hidden=\"true\"\n                  className=\"pointer-events-none absolute inset-x-0 top-0 h-px\"\n                  style={{\n                    background:\n                      \"linear-gradient(to right, transparent, rgba(255,255,255,0.7), transparent)\",\n                  }}\n                />\n              </div>\n\n              {/* LIVE badge — quiet, not blinking */}\n              {showLiveBadge && hasRealSite && (\n                <div className=\"absolute top-3 right-3\">\n                  <span\n                    className={`inline-flex items-center gap-1.5 rounded-${borderRadius} bg-white px-2 py-1 text-[9px] font-bold tracking-[0.18em] text-slate-700 uppercase`}\n                    style={{\n                      boxShadow:\n                        \"0 2px 8px rgba(15,23,42,0.08), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n                    }}\n                  >\n                    <span\n                      aria-hidden=\"true\"\n                      className={`bg-${accentColor} size-1.5 rounded-full`}\n                    />\n                    Live\n                  </span>\n                </div>\n              )}\n            </div>\n          )}\n\n          {/* Card footer — distinct tinted surface, QR column + right column */}\n          {showFooter && (\n            <div\n              className=\"flex items-stretch\"\n              style={{\n                borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n                background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n              }}\n            >\n              {/* QR column — spans the full footer height */}\n              {showQR && hasRealSite && (\n                <div\n                  className=\"flex shrink-0 items-center justify-center p-4\"\n                  style={{\n                    borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n                  }}\n                >\n                  <div\n                    className={`flex flex-col items-center gap-1.5 rounded-${borderRadius} bg-white p-2.5`}\n                    style={{\n                      boxShadow:\n                        \"0 2px 8px rgba(15,23,42,0.05), inset 0 0 0 1px rgba(15,23,42,0.06)\",\n                    }}\n                    role=\"img\"\n                    aria-label=\"QR code for your site\"\n                  >\n                    <QRCodeSVG\n                      value={url}\n                      size={64}\n                      level=\"H\"\n                      bgColor=\"#ffffff\"\n                      fgColor=\"#0f172a\"\n                    />\n                  </div>\n                </div>\n              )}\n\n              {/* Right column */}\n              <div className=\"flex min-w-0 flex-1 flex-col\">\n                {/* Stats row */}\n                {showStats && (\n                  <div className=\"grid grid-cols-2\">\n                    <StatCell\n                      label=\"Visitors\"\n                      value={formatCompactNumber(views)}\n                      textColor={textColor}\n                    />\n                    <StatCell\n                      label=\"Leads\"\n                      value={formatCompactNumber(leads)}\n                      textColor={textColor}\n                      leftDivider\n                    />\n                  </div>\n                )}\n\n                {/* Action row */}\n                {hasRealSite && (\n                  <div\n                    className=\"flex items-center gap-2 px-4 py-3\"\n                    style={showStats ? divider : undefined}\n                  >\n                    <button\n                      type=\"button\"\n                      onClick={handleCopy}\n                      aria-label={\n                        copyState === \"copied\"\n                          ? \"Copied to clipboard\"\n                          : \"Copy site link\"\n                      }\n                      className={`group/copy flex min-w-0 flex-1 items-center justify-between gap-2 rounded-${borderRadius} px-3 py-2 text-left text-[12px] transition-all duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40 ${copyState === \"copied\" ? `bg-${accentColor}/10` : `bg-${textColor}/5 hover:bg-${textColor}/10`}`}\n                      style={{\n                        boxShadow: `inset 0 0 0 1px color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n                      }}\n                    >\n                      <span\n                        className={`min-w-0 flex-1 truncate font-medium text-${textColor}`}\n                      >\n                        {urlPrefix && (\n                          <span className={`text-${textColor}/45`}>\n                            {urlPrefix}\n                          </span>\n                        )}\n                        <span className=\"font-semibold\">{urlPath || \"/\"}</span>\n                      </span>\n                      <span\n                        className={`flex size-6 shrink-0 items-center justify-center rounded-full transition-all duration-300 ${copyState === \"copied\" ? `scale-105 bg-${accentColor} text-${accentColor}-foreground` : `bg-${textColor}/10 text-${textColor} group-hover/copy:bg-${textColor}/20`}`}\n                      >\n                        {copyState === \"copied\" ? (\n                          <Check className=\"size-3\" />\n                        ) : (\n                          <Copy className=\"size-3\" />\n                        )}\n                      </span>\n                    </button>\n\n                    <a\n                      href={url}\n                      target=\"_blank\"\n                      rel=\"noopener noreferrer\"\n                      aria-label=\"Visit site\"\n                      className={`group/visit inline-flex size-9 shrink-0 items-center justify-center rounded-${borderRadius} bg-${accentColor} text-${accentColor}-foreground transition-all duration-300 hover:shadow-[0_10px_24px_-8px_color-mix(in_oklch,var(--color-${accentColor})_60%,transparent)]`}\n                    >\n                      <ArrowUpRight className=\"size-3.5 transition-transform duration-300 group-hover/visit:translate-x-0.5 group-hover/visit:-translate-y-0.5\" />\n                    </a>\n                  </div>\n                )}\n              </div>\n            </div>\n          )}\n        </div>\n      )}\n    </div>\n  );\n}\n\ntype MySitePreviewPlaceholderProps = {\n  hostLabel: string;\n};\n\n// Static placeholder shown in builder/preview contexts. Preview mode keeps\n// placeholder API values out of visible widget content.\nfunction MySitePreviewPlaceholder({\n  hostLabel,\n}: MySitePreviewPlaceholderProps): React.JSX.Element {\n  return (\n    <div className=\"bg-muted/30 absolute inset-0 flex flex-col items-center justify-center gap-3 p-4 text-center\">\n      <div className=\"bg-muted flex size-10 items-center justify-center rounded-full\">\n        <Globe className=\"text-muted-foreground size-5\" />\n      </div>\n      <div>\n        <p className=\"text-foreground text-sm font-medium\">MySite</p>\n        {hostLabel && (\n          <p className=\"text-muted-foreground mt-0.5 text-xs\">{hostLabel}</p>\n        )}\n      </div>\n    </div>\n  );\n}\n\ntype StatCellProps = {\n  label: string;\n  value: string;\n  textColor: ColorOptions;\n  leftDivider?: boolean;\n};\n\nfunction StatCell({ label, value, textColor, leftDivider }: StatCellProps) {\n  const leftDividerStyle: CSSProperties | undefined = leftDivider\n    ? {\n        borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n      }\n    : undefined;\n\n  return (\n    <div className=\"flex flex-col gap-1.5 px-5 py-4\" style={leftDividerStyle}>\n      <span\n        className={`text-[10px] font-bold tracking-[0.16em] uppercase text-${textColor}/55`}\n      >\n        {label}\n      </span>\n      <span\n        className={`text-[22px] leading-none font-bold tracking-[-0.02em] tabular-nums text-${textColor}`}\n      >\n        {value}\n      </span>\n    </div>\n  );\n}\n\ntype MySiteSkeletonProps = {\n  textColor: ColorOptions;\n  accentColor: ColorOptions;\n  borderRadius: BorderRadiusOptions;\n};\n\nfunction MySiteSkeleton({\n  textColor,\n  accentColor,\n  borderRadius,\n}: MySiteSkeletonProps) {\n  const divider: CSSProperties = {\n    borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n  };\n\n  return (\n    <div className=\"flex animate-pulse flex-col\" aria-busy=\"true\">\n      <div\n        className={`relative aspect-[16/10] w-full overflow-hidden bg-${textColor}/5`}\n      />\n\n      <div\n        className=\"flex items-stretch\"\n        style={{\n          borderTop: `1px solid color-mix(in oklch, var(--color-${textColor}) 10%, transparent)`,\n          background: `color-mix(in oklch, var(--color-${textColor}) 3%, transparent)`,\n        }}\n      >\n        {/* QR placeholder column */}\n        <div\n          className=\"flex shrink-0 items-center justify-center p-4\"\n          style={{\n            borderRight: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n          }}\n        >\n          <div\n            className={`size-[84px] rounded-${borderRadius} bg-${textColor}/10`}\n          />\n        </div>\n\n        <div className=\"flex min-w-0 flex-1 flex-col\">\n          <div className=\"grid grid-cols-2\">\n            {[0, 1].map((i) => (\n              <div\n                key={i}\n                className=\"flex flex-col gap-2 px-5 py-4\"\n                style={\n                  i > 0\n                    ? {\n                        borderLeft: `1px solid color-mix(in oklch, var(--color-${textColor}) 8%, transparent)`,\n                      }\n                    : undefined\n                }\n              >\n                <div className={`h-2 w-14 rounded-full bg-${textColor}/10`} />\n                <div className={`h-5 w-16 rounded-full bg-${textColor}/15`} />\n              </div>\n            ))}\n          </div>\n\n          <div className=\"flex items-center gap-2 px-4 py-3\" style={divider}>\n            <div\n              className={`h-8 flex-1 rounded-${borderRadius} bg-${textColor}/10`}\n            />\n            <div\n              className={`size-9 shrink-0 rounded-${borderRadius} bg-${accentColor}/30`}\n            />\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n\n// ----- Hooks -----\n\ntype CopyState = \"idle\" | \"copied\";\n\nfunction useRealMySiteData(mySite: MySiteData | undefined, isPreview: boolean) {\n  return useMemo(() => {\n    if (isPreview || !mySite?.url) {\n      return {\n        hasRealSite: false,\n        url: \"\",\n        views: 0,\n        leads: 0,\n        userName: \"\",\n      };\n    }\n\n    return {\n      hasRealSite: true,\n      url: mySite.url,\n      views: mySite.views,\n      leads: mySite.leads,\n      userName: mySite.userName,\n    };\n  }, [isPreview, mySite]);\n}\n\nfunction useMySiteDisplayUrls(url: string) {\n  const previewUrl = useMemo(() => {\n    if (!url) return \"\";\n    try {\n      const urlObj = new URL(url);\n      urlObj.searchParams.set(\"preview\", \"true\");\n      return urlObj.toString();\n    } catch {\n      return url;\n    }\n  }, [url]);\n\n  const hostLabel = useMemo(() => {\n    if (!url) return \"\";\n    try {\n      return new URL(url).host;\n    } catch {\n      return url.replace(/^https?:\\/\\//, \"\");\n    }\n  }, [url]);\n\n  const { prefix: urlPrefix, path: urlPath } = useMemo(\n    () => (url ? splitUrl(url) : { prefix: \"\", path: \"\" }),\n    [url],\n  );\n\n  return { previewUrl, hostLabel, urlPrefix, urlPath };\n}\n\nfunction useTimedCopyState(timeoutMs: number) {\n  const [copyState, setCopyState] = useState<CopyState>(\"idle\");\n\n  useEffect(() => {\n    if (copyState !== \"copied\") return;\n    const id = window.setTimeout(() => setCopyState(\"idle\"), timeoutMs);\n    return () => window.clearTimeout(id);\n  }, [copyState, timeoutMs]);\n\n  const markCopied = useCallback(() => {\n    setCopyState(\"copied\");\n  }, []);\n\n  return { copyState, markCopied };\n}\n\n// useLayoutEffect warns on the server. Widgets are client-rendered, but guard\n// for parity with the rest of the codebase.\nconst useIsoLayoutEffect =\n  typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n// Switches to a \"wide\" layout once the container reaches `threshold` px.\n// Uses useLayoutEffect so the initial measurement and state-flip land\n// synchronously before paint, avoiding a narrow→wide flash on mount.\nfunction useIsContainerWide(threshold: number) {\n  const rootRef = useRef<HTMLDivElement | null>(null);\n  const [isWide, setIsWide] = useState(false);\n\n  useIsoLayoutEffect(() => {\n    const el = rootRef.current;\n    if (!el) return;\n    const update = () => setIsWide(el.clientWidth >= threshold);\n    update();\n    const ro = new ResizeObserver(update);\n    ro.observe(el);\n    return () => ro.disconnect();\n  }, [threshold]);\n\n  return { rootRef, isWide };\n}\n\n// Allows the iframe to receive scroll/click events (so reps can scroll the\n// preview) while preventing any in-iframe navigation from sticking — when the\n// iframe fires a non-initial `load`, we reset it back to the original src.\n// Mirrors the snap-back used in PhonePreview.tsx (CURRENT-662).\nfunction useIframeNavigationLock(src: string) {\n  const iframeRef = useRef<HTMLIFrameElement>(null);\n  const isInitialLoadRef = useRef(true);\n\n  // Reset the initial-load flag whenever the src changes so the first load\n  // of a new src isn't treated as a navigation attempt. useLayoutEffect runs\n  // synchronously after the DOM mutation (before paint), so the flag is\n  // always set before any load event can fire — important for locally-served\n  // or `data:` preview URLs where the browser can fire `load` during commit.\n  useLayoutEffect(() => {\n    isInitialLoadRef.current = true;\n  }, [src]);\n\n  const handleIframeLoad = useCallback(() => {\n    if (isInitialLoadRef.current) {\n      isInitialLoadRef.current = false;\n      return;\n    }\n    const iframe = iframeRef.current;\n    if (!iframe) return;\n    isInitialLoadRef.current = true;\n    iframe.src = src;\n  }, [src]);\n\n  return { iframeRef, handleIframeLoad };\n}\n\ntype ScaledIframePreviewOptions = {\n  viewportWidth: number;\n  minIframeHeight: number;\n};\n\n// Renders the iframe at a real desktop viewport (`viewportWidth`) and scales\n// it to fit the actual container. The iframe's rendered height is computed\n// dynamically so it fills the container in both aspect-locked compact mode\n// AND the height-driven wide mode (no whitespace gap below the preview).\nfunction useScaledIframePreview({\n  viewportWidth,\n  minIframeHeight,\n}: ScaledIframePreviewOptions) {\n  const [metrics, setMetrics] = useState({\n    scale: 0.5,\n    iframeHeight: minIframeHeight,\n  });\n\n  const frameRef = useCallback(\n    (el: HTMLDivElement | null) => {\n      if (!el) return;\n      const update = () => {\n        const w = el.clientWidth;\n        const h = el.clientHeight;\n        if (w > 0 && h > 0) {\n          const scale = w / viewportWidth;\n          const iframeHeight = Math.max(minIframeHeight, h / scale);\n          setMetrics((prev) =>\n            prev.scale === scale && prev.iframeHeight === iframeHeight\n              ? prev\n              : { scale, iframeHeight },\n          );\n        }\n      };\n      update();\n      const ro = new ResizeObserver(update);\n      ro.observe(el);\n      return () => ro.disconnect();\n    },\n    [viewportWidth, minIframeHeight],\n  );\n\n  return { frameRef, scale: metrics.scale, iframeHeight: metrics.iframeHeight };\n}\n\nexport const mySiteWidgetPropertySchema: WidgetPropertySchema = {\n  widgetType: \"MySiteWidget\",\n  displayName: \"MySite Widget\",\n  tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n  fields: [\n    // Display group\n    {\n      key: \"showPreview\",\n      label: \"Show Site Preview\",\n      type: \"boolean\",\n      description: \"Show the live iframe preview of the storefront\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Display\",\n    },\n    {\n      key: \"showAnalytics\",\n      label: \"Show Stats\",\n      type: \"boolean\",\n      description: \"Visitors and Leads grid in the footer\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Display\",\n    },\n    {\n      key: \"showLiveBadge\",\n      label: \"Show LIVE Badge\",\n      type: \"boolean\",\n      description: \"Small 'Live' chip in the preview corner\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Display\",\n    },\n    {\n      key: \"showQR\",\n      label: \"Show QR Code\",\n      type: \"boolean\",\n      description: \"Show a scannable QR code in the card footer\",\n      defaultValue: true,\n      tab: \"styling\",\n      group: \"Display\",\n    },\n\n    // Design group\n    {\n      type: \"background\",\n      key: \"background\",\n      label: \"Background\",\n      description: \"Background for the widget container\",\n      defaultValue: { type: \"solid\", color: \"background\" },\n      tab: \"styling\",\n      group: \"Design\",\n    },\n    getColorField({\n      key: \"textColor\",\n      label: \"Text Color\",\n      description: \"Primary text, hairline, and neutral chip color\",\n      defaultValue: \"foreground\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    getColorField({\n      key: \"accentColor\",\n      label: \"Accent Color\",\n      description: \"Drives the Live dot, conversion ring, and Visit CTA\",\n      defaultValue: \"primary\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n    {\n      key: \"separator\",\n      type: \"separator\",\n      label: \"Separator\",\n      tab: \"styling\",\n      group: \"Design\",\n    },\n    getBorderRadiusField({\n      key: \"borderRadius\",\n      label: \"Border Radius\",\n      description: \"Corner radius for the widget and inner chips\",\n      defaultValue: \"xl\",\n      tab: \"styling\",\n      group: \"Design\",\n    }),\n  ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;;;;;AAEA,MAAa,eAA2B;CACtC,KAAK;CACL,OAAO;CACP,OAAO;CACP,UAAU;CACX;;;ACED,SAAgB,YAA+C;CAC7D,MAAM,aAAa,eAAe;CAClC,MAAM,EAAE,cAAc,yBAAyB;CAC/C,MAAM,EAAE,YAAY,6BAA6B;AAEjD,QAAO,SAAS;EACd,UAAU;GACR;GACA;GACA,YAAY,YAAY;GACzB;EACD,UAAU,EAAE,aAAa,WAAW,YAAY,OAAO;EACvD,SAAS,CAAC;EACV,GAAI,aAAa,EAAE,iBAAiB,cAAc;EACnD,CAAC;;;;;;;;ACmBJ,MAAM,uBAAuB,MAAkC;CAC7D,MAAM,QAAQ,KAAK;AACnB,KAAI,QAAQ,IAAM,QAAO,MAAM,gBAAgB;AAC/C,KAAI,QAAQ,IAAQ,QAAO,IAAI,QAAQ,KAAM,QAAQ,EAAE,CAAC;AACxD,KAAI,QAAQ,IAAW,QAAO,GAAG,KAAK,MAAM,QAAQ,IAAK,CAAC;AAC1D,QAAO,IAAI,QAAQ,KAAW,QAAQ,EAAE,CAAC;;AAG3C,MAAM,YAAY,QAAkD;AAClE,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,SAAO;GACL,QAAQ,GAAG,OAAO,SAAS,IAAI,OAAO;GACtC,MACE,GAAG,OAAO,WAAW,OAAO,SAAS,OAAO,OAAO,QACjD,QACA,GACD,IAAI;GACR;SACK;AACN,SAAO;GAAE,QAAQ;GAAI,MAAM;GAAK;;;AAIpC,SAAgB,aAAa,EAC3B,aAAa;CAAE,MAAM;CAAS,OAAO;CAAc,EACnD,YAAY,cACZ,cAAc,WACd,eAAe,MAEf,cAAc,MACd,gBAAgB,MAChB,gBAAgB,MAChB,SAAS,MAET,WACA,UAAU,WACV,YAAY,aACZ,GAAG,SAC2C;CAC9C,MAAM,EAAE,WAAW,eAAe,kBAAkB,KAAK;CACzD,MAAM,EAAE,SAAS,eAAe,WAAW,mBAAmB,IAAI;CAClE,MAAM,EACJ,UAAU,iBACV,OACA,iBACE,uBAAuB;EACzB,eAAe;EACf,iBAAiB;EAClB,CAAC;CACF,MAAM,kBAAkB,WAAW,SAAS;CAC5C,MAAM,mBACH,WAAW,UAAU,aAAa,WAAW,UAAU,aACxD,WAAW,SAAS,UAChB,OAAO,WAAW,SAAS,aAAa,WAAW,SAAS,SAAS,KACrE;CAEN,MAAM,EAAE,MAAM,QAAQ,WAAW,YAAY,WAAW;CACxD,MAAM,EAAE,cAAc,yBAAyB;CAE/C,MAAM,EAAE,aAAa,KAAK,OAAO,UADd,kBAAkB,QAAQ,UAAU;CAEvD,MAAM,EAAE,YAAY,WAAW,WAAW,YACxC,qBAAqB,IAAI;CAM3B,MAAM,EAAE,WAAW,qBAAqB,wBAAwB,WAAW;CAC3E,MAAM,sBAAsB,UAAU;CACtC,MAAM,YAAY,iBAAiB;CACnC,MAAM,aAAa;CAEnB,MAAM,aAAa,YAAY;AAC7B,MAAI,CAAC,IAAK;AACV,MAAI;AACF,SAAM,UAAU,UAAU,UAAU,IAAI;AACxC,eAAY;WACL,OAAO;AACd,WAAQ,MAAM,8BAA8B,MAAM;;;AAItD,KAAI,CAAC,aAAa,CAAC,WAAW,CAAC,aAAa,CAAC,YAC3C,QAAO;CAIT,MAAM,UAAyB,EAC7B,WAAW,6CAA6C,UAAU,qBACnE;AAED,QACE,oBAAC,OAAD;EACE,KAAK;EACL,WAAW,+CAA+C,aAAa,MAAM,gBAAgB,QAAQ,UAAU,GAAG,aAAa;EAC/H,OAAO;GACL;GACA,WAAW,yHAAyH,UAAU;GAC/I;EACD,GAAI;YAEH,YACC,oBAAC,gBAAD;GACa;GACE;GACC;GACd,CAAA,GACA,UACF,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,YAAD,EAAc,CAAA;GACV,CAAA,GACJ,sBACF,qBAAC,OAAD;GAAK,WAAU;aAAf,CAEG,eACC,qBAAC,OAAD;IACE,WAAU;IACV,OAAO;KACL,OAAO;KACP,aAAa,6CAA6C,UAAU;KACrE;cALH,CAOE,qBAAC,OAAD;KACE,KAAK;KACL,WAAU;eAFZ,CAIE,oBAAC,UAAD;MACE,KAAK;MACL,WAAU;MACV,KAAK;MACL,OAAO,GAAG,UAAU;MACpB,SAAQ;MACR,UAAU;MAKV,SAAQ;MACR,QAAQ;MACR,OAAO;OACL,OAAO;OACP,QAAQ,GAAG,aAAa;OACxB,WAAW,SAAS,MAAM;OAC3B;MACD,CAAA,EACF,oBAAC,OAAD;MACE,eAAY;MACZ,WAAU;MACV,OAAO,EACL,YACE,8EACH;MACD,CAAA,CACE;QAEL,iBACC,oBAAC,OAAD;KAAK,WAAU;eACb,qBAAC,QAAD;MACE,WAAW,4CAA4C,aAAa;MACpE,OAAO,EACL,WACE,sEACH;gBALH,CAOE,oBAAC,QAAD;OACE,eAAY;OACZ,WAAW,MAAM,YAAY;OAC7B,CAAA,EAAA,OAEG;;KACH,CAAA,CAEJ;OAIR,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,QAAD;MACE,WAAW,yDAAyD,UAAU;gBAC/E;MAEM,CAAA,EACP,oBAAC,MAAD;MACE,WAAW,oEAAoE;gBAChF;MAEI,CAAA,CACD,EAAA,CAAA;KAEL,eACC,qBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,cACE,cAAc,WACV,wBACA;MAEN,WAAW,gDAAgD,aAAa,gHAAgH,YAAY,MAAM,cAAc,WAAW,MAAM,YAAY,OAAO,MAAM,UAAU,cAAc,UAAU;MACpS,OAAO,EACL,WAAW,mDAAmD,UAAU,sBACzE;gBAXH;OAaE,oBAAC,OAAD,EAAO,WAAW,0BAA0B,UAAU,MAAQ,CAAA;OAC9D,qBAAC,QAAD;QACE,WAAW,qEAAqE;kBADlF,CAGG,WACA,QACI;;OACP,oBAAC,QAAD;QACE,WAAW,6FAA6F,cAAc,WAAW,MAAM,YAAY,QAAQ,YAAY,eAAe,MAAM,UAAU,QAAQ;kBAE7M,cAAc,WACb,oBAAC,OAAD,EAAO,WAAU,UAAW,CAAA,GAE5B,oBAAC,MAAD,EAAM,WAAU,UAAW,CAAA;QAExB,CAAA;OACA;;KAGV,aACC,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,OAAD,EACE,OAAO,EACL,WAAW,6CAA6C,UAAU,sBACnE,EACD,CAAA,EACF,qBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,OAAD;OACE,WAAW,0DAA0D,UAAU;iBAChF;OAEK,CAAA,EACN,oBAAC,OAAD;OACE,WAAW,gFAAgF;iBAE1F,oBAAoB,MAAM;OACvB,CAAA,CACF,EAAA,CAAA,EACN,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,OAAD;OACE,WAAW,0DAA0D,UAAU;iBAChF;OAEK,CAAA,EACN,oBAAC,OAAD;OACE,WAAW,gFAAgF;iBAE1F,oBAAoB,MAAM;OACvB,CAAA,CACF,EAAA,CAAA,CACF;QACL,EAAA,CAAA;KAGJ,eACC,qBAAC,KAAD;MACE,MAAM;MACN,QAAO;MACP,KAAI;MACJ,WAAW,8EAA8E,aAAa,MAAM,YAAY,wCAAwC,YAAY,wGAAwG,YAAY;gBAJlS,CAME,oBAAC,QAAD,EAAA,UAAM,sBAAyB,CAAA,EAC/B,oBAAC,cAAD,EAAc,WAAU,mHAAoH,CAAA,CAC1I;;KAEF;MACF;OAEN,qBAAC,OAAD;GAAK,WAAU;aAAf,CAEG,gBAAgB,eAAe,cAC9B,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,qBAAC,OAAD;KACE,KAAK;KACL,WAAU;eAFZ,CAIG,aAAa,CAAC,cACb,oBAAC,0BAAD,EAAqC,WAAa,CAAA,GAElD,oBAAC,UAAD;MACE,KAAK;MACL,WAAU;MACV,KAAK;MACL,OAAO,GAAG,UAAU;MACpB,SAAQ;MACR,UAAU;MACV,SAAQ;MACR,QAAQ;MACR,OAAO;OACL,OAAO;OACP,QAAQ,GAAG,aAAa;OACxB,WAAW,SAAS,MAAM;OAC3B;MACD,CAAA,EAGJ,oBAAC,OAAD;MACE,eAAY;MACZ,WAAU;MACV,OAAO,EACL,YACE,8EACH;MACD,CAAA,CACE;QAGL,iBAAiB,eAChB,oBAAC,OAAD;KAAK,WAAU;eACb,qBAAC,QAAD;MACE,WAAW,4CAA4C,aAAa;MACpE,OAAO,EACL,WACE,sEACH;gBALH,CAOE,oBAAC,QAAD;OACE,eAAY;OACZ,WAAW,MAAM,YAAY;OAC7B,CAAA,EAAA,OAEG;;KACH,CAAA,CAEJ;OAIP,cACC,qBAAC,OAAD;IACE,WAAU;IACV,OAAO;KACL,WAAW,6CAA6C,UAAU;KAClE,YAAY,mCAAmC,UAAU;KAC1D;cALH,CAQG,UAAU,eACT,oBAAC,OAAD;KACE,WAAU;KACV,OAAO,EACL,aAAa,6CAA6C,UAAU,qBACrE;eAED,oBAAC,OAAD;MACE,WAAW,8CAA8C,aAAa;MACtE,OAAO,EACL,WACE,sEACH;MACD,MAAK;MACL,cAAW;gBAEX,oBAAC,WAAD;OACE,OAAO;OACP,MAAM;OACN,OAAM;OACN,SAAQ;OACR,SAAQ;OACR,CAAA;MACE,CAAA;KACF,CAAA,EAIR,qBAAC,OAAD;KAAK,WAAU;eAAf,CAEG,aACC,qBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,oBAAC,UAAD;OACE,OAAM;OACN,OAAO,oBAAoB,MAAM;OACtB;OACX,CAAA,EACF,oBAAC,UAAD;OACE,OAAM;OACN,OAAO,oBAAoB,MAAM;OACtB;OACX,aAAA;OACA,CAAA,CACE;SAIP,eACC,qBAAC,OAAD;MACE,WAAU;MACV,OAAO,YAAY,UAAU,KAAA;gBAF/B,CAIE,qBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,cACE,cAAc,WACV,wBACA;OAEN,WAAW,6EAA6E,aAAa,0HAA0H,YAAY,MAAM,cAAc,WAAW,MAAM,YAAY,OAAO,MAAM,UAAU,cAAc,UAAU;OAC3U,OAAO,EACL,WAAW,mDAAmD,UAAU,qBACzE;iBAXH,CAaE,qBAAC,QAAD;QACE,WAAW,4CAA4C;kBADzD,CAGG,aACC,oBAAC,QAAD;SAAM,WAAW,QAAQ,UAAU;mBAChC;SACI,CAAA,EAET,oBAAC,QAAD;SAAM,WAAU;mBAAiB,WAAW;SAAW,CAAA,CAClD;WACP,oBAAC,QAAD;QACE,WAAW,6FAA6F,cAAc,WAAW,gBAAgB,YAAY,QAAQ,YAAY,eAAe,MAAM,UAAU,WAAW,UAAU,uBAAuB,UAAU;kBAErQ,cAAc,WACb,oBAAC,OAAD,EAAO,WAAU,UAAW,CAAA,GAE5B,oBAAC,MAAD,EAAM,WAAU,UAAW,CAAA;QAExB,CAAA,CACA;UAET,oBAAC,KAAD;OACE,MAAM;OACN,QAAO;OACP,KAAI;OACJ,cAAW;OACX,WAAW,+EAA+E,aAAa,MAAM,YAAY,QAAQ,YAAY,wGAAwG,YAAY;iBAEjQ,oBAAC,cAAD,EAAc,WAAU,mHAAoH,CAAA;OAC1I,CAAA,CACA;QAEJ;OACF;MAEJ;;EAEJ,CAAA;;AAUV,SAAS,yBAAyB,EAChC,aACmD;AACnD,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,OAAD,EAAO,WAAU,gCAAiC,CAAA;GAC9C,CAAA,EACN,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,KAAD;GAAG,WAAU;aAAsC;GAAU,CAAA,EAC5D,aACC,oBAAC,KAAD;GAAG,WAAU;aAAwC;GAAc,CAAA,CAEjE,EAAA,CAAA,CACF;;;AAWV,SAAS,SAAS,EAAE,OAAO,OAAO,WAAW,eAA8B;AAOzE,QACE,qBAAC,OAAD;EAAK,WAAU;EAAkC,OAPC,cAChD,EACE,YAAY,6CAA6C,UAAU,qBACpE,GACD,KAAA;YAGF,CACE,oBAAC,QAAD;GACE,WAAW,0DAA0D,UAAU;aAE9E;GACI,CAAA,EACP,oBAAC,QAAD;GACE,WAAW,2EAA2E;aAErF;GACI,CAAA,CACH;;;AAUV,SAAS,eAAe,EACtB,WACA,aACA,gBACsB;CACtB,MAAM,UAAyB,EAC7B,WAAW,6CAA6C,UAAU,qBACnE;AAED,QACE,qBAAC,OAAD;EAAK,WAAU;EAA8B,aAAU;YAAvD,CACE,oBAAC,OAAD,EACE,WAAW,qDAAqD,UAAU,KAC1E,CAAA,EAEF,qBAAC,OAAD;GACE,WAAU;GACV,OAAO;IACL,WAAW,6CAA6C,UAAU;IAClE,YAAY,mCAAmC,UAAU;IAC1D;aALH,CAQE,oBAAC,OAAD;IACE,WAAU;IACV,OAAO,EACL,aAAa,6CAA6C,UAAU,qBACrE;cAED,oBAAC,OAAD,EACE,WAAW,uBAAuB,aAAa,MAAM,UAAU,MAC/D,CAAA;IACE,CAAA,EAEN,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,OAAD;KAAK,WAAU;eACZ,CAAC,GAAG,EAAE,CAAC,KAAK,MACX,qBAAC,OAAD;MAEE,WAAU;MACV,OACE,IAAI,IACA,EACE,YAAY,6CAA6C,UAAU,qBACpE,GACD,KAAA;gBARR,CAWE,oBAAC,OAAD,EAAK,WAAW,4BAA4B,UAAU,MAAQ,CAAA,EAC9D,oBAAC,OAAD,EAAK,WAAW,4BAA4B,UAAU,MAAQ,CAAA,CAC1D;QAZC,EAYD,CACN;KACE,CAAA,EAEN,qBAAC,OAAD;KAAK,WAAU;KAAoC,OAAO;eAA1D,CACE,oBAAC,OAAD,EACE,WAAW,sBAAsB,aAAa,MAAM,UAAU,MAC9D,CAAA,EACF,oBAAC,OAAD,EACE,WAAW,2BAA2B,aAAa,MAAM,YAAY,MACrE,CAAA,CACE;OACF;MACF;KACF;;;AAQV,SAAS,kBAAkB,QAAgC,WAAoB;AAC7E,QAAO,cAAc;AACnB,MAAI,aAAa,CAAC,QAAQ,IACxB,QAAO;GACL,aAAa;GACb,KAAK;GACL,OAAO;GACP,OAAO;GACP,UAAU;GACX;AAGH,SAAO;GACL,aAAa;GACb,KAAK,OAAO;GACZ,OAAO,OAAO;GACd,OAAO,OAAO;GACd,UAAU,OAAO;GAClB;IACA,CAAC,WAAW,OAAO,CAAC;;AAGzB,SAAS,qBAAqB,KAAa;CACzC,MAAM,aAAa,cAAc;AAC/B,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;GACF,MAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,UAAO,aAAa,IAAI,WAAW,OAAO;AAC1C,UAAO,OAAO,UAAU;UAClB;AACN,UAAO;;IAER,CAAC,IAAI,CAAC;CAET,MAAM,YAAY,cAAc;AAC9B,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;AACF,UAAO,IAAI,IAAI,IAAI,CAAC;UACd;AACN,UAAO,IAAI,QAAQ,gBAAgB,GAAG;;IAEvC,CAAC,IAAI,CAAC;CAET,MAAM,EAAE,QAAQ,WAAW,MAAM,YAAY,cACpC,MAAM,SAAS,IAAI,GAAG;EAAE,QAAQ;EAAI,MAAM;EAAI,EACrD,CAAC,IAAI,CACN;AAED,QAAO;EAAE;EAAY;EAAW;EAAW;EAAS;;AAGtD,SAAS,kBAAkB,WAAmB;CAC5C,MAAM,CAAC,WAAW,gBAAgB,SAAoB,OAAO;AAE7D,iBAAgB;AACd,MAAI,cAAc,SAAU;EAC5B,MAAM,KAAK,OAAO,iBAAiB,aAAa,OAAO,EAAE,UAAU;AACnE,eAAa,OAAO,aAAa,GAAG;IACnC,CAAC,WAAW,UAAU,CAAC;AAM1B,QAAO;EAAE;EAAW,YAJD,kBAAkB;AACnC,gBAAa,SAAS;KACrB,EAAE,CAAC;EAE0B;;AAKlC,MAAM,qBACJ,OAAO,WAAW,cAAc,kBAAkB;AAKpD,SAAS,mBAAmB,WAAmB;CAC7C,MAAM,UAAU,OAA8B,KAAK;CACnD,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;AAE3C,0BAAyB;EACvB,MAAM,KAAK,QAAQ;AACnB,MAAI,CAAC,GAAI;EACT,MAAM,eAAe,UAAU,GAAG,eAAe,UAAU;AAC3D,UAAQ;EACR,MAAM,KAAK,IAAI,eAAe,OAAO;AACrC,KAAG,QAAQ,GAAG;AACd,eAAa,GAAG,YAAY;IAC3B,CAAC,UAAU,CAAC;AAEf,QAAO;EAAE;EAAS;EAAQ;;AAO5B,SAAS,wBAAwB,KAAa;CAC5C,MAAM,YAAY,OAA0B,KAAK;CACjD,MAAM,mBAAmB,OAAO,KAAK;AAOrC,uBAAsB;AACpB,mBAAiB,UAAU;IAC1B,CAAC,IAAI,CAAC;AAaT,QAAO;EAAE;EAAW,kBAXK,kBAAkB;AACzC,OAAI,iBAAiB,SAAS;AAC5B,qBAAiB,UAAU;AAC3B;;GAEF,MAAM,SAAS,UAAU;AACzB,OAAI,CAAC,OAAQ;AACb,oBAAiB,UAAU;AAC3B,UAAO,MAAM;KACZ,CAAC,IAAI,CAAC;EAE6B;;AAYxC,SAAS,uBAAuB,EAC9B,eACA,mBAC6B;CAC7B,MAAM,CAAC,SAAS,cAAc,SAAS;EACrC,OAAO;EACP,cAAc;EACf,CAAC;AA0BF,QAAO;EAAE,UAxBQ,aACd,OAA8B;AAC7B,OAAI,CAAC,GAAI;GACT,MAAM,eAAe;IACnB,MAAM,IAAI,GAAG;IACb,MAAM,IAAI,GAAG;AACb,QAAI,IAAI,KAAK,IAAI,GAAG;KAClB,MAAM,QAAQ,IAAI;KAClB,MAAM,eAAe,KAAK,IAAI,iBAAiB,IAAI,MAAM;AACzD,iBAAY,SACV,KAAK,UAAU,SAAS,KAAK,iBAAiB,eAC1C,OACA;MAAE;MAAO;MAAc,CAC5B;;;AAGL,WAAQ;GACR,MAAM,KAAK,IAAI,eAAe,OAAO;AACrC,MAAG,QAAQ,GAAG;AACd,gBAAa,GAAG,YAAY;KAE9B,CAAC,eAAe,gBAAgB,CACjC;EAEkB,OAAO,QAAQ;EAAO,cAAc,QAAQ;EAAc;;AAG/E,MAAa,6BAAmD;CAC9D,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ;EAEN;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR;EAGD;GACE,MAAM;GACN,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;IAAE,MAAM;IAAS,OAAO;IAAc;GACpD,KAAK;GACL,OAAO;GACR;EACD,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACD,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACH;CACF"}