| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Hugging Face Space demo</title> |
| <style> |
| body { |
| font-family: Arial, sans-serif; |
| margin: 0; |
| padding: 0; |
| background-color: #f0f2f5; |
| } |
| .container { |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| height: 100vh; |
| } |
| .login-container { |
| background-color: #fff; |
| padding: 40px; |
| border-radius: 8px; |
| box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); |
| width: 350px; |
| text-align: center; |
| } |
| .login-container h2 { |
| margin-bottom: 20px; |
| color: #333; |
| } |
| .login-container input[type="text"], |
| .login-container input[type="password"] { |
| width: calc(100% - 20px); |
| padding: 10px; |
| margin: 10px 0; |
| border: 1px solid #ccc; |
| border-radius: 4px; |
| } |
| .login-container .captcha-container { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| margin: 10px 0; |
| } |
| .login-container .captcha-container input { |
| width: 120px; |
| margin-right: 10px; |
| } |
| .login-container .captcha-container #captcha-text { |
| font-family: 'Courier New', Courier, monospace; |
| font-size: 24px; |
| font-style: italic; |
| text-decoration: line-through; |
| background-color: #e9e9e9; |
| padding: 5px 10px; |
| border-radius: 4px; |
| user-select: none; |
| cursor: pointer; |
| } |
| .login-container button { |
| width: 100%; |
| padding: 12px; |
| background-color: #007bff; |
| border: none; |
| color: white; |
| font-size: 16px; |
| border-radius: 4px; |
| cursor: pointer; |
| margin-top: 20px; |
| } |
| .login-container button:hover { |
| background-color: #0056b3; |
| } |
| #main-system { |
| display: none; |
| width: 100vw; |
| height: 100vh; |
| } |
| .system-header { |
| background-color: #2c3e50; |
| color: #ecf0f1; |
| padding: 15px 20px; |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); |
| } |
| .system-header h1 { |
| margin: 0; |
| font-size: 24px; |
| } |
| .system-header h2 { |
| margin: 0; |
| font-size: 14px; |
| color: #bdc3c7; |
| } |
| .system-header button { |
| background-color: #e74c3c; |
| border: none; |
| color: white; |
| padding: 8px 15px; |
| border-radius: 4px; |
| cursor: pointer; |
| } |
| .system-header button:hover { |
| background-color: #c0392b; |
| } |
| .system-content { |
| display: flex; |
| height: calc(100vh - 60px); |
| } |
| .sidebar { |
| width: 250px; |
| background-color: #34495e; |
| padding: 20px; |
| box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); |
| } |
| .sidebar a { |
| display: block; |
| color: #ecf0f1; |
| text-decoration: none; |
| padding: 15px; |
| margin-bottom: 10px; |
| border-radius: 5px; |
| transition: background-color 0.3s; |
| } |
| .sidebar a:hover, .sidebar a.active { |
| background-color: #1abc9c; |
| } |
| .iframe-container { |
| flex-grow: 1; |
| padding: 20px; |
| background-color: #f9f9f9; |
| overflow: hidden; |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| } |
| iframe { |
| width: 100%; |
| height: 100%; |
| border: 1px solid #ccc; |
| border-radius: 8px; |
| box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); |
| } |
| </style> |
| </head> |
| <body> |
|
|
| <div id="login-page" class="container"> |
| <div class="login-container"> |
| <h2>Hugging Face Space demo</h2> |
| <p>cjhuang@2025copyright</p> |
| <input type="text" id="username" placeholder="Username" required> |
| <input type="password" id="password" placeholder="Password" required> |
| <div class="captcha-container"> |
| <input type="text" id="captcha-input" placeholder="Enter CAPTCHA" required> |
| <span id="captcha-text" onclick="generateCaptcha()"></span> |
| </div> |
| <button onclick="handleLogin()">Login</button> |
| </div> |
| </div> |
|
|
| <div id="main-system"> |
| <div class="system-header"> |
| <div> |
| <h1>Hugging Face Space demo</h1> |
| <h2>cjhuang@2025copyright</h2> |
| </div> |
| <button onclick="logout()">Logout</button> |
| </div> |
| <div class="system-content"> |
| <div class="sidebar"> |
| <a href="#" id="api-tab" class="active" onclick="showIframe('iframe01', this)">多模態API</a> |
| <a href="#" id="webcam-tab" onclick="showIframe('iframe02', this)">WEBCAM_LineBot</a> |
| </div> |
| <div class="iframe-container"> |
| <iframe id="iframe01" src="https://cjian2025-groq-api-gradio.hf.space" frameborder="0"></iframe> |
| <iframe id="iframe02" src="https://cjian2025-webcam-groq-linebot-application.hf.space" frameborder="0" style="display: none;"></iframe> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| let captchaValue = ''; |
| |
| |
| const USER_HASH = '17721868461f8a846c4f02a6c8e312489c670a418525e98544490f23f03b22b6'; |
| const PASS_HASH = '1e374ffc8b82e2f694a974f07a51ac7a86f1b3e5828de316827038e530664972'; |
| |
| async function hashString(str) { |
| const encoder = new TextEncoder(); |
| const data = encoder.encode(str); |
| const hashBuffer = await crypto.subtle.digest('SHA-256', data); |
| const hashArray = Array.from(new Uint8Array(hashBuffer)); |
| const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); |
| return hashHex; |
| } |
| |
| function generateCaptcha() { |
| const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
| let result = ''; |
| for (let i = 0; i < 6; i++) { |
| result += chars.charAt(Math.floor(Math.random() * chars.length)); |
| } |
| captchaValue = result; |
| document.getElementById('captcha-text').innerText = captchaValue; |
| } |
| |
| async function handleLogin() { |
| const username = document.getElementById('username').value; |
| const password = document.getElementById('password').value; |
| const captchaInput = document.getElementById('captcha-input').value; |
| |
| const hashedUsername = await hashString(username); |
| const hashedPassword = await hashString(password); |
| |
| if (hashedUsername === USER_HASH && hashedPassword === PASS_HASH && captchaInput === captchaValue) { |
| document.getElementById('login-page').style.display = 'none'; |
| document.getElementById('main-system').style.display = 'block'; |
| } else { |
| alert('Invalid username, password, or CAPTCHA. Please try again.'); |
| generateCaptcha(); |
| } |
| } |
| |
| function logout() { |
| document.getElementById('main-system').style.display = 'none'; |
| document.getElementById('login-page').style.display = 'flex'; |
| document.getElementById('username').value = ''; |
| document.getElementById('password').value = ''; |
| document.getElementById('captcha-input').value = ''; |
| generateCaptcha(); |
| } |
| |
| function showIframe(iframeId, element) { |
| const iframes = document.querySelectorAll('.iframe-container iframe'); |
| iframes.forEach(iframe => { |
| iframe.style.display = 'none'; |
| }); |
| |
| document.getElementById(iframeId).style.display = 'block'; |
| |
| const tabs = document.querySelectorAll('.sidebar a'); |
| tabs.forEach(tab => { |
| tab.classList.remove('active'); |
| }); |
| |
| element.classList.add('active'); |
| } |
| |
| |
| window.onload = generateCaptcha; |
| </script> |
|
|
| </body> |
| </html> |