{
  "version": 3,
  "sources": ["../src/browser.ts", "../src/lib/fuzzy.ts", "../src/lib/identity.ts", "../src/lib/revision-projection.ts", "../src/lib/anchor-context.ts", "../src/lib/confidence-calibration.ts", "../src/lib/reanchor-core.ts", "../src/lib/global-reconciliation.ts", "../src/lib/validate-core.ts", "../mrsf.schema.json", "../src/lib/schema.ts", "../src/lib/serialize.ts"],
  "sourcesContent": ["import * as fuzzy from \"./lib/fuzzy.js\";\nimport * as identity from \"./lib/identity.js\";\nimport * as reanchorCore from \"./lib/reanchor-core.js\";\nimport * as anchorContext from \"./lib/anchor-context.js\";\nimport * as globalReconciliation from \"./lib/global-reconciliation.js\";\nimport * as revisionProjection from \"./lib/revision-projection.js\";\nimport * as confidenceCalibration from \"./lib/confidence-calibration.js\";\nimport * as validateCore from \"./lib/validate-core.js\";\nimport * as serialize from \"./lib/serialize.js\";\nimport { mrsfSchema } from \"./lib/schema.js\";\n\nexport type {\n  AnchorPosition,\n  Comment,\n  DiffHunk,\n  FuzzyCandidate,\n  MrsfDocument,\n  ReanchorResult,\n  ReanchorStatus,\n  ValidationDiagnostic,\n  ValidationResult,\n  DiagnosticSeverity,\n} from \"./lib/types.js\";\nexport type { ParsedAuthor } from \"./lib/identity.js\";\nexport type { LenientParseResult } from \"./lib/serialize.js\";\n\n// Parse / serialize (pure string \u21C4 document; no filesystem or argv deps).\nexport const parseSidecarContent = serialize.parseSidecarContent;\nexport const parseSidecarContentLenient = serialize.parseSidecarContentLenient;\nexport const toYaml = serialize.toYaml;\nexport const toJson = serialize.toJson;\n\nexport const combinedScore = fuzzy.combinedScore;\nexport const exactMatch = fuzzy.exactMatch;\nexport const fuzzySearch = fuzzy.fuzzySearch;\nexport const levenshteinScore = fuzzy.levenshteinScore;\nexport const normalizedMatch = fuzzy.normalizedMatch;\nexport const tokenLcsScore = fuzzy.tokenLcsScore;\n\nexport const applyReanchorResults = reanchorCore.applyReanchorResults;\nexport const DEFAULT_THRESHOLD = reanchorCore.DEFAULT_THRESHOLD;\nexport const HIGH_THRESHOLD = reanchorCore.HIGH_THRESHOLD;\nexport const reanchorComment = reanchorCore.reanchorComment;\nexport const reanchorDocumentLines = reanchorCore.reanchorDocumentLines;\nexport const reanchorDocumentText = reanchorCore.reanchorDocumentText;\nexport const resolveAnchor = reanchorCore.resolveAnchor;\nexport const toReanchorLines = reanchorCore.toReanchorLines;\nexport const createAnchorContextIndex = anchorContext.createAnchorContextIndex;\nexport const reconcileCommentAnchors =\n  globalReconciliation.reconcileCommentAnchors;\nexport const createRevisionProjection =\n  revisionProjection.createRevisionProjection;\nexport const calibrateAnchorEvidence =\n  confidenceCalibration.calibrateAnchorEvidence;\nexport type {\n  AnchorContextIndex,\n  ContextAnchorCandidate,\n  ContextAnchorResolution,\n} from \"./lib/anchor-context.js\";\nexport type {\n  ProjectedAnchor,\n  RevisionProjectionIndex,\n} from \"./lib/revision-projection.js\";\nexport type {\n  CalibratedAnchor,\n  ConfidenceBand,\n} from \"./lib/confidence-calibration.js\";\n\nexport const validateDocument = validateCore.validateDocument;\nexport { mrsfSchema };\n\nexport const formatAuthor = identity.formatAuthor;\nexport const parseAuthor = identity.parseAuthor;\nexport const newCommentId = identity.newCommentId;\n", "/**\n * MRSF Fuzzy Matching Engine\n *\n * Provides exact, normalized, token-level LCS, and character-level\n * Levenshtein matching for re-anchoring selected_text.\n */\n\nimport { distance as levenshtein } from \"fastest-levenshtein\";\nimport type { FuzzyCandidate } from \"./types.js\";\n\nexport const MAX_FUZZY_CANDIDATE_LINES = 64;\n\nexport interface FuzzySearchIndex {\n  lines: string[];\n  tokenPostings: Map<string, number[]>;\n  trigramPostings: Map<string, number[]>;\n}\n\nexport function createFuzzySearchIndex(lines: string[]): FuzzySearchIndex {\n  const tokenPostings = new Map<string, number[]>();\n  const trigramPostings = new Map<string, number[]>();\n  for (let line = 1; line < lines.length; line += 1) {\n    addPostingSignals(tokenPostings, lexicalTokens(lines[line]), line);\n    addPostingSignals(trigramPostings, characterTrigrams(lines[line]), line);\n  }\n  return { lines, tokenPostings, trigramPostings };\n}\n\n// ---------------------------------------------------------------------------\n// Exact matching\n// ---------------------------------------------------------------------------\n\n/**\n * Find all exact occurrences of `needle` in lines (1-based array).\n */\nexport function exactMatch(\n  lines: string[],\n  needle: string,\n): FuzzyCandidate[] {\n  if (!needle) return [];\n\n  const results: FuzzyCandidate[] = [];\n  const needleLines = needle.split(\"\\n\");\n  const needleLineCount = needleLines.length;\n\n  // Slide a window across the document\n  for (let startLine = 1; startLine <= lines.length - needleLineCount; startLine++) {\n    // Build the text for this window\n    const windowLines = lines.slice(startLine, startLine + needleLineCount);\n    const windowText = windowLines.join(\"\\n\");\n\n    // Check if the needle appears anywhere within this window (for single-line)\n    if (needleLineCount === 1) {\n      let col = 0;\n      const line = windowLines[0];\n      while (col < line.length) {\n        const idx = line.indexOf(needle, col);\n        if (idx === -1) break;\n        results.push({\n          text: needle,\n          line: startLine,\n          endLine: startLine,\n          startColumn: idx,\n          endColumn: idx + needle.length,\n          score: 1.0,\n        });\n        col = idx + 1;\n      }\n    } else {\n      // Multi-line: check if the window contains the exact needle\n      const idx = windowText.indexOf(needle);\n      if (idx !== -1) {\n        // Calculate start column\n        const beforeMatch = windowText.slice(0, idx);\n        const linesBeforeEnd = beforeMatch.split(\"\\n\");\n        const startCol = linesBeforeEnd[linesBeforeEnd.length - 1].length;\n\n        // Calculate end column\n        const afterMatch = needle.split(\"\\n\");\n        const endCol = afterMatch[afterMatch.length - 1].length;\n        if (startCol === 0 || linesBeforeEnd.length === 1) {\n          results.push({\n            text: needle,\n            line: startLine + linesBeforeEnd.length - 1,\n            endLine: startLine + linesBeforeEnd.length - 1 + afterMatch.length - 1,\n            startColumn: startCol,\n            endColumn: endCol,\n            score: 1.0,\n          });\n        }\n      }\n    }\n  }\n\n  return results;\n}\n\n// ---------------------------------------------------------------------------\n// Normalized matching (collapse whitespace)\n// ---------------------------------------------------------------------------\n\nfunction normalize(text: string): string {\n  return text.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Find matches after normalizing whitespace.\n */\nexport function normalizedMatch(\n  lines: string[],\n  needle: string,\n): FuzzyCandidate[] {\n  const normNeedle = normalize(needle);\n  if (!normNeedle) return [];\n\n  const results: FuzzyCandidate[] = [];\n\n  // Try expanding windows of varying sizes\n  const needleLineEstimate = needle.split(\"\\n\").length;\n  const minWindow = Math.max(1, needleLineEstimate - 1);\n  const maxWindow = Math.min(lines.length - 1, needleLineEstimate + 2);\n\n  for (let winSize = minWindow; winSize <= maxWindow; winSize++) {\n    for (let startLine = 1; startLine + winSize - 1 < lines.length; startLine++) {\n      const windowLines = lines.slice(startLine, startLine + winSize);\n      const windowText = windowLines.join(\"\\n\");\n      const normWindow = normalize(windowText);\n\n      if (normWindow.includes(normNeedle)) {\n        results.push({\n          text: windowText,\n          line: startLine,\n          endLine: startLine + winSize - 1,\n          startColumn: 0,\n          endColumn: windowLines[windowLines.length - 1].length,\n          score: 0.95,\n        });\n      }\n    }\n  }\n\n  return deduplicateCandidates(results);\n}\n\n// ---------------------------------------------------------------------------\n// Token-level LCS\n// ---------------------------------------------------------------------------\n\nfunction tokenize(text: string): string[] {\n  return text.split(/\\s+/).filter((t) => t.length > 0);\n}\n\n/**\n * Longest Common Subsequence length of two token arrays.\n */\nfunction lcsLength(a: string[], b: string[]): number {\n  const m = a.length;\n  const n = b.length;\n  // Optimize: use two rows instead of full matrix\n  let prev = new Array<number>(n + 1).fill(0);\n  let curr = new Array<number>(n + 1).fill(0);\n\n  for (let i = 1; i <= m; i++) {\n    for (let j = 1; j <= n; j++) {\n      if (a[i - 1] === b[j - 1]) {\n        curr[j] = prev[j - 1] + 1;\n      } else {\n        curr[j] = Math.max(prev[j], curr[j - 1]);\n      }\n    }\n    [prev, curr] = [curr, prev];\n    curr.fill(0);\n  }\n\n  return prev[n];\n}\n\n/**\n * Score two texts using token-level LCS.\n * Returns 0.0\u20131.0.\n */\nexport function tokenLcsScore(a: string, b: string): number {\n  const tokA = tokenize(a);\n  const tokB = tokenize(b);\n  if (tokA.length === 0 && tokB.length === 0) return 1.0;\n  if (tokA.length === 0 || tokB.length === 0) return 0.0;\n  const lcs = lcsLength(tokA, tokB);\n  return lcs / Math.max(tokA.length, tokB.length);\n}\n\n// ---------------------------------------------------------------------------\n// Character-level Levenshtein score\n// ---------------------------------------------------------------------------\n\n/**\n * Normalized Levenshtein similarity 0.0\u20131.0.\n */\nexport function levenshteinScore(a: string, b: string): number {\n  if (a.length === 0 && b.length === 0) return 1.0;\n  const maxLen = Math.max(a.length, b.length);\n  if (maxLen === 0) return 1.0;\n  const dist = levenshtein(a, b);\n  return 1 - dist / maxLen;\n}\n\n// ---------------------------------------------------------------------------\n// Combined fuzzy scoring\n// ---------------------------------------------------------------------------\n\n/**\n * Compute a combined similarity score between two text fragments.\n * Blends token LCS (structural) and Levenshtein (character-level).\n */\nexport function combinedScore(needle: string, candidate: string): number {\n  const tScore = tokenLcsScore(needle, candidate);\n\n  // Full Levenshtein is expensive for long texts; only use for short ones\n  let lScore: number;\n  if (needle.length < 500 && candidate.length < 500) {\n    lScore = levenshteinScore(needle, candidate);\n  } else {\n    lScore = tScore; // fall back to token score only\n  }\n\n  // Weight: 60% token LCS, 40% Levenshtein\n  return tScore * 0.6 + lScore * 0.4;\n}\n\n// ---------------------------------------------------------------------------\n// Fuzzy search across document\n// ---------------------------------------------------------------------------\n\n/**\n * Search the document for fuzzy matches of `needle`.\n *\n * @param lines     1-based line array (index 0 unused).\n * @param needle    The original selected_text.\n * @param threshold Minimum score to include (0.0\u20131.0).\n * @param hintLine  Optional original line number for proximity scoring.\n */\nexport function fuzzySearch(\n  lines: string[],\n  needle: string,\n  threshold: number = 0.6,\n  hintLine?: number,\n  index?: FuzzySearchIndex,\n): FuzzyCandidate[] {\n  return fuzzySearchThresholds(\n    lines,\n    needle,\n    [threshold],\n    hintLine,\n    index,\n  ).get(threshold) ?? [];\n}\n\n/**\n * Compute fuzzy candidates once and partition them by their unadjusted\n * similarity thresholds. Proximity remains a ranking bonus and does not make\n * a candidate eligible for a threshold it did not originally satisfy.\n */\nexport function fuzzySearchThresholds(\n  lines: string[],\n  needle: string,\n  thresholds: number[],\n  hintLine?: number,\n  index: FuzzySearchIndex = createFuzzySearchIndex(lines),\n): Map<number, FuzzyCandidate[]> {\n  const uniqueThresholds = [...new Set(thresholds)];\n  const results = new Map<number, FuzzyCandidate[]>();\n  if (uniqueThresholds.length === 0) return results;\n  if (!needle) {\n    for (const threshold of uniqueThresholds) results.set(threshold, []);\n    return results;\n  }\n\n  const needleLines = needle.split(\"\\n\");\n  const needleLineCount = needleLines.length;\n  const candidates: FuzzyCandidate[] = [];\n  const minimumThreshold = Math.min(...uniqueThresholds);\n  const candidateLines = retrieveCandidateLines(index, needle, hintLine);\n\n  // Window sizes: \u00B130% of original line count, minimum 1\n  const minWindow = Math.max(1, Math.floor(needleLineCount * 0.7));\n  const maxWindow = Math.min(\n    lines.length - 1,\n    Math.ceil(needleLineCount * 1.3) + 1,\n  );\n\n  for (let winSize = minWindow; winSize <= maxWindow; winSize++) {\n    const startLines = new Set<number>();\n    for (const candidateLine of candidateLines) {\n      for (let offset = 0; offset < winSize; offset += 1) {\n        const startLine = candidateLine - offset;\n        if (startLine >= 1 && startLine + winSize - 1 < lines.length) {\n          startLines.add(startLine);\n        }\n      }\n    }\n    for (const startLine of startLines) {\n      const windowLines = lines.slice(startLine, startLine + winSize);\n      const windowText = windowLines.join(\"\\n\");\n\n      const score = combinedScore(needle, windowText);\n\n      if (score >= minimumThreshold) {\n        candidates.push({\n          text: windowText,\n          line: startLine,\n          endLine: startLine + winSize - 1,\n          startColumn: 0,\n          endColumn: windowLines[windowLines.length - 1].length,\n          score,\n        });\n      }\n    }\n  }\n\n  // For single-line needles, also try substring matching within each line\n  if (needleLineCount === 1 && needle.length < 200) {\n    for (const lineNum of candidateLines) {\n      const line = lines[lineNum];\n      if (!line) continue;\n\n      const winLen = needle.length;\n      const minWinLen = Math.max(3, Math.floor(winLen * 0.7));\n      const maxWinLen = Math.min(line.length, Math.ceil(winLen * 1.3));\n      const lengths = evenlySpacedIntegers(minWinLen, maxWinLen, 7);\n      for (const len of lengths) {\n        for (let col = 0; col + len <= line.length; col++) {\n          const sub = line.substring(col, col + len);\n          const score = combinedScore(needle, sub);\n          if (score >= minimumThreshold) {\n            candidates.push({\n              text: sub,\n              line: lineNum,\n              endLine: lineNum,\n              startColumn: col,\n              endColumn: col + len,\n              score,\n            });\n          }\n        }\n      }\n    }\n  }\n\n  const deduped = deduplicateCandidates(candidates);\n  const scored = deduped.map((candidate) => ({\n    baseScore: candidate.score,\n    candidate: applyProximityBonus(candidate, hintLine),\n  }));\n\n  for (const threshold of uniqueThresholds) {\n    results.set(\n      threshold,\n      scored\n        .filter((item) => item.baseScore >= threshold)\n        .map((item) => item.candidate)\n        .sort((left, right) => right.score - left.score),\n    );\n  }\n\n  return results;\n}\n\nfunction retrieveCandidateLines(\n  index: FuzzySearchIndex,\n  needle: string,\n  hintLine?: number,\n): number[] {\n  const votes = new Map<number, number>();\n  const lineCount = Math.max(0, index.lines.length - 1);\n  const signals = [\n    ...postingSignals(index.tokenPostings, lexicalTokens(needle), 2),\n    ...postingSignals(index.trigramPostings, characterTrigrams(needle), 1),\n  ]\n    .sort((left, right) => left.postings.length - right.postings.length)\n    .slice(0, 16);\n\n  for (const signal of signals) {\n    const rarity = Math.log1p(lineCount / signal.postings.length);\n    for (const line of signal.postings) {\n      votes.set(line, (votes.get(line) ?? 0) + signal.weight * rarity);\n    }\n  }\n\n  if (hintLine != null) {\n    for (let offset = -4; offset <= 4; offset += 1) {\n      const line = hintLine + offset;\n      if (line >= 1 && line <= lineCount) {\n        votes.set(line, (votes.get(line) ?? 0) + 0.25);\n      }\n    }\n  }\n\n  if (votes.size === 0) {\n    return Array.from({ length: lineCount }, (_, index) => index + 1);\n  }\n\n  return [...votes.entries()]\n    .sort((left, right) =>\n      right[1] - left[1]\n      || distanceFromHint(left[0], hintLine) - distanceFromHint(right[0], hintLine)\n      || left[0] - right[0]\n    )\n    .slice(0, MAX_FUZZY_CANDIDATE_LINES)\n    .map(([line]) => line);\n}\n\nfunction postingSignals(\n  postings: Map<string, number[]>,\n  values: string[],\n  weight: number,\n): Array<{ postings: number[]; weight: number }> {\n  return [...new Set(values)]\n    .map((value) => ({ postings: postings.get(value) ?? [], weight }))\n    .filter((signal) => signal.postings.length > 0);\n}\n\nfunction addPostingSignals(\n  postings: Map<string, number[]>,\n  values: string[],\n  line: number,\n): void {\n  for (const value of new Set(values)) {\n    const lines = postings.get(value);\n    if (lines) {\n      lines.push(line);\n    } else {\n      postings.set(value, [line]);\n    }\n  }\n}\n\nfunction lexicalTokens(text: string): string[] {\n  return text.toLowerCase().match(/[\\p{L}\\p{N}_-]+/gu) ?? [];\n}\n\nfunction characterTrigrams(text: string): string[] {\n  const normalized = text.toLowerCase().replace(/\\s+/g, \" \").trim();\n  const characters = [...normalized];\n  if (characters.length < 3) return normalized ? [normalized] : [];\n  const trigrams: string[] = [];\n  for (let index = 0; index <= characters.length - 3; index += 1) {\n    trigrams.push(characters.slice(index, index + 3).join(\"\"));\n  }\n  return trigrams;\n}\n\nfunction evenlySpacedIntegers(\n  minimum: number,\n  maximum: number,\n  count: number,\n): number[] {\n  if (maximum <= minimum) return [minimum];\n  const values = new Set<number>();\n  for (let index = 0; index < count; index += 1) {\n    values.add(Math.round(minimum + (maximum - minimum) * index / (count - 1)));\n  }\n  return [...values];\n}\n\nfunction distanceFromHint(line: number, hintLine?: number): number {\n  return hintLine == null ? 0 : Math.abs(line - hintLine);\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction deduplicateCandidates(\n  candidates: FuzzyCandidate[],\n): FuzzyCandidate[] {\n  const seen = new Map<string, FuzzyCandidate>();\n  for (const c of candidates) {\n    const key = `${c.line}:${c.startColumn}:${c.endLine}:${c.endColumn}`;\n    const existing = seen.get(key);\n    if (!existing || c.score > existing.score) {\n      seen.set(key, c);\n    }\n  }\n  return Array.from(seen.values());\n}\n\nfunction applyProximityBonus(\n  candidate: FuzzyCandidate,\n  hintLine?: number,\n): FuzzyCandidate {\n  if (hintLine == null) return candidate;\n\n  const distance = Math.abs(candidate.line - hintLine);\n  const proximityBonus = 0.1 * Math.max(0, 1 - distance / 50);\n  return {\n    ...candidate,\n    score: Math.min(1.0, candidate.score + proximityBonus),\n  };\n}\n", "import { v4 as uuidv4 } from \"uuid\";\n\nexport interface ParsedAuthor {\n  name: string;\n  handle?: string;\n}\n\nexport function formatAuthor(name: string, handle?: string): string {\n  const trimmedName = name.trim();\n  const trimmedHandle = handle?.trim();\n  return trimmedHandle ? `${trimmedName} (${trimmedHandle})` : trimmedName;\n}\n\nexport function parseAuthor(author: string): ParsedAuthor {\n  const trimmed = author.trim();\n  const match = /^(.*?)\\s*\\(([^()]*)\\)\\s*$/.exec(trimmed);\n  if (!match) return { name: trimmed };\n\n  const name = match[1].trim();\n  const handle = match[2].trim();\n  return handle ? { name, handle } : { name };\n}\n\n/**\n * Create a collision-resistant MRSF comment id.\n * ULID is also permitted by the spec; UUIDv4 is the default for this package.\n */\nexport function newCommentId(): string {\n  return uuidv4();\n}\n", "import { combinedScore, exactMatch } from \"./fuzzy.js\";\nimport type { Comment } from \"./types.js\";\n\nconst CONTEXT_RADIUS = 8;\n\nexport interface RevisionProjectionIndex {\n  sourceLines: string[];\n  targetLines: string[];\n  lineMap: Map<number, number>;\n}\n\nexport interface ProjectedAnchor {\n  line: number;\n  endLine: number;\n  startColumn?: number;\n  endColumn?: number;\n  text: string;\n  score: number;\n  exact: boolean;\n  contextSupport: number;\n  contextMargin: number;\n  reason: string;\n}\n\nexport function createRevisionProjection(\n  sourceLines: string[],\n  targetLines: string[],\n): RevisionProjectionIndex {\n  const sourceOccurrences = collectLineOccurrences(sourceLines);\n  const targetOccurrences = collectLineOccurrences(targetLines);\n  const lineMap = new Map<number, number>();\n\n  for (const [text, sourceLineNumbers] of sourceOccurrences) {\n    const targetLineNumbers = targetOccurrences.get(text);\n    if (sourceLineNumbers.length === 1 && targetLineNumbers?.length === 1) {\n      lineMap.set(sourceLineNumbers[0], targetLineNumbers[0]);\n    }\n  }\n\n  return { sourceLines, targetLines, lineMap };\n}\n\nexport function projectCommentAnchor(\n  comment: Comment,\n  projection: RevisionProjectionIndex,\n  threshold: number,\n): ProjectedAnchor | undefined {\n  if (comment.line == null || !comment.selected_text) return undefined;\n\n  const sourceText = extractText(\n    projection.sourceLines,\n    comment.line,\n    comment.end_line,\n    comment.start_column,\n    comment.end_column,\n  );\n  if (sourceText !== comment.selected_text) return undefined;\n\n  const exactCandidates = exactMatch(\n    projection.targetLines,\n    comment.selected_text,\n  );\n  if (exactCandidates.length === 1) {\n    const candidate = exactCandidates[0];\n    const contextSupport = countIndependentExactSupport(\n      comment,\n      candidate.line,\n      projection,\n    );\n    if (contextSupport >= 2) {\n      return {\n        line: candidate.line,\n        endLine: candidate.endLine,\n        startColumn: candidate.startColumn,\n        endColumn: candidate.endColumn,\n        text: candidate.text,\n        score: 1,\n        exact: true,\n        contextSupport,\n        contextMargin: 1,\n        reason: \"Source revision and neighboring line evidence confirm exact relocation.\",\n      };\n    }\n  }\n  if (exactCandidates.length > 0) return undefined;\n\n  const projected = projectLineFromContext(comment, projection);\n  if (projected == null) return undefined;\n  const projectedLine = projected.line;\n\n  const lineSpan = (comment.end_line ?? comment.line) - comment.line;\n  const projectedEndLine = projectedLine + lineSpan;\n  if (\n    projectedLine < 1\n    || projectedEndLine >= projection.targetLines.length\n  ) {\n    return undefined;\n  }\n\n  const columns = projectColumns(comment, projection, projectedLine);\n  const targetText = extractText(\n    projection.targetLines,\n    projectedLine,\n    projectedEndLine,\n    columns.startColumn,\n    columns.endColumn,\n  );\n  if (targetText == null) return undefined;\n\n  const score = Math.min(\n    1,\n    combinedScore(comment.selected_text, targetText) + 0.1,\n  );\n  if (score < threshold) return undefined;\n\n  return {\n    line: projectedLine,\n    endLine: projectedEndLine,\n    startColumn: columns.startColumn,\n    endColumn: columns.endColumn,\n    text: targetText,\n    score,\n    exact: targetText === comment.selected_text,\n    contextSupport: projected.support,\n    contextMargin: projected.margin,\n    reason: \"Source revision context projects the edited anchor range.\",\n  };\n}\n\nfunction collectLineOccurrences(lines: string[]): Map<string, number[]> {\n  const occurrences = new Map<string, number[]>();\n\n  for (let line = 1; line < lines.length; line += 1) {\n    const text = lines[line];\n    if (!text.trim()) continue;\n    const existing = occurrences.get(text);\n    if (existing) {\n      existing.push(line);\n    } else {\n      occurrences.set(text, [line]);\n    }\n  }\n\n  return occurrences;\n}\n\nfunction countIndependentExactSupport(\n  comment: Comment,\n  candidateLine: number,\n  projection: RevisionProjectionIndex,\n): number {\n  const sourceEndLine = comment.end_line ?? (comment.line as number);\n  const expectedShift = candidateLine - (comment.line as number);\n\n  if (\n    comment.start_column != null\n    || comment.end_column != null\n  ) {\n    const mappedContainerLine = projection.lineMap.get(comment.line as number);\n    if (mappedContainerLine === candidateLine) return 2;\n  }\n\n  let support = 0;\n  for (\n    let distance = 1;\n    distance <= CONTEXT_RADIUS;\n    distance += 1\n  ) {\n    for (const sourceLine of [\n      (comment.line as number) - distance,\n      sourceEndLine + distance,\n    ]) {\n      if (sourceLine < 1 || sourceLine >= projection.sourceLines.length) {\n        continue;\n      }\n      const targetLine = projection.lineMap.get(sourceLine);\n      if (targetLine != null && targetLine - sourceLine === expectedShift) {\n        support += 1;\n      }\n    }\n  }\n\n  return support;\n}\n\nfunction projectLineFromContext(\n  comment: Comment,\n  projection: RevisionProjectionIndex,\n): { line: number; support: number; margin: number } | undefined {\n  const sourceLine = comment.line as number;\n  const sourceEndLine = comment.end_line ?? sourceLine;\n  const votes = new Map<number, { count: number; nearest: number }>();\n\n  for (let distance = 1; distance <= CONTEXT_RADIUS; distance += 1) {\n    for (const contextLine of [\n      sourceLine - distance,\n      sourceEndLine + distance,\n    ]) {\n      if (contextLine < 1 || contextLine >= projection.sourceLines.length) {\n        continue;\n      }\n      const targetLine = projection.lineMap.get(contextLine);\n      if (targetLine == null) continue;\n      const shift = targetLine - contextLine;\n      const vote = votes.get(shift);\n      if (vote) {\n        vote.count += 1;\n        vote.nearest = Math.min(vote.nearest, distance);\n      } else {\n        votes.set(shift, { count: 1, nearest: distance });\n      }\n    }\n  }\n\n  const ranked = [...votes.entries()].sort((left, right) =>\n    right[1].count - left[1].count\n    || left[1].nearest - right[1].nearest\n    || Math.abs(left[0]) - Math.abs(right[0])\n  );\n  const best = ranked[0];\n  if (!best) return undefined;\n  if (best[1].count < 2 && best[1].nearest > 3) return undefined;\n  if (\n    ranked[1]\n    && ranked[1][1].count === best[1].count\n    && ranked[1][1].nearest === best[1].nearest\n  ) {\n    return undefined;\n  }\n\n  const runnerUpCount = ranked[1]?.[1].count ?? 0;\n  return {\n    line: sourceLine + best[0],\n    support: best[1].count,\n    margin: (best[1].count - runnerUpCount) / best[1].count,\n  };\n}\n\nfunction projectColumns(\n  comment: Comment,\n  projection: RevisionProjectionIndex,\n  targetLine: number,\n): { startColumn?: number; endColumn?: number } {\n  if (\n    comment.line == null\n    || (comment.end_line != null && comment.end_line !== comment.line)\n    || comment.start_column == null\n    || comment.end_column == null\n  ) {\n    return {\n      startColumn: comment.start_column,\n      endColumn: comment.end_column,\n    };\n  }\n\n  const sourceLine = projection.sourceLines[comment.line];\n  const targetLineText = projection.targetLines[targetLine];\n  const prefix = sourceLine.slice(0, comment.start_column);\n  const suffix = sourceLine.slice(comment.end_column);\n  const startColumn = targetLineText.startsWith(prefix)\n    ? prefix.length\n    : Math.min(comment.start_column, targetLineText.length);\n  const endColumn = targetLineText.endsWith(suffix)\n    ? targetLineText.length - suffix.length\n    : Math.min(\n      targetLineText.length,\n      startColumn + (comment.end_column - comment.start_column),\n    );\n\n  return { startColumn, endColumn };\n}\n\nfunction extractText(\n  lines: string[],\n  line: number,\n  endLine?: number,\n  startColumn?: number,\n  endColumn?: number,\n): string | null {\n  const finalLine = endLine ?? line;\n  if (line < 1 || finalLine >= lines.length) return null;\n\n  if (line === finalLine) {\n    const text = lines[line];\n    return startColumn != null && endColumn != null\n      ? text.slice(startColumn, endColumn)\n      : text;\n  }\n\n  const result: string[] = [];\n  for (let current = line; current <= finalLine; current += 1) {\n    let text = lines[current];\n    if (current === line && startColumn != null) text = text.slice(startColumn);\n    if (current === finalLine && endColumn != null) text = text.slice(0, endColumn);\n    result.push(text);\n  }\n  return result.join(\"\\n\");\n}\n", "import { combinedScore } from \"./fuzzy.js\";\nimport type { Comment, ReanchorStatus } from \"./types.js\";\n\nconst MATCH_THRESHOLD = 0.35;\nconst AMBIGUITY_MARGIN = 0.03;\nexport const MAX_CONTEXT_CANDIDATE_BLOCKS = 64;\n\ntype BlockType =\n  | \"heading\"\n  | \"code\"\n  | \"list\"\n  | \"table\"\n  | \"blockquote\"\n  | \"paragraph\";\n\ninterface MarkdownBlock {\n  startLine: number;\n  endLine: number;\n  type: BlockType;\n  text: string;\n  headingPath: string[];\n}\n\ninterface DocumentBlockIndex {\n  lines: string[];\n  blocks: MarkdownBlock[];\n  lineToBlock: Map<number, number>;\n  tokenPostings: Map<string, number[]>;\n}\n\ninterface CandidateWindow {\n  startBlock: number;\n  endBlock: number;\n  startLine: number;\n  endLine: number;\n  type: BlockType;\n  text: string;\n  headingPath: string[];\n  score: number;\n}\n\nexport interface AnchorContextIndex {\n  source: DocumentBlockIndex;\n  target: DocumentBlockIndex;\n}\n\nexport interface ContextAnchorResolution {\n  status: Extract<ReanchorStatus, \"anchored\" | \"fuzzy\" | \"ambiguous\" | \"orphaned\">;\n  score: number;\n  line?: number;\n  endLine?: number;\n  startColumn?: number;\n  endColumn?: number;\n  text?: string;\n  candidateMargin: number;\n  reason: string;\n}\n\nexport interface ContextAnchorCandidate {\n  score: number;\n  line: number;\n  endLine: number;\n  startColumn?: number;\n  endColumn?: number;\n  text: string;\n  exact: boolean;\n}\n\nexport function createAnchorContextIndex(\n  sourceLines: string[],\n  targetLines: string[],\n): AnchorContextIndex {\n  return {\n    source: createDocumentBlockIndex(sourceLines),\n    target: createDocumentBlockIndex(targetLines),\n  };\n}\n\nexport function resolveContextAnchor(\n  comment: Comment,\n  index: AnchorContextIndex,\n): ContextAnchorResolution | undefined {\n  if (comment.line == null || !comment.selected_text) return undefined;\n  const sourceBlockIndex = index.source.lineToBlock.get(comment.line);\n  if (sourceBlockIndex == null) return undefined;\n  const sourceBlock = index.source.blocks[sourceBlockIndex];\n  const sourceText = extractText(\n    index.source.lines,\n    comment.line,\n    comment.end_line,\n    comment.start_column,\n    comment.end_column,\n  );\n  if (sourceText !== comment.selected_text) return undefined;\n  const textAtCurrentPosition = extractText(\n    index.target.lines,\n    comment.line,\n    comment.end_line,\n    comment.start_column,\n    comment.end_column,\n  );\n  if (textAtCurrentPosition === comment.selected_text) {\n    return {\n      status: \"anchored\",\n      score: 1,\n      line: comment.line,\n      endLine: comment.end_line ?? comment.line,\n      startColumn: comment.start_column,\n      endColumn: comment.end_column,\n      text: comment.selected_text,\n      candidateMargin: 1,\n      reason: \"Source-verified anchor remains exact at its stored position.\",\n    };\n  }\n\n  const candidates = findContextAnchorCandidates(comment, index);\n  const best = candidates[0];\n  if (!best) {\n    if (\n      index.target.lines.slice(1).join(\"\\n\").includes(comment.selected_text)\n    ) {\n      return undefined;\n    }\n    return {\n      status: \"orphaned\",\n      score: 0,\n      candidateMargin: 1,\n      reason: \"Source block has no plausible structural or contextual match.\",\n    };\n  }\n\n  if (candidates[1] && best.score - candidates[1].score < AMBIGUITY_MARGIN) {\n    return {\n      status: \"ambiguous\",\n      score: best.score,\n      line: best.line,\n      endLine: best.endLine,\n      candidateMargin: best.score - candidates[1].score,\n      reason:\n        `Structural candidates are too close (${best.score.toFixed(3)} vs `\n        + `${candidates[1].score.toFixed(3)}).`,\n    };\n  }\n\n  const repeatedExactText = best.exact\n    && countOccurrences(\n      index.target.lines.slice(1).join(\"\\n\"),\n      comment.selected_text,\n    ) > 1;\n  return {\n    status: best.exact && !repeatedExactText ? \"anchored\" : \"fuzzy\",\n    score: best.exact && !repeatedExactText ? 1 : best.score,\n    line: best.line,\n    endLine: best.endLine,\n    startColumn: best.startColumn,\n    endColumn: best.endColumn,\n    text: best.text,\n    candidateMargin: candidates[1] ? best.score - candidates[1].score : 1,\n    reason: best.exact && !repeatedExactText\n      ? \"Markdown structure and bidirectional context disambiguate the exact anchor.\"\n      : repeatedExactText\n        ? \"Markdown context selects one repeated exact anchor tentatively.\"\n        : \"Markdown structure and bidirectional context locate the edited anchor.\",\n  };\n}\n\nexport function findContextAnchorCandidates(\n  comment: Comment,\n  index: AnchorContextIndex,\n): ContextAnchorCandidate[] {\n  if (comment.line == null || !comment.selected_text) return [];\n  const sourceBlockIndex = index.source.lineToBlock.get(comment.line);\n  if (sourceBlockIndex == null) return [];\n  const sourceBlock = index.source.blocks[sourceBlockIndex];\n  const sourceText = extractText(\n    index.source.lines,\n    comment.line,\n    comment.end_line,\n    comment.start_column,\n    comment.end_column,\n  );\n  if (sourceText !== comment.selected_text) return [];\n\n  return createCandidateWindows(\n    sourceBlock,\n    sourceBlockIndex,\n    comment.line,\n    index,\n  )\n    .map((candidate) => ({\n      ...candidate,\n      score: scoreCandidate(\n        sourceBlock,\n        sourceBlockIndex,\n        candidate,\n        index,\n        comment.line as number,\n      ),\n    }))\n    .filter((candidate) => candidate.score >= MATCH_THRESHOLD)\n    .sort((left, right) =>\n      right.score - left.score\n      || Math.abs(left.startLine - (comment.line as number))\n        - Math.abs(right.startLine - (comment.line as number))\n    )\n    .map((candidate) => {\n      const range = resolveCandidateRange(\n        comment,\n        sourceBlock,\n        candidate,\n        index.target,\n      );\n      return {\n        score: candidate.score,\n        line: range.line,\n        endLine: range.endLine,\n        startColumn: range.startColumn,\n        endColumn: range.endColumn,\n        text: range.text,\n        exact: range.text === comment.selected_text,\n      };\n    });\n}\n\nexport function getAnchorContextScope(\n  comment: Comment,\n  index: AnchorContextIndex,\n): string | undefined {\n  if (comment.line == null) return undefined;\n  const blockIndex = index.source.lineToBlock.get(comment.line);\n  if (blockIndex == null) return undefined;\n  return index.source.blocks[blockIndex].headingPath.join(\"\\u001f\");\n}\n\nfunction createDocumentBlockIndex(lines: string[]): DocumentBlockIndex {\n  const blocks: MarkdownBlock[] = [];\n  const lineToBlock = new Map<number, number>();\n  const headings: Array<{ level: number; title: string }> = [];\n  let line = 1;\n\n  while (line < lines.length) {\n    if (!lines[line].trim()) {\n      line += 1;\n      continue;\n    }\n\n    const startLine = line;\n    const marker = classifyLine(lines[line]);\n    if (marker.type === \"heading\") {\n      while (\n        headings.length > 0\n        && headings[headings.length - 1].level >= marker.headingLevel\n      ) {\n        headings.pop();\n      }\n      const block = makeBlock(\n        lines,\n        startLine,\n        startLine,\n        \"heading\",\n        headings.map((heading) => heading.title),\n      );\n      blocks.push(block);\n      headings.push({ level: marker.headingLevel, title: marker.headingTitle });\n      line += 1;\n      continue;\n    }\n\n    if (marker.type === \"code\") {\n      line += 1;\n      while (line < lines.length && !lines[line].trimStart().startsWith(\"```\")) {\n        line += 1;\n      }\n      if (line < lines.length) line += 1;\n    } else {\n      line += 1;\n      while (\n        line < lines.length\n        && lines[line].trim()\n        && continuesBlock(marker.type, lines[line])\n      ) {\n        line += 1;\n      }\n    }\n\n    blocks.push(makeBlock(\n      lines,\n      startLine,\n      line - 1,\n      marker.type,\n      headings.map((heading) => heading.title),\n    ));\n  }\n\n  for (const [blockIndex, block] of blocks.entries()) {\n    for (let blockLine = block.startLine; blockLine <= block.endLine; blockLine += 1) {\n      lineToBlock.set(blockLine, blockIndex);\n    }\n  }\n\n  return {\n    lines,\n    blocks,\n    lineToBlock,\n    tokenPostings: createTokenPostings(blocks),\n  };\n}\n\nfunction makeBlock(\n  lines: string[],\n  startLine: number,\n  endLine: number,\n  type: BlockType,\n  headingPath: string[],\n): MarkdownBlock {\n  return {\n    startLine,\n    endLine,\n    type,\n    text: lines.slice(startLine, endLine + 1).join(\"\\n\"),\n    headingPath,\n  };\n}\n\nfunction classifyLine(line: string): {\n  type: BlockType;\n  headingLevel: number;\n  headingTitle: string;\n} {\n  const heading = line.match(/^(#{1,6})\\s+(.+)$/);\n  if (heading) {\n    return {\n      type: \"heading\",\n      headingLevel: heading[1].length,\n      headingTitle: heading[2].trim(),\n    };\n  }\n  if (line.trimStart().startsWith(\"```\")) {\n    return { type: \"code\", headingLevel: 0, headingTitle: \"\" };\n  }\n  if (/^\\s*(?:[-*+]|\\d+\\.)\\s+/.test(line)) {\n    return { type: \"list\", headingLevel: 0, headingTitle: \"\" };\n  }\n  if (/^\\s*\\|/.test(line)) {\n    return { type: \"table\", headingLevel: 0, headingTitle: \"\" };\n  }\n  if (/^\\s*>/.test(line)) {\n    return { type: \"blockquote\", headingLevel: 0, headingTitle: \"\" };\n  }\n  return { type: \"paragraph\", headingLevel: 0, headingTitle: \"\" };\n}\n\nfunction continuesBlock(type: BlockType, line: string): boolean {\n  if (type === \"list\") return /^\\s*(?:[-*+]|\\d+\\.)\\s+/.test(line);\n  if (type === \"table\") return /^\\s*\\|/.test(line);\n  if (type === \"blockquote\") return /^\\s*>/.test(line);\n  if (type === \"paragraph\") {\n    const next = classifyLine(line);\n    return next.type === \"paragraph\";\n  }\n  return false;\n}\n\nfunction createCandidateWindows(\n  sourceBlock: MarkdownBlock,\n  sourceBlockIndex: number,\n  originalLine: number,\n  index: AnchorContextIndex,\n): CandidateWindow[] {\n  const target = index.target;\n  const candidates: CandidateWindow[] = [];\n\n  for (const start of retrieveCandidateBlocks(\n    sourceBlock,\n    sourceBlockIndex,\n    originalLine,\n    index,\n  )) {\n    const block = target.blocks[start];\n    candidates.push(toCandidateWindow(target, start, start));\n\n    if (\n      sourceBlock.type === \"paragraph\"\n      && block.type === \"paragraph\"\n      && target.blocks[start + 1]?.type === \"paragraph\"\n      && samePath(block.headingPath, target.blocks[start + 1].headingPath)\n    ) {\n      candidates.push(toCandidateWindow(target, start, start + 1));\n    }\n  }\n\n  return candidates;\n}\n\nfunction createTokenPostings(\n  blocks: MarkdownBlock[],\n): Map<string, number[]> {\n  const postings = new Map<string, number[]>();\n  for (const [blockIndex, block] of blocks.entries()) {\n    for (const token of new Set(tokenize(block.text))) {\n      const blocksForToken = postings.get(token);\n      if (blocksForToken) {\n        blocksForToken.push(blockIndex);\n      } else {\n        postings.set(token, [blockIndex]);\n      }\n    }\n  }\n  return postings;\n}\n\n/**\n * Retrieve a small candidate pool using rare content tokens and directional\n * neighbor evidence. Expensive similarity scoring is bounded to this pool.\n */\nfunction retrieveCandidateBlocks(\n  sourceBlock: MarkdownBlock,\n  sourceBlockIndex: number,\n  originalLine: number,\n  index: AnchorContextIndex,\n): number[] {\n  const votes = new Map<number, number>();\n  const targetCount = index.target.blocks.length;\n  const addEvidence = (\n    text: string | undefined,\n    targetOffset: number,\n    weight: number,\n  ): void => {\n    if (!text) return;\n    const rankedTokens = [...new Set(tokenize(text))]\n      .map((token) => ({\n        token,\n        postings: index.target.tokenPostings.get(token) ?? [],\n      }))\n      .filter((item) => item.postings.length > 0)\n      .sort((left, right) => left.postings.length - right.postings.length)\n      .slice(0, 12);\n\n    for (const { postings } of rankedTokens) {\n      const rarity = Math.log1p(targetCount / postings.length);\n      for (const posting of postings) {\n        const candidate = posting + targetOffset;\n        if (candidate >= 0 && candidate < targetCount) {\n          votes.set(candidate, (votes.get(candidate) ?? 0) + weight * rarity);\n        }\n      }\n    }\n  };\n\n  addEvidence(sourceBlock.text, 0, 1);\n  addEvidence(index.source.blocks[sourceBlockIndex - 1]?.text, 1, 0.7);\n  addEvidence(index.source.blocks[sourceBlockIndex + 1]?.text, -1, 0.7);\n\n  const nearbyBlock = closestBlockToLine(index.target.blocks, originalLine);\n  if (nearbyBlock != null) {\n    for (let offset = -2; offset <= 2; offset += 1) {\n      const candidate = nearbyBlock + offset;\n      if (candidate >= 0 && candidate < targetCount) {\n        votes.set(candidate, (votes.get(candidate) ?? 0) + 0.25);\n      }\n    }\n  }\n\n  return [...votes.entries()]\n    .sort((left, right) =>\n      right[1] - left[1]\n      || Math.abs(index.target.blocks[left[0]].startLine - originalLine)\n        - Math.abs(index.target.blocks[right[0]].startLine - originalLine)\n      || left[0] - right[0]\n    )\n    .slice(0, MAX_CONTEXT_CANDIDATE_BLOCKS)\n    .map(([blockIndex]) => blockIndex);\n}\n\nfunction closestBlockToLine(\n  blocks: MarkdownBlock[],\n  line: number,\n): number | undefined {\n  if (blocks.length === 0) return undefined;\n  let low = 0;\n  let high = blocks.length - 1;\n  while (low <= high) {\n    const middle = Math.floor((low + high) / 2);\n    const block = blocks[middle];\n    if (line < block.startLine) {\n      high = middle - 1;\n    } else if (line > block.endLine) {\n      low = middle + 1;\n    } else {\n      return middle;\n    }\n  }\n  if (low >= blocks.length) return blocks.length - 1;\n  if (high < 0) return 0;\n  return Math.abs(blocks[low].startLine - line)\n      < Math.abs(blocks[high].endLine - line)\n    ? low\n    : high;\n}\n\nfunction toCandidateWindow(\n  target: DocumentBlockIndex,\n  startBlock: number,\n  endBlock: number,\n): CandidateWindow {\n  const first = target.blocks[startBlock];\n  const last = target.blocks[endBlock];\n  return {\n    startBlock,\n    endBlock,\n    startLine: first.startLine,\n    endLine: last.endLine,\n    type: first.type,\n    text: target.lines.slice(first.startLine, last.endLine + 1).join(\"\\n\"),\n    headingPath: first.headingPath,\n    score: 0,\n  };\n}\n\nfunction scoreCandidate(\n  sourceBlock: MarkdownBlock,\n  sourceBlockIndex: number,\n  candidate: CandidateWindow,\n  index: AnchorContextIndex,\n  originalLine: number,\n): number {\n  const content = textSimilarity(sourceBlock.text, candidate.text);\n  const type = sourceBlock.type === candidate.type ? 1 : 0;\n  const heading = pathSimilarity(sourceBlock.headingPath, candidate.headingPath);\n  const previous = neighborSimilarity(\n    index.source.blocks[sourceBlockIndex - 1],\n    index.target.blocks[candidate.startBlock - 1],\n  );\n  const next = neighborSimilarity(\n    index.source.blocks[sourceBlockIndex + 1],\n    index.target.blocks[candidate.endBlock + 1],\n  );\n  const proximity = Math.max(\n    0,\n    1 - Math.abs(candidate.startLine - originalLine) / 100,\n  );\n\n  return Math.min(\n    1,\n    content * 0.45\n      + type * 0.1\n      + heading * 0.1\n      + previous * 0.15\n      + next * 0.15\n      + proximity * 0.05,\n  );\n}\n\nfunction neighborSimilarity(\n  source: MarkdownBlock | undefined,\n  target: MarkdownBlock | undefined,\n): number {\n  if (!source || !target) return 0;\n  return textSimilarity(source.text, target.text);\n}\n\nfunction textSimilarity(left: string, right: string): number {\n  return Math.max(\n    tokenDice(left, right),\n    combinedScore(normalizeText(left), normalizeText(right)),\n  );\n}\n\nfunction pathSimilarity(left: string[], right: string[]): number {\n  if (left.length === 0 || right.length === 0) return 0;\n  return tokenDice(left.join(\" \"), right.join(\" \"));\n}\n\nfunction tokenDice(left: string, right: string): number {\n  const leftTokens = tokenize(left);\n  const rightTokens = tokenize(right);\n  if (leftTokens.length === 0 || rightTokens.length === 0) return 0;\n  const remaining = new Map<string, number>();\n  for (const token of rightTokens) {\n    remaining.set(token, (remaining.get(token) ?? 0) + 1);\n  }\n  let overlap = 0;\n  for (const token of leftTokens) {\n    const count = remaining.get(token) ?? 0;\n    if (count > 0) {\n      overlap += 1;\n      remaining.set(token, count - 1);\n    }\n  }\n  return (2 * overlap) / (leftTokens.length + rightTokens.length);\n}\n\nfunction tokenize(text: string): string[] {\n  return normalizeText(text).match(/[\\p{L}\\p{N}_-]+/gu) ?? [];\n}\n\nfunction normalizeText(text: string): string {\n  return text.toLowerCase().replace(/\\s+/g, \" \").trim();\n}\n\nfunction samePath(left: string[], right: string[]): boolean {\n  return left.length === right.length\n    && left.every((item, index) => item === right[index]);\n}\n\nfunction resolveCandidateRange(\n  comment: Comment,\n  sourceBlock: MarkdownBlock,\n  candidate: CandidateWindow,\n  target: DocumentBlockIndex,\n): {\n  line: number;\n  endLine: number;\n  startColumn?: number;\n  endColumn?: number;\n  text: string;\n} {\n  const exactIndex = candidate.text.indexOf(comment.selected_text as string);\n  const selectedIsWholeBlock =\n    comment.line === sourceBlock.startLine\n    && (comment.end_line ?? comment.line) === sourceBlock.endLine\n    && comment.start_column == null\n    && comment.end_column == null\n    && comment.selected_text === sourceBlock.text;\n  const sourceOccurrenceIsUnique =\n    countOccurrences(sourceBlock.text, comment.selected_text as string) === 1;\n  if (exactIndex >= 0 && (selectedIsWholeBlock || sourceOccurrenceIsUnique)) {\n    return exactRange(\n      candidate.startLine,\n      candidate.text,\n      comment.selected_text as string,\n      exactIndex,\n    );\n  }\n\n  if (selectedIsWholeBlock) {\n    return {\n      line: candidate.startLine,\n      endLine: candidate.endLine,\n      text: candidate.text,\n    };\n  }\n\n  const relativeLine = (comment.line as number) - sourceBlock.startLine;\n  const line = Math.min(candidate.endLine, candidate.startLine + relativeLine);\n  const lineSpan = (comment.end_line ?? comment.line as number)\n    - (comment.line as number);\n  const endLine = Math.min(candidate.endLine, line + lineSpan);\n  const startColumn = comment.start_column;\n  const endColumn = comment.end_column;\n  return {\n    line,\n    endLine,\n    startColumn,\n    endColumn,\n    text: extractText(\n      target.lines,\n      line,\n      endLine,\n      startColumn,\n      endColumn,\n    ) ?? \"\",\n  };\n}\n\nfunction countOccurrences(text: string, needle: string): number {\n  if (!needle) return 0;\n  let count = 0;\n  let offset = 0;\n  while (offset <= text.length - needle.length) {\n    const index = text.indexOf(needle, offset);\n    if (index < 0) break;\n    count += 1;\n    offset = index + 1;\n  }\n  return count;\n}\n\nfunction exactRange(\n  startLine: number,\n  candidateText: string,\n  selectedText: string,\n  index: number,\n): {\n  line: number;\n  endLine: number;\n  startColumn: number;\n  endColumn: number;\n  text: string;\n} {\n  const before = candidateText.slice(0, index).split(\"\\n\");\n  const selectedLines = selectedText.split(\"\\n\");\n  const line = startLine + before.length - 1;\n  const startColumn = before.at(-1)?.length ?? 0;\n  const finalSelectedLineLength = selectedLines.at(-1)?.length ?? 0;\n  return {\n    line,\n    endLine: line + selectedLines.length - 1,\n    startColumn,\n    endColumn: selectedLines.length === 1\n      ? startColumn + finalSelectedLineLength\n      : finalSelectedLineLength,\n    text: selectedText,\n  };\n}\n\nfunction extractText(\n  lines: string[],\n  line: number,\n  endLine?: number,\n  startColumn?: number,\n  endColumn?: number,\n): string | null {\n  const finalLine = endLine ?? line;\n  if (line < 1 || finalLine >= lines.length) return null;\n  if (line === finalLine) {\n    const text = lines[line];\n    return startColumn != null && endColumn != null\n      ? text.slice(startColumn, endColumn)\n      : text;\n  }\n\n  const result: string[] = [];\n  for (let current = line; current <= finalLine; current += 1) {\n    let text = lines[current];\n    if (current === line && startColumn != null) text = text.slice(startColumn);\n    if (current === finalLine && endColumn != null) text = text.slice(0, endColumn);\n    result.push(text);\n  }\n  return result.join(\"\\n\");\n}\n", "import type { ContextAnchorResolution } from \"./anchor-context.js\";\nimport type { ProjectedAnchor } from \"./revision-projection.js\";\nimport type { ReanchorResult } from \"./types.js\";\n\nexport type ConfidenceBand =\n  | \"certain\"\n  | \"probable\"\n  | \"ambiguous\"\n  | \"orphaned\";\n\nexport interface CalibratedAnchor {\n  band: ConfidenceBand;\n  result: ReanchorResult;\n}\n\n/**\n * Calibrate independent revision and structural evidence into a public result.\n *\n * Exact evidence is certain. Edited anchors are probable only when evidence\n * agrees or one source has a decisive margin; conflicting evidence abstains.\n */\nexport function calibrateAnchorEvidence(\n  commentId: string,\n  selectedText: string,\n  projected?: ProjectedAnchor,\n  contextual?: ContextAnchorResolution,\n): CalibratedAnchor | undefined {\n  if (projected?.exact) {\n    return {\n      band: \"certain\",\n      result: projectedResult(commentId, selectedText, projected),\n    };\n  }\n  if (contextual?.status === \"anchored\") {\n    return {\n      band: \"certain\",\n      result: contextualResult(commentId, selectedText, contextual),\n    };\n  }\n\n  if (projected && contextual) {\n    if (sameRange(projected, contextual)) {\n      const result = contextualResult(commentId, selectedText, contextual);\n      result.status = \"fuzzy\";\n      result.score = combineIndependentScores(projected.score, contextual.score);\n      result.reason =\n        `Probable anchor: revision projection and Markdown context agree `\n        + `(confidence ${result.score.toFixed(3)}).`;\n      return { band: \"probable\", result };\n    }\n\n    if (contextual.status === \"orphaned\" && !isStrongProjection(projected)) {\n      return {\n        band: \"orphaned\",\n        result: contextualResult(commentId, selectedText, contextual),\n      };\n    }\n\n    if (\n      contextual.status === \"fuzzy\"\n      && contextual.candidateMargin >= 0.15\n      && contextual.score >= projected.score + 0.1\n    ) {\n      return {\n        band: \"probable\",\n        result: contextualResult(commentId, selectedText, contextual),\n      };\n    }\n\n    return {\n      band: \"ambiguous\",\n      result: {\n        commentId,\n        status: \"ambiguous\",\n        score: Math.max(projected.score, contextual.score),\n        reason:\n          `Ambiguous evidence: revision projection points to line `\n          + `${projected.line}, while Markdown context points to `\n          + `${contextual.line ?? \"no location\"}.`,\n      },\n    };\n  }\n\n  if (contextual) {\n    const band = contextual.status === \"orphaned\"\n      ? \"orphaned\"\n      : contextual.status === \"ambiguous\"\n        ? \"ambiguous\"\n        : \"probable\";\n    return {\n      band,\n      result: contextualResult(commentId, selectedText, contextual),\n    };\n  }\n\n  if (projected) {\n    if (!isStrongProjection(projected)) return undefined;\n    return {\n      band: \"probable\",\n      result: projectedResult(commentId, selectedText, projected),\n    };\n  }\n\n  return undefined;\n}\n\nfunction isStrongProjection(projected: ProjectedAnchor): boolean {\n  return projected.contextSupport >= 3\n    || (projected.contextSupport >= 2 && projected.contextMargin >= 0.5);\n}\n\nfunction sameRange(\n  projected: ProjectedAnchor,\n  contextual: ContextAnchorResolution,\n): boolean {\n  return projected.line === contextual.line\n    && projected.endLine === contextual.endLine;\n}\n\nfunction combineIndependentScores(left: number, right: number): number {\n  return Math.min(0.95, (left + right) / 2 + 0.05);\n}\n\nfunction projectedResult(\n  commentId: string,\n  selectedText: string,\n  projected: ProjectedAnchor,\n): ReanchorResult {\n  return {\n    commentId,\n    status: projected.exact ? \"anchored\" : \"fuzzy\",\n    score: projected.score,\n    newLine: projected.line,\n    newEndLine: projected.endLine,\n    newStartColumn: projected.startColumn,\n    newEndColumn: projected.endColumn,\n    anchoredText: projected.exact ? undefined : projected.text,\n    previousSelectedText: projected.exact ? undefined : selectedText,\n    reason: projected.reason,\n  };\n}\n\nfunction contextualResult(\n  commentId: string,\n  selectedText: string,\n  contextual: ContextAnchorResolution,\n): ReanchorResult {\n  return {\n    commentId,\n    status: contextual.status,\n    score: contextual.score,\n    newLine: contextual.line,\n    newEndLine: contextual.endLine,\n    newStartColumn: contextual.startColumn,\n    newEndColumn: contextual.endColumn,\n    anchoredText: contextual.status === \"fuzzy\"\n      ? contextual.text\n      : undefined,\n    previousSelectedText: contextual.status === \"fuzzy\"\n      ? selectedText\n      : undefined,\n    reason: contextual.reason,\n  };\n}\n", "import type {\n  AnchorPosition,\n  Comment,\n  DiffHunk,\n  FuzzyCandidate,\n  MrsfDocument,\n  ReanchorResult,\n} from \"./types.js\";\nimport {\n  createFuzzySearchIndex,\n  exactMatch,\n  fuzzySearch,\n  fuzzySearchThresholds,\n  normalizedMatch,\n  type FuzzySearchIndex,\n} from \"./fuzzy.js\";\nimport {\n  projectCommentAnchor,\n  type RevisionProjectionIndex,\n} from \"./revision-projection.js\";\nimport {\n  resolveContextAnchor,\n  type AnchorContextIndex,\n} from \"./anchor-context.js\";\nimport { calibrateAnchorEvidence } from \"./confidence-calibration.js\";\n\nexport const HIGH_THRESHOLD = 0.8;\nexport const DEFAULT_THRESHOLD = 0.6;\n\n/**\n * Default proximity window (in lines) for the \u00A77.4 step 1a relocation guard.\n *\n * A lone exact match of `selected_text` that lands farther than this many\n * lines from the comment's original `line` \u2014 while the text at the original\n * position has changed \u2014 is treated as an in-place edit rather than a\n * confident relocation. See {@link isImplausibleExactRelocation}.\n */\nexport const DEFAULT_PROXIMITY_WINDOW = 5;\n\nexport function toReanchorLines(documentText: string): string[] {\n  return [\"\", ...documentText.replace(/\\r\\n/g, \"\\n\").split(\"\\n\")];\n}\n\nexport function reanchorComment(\n  comment: Comment,\n  documentLines: string[],\n  opts: {\n    diffHunks?: DiffHunk[];\n    threshold?: number;\n    commitIsStale?: boolean;\n    proximityWindow?: number;\n    revisionProjection?: RevisionProjectionIndex;\n    anchorContext?: AnchorContextIndex;\n    fuzzySearchIndex?: FuzzySearchIndex;\n    getFuzzySearchIndex?: () => FuzzySearchIndex;\n  } = {},\n): ReanchorResult {\n  const threshold = opts.threshold ?? DEFAULT_THRESHOLD;\n  const proximityWindow = opts.proximityWindow ?? DEFAULT_PROXIMITY_WINDOW;\n  const commentId = comment.id;\n  const selectedText = comment.selected_text;\n  let fuzzyCandidateSets: Map<number, FuzzyCandidate[]> | undefined;\n  let fuzzySearchIndex = opts.fuzzySearchIndex;\n  const getFuzzySearchIndex = (): FuzzySearchIndex => {\n    fuzzySearchIndex ??= opts.getFuzzySearchIndex?.()\n      ?? createFuzzySearchIndex(documentLines);\n    return fuzzySearchIndex;\n  };\n\n  if (!selectedText && comment.line == null) {\n    return {\n      commentId,\n      status: \"anchored\",\n      score: 1.0,\n      reason: \"Document-level comment (no anchor needed).\",\n    };\n  }\n\n  if (comment.line != null && opts.diffHunks?.length) {\n    const { shift, modified } = getLineShift(opts.diffHunks, comment.line);\n\n    if (!selectedText) {\n      const shiftedLine = comment.line + shift;\n      const lineSpan =\n        comment.end_line != null ? comment.end_line - comment.line : 0;\n      const shiftedEndLine =\n        comment.end_line != null ? shiftedLine + lineSpan : undefined;\n      return {\n        commentId,\n        status: shift === 0 ? \"anchored\" : \"shifted\",\n        score: 1.0,\n        newLine: shiftedLine,\n        newEndLine: shiftedEndLine,\n        reason:\n          shift === 0\n            ? \"Line-only comment unchanged (diff confirms position).\"\n            : `Line-only comment shifted by ${shift > 0 ? \"+\" : \"\"}${shift} line(s) via diff.`,\n      };\n    }\n\n    if (!modified) {\n      const shiftedLine = comment.line + shift;\n      const lineSpan =\n        comment.end_line != null ? comment.end_line - comment.line : 0;\n      const shiftedEndLine =\n        comment.end_line != null ? shiftedLine + lineSpan : undefined;\n\n      const textAtShifted = extractText(\n        documentLines,\n        shiftedLine,\n        shiftedEndLine,\n        comment.start_column,\n        comment.end_column,\n      );\n\n      if (textAtShifted === selectedText) {\n        return {\n          commentId,\n          status: shift === 0 ? \"anchored\" : \"shifted\",\n          score: 1.0,\n          newLine: shiftedLine,\n          newEndLine: shiftedEndLine,\n          reason:\n            shift === 0\n              ? \"Diff confirms text unchanged at original position.\"\n              : `Diff shifted by ${shift > 0 ? \"+\" : \"\"}${shift} line(s).`,\n        };\n      }\n    }\n  }\n\n  const projected = selectedText && opts.revisionProjection\n    ? projectCommentAnchor(\n      comment,\n      opts.revisionProjection,\n      threshold,\n    )\n    : undefined;\n  if (selectedText && projected?.exact) {\n    const exactCalibration = calibrateAnchorEvidence(\n      commentId,\n      selectedText,\n      projected,\n    );\n    if (exactCalibration) return exactCalibration.result;\n  }\n  const contextual = selectedText && opts.anchorContext\n    ? resolveContextAnchor(comment, opts.anchorContext)\n    : undefined;\n  if (selectedText && (projected || contextual)) {\n    const calibrated = calibrateAnchorEvidence(\n      commentId,\n      selectedText,\n      projected,\n      contextual,\n    );\n    if (calibrated) return calibrated.result;\n  }\n\n  if (selectedText) {\n    const exactCandidates = exactMatch(documentLines, selectedText);\n    if (exactCandidates.length > 1 && comment.line == null) {\n      return {\n        commentId,\n        status: \"ambiguous\",\n        score: 1,\n        reason:\n          `Ambiguous: ${exactCandidates.length} exact matches and no position `\n          + \"or source context to disambiguate them.\",\n      };\n    }\n\n    // Pick the best exact candidate: the only one, or \u2014 when several remain \u2014\n    // the one nearest to the original line (\u00A77.4 step 1b).\n    let chosen: FuzzyCandidate | undefined;\n    let chosenReason = \"\";\n    if (exactCandidates.length === 1) {\n      chosen = exactCandidates[0];\n      chosenReason = \"Exact text match (unique).\";\n    } else if (exactCandidates.length > 1 && comment.line != null) {\n      chosen = closestToLine(exactCandidates, comment.line);\n      chosenReason = `Exact text match (${exactCandidates.length} occurrences; chose nearest to original line ${comment.line}).`;\n    }\n\n    if (chosen) {\n      // \u00A77.4 step 1a proximity guard: a lone/closest exact match that lands far\n      // from the original position \u2014 while the text at the original position no\n      // longer equals selected_text \u2014 most likely indicates an in-place edit of\n      // the anchored text, not a genuine relocation. Keep the comment at its\n      // original position and flag it for re-anchoring instead of teleporting it\n      // onto an unrelated identical token with full confidence.\n      if (isImplausibleExactRelocation(comment, chosen, documentLines, proximityWindow)) {\n        const textAtOrigin = extractText(\n          documentLines,\n          comment.line as number,\n          comment.end_line,\n          comment.start_column,\n          comment.end_column,\n        );\n        return {\n          commentId,\n          status: \"fuzzy\",\n          score: 0.5,\n          newLine: comment.line,\n          newEndLine: comment.end_line,\n          newStartColumn: comment.start_column,\n          newEndColumn: comment.end_column,\n          anchoredText: textAtOrigin ?? undefined,\n          previousSelectedText: selectedText,\n          reason:\n            `Lone exact match at line ${chosen.line} is beyond the proximity window ` +\n            `(\u00B1${proximityWindow}) of original line ${comment.line} and the text at the ` +\n            `original position changed; kept at original position, needs re-anchoring.`,\n        };\n      }\n\n      return {\n        commentId,\n        status: \"anchored\",\n        score: 1.0,\n        newLine: chosen.line,\n        newEndLine: chosen.endLine,\n        newStartColumn: chosen.startColumn,\n        newEndColumn: chosen.endColumn,\n        reason: chosenReason,\n      };\n    }\n\n    const normCandidates = normalizedMatch(documentLines, selectedText);\n    if (normCandidates.length === 1) {\n      const candidate = normCandidates[0];\n      return {\n        commentId,\n        status: \"fuzzy\",\n        score: candidate.score,\n        newLine: candidate.line,\n        newEndLine: candidate.endLine,\n        newStartColumn: candidate.startColumn,\n        newEndColumn: candidate.endColumn,\n        anchoredText: candidate.text,\n        previousSelectedText: selectedText,\n        reason: \"Normalized whitespace match.\",\n      };\n    }\n\n    fuzzyCandidateSets = fuzzySearchThresholds(\n      documentLines,\n      selectedText,\n      [HIGH_THRESHOLD, threshold],\n      comment.line,\n      getFuzzySearchIndex(),\n    );\n    const fuzzyCandidates = fuzzyCandidateSets.get(HIGH_THRESHOLD) ?? [];\n\n    if (fuzzyCandidates.length === 1 || (fuzzyCandidates.length > 0 && fuzzyCandidates[0].score >= HIGH_THRESHOLD)) {\n      const best =\n        fuzzyCandidates.length === 1\n          ? fuzzyCandidates[0]\n          : closestToLine(fuzzyCandidates, comment.line ?? 1);\n      return {\n        commentId,\n        status: \"fuzzy\",\n        score: best.score,\n        newLine: best.line,\n        newEndLine: best.endLine,\n        newStartColumn: best.startColumn,\n        newEndColumn: best.endColumn,\n        anchoredText: best.text,\n        previousSelectedText: selectedText,\n        reason: `High-confidence fuzzy match (score ${best.score.toFixed(3)}).`,\n      };\n    }\n  }\n\n  if (comment.line != null) {\n    const lineIdx = comment.line;\n    if (lineIdx > 0 && lineIdx < documentLines.length) {\n      const qualifier = opts.commitIsStale\n        ? \" (commit is stale \u2014 line may have shifted)\"\n        : \"\";\n\n      if (selectedText) {\n        const lineText = documentLines[lineIdx];\n        const candidates = fuzzySearch([\"\", lineText], selectedText, DEFAULT_THRESHOLD);\n        if (candidates.length > 0) {\n          return {\n            commentId,\n            status: \"fuzzy\",\n            score: candidates[0].score,\n            newLine: comment.line,\n            newEndLine: comment.end_line,\n            anchoredText: candidates[0].text,\n            previousSelectedText: selectedText,\n            reason: `Line-fallback with fuzzy text match (score ${candidates[0].score.toFixed(3)})${qualifier}.`,\n          };\n        }\n      }\n\n      const isLineOnly = !selectedText;\n      return {\n        commentId,\n        status: isLineOnly ? \"anchored\" : (opts.commitIsStale ? \"ambiguous\" : \"anchored\"),\n        score: isLineOnly ? 1.0 : (opts.commitIsStale ? 0.5 : 0.8),\n        newLine: comment.line,\n        newEndLine: comment.end_line,\n        reason: isLineOnly\n          ? \"Line-only comment (no selected_text to verify).\"\n          : `Line/column fallback${qualifier}.`,\n      };\n    }\n  }\n\n  if (selectedText) {\n    const lowCandidates = fuzzyCandidateSets?.get(threshold)\n      ?? fuzzySearch(\n        documentLines,\n        selectedText,\n        threshold,\n        comment.line,\n        getFuzzySearchIndex(),\n      );\n\n    if (lowCandidates.length === 1) {\n      const candidate = lowCandidates[0];\n      return {\n        commentId,\n        status: \"fuzzy\",\n        score: candidate.score,\n        newLine: candidate.line,\n        newEndLine: candidate.endLine,\n        newStartColumn: candidate.startColumn,\n        newEndColumn: candidate.endColumn,\n        anchoredText: candidate.text,\n        previousSelectedText: selectedText,\n        reason: `Low-threshold fuzzy match (score ${candidate.score.toFixed(3)}).`,\n      };\n    }\n\n    if (lowCandidates.length > 1) {\n      const best = lowCandidates[0];\n      return {\n        commentId,\n        status: \"ambiguous\",\n        score: best.score,\n        newLine: best.line,\n        newEndLine: best.endLine,\n        reason: `Ambiguous: ${lowCandidates.length} fuzzy matches (best score ${best.score.toFixed(3)}).`,\n      };\n    }\n  }\n\n  return {\n    commentId,\n    status: \"orphaned\",\n    score: 0,\n    reason: \"No match found. Comment is orphaned.\",\n  };\n}\n\nexport function reanchorDocumentLines(\n  doc: MrsfDocument,\n  documentLines: string[],\n  opts: { threshold?: number; proximityWindow?: number } = {},\n): ReanchorResult[] {\n  let fuzzySearchIndex: FuzzySearchIndex | undefined;\n  const getFuzzySearchIndex = (): FuzzySearchIndex => {\n    fuzzySearchIndex ??= createFuzzySearchIndex(documentLines);\n    return fuzzySearchIndex;\n  };\n  return doc.comments.map((comment) =>\n    reanchorComment(comment, documentLines, { ...opts, getFuzzySearchIndex })\n  );\n}\n\nexport function reanchorDocumentText(\n  doc: MrsfDocument,\n  documentText: string,\n  opts: { threshold?: number; proximityWindow?: number } = {},\n): ReanchorResult[] {\n  return reanchorDocumentLines(doc, toReanchorLines(documentText), opts);\n}\n\nexport function resolveAnchor(\n  comment: Comment,\n  documentText: string,\n  opts: { threshold?: number; proximityWindow?: number } = {},\n): AnchorPosition {\n  const normalizedText = documentText.replace(/\\r\\n/g, \"\\n\");\n  const documentLines = toReanchorLines(documentText);\n  const result = reanchorComment(comment, documentLines, opts);\n\n  if (result.status === \"orphaned\") {\n    return {\n      status: \"orphaned\",\n      score: result.score,\n      reason: result.reason,\n    };\n  }\n\n  const line = result.newLine ?? comment.line;\n  if (line == null) {\n    return {\n      status: result.status,\n      score: result.score,\n      reason: result.reason,\n    };\n  }\n\n  const rawLines = normalizedText.split(\"\\n\");\n  const lineStarts = computeLineStarts(rawLines);\n  const endLine = result.newEndLine ?? comment.end_line ?? line;\n  const startColumn = result.newStartColumn ?? comment.start_column ?? 0;\n  const endColumn = result.newEndColumn ?? comment.end_column;\n  const from = offsetFor(lineStarts, rawLines, line, startColumn);\n  const selectedText = comment.selected_text?.replace(/\\r\\n/g, \"\\n\");\n  const to =\n    endColumn != null\n      ? offsetFor(lineStarts, rawLines, endLine, endColumn)\n      : selectedText\n        ? from + selectedText.length\n        : offsetFor(lineStarts, rawLines, endLine, rawLines[endLine - 1]?.length ?? 0);\n\n  return {\n    status: result.status,\n    score: result.score,\n    from,\n    to,\n    line,\n    endLine,\n    startColumn,\n    endColumn: endColumn ?? columnForOffset(lineStarts, rawLines, endLine, to),\n    reason: result.reason,\n  };\n}\n\nfunction computeLineStarts(lines: string[]): number[] {\n  const starts = [0];\n  let offset = 0;\n  for (const line of lines) {\n    starts.push(offset);\n    offset += line.length + 1;\n  }\n  return starts;\n}\n\nfunction offsetFor(\n  lineStarts: number[],\n  lines: string[],\n  line: number,\n  column: number,\n): number {\n  const start = lineStarts[line] ?? 0;\n  const maxColumn = lines[line - 1]?.length ?? 0;\n  return start + Math.max(0, Math.min(column, maxColumn));\n}\n\nfunction columnForOffset(\n  lineStarts: number[],\n  lines: string[],\n  line: number,\n  offset: number,\n): number {\n  const start = lineStarts[line] ?? 0;\n  const maxColumn = lines[line - 1]?.length ?? 0;\n  return Math.max(0, Math.min(offset - start, maxColumn));\n}\n\nexport function applyReanchorResults(\n  doc: MrsfDocument,\n  results: ReanchorResult[],\n  opts: { updateText?: boolean; force?: boolean; headCommit?: string } = {},\n): number {\n  let changed = 0;\n  const resultMap = new Map(results.map((result) => [result.commentId, result]));\n\n  for (const comment of doc.comments) {\n    const result = resultMap.get(comment.id);\n    if (!result) continue;\n\n    let isChanged = false;\n\n    if (result.newLine != null && result.newLine !== comment.line) {\n      comment.line = result.newLine;\n      isChanged = true;\n    }\n    if (result.newEndLine != null && result.newEndLine !== comment.end_line) {\n      comment.end_line = result.newEndLine;\n      isChanged = true;\n    }\n    if (result.newStartColumn != null && result.newStartColumn !== comment.start_column) {\n      comment.start_column = result.newStartColumn;\n      isChanged = true;\n    }\n    if (result.newEndColumn != null && result.newEndColumn !== comment.end_column) {\n      comment.end_column = result.newEndColumn;\n      isChanged = true;\n    }\n\n    if (result.anchoredText != null && result.anchoredText !== comment.selected_text) {\n      if (opts.updateText) {\n        comment.selected_text = result.anchoredText;\n        delete comment.anchored_text;\n      } else {\n        comment.anchored_text = result.anchoredText;\n      }\n      isChanged = true;\n    } else if (result.anchoredText != null && result.anchoredText === comment.selected_text) {\n      if (comment.anchored_text) {\n        delete comment.anchored_text;\n        isChanged = true;\n      }\n    }\n\n    if (isChanged || result.status !== \"anchored\") {\n      comment.x_reanchor_status = result.status;\n      comment.x_reanchor_score = result.score;\n    }\n\n    if (\n      opts.force\n      && opts.headCommit\n      && (result.status === \"anchored\" || result.status === \"shifted\")\n      && result.score >= HIGH_THRESHOLD\n    ) {\n      comment.commit = opts.headCommit;\n      delete comment.x_reanchor_status;\n      delete comment.x_reanchor_score;\n      if (comment.anchored_text && comment.anchored_text === comment.selected_text) {\n        delete comment.anchored_text;\n      }\n      isChanged = true;\n    }\n\n    if (isChanged) {\n      changed += 1;\n    }\n  }\n\n  return changed;\n}\n\nfunction extractText(\n  lines: string[],\n  line: number,\n  endLine?: number,\n  startColumn?: number,\n  endColumn?: number,\n): string | null {\n  const startIdx = line;\n  const endIdx = endLine ?? line;\n\n  if (startIdx < 1 || endIdx >= lines.length) return null;\n\n  if (startIdx === endIdx) {\n    const text = lines[startIdx];\n    if (startColumn != null && endColumn != null) {\n      return text.slice(startColumn, endColumn);\n    }\n    return text;\n  }\n\n  const result: string[] = [];\n  for (let index = startIdx; index <= endIdx; index += 1) {\n    let currentLine = lines[index];\n    if (index === startIdx && startColumn != null) currentLine = currentLine.slice(startColumn);\n    if (index === endIdx && endColumn != null) currentLine = currentLine.slice(0, endColumn);\n    result.push(currentLine);\n  }\n  return result.join(\"\\n\");\n}\n\nfunction closestToLine<T extends { line: number }>(candidates: T[], targetLine: number): T {\n  return candidates.reduce((best, candidate) =>\n    Math.abs(candidate.line - targetLine) < Math.abs(best.line - targetLine) ? candidate : best,\n  );\n}\n\n/**\n * \u00A77.4 step 1a relocation guard.\n *\n * Returns true when a chosen exact-match candidate is an *implausible*\n * full-confidence relocation: the original `line` still exists in the document,\n * the candidate is farther than `proximityWindow` lines away, and the text now\n * at the original position no longer equals `selected_text`. This is the\n * signature of an in-place edit of the anchored text (which removed the\n * original occurrence) rather than a genuine move of the selection.\n *\n * When the original line no longer exists (the document shrank or the section\n * was removed) or no positional anchor is available, relocation is treated as a\n * legitimate \u00A77.4 step 3 contextual re-anchor and this returns false.\n */\nfunction isImplausibleExactRelocation(\n  comment: Comment,\n  candidate: FuzzyCandidate,\n  lines: string[],\n  proximityWindow: number,\n): boolean {\n  if (comment.line == null) return false;\n\n  // Original position must still exist to be a viable fallback anchor.\n  if (comment.line <= 0 || comment.line >= lines.length) return false;\n\n  // A nearby match is plausibly the same (or an adjacent) edit region.\n  if (Math.abs(candidate.line - comment.line) <= proximityWindow) return false;\n\n  // If the text at the original position still equals selected_text, the\n  // original occurrence is intact and relocation is not a teleport.\n  const textAtOrigin = extractText(\n    lines,\n    comment.line,\n    comment.end_line,\n    comment.start_column,\n    comment.end_column,\n  );\n  if (textAtOrigin === comment.selected_text) return false;\n\n  return true;\n}\n\nfunction getLineShift(diffHunks: DiffHunk[], line: number): { shift: number; modified: boolean } {\n  let shift = 0;\n  let modified = false;\n\n  for (const hunk of diffHunks) {\n    const oldStart = hunk.oldStart;\n    const oldEnd = hunk.oldStart + Math.max(hunk.oldCount, 1) - 1;\n\n    if (line >= oldStart && line <= oldEnd && hunk.oldCount > 0) {\n      modified = true;\n    }\n\n    if (line > oldEnd || (hunk.oldCount === 0 && line >= oldStart)) {\n      shift += hunk.newCount - hunk.oldCount;\n    }\n  }\n\n  return { shift, modified };\n}", "import {\n  findContextAnchorCandidates,\n  getAnchorContextScope,\n  type AnchorContextIndex,\n  type ContextAnchorCandidate,\n} from \"./anchor-context.js\";\nimport type { Comment, ReanchorResult } from \"./types.js\";\n\nconst LOCAL_LANDMARK_WINDOW = 30;\nconst MIN_LANDMARK_SUPPORT = 0.65;\nconst MIN_SUPPORTING_LANDMARKS = 2;\nconst MIN_GLOBAL_MARGIN = 0.08;\nconst MAX_RECONCILIATION_ROUNDS = 4;\n\ninterface Landmark {\n  sourceLine: number;\n  targetLine: number;\n  scope: string;\n}\n\ninterface ScoredCandidate {\n  candidate: ContextAnchorCandidate;\n  globalScore: number;\n  support: number;\n  supportingLandmarks: number;\n}\n\n/**\n * Resolve uncertain comments from nearby high-confidence anchors.\n *\n * Each landmark votes for a local source-to-target displacement rather than\n * global document order, allowing whole sections to move independently.\n * Newly confirmed exact anchors become landmarks in subsequent rounds.\n */\nexport function reconcileCommentAnchors(\n  comments: Comment[],\n  results: ReanchorResult[],\n  anchorContext: AnchorContextIndex,\n): ReanchorResult[] {\n  const reconciled = results.map((result) => ({ ...result }));\n  if (\n    comments.length < MIN_SUPPORTING_LANDMARKS + 1\n    || !reconciled.some((result) => result.status === \"ambiguous\")\n  ) {\n    return reconciled;\n  }\n  const resultIndexes = new Map(\n    reconciled.map((result, index) => [result.commentId, index]),\n  );\n  const landmarks = collectLandmarks(comments, reconciled, anchorContext);\n  const landmarkCounts = new Map<string, number>();\n  for (const landmark of landmarks) {\n    landmarkCounts.set(\n      landmark.scope,\n      (landmarkCounts.get(landmark.scope) ?? 0) + 1,\n    );\n  }\n\n  for (let round = 0; round < MAX_RECONCILIATION_ROUNDS; round += 1) {\n    let changed = false;\n    for (const comment of comments) {\n      if (comment.line == null || !comment.selected_text) continue;\n      const scope = getAnchorContextScope(comment, anchorContext);\n      if (scope == null) continue;\n      if ((landmarkCounts.get(scope) ?? 0) < MIN_SUPPORTING_LANDMARKS) {\n        continue;\n      }\n      const resultIndex = resultIndexes.get(comment.id);\n      if (resultIndex == null) continue;\n      const result = reconciled[resultIndex];\n      if (result.status !== \"ambiguous\") continue;\n\n      const candidates = deduplicateCandidates(\n        findContextAnchorCandidates(comment, anchorContext),\n      ).slice(0, 8);\n      if (candidates.length < 2) continue;\n      const ranked = candidates\n        .map((candidate) =>\n          scoreWithLandmarks(\n            comment.line as number,\n            scope,\n            candidate,\n            landmarks,\n          )\n        )\n        .sort((left, right) =>\n          right.globalScore - left.globalScore\n          || right.candidate.score - left.candidate.score\n          || left.candidate.line - right.candidate.line\n        );\n      const best = ranked[0];\n      const second = ranked[1];\n      if (\n        !best.candidate.exact\n        || best.supportingLandmarks < MIN_SUPPORTING_LANDMARKS\n        || best.support < MIN_LANDMARK_SUPPORT\n        || best.globalScore - second.globalScore < MIN_GLOBAL_MARGIN\n      ) {\n        continue;\n      }\n\n      reconciled[resultIndex] = {\n        commentId: comment.id,\n        status: \"anchored\",\n        score: Math.min(0.99, 0.8 + best.support * 0.19),\n        newLine: best.candidate.line,\n        newEndLine: best.candidate.endLine,\n        newStartColumn: best.candidate.startColumn,\n        newEndColumn: best.candidate.endColumn,\n        reason:\n          `Global reconciliation selected this candidate from `\n          + `${best.supportingLandmarks} nearby landmark(s) `\n          + `(support ${best.support.toFixed(3)}, margin `\n          + `${(best.globalScore - second.globalScore).toFixed(3)}).`,\n      };\n      changed = true;\n\n      landmarks.push({\n        sourceLine: comment.line,\n        targetLine: best.candidate.line,\n        scope,\n      });\n      landmarkCounts.set(scope, (landmarkCounts.get(scope) ?? 0) + 1);\n    }\n    if (!changed) break;\n  }\n\n  return reconciled;\n}\n\nfunction collectLandmarks(\n  comments: Comment[],\n  results: ReanchorResult[],\n  anchorContext: AnchorContextIndex,\n): Landmark[] {\n  const resultMap = new Map(results.map((result) => [result.commentId, result]));\n  return comments.flatMap((comment): Landmark[] => {\n    const result = resultMap.get(comment.id);\n    if (\n      comment.line == null\n      || result?.newLine == null\n      || (result.status !== \"anchored\" && result.status !== \"shifted\")\n      || result.score < 0.99\n    ) {\n      return [];\n    }\n    const scope = getAnchorContextScope(comment, anchorContext);\n    return scope == null\n      ? []\n      : [{ sourceLine: comment.line, targetLine: result.newLine, scope }];\n  });\n}\n\nfunction scoreWithLandmarks(\n  sourceLine: number,\n  scope: string,\n  candidate: ContextAnchorCandidate,\n  landmarks: Landmark[],\n): ScoredCandidate {\n  let weightedSupport = 0;\n  let totalWeight = 0;\n  let supportingLandmarks = 0;\n  const candidateShift = candidate.line - sourceLine;\n\n  for (const landmark of landmarks) {\n    if (landmark.scope !== scope) continue;\n    const sourceDistance = Math.abs(sourceLine - landmark.sourceLine);\n    if (sourceDistance === 0 || sourceDistance > LOCAL_LANDMARK_WINDOW) continue;\n    const landmarkShift = landmark.targetLine - landmark.sourceLine;\n    const shiftError = Math.abs(candidateShift - landmarkShift);\n    const agreement = Math.max(0, 1 - shiftError / 8);\n    const weight = 1 / (1 + sourceDistance / 4);\n    weightedSupport += agreement * weight;\n    totalWeight += weight;\n    if (agreement >= MIN_LANDMARK_SUPPORT) supportingLandmarks += 1;\n  }\n\n  const support = totalWeight > 0 ? weightedSupport / totalWeight : 0;\n  return {\n    candidate,\n    globalScore:\n      candidate.score * 0.5 + support * 0.45 + (candidate.exact ? 0.05 : 0),\n    support,\n    supportingLandmarks,\n  };\n}\n\nfunction deduplicateCandidates(\n  candidates: ContextAnchorCandidate[],\n): ContextAnchorCandidate[] {\n  const unique = new Map<string, ContextAnchorCandidate>();\n  for (const candidate of candidates) {\n    const key = [\n      candidate.line,\n      candidate.endLine,\n      candidate.startColumn ?? \"\",\n      candidate.endColumn ?? \"\",\n    ].join(\":\");\n    const existing = unique.get(key);\n    if (!existing || candidate.score > existing.score) {\n      unique.set(key, candidate);\n    }\n  }\n  return [...unique.values()].sort((left, right) =>\n    right.score - left.score || left.line - right.line\n  );\n}\n", "import AjvModule from \"ajv\";\nimport addFormatsModule from \"ajv-formats\";\nimport { mrsfSchema } from \"./schema.js\";\nimport type {\n  MrsfDocument,\n  ValidationDiagnostic,\n  ValidationResult,\n} from \"./types.js\";\n\nconst Ajv = (AjvModule as any).default ?? AjvModule;\nconst addFormats = (addFormatsModule as any).default ?? addFormatsModule;\n\nexport type HashFunction = (text: string) => string;\n\nexport function validateDocument(\n  doc: MrsfDocument,\n  schema: object = mrsfSchema,\n): ValidationResult {\n  const errors: ValidationDiagnostic[] = [];\n  const warnings: ValidationDiagnostic[] = [];\n\n  validateSchema(doc, schema, errors);\n  validateCrossFields(doc, errors, warnings);\n\n  return {\n    valid: errors.length === 0,\n    errors,\n    warnings,\n  };\n}\n\nexport function validateSchema(\n  doc: MrsfDocument,\n  rawSchema: object,\n  errors: ValidationDiagnostic[],\n): void {\n  const { $schema, ...schema } = rawSchema as Record<string, unknown>;\n  void $schema;\n  const ajv = new Ajv({ allErrors: true, strict: false });\n  addFormats(ajv);\n  const ajvValidate = ajv.compile(schema);\n  const schemaValid = ajvValidate(doc);\n\n  if (!schemaValid && ajvValidate.errors) {\n    for (const err of ajvValidate.errors) {\n      errors.push({\n        severity: \"error\",\n        code: \"schema-violation\",\n        message: `${err.instancePath || \"/\"}: ${err.message ?? \"schema error\"}`,\n        path: err.instancePath || \"/\",\n      });\n    }\n  }\n}\n\nexport function validateCrossFields(\n  doc: MrsfDocument,\n  errors: ValidationDiagnostic[],\n  warnings: ValidationDiagnostic[],\n  hash?: HashFunction,\n): void {\n  if (!Array.isArray(doc.comments)) return;\n\n  const ids = new Set<string>();\n  const allIds = doc.comments.map((x) => x.id);\n\n  for (let i = 0; i < doc.comments.length; i++) {\n    const c = doc.comments[i];\n    const prefix = `/comments/${i}`;\n\n    if (c.id) {\n      if (ids.has(c.id)) {\n        errors.push({\n          severity: \"error\",\n          code: \"duplicate-id\",\n          message: `Duplicate comment id \"${c.id}\"`,\n          path: `${prefix}/id`,\n          commentId: c.id,\n        });\n      }\n      ids.add(c.id);\n    }\n\n    if (c.line != null && c.end_line != null && c.end_line < c.line) {\n      errors.push({\n        severity: \"error\",\n        code: \"end-line-before-line\",\n        message: `end_line (${c.end_line}) must be \u2265 line (${c.line})`,\n        path: `${prefix}/end_line`,\n        commentId: c.id,\n      });\n    }\n\n    if (\n      c.start_column != null &&\n      c.end_column != null &&\n      (c.line == null || c.end_line == null || c.line === c.end_line) &&\n      c.end_column < c.start_column\n    ) {\n      errors.push({\n        severity: \"error\",\n        code: \"end-column-before-start-column\",\n        message: `end_column (${c.end_column}) must be \u2265 start_column (${c.start_column}) on the same line`,\n        path: `${prefix}/end_column`,\n        commentId: c.id,\n      });\n    }\n\n    if (c.selected_text && c.selected_text.length > 4096) {\n      errors.push({\n        severity: \"error\",\n        code: \"selected-text-too-long\",\n        message: `selected_text exceeds 4096 characters (${c.selected_text.length})`,\n        path: `${prefix}/selected_text`,\n        commentId: c.id,\n      });\n    }\n\n    if (c.text && c.text.length > 16384) {\n      warnings.push({\n        severity: \"warning\",\n        code: \"text-too-long\",\n        message: `text exceeds recommended 16384 characters (${c.text.length})`,\n        path: `${prefix}/text`,\n        commentId: c.id,\n      });\n    }\n\n    // Browser-safe callers do not get the Node SHA-256 implementation.\n    // The hash check runs only when a hash function is injected by the Node validator.\n    if (hash && c.selected_text && c.selected_text_hash) {\n      const expected = hash(c.selected_text);\n      if (c.selected_text_hash !== expected) {\n        warnings.push({\n          severity: \"warning\",\n          code: \"hash-mismatch\",\n          message: `selected_text_hash mismatch (expected ${expected.slice(0, 12)}\u2026, got ${c.selected_text_hash.slice(0, 12)}\u2026)`,\n          path: `${prefix}/selected_text_hash`,\n          commentId: c.id,\n        });\n      }\n    }\n\n    if (c.reply_to && !ids.has(c.reply_to) && !allIds.includes(c.reply_to)) {\n      warnings.push({\n        severity: \"warning\",\n        code: \"unresolved-reply-to\",\n        message: `reply_to \"${c.reply_to}\" does not resolve to any comment id in this file`,\n        path: `${prefix}/reply_to`,\n        commentId: c.id,\n      });\n    }\n\n    if (c.line != null && !c.selected_text) {\n      warnings.push({\n        severity: \"warning\",\n        code: \"missing-selected-text\",\n        message: \"Comment has line anchors but no selected_text \u2014 anchoring will be fragile across edits\",\n        path: `${prefix}/selected_text`,\n        commentId: c.id,\n      });\n    }\n  }\n}\n", "\n{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://github.com/wictorwilen/MRSF/raw/main/mrsf.schema.json\",\n  \"title\": \"Markdown Review Sidecar Format (MRSF) v1.0\",\n  \"description\": \"Schema for MRSF review sidecar files. See MRSF-v1.0.md for the full specification.\",\n  \"type\": \"object\",\n  \"required\": [\"mrsf_version\", \"document\", \"comments\"],\n  \"additionalProperties\": true,\n  \"properties\": {\n    \"mrsf_version\": {\n      \"type\": \"string\",\n      \"pattern\": \"^1\\\\.\\\\d+$\",\n      \"description\": \"MRSF format version. MUST be a supported major.minor version (e.g., 1.0).\"\n    },\n    \"document\": {\n      \"type\": \"string\",\n      \"description\": \"Relative path to the Markdown document being reviewed.\"\n    },\n    \"comments\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"required\": [\"id\", \"author\", \"timestamp\", \"text\", \"resolved\"],\n        \"additionalProperties\": true,\n        \"properties\": {\n          \"id\": {\n            \"type\": \"string\",\n            \"description\": \"Globally unique, opaque, collision-resistant identifier for the comment.\"\n          },\n          \"author\": {\n            \"type\": \"string\",\n            \"description\": \"Creator of the comment. SHOULD follow the convention 'Display Name (identifier)'.\"\n          },\n          \"timestamp\": {\n            \"type\": \"string\",\n            \"format\": \"date-time\",\n            \"description\": \"ISO 8601 / RFC 3339 timestamp of comment creation; SHOULD include timezone offset.\"\n          },\n          \"text\": {\n            \"type\": \"string\",\n            \"maxLength\": 16384,\n            \"description\": \"The content of the review comment. MUST be plain text.\"\n          },\n          \"resolved\": {\n            \"type\": \"boolean\",\n            \"description\": \"Whether the comment has been resolved.\"\n          },\n          \"commit\": {\n            \"type\": \"string\",\n            \"description\": \"Git commit hash associated with the comment. SHOULD be the full (long) SHA.\"\n          },\n          \"type\": {\n            \"type\": \"string\",\n            \"description\": \"Categorization of the comment. Recommended values listed in examples.\",\n            \"examples\": [\n              \"suggestion\",\n              \"issue\",\n              \"question\",\n              \"accuracy\",\n              \"style\",\n              \"clarity\"\n            ]\n          },\n          \"severity\": {\n            \"type\": \"string\",\n            \"description\": \"Importance level of the comment.\",\n            \"enum\": [\"low\", \"medium\", \"high\"]\n          },\n          \"reply_to\": {\n            \"type\": \"string\",\n            \"description\": \"ID of another comment in the same file that this comment replies to.\"\n          },\n          \"line\": {\n            \"type\": \"integer\",\n            \"minimum\": 1,\n            \"description\": \"Starting line number (1-based) in the target document.\"\n          },\n          \"end_line\": {\n            \"type\": \"integer\",\n            \"minimum\": 1,\n            \"description\": \"Ending line number (inclusive, 1-based). MUST be >= line.\"\n          },\n          \"start_column\": {\n            \"type\": \"integer\",\n            \"minimum\": 0,\n            \"description\": \"Starting column index (0-based) within the starting line.\"\n          },\n          \"end_column\": {\n            \"type\": \"integer\",\n            \"minimum\": 0,\n            \"description\": \"Ending column index. MUST be >= start_column when on the same line.\"\n          },\n          \"selected_text\": {\n            \"type\": \"string\",\n            \"maxLength\": 4096,\n            \"description\": \"Exact text selected by the reviewer. SHOULD NOT be modified by re-anchoring tools. SHOULD NOT exceed 4096 characters.\"\n          },\n          \"anchored_text\": {\n            \"type\": \"string\",\n            \"maxLength\": 4096,\n            \"description\": \"Text currently found at the resolved anchor position. Populated by re-anchoring tools when the document text differs from selected_text. SHOULD be omitted when identical to selected_text.\"\n          },\n          \"selected_text_hash\": {\n            \"type\": \"string\",\n            \"pattern\": \"^[a-f0-9]{64}$\",\n            \"description\": \"Hex-encoded SHA-256 hash of selected_text. Immutable after creation; used for fast exact-match detection during re-anchoring, integrity verification, and staleness checks. SHOULD NOT be modified by re-anchoring tools unless selected_text is also replaced (opt-in behaviour), in which case it MUST be recomputed.\"\n          }\n        }\n      }\n    }\n  }\n}\n", "import mrsfSchemaJson from \"../../mrsf.schema.json\" with { type: \"json\" };\n\nexport const mrsfSchema = mrsfSchemaJson;\n", "/**\n * MRSF string (de)serialization \u2014 pure, dependency-light helpers that parse and\n * serialize MRSF sidecar content to/from strings.\n *\n * This module intentionally has **no Node-only imports** (no `node:fs`,\n * `node:path`, `node:crypto`, \u2026) so it can be consumed from browser/host\n * adapters via the slim `@mrsf/cli/browser` entry point. Filesystem-bound\n * helpers (read/discover/write a file) live in `parser.ts` / `writer.ts`.\n */\n\nimport yaml from \"js-yaml\";\nimport { Document } from \"yaml\";\nimport type { MrsfDocument, Comment } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Lenient parse result\n// ---------------------------------------------------------------------------\n\n/** Result from a lenient (non-throwing) parse attempt. */\nexport interface LenientParseResult {\n  /** Fully parsed document, or null if parsing failed entirely. */\n  doc: MrsfDocument | null;\n  /** If parsing failed or produced warnings, the error message. */\n  error?: string;\n  /** Comments that could be salvaged from a partially-corrupted sidecar. */\n  partialComments?: Comment[];\n}\n\n// ---------------------------------------------------------------------------\n// Parsing (string \u2192 document)\n// ---------------------------------------------------------------------------\n\n/**\n * Parse MRSF sidecar content from a string.\n * Detects JSON vs YAML based on content or optional filename hint.\n */\nexport function parseSidecarContent(\n  content: string,\n  filenameHint?: string,\n): MrsfDocument {\n  const trimmed = content.trim();\n\n  let parsed: unknown;\n\n  // Detect JSON by content or filename\n  const isJson =\n    trimmed.startsWith(\"{\") ||\n    (filenameHint && filenameHint.endsWith(\".review.json\"));\n\n  if (isJson) {\n    try {\n      parsed = JSON.parse(trimmed);\n    } catch (e) {\n      throw new Error(`Failed to parse JSON: ${(e as Error).message}`);\n    }\n  } else {\n    try {\n      parsed = yaml.load(trimmed, { schema: yaml.JSON_SCHEMA });\n    } catch (e) {\n      throw new Error(`Failed to parse YAML: ${(e as Error).message}`);\n    }\n  }\n\n  if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n    throw new Error(\"MRSF sidecar must be a YAML/JSON object\");\n  }\n\n  return parsed as MrsfDocument;\n}\n\n/**\n * Lenient parse from string content.\n */\nexport function parseSidecarContentLenient(\n  content: string,\n  filenameHint?: string,\n): LenientParseResult {\n  const trimmed = content.trim();\n  if (!trimmed) {\n    return { doc: null, error: \"File is empty\" };\n  }\n\n  const isJson =\n    trimmed.startsWith(\"{\") ||\n    (filenameHint && filenameHint.endsWith(\".review.json\"));\n\n  // First, try a normal parse\n  let parsed: unknown;\n  try {\n    parsed = isJson ? JSON.parse(trimmed) : yaml.load(trimmed, { schema: yaml.JSON_SCHEMA });\n  } catch (e) {\n    // Total parse failure \u2014 try to salvage what we can from YAML\n    if (!isJson) {\n      return salvageYaml(trimmed);\n    }\n    return { doc: null, error: `Failed to parse JSON: ${(e as Error).message}` };\n  }\n\n  if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n    return { doc: null, error: \"MRSF sidecar must be a YAML/JSON object\" };\n  }\n\n  const obj = parsed as Record<string, unknown>;\n  const doc: MrsfDocument = {\n    mrsf_version: typeof obj.mrsf_version === \"string\" ? obj.mrsf_version : \"1.0\",\n    document: typeof obj.document === \"string\" ? obj.document : \"unknown\",\n    comments: [],\n  };\n\n  if (!Array.isArray(obj.comments)) {\n    return {\n      doc,\n      error: \"comments field is not an array \u2014 file may be corrupted\",\n    };\n  }\n\n  // Validate each comment individually\n  const good: Comment[] = [];\n  const bad: number[] = [];\n\n  for (let i = 0; i < obj.comments.length; i++) {\n    const c = obj.comments[i];\n    if (c && typeof c === \"object\" && !Array.isArray(c) && typeof (c as Record<string, unknown>).id === \"string\") {\n      good.push(c as Comment);\n    } else {\n      bad.push(i);\n    }\n  }\n\n  doc.comments = good;\n\n  if (bad.length > 0) {\n    return {\n      doc,\n      error: `${bad.length} comment(s) at indices [${bad.join(\", \")}] were malformed and skipped`,\n      partialComments: good,\n    };\n  }\n\n  return { doc };\n}\n\n/**\n * Attempt to extract individual comment blocks from corrupted YAML by\n * splitting on `- id:` patterns and parsing each block independently.\n */\nfunction salvageYaml(content: string): LenientParseResult {\n  const salvaged: Comment[] = [];\n  let mrsf_version = \"1.0\";\n  let document = \"unknown\";\n\n  // Try to extract top-level fields from the beginning\n  const versionMatch = content.match(/^mrsf_version:\\s*[\"']?([^\"'\\n]+)/m);\n  if (versionMatch) mrsf_version = versionMatch[1].trim();\n\n  const docMatch = content.match(/^document:\\s*[\"']?([^\"'\\n]+)/m);\n  if (docMatch) document = docMatch[1].trim();\n\n  // Split on comment block boundaries (- id: ...)\n  const blocks = content.split(/(?=^  - id:\\s)/m);\n\n  for (const block of blocks) {\n    const trimmed = block.trim();\n    if (!trimmed.startsWith(\"- id:\")) continue;\n\n    // Wrap in a minimal YAML array context and try to parse\n    try {\n      const parsed = yaml.load(trimmed, { schema: yaml.JSON_SCHEMA });\n      if (Array.isArray(parsed) && parsed.length > 0) {\n        const c = parsed[0];\n        if (c && typeof c === \"object\" && typeof (c as Record<string, unknown>).id === \"string\") {\n          salvaged.push(c as Comment);\n        }\n      } else if (parsed && typeof parsed === \"object\" && typeof (parsed as Record<string, unknown>).id === \"string\") {\n        salvaged.push(parsed as Comment);\n      }\n    } catch {\n      // This block is unparseable \u2014 skip\n    }\n  }\n\n  const doc: MrsfDocument = {\n    mrsf_version,\n    document,\n    comments: salvaged,\n  };\n\n  return {\n    doc: salvaged.length > 0 ? doc : null,\n    error: `YAML parse failed. Salvaged ${salvaged.length} comment(s) from raw content.`,\n    partialComments: salvaged.length > 0 ? salvaged : undefined,\n  };\n}\n\n// ---------------------------------------------------------------------------\n// Serialization (document \u2192 string)\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize an MrsfDocument to YAML (for new files / non-round-trip use).\n */\nexport function toYaml(doc: MrsfDocument): string {\n  const yamlDoc = new Document(doc);\n  return yamlDoc.toString({ lineWidth: 0 });\n}\n\n/**\n * Serialize an MrsfDocument to JSON.\n */\nexport function toJson(doc: MrsfDocument): string {\n  return JSON.stringify(doc, null, 2) + \"\\n\";\n}\n"],
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,2BAAAA;AAAA,EAAA,sBAAAC;AAAA,EAAA,4BAAAC;AAAA,EAAA,+BAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,gCAAAC;AAAA,EAAA,gCAAAC;AAAA,EAAA,kBAAAC;AAAA,EAAA,oBAAAC;AAAA,EAAA,mBAAAC;AAAA,EAAA,wBAAAC;AAAA,EAAA;AAAA,sBAAAC;AAAA,EAAA,uBAAAC;AAAA,EAAA,mBAAAC;AAAA,EAAA,2BAAAC;AAAA,EAAA,kCAAAC;AAAA,EAAA,uBAAAC;AAAA,EAAA,6BAAAC;AAAA,EAAA,4BAAAC;AAAA,EAAA,+BAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,cAAAC;AAAA,EAAA,uBAAAC;AAAA,EAAA,cAAAC;AAAA,EAAA,qBAAAC;AAAA,EAAA,wBAAAC;AAAA;AAAA;;;ACOA,iCAAwC;AAGjC,IAAM,4BAA4B;AAQlC,SAAS,uBAAuB,OAAmC;AACxE,QAAM,gBAAgB,oBAAI,IAAsB;AAChD,QAAM,kBAAkB,oBAAI,IAAsB;AAClD,WAAS,OAAO,GAAG,OAAO,MAAM,QAAQ,QAAQ,GAAG;AACjD,sBAAkB,eAAe,cAAc,MAAM,IAAI,CAAC,GAAG,IAAI;AACjE,sBAAkB,iBAAiB,kBAAkB,MAAM,IAAI,CAAC,GAAG,IAAI;AAAA,EACzE;AACA,SAAO,EAAE,OAAO,eAAe,gBAAgB;AACjD;AASO,SAAS,WACd,OACA,QACkB;AAClB,MAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,QAAM,UAA4B,CAAC;AACnC,QAAM,cAAc,OAAO,MAAM,IAAI;AACrC,QAAM,kBAAkB,YAAY;AAGpC,WAAS,YAAY,GAAG,aAAa,MAAM,SAAS,iBAAiB,aAAa;AAEhF,UAAM,cAAc,MAAM,MAAM,WAAW,YAAY,eAAe;AACtE,UAAM,aAAa,YAAY,KAAK,IAAI;AAGxC,QAAI,oBAAoB,GAAG;AACzB,UAAI,MAAM;AACV,YAAM,OAAO,YAAY,CAAC;AAC1B,aAAO,MAAM,KAAK,QAAQ;AACxB,cAAM,MAAM,KAAK,QAAQ,QAAQ,GAAG;AACpC,YAAI,QAAQ,GAAI;AAChB,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aAAa;AAAA,UACb,WAAW,MAAM,OAAO;AAAA,UACxB,OAAO;AAAA,QACT,CAAC;AACD,cAAM,MAAM;AAAA,MACd;AAAA,IACF,OAAO;AAEL,YAAM,MAAM,WAAW,QAAQ,MAAM;AACrC,UAAI,QAAQ,IAAI;AAEd,cAAM,cAAc,WAAW,MAAM,GAAG,GAAG;AAC3C,cAAM,iBAAiB,YAAY,MAAM,IAAI;AAC7C,cAAM,WAAW,eAAe,eAAe,SAAS,CAAC,EAAE;AAG3D,cAAM,aAAa,OAAO,MAAM,IAAI;AACpC,cAAM,SAAS,WAAW,WAAW,SAAS,CAAC,EAAE;AACjD,YAAI,aAAa,KAAK,eAAe,WAAW,GAAG;AACjD,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,MAAM,YAAY,eAAe,SAAS;AAAA,YAC1C,SAAS,YAAY,eAAe,SAAS,IAAI,WAAW,SAAS;AAAA,YACrE,aAAa;AAAA,YACb,WAAW;AAAA,YACX,OAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAMA,SAAS,UAAU,MAAsB;AACvC,SAAO,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACxC;AAKO,SAAS,gBACd,OACA,QACkB;AAClB,QAAM,aAAa,UAAU,MAAM;AACnC,MAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,QAAM,UAA4B,CAAC;AAGnC,QAAM,qBAAqB,OAAO,MAAM,IAAI,EAAE;AAC9C,QAAM,YAAY,KAAK,IAAI,GAAG,qBAAqB,CAAC;AACpD,QAAM,YAAY,KAAK,IAAI,MAAM,SAAS,GAAG,qBAAqB,CAAC;AAEnE,WAAS,UAAU,WAAW,WAAW,WAAW,WAAW;AAC7D,aAAS,YAAY,GAAG,YAAY,UAAU,IAAI,MAAM,QAAQ,aAAa;AAC3E,YAAM,cAAc,MAAM,MAAM,WAAW,YAAY,OAAO;AAC9D,YAAM,aAAa,YAAY,KAAK,IAAI;AACxC,YAAM,aAAa,UAAU,UAAU;AAEvC,UAAI,WAAW,SAAS,UAAU,GAAG;AACnC,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,YAAY,UAAU;AAAA,UAC/B,aAAa;AAAA,UACb,WAAW,YAAY,YAAY,SAAS,CAAC,EAAE;AAAA,UAC/C,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO,sBAAsB,OAAO;AACtC;AAMA,SAAS,SAAS,MAAwB;AACxC,SAAO,KAAK,MAAM,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AACrD;AAKA,SAAS,UAAU,GAAa,GAAqB;AACnD,QAAM,IAAI,EAAE;AACZ,QAAM,IAAI,EAAE;AAEZ,MAAI,OAAO,IAAI,MAAc,IAAI,CAAC,EAAE,KAAK,CAAC;AAC1C,MAAI,OAAO,IAAI,MAAc,IAAI,CAAC,EAAE,KAAK,CAAC;AAE1C,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,UAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG;AACzB,aAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;AAAA,MAC1B,OAAO;AACL,aAAK,CAAC,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;AAAA,MACzC;AAAA,IACF;AACA,KAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI;AAC1B,SAAK,KAAK,CAAC;AAAA,EACb;AAEA,SAAO,KAAK,CAAC;AACf;AAMO,SAAS,cAAc,GAAW,GAAmB;AAC1D,QAAM,OAAO,SAAS,CAAC;AACvB,QAAM,OAAO,SAAS,CAAC;AACvB,MAAI,KAAK,WAAW,KAAK,KAAK,WAAW,EAAG,QAAO;AACnD,MAAI,KAAK,WAAW,KAAK,KAAK,WAAW,EAAG,QAAO;AACnD,QAAM,MAAM,UAAU,MAAM,IAAI;AAChC,SAAO,MAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,MAAM;AAChD;AASO,SAAS,iBAAiB,GAAW,GAAmB;AAC7D,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAC7C,QAAM,SAAS,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,MAAI,WAAW,EAAG,QAAO;AACzB,QAAM,WAAO,2BAAAC,UAAY,GAAG,CAAC;AAC7B,SAAO,IAAI,OAAO;AACpB;AAUO,SAAS,cAAc,QAAgB,WAA2B;AACvE,QAAM,SAAS,cAAc,QAAQ,SAAS;AAG9C,MAAI;AACJ,MAAI,OAAO,SAAS,OAAO,UAAU,SAAS,KAAK;AACjD,aAAS,iBAAiB,QAAQ,SAAS;AAAA,EAC7C,OAAO;AACL,aAAS;AAAA,EACX;AAGA,SAAO,SAAS,MAAM,SAAS;AACjC;AAcO,SAAS,YACd,OACA,QACA,YAAoB,KACpB,UACA,OACkB;AAClB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC,SAAS;AAAA,IACV;AAAA,IACA;AAAA,EACF,EAAE,IAAI,SAAS,KAAK,CAAC;AACvB;AAOO,SAAS,sBACd,OACA,QACA,YACA,UACA,QAA0B,uBAAuB,KAAK,GACvB;AAC/B,QAAM,mBAAmB,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC;AAChD,QAAM,UAAU,oBAAI,IAA8B;AAClD,MAAI,iBAAiB,WAAW,EAAG,QAAO;AAC1C,MAAI,CAAC,QAAQ;AACX,eAAW,aAAa,iBAAkB,SAAQ,IAAI,WAAW,CAAC,CAAC;AACnE,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,OAAO,MAAM,IAAI;AACrC,QAAM,kBAAkB,YAAY;AACpC,QAAM,aAA+B,CAAC;AACtC,QAAM,mBAAmB,KAAK,IAAI,GAAG,gBAAgB;AACrD,QAAM,iBAAiB,uBAAuB,OAAO,QAAQ,QAAQ;AAGrE,QAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,GAAG,CAAC;AAC/D,QAAM,YAAY,KAAK;AAAA,IACrB,MAAM,SAAS;AAAA,IACf,KAAK,KAAK,kBAAkB,GAAG,IAAI;AAAA,EACrC;AAEA,WAAS,UAAU,WAAW,WAAW,WAAW,WAAW;AAC7D,UAAM,aAAa,oBAAI,IAAY;AACnC,eAAW,iBAAiB,gBAAgB;AAC1C,eAAS,SAAS,GAAG,SAAS,SAAS,UAAU,GAAG;AAClD,cAAM,YAAY,gBAAgB;AAClC,YAAI,aAAa,KAAK,YAAY,UAAU,IAAI,MAAM,QAAQ;AAC5D,qBAAW,IAAI,SAAS;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AACA,eAAW,aAAa,YAAY;AAClC,YAAM,cAAc,MAAM,MAAM,WAAW,YAAY,OAAO;AAC9D,YAAM,aAAa,YAAY,KAAK,IAAI;AAExC,YAAM,QAAQ,cAAc,QAAQ,UAAU;AAE9C,UAAI,SAAS,kBAAkB;AAC7B,mBAAW,KAAK;AAAA,UACd,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,YAAY,UAAU;AAAA,UAC/B,aAAa;AAAA,UACb,WAAW,YAAY,YAAY,SAAS,CAAC,EAAE;AAAA,UAC/C;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,MAAI,oBAAoB,KAAK,OAAO,SAAS,KAAK;AAChD,eAAW,WAAW,gBAAgB;AACpC,YAAM,OAAO,MAAM,OAAO;AAC1B,UAAI,CAAC,KAAM;AAEX,YAAM,SAAS,OAAO;AACtB,YAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,GAAG,CAAC;AACtD,YAAM,YAAY,KAAK,IAAI,KAAK,QAAQ,KAAK,KAAK,SAAS,GAAG,CAAC;AAC/D,YAAM,UAAU,qBAAqB,WAAW,WAAW,CAAC;AAC5D,iBAAW,OAAO,SAAS;AACzB,iBAAS,MAAM,GAAG,MAAM,OAAO,KAAK,QAAQ,OAAO;AACjD,gBAAM,MAAM,KAAK,UAAU,KAAK,MAAM,GAAG;AACzC,gBAAM,QAAQ,cAAc,QAAQ,GAAG;AACvC,cAAI,SAAS,kBAAkB;AAC7B,uBAAW,KAAK;AAAA,cACd,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,cACb,WAAW,MAAM;AAAA,cACjB;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,sBAAsB,UAAU;AAChD,QAAM,SAAS,QAAQ,IAAI,CAAC,eAAe;AAAA,IACzC,WAAW,UAAU;AAAA,IACrB,WAAW,oBAAoB,WAAW,QAAQ;AAAA,EACpD,EAAE;AAEF,aAAW,aAAa,kBAAkB;AACxC,YAAQ;AAAA,MACN;AAAA,MACA,OACG,OAAO,CAAC,SAAS,KAAK,aAAa,SAAS,EAC5C,IAAI,CAAC,SAAS,KAAK,SAAS,EAC5B,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK;AAAA,IACnD;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBACP,OACA,QACA,UACU;AACV,QAAM,QAAQ,oBAAI,IAAoB;AACtC,QAAM,YAAY,KAAK,IAAI,GAAG,MAAM,MAAM,SAAS,CAAC;AACpD,QAAM,UAAU;AAAA,IACd,GAAG,eAAe,MAAM,eAAe,cAAc,MAAM,GAAG,CAAC;AAAA,IAC/D,GAAG,eAAe,MAAM,iBAAiB,kBAAkB,MAAM,GAAG,CAAC;AAAA,EACvE,EACG,KAAK,CAAC,MAAM,UAAU,KAAK,SAAS,SAAS,MAAM,SAAS,MAAM,EAClE,MAAM,GAAG,EAAE;AAEd,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,KAAK,MAAM,YAAY,OAAO,SAAS,MAAM;AAC5D,eAAW,QAAQ,OAAO,UAAU;AAClC,YAAM,IAAI,OAAO,MAAM,IAAI,IAAI,KAAK,KAAK,OAAO,SAAS,MAAM;AAAA,IACjE;AAAA,EACF;AAEA,MAAI,YAAY,MAAM;AACpB,aAAS,SAAS,IAAI,UAAU,GAAG,UAAU,GAAG;AAC9C,YAAM,OAAO,WAAW;AACxB,UAAI,QAAQ,KAAK,QAAQ,WAAW;AAClC,cAAM,IAAI,OAAO,MAAM,IAAI,IAAI,KAAK,KAAK,IAAI;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO,MAAM,KAAK,EAAE,QAAQ,UAAU,GAAG,CAAC,GAAGC,WAAUA,SAAQ,CAAC;AAAA,EAClE;AAEA,SAAO,CAAC,GAAG,MAAM,QAAQ,CAAC,EACvB;AAAA,IAAK,CAAC,MAAM,UACX,MAAM,CAAC,IAAI,KAAK,CAAC,KACd,iBAAiB,KAAK,CAAC,GAAG,QAAQ,IAAI,iBAAiB,MAAM,CAAC,GAAG,QAAQ,KACzE,KAAK,CAAC,IAAI,MAAM,CAAC;AAAA,EACtB,EACC,MAAM,GAAG,yBAAyB,EAClC,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AACzB;AAEA,SAAS,eACP,UACA,QACA,QAC+C;AAC/C,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,EACvB,IAAI,CAAC,WAAW,EAAE,UAAU,SAAS,IAAI,KAAK,KAAK,CAAC,GAAG,OAAO,EAAE,EAChE,OAAO,CAAC,WAAW,OAAO,SAAS,SAAS,CAAC;AAClD;AAEA,SAAS,kBACP,UACA,QACA,MACM;AACN,aAAW,SAAS,IAAI,IAAI,MAAM,GAAG;AACnC,UAAM,QAAQ,SAAS,IAAI,KAAK;AAChC,QAAI,OAAO;AACT,YAAM,KAAK,IAAI;AAAA,IACjB,OAAO;AACL,eAAS,IAAI,OAAO,CAAC,IAAI,CAAC;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,SAAS,cAAc,MAAwB;AAC7C,SAAO,KAAK,YAAY,EAAE,MAAM,mBAAmB,KAAK,CAAC;AAC3D;AAEA,SAAS,kBAAkB,MAAwB;AACjD,QAAM,aAAa,KAAK,YAAY,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAChE,QAAM,aAAa,CAAC,GAAG,UAAU;AACjC,MAAI,WAAW,SAAS,EAAG,QAAO,aAAa,CAAC,UAAU,IAAI,CAAC;AAC/D,QAAM,WAAqB,CAAC;AAC5B,WAAS,QAAQ,GAAG,SAAS,WAAW,SAAS,GAAG,SAAS,GAAG;AAC9D,aAAS,KAAK,WAAW,MAAM,OAAO,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,qBACP,SACA,SACA,OACU;AACV,MAAI,WAAW,QAAS,QAAO,CAAC,OAAO;AACvC,QAAM,SAAS,oBAAI,IAAY;AAC/B,WAAS,QAAQ,GAAG,QAAQ,OAAO,SAAS,GAAG;AAC7C,WAAO,IAAI,KAAK,MAAM,WAAW,UAAU,WAAW,SAAS,QAAQ,EAAE,CAAC;AAAA,EAC5E;AACA,SAAO,CAAC,GAAG,MAAM;AACnB;AAEA,SAAS,iBAAiB,MAAc,UAA2B;AACjE,SAAO,YAAY,OAAO,IAAI,KAAK,IAAI,OAAO,QAAQ;AACxD;AAMA,SAAS,sBACP,YACkB;AAClB,QAAM,OAAO,oBAAI,IAA4B;AAC7C,aAAW,KAAK,YAAY;AAC1B,UAAM,MAAM,GAAG,EAAE,IAAI,IAAI,EAAE,WAAW,IAAI,EAAE,OAAO,IAAI,EAAE,SAAS;AAClE,UAAM,WAAW,KAAK,IAAI,GAAG;AAC7B,QAAI,CAAC,YAAY,EAAE,QAAQ,SAAS,OAAO;AACzC,WAAK,IAAI,KAAK,CAAC;AAAA,IACjB;AAAA,EACF;AACA,SAAO,MAAM,KAAK,KAAK,OAAO,CAAC;AACjC;AAEA,SAAS,oBACP,WACA,UACgB;AAChB,MAAI,YAAY,KAAM,QAAO;AAE7B,QAAM,WAAW,KAAK,IAAI,UAAU,OAAO,QAAQ;AACnD,QAAM,iBAAiB,MAAM,KAAK,IAAI,GAAG,IAAI,WAAW,EAAE;AAC1D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,KAAK,IAAI,GAAK,UAAU,QAAQ,cAAc;AAAA,EACvD;AACF;;;ACjfA,kBAA6B;AAOtB,SAAS,aAAa,MAAc,QAAyB;AAClE,QAAM,cAAc,KAAK,KAAK;AAC9B,QAAM,gBAAgB,QAAQ,KAAK;AACnC,SAAO,gBAAgB,GAAG,WAAW,KAAK,aAAa,MAAM;AAC/D;AAEO,SAAS,YAAY,QAA8B;AACxD,QAAM,UAAU,OAAO,KAAK;AAC5B,QAAM,QAAQ,4BAA4B,KAAK,OAAO;AACtD,MAAI,CAAC,MAAO,QAAO,EAAE,MAAM,QAAQ;AAEnC,QAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,QAAM,SAAS,MAAM,CAAC,EAAE,KAAK;AAC7B,SAAO,SAAS,EAAE,MAAM,OAAO,IAAI,EAAE,KAAK;AAC5C;AAMO,SAAS,eAAuB;AACrC,aAAO,YAAAC,IAAO;AAChB;;;AC1BA,IAAM,iBAAiB;AAqBhB,SAAS,yBACd,aACA,aACyB;AACzB,QAAM,oBAAoB,uBAAuB,WAAW;AAC5D,QAAM,oBAAoB,uBAAuB,WAAW;AAC5D,QAAM,UAAU,oBAAI,IAAoB;AAExC,aAAW,CAAC,MAAM,iBAAiB,KAAK,mBAAmB;AACzD,UAAM,oBAAoB,kBAAkB,IAAI,IAAI;AACpD,QAAI,kBAAkB,WAAW,KAAK,mBAAmB,WAAW,GAAG;AACrE,cAAQ,IAAI,kBAAkB,CAAC,GAAG,kBAAkB,CAAC,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,aAAa,QAAQ;AAC7C;AAEO,SAAS,qBACd,SACA,YACA,WAC6B;AAC7B,MAAI,QAAQ,QAAQ,QAAQ,CAAC,QAAQ,cAAe,QAAO;AAE3D,QAAM,aAAa;AAAA,IACjB,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,MAAI,eAAe,QAAQ,cAAe,QAAO;AAEjD,QAAM,kBAAkB;AAAA,IACtB,WAAW;AAAA,IACX,QAAQ;AAAA,EACV;AACA,MAAI,gBAAgB,WAAW,GAAG;AAChC,UAAM,YAAY,gBAAgB,CAAC;AACnC,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA,UAAU;AAAA,MACV;AAAA,IACF;AACA,QAAI,kBAAkB,GAAG;AACvB,aAAO;AAAA,QACL,MAAM,UAAU;AAAA,QAChB,SAAS,UAAU;AAAA,QACnB,aAAa,UAAU;AAAA,QACvB,WAAW,UAAU;AAAA,QACrB,MAAM,UAAU;AAAA,QAChB,OAAO;AAAA,QACP,OAAO;AAAA,QACP;AAAA,QACA,eAAe;AAAA,QACf,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,MAAI,gBAAgB,SAAS,EAAG,QAAO;AAEvC,QAAM,YAAY,uBAAuB,SAAS,UAAU;AAC5D,MAAI,aAAa,KAAM,QAAO;AAC9B,QAAM,gBAAgB,UAAU;AAEhC,QAAM,YAAY,QAAQ,YAAY,QAAQ,QAAQ,QAAQ;AAC9D,QAAM,mBAAmB,gBAAgB;AACzC,MACE,gBAAgB,KACb,oBAAoB,WAAW,YAAY,QAC9C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,eAAe,SAAS,YAAY,aAAa;AACjE,QAAM,aAAa;AAAA,IACjB,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,MAAI,cAAc,KAAM,QAAO;AAE/B,QAAM,QAAQ,KAAK;AAAA,IACjB;AAAA,IACA,cAAc,QAAQ,eAAe,UAAU,IAAI;AAAA,EACrD;AACA,MAAI,QAAQ,UAAW,QAAO;AAE9B,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa,QAAQ;AAAA,IACrB,WAAW,QAAQ;AAAA,IACnB,MAAM;AAAA,IACN;AAAA,IACA,OAAO,eAAe,QAAQ;AAAA,IAC9B,gBAAgB,UAAU;AAAA,IAC1B,eAAe,UAAU;AAAA,IACzB,QAAQ;AAAA,EACV;AACF;AAEA,SAAS,uBAAuB,OAAwC;AACtE,QAAM,cAAc,oBAAI,IAAsB;AAE9C,WAAS,OAAO,GAAG,OAAO,MAAM,QAAQ,QAAQ,GAAG;AACjD,UAAM,OAAO,MAAM,IAAI;AACvB,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,UAAM,WAAW,YAAY,IAAI,IAAI;AACrC,QAAI,UAAU;AACZ,eAAS,KAAK,IAAI;AAAA,IACpB,OAAO;AACL,kBAAY,IAAI,MAAM,CAAC,IAAI,CAAC;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,6BACP,SACA,eACA,YACQ;AACR,QAAM,gBAAgB,QAAQ,YAAa,QAAQ;AACnD,QAAM,gBAAgB,gBAAiB,QAAQ;AAE/C,MACE,QAAQ,gBAAgB,QACrB,QAAQ,cAAc,MACzB;AACA,UAAM,sBAAsB,WAAW,QAAQ,IAAI,QAAQ,IAAc;AACzE,QAAI,wBAAwB,cAAe,QAAO;AAAA,EACpD;AAEA,MAAI,UAAU;AACd,WACM,WAAW,GACf,YAAY,gBACZ,YAAY,GACZ;AACA,eAAW,cAAc;AAAA,MACtB,QAAQ,OAAkB;AAAA,MAC3B,gBAAgB;AAAA,IAClB,GAAG;AACD,UAAI,aAAa,KAAK,cAAc,WAAW,YAAY,QAAQ;AACjE;AAAA,MACF;AACA,YAAM,aAAa,WAAW,QAAQ,IAAI,UAAU;AACpD,UAAI,cAAc,QAAQ,aAAa,eAAe,eAAe;AACnE,mBAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBACP,SACA,YAC+D;AAC/D,QAAM,aAAa,QAAQ;AAC3B,QAAM,gBAAgB,QAAQ,YAAY;AAC1C,QAAM,QAAQ,oBAAI,IAAgD;AAElE,WAAS,WAAW,GAAG,YAAY,gBAAgB,YAAY,GAAG;AAChE,eAAW,eAAe;AAAA,MACxB,aAAa;AAAA,MACb,gBAAgB;AAAA,IAClB,GAAG;AACD,UAAI,cAAc,KAAK,eAAe,WAAW,YAAY,QAAQ;AACnE;AAAA,MACF;AACA,YAAM,aAAa,WAAW,QAAQ,IAAI,WAAW;AACrD,UAAI,cAAc,KAAM;AACxB,YAAM,QAAQ,aAAa;AAC3B,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAI,MAAM;AACR,aAAK,SAAS;AACd,aAAK,UAAU,KAAK,IAAI,KAAK,SAAS,QAAQ;AAAA,MAChD,OAAO;AACL,cAAM,IAAI,OAAO,EAAE,OAAO,GAAG,SAAS,SAAS,CAAC;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,CAAC,GAAG,MAAM,QAAQ,CAAC,EAAE;AAAA,IAAK,CAAC,MAAM,UAC9C,MAAM,CAAC,EAAE,QAAQ,KAAK,CAAC,EAAE,SACtB,KAAK,CAAC,EAAE,UAAU,MAAM,CAAC,EAAE,WAC3B,KAAK,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,CAAC;AAAA,EAC1C;AACA,QAAM,OAAO,OAAO,CAAC;AACrB,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,KAAK,CAAC,EAAE,QAAQ,KAAK,KAAK,CAAC,EAAE,UAAU,EAAG,QAAO;AACrD,MACE,OAAO,CAAC,KACL,OAAO,CAAC,EAAE,CAAC,EAAE,UAAU,KAAK,CAAC,EAAE,SAC/B,OAAO,CAAC,EAAE,CAAC,EAAE,YAAY,KAAK,CAAC,EAAE,SACpC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS;AAC9C,SAAO;AAAA,IACL,MAAM,aAAa,KAAK,CAAC;AAAA,IACzB,SAAS,KAAK,CAAC,EAAE;AAAA,IACjB,SAAS,KAAK,CAAC,EAAE,QAAQ,iBAAiB,KAAK,CAAC,EAAE;AAAA,EACpD;AACF;AAEA,SAAS,eACP,SACA,YACA,YAC8C;AAC9C,MACE,QAAQ,QAAQ,QACZ,QAAQ,YAAY,QAAQ,QAAQ,aAAa,QAAQ,QAC1D,QAAQ,gBAAgB,QACxB,QAAQ,cAAc,MACzB;AACA,WAAO;AAAA,MACL,aAAa,QAAQ;AAAA,MACrB,WAAW,QAAQ;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,aAAa,WAAW,YAAY,QAAQ,IAAI;AACtD,QAAM,iBAAiB,WAAW,YAAY,UAAU;AACxD,QAAM,SAAS,WAAW,MAAM,GAAG,QAAQ,YAAY;AACvD,QAAM,SAAS,WAAW,MAAM,QAAQ,UAAU;AAClD,QAAM,cAAc,eAAe,WAAW,MAAM,IAChD,OAAO,SACP,KAAK,IAAI,QAAQ,cAAc,eAAe,MAAM;AACxD,QAAM,YAAY,eAAe,SAAS,MAAM,IAC5C,eAAe,SAAS,OAAO,SAC/B,KAAK;AAAA,IACL,eAAe;AAAA,IACf,eAAe,QAAQ,aAAa,QAAQ;AAAA,EAC9C;AAEF,SAAO,EAAE,aAAa,UAAU;AAClC;AAEA,SAAS,YACP,OACA,MACA,SACA,aACA,WACe;AACf,QAAM,YAAY,WAAW;AAC7B,MAAI,OAAO,KAAK,aAAa,MAAM,OAAQ,QAAO;AAElD,MAAI,SAAS,WAAW;AACtB,UAAM,OAAO,MAAM,IAAI;AACvB,WAAO,eAAe,QAAQ,aAAa,OACvC,KAAK,MAAM,aAAa,SAAS,IACjC;AAAA,EACN;AAEA,QAAM,SAAmB,CAAC;AAC1B,WAAS,UAAU,MAAM,WAAW,WAAW,WAAW,GAAG;AAC3D,QAAI,OAAO,MAAM,OAAO;AACxB,QAAI,YAAY,QAAQ,eAAe,KAAM,QAAO,KAAK,MAAM,WAAW;AAC1E,QAAI,YAAY,aAAa,aAAa,KAAM,QAAO,KAAK,MAAM,GAAG,SAAS;AAC9E,WAAO,KAAK,IAAI;AAAA,EAClB;AACA,SAAO,OAAO,KAAK,IAAI;AACzB;;;ACtSA,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AAClB,IAAM,+BAA+B;AA+DrC,SAAS,yBACd,aACA,aACoB;AACpB,SAAO;AAAA,IACL,QAAQ,yBAAyB,WAAW;AAAA,IAC5C,QAAQ,yBAAyB,WAAW;AAAA,EAC9C;AACF;AAEO,SAAS,qBACd,SACA,OACqC;AACrC,MAAI,QAAQ,QAAQ,QAAQ,CAAC,QAAQ,cAAe,QAAO;AAC3D,QAAM,mBAAmB,MAAM,OAAO,YAAY,IAAI,QAAQ,IAAI;AAClE,MAAI,oBAAoB,KAAM,QAAO;AACrC,QAAM,cAAc,MAAM,OAAO,OAAO,gBAAgB;AACxD,QAAM,aAAaC;AAAA,IACjB,MAAM,OAAO;AAAA,IACb,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,MAAI,eAAe,QAAQ,cAAe,QAAO;AACjD,QAAM,wBAAwBA;AAAA,IAC5B,MAAM,OAAO;AAAA,IACb,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,MAAI,0BAA0B,QAAQ,eAAe;AACnD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM,QAAQ;AAAA,MACd,SAAS,QAAQ,YAAY,QAAQ;AAAA,MACrC,aAAa,QAAQ;AAAA,MACrB,WAAW,QAAQ;AAAA,MACnB,MAAM,QAAQ;AAAA,MACd,iBAAiB;AAAA,MACjB,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,aAAa,4BAA4B,SAAS,KAAK;AAC7D,QAAM,OAAO,WAAW,CAAC;AACzB,MAAI,CAAC,MAAM;AACT,QACE,MAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE,SAAS,QAAQ,aAAa,GACrE;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,iBAAiB;AAAA,MACjB,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,WAAW,CAAC,KAAK,KAAK,QAAQ,WAAW,CAAC,EAAE,QAAQ,kBAAkB;AACxE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,iBAAiB,KAAK,QAAQ,WAAW,CAAC,EAAE;AAAA,MAC5C,QACE,wCAAwC,KAAK,MAAM,QAAQ,CAAC,CAAC,OACxD,WAAW,CAAC,EAAE,MAAM,QAAQ,CAAC,CAAC;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,oBAAoB,KAAK,SAC1B;AAAA,IACD,MAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,IAAI;AAAA,IACrC,QAAQ;AAAA,EACV,IAAI;AACN,SAAO;AAAA,IACL,QAAQ,KAAK,SAAS,CAAC,oBAAoB,aAAa;AAAA,IACxD,OAAO,KAAK,SAAS,CAAC,oBAAoB,IAAI,KAAK;AAAA,IACnD,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK;AAAA,IAChB,MAAM,KAAK;AAAA,IACX,iBAAiB,WAAW,CAAC,IAAI,KAAK,QAAQ,WAAW,CAAC,EAAE,QAAQ;AAAA,IACpE,QAAQ,KAAK,SAAS,CAAC,oBACnB,gFACA,oBACE,oEACA;AAAA,EACR;AACF;AAEO,SAAS,4BACd,SACA,OAC0B;AAC1B,MAAI,QAAQ,QAAQ,QAAQ,CAAC,QAAQ,cAAe,QAAO,CAAC;AAC5D,QAAM,mBAAmB,MAAM,OAAO,YAAY,IAAI,QAAQ,IAAI;AAClE,MAAI,oBAAoB,KAAM,QAAO,CAAC;AACtC,QAAM,cAAc,MAAM,OAAO,OAAO,gBAAgB;AACxD,QAAM,aAAaA;AAAA,IACjB,MAAM,OAAO;AAAA,IACb,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,MAAI,eAAe,QAAQ,cAAe,QAAO,CAAC;AAElD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,EACF,EACG,IAAI,CAAC,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF,EAAE,EACD,OAAO,CAAC,cAAc,UAAU,SAAS,eAAe,EACxD;AAAA,IAAK,CAAC,MAAM,UACX,MAAM,QAAQ,KAAK,SAChB,KAAK,IAAI,KAAK,YAAa,QAAQ,IAAe,IACjD,KAAK,IAAI,MAAM,YAAa,QAAQ,IAAe;AAAA,EACzD,EACC,IAAI,CAAC,cAAc;AAClB,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM;AAAA,IACR;AACA,WAAO;AAAA,MACL,OAAO,UAAU;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,aAAa,MAAM;AAAA,MACnB,WAAW,MAAM;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM,SAAS,QAAQ;AAAA,IAChC;AAAA,EACF,CAAC;AACL;AAEO,SAAS,sBACd,SACA,OACoB;AACpB,MAAI,QAAQ,QAAQ,KAAM,QAAO;AACjC,QAAM,aAAa,MAAM,OAAO,YAAY,IAAI,QAAQ,IAAI;AAC5D,MAAI,cAAc,KAAM,QAAO;AAC/B,SAAO,MAAM,OAAO,OAAO,UAAU,EAAE,YAAY,KAAK,GAAQ;AAClE;AAEA,SAAS,yBAAyB,OAAqC;AACrE,QAAM,SAA0B,CAAC;AACjC,QAAM,cAAc,oBAAI,IAAoB;AAC5C,QAAM,WAAoD,CAAC;AAC3D,MAAI,OAAO;AAEX,SAAO,OAAO,MAAM,QAAQ;AAC1B,QAAI,CAAC,MAAM,IAAI,EAAE,KAAK,GAAG;AACvB,cAAQ;AACR;AAAA,IACF;AAEA,UAAM,YAAY;AAClB,UAAM,SAAS,aAAa,MAAM,IAAI,CAAC;AACvC,QAAI,OAAO,SAAS,WAAW;AAC7B,aACE,SAAS,SAAS,KACf,SAAS,SAAS,SAAS,CAAC,EAAE,SAAS,OAAO,cACjD;AACA,iBAAS,IAAI;AAAA,MACf;AACA,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,IAAI,CAAC,YAAY,QAAQ,KAAK;AAAA,MACzC;AACA,aAAO,KAAK,KAAK;AACjB,eAAS,KAAK,EAAE,OAAO,OAAO,cAAc,OAAO,OAAO,aAAa,CAAC;AACxE,cAAQ;AACR;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,QAAQ;AAC1B,cAAQ;AACR,aAAO,OAAO,MAAM,UAAU,CAAC,MAAM,IAAI,EAAE,UAAU,EAAE,WAAW,KAAK,GAAG;AACxE,gBAAQ;AAAA,MACV;AACA,UAAI,OAAO,MAAM,OAAQ,SAAQ;AAAA,IACnC,OAAO;AACL,cAAQ;AACR,aACE,OAAO,MAAM,UACV,MAAM,IAAI,EAAE,KAAK,KACjB,eAAe,OAAO,MAAM,MAAM,IAAI,CAAC,GAC1C;AACA,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS,IAAI,CAAC,YAAY,QAAQ,KAAK;AAAA,IACzC,CAAC;AAAA,EACH;AAEA,aAAW,CAAC,YAAY,KAAK,KAAK,OAAO,QAAQ,GAAG;AAClD,aAAS,YAAY,MAAM,WAAW,aAAa,MAAM,SAAS,aAAa,GAAG;AAChF,kBAAY,IAAI,WAAW,UAAU;AAAA,IACvC;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,oBAAoB,MAAM;AAAA,EAC3C;AACF;AAEA,SAAS,UACP,OACA,WACA,SACA,MACA,aACe;AACf,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,MAAM,MAAM,WAAW,UAAU,CAAC,EAAE,KAAK,IAAI;AAAA,IACnD;AAAA,EACF;AACF;AAEA,SAAS,aAAa,MAIpB;AACA,QAAM,UAAU,KAAK,MAAM,mBAAmB;AAC9C,MAAI,SAAS;AACX,WAAO;AAAA,MACL,MAAM;AAAA,MACN,cAAc,QAAQ,CAAC,EAAE;AAAA,MACzB,cAAc,QAAQ,CAAC,EAAE,KAAK;AAAA,IAChC;AAAA,EACF;AACA,MAAI,KAAK,UAAU,EAAE,WAAW,KAAK,GAAG;AACtC,WAAO,EAAE,MAAM,QAAQ,cAAc,GAAG,cAAc,GAAG;AAAA,EAC3D;AACA,MAAI,yBAAyB,KAAK,IAAI,GAAG;AACvC,WAAO,EAAE,MAAM,QAAQ,cAAc,GAAG,cAAc,GAAG;AAAA,EAC3D;AACA,MAAI,SAAS,KAAK,IAAI,GAAG;AACvB,WAAO,EAAE,MAAM,SAAS,cAAc,GAAG,cAAc,GAAG;AAAA,EAC5D;AACA,MAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,WAAO,EAAE,MAAM,cAAc,cAAc,GAAG,cAAc,GAAG;AAAA,EACjE;AACA,SAAO,EAAE,MAAM,aAAa,cAAc,GAAG,cAAc,GAAG;AAChE;AAEA,SAAS,eAAe,MAAiB,MAAuB;AAC9D,MAAI,SAAS,OAAQ,QAAO,yBAAyB,KAAK,IAAI;AAC9D,MAAI,SAAS,QAAS,QAAO,SAAS,KAAK,IAAI;AAC/C,MAAI,SAAS,aAAc,QAAO,QAAQ,KAAK,IAAI;AACnD,MAAI,SAAS,aAAa;AACxB,UAAM,OAAO,aAAa,IAAI;AAC9B,WAAO,KAAK,SAAS;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAAS,uBACP,aACA,kBACA,cACA,OACmB;AACnB,QAAM,SAAS,MAAM;AACrB,QAAM,aAAgC,CAAC;AAEvC,aAAW,SAAS;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAG;AACD,UAAM,QAAQ,OAAO,OAAO,KAAK;AACjC,eAAW,KAAK,kBAAkB,QAAQ,OAAO,KAAK,CAAC;AAEvD,QACE,YAAY,SAAS,eAClB,MAAM,SAAS,eACf,OAAO,OAAO,QAAQ,CAAC,GAAG,SAAS,eACnC,SAAS,MAAM,aAAa,OAAO,OAAO,QAAQ,CAAC,EAAE,WAAW,GACnE;AACA,iBAAW,KAAK,kBAAkB,QAAQ,OAAO,QAAQ,CAAC,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,oBACP,QACuB;AACvB,QAAM,WAAW,oBAAI,IAAsB;AAC3C,aAAW,CAAC,YAAY,KAAK,KAAK,OAAO,QAAQ,GAAG;AAClD,eAAW,SAAS,IAAI,IAAIC,UAAS,MAAM,IAAI,CAAC,GAAG;AACjD,YAAM,iBAAiB,SAAS,IAAI,KAAK;AACzC,UAAI,gBAAgB;AAClB,uBAAe,KAAK,UAAU;AAAA,MAChC,OAAO;AACL,iBAAS,IAAI,OAAO,CAAC,UAAU,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAMA,SAAS,wBACP,aACA,kBACA,cACA,OACU;AACV,QAAM,QAAQ,oBAAI,IAAoB;AACtC,QAAM,cAAc,MAAM,OAAO,OAAO;AACxC,QAAM,cAAc,CAClB,MACA,cACA,WACS;AACT,QAAI,CAAC,KAAM;AACX,UAAM,eAAe,CAAC,GAAG,IAAI,IAAIA,UAAS,IAAI,CAAC,CAAC,EAC7C,IAAI,CAAC,WAAW;AAAA,MACf;AAAA,MACA,UAAU,MAAM,OAAO,cAAc,IAAI,KAAK,KAAK,CAAC;AAAA,IACtD,EAAE,EACD,OAAO,CAAC,SAAS,KAAK,SAAS,SAAS,CAAC,EACzC,KAAK,CAAC,MAAM,UAAU,KAAK,SAAS,SAAS,MAAM,SAAS,MAAM,EAClE,MAAM,GAAG,EAAE;AAEd,eAAW,EAAE,SAAS,KAAK,cAAc;AACvC,YAAM,SAAS,KAAK,MAAM,cAAc,SAAS,MAAM;AACvD,iBAAW,WAAW,UAAU;AAC9B,cAAM,YAAY,UAAU;AAC5B,YAAI,aAAa,KAAK,YAAY,aAAa;AAC7C,gBAAM,IAAI,YAAY,MAAM,IAAI,SAAS,KAAK,KAAK,SAAS,MAAM;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,cAAY,YAAY,MAAM,GAAG,CAAC;AAClC,cAAY,MAAM,OAAO,OAAO,mBAAmB,CAAC,GAAG,MAAM,GAAG,GAAG;AACnE,cAAY,MAAM,OAAO,OAAO,mBAAmB,CAAC,GAAG,MAAM,IAAI,GAAG;AAEpE,QAAM,cAAc,mBAAmB,MAAM,OAAO,QAAQ,YAAY;AACxE,MAAI,eAAe,MAAM;AACvB,aAAS,SAAS,IAAI,UAAU,GAAG,UAAU,GAAG;AAC9C,YAAM,YAAY,cAAc;AAChC,UAAI,aAAa,KAAK,YAAY,aAAa;AAC7C,cAAM,IAAI,YAAY,MAAM,IAAI,SAAS,KAAK,KAAK,IAAI;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,MAAM,QAAQ,CAAC,EACvB;AAAA,IAAK,CAAC,MAAM,UACX,MAAM,CAAC,IAAI,KAAK,CAAC,KACd,KAAK,IAAI,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC,EAAE,YAAY,YAAY,IAC7D,KAAK,IAAI,MAAM,OAAO,OAAO,MAAM,CAAC,CAAC,EAAE,YAAY,YAAY,KAChE,KAAK,CAAC,IAAI,MAAM,CAAC;AAAA,EACtB,EACC,MAAM,GAAG,4BAA4B,EACrC,IAAI,CAAC,CAAC,UAAU,MAAM,UAAU;AACrC;AAEA,SAAS,mBACP,QACA,MACoB;AACpB,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,MAAI,MAAM;AACV,MAAI,OAAO,OAAO,SAAS;AAC3B,SAAO,OAAO,MAAM;AAClB,UAAM,SAAS,KAAK,OAAO,MAAM,QAAQ,CAAC;AAC1C,UAAM,QAAQ,OAAO,MAAM;AAC3B,QAAI,OAAO,MAAM,WAAW;AAC1B,aAAO,SAAS;AAAA,IAClB,WAAW,OAAO,MAAM,SAAS;AAC/B,YAAM,SAAS;AAAA,IACjB,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,OAAO,OAAO,OAAQ,QAAO,OAAO,SAAS;AACjD,MAAI,OAAO,EAAG,QAAO;AACrB,SAAO,KAAK,IAAI,OAAO,GAAG,EAAE,YAAY,IAAI,IACtC,KAAK,IAAI,OAAO,IAAI,EAAE,UAAU,IAAI,IACtC,MACA;AACN;AAEA,SAAS,kBACP,QACA,YACA,UACiB;AACjB,QAAM,QAAQ,OAAO,OAAO,UAAU;AACtC,QAAM,OAAO,OAAO,OAAO,QAAQ;AACnC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW,MAAM;AAAA,IACjB,SAAS,KAAK;AAAA,IACd,MAAM,MAAM;AAAA,IACZ,MAAM,OAAO,MAAM,MAAM,MAAM,WAAW,KAAK,UAAU,CAAC,EAAE,KAAK,IAAI;AAAA,IACrE,aAAa,MAAM;AAAA,IACnB,OAAO;AAAA,EACT;AACF;AAEA,SAAS,eACP,aACA,kBACA,WACA,OACA,cACQ;AACR,QAAM,UAAU,eAAe,YAAY,MAAM,UAAU,IAAI;AAC/D,QAAM,OAAO,YAAY,SAAS,UAAU,OAAO,IAAI;AACvD,QAAM,UAAU,eAAe,YAAY,aAAa,UAAU,WAAW;AAC7E,QAAM,WAAW;AAAA,IACf,MAAM,OAAO,OAAO,mBAAmB,CAAC;AAAA,IACxC,MAAM,OAAO,OAAO,UAAU,aAAa,CAAC;AAAA,EAC9C;AACA,QAAM,OAAO;AAAA,IACX,MAAM,OAAO,OAAO,mBAAmB,CAAC;AAAA,IACxC,MAAM,OAAO,OAAO,UAAU,WAAW,CAAC;AAAA,EAC5C;AACA,QAAM,YAAY,KAAK;AAAA,IACrB;AAAA,IACA,IAAI,KAAK,IAAI,UAAU,YAAY,YAAY,IAAI;AAAA,EACrD;AAEA,SAAO,KAAK;AAAA,IACV;AAAA,IACA,UAAU,OACN,OAAO,MACP,UAAU,MACV,WAAW,OACX,OAAO,OACP,YAAY;AAAA,EAClB;AACF;AAEA,SAAS,mBACP,QACA,QACQ;AACR,MAAI,CAAC,UAAU,CAAC,OAAQ,QAAO;AAC/B,SAAO,eAAe,OAAO,MAAM,OAAO,IAAI;AAChD;AAEA,SAAS,eAAe,MAAc,OAAuB;AAC3D,SAAO,KAAK;AAAA,IACV,UAAU,MAAM,KAAK;AAAA,IACrB,cAAc,cAAc,IAAI,GAAG,cAAc,KAAK,CAAC;AAAA,EACzD;AACF;AAEA,SAAS,eAAe,MAAgB,OAAyB;AAC/D,MAAI,KAAK,WAAW,KAAK,MAAM,WAAW,EAAG,QAAO;AACpD,SAAO,UAAU,KAAK,KAAK,GAAG,GAAG,MAAM,KAAK,GAAG,CAAC;AAClD;AAEA,SAAS,UAAU,MAAc,OAAuB;AACtD,QAAM,aAAaA,UAAS,IAAI;AAChC,QAAM,cAAcA,UAAS,KAAK;AAClC,MAAI,WAAW,WAAW,KAAK,YAAY,WAAW,EAAG,QAAO;AAChE,QAAM,YAAY,oBAAI,IAAoB;AAC1C,aAAW,SAAS,aAAa;AAC/B,cAAU,IAAI,QAAQ,UAAU,IAAI,KAAK,KAAK,KAAK,CAAC;AAAA,EACtD;AACA,MAAI,UAAU;AACd,aAAW,SAAS,YAAY;AAC9B,UAAM,QAAQ,UAAU,IAAI,KAAK,KAAK;AACtC,QAAI,QAAQ,GAAG;AACb,iBAAW;AACX,gBAAU,IAAI,OAAO,QAAQ,CAAC;AAAA,IAChC;AAAA,EACF;AACA,SAAQ,IAAI,WAAY,WAAW,SAAS,YAAY;AAC1D;AAEA,SAASA,UAAS,MAAwB;AACxC,SAAO,cAAc,IAAI,EAAE,MAAM,mBAAmB,KAAK,CAAC;AAC5D;AAEA,SAAS,cAAc,MAAsB;AAC3C,SAAO,KAAK,YAAY,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACtD;AAEA,SAAS,SAAS,MAAgB,OAA0B;AAC1D,SAAO,KAAK,WAAW,MAAM,UACxB,KAAK,MAAM,CAAC,MAAM,UAAU,SAAS,MAAM,KAAK,CAAC;AACxD;AAEA,SAAS,sBACP,SACA,aACA,WACA,QAOA;AACA,QAAM,aAAa,UAAU,KAAK,QAAQ,QAAQ,aAAuB;AACzE,QAAM,uBACJ,QAAQ,SAAS,YAAY,cACzB,QAAQ,YAAY,QAAQ,UAAU,YAAY,WACnD,QAAQ,gBAAgB,QACxB,QAAQ,cAAc,QACtB,QAAQ,kBAAkB,YAAY;AAC3C,QAAM,2BACJ,iBAAiB,YAAY,MAAM,QAAQ,aAAuB,MAAM;AAC1E,MAAI,cAAc,MAAM,wBAAwB,2BAA2B;AACzE,WAAO;AAAA,MACL,UAAU;AAAA,MACV,UAAU;AAAA,MACV,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,MAAI,sBAAsB;AACxB,WAAO;AAAA,MACL,MAAM,UAAU;AAAA,MAChB,SAAS,UAAU;AAAA,MACnB,MAAM,UAAU;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,eAAgB,QAAQ,OAAkB,YAAY;AAC5D,QAAM,OAAO,KAAK,IAAI,UAAU,SAAS,UAAU,YAAY,YAAY;AAC3E,QAAM,YAAY,QAAQ,YAAY,QAAQ,QACzC,QAAQ;AACb,QAAM,UAAU,KAAK,IAAI,UAAU,SAAS,OAAO,QAAQ;AAC3D,QAAM,cAAc,QAAQ;AAC5B,QAAM,YAAY,QAAQ;AAC1B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAMD;AAAA,MACJ,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,KAAK;AAAA,EACP;AACF;AAEA,SAAS,iBAAiB,MAAc,QAAwB;AAC9D,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,SAAO,UAAU,KAAK,SAAS,OAAO,QAAQ;AAC5C,UAAM,QAAQ,KAAK,QAAQ,QAAQ,MAAM;AACzC,QAAI,QAAQ,EAAG;AACf,aAAS;AACT,aAAS,QAAQ;AAAA,EACnB;AACA,SAAO;AACT;AAEA,SAAS,WACP,WACA,eACA,cACA,OAOA;AACA,QAAM,SAAS,cAAc,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI;AACvD,QAAM,gBAAgB,aAAa,MAAM,IAAI;AAC7C,QAAM,OAAO,YAAY,OAAO,SAAS;AACzC,QAAM,cAAc,OAAO,GAAG,EAAE,GAAG,UAAU;AAC7C,QAAM,0BAA0B,cAAc,GAAG,EAAE,GAAG,UAAU;AAChE,SAAO;AAAA,IACL;AAAA,IACA,SAAS,OAAO,cAAc,SAAS;AAAA,IACvC;AAAA,IACA,WAAW,cAAc,WAAW,IAChC,cAAc,0BACd;AAAA,IACJ,MAAM;AAAA,EACR;AACF;AAEA,SAASA,aACP,OACA,MACA,SACA,aACA,WACe;AACf,QAAM,YAAY,WAAW;AAC7B,MAAI,OAAO,KAAK,aAAa,MAAM,OAAQ,QAAO;AAClD,MAAI,SAAS,WAAW;AACtB,UAAM,OAAO,MAAM,IAAI;AACvB,WAAO,eAAe,QAAQ,aAAa,OACvC,KAAK,MAAM,aAAa,SAAS,IACjC;AAAA,EACN;AAEA,QAAM,SAAmB,CAAC;AAC1B,WAAS,UAAU,MAAM,WAAW,WAAW,WAAW,GAAG;AAC3D,QAAI,OAAO,MAAM,OAAO;AACxB,QAAI,YAAY,QAAQ,eAAe,KAAM,QAAO,KAAK,MAAM,WAAW;AAC1E,QAAI,YAAY,aAAa,aAAa,KAAM,QAAO,KAAK,MAAM,GAAG,SAAS;AAC9E,WAAO,KAAK,IAAI;AAAA,EAClB;AACA,SAAO,OAAO,KAAK,IAAI;AACzB;;;ACrsBO,SAAS,wBACd,WACA,cACA,WACA,YAC8B;AAC9B,MAAI,WAAW,OAAO;AACpB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,gBAAgB,WAAW,cAAc,SAAS;AAAA,IAC5D;AAAA,EACF;AACA,MAAI,YAAY,WAAW,YAAY;AACrC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,iBAAiB,WAAW,cAAc,UAAU;AAAA,IAC9D;AAAA,EACF;AAEA,MAAI,aAAa,YAAY;AAC3B,QAAI,UAAU,WAAW,UAAU,GAAG;AACpC,YAAM,SAAS,iBAAiB,WAAW,cAAc,UAAU;AACnE,aAAO,SAAS;AAChB,aAAO,QAAQ,yBAAyB,UAAU,OAAO,WAAW,KAAK;AACzE,aAAO,SACL,+EACiB,OAAO,MAAM,QAAQ,CAAC,CAAC;AAC1C,aAAO,EAAE,MAAM,YAAY,OAAO;AAAA,IACpC;AAEA,QAAI,WAAW,WAAW,cAAc,CAAC,mBAAmB,SAAS,GAAG;AACtE,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,iBAAiB,WAAW,cAAc,UAAU;AAAA,MAC9D;AAAA,IACF;AAEA,QACE,WAAW,WAAW,WACnB,WAAW,mBAAmB,QAC9B,WAAW,SAAS,UAAU,QAAQ,KACzC;AACA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,iBAAiB,WAAW,cAAc,UAAU;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,QACN;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,KAAK,IAAI,UAAU,OAAO,WAAW,KAAK;AAAA,QACjD,QACE,0DACK,UAAU,IAAI,sCACd,WAAW,QAAQ,aAAa;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY;AACd,UAAM,OAAO,WAAW,WAAW,aAC/B,aACA,WAAW,WAAW,cACpB,cACA;AACN,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,iBAAiB,WAAW,cAAc,UAAU;AAAA,IAC9D;AAAA,EACF;AAEA,MAAI,WAAW;AACb,QAAI,CAAC,mBAAmB,SAAS,EAAG,QAAO;AAC3C,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,gBAAgB,WAAW,cAAc,SAAS;AAAA,IAC5D;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,mBAAmB,WAAqC;AAC/D,SAAO,UAAU,kBAAkB,KAC7B,UAAU,kBAAkB,KAAK,UAAU,iBAAiB;AACpE;AAEA,SAAS,UACP,WACA,YACS;AACT,SAAO,UAAU,SAAS,WAAW,QAChC,UAAU,YAAY,WAAW;AACxC;AAEA,SAAS,yBAAyB,MAAc,OAAuB;AACrE,SAAO,KAAK,IAAI,OAAO,OAAO,SAAS,IAAI,IAAI;AACjD;AAEA,SAAS,gBACP,WACA,cACA,WACgB;AAChB,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,UAAU,QAAQ,aAAa;AAAA,IACvC,OAAO,UAAU;AAAA,IACjB,SAAS,UAAU;AAAA,IACnB,YAAY,UAAU;AAAA,IACtB,gBAAgB,UAAU;AAAA,IAC1B,cAAc,UAAU;AAAA,IACxB,cAAc,UAAU,QAAQ,SAAY,UAAU;AAAA,IACtD,sBAAsB,UAAU,QAAQ,SAAY;AAAA,IACpD,QAAQ,UAAU;AAAA,EACpB;AACF;AAEA,SAAS,iBACP,WACA,cACA,YACgB;AAChB,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,WAAW;AAAA,IACnB,OAAO,WAAW;AAAA,IAClB,SAAS,WAAW;AAAA,IACpB,YAAY,WAAW;AAAA,IACvB,gBAAgB,WAAW;AAAA,IAC3B,cAAc,WAAW;AAAA,IACzB,cAAc,WAAW,WAAW,UAChC,WAAW,OACX;AAAA,IACJ,sBAAsB,WAAW,WAAW,UACxC,eACA;AAAA,IACJ,QAAQ,WAAW;AAAA,EACrB;AACF;;;ACzIO,IAAM,iBAAiB;AACvB,IAAM,oBAAoB;AAU1B,IAAM,2BAA2B;AAEjC,SAAS,gBAAgB,cAAgC;AAC9D,SAAO,CAAC,IAAI,GAAG,aAAa,QAAQ,SAAS,IAAI,EAAE,MAAM,IAAI,CAAC;AAChE;AAEO,SAAS,gBACd,SACA,eACA,OASI,CAAC,GACW;AAChB,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,kBAAkB,KAAK,mBAAmB;AAChD,QAAM,YAAY,QAAQ;AAC1B,QAAM,eAAe,QAAQ;AAC7B,MAAI;AACJ,MAAI,mBAAmB,KAAK;AAC5B,QAAM,sBAAsB,MAAwB;AAClD,yBAAqB,KAAK,sBAAsB,KAC3C,uBAAuB,aAAa;AACzC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,gBAAgB,QAAQ,QAAQ,MAAM;AACzC,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ,QAAQ,KAAK,WAAW,QAAQ;AAClD,UAAM,EAAE,OAAO,SAAS,IAAI,aAAa,KAAK,WAAW,QAAQ,IAAI;AAErE,QAAI,CAAC,cAAc;AACjB,YAAM,cAAc,QAAQ,OAAO;AACnC,YAAM,WACJ,QAAQ,YAAY,OAAO,QAAQ,WAAW,QAAQ,OAAO;AAC/D,YAAM,iBACJ,QAAQ,YAAY,OAAO,cAAc,WAAW;AACtD,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,UAAU,IAAI,aAAa;AAAA,QACnC,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,QACE,UAAU,IACN,0DACA,gCAAgC,QAAQ,IAAI,MAAM,EAAE,GAAG,KAAK;AAAA,MACpE;AAAA,IACF;AAEA,QAAI,CAAC,UAAU;AACb,YAAM,cAAc,QAAQ,OAAO;AACnC,YAAM,WACJ,QAAQ,YAAY,OAAO,QAAQ,WAAW,QAAQ,OAAO;AAC/D,YAAM,iBACJ,QAAQ,YAAY,OAAO,cAAc,WAAW;AAEtD,YAAM,gBAAgBE;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAEA,UAAI,kBAAkB,cAAc;AAClC,eAAO;AAAA,UACL;AAAA,UACA,QAAQ,UAAU,IAAI,aAAa;AAAA,UACnC,OAAO;AAAA,UACP,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,QACE,UAAU,IACN,uDACA,mBAAmB,QAAQ,IAAI,MAAM,EAAE,GAAG,KAAK;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,gBAAgB,KAAK,qBACnC;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL;AAAA,EACF,IACE;AACJ,MAAI,gBAAgB,WAAW,OAAO;AACpC,UAAM,mBAAmB;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,iBAAkB,QAAO,iBAAiB;AAAA,EAChD;AACA,QAAM,aAAa,gBAAgB,KAAK,gBACpC,qBAAqB,SAAS,KAAK,aAAa,IAChD;AACJ,MAAI,iBAAiB,aAAa,aAAa;AAC7C,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,WAAY,QAAO,WAAW;AAAA,EACpC;AAEA,MAAI,cAAc;AAChB,UAAM,kBAAkB,WAAW,eAAe,YAAY;AAC9D,QAAI,gBAAgB,SAAS,KAAK,QAAQ,QAAQ,MAAM;AACtD,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,QACE,cAAc,gBAAgB,MAAM;AAAA,MAExC;AAAA,IACF;AAIA,QAAI;AACJ,QAAI,eAAe;AACnB,QAAI,gBAAgB,WAAW,GAAG;AAChC,eAAS,gBAAgB,CAAC;AAC1B,qBAAe;AAAA,IACjB,WAAW,gBAAgB,SAAS,KAAK,QAAQ,QAAQ,MAAM;AAC7D,eAAS,cAAc,iBAAiB,QAAQ,IAAI;AACpD,qBAAe,qBAAqB,gBAAgB,MAAM,gDAAgD,QAAQ,IAAI;AAAA,IACxH;AAEA,QAAI,QAAQ;AAOV,UAAI,6BAA6B,SAAS,QAAQ,eAAe,eAAe,GAAG;AACjF,cAAM,eAAeA;AAAA,UACnB;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AACA,eAAO;AAAA,UACL;AAAA,UACA,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,SAAS,QAAQ;AAAA,UACjB,YAAY,QAAQ;AAAA,UACpB,gBAAgB,QAAQ;AAAA,UACxB,cAAc,QAAQ;AAAA,UACtB,cAAc,gBAAgB;AAAA,UAC9B,sBAAsB;AAAA,UACtB,QACE,4BAA4B,OAAO,IAAI,wCAClC,eAAe,sBAAsB,QAAQ,IAAI;AAAA,QAE1D;AAAA,MACF;AAEA,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,SAAS,OAAO;AAAA,QAChB,YAAY,OAAO;AAAA,QACnB,gBAAgB,OAAO;AAAA,QACvB,cAAc,OAAO;AAAA,QACrB,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,iBAAiB,gBAAgB,eAAe,YAAY;AAClE,QAAI,eAAe,WAAW,GAAG;AAC/B,YAAM,YAAY,eAAe,CAAC;AAClC,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,UAAU;AAAA,QACjB,SAAS,UAAU;AAAA,QACnB,YAAY,UAAU;AAAA,QACtB,gBAAgB,UAAU;AAAA,QAC1B,cAAc,UAAU;AAAA,QACxB,cAAc,UAAU;AAAA,QACxB,sBAAsB;AAAA,QACtB,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,yBAAqB;AAAA,MACnB;AAAA,MACA;AAAA,MACA,CAAC,gBAAgB,SAAS;AAAA,MAC1B,QAAQ;AAAA,MACR,oBAAoB;AAAA,IACtB;AACA,UAAM,kBAAkB,mBAAmB,IAAI,cAAc,KAAK,CAAC;AAEnE,QAAI,gBAAgB,WAAW,KAAM,gBAAgB,SAAS,KAAK,gBAAgB,CAAC,EAAE,SAAS,gBAAiB;AAC9G,YAAM,OACJ,gBAAgB,WAAW,IACvB,gBAAgB,CAAC,IACjB,cAAc,iBAAiB,QAAQ,QAAQ,CAAC;AACtD,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,QACd,YAAY,KAAK;AAAA,QACjB,gBAAgB,KAAK;AAAA,QACrB,cAAc,KAAK;AAAA,QACnB,cAAc,KAAK;AAAA,QACnB,sBAAsB;AAAA,QACtB,QAAQ,sCAAsC,KAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ,MAAM;AACxB,UAAM,UAAU,QAAQ;AACxB,QAAI,UAAU,KAAK,UAAU,cAAc,QAAQ;AACjD,YAAM,YAAY,KAAK,gBACnB,oDACA;AAEJ,UAAI,cAAc;AAChB,cAAM,WAAW,cAAc,OAAO;AACtC,cAAM,aAAa,YAAY,CAAC,IAAI,QAAQ,GAAG,cAAc,iBAAiB;AAC9E,YAAI,WAAW,SAAS,GAAG;AACzB,iBAAO;AAAA,YACL;AAAA,YACA,QAAQ;AAAA,YACR,OAAO,WAAW,CAAC,EAAE;AAAA,YACrB,SAAS,QAAQ;AAAA,YACjB,YAAY,QAAQ;AAAA,YACpB,cAAc,WAAW,CAAC,EAAE;AAAA,YAC5B,sBAAsB;AAAA,YACtB,QAAQ,8CAA8C,WAAW,CAAC,EAAE,MAAM,QAAQ,CAAC,CAAC,IAAI,SAAS;AAAA,UACnG;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa,CAAC;AACpB,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,aAAa,aAAc,KAAK,gBAAgB,cAAc;AAAA,QACtE,OAAO,aAAa,IAAO,KAAK,gBAAgB,MAAM;AAAA,QACtD,SAAS,QAAQ;AAAA,QACjB,YAAY,QAAQ;AAAA,QACpB,QAAQ,aACJ,oDACA,uBAAuB,SAAS;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc;AAChB,UAAM,gBAAgB,oBAAoB,IAAI,SAAS,KAClD;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,oBAAoB;AAAA,IACtB;AAEF,QAAI,cAAc,WAAW,GAAG;AAC9B,YAAM,YAAY,cAAc,CAAC;AACjC,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,UAAU;AAAA,QACjB,SAAS,UAAU;AAAA,QACnB,YAAY,UAAU;AAAA,QACtB,gBAAgB,UAAU;AAAA,QAC1B,cAAc,UAAU;AAAA,QACxB,cAAc,UAAU;AAAA,QACxB,sBAAsB;AAAA,QACtB,QAAQ,oCAAoC,UAAU,MAAM,QAAQ,CAAC,CAAC;AAAA,MACxE;AAAA,IACF;AAEA,QAAI,cAAc,SAAS,GAAG;AAC5B,YAAM,OAAO,cAAc,CAAC;AAC5B,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,QACd,YAAY,KAAK;AAAA,QACjB,QAAQ,cAAc,cAAc,MAAM,8BAA8B,KAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,MAC/F;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,sBACd,KACA,eACA,OAAyD,CAAC,GACxC;AAClB,MAAI;AACJ,QAAM,sBAAsB,MAAwB;AAClD,yBAAqB,uBAAuB,aAAa;AACzD,WAAO;AAAA,EACT;AACA,SAAO,IAAI,SAAS;AAAA,IAAI,CAAC,YACvB,gBAAgB,SAAS,eAAe,EAAE,GAAG,MAAM,oBAAoB,CAAC;AAAA,EAC1E;AACF;AAEO,SAAS,qBACd,KACA,cACA,OAAyD,CAAC,GACxC;AAClB,SAAO,sBAAsB,KAAK,gBAAgB,YAAY,GAAG,IAAI;AACvE;AAEO,SAAS,cACd,SACA,cACA,OAAyD,CAAC,GAC1C;AAChB,QAAM,iBAAiB,aAAa,QAAQ,SAAS,IAAI;AACzD,QAAM,gBAAgB,gBAAgB,YAAY;AAClD,QAAM,SAAS,gBAAgB,SAAS,eAAe,IAAI;AAE3D,MAAI,OAAO,WAAW,YAAY;AAChC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,OAAO,OAAO,WAAW,QAAQ;AACvC,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,MACL,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,WAAW,eAAe,MAAM,IAAI;AAC1C,QAAM,aAAa,kBAAkB,QAAQ;AAC7C,QAAM,UAAU,OAAO,cAAc,QAAQ,YAAY;AACzD,QAAM,cAAc,OAAO,kBAAkB,QAAQ,gBAAgB;AACrE,QAAM,YAAY,OAAO,gBAAgB,QAAQ;AACjD,QAAM,OAAO,UAAU,YAAY,UAAU,MAAM,WAAW;AAC9D,QAAM,eAAe,QAAQ,eAAe,QAAQ,SAAS,IAAI;AACjE,QAAM,KACJ,aAAa,OACT,UAAU,YAAY,UAAU,SAAS,SAAS,IAClD,eACE,OAAO,aAAa,SACpB,UAAU,YAAY,UAAU,SAAS,SAAS,UAAU,CAAC,GAAG,UAAU,CAAC;AAEnF,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA,IACf,OAAO,OAAO;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,aAAa,gBAAgB,YAAY,UAAU,SAAS,EAAE;AAAA,IACzE,QAAQ,OAAO;AAAA,EACjB;AACF;AAEA,SAAS,kBAAkB,OAA2B;AACpD,QAAM,SAAS,CAAC,CAAC;AACjB,MAAI,SAAS;AACb,aAAW,QAAQ,OAAO;AACxB,WAAO,KAAK,MAAM;AAClB,cAAU,KAAK,SAAS;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,SAAS,UACP,YACA,OACA,MACA,QACQ;AACR,QAAM,QAAQ,WAAW,IAAI,KAAK;AAClC,QAAM,YAAY,MAAM,OAAO,CAAC,GAAG,UAAU;AAC7C,SAAO,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,SAAS,CAAC;AACxD;AAEA,SAAS,gBACP,YACA,OACA,MACA,QACQ;AACR,QAAM,QAAQ,WAAW,IAAI,KAAK;AAClC,QAAM,YAAY,MAAM,OAAO,CAAC,GAAG,UAAU;AAC7C,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,OAAO,SAAS,CAAC;AACxD;AAEO,SAAS,qBACd,KACA,SACA,OAAuE,CAAC,GAChE;AACR,MAAI,UAAU;AACd,QAAM,YAAY,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,WAAW,MAAM,CAAC,CAAC;AAE7E,aAAW,WAAW,IAAI,UAAU;AAClC,UAAM,SAAS,UAAU,IAAI,QAAQ,EAAE;AACvC,QAAI,CAAC,OAAQ;AAEb,QAAI,YAAY;AAEhB,QAAI,OAAO,WAAW,QAAQ,OAAO,YAAY,QAAQ,MAAM;AAC7D,cAAQ,OAAO,OAAO;AACtB,kBAAY;AAAA,IACd;AACA,QAAI,OAAO,cAAc,QAAQ,OAAO,eAAe,QAAQ,UAAU;AACvE,cAAQ,WAAW,OAAO;AAC1B,kBAAY;AAAA,IACd;AACA,QAAI,OAAO,kBAAkB,QAAQ,OAAO,mBAAmB,QAAQ,cAAc;AACnF,cAAQ,eAAe,OAAO;AAC9B,kBAAY;AAAA,IACd;AACA,QAAI,OAAO,gBAAgB,QAAQ,OAAO,iBAAiB,QAAQ,YAAY;AAC7E,cAAQ,aAAa,OAAO;AAC5B,kBAAY;AAAA,IACd;AAEA,QAAI,OAAO,gBAAgB,QAAQ,OAAO,iBAAiB,QAAQ,eAAe;AAChF,UAAI,KAAK,YAAY;AACnB,gBAAQ,gBAAgB,OAAO;AAC/B,eAAO,QAAQ;AAAA,MACjB,OAAO;AACL,gBAAQ,gBAAgB,OAAO;AAAA,MACjC;AACA,kBAAY;AAAA,IACd,WAAW,OAAO,gBAAgB,QAAQ,OAAO,iBAAiB,QAAQ,eAAe;AACvF,UAAI,QAAQ,eAAe;AACzB,eAAO,QAAQ;AACf,oBAAY;AAAA,MACd;AAAA,IACF;AAEA,QAAI,aAAa,OAAO,WAAW,YAAY;AAC7C,cAAQ,oBAAoB,OAAO;AACnC,cAAQ,mBAAmB,OAAO;AAAA,IACpC;AAEA,QACE,KAAK,SACF,KAAK,eACJ,OAAO,WAAW,cAAc,OAAO,WAAW,cACnD,OAAO,SAAS,gBACnB;AACA,cAAQ,SAAS,KAAK;AACtB,aAAO,QAAQ;AACf,aAAO,QAAQ;AACf,UAAI,QAAQ,iBAAiB,QAAQ,kBAAkB,QAAQ,eAAe;AAC5E,eAAO,QAAQ;AAAA,MACjB;AACA,kBAAY;AAAA,IACd;AAEA,QAAI,WAAW;AACb,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASA,aACP,OACA,MACA,SACA,aACA,WACe;AACf,QAAM,WAAW;AACjB,QAAM,SAAS,WAAW;AAE1B,MAAI,WAAW,KAAK,UAAU,MAAM,OAAQ,QAAO;AAEnD,MAAI,aAAa,QAAQ;AACvB,UAAM,OAAO,MAAM,QAAQ;AAC3B,QAAI,eAAe,QAAQ,aAAa,MAAM;AAC5C,aAAO,KAAK,MAAM,aAAa,SAAS;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAmB,CAAC;AAC1B,WAAS,QAAQ,UAAU,SAAS,QAAQ,SAAS,GAAG;AACtD,QAAI,cAAc,MAAM,KAAK;AAC7B,QAAI,UAAU,YAAY,eAAe,KAAM,eAAc,YAAY,MAAM,WAAW;AAC1F,QAAI,UAAU,UAAU,aAAa,KAAM,eAAc,YAAY,MAAM,GAAG,SAAS;AACvF,WAAO,KAAK,WAAW;AAAA,EACzB;AACA,SAAO,OAAO,KAAK,IAAI;AACzB;AAEA,SAAS,cAA0C,YAAiB,YAAuB;AACzF,SAAO,WAAW;AAAA,IAAO,CAAC,MAAM,cAC9B,KAAK,IAAI,UAAU,OAAO,UAAU,IAAI,KAAK,IAAI,KAAK,OAAO,UAAU,IAAI,YAAY;AAAA,EACzF;AACF;AAgBA,SAAS,6BACP,SACA,WACA,OACA,iBACS;AACT,MAAI,QAAQ,QAAQ,KAAM,QAAO;AAGjC,MAAI,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,MAAM,OAAQ,QAAO;AAG9D,MAAI,KAAK,IAAI,UAAU,OAAO,QAAQ,IAAI,KAAK,gBAAiB,QAAO;AAIvE,QAAM,eAAeA;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,MAAI,iBAAiB,QAAQ,cAAe,QAAO;AAEnD,SAAO;AACT;AAEA,SAAS,aAAa,WAAuB,MAAoD;AAC/F,MAAI,QAAQ;AACZ,MAAI,WAAW;AAEf,aAAW,QAAQ,WAAW;AAC5B,UAAM,WAAW,KAAK;AACtB,UAAM,SAAS,KAAK,WAAW,KAAK,IAAI,KAAK,UAAU,CAAC,IAAI;AAE5D,QAAI,QAAQ,YAAY,QAAQ,UAAU,KAAK,WAAW,GAAG;AAC3D,iBAAW;AAAA,IACb;AAEA,QAAI,OAAO,UAAW,KAAK,aAAa,KAAK,QAAQ,UAAW;AAC9D,eAAS,KAAK,WAAW,KAAK;AAAA,IAChC;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,SAAS;AAC3B;;;ACrnBA,IAAM,wBAAwB;AAC9B,IAAM,uBAAuB;AAC7B,IAAM,2BAA2B;AACjC,IAAM,oBAAoB;AAC1B,IAAM,4BAA4B;AAsB3B,SAAS,wBACd,UACA,SACA,eACkB;AAClB,QAAM,aAAa,QAAQ,IAAI,CAAC,YAAY,EAAE,GAAG,OAAO,EAAE;AAC1D,MACE,SAAS,SAAS,2BAA2B,KAC1C,CAAC,WAAW,KAAK,CAAC,WAAW,OAAO,WAAW,WAAW,GAC7D;AACA,WAAO;AAAA,EACT;AACA,QAAM,gBAAgB,IAAI;AAAA,IACxB,WAAW,IAAI,CAAC,QAAQ,UAAU,CAAC,OAAO,WAAW,KAAK,CAAC;AAAA,EAC7D;AACA,QAAM,YAAY,iBAAiB,UAAU,YAAY,aAAa;AACtE,QAAM,iBAAiB,oBAAI,IAAoB;AAC/C,aAAW,YAAY,WAAW;AAChC,mBAAe;AAAA,MACb,SAAS;AAAA,OACR,eAAe,IAAI,SAAS,KAAK,KAAK,KAAK;AAAA,IAC9C;AAAA,EACF;AAEA,WAAS,QAAQ,GAAG,QAAQ,2BAA2B,SAAS,GAAG;AACjE,QAAI,UAAU;AACd,eAAW,WAAW,UAAU;AAC9B,UAAI,QAAQ,QAAQ,QAAQ,CAAC,QAAQ,cAAe;AACpD,YAAM,QAAQ,sBAAsB,SAAS,aAAa;AAC1D,UAAI,SAAS,KAAM;AACnB,WAAK,eAAe,IAAI,KAAK,KAAK,KAAK,0BAA0B;AAC/D;AAAA,MACF;AACA,YAAM,cAAc,cAAc,IAAI,QAAQ,EAAE;AAChD,UAAI,eAAe,KAAM;AACzB,YAAM,SAAS,WAAW,WAAW;AACrC,UAAI,OAAO,WAAW,YAAa;AAEnC,YAAM,aAAaC;AAAA,QACjB,4BAA4B,SAAS,aAAa;AAAA,MACpD,EAAE,MAAM,GAAG,CAAC;AACZ,UAAI,WAAW,SAAS,EAAG;AAC3B,YAAM,SAAS,WACZ;AAAA,QAAI,CAAC,cACJ;AAAA,UACE,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,EACC;AAAA,QAAK,CAAC,MAAM,UACX,MAAM,cAAc,KAAK,eACtB,MAAM,UAAU,QAAQ,KAAK,UAAU,SACvC,KAAK,UAAU,OAAO,MAAM,UAAU;AAAA,MAC3C;AACF,YAAM,OAAO,OAAO,CAAC;AACrB,YAAM,SAAS,OAAO,CAAC;AACvB,UACE,CAAC,KAAK,UAAU,SACb,KAAK,sBAAsB,4BAC3B,KAAK,UAAU,wBACf,KAAK,cAAc,OAAO,cAAc,mBAC3C;AACA;AAAA,MACF;AAEA,iBAAW,WAAW,IAAI;AAAA,QACxB,WAAW,QAAQ;AAAA,QACnB,QAAQ;AAAA,QACR,OAAO,KAAK,IAAI,MAAM,MAAM,KAAK,UAAU,IAAI;AAAA,QAC/C,SAAS,KAAK,UAAU;AAAA,QACxB,YAAY,KAAK,UAAU;AAAA,QAC3B,gBAAgB,KAAK,UAAU;AAAA,QAC/B,cAAc,KAAK,UAAU;AAAA,QAC7B,QACE,sDACK,KAAK,mBAAmB,gCACf,KAAK,QAAQ,QAAQ,CAAC,CAAC,aAC/B,KAAK,cAAc,OAAO,aAAa,QAAQ,CAAC,CAAC;AAAA,MAC3D;AACA,gBAAU;AAEV,gBAAU,KAAK;AAAA,QACb,YAAY,QAAQ;AAAA,QACpB,YAAY,KAAK,UAAU;AAAA,QAC3B;AAAA,MACF,CAAC;AACD,qBAAe,IAAI,QAAQ,eAAe,IAAI,KAAK,KAAK,KAAK,CAAC;AAAA,IAChE;AACA,QAAI,CAAC,QAAS;AAAA,EAChB;AAEA,SAAO;AACT;AAEA,SAAS,iBACP,UACA,SACA,eACY;AACZ,QAAM,YAAY,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,WAAW,MAAM,CAAC,CAAC;AAC7E,SAAO,SAAS,QAAQ,CAAC,YAAwB;AAC/C,UAAM,SAAS,UAAU,IAAI,QAAQ,EAAE;AACvC,QACE,QAAQ,QAAQ,QACb,QAAQ,WAAW,QAClB,OAAO,WAAW,cAAc,OAAO,WAAW,aACnD,OAAO,QAAQ,MAClB;AACA,aAAO,CAAC;AAAA,IACV;AACA,UAAM,QAAQ,sBAAsB,SAAS,aAAa;AAC1D,WAAO,SAAS,OACZ,CAAC,IACD,CAAC,EAAE,YAAY,QAAQ,MAAM,YAAY,OAAO,SAAS,MAAM,CAAC;AAAA,EACtE,CAAC;AACH;AAEA,SAAS,mBACP,YACA,OACA,WACA,WACiB;AACjB,MAAI,kBAAkB;AACtB,MAAI,cAAc;AAClB,MAAI,sBAAsB;AAC1B,QAAM,iBAAiB,UAAU,OAAO;AAExC,aAAW,YAAY,WAAW;AAChC,QAAI,SAAS,UAAU,MAAO;AAC9B,UAAM,iBAAiB,KAAK,IAAI,aAAa,SAAS,UAAU;AAChE,QAAI,mBAAmB,KAAK,iBAAiB,sBAAuB;AACpE,UAAM,gBAAgB,SAAS,aAAa,SAAS;AACrD,UAAM,aAAa,KAAK,IAAI,iBAAiB,aAAa;AAC1D,UAAM,YAAY,KAAK,IAAI,GAAG,IAAI,aAAa,CAAC;AAChD,UAAM,SAAS,KAAK,IAAI,iBAAiB;AACzC,uBAAmB,YAAY;AAC/B,mBAAe;AACf,QAAI,aAAa,qBAAsB,wBAAuB;AAAA,EAChE;AAEA,QAAM,UAAU,cAAc,IAAI,kBAAkB,cAAc;AAClE,SAAO;AAAA,IACL;AAAA,IACA,aACE,UAAU,QAAQ,MAAM,UAAU,QAAQ,UAAU,QAAQ,OAAO;AAAA,IACrE;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAASA,uBACP,YAC0B;AAC1B,QAAM,SAAS,oBAAI,IAAoC;AACvD,aAAW,aAAa,YAAY;AAClC,UAAM,MAAM;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU,eAAe;AAAA,MACzB,UAAU,aAAa;AAAA,IACzB,EAAE,KAAK,GAAG;AACV,UAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,QAAI,CAAC,YAAY,UAAU,QAAQ,SAAS,OAAO;AACjD,aAAO,IAAI,KAAK,SAAS;AAAA,IAC3B;AAAA,EACF;AACA,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE;AAAA,IAAK,CAAC,MAAM,UACtC,MAAM,QAAQ,KAAK,SAAS,KAAK,OAAO,MAAM;AAAA,EAChD;AACF;;;AC9MA,iBAAsB;AACtB,yBAA6B;;;ACA7B;AAAA,EACE,SAAW;AAAA,EACX,KAAO;AAAA,EACP,OAAS;AAAA,EACT,aAAe;AAAA,EACf,MAAQ;AAAA,EACR,UAAY,CAAC,gBAAgB,YAAY,UAAU;AAAA,EACnD,sBAAwB;AAAA,EACxB,YAAc;AAAA,IACZ,cAAgB;AAAA,MACd,MAAQ;AAAA,MACR,SAAW;AAAA,MACX,aAAe;AAAA,IACjB;AAAA,IACA,UAAY;AAAA,MACV,MAAQ;AAAA,MACR,aAAe;AAAA,IACjB;AAAA,IACA,UAAY;AAAA,MACV,MAAQ;AAAA,MACR,OAAS;AAAA,QACP,MAAQ;AAAA,QACR,UAAY,CAAC,MAAM,UAAU,aAAa,QAAQ,UAAU;AAAA,QAC5D,sBAAwB;AAAA,QACxB,YAAc;AAAA,UACZ,IAAM;AAAA,YACJ,MAAQ;AAAA,YACR,aAAe;AAAA,UACjB;AAAA,UACA,QAAU;AAAA,YACR,MAAQ;AAAA,YACR,aAAe;AAAA,UACjB;AAAA,UACA,WAAa;AAAA,YACX,MAAQ;AAAA,YACR,QAAU;AAAA,YACV,aAAe;AAAA,UACjB;AAAA,UACA,MAAQ;AAAA,YACN,MAAQ;AAAA,YACR,WAAa;AAAA,YACb,aAAe;AAAA,UACjB;AAAA,UACA,UAAY;AAAA,YACV,MAAQ;AAAA,YACR,aAAe;AAAA,UACjB;AAAA,UACA,QAAU;AAAA,YACR,MAAQ;AAAA,YACR,aAAe;AAAA,UACjB;AAAA,UACA,MAAQ;AAAA,YACN,MAAQ;AAAA,YACR,aAAe;AAAA,YACf,UAAY;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,UACA,UAAY;AAAA,YACV,MAAQ;AAAA,YACR,aAAe;AAAA,YACf,MAAQ,CAAC,OAAO,UAAU,MAAM;AAAA,UAClC;AAAA,UACA,UAAY;AAAA,YACV,MAAQ;AAAA,YACR,aAAe;AAAA,UACjB;AAAA,UACA,MAAQ;AAAA,YACN,MAAQ;AAAA,YACR,SAAW;AAAA,YACX,aAAe;AAAA,UACjB;AAAA,UACA,UAAY;AAAA,YACV,MAAQ;AAAA,YACR,SAAW;AAAA,YACX,aAAe;AAAA,UACjB;AAAA,UACA,cAAgB;AAAA,YACd,MAAQ;AAAA,YACR,SAAW;AAAA,YACX,aAAe;AAAA,UACjB;AAAA,UACA,YAAc;AAAA,YACZ,MAAQ;AAAA,YACR,SAAW;AAAA,YACX,aAAe;AAAA,UACjB;AAAA,UACA,eAAiB;AAAA,YACf,MAAQ;AAAA,YACR,WAAa;AAAA,YACb,aAAe;AAAA,UACjB;AAAA,UACA,eAAiB;AAAA,YACf,MAAQ;AAAA,YACR,WAAa;AAAA,YACb,aAAe;AAAA,UACjB;AAAA,UACA,oBAAsB;AAAA,YACpB,MAAQ;AAAA,YACR,SAAW;AAAA,YACX,aAAe;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC9GO,IAAM,aAAa;;;AFO1B,IAAM,MAAO,WAAAC,QAAkB,WAAW,WAAAA;AAC1C,IAAM,aAAc,mBAAAC,QAAyB,WAAW,mBAAAA;AAIjD,SAAS,iBACd,KACA,SAAiB,YACC;AAClB,QAAM,SAAiC,CAAC;AACxC,QAAM,WAAmC,CAAC;AAE1C,iBAAe,KAAK,QAAQ,MAAM;AAClC,sBAAoB,KAAK,QAAQ,QAAQ;AAEzC,SAAO;AAAA,IACL,OAAO,OAAO,WAAW;AAAA,IACzB;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,eACd,KACA,WACA,QACM;AACN,QAAM,EAAE,SAAS,GAAG,OAAO,IAAI;AAC/B,OAAK;AACL,QAAM,MAAM,IAAI,IAAI,EAAE,WAAW,MAAM,QAAQ,MAAM,CAAC;AACtD,aAAW,GAAG;AACd,QAAM,cAAc,IAAI,QAAQ,MAAM;AACtC,QAAM,cAAc,YAAY,GAAG;AAEnC,MAAI,CAAC,eAAe,YAAY,QAAQ;AACtC,eAAW,OAAO,YAAY,QAAQ;AACpC,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,GAAG,IAAI,gBAAgB,GAAG,KAAK,IAAI,WAAW,cAAc;AAAA,QACrE,MAAM,IAAI,gBAAgB;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,oBACd,KACA,QACA,UACA,MACM;AACN,MAAI,CAAC,MAAM,QAAQ,IAAI,QAAQ,EAAG;AAElC,QAAM,MAAM,oBAAI,IAAY;AAC5B,QAAM,SAAS,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE;AAE3C,WAAS,IAAI,GAAG,IAAI,IAAI,SAAS,QAAQ,KAAK;AAC5C,UAAM,IAAI,IAAI,SAAS,CAAC;AACxB,UAAM,SAAS,aAAa,CAAC;AAE7B,QAAI,EAAE,IAAI;AACR,UAAI,IAAI,IAAI,EAAE,EAAE,GAAG;AACjB,eAAO,KAAK;AAAA,UACV,UAAU;AAAA,UACV,MAAM;AAAA,UACN,SAAS,yBAAyB,EAAE,EAAE;AAAA,UACtC,MAAM,GAAG,MAAM;AAAA,UACf,WAAW,EAAE;AAAA,QACf,CAAC;AAAA,MACH;AACA,UAAI,IAAI,EAAE,EAAE;AAAA,IACd;AAEA,QAAI,EAAE,QAAQ,QAAQ,EAAE,YAAY,QAAQ,EAAE,WAAW,EAAE,MAAM;AAC/D,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,aAAa,EAAE,QAAQ,0BAAqB,EAAE,IAAI;AAAA,QAC3D,MAAM,GAAG,MAAM;AAAA,QACf,WAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AAEA,QACE,EAAE,gBAAgB,QAClB,EAAE,cAAc,SACf,EAAE,QAAQ,QAAQ,EAAE,YAAY,QAAQ,EAAE,SAAS,EAAE,aACtD,EAAE,aAAa,EAAE,cACjB;AACA,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,eAAe,EAAE,UAAU,kCAA6B,EAAE,YAAY;AAAA,QAC/E,MAAM,GAAG,MAAM;AAAA,QACf,WAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AAEA,QAAI,EAAE,iBAAiB,EAAE,cAAc,SAAS,MAAM;AACpD,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,0CAA0C,EAAE,cAAc,MAAM;AAAA,QACzE,MAAM,GAAG,MAAM;AAAA,QACf,WAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AAEA,QAAI,EAAE,QAAQ,EAAE,KAAK,SAAS,OAAO;AACnC,eAAS,KAAK;AAAA,QACZ,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,8CAA8C,EAAE,KAAK,MAAM;AAAA,QACpE,MAAM,GAAG,MAAM;AAAA,QACf,WAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AAIA,QAAI,QAAQ,EAAE,iBAAiB,EAAE,oBAAoB;AACnD,YAAM,WAAW,KAAK,EAAE,aAAa;AACrC,UAAI,EAAE,uBAAuB,UAAU;AACrC,iBAAS,KAAK;AAAA,UACZ,UAAU;AAAA,UACV,MAAM;AAAA,UACN,SAAS,yCAAyC,SAAS,MAAM,GAAG,EAAE,CAAC,eAAU,EAAE,mBAAmB,MAAM,GAAG,EAAE,CAAC;AAAA,UAClH,MAAM,GAAG,MAAM;AAAA,UACf,WAAW,EAAE;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,EAAE,YAAY,CAAC,IAAI,IAAI,EAAE,QAAQ,KAAK,CAAC,OAAO,SAAS,EAAE,QAAQ,GAAG;AACtE,eAAS,KAAK;AAAA,QACZ,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,aAAa,EAAE,QAAQ;AAAA,QAChC,MAAM,GAAG,MAAM;AAAA,QACf,WAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AAEA,QAAI,EAAE,QAAQ,QAAQ,CAAC,EAAE,eAAe;AACtC,eAAS,KAAK;AAAA,QACZ,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM,GAAG,MAAM;AAAA,QACf,WAAW,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AGzJA,qBAAiB;AACjB,kBAAyB;AAyBlB,SAAS,oBACd,SACA,cACc;AACd,QAAM,UAAU,QAAQ,KAAK;AAE7B,MAAI;AAGJ,QAAM,SACJ,QAAQ,WAAW,GAAG,KACrB,gBAAgB,aAAa,SAAS,cAAc;AAEvD,MAAI,QAAQ;AACV,QAAI;AACF,eAAS,KAAK,MAAM,OAAO;AAAA,IAC7B,SAAS,GAAG;AACV,YAAM,IAAI,MAAM,yBAA0B,EAAY,OAAO,EAAE;AAAA,IACjE;AAAA,EACF,OAAO;AACL,QAAI;AACF,eAAS,eAAAC,QAAK,KAAK,SAAS,EAAE,QAAQ,eAAAA,QAAK,YAAY,CAAC;AAAA,IAC1D,SAAS,GAAG;AACV,YAAM,IAAI,MAAM,yBAA0B,EAAY,OAAO,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAClE,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3D;AAEA,SAAO;AACT;AAKO,SAAS,2BACd,SACA,cACoB;AACpB,QAAM,UAAU,QAAQ,KAAK;AAC7B,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,KAAK,MAAM,OAAO,gBAAgB;AAAA,EAC7C;AAEA,QAAM,SACJ,QAAQ,WAAW,GAAG,KACrB,gBAAgB,aAAa,SAAS,cAAc;AAGvD,MAAI;AACJ,MAAI;AACF,aAAS,SAAS,KAAK,MAAM,OAAO,IAAI,eAAAA,QAAK,KAAK,SAAS,EAAE,QAAQ,eAAAA,QAAK,YAAY,CAAC;AAAA,EACzF,SAAS,GAAG;AAEV,QAAI,CAAC,QAAQ;AACX,aAAO,YAAY,OAAO;AAAA,IAC5B;AACA,WAAO,EAAE,KAAK,MAAM,OAAO,yBAA0B,EAAY,OAAO,GAAG;AAAA,EAC7E;AAEA,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAClE,WAAO,EAAE,KAAK,MAAM,OAAO,0CAA0C;AAAA,EACvE;AAEA,QAAM,MAAM;AACZ,QAAM,MAAoB;AAAA,IACxB,cAAc,OAAO,IAAI,iBAAiB,WAAW,IAAI,eAAe;AAAA,IACxE,UAAU,OAAO,IAAI,aAAa,WAAW,IAAI,WAAW;AAAA,IAC5D,UAAU,CAAC;AAAA,EACb;AAEA,MAAI,CAAC,MAAM,QAAQ,IAAI,QAAQ,GAAG;AAChC,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,OAAkB,CAAC;AACzB,QAAM,MAAgB,CAAC;AAEvB,WAAS,IAAI,GAAG,IAAI,IAAI,SAAS,QAAQ,KAAK;AAC5C,UAAM,IAAI,IAAI,SAAS,CAAC;AACxB,QAAI,KAAK,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC,KAAK,OAAQ,EAA8B,OAAO,UAAU;AAC5G,WAAK,KAAK,CAAY;AAAA,IACxB,OAAO;AACL,UAAI,KAAK,CAAC;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,WAAW;AAEf,MAAI,IAAI,SAAS,GAAG;AAClB,WAAO;AAAA,MACL;AAAA,MACA,OAAO,GAAG,IAAI,MAAM,2BAA2B,IAAI,KAAK,IAAI,CAAC;AAAA,MAC7D,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,SAAO,EAAE,IAAI;AACf;AAMA,SAAS,YAAY,SAAqC;AACxD,QAAM,WAAsB,CAAC;AAC7B,MAAI,eAAe;AACnB,MAAI,WAAW;AAGf,QAAM,eAAe,QAAQ,MAAM,mCAAmC;AACtE,MAAI,aAAc,gBAAe,aAAa,CAAC,EAAE,KAAK;AAEtD,QAAM,WAAW,QAAQ,MAAM,+BAA+B;AAC9D,MAAI,SAAU,YAAW,SAAS,CAAC,EAAE,KAAK;AAG1C,QAAM,SAAS,QAAQ,MAAM,iBAAiB;AAE9C,aAAW,SAAS,QAAQ;AAC1B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,CAAC,QAAQ,WAAW,OAAO,EAAG;AAGlC,QAAI;AACF,YAAM,SAAS,eAAAA,QAAK,KAAK,SAAS,EAAE,QAAQ,eAAAA,QAAK,YAAY,CAAC;AAC9D,UAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,SAAS,GAAG;AAC9C,cAAM,IAAI,OAAO,CAAC;AAClB,YAAI,KAAK,OAAO,MAAM,YAAY,OAAQ,EAA8B,OAAO,UAAU;AACvF,mBAAS,KAAK,CAAY;AAAA,QAC5B;AAAA,MACF,WAAW,UAAU,OAAO,WAAW,YAAY,OAAQ,OAAmC,OAAO,UAAU;AAC7G,iBAAS,KAAK,MAAiB;AAAA,MACjC;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,MAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ;AAEA,SAAO;AAAA,IACL,KAAK,SAAS,SAAS,IAAI,MAAM;AAAA,IACjC,OAAO,+BAA+B,SAAS,MAAM;AAAA,IACrD,iBAAiB,SAAS,SAAS,IAAI,WAAW;AAAA,EACpD;AACF;AASO,SAAS,OAAO,KAA2B;AAChD,QAAM,UAAU,IAAI,qBAAS,GAAG;AAChC,SAAO,QAAQ,SAAS,EAAE,WAAW,EAAE,CAAC;AAC1C;AAKO,SAAS,OAAO,KAA2B;AAChD,SAAO,KAAK,UAAU,KAAK,MAAM,CAAC,IAAI;AACxC;;;AXxLO,IAAMC,uBAAgC;AACtC,IAAMC,8BAAuC;AAC7C,IAAMC,UAAmB;AACzB,IAAMC,UAAmB;AAEzB,IAAMC,iBAAsB;AAC5B,IAAMC,cAAmB;AACzB,IAAMC,eAAoB;AAC1B,IAAMC,oBAAyB;AAC/B,IAAMC,mBAAwB;AAC9B,IAAMC,iBAAsB;AAE5B,IAAMC,wBAAoC;AAC1C,IAAMC,qBAAiC;AACvC,IAAMC,kBAA8B;AACpC,IAAMC,mBAA+B;AACrC,IAAMC,yBAAqC;AAC3C,IAAMC,wBAAoC;AAC1C,IAAMC,iBAA6B;AACnC,IAAMC,mBAA+B;AACrC,IAAMC,4BAAyC;AAC/C,IAAMC,2BACU;AAChB,IAAMC,4BACQ;AACd,IAAMC,2BACW;AAejB,IAAMC,oBAAgC;AAGtC,IAAMC,gBAAwB;AAC9B,IAAMC,eAAuB;AAC7B,IAAMC,gBAAwB;",
  "names": ["DEFAULT_THRESHOLD", "HIGH_THRESHOLD", "applyReanchorResults", "calibrateAnchorEvidence", "combinedScore", "createAnchorContextIndex", "createRevisionProjection", "exactMatch", "formatAuthor", "fuzzySearch", "levenshteinScore", "newCommentId", "normalizedMatch", "parseAuthor", "parseSidecarContent", "parseSidecarContentLenient", "reanchorComment", "reanchorDocumentLines", "reanchorDocumentText", "reconcileCommentAnchors", "resolveAnchor", "toJson", "toReanchorLines", "toYaml", "tokenLcsScore", "validateDocument", "levenshtein", "index", "uuidv4", "extractText", "tokenize", "extractText", "deduplicateCandidates", "AjvModule", "addFormatsModule", "yaml", "parseSidecarContent", "parseSidecarContentLenient", "toYaml", "toJson", "combinedScore", "exactMatch", "fuzzySearch", "levenshteinScore", "normalizedMatch", "tokenLcsScore", "applyReanchorResults", "DEFAULT_THRESHOLD", "HIGH_THRESHOLD", "reanchorComment", "reanchorDocumentLines", "reanchorDocumentText", "resolveAnchor", "toReanchorLines", "createAnchorContextIndex", "reconcileCommentAnchors", "createRevisionProjection", "calibrateAnchorEvidence", "validateDocument", "formatAuthor", "parseAuthor", "newCommentId"]
}
