Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Node View - TUM Neural Net</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet"> | |
| <style> | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-slate-50 text-slate-800 min-h-screen pb-20"> | |
| <!-- Navbar --> | |
| <nav class="bg-white border-b border-slate-200 sticky top-0 z-50"> | |
| <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | |
| <div class="flex justify-between h-16"> | |
| <div class="flex items-center"> | |
| <a href="/" class="flex items-center gap-2 text-slate-500 hover:text-slate-900 transition-colors"> | |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | |
| d="M10 19l-7-7m0 0l7-7m-7 7h18"></path> | |
| </svg> | |
| <span class="font-medium">Return to Network</span> | |
| </a> | |
| </div> | |
| <div class="flex items-center"> | |
| <span class="text-sm font-mono text-slate-400" id="node-id-display">Node ID: Loading...</span> | |
| </div> | |
| </div> | |
| </div> | |
| </nav> | |
| <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> | |
| <!-- Left Column: Content (2/3) --> | |
| <div class="lg:col-span-2 space-y-8"> | |
| <!-- Header Card --> | |
| <div class="bg-white p-8 rounded-2xl shadow-sm border border-slate-200"> | |
| <div class="flex items-center gap-2 mb-4"> | |
| <span | |
| class="bg-blue-100 text-blue-800 text-xs font-bold px-2.5 py-0.5 rounded border border-blue-200">ACTIVE | |
| NODE</span> | |
| <span class="text-xs text-slate-400 font-mono" id="node-type">Type: WebPage</span> | |
| </div> | |
| <h1 class="text-3xl font-extrabold text-slate-900 mb-4 leading-tight" id="title">Loading Node | |
| Data...</h1> | |
| <div class="flex items-center gap-4 text-sm text-slate-500 border-t border-slate-100 pt-4"> | |
| <a href="#" id="external-link" target="_blank" | |
| class="flex items-center gap-1 text-blue-600 hover:text-blue-800 font-medium transition-colors"> | |
| <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | |
| d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"> | |
| </path> | |
| </svg> | |
| Visit Source Origin | |
| </a> | |
| </div> | |
| </div> | |
| <!-- Content Card --> | |
| <div class="bg-white p-8 rounded-2xl shadow-sm border border-slate-200"> | |
| <h2 class="text-lg font-bold text-slate-900 mb-4 flex items-center gap-2"> | |
| <svg class="w-5 h-5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | |
| d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"> | |
| </path> | |
| </svg> | |
| Extracted Knowledge | |
| </h2> | |
| <div class="prose prose-slate max-w-none text-slate-600 leading-relaxed" id="content"> | |
| <!-- Content injected here --> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Column: Connections (1/3) --> | |
| <div class="space-y-8"> | |
| <!-- Collaborative Filtering (Community Trails) --> | |
| <div id="collab-section" class="hidden"> | |
| <div | |
| class="bg-gradient-to-br from-orange-50 to-white p-6 rounded-2xl shadow-sm border border-orange-100"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <h2 class="text-lg font-bold text-orange-900 flex items-center gap-2"> | |
| 👣 Community Trails | |
| </h2> | |
| <div class="group relative flex justify-center"> | |
| <svg class="w-4 h-4 text-orange-400 cursor-help" fill="none" stroke="currentColor" | |
| viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | |
| d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path> | |
| </svg> | |
| <span | |
| class="absolute bottom-6 scale-0 transition-all rounded bg-slate-800 p-2 text-xs text-white group-hover:scale-100 w-48 text-center z-50"> | |
| Paths frequently taken by other humans. These links have high "Transitive Trust". | |
| </span> | |
| </div> | |
| </div> | |
| <div class="space-y-3" id="collab-list"> | |
| <!-- Injected Items --> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Semantic Recommendations (Synapses) --> | |
| <div class="bg-white p-6 rounded-2xl shadow-sm border border-slate-200"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <h2 class="text-lg font-bold text-slate-900 flex items-center gap-2"> | |
| 🧠 Semantic Synapses | |
| </h2> | |
| <div class="group relative flex justify-center"> | |
| <svg class="w-4 h-4 text-slate-400 cursor-help" fill="none" stroke="currentColor" | |
| viewBox="0 0 24 24"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | |
| d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path> | |
| </svg> | |
| <span | |
| class="absolute bottom-6 scale-0 transition-all rounded bg-slate-800 p-2 text-xs text-white group-hover:scale-100 w-48 text-center z-50"> | |
| Concepts that are mathematically similar in the high-dimensional vector space. | |
| </span> | |
| </div> | |
| </div> | |
| <div class="space-y-3" id="related-list"> | |
| <!-- Injected Items --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <script src="config.js"></script> | |
| <script> | |
| const itemId = window.location.pathname.split('/').pop(); | |
| let currentUrl = ""; | |
| async function loadItem() { | |
| try { | |
| const response = await fetch(API_CONFIG.getURL(`${API_CONFIG.endpoints.item}/${itemId}`)); | |
| const data = await response.json(); | |
| if (!response.ok) throw new Error(data.message || 'Failed to load'); | |
| const item = data.item; | |
| const payload = item.payload; | |
| currentUrl = payload.url; | |
| // Render Main Content | |
| document.title = `Node: ${payload.url} - TUM Neural Net`; | |
| document.getElementById('title').textContent = payload.url; | |
| document.getElementById('node-id-display').textContent = `ID: ${item.id.substring(0, 8)}...`; | |
| document.getElementById('content').textContent = payload.content || payload.content_preview; | |
| document.getElementById('external-link').href = payload.url; | |
| // Render Semantic Synapses (Related) | |
| const relatedList = document.getElementById('related-list'); | |
| relatedList.innerHTML = ''; | |
| data.related.forEach(rel => { | |
| const card = document.createElement('a'); | |
| card.href = `/view/${rel.id}`; | |
| card.className = 'block p-4 rounded-xl border border-slate-100 hover:border-blue-300 hover:bg-blue-50 transition-all group'; | |
| card.onclick = (e) => { recordTransition(rel.id); }; | |
| card.innerHTML = ` | |
| <div class="text-sm font-semibold text-slate-800 group-hover:text-blue-700 truncate mb-1">${rel.payload.url}</div> | |
| <div class="text-xs text-slate-500 line-clamp-2 mb-2">${(rel.payload.content_preview || '').substring(0, 80)}...</div> | |
| <div class="flex items-center gap-1 text-xs text-slate-400 font-mono"> | |
| <span class="w-1.5 h-1.5 bg-blue-400 rounded-full"></span> | |
| Sim: ${rel.score.toFixed(4)} | |
| </div> | |
| `; | |
| relatedList.appendChild(card); | |
| }); | |
| // Render Community Trails (Collaborative) | |
| const collabList = document.getElementById('collab-list'); | |
| if (data.collaborative && data.collaborative.length > 0) { | |
| document.getElementById('collab-section').classList.remove('hidden'); | |
| collabList.innerHTML = ''; | |
| data.collaborative.forEach(col => { | |
| const card = document.createElement('a'); | |
| card.href = `/view/${col.id}`; | |
| card.className = 'block p-4 rounded-xl bg-white border border-orange-100 hover:border-orange-300 hover:shadow-sm transition-all group'; | |
| card.onclick = (e) => { recordTransition(col.id); }; | |
| card.innerHTML = ` | |
| <div class="flex items-center gap-2 mb-1"> | |
| <span class="text-orange-500">🔥</span> | |
| <div class="text-sm font-bold text-slate-800 group-hover:text-orange-700 truncate flex-1">${col.payload.url}</div> | |
| </div> | |
| <div class="text-xs text-slate-500 line-clamp-2 mb-2">${(col.payload.content_preview || '').substring(0, 80)}...</div> | |
| <div class="flex items-center gap-1 text-xs text-orange-600 font-bold bg-orange-50 inline-block px-2 py-1 rounded"> | |
| ${col.count} Travelers | |
| </div> | |
| `; | |
| collabList.appendChild(card); | |
| }); | |
| } else { | |
| document.getElementById('collab-section').classList.add('hidden'); | |
| } | |
| } catch (e) { | |
| document.body.innerHTML = `<div class="p-10 text-center text-red-600 font-bold">Error loading node: ${e.message}</div>`; | |
| } | |
| } | |
| function recordTransition(targetId) { | |
| const formData = new FormData(); | |
| formData.append('item_id', targetId); | |
| formData.append('action', 'click'); | |
| formData.append('source_id', itemId); // itemId is UUID from URL | |
| fetch(API_CONFIG.getURL(API_CONFIG.endpoints.feedback), { | |
| method: 'POST', | |
| body: formData, | |
| keepalive: true | |
| }); | |
| } | |
| loadItem(); | |
| </script> | |
| </body> | |
| </html> |