// shared/publishers.ts
var PAYWALLED_PUBLISHERS = {
  "bloomberg.com": "Bloomberg",
  "wsj.com": "Wall Street Journal",
  "ft.com": "Financial Times",
  "economist.com": "The Economist"
};
var OUTLET_BY_HOST = {
  ...PAYWALLED_PUBLISHERS,
  "federalreserve.gov": "Federal Reserve",
  "reuters.com": "Reuters",
  "npr.org": "NPR",
  "bbc.com": "BBC",
  "theguardian.com": "The Guardian"
};
function normalizeHost(hostname) {
  return hostname.toLowerCase().replace(/^www\./, "");
}
function suggestOutlet(hostname) {
  const host = normalizeHost(hostname);
  if (OUTLET_BY_HOST[host]) return OUTLET_BY_HOST[host];
  for (const [domain, label] of Object.entries(OUTLET_BY_HOST)) {
    if (host.endsWith(`.${domain}`)) return label;
  }
  const parts = host.split(".").filter(Boolean);
  if (parts.length >= 2) {
    return parts[parts.length - 2].charAt(0).toUpperCase() + parts[parts.length - 2].slice(1);
  }
  return host;
}

// shared/types.ts
var MIN_TEXT_CHARS = 100;

// shared/extractors/domUtils.ts
function collapseWhitespace(input) {
  return input.replace(/\s+/g, " ").trim();
}
function textFromElement(el) {
  if (!el) return "";
  const clone = el.cloneNode(true);
  clone.querySelectorAll(
    [
      "script",
      "style",
      "noscript",
      "nav",
      "footer",
      "aside",
      "video",
      "audio",
      "figure video",
      ".ad",
      "[aria-hidden='true']",
      "[data-component='media-player']",
      "[data-component='social-share']",
      "[data-component='share-tools']",
      "[class*='share']",
      "[class*='ShareBar']",
      "[class*='video-player']",
      "[class*='VideoPlayer']",
      "[class*='newsletter']",
      "[class*='terminal-promo']",
      "[data-testid*='share']",
      "[data-testid*='video']"
    ].join(", ")
  ).forEach((n) => n.remove());
  return collapseWhitespace(clone.innerText ?? clone.textContent ?? "");
}
function metaContent(doc, selectors) {
  for (const sel of selectors) {
    const el = doc.querySelector(sel);
    const content = el?.getAttribute("content")?.trim();
    if (content) return collapseWhitespace(content);
  }
  return void 0;
}
function parseJsonLd(doc) {
  const nodes = [];
  doc.querySelectorAll('script[type="application/ld+json"]').forEach((script) => {
    try {
      const data = JSON.parse(script.textContent ?? "");
      if (Array.isArray(data)) nodes.push(...data.filter((n) => Boolean(n && typeof n === "object")));
      else if (data && typeof data === "object") nodes.push(data);
    } catch {
    }
  });
  return nodes;
}
function authorFromJsonLd(doc) {
  for (const node of parseJsonLd(doc)) {
    const author = node.author;
    if (typeof author === "string" && author.trim()) return collapseWhitespace(author);
    if (author && typeof author === "object" && !Array.isArray(author)) {
      const name = author.name;
      if (typeof name === "string" && name.trim()) return collapseWhitespace(name);
    }
    if (Array.isArray(author)) {
      for (const a of author) {
        if (typeof a === "string" && a.trim()) return collapseWhitespace(a);
        if (a && typeof a === "object" && typeof a.name === "string") {
          return collapseWhitespace(String(a.name));
        }
      }
    }
  }
  return void 0;
}
function titleFromJsonLd(doc) {
  for (const node of parseJsonLd(doc)) {
    const type = String(node["@type"] ?? "");
    if (!/NewsArticle|Article|Report/i.test(type)) continue;
    const headline = node.headline ?? node.name;
    if (typeof headline === "string" && headline.trim()) return collapseWhitespace(headline);
  }
  return void 0;
}
function bodyFromJsonLd(doc) {
  for (const node of parseJsonLd(doc)) {
    const type = String(node["@type"] ?? "");
    if (!/NewsArticle|Article|Report|WebPage/i.test(type)) continue;
    const body = node.articleBody ?? node.text ?? node.description;
    if (typeof body === "string" && body.trim().length >= MIN_TEXT_CHARS) {
      return collapseWhitespace(body.replace(/<[^>]+>/g, " "));
    }
  }
  return void 0;
}
function pickLongestText(candidates) {
  const valid = candidates.filter((c) => Boolean(c && c.length >= MIN_TEXT_CHARS));
  if (valid.length === 0) return void 0;
  return valid.reduce((best, cur) => cur.length > best.length ? cur : best);
}
function titleFromDocument(doc) {
  return titleFromJsonLd(doc) ?? metaContent(doc, ['meta[property="og:title"]', 'meta[name="twitter:title"]']) ?? collapseWhitespace(doc.title ?? "") ?? "Untitled article";
}
function authorFromDocument(doc) {
  return authorFromJsonLd(doc) ?? metaContent(doc, ['meta[name="author"]', 'meta[property="article:author"]', 'meta[name="dc.creator"]']) ?? doc.querySelector("[rel='author'], .byline, [data-testid='byline']")?.textContent?.trim();
}

// shared/extractors/sanitizePublisherText.ts
var CHROME_PATTERNS = [
  /Facebook\s*X\s*LinkedIn\s*Email\s*Link\s*Gift/gi,
  /FacebookXLinkedInEmailLinkGift/gi,
  /Gift this article/gi,
  /Add us on Google/gi,
  /Provide news feedback or report an error/gi,
  /Confidential tip\?/gi,
  /Send a tip to our reporters/gi,
  /Site feedback:\s*/gi,
  /Take our Survey/gi,
  /New Window/gi,
  /Bookmark\s*Save\s*Translate/gi,
  /BookmarkSaveTranslate/gi,
  /Video Player is loading\.?/gi,
  /\bUnmute\b/gi,
  /\bMute\b/gi,
  /Current Time\s*\d+:\d+/gi,
  /Loaded:\s*[\d.]+%/gi,
  /\d+x\s*Playback Rate/gi,
  /Playback Rate/gi,
  /captions off,?\s*selected/gi,
  /Share\s*Ad/gi,
  /Before it's here, it's on the Bloomberg Terminal/gi,
  /Bloomberg Terminal\s*LEARN MORE/gi,
  /\bLEARN MORE\b/gi,
  /Source:\s*Bloomberg/gi,
  /Politics(?=[A-Z])/g
];
var CHROME_SENTENCE_RE = /bloomberg terminal|gift this article|video player is loading|take our survey|playback rate|captions off|facebookxlinkedin|learn more|site feedback|confidential tip|add us on google/i;
function sanitizePublisherText(input) {
  let text = input.replace(/\u00a0/g, " ");
  for (const re of CHROME_PATTERNS) {
    text = text.replace(re, " ");
  }
  text = text.replace(/\bWATCH:\s*/gi, " ");
  const parts = text.split(/(?<=[.!?])\s+|\n+/).map((p) => collapseWhitespace(p)).filter((p) => p.length >= 20).filter((p) => !CHROME_SENTENCE_RE.test(p)).filter((p) => !isMostlyChromeTokens(p));
  if (parts.length === 0) {
    return collapseWhitespace(text);
  }
  return collapseWhitespace(parts.join(" "));
}
function isMostlyChromeTokens(sentence) {
  const lower = sentence.toLowerCase();
  const chromeHits = (lower.match(
    /\b(facebook|linkedin|unmute|mute|repost|bookmark|translate|survey|terminal|gift|share|ad)\b/g
  ) ?? []).length;
  const words = sentence.split(/\s+/).filter(Boolean).length;
  return words > 0 && chromeHits / words > 0.35;
}

// shared/extractors/bloomberg.ts
function extractBloomberg(doc, sourceUrl) {
  const title = titleFromDocument(doc);
  const author = authorFromDocument(doc);
  const jsonLd = bodyFromJsonLd(doc);
  const raw = jsonLd ?? pickLongestText([
    textFromElement(doc.querySelector("article[data-component='article']")),
    textFromElement(doc.querySelector('[data-component="body-content"]')),
    textFromElement(doc.querySelector(".body-content")),
    textFromElement(doc.querySelector("article"))
  ]) ?? "";
  const text = sanitizePublisherText(raw);
  if (text.length < 100) {
    return {
      ok: false,
      code: "insufficient_text",
      message: "Bloomberg article text not found. Make sure you are logged in and the full article is visible."
    };
  }
  return {
    ok: true,
    payload: {
      sourceUrl,
      title,
      text,
      author: author || void 0,
      sourceOutlet: "Bloomberg",
      voiceSegment: "journalist_obligation",
      contentKind: "article"
    }
  };
}

// shared/extractors/economist.ts
function extractEconomist(doc, sourceUrl) {
  const title = titleFromDocument(doc);
  const author = authorFromDocument(doc);
  const jsonLd = bodyFromJsonLd(doc);
  const raw = jsonLd ?? pickLongestText([
    textFromElement(doc.querySelector('[data-test-id="Article"]')),
    textFromElement(doc.querySelector(".article__body-text")),
    textFromElement(doc.querySelector("article"))
  ]) ?? "";
  const text = sanitizePublisherText(raw);
  if (text.length < 100) {
    return {
      ok: false,
      code: "insufficient_text",
      message: "Economist article text not found. Open the full article while logged in, then try again."
    };
  }
  return {
    ok: true,
    payload: {
      sourceUrl,
      title,
      text,
      author: author || void 0,
      sourceOutlet: "The Economist",
      voiceSegment: "journalist_obligation",
      contentKind: "article"
    }
  };
}

// shared/extractors/ft.ts
function extractFt(doc, sourceUrl) {
  const title = titleFromDocument(doc);
  const author = authorFromDocument(doc);
  const jsonLd = bodyFromJsonLd(doc);
  const raw = jsonLd ?? pickLongestText([
    textFromElement(doc.querySelector('[data-trackable="article-body"]')),
    textFromElement(doc.querySelector(".article__content-body")),
    textFromElement(doc.querySelector("article"))
  ]) ?? "";
  const text = sanitizePublisherText(raw);
  if (text.length < 100) {
    return {
      ok: false,
      code: "insufficient_text",
      message: "FT article text not found. Open the full article while logged in, then try again."
    };
  }
  return {
    ok: true,
    payload: {
      sourceUrl,
      title,
      text,
      author: author || void 0,
      sourceOutlet: "Financial Times",
      voiceSegment: "journalist_obligation",
      contentKind: "article"
    }
  };
}

// shared/extractors/generic.ts
function extractGeneric(doc, sourceUrl) {
  const hostname = new URL(sourceUrl).hostname;
  const title = titleFromDocument(doc);
  const author = authorFromDocument(doc);
  const jsonLd = bodyFromJsonLd(doc);
  const raw = jsonLd ?? pickLongestText([
    textFromElement(doc.querySelector("article")),
    textFromElement(doc.querySelector("main")),
    textFromElement(doc.querySelector("#content")),
    textFromElement(doc.querySelector('[role="main"]'))
  ]) ?? "";
  const text = sanitizePublisherText(raw);
  if (text.length < 100) {
    return {
      ok: false,
      code: "insufficient_text",
      message: "Could not extract enough article text. Select the article body and use the context menu, or paste manually in Sentinel."
    };
  }
  return {
    ok: true,
    payload: {
      sourceUrl,
      title,
      text,
      author: author || void 0,
      sourceOutlet: suggestOutlet(hostname),
      voiceSegment: "journalist_obligation",
      contentKind: "article"
    }
  };
}

// shared/extractors/wsj.ts
function extractWsj(doc, sourceUrl) {
  const title = titleFromDocument(doc);
  const author = authorFromDocument(doc);
  const jsonLd = bodyFromJsonLd(doc);
  const raw = jsonLd ?? pickLongestText([
    textFromElement(doc.querySelector('[data-module="ArticleBody"]')),
    textFromElement(doc.querySelector(".wsj-article-body")),
    textFromElement(doc.querySelector("article"))
  ]) ?? "";
  const text = sanitizePublisherText(raw);
  if (text.length < 100) {
    return {
      ok: false,
      code: "insufficient_text",
      message: "WSJ article text not found. Open the full article while logged in, then try again."
    };
  }
  return {
    ok: true,
    payload: {
      sourceUrl,
      title,
      text,
      author: author || void 0,
      sourceOutlet: "Wall Street Journal",
      voiceSegment: "journalist_obligation",
      contentKind: "article"
    }
  };
}

// shared/extractors/index.ts
function extractFromDocument(doc, sourceUrl) {
  let hostname;
  try {
    hostname = normalizeHost(new URL(sourceUrl).hostname);
  } catch {
    return { ok: false, code: "no_article", message: "Invalid page URL." };
  }
  if (hostname.includes("bloomberg.com")) return extractBloomberg(doc, sourceUrl);
  if (hostname.includes("wsj.com")) return extractWsj(doc, sourceUrl);
  if (hostname.includes("ft.com")) return extractFt(doc, sourceUrl);
  if (hostname.includes("economist.com")) return extractEconomist(doc, sourceUrl);
  return extractGeneric(doc, sourceUrl);
}
function extractFromSelection(doc, sourceUrl, selectionText) {
  const trimmed = sanitizePublisherText(selectionText.replace(/\s+/g, " ").trim());
  if (trimmed.length >= 100) {
    const hostname = normalizeHost(new URL(sourceUrl).hostname);
    return {
      ok: true,
      payload: {
        sourceUrl,
        title: titleFromDocument(doc),
        text: trimmed,
        sourceOutlet: suggestOutlet(hostname),
        voiceSegment: "journalist_obligation",
        contentKind: "article"
      }
    };
  }
  return extractFromDocument(doc, sourceUrl);
}

// chrome/content.ts
chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
  void (async () => {
    if (message.type === "EXTRACT_PAGE") {
      const outcome = extractFromDocument(document, location.href);
      const res = await chrome.runtime.sendMessage({ type: "CAPTURE_RESULT", outcome });
      sendResponse(res);
      return;
    }
    if (message.type === "EXTRACT_SELECTION") {
      const outcome = extractFromSelection(document, location.href, message.selectionText ?? "");
      const res = await chrome.runtime.sendMessage({ type: "CAPTURE_RESULT", outcome });
      sendResponse(res);
      return;
    }
    sendResponse({ ok: false, error: "Unknown content message" });
  })();
  return true;
});
//# sourceMappingURL=content.js.map
