📄 CONTRACT INPUT 0 chars
🔒 DSGVO COMPLIANT: Sensitive data (IBANs, emails, names, addresses) automatically masked before API call

Standard Contracts:

🧪 Test Contracts (with PII for Masking):

💡 TEST CONTRACTS INFO
Test contracts contain realistic PII (IBANs, emails, phone, addresses, names). When you click ANALYZE, watch the console to see which data gets masked before API call. ✅ DSGVO compliant!
🔒 MASKING TEST GUIDE
1. Load a test contract from Samples tab
2. Click ANALYZE
3. Open Browser Console (F12 → Console)
4. Look for: "🔒 Masked X sensitive data points"
5. Check Masking Report below for details
📊 Detected PII Patterns:
No test run yet. Click "Run Masking Test" button.
✅ Patterns Being Masked:
• IBANs (DE89 3704...)
• Emails (name@domain.com)
• Phone (+49 30 123...)
• Credit Cards (1234 5678...)
• IDs (AB1234567)
• Addresses (12345 City, Street)
• Names (Herr/Frau Name)
• SSN (123-45-6789)
🧠 ANALYSIS RESULTS Enterprise AI
Click ANALYZE to start AI analysis
🔍
Analysis results will appear here
📄 ORIGINAL CONTRACT
Contains raw PII. See ✨ CLEAN tab for masked version sent to API.
📄
Original contract will appear here
✨ CLEAN CONTRACT (DSGVO MASKED)
🔒 All PII masked. This is the exact version sent to Mistral AI for analysis.
Masked contract will appear here after ANALYZE
Translation will appear here
`; const blob = new Blob([html], { type: 'text/html' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'contract-analysis.html'; link.click(); showToast('✅ HTML exported', 'success'); } function exportToTXT() { if (!analysisState.currentAnalysis) { showToast('❌ No analysis to export', 'error'); return; } const a = analysisState.currentAnalysis; let txt = `CONTRACT ANALYSIS REPORT\n${'='.repeat(50)}\nDate: ${new Date().toLocaleString()}\n\nRISK SCORE: ${a.riskScore}% (${a.riskLevel})\nConfidence: ${(a.confidence*100).toFixed(0)}%\n\n${'='.repeat(50)}\n\nCRITICAL RISKS:\n${a.critical_risks?.length>0?a.critical_risks.map((r,i)=>`${i+1}. [${r.impact||'HIGH'}] ${r.risk}`).join('\n'):'None'}\n\nMISSING CLAUSES:\n${a.missing_clauses?.length>0?a.missing_clauses.map((c,i)=>`${i+1}. ${c}`).join('\n'):'None'}\n\n${'='.repeat(50)}\n🔒 DSGVO Compliant | ⚖️ Contract Analyzer Pro`; const blob = new Blob([txt], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'contract-analysis.txt'; link.click(); showToast('✅ TXT exported', 'success'); } function copyToClipboard() { if (!analysisState.currentAnalysis) { showToast('❌ No analysis to copy', 'error'); return; } const text = JSON.stringify(analysisState.currentAnalysis, null, 2); navigator.clipboard.writeText(text) .then(() => showToast('✅ Copied to clipboard', 'success')) .catch(() => showToast('❌ Copy failed', 'error')); } function clearAll() { if (confirm('Clear all data?')) { document.getElementById('contractInput').value = ''; updateCharCount(); showToast('✅ Cleared', 'success'); } } function showToast(message, type = 'info') { const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => toast.remove(), 3000); } function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, m => map[m]); } function runMaskingTest() { const contractText = document.getElementById('contractInput').value.trim(); if (!contractText) { showToast('❌ Paste contract first', 'error'); return; } let report = '🔒 MASKING TEST REPORT\n\n'; let maskCount = 0; let details = []; // Test each pattern const testPatterns = [ { name: 'IBAN', regex: /\b[A-Z]{2}\d{2}(?:\s?\d{4}){4}(?:\s?\d{1,2})?\b/g }, { name: 'EMAIL', regex: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g }, { name: 'PHONE', regex: /(?:\+49|0)[0-9]{2,3}[\s-]?[\d\s-]{6,10}/g }, { name: 'CREDITCARD', regex: /\b(?:\d{4}[\s-]?){3}\d{4}\b/g }, { name: 'ID', regex: /\b[A-Z]{1,2}\d{7}\b/g }, { name: 'SSN', regex: /\b\d{3}-\d{2}-\d{4}\b/g }, { name: 'ADDRESS', regex: /\d{5}\s+[A-Za-zäöüß\s-]+(?:straße|str\.|platz|allee|ring|weg|strasse)/gi }, { name: 'NAME', regex: /\b(?:Herr|Frau|Mr\.|Mrs\.|Ms\.|Dr\.|Prof\.)\s+([A-Z][a-zäöüß]+(?:\s[A-Z][a-zäöüß]+)?)/g } ]; testPatterns.forEach(pattern => { const matches = contractText.match(pattern.regex) || []; if (matches.length > 0) { maskCount += matches.length; details.push(`\n✅ ${pattern.name}: ${matches.length} found`); matches.slice(0, 3).forEach((m, i) => { details.push(` ${i+1}. "${escapeHtml(m.substring(0, 30))}${m.length > 30 ? '...' : ''}"`); }); if (matches.length > 3) { details.push(` ... and ${matches.length - 3} more`); } } }); report += `\n📊 TOTAL: ${maskCount} sensitive data points detected\n`; report += `\nWhen you click ANALYZE, all ${maskCount} items will be masked\nbefore sending to Mistral API.\n`; report += details.join('\n'); document.getElementById('maskingReport').innerHTML = `
${escapeHtml(report)}
`; showToast(`✅ Found ${maskCount} sensitive data points`, 'success'); } function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, m => map[m]); }