Spaces:
Sleeping
Sleeping
File size: 6,334 Bytes
6c36389 085e4f6 6c36389 085e4f6 6c36389 085e4f6 6c36389 085e4f6 6c36389 085e4f6 6c36389 085e4f6 6c36389 085e4f6 6c36389 085e4f6 6c36389 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Python Code Parser</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/[email protected]"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<style>
.table-container { overflow-x: auto; }
pre { white-space: pre-wrap; word-wrap: break-word; }
#point-cloud { display: none; width: 100%; height: 400px; }
#point-details { width: 100%; min-height: 100px; background: #1f2937; padding: 1rem; border-radius: 0.5rem; }
</style>
</head>
<body class="bg-gray-900 text-gray-200 min-h-screen p-8 font-sans">
<div class="max-w-7xl mx-auto bg-gray-800 p-6 rounded-xl shadow-2xl">
<h1 class="text-3xl font-bold text-blue-400 mb-6">Python Code Parser</h1>
<!-- Form -->
<form hx-post="/" hx-target="#results" hx-swap="innerHTML" class="space-y-6">
<div>
<label class="block text-sm font-medium text-gray-300 mb-2">Upload a Python File</label>
<input type="file" name="file" accept=".py" class="w-full p-2 border rounded-lg bg-gray-700 text-gray-200">
</div>
<div>
<label class="block text-sm font-medium text-gray-300 mb-2">Or Paste Your Code</label>
<textarea name="code" rows="6" class="w-full p-2 border rounded-lg bg-gray-700 text-gray-200" placeholder="Paste Python code here...">{{ code_input or '' }}</textarea>
<input type="text" name="filename" class="mt-2 w-full p-2 border rounded-lg bg-gray-700 text-gray-200" placeholder="Enter filename (e.g., script.py)" value="{{ filename or '' }}">
</div>
<button type="submit" class="w-full bg-blue-500 text-white p-2 rounded-lg hover:bg-blue-600 transition">Parse</button>
</form>
<!-- Results Section -->
<div id="results" class="mt-8">
{% if parts %}
{% include 'results_partial.html' %}
{% endif %}
</div>
</div>
<!-- Three.js Point Cloud Script -->
<script>
let scene, camera, renderer, points, raycaster, mouse, hoveredPoint = null;
const pointDetails = document.getElementById('point-details');
function initPointCloud(parts) {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / 400, 0.1, 1000);
renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('point-cloud') });
renderer.setSize(window.innerWidth * 0.9, 400);
const positions = [];
const colors = [];
parts.forEach((part, index) => {
const vector = part.vector;
const x = vector[0] * 10; // category_id
const y = vector[1] * 10; // level
const z = vector[2] * 100; // center_pos
positions.push(x, y, z);
colors.push(1, 0.5, 0); // Orange points
part.pointIndex = index * 3; // Store index for lookup
});
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
const material = new THREE.PointsMaterial({ size: 5, vertexColors: true });
points = new THREE.Points(geometry, material);
scene.add(points);
camera.position.z = 100;
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
animate();
}
function animate() {
requestAnimationFrame(animate);
points.rotation.y += 0.005;
renderer.render(scene, camera);
}
function onMouseMove(event) {
const rect = renderer.domElement.getBoundingClientRect();
mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObject(points);
if (intersects.length > 0) {
const index = intersects[0].index;
const part = window.parts.find(p => p.pointIndex === index * 3);
if (part && hoveredPoint !== part) {
hoveredPoint = part;
pointDetails.innerHTML = `
<div class="text-gray-200">
<strong>Category:</strong> ${part.category}<br>
<strong>Node ID:</strong> ${part.node_id}<br>
<strong>Parent Path:</strong> ${part.parent_path}<br>
<strong>Level:</strong> ${part.level}<br>
<strong>Location:</strong> Lines ${part.location[0]} to ${part.location[1]}<br>
<strong>Vector:</strong> [${part.vector.join(', ')}]<br>
<strong>Code:</strong><pre class="text-xs text-gray-300">${part.source}</pre>
</div>
`;
}
} else {
hoveredPoint = null;
pointDetails.innerHTML = '<p class="text-gray-400">Hover over a point to see details</p>';
}
}
function togglePointCloud() {
const canvas = document.getElementById('point-cloud');
const table = document.getElementById('results-table');
if (canvas.style.display === 'none') {
canvas.style.display = 'block';
table.style.display = 'none';
if (!scene && window.parts) {
initPointCloud(window.parts);
document.addEventListener('mousemove', onMouseMove);
}
} else {
canvas.style.display = 'none';
table.style.display = 'block';
document.removeEventListener('mousemove', onMouseMove);
}
}
</script>
</body>
</html> |