From de73a60a236ee16136f75597e7c46b58cdc0738e Mon Sep 17 00:00:00 2001 From: Dicken Date: Mon, 1 Jun 2026 11:04:14 +0200 Subject: [PATCH] =?UTF-8?q?DevTools:=20Text=20Diff=20und=20Netzwerk-Rechne?= =?UTF-8?q?r=20(Geschwindigkeit,=20IP/Subnetz,=20CIDR)=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/tools/devtools.jsx | 408 +++++++++++++++++++++++++++++++- 1 file changed, 407 insertions(+), 1 deletion(-) diff --git a/frontend/src/tools/devtools.jsx b/frontend/src/tools/devtools.jsx index 04671af..defccb6 100644 --- a/frontend/src/tools/devtools.jsx +++ b/frontend/src/tools/devtools.jsx @@ -939,6 +939,411 @@ function KeyGen({ toast }) { ); } +// ─────────────────────────────────────────────────────────────── Text Diff ── + +function diffLines(a, b) { + const aLines = a.split('\n'); + const bLines = b.split('\n'); + // Myers diff (simple LCS-based) + const m = aLines.length, n = bLines.length; + const dp = Array.from({length: m+1}, () => new Array(n+1).fill(0)); + for (let i = m-1; i >= 0; i--) + for (let j = n-1; j >= 0; j--) + dp[i][j] = aLines[i] === bLines[j] ? dp[i+1][j+1]+1 : Math.max(dp[i+1][j], dp[i][j+1]); + + const result = []; + let i = 0, j = 0; + while (i < m || j < n) { + if (i < m && j < n && aLines[i] === bLines[j]) { + result.push({ type: 'same', text: aLines[i] }); i++; j++; + } else if (j < n && (i >= m || dp[i][j+1] >= dp[i+1][j])) { + result.push({ type: 'add', text: bLines[j] }); j++; + } else { + result.push({ type: 'del', text: aLines[i] }); i++; + } + } + return result; +} + +function TextDiff({ mobile }) { + const [left, setLeft] = useState(''); + const [right, setRight] = useState(''); + const [diff, setDiff] = useState(null); + + function compare() { + if (!left.trim() && !right.trim()) return; + setDiff(diffLines(left, right)); + } + + function clear() { setLeft(''); setRight(''); setDiff(null); } + + function loadFile(e, setter) { + const file = e.target.files?.[0]; + if (!file) return; + const reader = new FileReader(); + reader.onload = ev => { setter(ev.target.result); setDiff(null); }; + reader.readAsText(file); + e.target.value = ''; + } + + const added = diff ? diff.filter(d=>d.type==='add').length : 0; + const removed = diff ? diff.filter(d=>d.type==='del').length : 0; + const same = diff ? diff.filter(d=>d.type==='same').length : 0; + + const ta = { ...S.inp, fontSize:12, fontFamily:"'Courier New',monospace", width:'100%', + boxSizing:'border-box', minHeight:180, resize:'vertical', lineHeight:1.6 }; + + return ( +
+
+ {[['left','Text A (Original)', left, setLeft], ['right','Text B (Neu)', right, setRight]].map(([side, label, val, setter])=>( +
+
+ {label} + +
+