Download static/app.js from 192C3/QanoonAI: direct link, hf CLI and curl.
- Browser
- Download file 7.03 kB
-
https://huggingface.co/spaces/192C3/QanoonAI/resolve/main/static/app.js
- Command line
-
hf download hf://spaces/192C3/QanoonAI/static/app.js
-
curl -L -o app.js https://huggingface.co/spaces/192C3/QanoonAI/resolve/main/static/app.js
7.03 kB
| let currentDomain = 'general'; | |
| let currentLang = 'en'; | |
| let currentAnswer = ''; | |
| let mediaRecorder = null; | |
| let audioChunks = []; | |
| function setDomain(domain) { | |
| currentDomain = domain; | |
| document.getElementById('phone-home').style.display = 'none'; | |
| document.getElementById('phone-detail').style.display = 'block'; | |
| const domainNames = { | |
| 'islamic': 'Islamic law', | |
| 'harassment': 'Harassment law', | |
| 'inheritance': 'Inheritance law', | |
| 'verify': 'Law verification', | |
| 'general': 'General law' | |
| }; | |
| document.getElementById('detail-domain').textContent = domainNames[domain]; | |
| document.getElementById('detail-question').textContent = 'Ask your question...'; | |
| document.getElementById('detail-answer').textContent = 'Your answer will appear here.'; | |
| // Focus search | |
| document.getElementById('search-input').focus(); | |
| } | |
| function showHome() { | |
| document.getElementById('phone-home').style.display = 'block'; | |
| document.getElementById('phone-detail').style.display = 'none'; | |
| } | |
| function focusSearch() { | |
| document.getElementById('search-input').focus(); | |
| } | |
| function setLang(lang, btn) { | |
| currentLang = lang; | |
| document.querySelectorAll('.lang-btn').forEach(b => b.classList.remove('active')); | |
| btn.classList.add('active'); | |
| } | |
| function setAnswerLang(lang, btn) { | |
| // Re-generate answer in new language | |
| if (currentAnswer && currentAnswer.original_query) { | |
| askAPI(currentAnswer.original_query, currentDomain, lang, currentAnswer.mode || 'qa'); | |
| } | |
| document.querySelectorAll('#phone-detail .lang-btn').forEach(b => b.classList.remove('active')); | |
| btn.classList.add('active'); | |
| } | |
| function loadRecent(question, domain) { | |
| setDomain(domain); | |
| document.getElementById('detail-question').textContent = question; | |
| askAPI(question, domain, currentLang, 'qa'); | |
| } | |
| function searchQuery() { | |
| const query = document.getElementById('search-input').value.trim(); | |
| if (!query) return; | |
| setDomain(currentDomain); | |
| document.getElementById('detail-question').textContent = query; | |
| askAPI(query, currentDomain, currentLang, 'qa'); | |
| } | |
| async function askAPI(query, domain, lang, mode) { | |
| showLoading(true); | |
| try { | |
| const res = await fetch('/api/ask', { | |
| method: 'POST', | |
| headers: {'Content-Type': 'application/json'}, | |
| body: JSON.stringify({query, domain, lang, mode}) | |
| }); | |
| const data = await res.json(); | |
| currentAnswer = data; | |
| // Update UI | |
| document.getElementById('detail-answer').textContent = data.plain_answer || 'No answer found.'; | |
| document.getElementById('detail-law').textContent = data.law_cited || 'N/A'; | |
| document.getElementById('detail-verdict').textContent = | |
| (data.verdict === 'VERIFIED' ? '✓ Verified: ' : '⚠ ') + | |
| (data.verdict || 'Unknown'); | |
| document.getElementById('detail-dept').textContent = data.where_to_file || 'N/A'; | |
| document.getElementById('detail-action').textContent = data.department || 'Consult local court.'; | |
| document.getElementById('detail-source').textContent = | |
| data.law_cited ? `Source: ${data.law_cited.split(',')[0]}` : 'Source: Database search'; | |
| // Color code verdict | |
| const verifyBox = document.getElementById('detail-verify'); | |
| if (data.verdict === 'FARCE') { | |
| verifyBox.style.background = '#FCEBEB'; | |
| verifyBox.querySelector('.verify-icon').style.background = '#E24B4A'; | |
| verifyBox.querySelector('.verify-text').style.color = '#A32D2D'; | |
| } else if (data.verdict === 'NOT IN DATABASE') { | |
| verifyBox.style.background = '#FFF3E0'; | |
| verifyBox.querySelector('.verify-icon').style.background = '#F57C00'; | |
| verifyBox.querySelector('.verify-text').style.color = '#E65100'; | |
| } | |
| } catch (err) { | |
| document.getElementById('detail-answer').textContent = 'Error: Could not connect to server.'; | |
| console.error(err); | |
| } | |
| showLoading(false); | |
| } | |
| async function startVoice() { | |
| try { | |
| const stream = await navigator.mediaDevices.getUserMedia({audio: true}); | |
| mediaRecorder = new MediaRecorder(stream); | |
| audioChunks = []; | |
| mediaRecorder.ondataavailable = e => audioChunks.push(e.data); | |
| mediaRecorder.onstop = async () => { | |
| const audioBlob = new Blob(audioChunks, {type: 'audio/wav'}); | |
| await sendVoice(audioBlob); | |
| }; | |
| mediaRecorder.start(); | |
| alert('🎙️ Recording... Speak now! Click OK to stop.'); | |
| mediaRecorder.stop(); | |
| stream.getTracks().forEach(t => t.stop()); | |
| } catch (err) { | |
| alert('Microphone access denied or not available.'); | |
| } | |
| } | |
| async function sendVoice(audioBlob) { | |
| showLoading(true); | |
| const formData = new FormData(); | |
| formData.append('audio', audioBlob); | |
| formData.append('domain', currentDomain); | |
| formData.append('lang', currentLang); | |
| try { | |
| const res = await fetch('/api/voice', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| const data = await res.json(); | |
| document.getElementById('detail-question').textContent = data.transcript || 'Voice input'; | |
| currentAnswer = data; | |
| document.getElementById('detail-answer').textContent = data.plain_answer || 'No answer.'; | |
| document.getElementById('detail-law').textContent = data.law_cited || 'N/A'; | |
| document.getElementById('detail-verdict').textContent = data.verdict || 'Unknown'; | |
| document.getElementById('detail-dept').textContent = data.where_to_file || 'N/A'; | |
| showHome(); | |
| document.getElementById('phone-detail').style.display = 'block'; | |
| } catch (err) { | |
| alert('Error processing voice.'); | |
| } | |
| showLoading(false); | |
| } | |
| async function speakAnswer() { | |
| if (!currentAnswer || !currentAnswer.plain_answer) return; | |
| const text = currentAnswer.plain_answer; | |
| const lang = currentLang === 'urdu' ? 'urdu' : 'en'; | |
| try { | |
| const res = await fetch(`/api/tts?text=${encodeURIComponent(text)}&lang=${lang}`); | |
| const blob = await res.blob(); | |
| const url = URL.createObjectURL(blob); | |
| const audio = document.getElementById('tts-audio'); | |
| audio.src = url; | |
| audio.style.display = 'block'; | |
| audio.play(); | |
| } catch (err) { | |
| console.error('TTS error:', err); | |
| } | |
| } | |
| function showHistory() { | |
| alert('History feature coming soon!'); | |
| } | |
| function showLoading(show) { | |
| document.getElementById('loading').classList.toggle('active', show); | |
| } | |
| // Clock | |
| setInterval(() => { | |
| const now = new Date(); | |
| const time = now.getHours() + ':' + String(now.getMinutes()).padStart(2, '0'); | |
| document.getElementById('clock').textContent = time; | |
| document.getElementById('clock2').textContent = time; | |
| }, 1000); |