@knpkv/rly 0.11.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_Fragment","styles","useNarrowerThan","Fragment$1","BoundedDiffCodeView_module_default","invalid","HUNK","HEADER","unquote","path","source","bytes","encoder","escapes","offset","match","literal","byte","code","trailing","headerPaths","candidates","index","header","left","right","destination","defaultPrefixes","prefixes","selected","oldPath","newPath","moved","unmarkedBinary","paths","binaryPaths","summary","body","selections","status","parsePatch","text","records","lines","line","files","currentPaths","movedSource","movedDestination","fileMode","oldMode","newMode","binary","binarySummary","hunks","oldEnd","newEnd","oldEof","newEof","oldCoordinates","newCoordinates","mode","value","kind","payload","readBinary","parsed","readHunk","record","hunk","markerStatus","start","chunks","first","lead","length","oldStart","newStart","oldCount","newCount","oldOffset","newOffset","oldNo","newNo","marker","previous","pathsOf","file","findFile","patch","pairRows","rows","deleted","added","next","PatchDiffView","narrow","measureRef","shown","cell","number","side","wrap","id","annotation","content","renderAnnotation","Fragment","row","rowIndex","lineIndex","hunkIndex"],"sources":["../../../src/diff/bounded/BoundedDiffCodeView.module.css","../../../src/diff/patch/parse.ts","../../../src/diff/patch/PatchDiffView.tsx"],"sourcesContent":[".root {\n overflow: hidden;\n border: 1px solid var(--rly-color-border-1);\n border-radius: var(--rly-radius-field);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n}\n\n.file + .file {\n border-top: 1px solid var(--rly-color-border-1);\n}\n\n.noChanges {\n margin: 0;\n padding: var(--rly-space-16);\n color: var(--rly-color-text-2);\n font: var(--rly-type-body-weight) var(--rly-type-body-size) / var(--rly-type-body-line-height)\n var(--rly-type-body-font);\n}\n\n.fileName {\n margin: 0;\n padding: var(--rly-space-12) var(--rly-space-16);\n border-bottom: 1px solid var(--rly-color-border-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.scroller {\n max-height: min(70vh, 56rem);\n overflow: auto;\n}\n\n.table {\n width: 100%;\n border-spacing: 0;\n border-collapse: collapse;\n font-family: var(--rly-font-mono);\n font-size: 0.78rem;\n line-height: 1.55;\n}\n\n.table td {\n min-width: 0;\n padding: 0;\n vertical-align: top;\n}\n\n.hunk td {\n padding: var(--rly-space-4) var(--rly-space-12);\n border-block: 1px solid var(--rly-color-border-1);\n background: var(--rly-color-surface-2);\n color: var(--rly-color-text-2);\n}\n\n.lineNumber {\n width: 3.25rem;\n /* Room either side of the number, so the column rule reads as one rule, not a box per line. */\n padding-inline: var(--rly-space-8) var(--rly-space-6) !important;\n border-right: 1px solid var(--rly-color-border-1);\n color: var(--rly-color-text-3);\n text-align: right;\n user-select: none;\n}\n\n.marker {\n width: 1.5rem;\n color: var(--rly-color-text-3);\n text-align: center;\n user-select: none;\n}\n\n.code,\n.wrappedCode {\n display: block;\n min-height: 1.55em;\n padding-inline: var(--rly-space-12);\n white-space: pre;\n}\n\n.wrappedCode {\n white-space: pre-wrap;\n overflow-wrap: break-word;\n}\n\n/*\n * In an auto-sized table a long token would widen its column rather than wrap. Capping the wrapped\n * code cell at zero and letting it take the remaining width bounds it to the viewport, so\n * break-word can wrap a 200-character string; unwrapped views keep their horizontal scroll.\n */\n.table td:has(> .wrappedCode) {\n inline-size: 100%;\n max-inline-size: 0;\n}\n\n.deletion > td,\n.change .deletionCode {\n background: var(--rly-color-blocked-tint);\n}\n\n.addition > td,\n.change .additionCode {\n background: var(--rly-color-success-tint);\n}\n\n.deletion .lineNumber,\n.addition .lineNumber,\n.deletion .marker,\n.addition .marker {\n color: var(--rly-color-text-2);\n}\n\n.context > td {\n background: var(--rly-color-surface-1);\n}\n\n.deletionCode,\n.additionCode {\n width: 50%;\n border-right: 1px solid var(--rly-color-border-1);\n}\n\n.annotationRow > td {\n background: var(--rly-color-surface-2);\n border-block: 1px solid var(--rly-color-border-1);\n}\n\n.annotationRow > .annotationCell {\n padding: var(--rly-space-8);\n}\n\n.annotation {\n background: var(--rly-color-held-tint);\n border: 1px solid color-mix(in oklab, var(--rly-color-held-ink) 35%, transparent);\n border-radius: var(--rly-radius-tag);\n color: var(--rly-color-text-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n padding: var(--rly-space-8) var(--rly-space-12);\n}\n\n.annotation:focus-visible,\n[data-rly-diff-line]:focus-visible {\n outline: var(--rly-space-2) solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n\n@media (forced-colors: active) {\n .annotation,\n [data-rly-diff-line]:focus-visible {\n forced-color-adjust: auto;\n }\n}\n\n/*\n * Forced colours drop the add/remove tints. Split cells have no marker column, so a changed cell\n * gets its sign drawn before the code (hidden from assistive technology, which reads the column).\n */\n@media (forced-colors: active) {\n .change .deletionCode > :is(.code, .wrappedCode)::before {\n content: \"− \" / \"\";\n }\n .change .additionCode > :is(.code, .wrappedCode)::before {\n content: \"+ \" / \"\";\n }\n}\n\n:where([data-forced-colors=\"active\"], [data-rly-forced-colors=\"active\"])\n .change\n .deletionCode\n > :is(.code, .wrappedCode)::before {\n content: \"− \" / \"\";\n}\n:where([data-forced-colors=\"active\"], [data-rly-forced-colors=\"active\"])\n .change\n .additionCode\n > :is(.code, .wrappedCode)::before {\n content: \"+ \" / \"\";\n}\n","/**\n * A `git diff` parsed into files, hunks and numbered lines.\n *\n * Only what the renderer and the anchoring need: which files changed and how, and for\n * every line in a hunk its number on the old and the new side. Status, mode and body\n * evidence must agree; index and similarity values are not used for line anchoring.\n */\n\n/** A malformed patch cannot supply trustworthy source line positions. */\nexport interface PatchInvalid {\n readonly _tag: \"PatchInvalid\"\n readonly reason: string\n}\n\n/** What `parsePatch` returns: either a patch, or the reason it could not be trusted. */\nexport type ParseResult = { readonly _tag: \"Patch\"; readonly patch: Patch } | PatchInvalid\n\nconst invalid = (reason: string): PatchInvalid => ({ _tag: \"PatchInvalid\", reason })\n\ntype UnquotedPath = { readonly _tag: \"Path\"; readonly path: string } | PatchInvalid\nexport type LineKind = \"context\" | \"add\" | \"del\"\n\nexport interface DiffLine {\n readonly kind: LineKind\n readonly text: string\n /** Git EOF marker on this record: old side for deletions, new for additions, both for context. */\n readonly noNewline?: boolean\n /** Line number in the old file; absent on added lines. */\n readonly oldNo?: number\n /** Line number in the new file; absent on deleted lines. */\n readonly newNo?: number\n}\n\nexport interface Hunk {\n readonly header: string\n readonly oldStart: number\n readonly newStart: number\n readonly lines: ReadonlyArray<DiffLine>\n}\n\nexport type FileStatus = \"added\" | \"deleted\" | \"modified\" | \"renamed\" | \"copied\"\n\nexport interface FileDiff {\n /** The path a guide refers to: the new path, or the old one when the file was deleted. */\n readonly path: string\n readonly oldPath: string\n readonly newPath: string\n readonly status: FileStatus\n readonly binary: boolean\n /** Explicit mode headers only; an absent side or unreported mode stays absent. */\n readonly oldMode?: string\n readonly newMode?: string\n readonly hunks: ReadonlyArray<Hunk>\n}\n\nexport interface Patch {\n readonly files: ReadonlyArray<FileDiff>\n}\n\nconst HUNK = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@(.*)$/\nconst HEADER = \"diff --git \"\n\n/** Exact Git producer prefixes. Use two empty strings for --no-prefix, including paths resembling a/ and b/. */\nexport interface PatchPrefixes {\n readonly source: string\n readonly destination: string\n}\n\nconst unquote = (path: string): UnquotedPath => {\n if (path.includes(\"\\u0000\")) return invalid(\"Git paths cannot contain NUL\")\n if (!path.startsWith(\"\\\"\")) return { _tag: \"Path\", path }\n if (!path.endsWith(\"\\\"\")) return invalid(\"Unclosed quoted path\")\n const source = path.slice(1, -1)\n const bytes: Array<number> = []\n const encoder = new TextEncoder()\n const escapes = new Map([\n [\"a\", 7],\n [\"b\", 8],\n [\"t\", 9],\n [\"n\", 10],\n [\"v\", 11],\n [\"f\", 12],\n [\"r\", 13],\n [\"\\\"\", 34],\n [\"\\\\\", 92]\n ])\n let offset = 0\n for (const match of source.matchAll(/\\\\([0-7]{3}|.)/gs)) {\n const literal = source.slice(offset, match.index)\n if (literal.includes(\"\\\"\")) return invalid(\"Unescaped quote in quoted path\")\n for (const byte of encoder.encode(literal)) bytes.push(byte)\n const code = match[1] ?? \"\"\n const byte = /^[0-7]{3}$/.test(code) ? parseInt(code, 8) : escapes.get(code)\n if (byte === undefined || byte === 0 || byte > 255) return invalid(\"Invalid quoted path escape\")\n bytes.push(byte)\n offset = match.index + match[0].length\n }\n const trailing = source.slice(offset)\n if (trailing.includes(\"\\\\\")) return invalid(\"Dangling quoted path escape\")\n if (trailing.includes(\"\\\"\")) return invalid(\"Unescaped quote in quoted path\")\n for (const byte of encoder.encode(trailing)) bytes.push(byte)\n try {\n return {\n _tag: \"Path\",\n path: new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true }).decode(new Uint8Array(bytes))\n }\n } catch {\n return invalid(\"Quoted Git path is not valid UTF-8\")\n }\n}\n\n/** Resolve header boundaries against file markers; spaces in unquoted filenames are legal Git output. */\nconst headerPaths = (\n header: string,\n source: string | undefined,\n destination: string | undefined,\n prefixes: PatchPrefixes | undefined,\n moved: { readonly source: string; readonly destination: string } | undefined,\n unmarkedBinary = false\n): { readonly _tag: \"Paths\"; readonly oldPath: string; readonly newPath: string } | PatchInvalid => {\n const candidates: Array<{ readonly oldPath: string; readonly newPath: string }> = []\n for (let index = 0; index < header.length; index++) {\n if (header[index] !== \" \") continue\n const left = unquote(header.slice(0, index))\n const right = unquote(header.slice(index + 1))\n if (left._tag === \"PatchInvalid\" || right._tag === \"PatchInvalid\") continue\n if (left.path === \"\" || right.path === \"\") continue\n if (source !== undefined && source !== \"/dev/null\" && source !== left.path) continue\n if (destination !== undefined && destination !== \"/dev/null\" && destination !== right.path) continue\n const defaultPrefixes = prefixes === undefined && left.path.startsWith(\"a/\") && right.path.startsWith(\"b/\")\n const selected = prefixes ?? (defaultPrefixes\n ? { source: \"a/\", destination: \"b/\" }\n : { source: \"\", destination: \"\" })\n if (!left.path.startsWith(selected.source) || !right.path.startsWith(selected.destination)) continue\n const oldPath = left.path.slice(selected.source.length)\n const newPath = right.path.slice(selected.destination.length)\n if (oldPath === \"\" || newPath === \"\") continue\n if (moved !== undefined && (oldPath !== moved.source || newPath !== moved.destination)) continue\n if (\n moved === undefined && source === undefined && destination === undefined && oldPath !== newPath &&\n !(unmarkedBinary && (defaultPrefixes || prefixes !== undefined))\n ) continue\n candidates.push({ oldPath, newPath })\n }\n const paths = candidates[0]\n return candidates.length === 1 && paths !== undefined\n ? { _tag: \"Paths\", ...paths }\n : invalid(\"Inconsistent or ambiguous Git file headers; custom prefixes must be supplied explicitly\")\n}\n\n/** Match every possible summary separator against the authoritative header, including quoted and spaced paths. */\nconst binaryPaths = (\n header: string,\n summary: string,\n prefixes: PatchPrefixes | undefined,\n moved: { readonly source: string; readonly destination: string } | undefined,\n status: FileStatus\n): ReturnType<typeof headerPaths> => {\n if (!summary.endsWith(\" differ\")) return invalid(\"Incomplete binary summary\")\n const body = summary.slice(\"Binary files \".length, -\" differ\".length)\n // Auto mode tries Git's standard prefixes before an unprefixed producer.\n // Otherwise a filename ending in \" and\" can fabricate a second no-prefix interpretation.\n const selections = prefixes === undefined\n ? [{ source: \"a/\", destination: \"b/\" }, { source: \"\", destination: \"\" }]\n : [prefixes]\n for (const selected of selections) {\n const candidates: Array<Extract<ReturnType<typeof headerPaths>, { readonly _tag: \"Paths\" }>> = []\n for (const match of body.matchAll(/(?= and )/g)) {\n const source = unquote(body.slice(0, match.index))\n const destination = unquote(body.slice(match.index + \" and \".length))\n if (source._tag === \"PatchInvalid\" || destination._tag === \"PatchInvalid\") continue\n if ((source.path === \"/dev/null\") !== (status === \"added\")) continue\n if ((destination.path === \"/dev/null\") !== (status === \"deleted\")) continue\n const paths = headerPaths(header, source.path, destination.path, selected, moved)\n if (paths._tag === \"Paths\") candidates.push(paths)\n }\n const paths = candidates[0]\n if (candidates.length === 1 && paths !== undefined) return paths\n if (candidates.length > 1) return invalid(\"Ambiguous binary summary paths\")\n }\n return invalid(\"Binary summary paths disagree with Git headers\")\n}\n\n/** Infer default a/b prefixes when present; pass explicit empty prefixes for unambiguous --no-prefix parsing. */\nexport const parsePatch = (text: string, prefixes?: PatchPrefixes): ParseResult => {\n if (text !== \"\" && !text.endsWith(\"\\n\")) return invalid(\"Unterminated patch record\")\n // A CR on a Git header identifies transport line endings; body-only CR belongs to the source.\n const records = text.split(\"\\n\")\n const converted = records.some((line) => line.startsWith(HEADER) && line.endsWith(\"\\r\"))\n const lines = converted ? records.map((line) => line.endsWith(\"\\r\") ? line.slice(0, -1) : line) : records\n const files: Array<FileDiff> = []\n const currentPaths = new Set<string>()\n let index = 0\n\n while (index < lines.length) {\n const line = lines[index] ?? \"\"\n if (!line.startsWith(HEADER)) {\n index += 1\n continue\n }\n const header = line.slice(HEADER.length)\n let source: string | undefined\n let destination: string | undefined\n let movedSource: string | undefined\n let movedDestination: string | undefined\n let status: FileStatus = \"modified\"\n let fileMode: string | undefined\n let oldMode: string | undefined\n let newMode: string | undefined\n let binary = false\n let binarySummary: string | undefined\n const hunks: Array<Hunk> = []\n let oldEnd = 0\n let newEnd = 0\n let oldEof = false\n let newEof = false\n const oldCoordinates = new Set<number>()\n const newCoordinates = new Set<number>()\n index += 1\n\n while (index < lines.length && !(lines[index] ?? \"\").startsWith(HEADER)) {\n const line = lines[index] ?? \"\"\n if (/^(new file|deleted file|old|new) mode/.test(line)) {\n const mode = /^(new file|deleted file|old|new) mode ([0-7]{6})$/.exec(line)\n if (mode === null) return invalid(\"Invalid file mode header\")\n const value = mode[2]\n if (mode[1] === \"old\") {\n if (oldMode !== undefined && oldMode !== value) return invalid(\"Conflicting old modes\")\n oldMode = value\n } else if (mode[1] === \"new\") {\n if (newMode !== undefined && newMode !== value) return invalid(\"Conflicting new modes\")\n newMode = value\n } else {\n const kind = mode[1] === \"new file\" ? \"added\" : \"deleted\"\n if (status !== \"modified\" && status !== kind) return invalid(\"Conflicting file status headers\")\n if (fileMode !== undefined && fileMode !== value) return invalid(\"Conflicting file modes\")\n status = kind\n fileMode = value\n }\n } else if (/^(rename|copy) (from|to) /.test(line)) {\n const kind = line.startsWith(\"copy \") ? \"copied\" : \"renamed\"\n if (status !== \"modified\" && status !== kind) return invalid(\"Conflicting file status headers\")\n status = kind\n const path = unquote(line.replace(/^(rename|copy) (from|to) /, \"\"))\n if (path._tag === \"PatchInvalid\") return path\n if (/^(rename|copy) from /.test(line)) {\n if (movedSource !== undefined && movedSource !== path.path) return invalid(\"Conflicting move source paths\")\n movedSource = path.path\n } else {\n if (movedDestination !== undefined && movedDestination !== path.path) {\n return invalid(\"Conflicting move destination paths\")\n }\n movedDestination = path.path\n }\n } else if (line.startsWith(\"GIT binary patch\")) {\n if (line !== \"GIT binary patch\") return invalid(\"Invalid binary patch marker\")\n const payload = readBinary(lines, index + 1)\n if (payload._tag === \"PatchInvalid\") return payload\n binary = true\n index = payload.next\n continue\n } else if (line.startsWith(\"Binary files \")) {\n if (binarySummary !== undefined && binarySummary !== line) return invalid(\"Conflicting binary summaries\")\n binarySummary = line\n binary = true\n } else if (line.startsWith(\"--- \") || line.startsWith(\"+++ \")) {\n const path = unquote(line.slice(4).replace(/\\t$/, \"\"))\n if (path._tag === \"PatchInvalid\") return path\n if (line.startsWith(\"--- \")) {\n if (source !== undefined && source !== path.path) return invalid(\"Conflicting source file markers\")\n source = path.path\n } else {\n if (destination !== undefined && destination !== path.path) {\n return invalid(\"Conflicting destination file markers\")\n }\n destination = path.path\n }\n } else if (HUNK.test(line)) {\n if (source === undefined || destination === undefined) return invalid(\"Text hunks require paired file markers\")\n const parsed = readHunk(lines, index)\n if (parsed._tag === \"PatchInvalid\") return parsed\n if (!parsed.hunk.lines.some((record) => record.kind === \"add\" || record.kind === \"del\")) {\n return invalid(\"Text hunk has no change evidence\")\n }\n if (parsed.oldOffset < oldEnd || parsed.newOffset < newEnd) return invalid(\"Hunk ranges move backwards\")\n oldEnd = parsed.oldEnd\n newEnd = parsed.newEnd\n for (const record of parsed.hunk.lines) {\n if ((oldEof && record.oldNo !== undefined) || (newEof && record.newNo !== undefined)) {\n return invalid(\"Patch records follow an EOF marker on the same side\")\n }\n if (record.noNewline === true) {\n oldEof ||= record.oldNo !== undefined\n newEof ||= record.newNo !== undefined\n }\n if (\n (record.oldNo !== undefined && oldCoordinates.has(record.oldNo)) ||\n (record.newNo !== undefined && newCoordinates.has(record.newNo))\n ) return invalid(`Overlapping hunk at line ${index + 1}`)\n if (record.oldNo !== undefined) oldCoordinates.add(record.oldNo)\n if (record.newNo !== undefined) newCoordinates.add(record.newNo)\n }\n hunks.push(parsed.hunk)\n index = parsed.next\n continue\n } else if (/^(?:@@|[+\\- \\\\])/.test(line)) {\n return invalid(`Unexpected patch body at line ${index + 1}`)\n }\n index += 1\n }\n if ((source === undefined) !== (destination === undefined)) return invalid(\"Unpaired file markers\")\n if ((movedSource === undefined) !== (movedDestination === undefined)) {\n return invalid(\"Unpaired rename or copy headers\")\n }\n if ((oldMode === undefined) !== (newMode === undefined)) return invalid(\"Unpaired mode transition\")\n if (fileMode !== undefined && oldMode !== undefined) return invalid(\"Conflicting file mode headers\")\n if (oldMode !== undefined && (source === \"/dev/null\" || destination === \"/dev/null\")) {\n return invalid(\"Mode transition requires both file sides\")\n }\n if (binary && source !== undefined) return invalid(\"Mixed binary and text bodies\")\n if (source !== undefined && hunks.length === 0) return invalid(\"Text markers require hunks\")\n if (source === \"/dev/null\" && destination === \"/dev/null\") return invalid(\"Both file sides are absent\")\n if (\n hunks.some((hunk) =>\n hunk.lines.some((line) =>\n (source === \"/dev/null\" && line.oldNo !== undefined) ||\n (destination === \"/dev/null\" && line.newNo !== undefined)\n )\n )\n ) return invalid(\"Absent file side contains text lines\")\n if (source !== undefined) {\n const markerStatus = source === \"/dev/null\" ? \"added\" : destination === \"/dev/null\" ? \"deleted\" : \"modified\"\n if (\n (status === \"added\" || status === \"deleted\" || markerStatus !== \"modified\") &&\n status !== \"modified\" && status !== markerStatus\n ) return invalid(\"File status disagrees with file markers\")\n if (markerStatus !== \"modified\") status = markerStatus\n }\n if (\n hunks.length === 0 && !binary && movedSource === undefined && fileMode === undefined &&\n (oldMode === undefined || oldMode === newMode)\n ) return invalid(\"File block has no change evidence\")\n const moved = movedSource === undefined || movedDestination === undefined\n ? undefined\n : { source: movedSource, destination: movedDestination }\n const paths = binarySummary === undefined\n ? headerPaths(header, source, destination, prefixes, moved, binary)\n : binaryPaths(header, binarySummary, prefixes, moved, status)\n if (paths._tag === \"PatchInvalid\") return paths\n if (\n binary && source === undefined && moved === undefined && status !== \"modified\" && paths.oldPath !== paths.newPath\n ) {\n return invalid(\"Binary addition or deletion has conflicting header paths\")\n }\n const path = status === \"deleted\" ? paths.oldPath : paths.newPath\n if (currentPaths.has(path)) return invalid(\"Duplicate canonical current file path\")\n currentPaths.add(path)\n files.push({\n path,\n oldPath: paths.oldPath,\n newPath: paths.newPath,\n status,\n binary,\n ...(status === \"deleted\" && fileMode !== undefined\n ? { oldMode: fileMode }\n : oldMode === undefined\n ? {}\n : { oldMode }),\n ...(status === \"added\" && fileMode !== undefined\n ? { newMode: fileMode }\n : newMode === undefined\n ? {}\n : { newMode }),\n hunks\n })\n }\n if (files.length === 0 && text.trim() !== \"\") return invalid(\"Expected a git unified diff\")\n return { _tag: \"Patch\", patch: { files } }\n}\n\n/** Validate Git's literal/delta record framing without inflating or applying binary content. */\nconst readBinary = (\n lines: ReadonlyArray<string>,\n start: number\n): { readonly _tag: \"Binary\"; readonly next: number } | PatchInvalid => {\n let index = start\n let chunks = 0\n do {\n const header = /^(literal|delta) (\\d+)$/.exec(lines[index] ?? \"\")\n if (header === null || !Number.isSafeInteger(Number(header[2]))) return invalid(\"Invalid binary chunk header\")\n index += 1\n const first = index\n while (index < lines.length && lines[index] !== \"\") {\n const line = lines[index] ?? \"\"\n const lead = line.charCodeAt(0)\n const length = lead >= 65 && lead <= 90 ? lead - 64 : lead >= 97 && lead <= 122 ? lead - 70 : 0\n if (\n length === 0 || line.length !== 1 + Math.ceil(length / 4) * 5 ||\n !/^[0-9A-Za-z!#$%&()*+;<=>?@^_`{|}~-]+$/.test(line.slice(1))\n ) return invalid(\"Invalid binary chunk data\")\n index += 1\n }\n // A final split sentinel is not the blank record that terminates a Git payload.\n if (index === first || index >= lines.length - 1) return invalid(\"Incomplete binary chunk\")\n index += 1\n chunks += 1\n } while (chunks < 2 && /^(literal|delta)(?:\\s|$)/.test(lines[index] ?? \"\"))\n if (/^(literal|delta)(?:\\s|$)/.test(lines[index] ?? \"\")) return invalid(\"Surplus binary chunk\")\n return { _tag: \"Binary\", next: index }\n}\n\nconst readHunk = (\n lines: ReadonlyArray<string>,\n start: number\n): {\n readonly _tag: \"Hunk\"\n readonly hunk: Hunk\n readonly next: number\n readonly oldOffset: number\n readonly newOffset: number\n readonly oldEnd: number\n readonly newEnd: number\n} | PatchInvalid => {\n const match = HUNK.exec(lines[start] ?? \"\")\n if (match === null) return invalid(`not a hunk header at line ${start + 1}`)\n const oldStart = Number(match[1])\n const newStart = Number(match[3])\n let oldCount = match[2] === undefined ? 1 : Number(match[2])\n let newCount = match[4] === undefined ? 1 : Number(match[4])\n if (![oldStart, newStart, oldCount, newCount].every(Number.isSafeInteger)) return invalid(\"Unsafe hunk integers\")\n if (oldCount === 0 && newCount === 0) return invalid(\"Empty hunk\")\n if (\n (oldCount > 0 && !Number.isSafeInteger(oldStart + (oldCount - 1))) ||\n (newCount > 0 && !Number.isSafeInteger(newStart + (newCount - 1)))\n ) return invalid(\"Hunk coordinates overflow\")\n // Half-open zero-based ranges: empty Git ranges anchor after the named line.\n const oldOffset = oldStart - (oldCount === 0 ? 0 : 1)\n const newOffset = newStart - (newCount === 0 ? 0 : 1)\n const oldEnd = oldOffset + oldCount\n const newEnd = newOffset + newCount\n let oldNo = oldStart\n let newNo = newStart\n const body: Array<DiffLine> = []\n let index = start + 1\n\n while (index < lines.length && (oldCount > 0 || newCount > 0)) {\n const line = lines[index] ?? \"\"\n const marker = line[0]\n const text = line.slice(1)\n if (marker === \"+\") {\n body.push({ kind: \"add\", text, newNo })\n newNo += 1\n newCount -= 1\n } else if (marker === \"-\") {\n body.push({ kind: \"del\", text, oldNo })\n oldNo += 1\n oldCount -= 1\n } else if (marker === \" \") {\n body.push({ kind: \"context\", text, oldNo, newNo })\n oldNo += 1\n newNo += 1\n oldCount -= 1\n newCount -= 1\n } else {\n break\n }\n index += 1\n // A marker belongs to exactly one preceding body record and consumes no coordinate.\n if ((lines[index] ?? \"\").startsWith(\"\\\\\")) {\n if (lines[index] !== \"\\\\") return invalid(`Invalid newline marker at line ${index + 1}`)\n const previous = body[body.length - 1]\n if (previous !== undefined) body[body.length - 1] = { ...previous, noNewline: true }\n index += 1\n }\n }\n if (oldCount !== 0 || newCount !== 0) return invalid(`Incomplete hunk at line ${start + 1}`)\n\n return {\n _tag: \"Hunk\",\n oldOffset,\n newOffset,\n oldEnd,\n newEnd,\n hunk: { header: match[5]?.trim() ?? \"\", oldStart, newStart, lines: body },\n next: index\n }\n}\n\n/** Changed-file paths: the current name first, then the source of a rename or modified comparison. */\nexport const pathsOf = (file: FileDiff): ReadonlyArray<string> =>\n file.status === \"renamed\" || (file.status === \"modified\" && file.oldPath !== file.newPath)\n ? [file.newPath, file.oldPath]\n : [file.path]\n\nexport const findFile = (patch: Patch, path: string): FileDiff | undefined =>\n patch.files.find((file) => file.path === path) ?? patch.files.find((file) => pathsOf(file).includes(path))\n","import { Fragment, type ReactElement, type ReactNode } from \"react\"\nimport styles from \"../bounded/BoundedDiffCodeView.module.css\"\nimport { RLY_SPLIT_DIFF_MIN_WIDTH, useNarrowerThan } from \"../../internal/useNarrowerThan.js\"\nimport type { DiffLine, FileDiff, Hunk } from \"./parse.js\"\n\nexport { findFile, parsePatch, pathsOf } from \"./parse.js\"\nexport type {\n DiffLine,\n FileDiff,\n FileStatus,\n Hunk,\n LineKind,\n ParseResult,\n Patch,\n PatchInvalid,\n PatchPrefixes\n} from \"./parse.js\"\n\nexport interface PatchDiffViewProps {\n readonly file: FileDiff\n /** Unique prefix for stable source-line links within the document. */\n readonly id: string\n readonly mode?: \"split\" | \"stacked\"\n readonly wrap?: boolean\n /** Called once for each visible side and line; consumers own annotation identity and content. */\n readonly renderAnnotation?: (side: \"old\" | \"new\", line: number) => ReactNode\n}\n\ninterface Row {\n readonly left: DiffLine | undefined\n readonly right: DiffLine | undefined\n}\n\n/** Pair consecutive deletions and additions without renumbering sparse patch hunks. */\nexport const pairRows = (hunk: Hunk): ReadonlyArray<Row> => {\n const rows: Array<Row> = []\n let index = 0\n while (index < hunk.lines.length) {\n const line = hunk.lines[index]\n if (line === undefined) break\n if (line.kind === \"context\") {\n rows.push({ left: line, right: line })\n index++\n continue\n }\n const deleted: Array<DiffLine> = []\n const added: Array<DiffLine> = []\n while (hunk.lines[index]?.kind === \"del\") {\n const next = hunk.lines[index++]\n if (next !== undefined) deleted.push(next)\n }\n while (hunk.lines[index]?.kind === \"add\") {\n const next = hunk.lines[index++]\n if (next !== undefined) added.push(next)\n }\n for (let offset = 0; offset < Math.max(deleted.length, added.length); offset++) {\n const left = deleted[offset]\n const right = added[offset]\n rows.push({ left, right })\n }\n }\n return rows\n}\n\n/** Render a patch as an accessible, server-renderable table. Source omissions stay omitted. */\nexport const PatchDiffView = ({\n file,\n id,\n mode = \"split\",\n renderAnnotation,\n wrap = false\n}: PatchDiffViewProps): ReactElement => {\n // A split view stacks in a narrow container, so neither side is clipped to a sliver.\n const [narrow, measureRef] = useNarrowerThan<HTMLDivElement>(RLY_SPLIT_DIFF_MIN_WIDTH)\n const shown = mode === \"split\" && narrow ? \"stacked\" : mode\n const cell = (line: DiffLine | undefined, side: \"old\" | \"new\") => {\n const number = side === \"old\" ? line?.oldNo : line?.newNo\n return (\n <>\n <td className={styles.lineNumber}>{number}</td>\n <td className={side === \"old\" ? styles.deletionCode : styles.additionCode}>\n {line === undefined ? null : (\n <>\n <code className={wrap ? styles.wrappedCode : styles.code} id={`${id}-${side}-${number}`} tabIndex={-1}>\n {line.text || \" \"}\n </code>\n {line.noNewline === true ? (\n <small aria-label={`${side === \"old\" ? \"Before\" : \"After\"}: no newline`}>\n No newline at end of file\n </small>\n ) : null}\n </>\n )}\n </td>\n </>\n )\n }\n const annotation = (line: DiffLine | undefined, side: \"old\" | \"new\") => {\n const number = side === \"old\" ? line?.oldNo : line?.newNo\n const content = number === undefined ? undefined : renderAnnotation?.(side, number)\n return content == null ? null : (\n <tr className={styles.annotationRow}>\n <td className={styles.annotationCell} colSpan={4}>\n {content}\n </td>\n </tr>\n )\n }\n return (\n <div className={styles.root} data-rly-patch-diff=\"\" data-rly-diff-mode={shown} ref={measureRef}>\n {file.oldMode === undefined && file.newMode === undefined ? null : (\n <p className={styles.noChanges}>\n {file.oldMode === undefined\n ? `Mode added: ${file.newMode}`\n : file.newMode === undefined\n ? `Mode removed: ${file.oldMode}`\n : `Mode: ${file.oldMode} → ${file.newMode}`}\n </p>\n )}\n {file.binary || file.hunks.length === 0 ? (\n <p className={styles.noChanges}>{file.binary ? \"Binary file.\" : \"No content change.\"}</p>\n ) : (\n <div style={{ overflowX: \"auto\" }} role=\"region\" aria-label={`Changes in ${file.path}`} tabIndex={0}>\n <table className={styles.table} aria-label={`Changes in ${file.path}`}>\n <thead>\n <tr>\n {shown === \"split\" ? (\n <>\n <th colSpan={2} scope=\"colgroup\">\n Before\n </th>\n <th colSpan={2} scope=\"colgroup\">\n After\n </th>\n </>\n ) : (\n <>\n <th scope=\"col\">Before</th>\n <th scope=\"col\">After</th>\n <th colSpan={2} scope=\"colgroup\">\n Change\n </th>\n </>\n )}\n </tr>\n </thead>\n <tbody>\n {file.hunks.map((hunk, hunkIndex) => (\n <Fragment key={hunkIndex}>\n <tr className={styles.hunk}>\n <td colSpan={4}>\n @@ {hunk.oldStart} → {hunk.newStart} {hunk.header}\n </td>\n </tr>\n {shown === \"split\"\n ? pairRows(hunk).map((row, rowIndex) => (\n <Fragment key={rowIndex}>\n <tr className={row.left?.kind === \"context\" ? styles.context : styles.change}>\n {cell(row.left, \"old\")}\n {cell(row.right, \"new\")}\n </tr>\n {annotation(row.left, \"old\")}\n {annotation(row.right, \"new\")}\n </Fragment>\n ))\n : hunk.lines.map((line, lineIndex) => (\n <Fragment key={lineIndex}>\n <tr\n className={\n line.kind === \"add\"\n ? styles.addition\n : line.kind === \"del\"\n ? styles.deletion\n : styles.context\n }\n >\n <td className={styles.lineNumber}>\n <span id={line.oldNo === undefined ? undefined : `${id}-old-${line.oldNo}`} tabIndex={-1}>\n {line.oldNo}\n </span>\n </td>\n <td className={styles.lineNumber}>\n <span id={line.newNo === undefined ? undefined : `${id}-new-${line.newNo}`} tabIndex={-1}>\n {line.newNo}\n </span>\n </td>\n <td className={styles.marker}>\n {line.kind === \"add\" ? \"+\" : line.kind === \"del\" ? \"−\" : \" \"}\n </td>\n <td>\n <code className={wrap ? styles.wrappedCode : styles.code}>{line.text || \" \"}</code>\n {line.noNewline === true ? (\n <small\n aria-label={\n line.kind === \"del\"\n ? \"Before: no newline\"\n : line.kind === \"add\"\n ? \"After: no newline\"\n : \"Before: no newline; After: no newline\"\n }\n >\n No newline at end of file\n </small>\n ) : null}\n </td>\n </tr>\n {annotation(line, \"old\")}\n {annotation(line, \"new\")}\n </Fragment>\n ))}\n </Fragment>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["_Fragment","styles","useNarrowerThan","Fragment$1","BoundedDiffCodeView_module_default","invalid","HUNK","HEADER","unquote","path","source","bytes","encoder","escapes","offset","match","literal","byte","code","trailing","headerPaths","candidates","index","header","left","right","destination","defaultPrefixes","prefixes","selected","oldPath","newPath","moved","unmarkedBinary","paths","binaryPaths","summary","body","selections","status","parsePatch","text","records","lines","line","files","currentPaths","movedSource","movedDestination","fileMode","oldMode","newMode","binary","binarySummary","hunks","oldEnd","newEnd","oldEof","newEof","oldCoordinates","newCoordinates","mode","value","kind","payload","readBinary","parsed","readHunk","record","hunk","markerStatus","start","chunks","first","lead","length","oldStart","newStart","oldCount","newCount","oldOffset","newOffset","oldNo","newNo","marker","previous","pathsOf","file","findFile","patch","pairRows","rows","deleted","added","next","PatchDiffView","narrow","measureRef","shown","cell","number","side","wrap","id","annotation","content","renderAnnotation","Fragment","row","rowIndex","lineIndex","hunkIndex"],"sources":["../../../src/diff/bounded/BoundedDiffCodeView.module.css","../../../src/diff/patch/parse.ts","../../../src/diff/patch/PatchDiffView.tsx"],"sourcesContent":[".root {\n overflow: hidden;\n border: 1px solid var(--rly-color-border-1);\n border-radius: var(--rly-radius-field);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n}\n\n.file + .file {\n border-top: 1px solid var(--rly-color-border-1);\n}\n\n.noChanges {\n margin: 0;\n padding: var(--rly-space-16);\n color: var(--rly-color-text-2);\n font: var(--rly-type-body-weight) var(--rly-type-body-size) / var(--rly-type-body-line-height)\n var(--rly-type-body-font);\n}\n\n.fileName {\n margin: 0;\n padding: var(--rly-space-12) var(--rly-space-16);\n border-bottom: 1px solid var(--rly-color-border-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.scroller {\n max-height: min(70vh, 56rem);\n overflow: auto;\n}\n\n.table {\n width: 100%;\n border-spacing: 0;\n border-collapse: collapse;\n font-family: var(--rly-font-mono);\n font-size: 0.78rem;\n line-height: 1.55;\n}\n\n.table td {\n min-width: 0;\n padding: 0;\n vertical-align: top;\n}\n\n.hunk td {\n padding: var(--rly-space-4) var(--rly-space-12);\n border-block: 1px solid var(--rly-color-border-1);\n background: var(--rly-color-surface-2);\n color: var(--rly-color-text-2);\n}\n\n.lineNumber {\n width: 3.25rem;\n /* Room either side of the number, so the column rule reads as one rule, not a box per line. */\n padding-inline: var(--rly-space-8) var(--rly-space-6) !important;\n border-right: 1px solid var(--rly-color-border-1);\n color: var(--rly-color-text-3);\n text-align: right;\n user-select: none;\n}\n\n.marker {\n width: 1.5rem;\n color: var(--rly-color-text-3);\n text-align: center;\n user-select: none;\n}\n\n.code,\n.wrappedCode {\n display: block;\n min-height: 1.55em;\n padding-inline: var(--rly-space-12);\n white-space: pre;\n}\n\n.wrappedCode {\n white-space: pre-wrap;\n overflow-wrap: break-word;\n}\n\n/*\n * In an auto-sized table a long token would widen its column rather than wrap. Capping the wrapped\n * code cell at zero and letting it take the remaining width bounds it to the viewport, so\n * break-word can wrap a 200-character string; unwrapped views keep their horizontal scroll.\n */\n.table td:has(> .wrappedCode) {\n inline-size: 100%;\n max-inline-size: 0;\n}\n\n.deletion > td,\n.change .deletionCode {\n background: var(--rly-color-blocked-tint);\n}\n\n.addition > td,\n.change .additionCode {\n background: var(--rly-color-success-tint);\n}\n\n.deletion .lineNumber,\n.addition .lineNumber,\n.deletion .marker,\n.addition .marker {\n color: var(--rly-color-text-2);\n}\n\n.context > td {\n background: var(--rly-color-surface-1);\n}\n\n.deletionCode,\n.additionCode {\n width: 50%;\n border-right: 1px solid var(--rly-color-border-1);\n}\n\n.annotationRow > td {\n background: var(--rly-color-surface-2);\n border-block: 1px solid var(--rly-color-border-1);\n}\n\n.annotationRow > .annotationCell {\n padding: var(--rly-space-8);\n}\n\n.annotation {\n background: var(--rly-color-held-tint);\n border: 1px solid color-mix(in oklab, var(--rly-color-held-ink) 35%, transparent);\n border-radius: var(--rly-radius-tag);\n color: var(--rly-color-text-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n padding: var(--rly-space-8) var(--rly-space-12);\n}\n\n.annotation:focus-visible,\n[data-rly-diff-line]:focus-visible {\n outline: var(--rly-focus-ring-width) solid var(--rly-color-focus);\n outline-offset: var(--rly-focus-ring-offset);\n}\n\n@media (forced-colors: active) {\n .annotation,\n [data-rly-diff-line]:focus-visible {\n forced-color-adjust: auto;\n }\n}\n\n/*\n * Forced colours drop the add/remove tints. Split cells have no marker column, so a changed cell\n * gets its sign drawn before the code (hidden from assistive technology, which reads the column).\n */\n@media (forced-colors: active) {\n .change .deletionCode > :is(.code, .wrappedCode)::before {\n content: \"− \" / \"\";\n }\n .change .additionCode > :is(.code, .wrappedCode)::before {\n content: \"+ \" / \"\";\n }\n}\n\n:where([data-forced-colors=\"active\"], [data-rly-forced-colors=\"active\"])\n .change\n .deletionCode\n > :is(.code, .wrappedCode)::before {\n content: \"− \" / \"\";\n}\n:where([data-forced-colors=\"active\"], [data-rly-forced-colors=\"active\"])\n .change\n .additionCode\n > :is(.code, .wrappedCode)::before {\n content: \"+ \" / \"\";\n}\n","/**\n * A `git diff` parsed into files, hunks and numbered lines.\n *\n * Only what the renderer and the anchoring need: which files changed and how, and for\n * every line in a hunk its number on the old and the new side. Status, mode and body\n * evidence must agree; index and similarity values are not used for line anchoring.\n */\n\n/** A malformed patch cannot supply trustworthy source line positions. */\nexport interface PatchInvalid {\n readonly _tag: \"PatchInvalid\"\n readonly reason: string\n}\n\n/** What `parsePatch` returns: either a patch, or the reason it could not be trusted. */\nexport type ParseResult = { readonly _tag: \"Patch\"; readonly patch: Patch } | PatchInvalid\n\nconst invalid = (reason: string): PatchInvalid => ({ _tag: \"PatchInvalid\", reason })\n\ntype UnquotedPath = { readonly _tag: \"Path\"; readonly path: string } | PatchInvalid\nexport type LineKind = \"context\" | \"add\" | \"del\"\n\nexport interface DiffLine {\n readonly kind: LineKind\n readonly text: string\n /** Git EOF marker on this record: old side for deletions, new for additions, both for context. */\n readonly noNewline?: boolean\n /** Line number in the old file; absent on added lines. */\n readonly oldNo?: number\n /** Line number in the new file; absent on deleted lines. */\n readonly newNo?: number\n}\n\nexport interface Hunk {\n readonly header: string\n readonly oldStart: number\n readonly newStart: number\n readonly lines: ReadonlyArray<DiffLine>\n}\n\nexport type FileStatus = \"added\" | \"deleted\" | \"modified\" | \"renamed\" | \"copied\"\n\nexport interface FileDiff {\n /** The path a guide refers to: the new path, or the old one when the file was deleted. */\n readonly path: string\n readonly oldPath: string\n readonly newPath: string\n readonly status: FileStatus\n readonly binary: boolean\n /** Explicit mode headers only; an absent side or unreported mode stays absent. */\n readonly oldMode?: string\n readonly newMode?: string\n readonly hunks: ReadonlyArray<Hunk>\n}\n\nexport interface Patch {\n readonly files: ReadonlyArray<FileDiff>\n}\n\nconst HUNK = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@(.*)$/\nconst HEADER = \"diff --git \"\n\n/** Exact Git producer prefixes. Use two empty strings for --no-prefix, including paths resembling a/ and b/. */\nexport interface PatchPrefixes {\n readonly source: string\n readonly destination: string\n}\n\nconst unquote = (path: string): UnquotedPath => {\n if (path.includes(\"\\u0000\")) return invalid(\"Git paths cannot contain NUL\")\n if (!path.startsWith(\"\\\"\")) return { _tag: \"Path\", path }\n if (!path.endsWith(\"\\\"\")) return invalid(\"Unclosed quoted path\")\n const source = path.slice(1, -1)\n const bytes: Array<number> = []\n const encoder = new TextEncoder()\n const escapes = new Map([\n [\"a\", 7],\n [\"b\", 8],\n [\"t\", 9],\n [\"n\", 10],\n [\"v\", 11],\n [\"f\", 12],\n [\"r\", 13],\n [\"\\\"\", 34],\n [\"\\\\\", 92]\n ])\n let offset = 0\n for (const match of source.matchAll(/\\\\([0-7]{3}|.)/gs)) {\n const literal = source.slice(offset, match.index)\n if (literal.includes(\"\\\"\")) return invalid(\"Unescaped quote in quoted path\")\n for (const byte of encoder.encode(literal)) bytes.push(byte)\n const code = match[1] ?? \"\"\n const byte = /^[0-7]{3}$/.test(code) ? parseInt(code, 8) : escapes.get(code)\n if (byte === undefined || byte === 0 || byte > 255) return invalid(\"Invalid quoted path escape\")\n bytes.push(byte)\n offset = match.index + match[0].length\n }\n const trailing = source.slice(offset)\n if (trailing.includes(\"\\\\\")) return invalid(\"Dangling quoted path escape\")\n if (trailing.includes(\"\\\"\")) return invalid(\"Unescaped quote in quoted path\")\n for (const byte of encoder.encode(trailing)) bytes.push(byte)\n try {\n return {\n _tag: \"Path\",\n path: new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true }).decode(new Uint8Array(bytes))\n }\n } catch {\n return invalid(\"Quoted Git path is not valid UTF-8\")\n }\n}\n\n/** Resolve header boundaries against file markers; spaces in unquoted filenames are legal Git output. */\nconst headerPaths = (\n header: string,\n source: string | undefined,\n destination: string | undefined,\n prefixes: PatchPrefixes | undefined,\n moved: { readonly source: string; readonly destination: string } | undefined,\n unmarkedBinary = false\n): { readonly _tag: \"Paths\"; readonly oldPath: string; readonly newPath: string } | PatchInvalid => {\n const candidates: Array<{ readonly oldPath: string; readonly newPath: string }> = []\n for (let index = 0; index < header.length; index++) {\n if (header[index] !== \" \") continue\n const left = unquote(header.slice(0, index))\n const right = unquote(header.slice(index + 1))\n if (left._tag === \"PatchInvalid\" || right._tag === \"PatchInvalid\") continue\n if (left.path === \"\" || right.path === \"\") continue\n if (source !== undefined && source !== \"/dev/null\" && source !== left.path) continue\n if (destination !== undefined && destination !== \"/dev/null\" && destination !== right.path) continue\n const defaultPrefixes = prefixes === undefined && left.path.startsWith(\"a/\") && right.path.startsWith(\"b/\")\n const selected = prefixes ?? (defaultPrefixes\n ? { source: \"a/\", destination: \"b/\" }\n : { source: \"\", destination: \"\" })\n if (!left.path.startsWith(selected.source) || !right.path.startsWith(selected.destination)) continue\n const oldPath = left.path.slice(selected.source.length)\n const newPath = right.path.slice(selected.destination.length)\n if (oldPath === \"\" || newPath === \"\") continue\n if (moved !== undefined && (oldPath !== moved.source || newPath !== moved.destination)) continue\n if (\n moved === undefined && source === undefined && destination === undefined && oldPath !== newPath &&\n !(unmarkedBinary && (defaultPrefixes || prefixes !== undefined))\n ) continue\n candidates.push({ oldPath, newPath })\n }\n const paths = candidates[0]\n return candidates.length === 1 && paths !== undefined\n ? { _tag: \"Paths\", ...paths }\n : invalid(\"Inconsistent or ambiguous Git file headers; custom prefixes must be supplied explicitly\")\n}\n\n/** Match every possible summary separator against the authoritative header, including quoted and spaced paths. */\nconst binaryPaths = (\n header: string,\n summary: string,\n prefixes: PatchPrefixes | undefined,\n moved: { readonly source: string; readonly destination: string } | undefined,\n status: FileStatus\n): ReturnType<typeof headerPaths> => {\n if (!summary.endsWith(\" differ\")) return invalid(\"Incomplete binary summary\")\n const body = summary.slice(\"Binary files \".length, -\" differ\".length)\n // Auto mode tries Git's standard prefixes before an unprefixed producer.\n // Otherwise a filename ending in \" and\" can fabricate a second no-prefix interpretation.\n const selections = prefixes === undefined\n ? [{ source: \"a/\", destination: \"b/\" }, { source: \"\", destination: \"\" }]\n : [prefixes]\n for (const selected of selections) {\n const candidates: Array<Extract<ReturnType<typeof headerPaths>, { readonly _tag: \"Paths\" }>> = []\n for (const match of body.matchAll(/(?= and )/g)) {\n const source = unquote(body.slice(0, match.index))\n const destination = unquote(body.slice(match.index + \" and \".length))\n if (source._tag === \"PatchInvalid\" || destination._tag === \"PatchInvalid\") continue\n if ((source.path === \"/dev/null\") !== (status === \"added\")) continue\n if ((destination.path === \"/dev/null\") !== (status === \"deleted\")) continue\n const paths = headerPaths(header, source.path, destination.path, selected, moved)\n if (paths._tag === \"Paths\") candidates.push(paths)\n }\n const paths = candidates[0]\n if (candidates.length === 1 && paths !== undefined) return paths\n if (candidates.length > 1) return invalid(\"Ambiguous binary summary paths\")\n }\n return invalid(\"Binary summary paths disagree with Git headers\")\n}\n\n/** Infer default a/b prefixes when present; pass explicit empty prefixes for unambiguous --no-prefix parsing. */\nexport const parsePatch = (text: string, prefixes?: PatchPrefixes): ParseResult => {\n if (text !== \"\" && !text.endsWith(\"\\n\")) return invalid(\"Unterminated patch record\")\n // A CR on a Git header identifies transport line endings; body-only CR belongs to the source.\n const records = text.split(\"\\n\")\n const converted = records.some((line) => line.startsWith(HEADER) && line.endsWith(\"\\r\"))\n const lines = converted ? records.map((line) => line.endsWith(\"\\r\") ? line.slice(0, -1) : line) : records\n const files: Array<FileDiff> = []\n const currentPaths = new Set<string>()\n let index = 0\n\n while (index < lines.length) {\n const line = lines[index] ?? \"\"\n if (!line.startsWith(HEADER)) {\n index += 1\n continue\n }\n const header = line.slice(HEADER.length)\n let source: string | undefined\n let destination: string | undefined\n let movedSource: string | undefined\n let movedDestination: string | undefined\n let status: FileStatus = \"modified\"\n let fileMode: string | undefined\n let oldMode: string | undefined\n let newMode: string | undefined\n let binary = false\n let binarySummary: string | undefined\n const hunks: Array<Hunk> = []\n let oldEnd = 0\n let newEnd = 0\n let oldEof = false\n let newEof = false\n const oldCoordinates = new Set<number>()\n const newCoordinates = new Set<number>()\n index += 1\n\n while (index < lines.length && !(lines[index] ?? \"\").startsWith(HEADER)) {\n const line = lines[index] ?? \"\"\n if (/^(new file|deleted file|old|new) mode/.test(line)) {\n const mode = /^(new file|deleted file|old|new) mode ([0-7]{6})$/.exec(line)\n if (mode === null) return invalid(\"Invalid file mode header\")\n const value = mode[2]\n if (mode[1] === \"old\") {\n if (oldMode !== undefined && oldMode !== value) return invalid(\"Conflicting old modes\")\n oldMode = value\n } else if (mode[1] === \"new\") {\n if (newMode !== undefined && newMode !== value) return invalid(\"Conflicting new modes\")\n newMode = value\n } else {\n const kind = mode[1] === \"new file\" ? \"added\" : \"deleted\"\n if (status !== \"modified\" && status !== kind) return invalid(\"Conflicting file status headers\")\n if (fileMode !== undefined && fileMode !== value) return invalid(\"Conflicting file modes\")\n status = kind\n fileMode = value\n }\n } else if (/^(rename|copy) (from|to) /.test(line)) {\n const kind = line.startsWith(\"copy \") ? \"copied\" : \"renamed\"\n if (status !== \"modified\" && status !== kind) return invalid(\"Conflicting file status headers\")\n status = kind\n const path = unquote(line.replace(/^(rename|copy) (from|to) /, \"\"))\n if (path._tag === \"PatchInvalid\") return path\n if (/^(rename|copy) from /.test(line)) {\n if (movedSource !== undefined && movedSource !== path.path) return invalid(\"Conflicting move source paths\")\n movedSource = path.path\n } else {\n if (movedDestination !== undefined && movedDestination !== path.path) {\n return invalid(\"Conflicting move destination paths\")\n }\n movedDestination = path.path\n }\n } else if (line.startsWith(\"GIT binary patch\")) {\n if (line !== \"GIT binary patch\") return invalid(\"Invalid binary patch marker\")\n const payload = readBinary(lines, index + 1)\n if (payload._tag === \"PatchInvalid\") return payload\n binary = true\n index = payload.next\n continue\n } else if (line.startsWith(\"Binary files \")) {\n if (binarySummary !== undefined && binarySummary !== line) return invalid(\"Conflicting binary summaries\")\n binarySummary = line\n binary = true\n } else if (line.startsWith(\"--- \") || line.startsWith(\"+++ \")) {\n const path = unquote(line.slice(4).replace(/\\t$/, \"\"))\n if (path._tag === \"PatchInvalid\") return path\n if (line.startsWith(\"--- \")) {\n if (source !== undefined && source !== path.path) return invalid(\"Conflicting source file markers\")\n source = path.path\n } else {\n if (destination !== undefined && destination !== path.path) {\n return invalid(\"Conflicting destination file markers\")\n }\n destination = path.path\n }\n } else if (HUNK.test(line)) {\n if (source === undefined || destination === undefined) return invalid(\"Text hunks require paired file markers\")\n const parsed = readHunk(lines, index)\n if (parsed._tag === \"PatchInvalid\") return parsed\n if (!parsed.hunk.lines.some((record) => record.kind === \"add\" || record.kind === \"del\")) {\n return invalid(\"Text hunk has no change evidence\")\n }\n if (parsed.oldOffset < oldEnd || parsed.newOffset < newEnd) return invalid(\"Hunk ranges move backwards\")\n oldEnd = parsed.oldEnd\n newEnd = parsed.newEnd\n for (const record of parsed.hunk.lines) {\n if ((oldEof && record.oldNo !== undefined) || (newEof && record.newNo !== undefined)) {\n return invalid(\"Patch records follow an EOF marker on the same side\")\n }\n if (record.noNewline === true) {\n oldEof ||= record.oldNo !== undefined\n newEof ||= record.newNo !== undefined\n }\n if (\n (record.oldNo !== undefined && oldCoordinates.has(record.oldNo)) ||\n (record.newNo !== undefined && newCoordinates.has(record.newNo))\n ) return invalid(`Overlapping hunk at line ${index + 1}`)\n if (record.oldNo !== undefined) oldCoordinates.add(record.oldNo)\n if (record.newNo !== undefined) newCoordinates.add(record.newNo)\n }\n hunks.push(parsed.hunk)\n index = parsed.next\n continue\n } else if (/^(?:@@|[+\\- \\\\])/.test(line)) {\n return invalid(`Unexpected patch body at line ${index + 1}`)\n }\n index += 1\n }\n if ((source === undefined) !== (destination === undefined)) return invalid(\"Unpaired file markers\")\n if ((movedSource === undefined) !== (movedDestination === undefined)) {\n return invalid(\"Unpaired rename or copy headers\")\n }\n if ((oldMode === undefined) !== (newMode === undefined)) return invalid(\"Unpaired mode transition\")\n if (fileMode !== undefined && oldMode !== undefined) return invalid(\"Conflicting file mode headers\")\n if (oldMode !== undefined && (source === \"/dev/null\" || destination === \"/dev/null\")) {\n return invalid(\"Mode transition requires both file sides\")\n }\n if (binary && source !== undefined) return invalid(\"Mixed binary and text bodies\")\n if (source !== undefined && hunks.length === 0) return invalid(\"Text markers require hunks\")\n if (source === \"/dev/null\" && destination === \"/dev/null\") return invalid(\"Both file sides are absent\")\n if (\n hunks.some((hunk) =>\n hunk.lines.some((line) =>\n (source === \"/dev/null\" && line.oldNo !== undefined) ||\n (destination === \"/dev/null\" && line.newNo !== undefined)\n )\n )\n ) return invalid(\"Absent file side contains text lines\")\n if (source !== undefined) {\n const markerStatus = source === \"/dev/null\" ? \"added\" : destination === \"/dev/null\" ? \"deleted\" : \"modified\"\n if (\n (status === \"added\" || status === \"deleted\" || markerStatus !== \"modified\") &&\n status !== \"modified\" && status !== markerStatus\n ) return invalid(\"File status disagrees with file markers\")\n if (markerStatus !== \"modified\") status = markerStatus\n }\n if (\n hunks.length === 0 && !binary && movedSource === undefined && fileMode === undefined &&\n (oldMode === undefined || oldMode === newMode)\n ) return invalid(\"File block has no change evidence\")\n const moved = movedSource === undefined || movedDestination === undefined\n ? undefined\n : { source: movedSource, destination: movedDestination }\n const paths = binarySummary === undefined\n ? headerPaths(header, source, destination, prefixes, moved, binary)\n : binaryPaths(header, binarySummary, prefixes, moved, status)\n if (paths._tag === \"PatchInvalid\") return paths\n if (\n binary && source === undefined && moved === undefined && status !== \"modified\" && paths.oldPath !== paths.newPath\n ) {\n return invalid(\"Binary addition or deletion has conflicting header paths\")\n }\n const path = status === \"deleted\" ? paths.oldPath : paths.newPath\n if (currentPaths.has(path)) return invalid(\"Duplicate canonical current file path\")\n currentPaths.add(path)\n files.push({\n path,\n oldPath: paths.oldPath,\n newPath: paths.newPath,\n status,\n binary,\n ...(status === \"deleted\" && fileMode !== undefined\n ? { oldMode: fileMode }\n : oldMode === undefined\n ? {}\n : { oldMode }),\n ...(status === \"added\" && fileMode !== undefined\n ? { newMode: fileMode }\n : newMode === undefined\n ? {}\n : { newMode }),\n hunks\n })\n }\n if (files.length === 0 && text.trim() !== \"\") return invalid(\"Expected a git unified diff\")\n return { _tag: \"Patch\", patch: { files } }\n}\n\n/** Validate Git's literal/delta record framing without inflating or applying binary content. */\nconst readBinary = (\n lines: ReadonlyArray<string>,\n start: number\n): { readonly _tag: \"Binary\"; readonly next: number } | PatchInvalid => {\n let index = start\n let chunks = 0\n do {\n const header = /^(literal|delta) (\\d+)$/.exec(lines[index] ?? \"\")\n if (header === null || !Number.isSafeInteger(Number(header[2]))) return invalid(\"Invalid binary chunk header\")\n index += 1\n const first = index\n while (index < lines.length && lines[index] !== \"\") {\n const line = lines[index] ?? \"\"\n const lead = line.charCodeAt(0)\n const length = lead >= 65 && lead <= 90 ? lead - 64 : lead >= 97 && lead <= 122 ? lead - 70 : 0\n if (\n length === 0 || line.length !== 1 + Math.ceil(length / 4) * 5 ||\n !/^[0-9A-Za-z!#$%&()*+;<=>?@^_`{|}~-]+$/.test(line.slice(1))\n ) return invalid(\"Invalid binary chunk data\")\n index += 1\n }\n // A final split sentinel is not the blank record that terminates a Git payload.\n if (index === first || index >= lines.length - 1) return invalid(\"Incomplete binary chunk\")\n index += 1\n chunks += 1\n } while (chunks < 2 && /^(literal|delta)(?:\\s|$)/.test(lines[index] ?? \"\"))\n if (/^(literal|delta)(?:\\s|$)/.test(lines[index] ?? \"\")) return invalid(\"Surplus binary chunk\")\n return { _tag: \"Binary\", next: index }\n}\n\nconst readHunk = (\n lines: ReadonlyArray<string>,\n start: number\n): {\n readonly _tag: \"Hunk\"\n readonly hunk: Hunk\n readonly next: number\n readonly oldOffset: number\n readonly newOffset: number\n readonly oldEnd: number\n readonly newEnd: number\n} | PatchInvalid => {\n const match = HUNK.exec(lines[start] ?? \"\")\n if (match === null) return invalid(`not a hunk header at line ${start + 1}`)\n const oldStart = Number(match[1])\n const newStart = Number(match[3])\n let oldCount = match[2] === undefined ? 1 : Number(match[2])\n let newCount = match[4] === undefined ? 1 : Number(match[4])\n if (![oldStart, newStart, oldCount, newCount].every(Number.isSafeInteger)) return invalid(\"Unsafe hunk integers\")\n if (oldCount === 0 && newCount === 0) return invalid(\"Empty hunk\")\n if (\n (oldCount > 0 && !Number.isSafeInteger(oldStart + (oldCount - 1))) ||\n (newCount > 0 && !Number.isSafeInteger(newStart + (newCount - 1)))\n ) return invalid(\"Hunk coordinates overflow\")\n // Half-open zero-based ranges: empty Git ranges anchor after the named line.\n const oldOffset = oldStart - (oldCount === 0 ? 0 : 1)\n const newOffset = newStart - (newCount === 0 ? 0 : 1)\n const oldEnd = oldOffset + oldCount\n const newEnd = newOffset + newCount\n let oldNo = oldStart\n let newNo = newStart\n const body: Array<DiffLine> = []\n let index = start + 1\n\n while (index < lines.length && (oldCount > 0 || newCount > 0)) {\n const line = lines[index] ?? \"\"\n const marker = line[0]\n const text = line.slice(1)\n if (marker === \"+\") {\n body.push({ kind: \"add\", text, newNo })\n newNo += 1\n newCount -= 1\n } else if (marker === \"-\") {\n body.push({ kind: \"del\", text, oldNo })\n oldNo += 1\n oldCount -= 1\n } else if (marker === \" \") {\n body.push({ kind: \"context\", text, oldNo, newNo })\n oldNo += 1\n newNo += 1\n oldCount -= 1\n newCount -= 1\n } else {\n break\n }\n index += 1\n // A marker belongs to exactly one preceding body record and consumes no coordinate.\n if ((lines[index] ?? \"\").startsWith(\"\\\\\")) {\n if (lines[index] !== \"\\\\") return invalid(`Invalid newline marker at line ${index + 1}`)\n const previous = body[body.length - 1]\n if (previous !== undefined) body[body.length - 1] = { ...previous, noNewline: true }\n index += 1\n }\n }\n if (oldCount !== 0 || newCount !== 0) return invalid(`Incomplete hunk at line ${start + 1}`)\n\n return {\n _tag: \"Hunk\",\n oldOffset,\n newOffset,\n oldEnd,\n newEnd,\n hunk: { header: match[5]?.trim() ?? \"\", oldStart, newStart, lines: body },\n next: index\n }\n}\n\n/** Changed-file paths: the current name first, then the source of a rename or modified comparison. */\nexport const pathsOf = (file: FileDiff): ReadonlyArray<string> =>\n file.status === \"renamed\" || (file.status === \"modified\" && file.oldPath !== file.newPath)\n ? [file.newPath, file.oldPath]\n : [file.path]\n\nexport const findFile = (patch: Patch, path: string): FileDiff | undefined =>\n patch.files.find((file) => file.path === path) ?? patch.files.find((file) => pathsOf(file).includes(path))\n","import { Fragment, type ReactElement, type ReactNode } from \"react\"\nimport styles from \"../bounded/BoundedDiffCodeView.module.css\"\nimport { RLY_SPLIT_DIFF_MIN_WIDTH, useNarrowerThan } from \"../../internal/useNarrowerThan.js\"\nimport type { DiffLine, FileDiff, Hunk } from \"./parse.js\"\n\nexport { findFile, parsePatch, pathsOf } from \"./parse.js\"\nexport type {\n DiffLine,\n FileDiff,\n FileStatus,\n Hunk,\n LineKind,\n ParseResult,\n Patch,\n PatchInvalid,\n PatchPrefixes\n} from \"./parse.js\"\n\nexport interface PatchDiffViewProps {\n readonly file: FileDiff\n /** Unique prefix for stable source-line links within the document. */\n readonly id: string\n readonly mode?: \"split\" | \"stacked\"\n readonly wrap?: boolean\n /** Called once for each visible side and line; consumers own annotation identity and content. */\n readonly renderAnnotation?: (side: \"old\" | \"new\", line: number) => ReactNode\n}\n\ninterface Row {\n readonly left: DiffLine | undefined\n readonly right: DiffLine | undefined\n}\n\n/** Pair consecutive deletions and additions without renumbering sparse patch hunks. */\nexport const pairRows = (hunk: Hunk): ReadonlyArray<Row> => {\n const rows: Array<Row> = []\n let index = 0\n while (index < hunk.lines.length) {\n const line = hunk.lines[index]\n if (line === undefined) break\n if (line.kind === \"context\") {\n rows.push({ left: line, right: line })\n index++\n continue\n }\n const deleted: Array<DiffLine> = []\n const added: Array<DiffLine> = []\n while (hunk.lines[index]?.kind === \"del\") {\n const next = hunk.lines[index++]\n if (next !== undefined) deleted.push(next)\n }\n while (hunk.lines[index]?.kind === \"add\") {\n const next = hunk.lines[index++]\n if (next !== undefined) added.push(next)\n }\n for (let offset = 0; offset < Math.max(deleted.length, added.length); offset++) {\n const left = deleted[offset]\n const right = added[offset]\n rows.push({ left, right })\n }\n }\n return rows\n}\n\n/** Render a patch as an accessible, server-renderable table. Source omissions stay omitted. */\nexport const PatchDiffView = ({\n file,\n id,\n mode = \"split\",\n renderAnnotation,\n wrap = false\n}: PatchDiffViewProps): ReactElement => {\n // A split view stacks in a narrow container, so neither side is clipped to a sliver.\n const [narrow, measureRef] = useNarrowerThan<HTMLDivElement>(RLY_SPLIT_DIFF_MIN_WIDTH)\n const shown = mode === \"split\" && narrow ? \"stacked\" : mode\n const cell = (line: DiffLine | undefined, side: \"old\" | \"new\") => {\n const number = side === \"old\" ? line?.oldNo : line?.newNo\n return (\n <>\n <td className={styles.lineNumber}>{number}</td>\n <td className={side === \"old\" ? styles.deletionCode : styles.additionCode}>\n {line === undefined ? null : (\n <>\n <code className={wrap ? styles.wrappedCode : styles.code} id={`${id}-${side}-${number}`} tabIndex={-1}>\n {line.text || \" \"}\n </code>\n {line.noNewline === true ? (\n <small aria-label={`${side === \"old\" ? \"Before\" : \"After\"}: no newline`}>\n No newline at end of file\n </small>\n ) : null}\n </>\n )}\n </td>\n </>\n )\n }\n const annotation = (line: DiffLine | undefined, side: \"old\" | \"new\") => {\n const number = side === \"old\" ? line?.oldNo : line?.newNo\n const content = number === undefined ? undefined : renderAnnotation?.(side, number)\n return content == null ? null : (\n <tr className={styles.annotationRow}>\n <td className={styles.annotationCell} colSpan={4}>\n {content}\n </td>\n </tr>\n )\n }\n return (\n <div className={styles.root} data-rly-patch-diff=\"\" data-rly-diff-mode={shown} ref={measureRef}>\n {file.oldMode === undefined && file.newMode === undefined ? null : (\n <p className={styles.noChanges}>\n {file.oldMode === undefined\n ? `Mode added: ${file.newMode}`\n : file.newMode === undefined\n ? `Mode removed: ${file.oldMode}`\n : `Mode: ${file.oldMode} → ${file.newMode}`}\n </p>\n )}\n {file.binary || file.hunks.length === 0 ? (\n <p className={styles.noChanges}>{file.binary ? \"Binary file.\" : \"No content change.\"}</p>\n ) : (\n <div style={{ overflowX: \"auto\" }} role=\"region\" aria-label={`Changes in ${file.path}`} tabIndex={0}>\n <table className={styles.table} aria-label={`Changes in ${file.path}`}>\n <thead>\n <tr>\n {shown === \"split\" ? (\n <>\n <th colSpan={2} scope=\"colgroup\">\n Before\n </th>\n <th colSpan={2} scope=\"colgroup\">\n After\n </th>\n </>\n ) : (\n <>\n <th scope=\"col\">Before</th>\n <th scope=\"col\">After</th>\n <th colSpan={2} scope=\"colgroup\">\n Change\n </th>\n </>\n )}\n </tr>\n </thead>\n <tbody>\n {file.hunks.map((hunk, hunkIndex) => (\n <Fragment key={hunkIndex}>\n <tr className={styles.hunk}>\n <td colSpan={4}>\n @@ {hunk.oldStart} → {hunk.newStart} {hunk.header}\n </td>\n </tr>\n {shown === \"split\"\n ? pairRows(hunk).map((row, rowIndex) => (\n <Fragment key={rowIndex}>\n <tr className={row.left?.kind === \"context\" ? styles.context : styles.change}>\n {cell(row.left, \"old\")}\n {cell(row.right, \"new\")}\n </tr>\n {annotation(row.left, \"old\")}\n {annotation(row.right, \"new\")}\n </Fragment>\n ))\n : hunk.lines.map((line, lineIndex) => (\n <Fragment key={lineIndex}>\n <tr\n className={\n line.kind === \"add\"\n ? styles.addition\n : line.kind === \"del\"\n ? styles.deletion\n : styles.context\n }\n >\n <td className={styles.lineNumber}>\n <span id={line.oldNo === undefined ? undefined : `${id}-old-${line.oldNo}`} tabIndex={-1}>\n {line.oldNo}\n </span>\n </td>\n <td className={styles.lineNumber}>\n <span id={line.newNo === undefined ? undefined : `${id}-new-${line.newNo}`} tabIndex={-1}>\n {line.newNo}\n </span>\n </td>\n <td className={styles.marker}>\n {line.kind === \"add\" ? \"+\" : line.kind === \"del\" ? \"−\" : \" \"}\n </td>\n <td>\n <code className={wrap ? styles.wrappedCode : styles.code}>{line.text || \" \"}</code>\n {line.noNewline === true ? (\n <small\n aria-label={\n line.kind === \"del\"\n ? \"Before: no newline\"\n : line.kind === \"add\"\n ? \"After: no newline\"\n : \"Before: no newline; After: no newline\"\n }\n >\n No newline at end of file\n </small>\n ) : null}\n </td>\n </tr>\n {annotation(line, \"old\")}\n {annotation(line, \"new\")}\n </Fragment>\n ))}\n </Fragment>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
@@ -4,6 +4,8 @@
4
4
  color-scheme: light dark;
5
5
  --rly-font-ui: "Geist Variable", "Geist", system-ui, sans-serif;
6
6
  --rly-font-mono: "Geist Mono Variable", "Geist Mono", ui-monospace, monospace;
7
+ --rly-focus-ring-width: 2px;
8
+ --rly-focus-ring-offset: 2px;
7
9
  --rly-color-canvas: light-dark(#F6F6F8, #101114);
8
10
  --rly-color-surface-1: light-dark(#FFFFFF, #17181C);
9
11
  --rly-color-surface-2: light-dark(#F0F1F4, #1E2025);