Spaces:
Paused
Paused
| export interface LineDiff { | |
| type: 'same' | 'add' | 'remove'; | |
| content: string; | |
| oldLineNumber?: number; | |
| newLineNumber?: number; | |
| truncated?: boolean; | |
| } | |
| export function calculateLineDiff( | |
| oldText: string, | |
| newText: string | |
| ): LineDiff[] { | |
| const oldLines = oldText.split('\n'); | |
| const newLines = newText.split('\n'); | |
| // Safety check | |
| if (oldLines.length * newLines.length > 2500000) { | |
| // 1500 x 1500 lines | |
| return [ | |
| { | |
| type: 'remove', | |
| content: `[Content too large to diff: ${oldLines.length} lines]`, | |
| oldLineNumber: 1, | |
| truncated: true, | |
| }, | |
| { | |
| type: 'add', | |
| content: `[Content too large to diff: ${newLines.length} lines]`, | |
| newLineNumber: 1, | |
| truncated: true, | |
| }, | |
| ]; | |
| } | |
| return computeDiff(oldLines, newLines); | |
| } | |
| function computeDiff(oldLines: string[], newLines: string[]): LineDiff[] { | |
| const N = oldLines.length; | |
| const M = newLines.length; | |
| const dp: number[][] = Array(N + 1) | |
| .fill(0) | |
| .map(() => Array(M + 1).fill(0)); | |
| for (let i = 1; i <= N; i++) { | |
| for (let j = 1; j <= M; j++) { | |
| if (oldLines[i - 1] === newLines[j - 1]) { | |
| dp[i][j] = dp[i - 1][j - 1] + 1; | |
| } else { | |
| dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); | |
| } | |
| } | |
| } | |
| const diff: LineDiff[] = []; | |
| let i = N; | |
| let j = M; | |
| while (i > 0 || j > 0) { | |
| if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) { | |
| diff.push({ | |
| type: 'same', | |
| content: oldLines[i - 1], | |
| oldLineNumber: i, | |
| newLineNumber: j, | |
| }); | |
| i--; | |
| j--; | |
| } else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) { | |
| diff.push({ | |
| type: 'add', | |
| content: newLines[j - 1], | |
| newLineNumber: j, | |
| }); | |
| j--; | |
| } else if (i > 0 && (j === 0 || dp[i][j - 1] < dp[i - 1][j])) { | |
| diff.push({ | |
| type: 'remove', | |
| content: oldLines[i - 1], | |
| oldLineNumber: i, | |
| }); | |
| i--; | |
| } | |
| } | |
| return diff.reverse(); | |
| } | |