Download templates/single.html from devranx/PRISM: direct link, hf CLI and curl.
- Browser
- Download file 10.4 kB
-
https://huggingface.co/spaces/devranx/PRISM/resolve/main/templates/single.html
- Command line
-
hf download hf://spaces/devranx/PRISM/templates/single.html
-
curl -L -o single.html https://huggingface.co/spaces/devranx/PRISM/resolve/main/templates/single.html
10.4 kB
| <html lang="en" class="dark"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Single Classification</title> | |
| <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> | |
| <style> | |
| html.dark { | |
| --bg-color: #1a202c; | |
| --text-color: #e2e8f0; | |
| --card-bg-color: #2d3748; | |
| --card-border-color: #4a5568; | |
| --btn-bg-color: #4a5568; | |
| --btn-hover-bg-color: #2c5282; | |
| --btn-text-color: #e2e8f0; | |
| } | |
| html.light { | |
| --bg-color: #f7fafc; | |
| --text-color: #2d3748; | |
| --card-bg-color: #ffffff; | |
| --card-border-color: #e2e8f0; | |
| --btn-bg-color: #3182ce; | |
| --btn-hover-bg-color: #2c5282; | |
| --btn-text-color: #ffffff; | |
| } | |
| body { | |
| background-color: var(--bg-color); | |
| color: var(--text-color); | |
| } | |
| .card { | |
| background-color: var(--card-bg-color); | |
| border: 1px solid var(--card-border-color); | |
| } | |
| .btn { | |
| background-color: var(--btn-bg-color); | |
| color: var(--btn-text-color); | |
| } | |
| .btn:hover { | |
| background-color: var(--btn-hover-bg-color); | |
| } | |
| .loading { | |
| display: none; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0, 0, 0, 0.5); | |
| z-index: 1000; | |
| } | |
| .result-table { | |
| font-family: monospace; | |
| white-space: pre; | |
| } | |
| .classification-text { | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| } | |
| .btn-classify { | |
| background-color: #10b981; | |
| color: white; | |
| font-size: 1.1rem; | |
| padding: 0.75rem 1.5rem; | |
| border-radius: 9999px; | |
| } | |
| .btn-classify:hover { | |
| background-color: #059669; | |
| } | |
| .btn-remove { | |
| background-color: #ef4444; | |
| color: white; | |
| font-size: 1.1rem; | |
| padding: 0.75rem 1.5rem; | |
| border-radius: 9999px; | |
| } | |
| .btn-remove:hover { | |
| background-color: #dc2626; | |
| } | |
| .results-container { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| text-align: center; | |
| } | |
| .classification-result { | |
| margin: 1.5rem 0; | |
| text-align: center; | |
| } | |
| .table-container { | |
| width: 100%; | |
| display: flex; | |
| justify-content: center; | |
| text-align: left; | |
| } | |
| /* Loading overlay styles */ | |
| .loading-overlay { | |
| background: rgba(0, 0, 0, 0.7); | |
| color: white; | |
| } | |
| .loading-text { | |
| color: white; | |
| font-size: 1.2rem; | |
| font-weight: 500; | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <div class="flex justify-end mb-4"> | |
| <button id="themeToggle" class="bg-gray-800 text-white px-4 py-2 rounded hover:bg-gray-600"> | |
| ☀️ | |
| </button> | |
| </div> | |
| <h1 class="text-3xl font-bold text-center mb-8">Single Image Classification</h1> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-8"> | |
| <!-- Left Column: Image Upload --> | |
| <div class="card p-6 rounded-lg shadow-md"> | |
| <div id="uploadSection" class="mb-4"> | |
| <label class="block text-sm font-bold mb-2">Upload Image</label> | |
| <input type="file" id="imageInput" accept=".jpg,.jpeg,.png" class="hidden"> | |
| <button onclick="document.getElementById('imageInput').click()" class="btn w-full py-2 px-4 rounded"> | |
| Select Image | |
| </button> | |
| </div> | |
| <div id="imagePreview" class="mt-4 hidden"> | |
| <img id="preview" class="max-w-full h-auto rounded-lg"> | |
| <div class="mt-4 flex space-x-4"> | |
| <button onclick="removeImage()" class="btn btn-remove flex-1"> | |
| Remove | |
| </button> | |
| <button onclick="classifyImage()" class="btn btn-classify flex-1"> | |
| Classify | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Column: Results --> | |
| <div class="card p-6 rounded-lg shadow-md"> | |
| <h2 class="text-xl font-bold mb-4 text-center">Classification Results</h2> | |
| <div id="results" class="results-container"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Loading Overlay --> | |
| <div id="loading" class="loading flex items-center justify-center"> | |
| <div class="loading-overlay p-8 rounded-lg text-center"> | |
| <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-white mx-auto"></div> | |
| <p id="loadingText" class="mt-4 loading-text">Processing...</p> | |
| </div> | |
| </div> | |
| <script> | |
| // Theme handling | |
| const themeToggle = document.getElementById('themeToggle'); | |
| const htmlElement = document.documentElement; | |
| // Initialize theme | |
| if (!localStorage.getItem('theme')) { | |
| localStorage.setItem('theme', 'dark'); | |
| } | |
| // Apply saved theme or default to dark | |
| const currentTheme = localStorage.getItem('theme') || 'dark'; | |
| htmlElement.classList.remove('light', 'dark'); | |
| htmlElement.classList.add(currentTheme); | |
| themeToggle.textContent = currentTheme === 'dark' ? '☀️' : '🌙'; | |
| // Theme toggle handler | |
| themeToggle.addEventListener('click', () => { | |
| const isDark = htmlElement.classList.contains('dark'); | |
| htmlElement.classList.remove('dark', 'light'); | |
| const newTheme = isDark ? 'light' : 'dark'; | |
| htmlElement.classList.add(newTheme); | |
| localStorage.setItem('theme', newTheme); | |
| themeToggle.textContent = newTheme === 'dark' ? '☀️' : '🌙'; | |
| }); | |
| // File handling | |
| let currentFile = null; | |
| document.getElementById('imageInput').addEventListener('change', function(e) { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| uploadFile(file); | |
| } | |
| }); | |
| function uploadFile(file) { | |
| const formData = new FormData(); | |
| formData.append('file', file); | |
| showLoading('Uploading...'); | |
| fetch('/upload_single', { | |
| method: 'POST', | |
| body: formData | |
| }) | |
| .then(response => response.json()) | |
| .then(data => { | |
| if (data.filename) { | |
| currentFile = data.filename; | |
| document.getElementById('preview').src = `/static/uploads/single/${data.filename}`; | |
| document.getElementById('imagePreview').classList.remove('hidden'); | |
| document.getElementById('uploadSection').classList.add('hidden'); | |
| } else { | |
| alert(data.error || 'Upload failed'); | |
| } | |
| }) | |
| .catch(error => { | |
| console.error('Error:', error); | |
| alert('Upload failed'); | |
| }) | |
| .finally(() => { | |
| hideLoading(); | |
| }); | |
| } | |
| function removeImage() { | |
| document.getElementById('imageInput').value = ''; | |
| document.getElementById('imagePreview').classList.add('hidden'); | |
| document.getElementById('uploadSection').classList.remove('hidden'); | |
| document.getElementById('results').innerHTML = ''; | |
| currentFile = null; | |
| } | |
| function classifyImage() { | |
| if (!currentFile) { | |
| alert('Please upload an image first'); | |
| return; | |
| } | |
| showLoading('Classifying...'); | |
| fetch('/classify_single', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ filename: currentFile }) | |
| }) | |
| .then(response => response.json()) | |
| .then(data => { | |
| if (data.error) { | |
| throw new Error(data.error); | |
| } | |
| const resultsDiv = document.getElementById('results'); | |
| resultsDiv.innerHTML = ` | |
| <div class="classification-result"> | |
| <span class="font-bold">Classification: </span> | |
| <span class="classification-text ${data.classification === 'Pass' ? 'text-green-600' : 'text-red-600'}"> | |
| ${data.classification} | |
| </span> | |
| </div> | |
| <div class="table-container"> | |
| <pre class="whitespace-pre-wrap font-mono text-sm">${data.result_table}</pre> | |
| </div> | |
| `; | |
| }) | |
| .catch(error => { | |
| console.error('Error:', error); | |
| alert('Classification failed: ' + error.message); | |
| }) | |
| .finally(() => { | |
| hideLoading(); | |
| }); | |
| } | |
| function showLoading(text) { | |
| document.getElementById('loading').style.display = 'flex'; | |
| document.getElementById('loadingText').textContent = text; | |
| } | |
| function hideLoading() { | |
| document.getElementById('loading').style.display = 'none'; | |
| } | |
| </script> | |
| </body> | |
| </html> |