Download api/static/app.js from arjun10g/RAG-PSYCH: direct link, hf CLI and curl.
- Browser
- Download file 4.41 kB
-
https://huggingface.co/spaces/arjun10g/RAG-PSYCH/resolve/main/api/static/app.js
- Command line
-
hf download hf://spaces/arjun10g/RAG-PSYCH/api/static/app.js
-
curl -L -o app.js https://huggingface.co/spaces/arjun10g/RAG-PSYCH/resolve/main/api/static/app.js
4.41 kB
| // Three.js neural-particle hero scene. | |
| // | |
| // A drifting cloud of particles connected by short lines whenever any two | |
| // particles fall within a threshold distance. Loose neuro/network theme, | |
| // keeps memory and CPU low (no model loads, no shaders beyond the | |
| // PointsMaterial built-in). Resizes with the viewport and pauses when | |
| // the tab is hidden so it doesn't drain battery in the background. | |
| import * as THREE from "three"; | |
| const canvas = document.getElementById("neural-bg"); | |
| if (canvas) { | |
| const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true }); | |
| renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); | |
| const scene = new THREE.Scene(); | |
| const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 1000); | |
| camera.position.z = 60; | |
| const PARTICLE_COUNT = 140; | |
| const FIELD_SIZE = 80; | |
| const LINK_DISTANCE = 14; | |
| const positions = new Float32Array(PARTICLE_COUNT * 3); | |
| const velocities = new Float32Array(PARTICLE_COUNT * 3); | |
| for (let i = 0; i < PARTICLE_COUNT; i++) { | |
| positions[i * 3] = (Math.random() - 0.5) * FIELD_SIZE; | |
| positions[i * 3 + 1] = (Math.random() - 0.5) * FIELD_SIZE; | |
| positions[i * 3 + 2] = (Math.random() - 0.5) * FIELD_SIZE * 0.6; | |
| velocities[i * 3] = (Math.random() - 0.5) * 0.04; | |
| velocities[i * 3 + 1] = (Math.random() - 0.5) * 0.04; | |
| velocities[i * 3 + 2] = (Math.random() - 0.5) * 0.04; | |
| } | |
| const pGeom = new THREE.BufferGeometry(); | |
| pGeom.setAttribute("position", new THREE.BufferAttribute(positions, 3)); | |
| const pMat = new THREE.PointsMaterial({ | |
| size: 1.4, | |
| color: 0x67e8f9, // cyan-300 | |
| transparent: true, | |
| opacity: 0.85, | |
| sizeAttenuation: true, | |
| }); | |
| const points = new THREE.Points(pGeom, pMat); | |
| scene.add(points); | |
| // Pre-allocate the lines geometry to a generous upper bound so we don't | |
| // re-allocate buffers every frame. Capacity is the worst-case pair count. | |
| const MAX_LINKS = PARTICLE_COUNT * 8; | |
| const linePositions = new Float32Array(MAX_LINKS * 2 * 3); | |
| const lineGeom = new THREE.BufferGeometry(); | |
| lineGeom.setAttribute("position", new THREE.BufferAttribute(linePositions, 3)); | |
| const lineMat = new THREE.LineBasicMaterial({ | |
| color: 0xe879f9, // fuchsia-400 | |
| transparent: true, | |
| opacity: 0.18, | |
| }); | |
| const lines = new THREE.LineSegments(lineGeom, lineMat); | |
| scene.add(lines); | |
| function resize() { | |
| const w = window.innerWidth, h = window.innerHeight; | |
| renderer.setSize(w, h, false); | |
| camera.aspect = w / h; | |
| camera.updateProjectionMatrix(); | |
| } | |
| resize(); | |
| window.addEventListener("resize", resize); | |
| let running = true; | |
| document.addEventListener("visibilitychange", () => { | |
| running = document.visibilityState === "visible"; | |
| if (running) animate(); | |
| }); | |
| function animate() { | |
| if (!running) return; | |
| requestAnimationFrame(animate); | |
| // Drift particles, wrap around the field box. | |
| for (let i = 0; i < PARTICLE_COUNT; i++) { | |
| for (let axis = 0; axis < 3; axis++) { | |
| const idx = i * 3 + axis; | |
| positions[idx] += velocities[idx]; | |
| const limit = axis === 2 ? FIELD_SIZE * 0.3 : FIELD_SIZE * 0.5; | |
| if (positions[idx] > limit) positions[idx] = -limit; | |
| else if (positions[idx] < -limit) positions[idx] = limit; | |
| } | |
| } | |
| pGeom.attributes.position.needsUpdate = true; | |
| // Recompute neighbor links. O(N²) but N=140 → ~20K dist checks/frame, fine. | |
| let written = 0; | |
| for (let i = 0; i < PARTICLE_COUNT; i++) { | |
| for (let j = i + 1; j < PARTICLE_COUNT; j++) { | |
| const dx = positions[i*3] - positions[j*3]; | |
| const dy = positions[i*3+1] - positions[j*3+1]; | |
| const dz = positions[i*3+2] - positions[j*3+2]; | |
| const d2 = dx*dx + dy*dy + dz*dz; | |
| if (d2 < LINK_DISTANCE * LINK_DISTANCE && written < MAX_LINKS) { | |
| const k = written * 6; | |
| linePositions[k] = positions[i*3]; | |
| linePositions[k+1] = positions[i*3+1]; | |
| linePositions[k+2] = positions[i*3+2]; | |
| linePositions[k+3] = positions[j*3]; | |
| linePositions[k+4] = positions[j*3+1]; | |
| linePositions[k+5] = positions[j*3+2]; | |
| written++; | |
| } | |
| } | |
| } | |
| lineGeom.setDrawRange(0, written * 2); | |
| lineGeom.attributes.position.needsUpdate = true; | |
| points.rotation.y += 0.0008; | |
| lines.rotation.y += 0.0008; | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| } | |