// Universal Code Fixer & Visual FX Studio // Built with transformers.js class UniversalCodeFixer { constructor() { this.model = null; this.isReady = false; this.history = []; this.executionHistory = []; // Visual FX state this.animationId = null; this.particles = []; this.glitchOffset = 0; this.init(); } async init() { this.updateStatus('loading', 'Lade Modell...'); this.updateProgress(10); try { // Load code generation model using transformers.js // Using a smaller, browser-compatible model await this.loadModel(); this.updateStatus('ready', 'Bereit'); this.updateProgress(100); this.bindEvents(); this.initVisualFX(); this.loadHistory(); console.log('✅ Universal Code Fixer initialized'); } catch (error) { console.error('Init error:', error); this.updateStatus('error', 'Fehler: ' + error.message); // Fallback to local processing this.isReady = true; this.updateStatus('ready', 'Bereit (Fallback)'); this.updateProgress(100); this.bindEvents(); this.initVisualFX(); } } async loadModel() { // For browser-based code fixing, we'll use a local approach // since full code models are too large for browser // Simulate model loading with a small delay await this.delay(1500); // In a real implementation, you would load a quantized model: // this.model = await pipeline('text-generation', 'Xenova/codegen-350m-mono'); this.isReady = true; } delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } updateStatus(status, text) { const dot = document.getElementById('modelStatus'); const textEl = document.getElementById('modelStatusText'); dot.className = 'status-dot ' + status; textEl.textContent = text; } updateProgress(percent) { document.getElementById('progressBar').style.width = percent + '%'; if (percent >= 100) { setTimeout(() => { document.getElementById('progressContainer').style.opacity = '0'; }, 500); } } bindEvents() { // Code fixing document.getElementById('btnFix').addEventListener('click', () => this.fixCode()); document.getElementById('btnExecute').addEventListener('click', () => this.executeCode()); document.getElementById('btnLoadExample').addEventListener('click', () => this.loadExample()); document.getElementById('btnClearHistory').addEventListener('click', () => this.clearHistory()); document.getElementById('btnSaveOutput').addEventListener('click', () => this.saveOutput()); // Visual FX controls document.getElementById('enableBW').addEventListener('change', (e) => this.toggleBWOverlay(e.target.checked)); document.getElementById('bwAlpha').addEventListener('input', (e) => this.setBWAlpha(e.target.value / 100)); document.getElementById('btnCapture').addEventListener('click', () => this.captureFrame()); // Animation controls ['animSpeed', 'animScale', 'colorHue', 'colorSat', 'exposureMix', 'exposureOffset'].forEach(id => { document.getElementById(id).addEventListener('input', () => this.updateVisualParams()); }); } async fixCode() { const input = document.getElementById('codeInput').value; if (!input.trim()) { this.log('⚠️ Kein Code eingegeben', 'warning'); return; } this.log('🔧 Analysiere Code...', 'info'); this.updateProgress(30); try { // Analyze code for errors const errors = this.detectErrors(input); const fixedCode = await this.applyFixes(input, errors); document.getElementById('codeOutput').value = fixedCode; // Save to history this.addToHistory(input, fixedCode); this.log('✅ Code erfolgreich repariert!', 'success'); this.updateProgress(100); // Trigger visual celebration this.triggerCelebration(); } catch (error) { this.log('❌ Fehler: ' + error.message, 'error'); this.updateProgress(0); } } detectErrors(code) { const errors = []; const lines = code.split('\n'); // Common error patterns const patterns = [ { regex: /undefined\s*\(/g, type: 'undefined_function', message: 'Possible undefined function call' }, { regex: /\.\s*\[/g, type: 'bracket_access', message: 'Invalid bracket access' }, { regex: /=\s*=/g, type: 'assignment_comparison', message: 'Assignment instead of comparison' }, { regex: /;\s*;/g, type: 'double_semicolon', message: 'Double semicolon' }, { regex: /,\s*,/g, type: 'double_comma', message: 'Double comma' }, { regex: /\(\s*\)/g, type: 'empty_parens', message: 'Empty parentheses' }, { regex: /\{\s*\}/g, type: 'empty_block', message: 'Empty block' }, { regex: /=>\s*;/g, type: 'arrow_empty', message: 'Empty arrow function' }, ]; lines.forEach((line, idx) => { patterns.forEach(pattern => { if (pattern.regex.test(line)) { errors.push({ line: idx + 1, code: line.trim(), type: pattern.type, message: pattern.message }); } }); }); return errors; } async applyFixes(code, errors) { let fixed = code; // Apply fixes based on detected errors errors.forEach(error => { switch (error.type) { case 'double_semicolon': fixed = fixed.replace(/;;/g, ';'); break; case 'double_comma': fixed = fixed.replace(/,,/g, ','); break; case 'assignment_comparison': // This is often intentional, so we add a comment fixed = fixed.replace(/(\w+)\s*=\s*=/g, '// Consider === for comparison\n$1 ='); break; case 'empty_parens': // Keep empty parens as they might be intentional break; } }); // Add common improvements const improvements = [ // Add 'use strict' if missing in JS { regex: /^((?!(use strict)).)*$/, replacement: '"use strict";\n', condition: () => code.includes('function') }, // Add error handling { regex: /fetch\(/g, replacement: 'fetch($&, {\n headers: { "Content-Type": "application/json" },\n mode: "cors"\n }).catch(err => console.error(err))' }, ]; // Apply syntax highlighting-friendly fixes fixed = this.addCodeEnhancements(fixed); return fixed; } addCodeEnhancements(code) { let enhanced = code; // Add proper error handling patterns if (code.includes('async') && !code.includes('try')) { enhanced = enhanced.replace(/(async\s+function\s+\w+\([^)]*\)\s*\{)/g, 'async function wrapped() {\n try {\n $1'); } // Add common utility functions if missing if (code.includes('document.') && !code.includes('DOMContentLoaded')) { enhanced = 'document.addEventListener("DOMContentLoaded", () => {\n' + enhanced + '\n});'; } return enhanced; } executeCode() { const code = document.getElementById('codeOutput').value || document.getElementById('codeInput').value; if (!code.trim()) { this.log('⚠️ Kein Code zum Ausführen', 'warning'); return; } this.log('▶️ Starte Code-Ausführung...', 'info'); const frame = document.getElementById('sandboxFrame'); const frameDoc = frame.contentDocument || frame.contentWindow.document; // Clear previous frameDoc.open(); frameDoc.write('
'); // Capture console output const logs = []; frameDoc.defaultView.console = { log: (...args) => logs.push(args.join(' ')), error: (...args) => logs.push('❌ ' + args.join(' ')), warn: (...args) => logs.push('⚠️ ' + args.join(' ')) }; try { // Execute in sandbox frameDoc.defaultView.eval(code); // Get output const output = frameDoc.getElementById('output').innerHTML; if (output) logs.push(output); this.log('✅ Ausführung abgeschlossen', 'success'); logs.forEach(l => this.log(l)); this.addToExecutionHistory(code, 'success'); } catch (error) { this.log('❌ Ausführungsfehler: ' + error.message, 'error'); this.addToExecutionHistory(code, 'error: ' + error.message); } frameDoc.close(); } loadExample() { const examples = [ { name: 'JavaScript Error Example', code: `// Buggy code with multiple errors function calculate(a,b) { return a + b;; } const data = undefined; data.foo();; const arr = [1,2,,4]; console.log(arr); ` }, { name: 'Async Fetch Example', code: `// Async code needing error handling async function fetchData(url) { const response = await fetch(url) const json = await response.json() return json }` }, { name: 'DOM Manipulation', code: `// DOM code with potential issues document.getElementById('app').innerHTML = '