'use strict';

var chunkOLISEQHS_cjs = require('./chunk-OLISEQHS.cjs');
var React6 = require('react');
require('@djangocfg/ui-core/styles/palette');
var jsxRuntime = require('react/jsx-runtime');
var ReactMarkdown = require('react-markdown');
var rehypeExternalLinks = require('rehype-external-links');
var rehypeRaw = require('rehype-raw');
var rehypeSanitize = require('rehype-sanitize');
var remarkBreaks = require('remark-breaks');
var remarkEmoji = require('remark-emoji');
var remarkGfm = require('remark-gfm');
var remarkSmartypants = require('remark-smartypants');
var components = require('@djangocfg/ui-core/components');
var hooks = require('@djangocfg/ui-core/hooks');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var React6__default = /*#__PURE__*/_interopDefault(React6);
var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
var rehypeExternalLinks__default = /*#__PURE__*/_interopDefault(rehypeExternalLinks);
var rehypeRaw__default = /*#__PURE__*/_interopDefault(rehypeRaw);
var rehypeSanitize__default = /*#__PURE__*/_interopDefault(rehypeSanitize);
var remarkBreaks__default = /*#__PURE__*/_interopDefault(remarkBreaks);
var remarkEmoji__default = /*#__PURE__*/_interopDefault(remarkEmoji);
var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
var remarkSmartypants__default = /*#__PURE__*/_interopDefault(remarkSmartypants);

function smartTruncate(content, maxLength) {
  if (content.length <= maxLength) {
    return content;
  }
  let breakPoint = maxLength;
  while (breakPoint > maxLength - 50 && breakPoint > 0) {
    const char = content[breakPoint];
    if (char === " " || char === "\n" || char === "	") {
      break;
    }
    breakPoint--;
  }
  if (breakPoint <= maxLength - 50) {
    breakPoint = maxLength;
  }
  let truncated = content.slice(0, breakPoint).trimEnd();
  truncated = fixUnclosedMarkdown(truncated);
  return truncated;
}
chunkOLISEQHS_cjs.__name(smartTruncate, "smartTruncate");
function truncateByLines(content, maxLines) {
  const lines = content.split("\n");
  if (lines.length <= maxLines) {
    return content;
  }
  let truncated = lines.slice(0, maxLines).join("\n").trimEnd();
  truncated = fixUnclosedMarkdown(truncated);
  return truncated;
}
chunkOLISEQHS_cjs.__name(truncateByLines, "truncateByLines");
function fixUnclosedMarkdown(content) {
  let result = content;
  const countOccurrences = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((str, marker) => {
    const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    const matches = str.match(new RegExp(escaped, "g"));
    return matches ? matches.length : 0;
  }, "countOccurrences");
  const boldCount = countOccurrences(result, "**");
  if (boldCount % 2 !== 0) {
    result += "**";
  }
  const withoutBold = result.replace(/\*\*/g, "");
  const italicCount = countOccurrences(withoutBold, "*");
  if (italicCount % 2 !== 0) {
    result += "*";
  }
  const codeCount = countOccurrences(result, "`");
  const tripleCount = countOccurrences(result, "```");
  const singleCodeCount = codeCount - tripleCount * 3;
  if (singleCodeCount % 2 !== 0) {
    result += "`";
  }
  if (tripleCount % 2 !== 0) {
    result += "\n```";
  }
  const strikeCount = countOccurrences(result, "~~");
  if (strikeCount % 2 !== 0) {
    result += "~~";
  }
  const underlineBoldCount = countOccurrences(result, "__");
  if (underlineBoldCount % 2 !== 0) {
    result += "__";
  }
  const withoutUnderlineBold = result.replace(/__/g, "");
  const underlineItalicCount = countOccurrences(withoutUnderlineBold, "_");
  if (underlineItalicCount % 2 !== 0) {
    result += "_";
  }
  return result;
}
chunkOLISEQHS_cjs.__name(fixUnclosedMarkdown, "fixUnclosedMarkdown");
function useCollapsibleContent(content, options = {}) {
  const { maxLength, maxLines, defaultExpanded = false } = options;
  const [isCollapsed, setIsCollapsed] = React6.useState(!defaultExpanded);
  const originalLength = content.length;
  const originalLineCount = content.split("\n").length;
  const { shouldCollapse, truncatedContent } = React6.useMemo(() => {
    if (maxLength === void 0 && maxLines === void 0) {
      return { shouldCollapse: false, truncatedContent: content };
    }
    let needsCollapse = false;
    let result = content;
    if (maxLines !== void 0 && originalLineCount > maxLines) {
      needsCollapse = true;
      result = truncateByLines(result, maxLines);
    }
    if (maxLength !== void 0 && result.length > maxLength) {
      needsCollapse = true;
      result = smartTruncate(result, maxLength);
    }
    return { shouldCollapse: needsCollapse, truncatedContent: result };
  }, [content, maxLength, maxLines, originalLineCount]);
  const displayContent = React6.useMemo(() => {
    if (!shouldCollapse || !isCollapsed) {
      return content;
    }
    return truncatedContent;
  }, [content, truncatedContent, shouldCollapse, isCollapsed]);
  const toggleCollapsed = React6.useCallback(() => {
    setIsCollapsed((prev) => !prev);
  }, []);
  const setCollapsed = React6.useCallback((collapsed) => {
    setIsCollapsed(collapsed);
  }, []);
  return {
    isCollapsed,
    toggleCollapsed,
    setCollapsed,
    displayContent,
    shouldCollapse,
    originalLength,
    originalLineCount
  };
}
chunkOLISEQHS_cjs.__name(useCollapsibleContent, "useCollapsibleContent");
function extractTextFromChildren(children) {
  if (typeof children === "string") return children;
  if (typeof children === "number") return String(children);
  if (React6__default.default.isValidElement(children)) {
    const props = children.props;
    return extractTextFromChildren(props.children);
  }
  if (Array.isArray(children)) {
    return children.map(extractTextFromChildren).join("");
  }
  return "";
}
chunkOLISEQHS_cjs.__name(extractTextFromChildren, "extractTextFromChildren");
function looksLikePlainProse(text) {
  const trimmed = text.trim();
  if (trimmed.length === 0) return true;
  if (trimmed.length > 500) return false;
  if (/\n\s*\n/.test(trimmed)) return false;
  const newlineCount = (trimmed.match(/\n/g) || []).length;
  if (newlineCount > 4) return false;
  if (hasMarkdownSyntax(trimmed)) return false;
  return true;
}
chunkOLISEQHS_cjs.__name(looksLikePlainProse, "looksLikePlainProse");
function hasMarkdownSyntax(text) {
  if (text.trim().includes("\n")) return true;
  if (/<\/?[a-zA-Z][a-zA-Z0-9-]*(\s[^>]*)?\/?>/.test(text)) return true;
  const patterns = [
    /^#{1,6}\s/m,
    // Headers
    /\*\*[^*]+\*\*/,
    // Bold
    /\*[^*]+\*/,
    // Italic
    /__[^_]+__/,
    // Bold (underscore)
    /_[^_]+_/,
    // Italic (underscore)
    /\[.+\]\(.+\)/,
    // Links
    /!\[.*\]\(.+\)/,
    // Images
    /```[\s\S]*```/,
    // Code blocks
    /`[^`]+`/,
    // Inline code
    /^\s*[-*+]\s/m,
    // Unordered lists
    /^\s*\d+\.\s/m,
    // Ordered lists
    /^\s*>/m,
    // Blockquotes
    /\|.+\|/,
    // Tables
    /^---+$/m,
    // Horizontal rules
    /~~[^~]+~~/
    // Strikethrough
  ];
  return patterns.some((p) => p.test(text));
}
chunkOLISEQHS_cjs.__name(hasMarkdownSyntax, "hasMarkdownSyntax");
var MermaidClient = React6.lazy(() => import('./Mermaid.client-NNTI6DFX.cjs'));
var LoadingFallback = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center items-center min-h-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-primary" }) }), "LoadingFallback");
var Mermaid = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((props) => {
  return /* @__PURE__ */ jsxRuntime.jsx(React6.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingFallback, {}), children: /* @__PURE__ */ jsxRuntime.jsx(MermaidClient, { ...props }) });
}, "Mermaid");
var Mermaid_default = Mermaid;
var PrettyCodeClient = React6.lazy(() => import('./PrettyCode.client-KOHDVPPN.cjs'));
var LoadingFallback2 = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative rounded-sm border border-border overflow-hidden bg-muted dark:bg-zinc-900", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-pulse h-4 w-4 rounded-full bg-muted-foreground/20" }),
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Loading code..." })
] }) }) }), "LoadingFallback");
var PrettyCode = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((props) => {
  return /* @__PURE__ */ jsxRuntime.jsx(React6.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingFallback2, {}), children: /* @__PURE__ */ jsxRuntime.jsx(PrettyCodeClient, { ...props }) });
}, "PrettyCode");
var PrettyCode_default = PrettyCode;
var HTML_SCHEMA_BASE = {
  ...rehypeSanitize.defaultSchema,
  tagNames: [
    ...rehypeSanitize.defaultSchema.tagNames ?? [],
    "br",
    "b",
    "i",
    "u",
    "s",
    "sub",
    "sup",
    "small",
    "mark",
    "kbd",
    "code",
    "pre",
    "details",
    "summary"
  ]
};
function buildSchema(extraProtocols) {
  if (!extraProtocols || extraProtocols.length === 0) return HTML_SCHEMA_BASE;
  const baseProtocols = HTML_SCHEMA_BASE.protocols ?? rehypeSanitize.defaultSchema.protocols ?? {};
  const baseHref = baseProtocols.href ?? ["http", "https", "mailto", "xmpp", "irc", "ircs"];
  return {
    ...HTML_SCHEMA_BASE,
    protocols: {
      ...baseProtocols,
      href: [...baseHref, ...extraProtocols]
    }
  };
}
chunkOLISEQHS_cjs.__name(buildSchema, "buildSchema");
function buildUrlTransform(extraProtocols) {
  if (!extraProtocols || extraProtocols.length === 0) return void 0;
  const lower = extraProtocols.map((p) => p.toLowerCase() + ":");
  return (url) => {
    const u = url.trim().toLowerCase();
    for (const p of lower) {
      if (u.startsWith(p)) return url;
    }
    if (/^(https?:|mailto:|tel:|xmpp:|irc:|ircs:|#|\/|\.\/|\.\.\/|\?)/i.test(u) || /^[a-z0-9._~!$&'()*+,;=:@%-]+$/i.test(u)) {
      return url;
    }
    return "";
  };
}
chunkOLISEQHS_cjs.__name(buildUrlTransform, "buildUrlTransform");
var CodeBlock = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ code, language }) => {
  const theme = hooks.useResolvedTheme();
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-2", children: /* @__PURE__ */ jsxRuntime.jsx(
    PrettyCode_default,
    {
      data: code,
      language,
      className: "text-xs",
      customBg: "bg-code",
      mode: theme,
      isCompact: true,
      scrollIsolation: false
    }
  ) });
}, "CodeBlock");
var CodeBlockFallback = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ code, isUser }) => {
  const copyHoverClass = isUser ? "hover:bg-white/20 text-white" : "hover:bg-muted-foreground/20 text-muted-foreground hover:text-foreground";
  const copyButtonClass = `absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity h-8 w-8 ${copyHoverClass}`;
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group my-3", children: [
    /* @__PURE__ */ jsxRuntime.jsx(
      components.CopyButton,
      {
        value: code,
        variant: "ghost",
        className: copyButtonClass,
        title: "Copy code"
      }
    ),
    /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "p-3 rounded text-xs font-mono overflow-x-auto bg-code text-code-foreground border border-code-border", children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code }) })
  ] });
}, "CodeBlockFallback");
function createMarkdownComponents(isUser = false, isCompact = false) {
  const textSize = isCompact ? "text-xs" : "text-sm";
  const headingBase = isCompact ? "text-sm" : "text-base";
  const headingSm = isCompact ? "text-xs" : "text-sm";
  return {
    h1: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { className: `${headingBase} font-semibold mb-2 mt-3 first:mt-0`, children }), "h1"),
    h2: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { className: `${headingSm} font-semibold mb-2 mt-3 first:mt-0`, children }), "h2"),
    h3: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h3", { className: `${headingSm} font-semibold mb-1 mt-2 first:mt-0`, children }), "h3"),
    h4: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h4", { className: `${headingSm} font-semibold mb-1 mt-2 first:mt-0`, children }), "h4"),
    h5: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h5", { className: `${headingSm} font-medium mb-1 mt-2 first:mt-0`, children }), "h5"),
    h6: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h6", { className: `${headingSm} font-medium mb-1 mt-2 first:mt-0`, children }), "h6"),
    p: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${textSize} mb-4 last:mb-0 leading-relaxed break-words`, children }), "p"),
    ul: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: `list-disc list-inside mb-2 space-y-1 ${textSize}`, children }), "ul"),
    ol: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: `list-decimal list-inside mb-2 space-y-1 ${textSize}`, children }), "ol"),
    li: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "break-words", children }), "li"),
    // `target` / `rel` for external links are NOT set here — the
    // rehype-external-links plugin tags them on the rehype side, so
    // every `<a>` that sanitize let through gets the same security
    // treatment regardless of which renderer (default vs linkRules
    // override) emitted it. Doing it twice here would just duplicate
    // attributes; doing it only here would miss the linkRules path.
    a: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ href, children, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx(
      "a",
      {
        ...rest,
        href,
        className: `${textSize} ${isUser ? "text-white/90 underline hover:text-white" : "text-primary underline hover:text-primary/80"} transition-colors break-all`,
        children
      }
    ), "a"),
    pre: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => {
      let codeContent = "";
      let language = "plaintext";
      if (React6__default.default.isValidElement(children)) {
        const child = children;
        if (child.type === "code" || typeof child.type === "function" && child.type.name === "code") {
          const codeProps = child.props;
          const rawClassName = codeProps.className;
          language = rawClassName?.replace(/language-/, "").trim() || "plaintext";
          codeContent = extractTextFromChildren(codeProps.children).trim();
        } else {
          codeContent = extractTextFromChildren(children).trim();
        }
      } else {
        codeContent = extractTextFromChildren(children).trim();
      }
      if (!codeContent) {
        return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-3 p-3 bg-muted rounded text-sm text-muted-foreground", children: "No content available" });
      }
      if (language === "mermaid") {
        return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-3 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(Mermaid_default, { chart: codeContent, isCompact }) });
      }
      try {
        return /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { code: codeContent, language, isUser, isCompact });
      } catch (error) {
        console.warn("CodeBlock failed, using fallback:", error);
        return /* @__PURE__ */ jsxRuntime.jsx(CodeBlockFallback, { code: codeContent, language, isUser, isCompact });
      }
    }, "pre"),
    code: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children, className }) => {
      if (className?.includes("language-")) {
        return /* @__PURE__ */ jsxRuntime.jsx("code", { className, children });
      }
      const inlineCodeClass = isUser ? "bg-primary-foreground/15 text-primary-foreground" : "bg-code-inline text-code-inline-foreground";
      return /* @__PURE__ */ jsxRuntime.jsx("code", { className: `px-1 py-0.5 rounded font-mono text-[0.875em] ${inlineCodeClass} break-all`, children: extractTextFromChildren(children) });
    }, "code"),
    // Modern chat convention drops italic on blockquotes — italic +
    // tight bubble = hard to read. Border-left at 2px (4px reads
    // heavy in a 320–480px bubble). On the saturated user bubble we
    // use a primary-foreground tint; on the assistant bubble we use
    // the muted-foreground role for de-emphasis.
    blockquote: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => {
      const cls = isUser ? "border-primary-foreground/40 text-primary-foreground/80" : "border-border text-muted-foreground";
      return /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: `${textSize} border-l-2 pl-3 my-3 break-words ${cls}`, children });
    }, "blockquote"),
    // Tables: outer wrapper handles overflow, inner `<table>`
    // inherits the chat-density text size. Borders / header use
    // semantic tokens — `border-code-border` for the assistant
    // (matches the code-fence panel for visual cohesion when both
    // appear in the same reply); primary-foreground/N for the user
    // bubble so lines read against the saturated `bg-primary`.
    table: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto my-3", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: `min-w-full ${textSize} border-collapse`, children }) }), "table"),
    thead: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("thead", { className: isUser ? "bg-primary-foreground/10" : "bg-muted/40", children }), "thead"),
    tbody: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("tbody", { children }), "tbody"),
    tr: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("tr", { className: isUser ? "border-b border-primary-foreground/15" : "border-b border-border", children }), "tr"),
    th: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => {
      const borderCls = isUser ? "border-primary-foreground/25" : "border-border";
      return /* @__PURE__ */ jsxRuntime.jsx("th", { className: `px-2 py-1.5 text-left font-semibold border-b ${borderCls} break-words`, children });
    }, "th"),
    td: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-2 py-1.5 break-words", children }), "td"),
    // Soft separator. ChatGPT / Slack / Linear strip the visible
    // line, Claude.ai keeps a hairline. We follow Claude — present
    // but quiet. Palette switches by role so the hairline reads on
    // both surfaces.
    hr: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => /* @__PURE__ */ jsxRuntime.jsx(
      "hr",
      {
        className: `my-4 border-0 h-px ${isUser ? "bg-primary-foreground/20" : "bg-border"}`
      }
    ), "hr"),
    strong: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-semibold", children }), "strong"),
    em: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx("em", { className: "italic", children }), "em")
  };
}
chunkOLISEQHS_cjs.__name(createMarkdownComponents, "createMarkdownComponents");
var CollapseToggle = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({
  isCollapsed,
  onClick,
  readMoreLabel,
  showLessLabel,
  isUser,
  isCompact
}) => {
  const textSize = isCompact ? "text-xs" : "text-sm";
  return /* @__PURE__ */ jsxRuntime.jsx(
    "button",
    {
      type: "button",
      onClick,
      className: `
        ${textSize} font-medium cursor-pointer
        transition-colors duration-200
        ${isUser ? "text-white/80 hover:text-white" : "text-primary hover:text-primary/80"}
        inline-flex items-center gap-1
        mt-1
      `,
      children: isCollapsed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
        readMoreLabel,
        /* @__PURE__ */ jsxRuntime.jsx(Chevron, { direction: "down" })
      ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
        showLessLabel,
        /* @__PURE__ */ jsxRuntime.jsx(Chevron, { direction: "up" })
      ] })
    }
  );
}, "CollapseToggle");
function Chevron({ direction }) {
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx(
    "path",
    {
      strokeLinecap: "round",
      strokeLinejoin: "round",
      strokeWidth: 2,
      d: direction === "down" ? "M19 9l-7 7-7-7" : "M5 15l7-7 7 7"
    }
  ) });
}
chunkOLISEQHS_cjs.__name(Chevron, "Chevron");
function applyPreprocess(source, rules) {
  if (!rules || rules.length === 0) return source;
  let s = source;
  for (const rule of rules) {
    if (!rule.preprocess) continue;
    try {
      s = rule.preprocess(s);
    } catch (err) {
      console.warn(
        `[MarkdownMessage] linkRule "${rule.name ?? "(anonymous)"}" preprocess threw; skipping`,
        err
      );
    }
  }
  return s;
}
chunkOLISEQHS_cjs.__name(applyPreprocess, "applyPreprocess");
function collectProtocols(extraHrefProtocols, rules) {
  const set = /* @__PURE__ */ new Set();
  if (extraHrefProtocols) for (const p of extraHrefProtocols) set.add(p);
  if (rules) {
    for (const r of rules) {
      if (r.protocols) for (const p of r.protocols) set.add(p);
    }
  }
  return set.size === 0 ? void 0 : Array.from(set);
}
chunkOLISEQHS_cjs.__name(collectProtocols, "collectProtocols");
function buildLinkRulesComponent(rules, isUser, callerA) {
  const Renderer = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((props) => {
    const { href, children } = props;
    if (typeof href === "string") {
      for (const rule of rules) {
        if (rule.match(href)) {
          return React6__default.default.createElement(
            React6__default.default.Fragment,
            null,
            rule.render({ href, children, isUser })
          );
        }
      }
    }
    if (callerA && typeof callerA === "function") {
      const Caller = callerA;
      return React6__default.default.createElement(Caller, props);
    }
    return React6__default.default.createElement("a", props, children);
  }, "Renderer");
  return Renderer;
}
chunkOLISEQHS_cjs.__name(buildLinkRulesComponent, "buildLinkRulesComponent");
var MarkdownMessage = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({
  content,
  className = "",
  isUser = false,
  isCompact = false,
  plainText,
  customComponents,
  extraHrefProtocols,
  linkRules,
  collapsible = false,
  maxLength,
  maxLines,
  readMoreLabel = "Read more...",
  showLessLabel = "Show less",
  defaultExpanded = false,
  onCollapseChange
}) => {
  const preprocessed = React6__default.default.useMemo(
    () => applyPreprocess(content, linkRules),
    [content, linkRules]
  );
  const effectiveProtocols = React6__default.default.useMemo(
    () => collectProtocols(extraHrefProtocols, linkRules),
    [extraHrefProtocols, linkRules]
  );
  const effectiveCustomComponents = React6__default.default.useMemo(() => {
    if (!linkRules || linkRules.length === 0) return customComponents;
    const callerA = customComponents?.a;
    const aRenderer = buildLinkRulesComponent(linkRules, isUser, callerA);
    return { ...customComponents ?? {}, a: aRenderer };
  }, [customComponents, linkRules, isUser]);
  const trimmedContent = preprocessed.trim();
  const collapsibleOptions = React6__default.default.useMemo(() => {
    if (!collapsible) return {};
    return {
      maxLength: maxLength ?? 1e3,
      maxLines: maxLines ?? 10,
      defaultExpanded
    };
  }, [collapsible, maxLength, maxLines, defaultExpanded]);
  const { isCollapsed, toggleCollapsed, displayContent, shouldCollapse } = useCollapsibleContent(trimmedContent, collapsible ? collapsibleOptions : {});
  React6__default.default.useEffect(() => {
    if (collapsible && shouldCollapse && onCollapseChange) {
      onCollapseChange(isCollapsed);
    }
  }, [isCollapsed, collapsible, shouldCollapse, onCollapseChange]);
  const components = React6__default.default.useMemo(() => {
    const base = createMarkdownComponents(isUser, isCompact);
    return effectiveCustomComponents ? { ...base, ...effectiveCustomComponents } : base;
  }, [isUser, isCompact, effectiveCustomComponents]);
  const schema = React6__default.default.useMemo(() => buildSchema(effectiveProtocols), [effectiveProtocols]);
  const urlTransform = React6__default.default.useMemo(
    () => buildUrlTransform(effectiveProtocols),
    [effectiveProtocols]
  );
  const textSizeClass = isCompact ? "text-xs" : "text-sm";
  const proseClass = isCompact ? "prose-xs" : "prose-sm";
  const customComponentsBeyondLinks = React6__default.default.useMemo(() => {
    if (!customComponents) return false;
    return Object.keys(customComponents).some((k) => k !== "a");
  }, [customComponents]);
  const isPlainText = plainText !== void 0 ? plainText : !customComponentsBeyondLinks && looksLikePlainProse(displayContent);
  if (isPlainText) {
    return /* @__PURE__ */ jsxRuntime.jsxs(
      "div",
      {
        className: `${textSizeClass} font-normal antialiased leading-snug break-words whitespace-pre-wrap ${className}`,
        children: [
          displayContent,
          collapsible && shouldCollapse && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
            isCollapsed && "... ",
            /* @__PURE__ */ jsxRuntime.jsx(
              CollapseToggle,
              {
                isCollapsed,
                onClick: toggleCollapsed,
                readMoreLabel,
                showLessLabel,
                isUser,
                isCompact
              }
            )
          ] })
        ]
      }
    );
  }
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
    /* @__PURE__ */ jsxRuntime.jsx(
      "div",
      {
        className: `
          prose ${proseClass} max-w-none break-words overflow-hidden ${textSizeClass} font-normal antialiased
          ${isUser ? "prose-invert" : "dark:prose-invert"}
          [&>*]:leading-relaxed
          [&>*:first-child]:mt-0 [&>*:last-child]:mb-0
          [&_p]:my-2
          [&_ul]:my-2 [&_ol]:my-2 [&_ul]:pl-5 [&_ol]:pl-5
          [&_li]:my-1 [&_li>p]:my-0
          [&_h1]:mt-4 [&_h1]:mb-2 [&_h1]:text-base [&_h1]:font-semibold
          [&_h2]:mt-3.5 [&_h2]:mb-1.5 [&_h2]:text-[15px] [&_h2]:font-semibold
          [&_h3]:mt-3 [&_h3]:mb-1 [&_h3]:text-sm [&_h3]:font-medium
          [&_h4]:mt-3 [&_h4]:mb-1 [&_h4]:text-sm [&_h4]:font-medium
        `,
        style: {
          // Inherit colors from parent — fixes issues with external
          // CSS variables overriding prose tokens.
          "--tw-prose-body": "inherit",
          "--tw-prose-headings": "inherit",
          "--tw-prose-bold": "inherit",
          "--tw-prose-links": "inherit",
          color: "inherit"
        },
        children: /* @__PURE__ */ jsxRuntime.jsx(
          ReactMarkdown__default.default,
          {
            remarkPlugins: [remarkGfm__default.default, remarkBreaks__default.default, remarkSmartypants__default.default, remarkEmoji__default.default],
            rehypePlugins: [
              rehypeRaw__default.default,
              [rehypeSanitize__default.default, schema],
              [rehypeExternalLinks__default.default, { target: "_blank", rel: ["noopener", "noreferrer"] }]
            ],
            components,
            urlTransform,
            children: displayContent
          }
        )
      }
    ),
    collapsible && shouldCollapse && /* @__PURE__ */ jsxRuntime.jsx(
      CollapseToggle,
      {
        isCollapsed,
        onClick: toggleCollapsed,
        readMoreLabel,
        showLessLabel,
        isUser,
        isCompact
      }
    )
  ] });
}, "MarkdownMessage");

exports.MarkdownMessage = MarkdownMessage;
exports.Mermaid_default = Mermaid_default;
exports.PrettyCode_default = PrettyCode_default;
exports.extractTextFromChildren = extractTextFromChildren;
exports.useCollapsibleContent = useCollapsibleContent;
//# sourceMappingURL=chunk-B5AWZOHJ.cjs.map
//# sourceMappingURL=chunk-B5AWZOHJ.cjs.map