Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>GoLang Nexus | Developer Dashboard</title> | |
| <!-- Importing Inter Font and Fira Code for that IDE look --> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> | |
| <!-- Font Awesome for Icons --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| /* Go Brand Colors & Dark Theme Palette */ | |
| --go-cyan: #00ADD8; | |
| --go-cyan-dim: #008bae; | |
| --bg-dark: #0f1115; | |
| --bg-panel: #161b22; | |
| --bg-panel-hover: #21262d; | |
| --border-color: #30363d; | |
| --text-main: #c9d1d9; | |
| --text-muted: #8b949e; | |
| --success: #2ea043; | |
| --code-bg: #0d1117; | |
| /* Syntax Highlighting Colors */ | |
| --syntax-keyword: #ff7b72; | |
| --syntax-func: #d2a8ff; | |
| --syntax-string: #a5d6ff; | |
| --syntax-comment: #8b949e; | |
| --syntax-type: #79c0ff; | |
| --sidebar-width: 260px; | |
| --header-height: 60px; | |
| --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background-color: var(--bg-dark); | |
| color: var(--text-main); | |
| height: 100vh; | |
| overflow: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| /* --- Scrollbar Styling --- */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| height: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: var(--bg-dark); | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: var(--border-color); | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: var(--text-muted); | |
| } | |
| /* --- Header --- */ | |
| header { | |
| height: var(--header-height); | |
| background-color: var(--bg-panel); | |
| border-bottom: 1px solid var(--border-color); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 0 20px; | |
| z-index: 100; | |
| } | |
| .brand { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| font-weight: 700; | |
| font-size: 1.2rem; | |
| color: #fff; | |
| text-decoration: none; | |
| } | |
| .brand i { | |
| color: var(--go-cyan); | |
| font-size: 1.4rem; | |
| } | |
| .anycoder-link { | |
| font-size: 0.8rem; | |
| color: var(--text-muted); | |
| text-decoration: none; | |
| background: rgba(0, 173, 216, 0.1); | |
| padding: 4px 8px; | |
| border-radius: 4px; | |
| transition: var(--transition); | |
| border: 1px solid transparent; | |
| } | |
| .anycoder-link:hover { | |
| color: var(--go-cyan); | |
| border-color: var(--go-cyan); | |
| background: rgba(0, 173, 216, 0.15); | |
| } | |
| .header-actions { | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| } | |
| .search-bar { | |
| position: relative; | |
| display: none; /* Hidden on small mobile */ | |
| } | |
| @media (min-width: 768px) { | |
| .search-bar { display: block; } | |
| } | |
| .search-bar input { | |
| background: var(--bg-dark); | |
| border: 1px solid var(--border-color); | |
| padding: 8px 12px 8px 35px; | |
| border-radius: 6px; | |
| color: var(--text-main); | |
| font-family: 'Inter', sans-serif; | |
| font-size: 0.9rem; | |
| width: 250px; | |
| transition: var(--transition); | |
| } | |
| .search-bar input:focus { | |
| outline: none; | |
| border-color: var(--go-cyan); | |
| width: 300px; | |
| } | |
| .search-bar i { | |
| position: absolute; | |
| left: 10px; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| color: var(--text-muted); | |
| font-size: 0.8rem; | |
| } | |
| .user-avatar { | |
| width: 32px; | |
| height: 32px; | |
| border-radius: 50%; | |
| background: linear-gradient(45deg, var(--go-cyan), #4facfe); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: bold; | |
| color: #fff; | |
| cursor: pointer; | |
| } | |
| /* --- Main Layout --- */ | |
| .layout { | |
| display: flex; | |
| flex: 1; | |
| overflow: hidden; | |
| } | |
| /* --- Sidebar --- */ | |
| aside { | |
| width: var(--sidebar-width); | |
| background-color: var(--bg-panel); | |
| border-right: 1px solid var(--border-color); | |
| display: flex; | |
| flex-direction: column; | |
| padding: 20px 0; | |
| transition: var(--transition); | |
| } | |
| .nav-group { | |
| margin-bottom: 25px; | |
| } | |
| .nav-title { | |
| padding: 0 20px; | |
| font-size: 0.75rem; | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| color: var(--text-muted); | |
| margin-bottom: 10px; | |
| font-weight: 600; | |
| } | |
| .nav-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| padding: 10px 20px; | |
| color: var(--text-main); | |
| text-decoration: none; | |
| transition: var(--transition); | |
| border-left: 3px solid transparent; | |
| cursor: pointer; | |
| } | |
| .nav-item:hover { | |
| background-color: var(--bg-panel-hover); | |
| color: #fff; | |
| } | |
| .nav-item.active { | |
| background-color: rgba(0, 173, 216, 0.1); | |
| color: var(--go-cyan); | |
| border-left-color: var(--go-cyan); | |
| } | |
| .nav-item i { | |
| width: 20px; | |
| text-align: center; | |
| } | |
| /* --- Content Area --- */ | |
| main { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| position: relative; | |
| background-color: var(--bg-dark); | |
| } | |
| .toolbar { | |
| height: 50px; | |
| border-bottom: 1px solid var(--border-color); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 0 20px; | |
| background: var(--bg-dark); | |
| } | |
| .file-info { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| font-family: 'Fira Code', monospace; | |
| font-size: 0.9rem; | |
| color: var(--text-muted); | |
| } | |
| .file-info i { color: var(--go-cyan); } | |
| .run-btn { | |
| background-color: var(--success); | |
| color: white; | |
| border: none; | |
| padding: 8px 16px; | |
| border-radius: 6px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| transition: var(--transition); | |
| box-shadow: 0 4px 12px rgba(46, 160, 67, 0.3); | |
| } | |
| .run-btn:hover { | |
| background-color: #2c974b; | |
| transform: translateY(-1px); | |
| } | |
| .run-btn:active { | |
| transform: translateY(1px); | |
| } | |
| /* --- Editor & Output Split --- */ | |
| .workspace { | |
| display: flex; | |
| flex: 1; | |
| overflow: hidden; | |
| } | |
| .editor-pane, .output-pane { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| .editor-pane { | |
| border-right: 1px solid var(--border-color); | |
| } | |
| .pane-header { | |
| padding: 10px 20px; | |
| background: var(--bg-panel); | |
| font-size: 0.8rem; | |
| color: var(--text-muted); | |
| border-bottom: 1px solid var(--border-color); | |
| display: flex; | |
| justify-content: space-between; | |
| } | |
| /* Code Editor Simulation */ | |
| .code-container { | |
| flex: 1; | |
| position: relative; | |
| overflow: auto; | |
| background-color: var(--code-bg); | |
| } | |
| #code-editor { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| padding: 20px; | |
| border: none; | |
| background: transparent; | |
| color: transparent; /* Text is transparent, caret is visible */ | |
| caret-color: white; | |
| font-family: 'Fira Code', monospace; | |
| font-size: 14px; | |
| line-height: 1.6; | |
| resize: none; | |
| outline: none; | |
| white-space: pre; | |
| z-index: 2; | |
| } | |
| #code-highlight { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| padding: 20px; | |
| font-family: 'Fira Code', monospace; | |
| font-size: 14px; | |
| line-height: 1.6; | |
| pointer-events: none; /* Let clicks pass through to textarea */ | |
| z-index: 1; | |
| white-space: pre; | |
| color: var(--text-main); | |
| } | |
| /* Output Console */ | |
| .output-content { | |
| flex: 1; | |
| padding: 20px; | |
| font-family: 'Fira Code', monospace; | |
| font-size: 14px; | |
| color: var(--text-main); | |
| overflow-y: auto; | |
| } | |
| .log-entry { | |
| margin-bottom: 5px; | |
| opacity: 0; | |
| animation: fadeIn 0.3s forwards; | |
| } | |
| .log-entry.error { color: #ff7b72; } | |
| .log-entry.success { color: #79c0ff; } | |
| .log-entry.info { color: var(--text-muted); } | |
| @keyframes fadeIn { | |
| to { opacity: 1; } | |
| } | |
| /* Gopher Animation Area */ | |
| .gopher-stage { | |
| height: 150px; | |
| background: linear-gradient(180deg, var(--bg-panel) 0%, var(--bg-dark) 100%); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| border-bottom: 1px solid var(--border-color); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .gopher-svg { | |
| height: 100px; | |
| transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); | |
| } | |
| .gopher-svg.running { | |
| animation: bounce 0.6s infinite alternate; | |
| } | |
| @keyframes bounce { | |
| from { transform: translateY(0); } | |
| to { transform: translateY(-20px); } | |
| } | |
| /* Mobile Responsive */ | |
| .mobile-toggle { | |
| display: none; | |
| background: none; | |
| border: none; | |
| color: var(--text-main); | |
| font-size: 1.2rem; | |
| cursor: pointer; | |
| } | |
| @media (max-width: 768px) { | |
| .mobile-toggle { display: block; margin-right: 15px; } | |
| aside { | |
| position: absolute; | |
| left: -100%; | |
| height: 100%; | |
| z-index: 200; | |
| box-shadow: 10px 0 20px rgba(0,0,0,0.5); | |
| } | |
| aside.open { left: 0; } | |
| .workspace { flex-direction: column; } | |
| .editor-pane { border-right: none; border-bottom: 1px solid var(--border-color); height: 60%; } | |
| .output-pane { height: 40%; } | |
| .search-bar { display: none; } | |
| } | |
| /* Syntax Highlighting Classes */ | |
| .kw { color: var(--syntax-keyword); font-weight: bold; } | |
| .fn { color: var(--syntax-func); } | |
| .str { color: var(--syntax-string); } | |
| .com { color: var(--syntax-comment); font-style: italic; } | |
| .typ { color: var(--syntax-type); } | |
| .num { color: #bd93f9; } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Header --> | |
| <header> | |
| <div class="brand"> | |
| <button class="mobile-toggle" onclick="toggleSidebar()"><i class="fas fa-bars"></i></button> | |
| <i class="fab fa-golang"></i> | |
| <span>GoNexus</span> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a> | |
| </div> | |
| <div class="header-actions"> | |
| <div class="search-bar"> | |
| <i class="fas fa-search"></i> | |
| <input type="text" placeholder="Search packages (e.g. fmt, http)..."> | |
| </div> | |
| <div class="user-avatar" title="User Profile">GD</div> | |
| </div> | |
| </header> | |
| <div class="layout"> | |
| <!-- Sidebar --> | |
| <aside id="sidebar"> | |
| <div class="nav-group"> | |
| <div class="nav-title">Workspace</div> | |
| <a href="#" class="nav-item active" onclick="switchTab(this, 'playground')"> | |
| <i class="fas fa-terminal"></i> Playground | |
| </a> | |
| <a href="#" class="nav-item" onclick="switchTab(this, 'docs')"> | |
| <i class="fas fa-book"></i> Documentation | |
| </a> | |
| <a href="#" class="nav-item" onclick="switchTab(this, 'packages')"> | |
| <i class="fas fa-box-open"></i> Packages | |
| </a> | |
| </div> | |
| <div class="nav-group"> | |
| <div class="nav-title">Examples</div> | |
| <a href="#" class="nav-item" onclick="loadExample('hello')"> | |
| <i class="fas fa-code"></i> Hello World | |
| </a> | |
| <a href="#" class="nav-item" onclick="loadExample('loop')"> | |
| <i class="fas fa-sync"></i> Loops & Switch | |
| </a> | |
| <a href="#" class="nav-item" onclick="loadExample('struct')"> | |
| <i class="fas fa-cubes"></i> Structs | |
| </a> | |
| </div> | |
| <div style="margin-top: auto; padding: 20px;"> | |
| <div style="font-size: 0.8rem; color: var(--text-muted);"> | |
| Go Version: <span style="color: var(--go-cyan);">1.21.0</span> | |
| </div> | |
| </div> | |
| </aside> | |
| <!-- Main Content --> | |
| <main> | |
| <!-- Toolbar --> | |
| <div class="toolbar"> | |
| <div class="file-info"> | |
| <i class="far fa-file-code"></i> | |
| <span>main.go</span> | |
| </div> | |
| <button class="run-btn" onclick="runCode()"> | |
| <i class="fas fa-play"></i> Run | |
| </button> | |
| </div> | |
| <div class="workspace"> | |
| <!-- Editor --> | |
| <div class="editor-pane"> | |
| <div class="code-container"> | |
| <!-- Highlight Layer --> | |
| <div id="code-highlight"></div> | |
| <!-- Input Layer --> | |
| <textarea id="code-editor" spellcheck="false" oninput="updateHighlight()" onscroll="syncScroll()"></textarea> | |
| </div> | |
| </div> | |
| <!-- Output --> | |
| <div class="output-pane"> | |
| <div class="gopher-stage"> | |
| <!-- Inline SVG Go Gopher --> | |
| <svg class="gopher-svg" id="gopher" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"> | |
| <g fill="#00ADD8"> | |
| <path d="M100,40 C70,40 50,60 50,90 C50,110 60,120 60,120 L60,140 C60,140 40,140 40,160 C40,175 60,180 80,180 L120,180 C140,180 160,175 160,160 C160,140 140,140 140,140 L140,120 C140,120 150,110 150,90 C150,60 130,40 100,40 Z"/> | |
| <circle cx="85" cy="80" r="8" fill="#fff"/> | |
| <circle cx="115" cy="80" r="8" fill="#fff"/> | |
| <circle cx="85" cy="80" r="3" fill="#000"/> | |
| <circle cx="115" cy="80" r="3" fill="#000"/> | |
| <path d="M90,100 Q100,110 110,100" stroke="#fff" stroke-width="3" fill="none" stroke-linecap="round"/> | |
| </g> | |
| <g fill="#fff"> | |
| <path d="M40,100 L20,90 L25,110 Z"/> | |
| <path d="M160,100 L180,90 L175,110 Z"/> | |
| </g> | |
| </svg> | |
| </div> | |
| <div class="pane-header"> | |
| <span>Console Output</span> | |
| <i class="fas fa-trash" style="cursor:pointer" onclick="clearConsole()" title="Clear Console"></i> | |
| </div> | |
| <div class="output-content" id="console-output"> | |
| <div class="log-entry info">// Ready to compile...</div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| <script> | |
| // --- Data & State --- | |
| const examples = { | |
| hello: `package main | |
| import "fmt" | |
| func main() { | |
| fmt.Println("Hello, Go Developer!") | |
| fmt.Println("Welcome to GoNexus.") | |
| }`, | |
| loop: `package main | |
| import "fmt" | |
| func main() { | |
| i := 1 | |
| for i <= 3 { | |
| fmt.Println(i) | |
| i = i + 1 | |
| } | |
| switch 2 { | |
| case 1: | |
| fmt.Println("One") | |
| case 2: | |
| fmt.Println("Two") | |
| default: | |
| fmt.Println("Other") | |
| } | |
| }`, | |
| struct: `package main | |
| import "fmt" | |
| type Vertex struct { | |
| X int | |
| Y int | |
| } | |
| func main() { | |
| v := Vertex{1, 2} | |
| fmt.Println(v) | |
| fmt.Println(v.X) | |
| // Modifying fields | |
| v.X = 10 | |
| fmt.Println("Updated:", v) | |
| }` | |
| }; | |
| // --- Core Functions --- | |
| function init() { | |
| loadExample('hello'); | |
| setupEditorEvents(); | |
| } | |
| function toggleSidebar() { | |
| document.getElementById('sidebar').classList.toggle('open'); | |
| } | |
| function switchTab(element, tabName) { | |
| // Remove active class from all nav items | |
| document.querySelectorAll('.nav-item').forEach(el => el.classList.remove('active')); | |
| // Add active to clicked | |
| element.classList.add('active'); | |
| // Close sidebar on mobile after click | |
| if(window.innerWidth <= 768) { | |
| document.getElementById('sidebar').classList.remove('open'); | |
| } | |
| if(tabName !== 'playground') { | |
| logToConsole(`[System] Navigated to ${tabName} view (Demo only)`, 'info'); | |
| } | |
| } | |
| function loadExample(key) { | |
| const code = examples[key]; | |
| const editor = document.getElementById('code-editor'); | |
| editor.value = code; | |
| updateHighlight(); | |
| clearConsole(); | |
| logToConsole(`[System] Loaded example: ${key}.go`, 'info'); | |
| } | |
| // --- Syntax Highlighting Logic (Simple Regex) --- | |
| function updateHighlight() { | |
| const editor = document.getElementById('code-editor'); | |
| const highlight = document.getElementById('code-highlight'); | |
| let text = editor.value; | |
| // Escape HTML | |
| text = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); | |
| // Simple Go Syntax Highlighting Rules | |
| // Keywords | |
| text = text.replace(/\b(package|import|func|return|var|const|type|struct|interface|map|chan|go|defer|if|else|for|switch|case|default|break|continue)\b/g, '<span class="kw">$1</span>'); | |
| // Built-in types | |
| text = text.replace(/\b(int|string|bool|float64|byte|rune|error|nil)\b/g, '<span class="typ">$1</span>'); | |
| // Functions (rough approximation) | |
| text = text.replace(/\b(fmt|Println|Printf|Sprintf|make|len|cap|new|append|copy|close|delete|complex|real|imag|panic|recover)\b/g, '<span class="fn">$1</span>'); | |
| // Strings | |
| text = text.replace(/(".*?")/g, '<span class="str">$1</span>'); | |
| // Comments | |
| text = text.replace(/(\/\/.*)/g, '<span class="com">$1</span>'); | |
| // Numbers | |
| text = text.replace(/\b(\d+)\b/g, '<span class="num">$1</span>'); | |
| // Handle trailing newline for visual consistency | |
| if (text[text.length - 1] === "\n") { | |
| text += " "; | |
| } | |
| highlight.innerHTML = text; | |
| } | |
| function syncScroll() { | |
| const editor = document.getElementById('code-editor'); | |
| const highlight = document.getElementById('code-highlight'); | |
| highlight.scrollTop = editor.scrollTop; | |
| highlight.scrollLeft = editor.scrollLeft; | |
| } | |
| function setupEditorEvents() { | |
| const editor = document.getElementById('code-editor'); | |
| // Handle Tab key to insert spaces instead of changing focus | |
| editor.addEventListener('keydown', function(e) { | |
| if (e.key == 'Tab') { | |
| e.preventDefault(); | |
| var start = this.selectionStart; | |
| var end = this.selectionEnd; | |
| // Set textarea value to: text before caret + tab + text after caret | |
| this.value = this.value.substring(0, start) + | |
| " " + this.value.substring(end); | |
| // Put caret at right position again | |
| this.selectionStart = this.selectionEnd = start + 4; | |
| updateHighlight(); | |
| } | |
| }); | |
| } | |
| // --- Simulation Logic --- | |
| function runCode() { | |
| const code = document.getElementById('code-editor').value; | |
| const gopher = document.getElementById('gopher'); | |
| const outputDiv = document.getElementById('console-output'); | |
| // UI Feedback | |
| gopher.classList.add('running'); | |
| logToConsole("> go run main.go", 'info'); | |
| // Simulate processing time | |
| setTimeout(() => { | |
| gopher.classList.remove('running'); | |
| // Very basic parser to simulate output based on input text | |
| // This is a mock interpreter for the UI demo | |
| const lines = code.split('\n'); | |
| let hasOutput = false; | |
| lines.forEach(line => { | |
| // Clean line | |
| const cleanLine = line.trim(); | |
| if (cleanLine.includes('fmt.Println')) { | |
| // Extract string inside quotes | |
| const match = cleanLine.match(/fmt\.Println\((.*)\)/); | |
| if (match && match[1]) { | |
| let content = match[1].replace(/"/g, ''); | |
| // Handle variables roughly | |
| if(content.includes('+') || content.includes('v')) { | |
| // Mock dynamic content | |
| if(content.includes('v')) content = "{10 2}"; | |
| else content = "Calculated Value"; | |
| } | |
| logToConsole(content, 'success'); | |
| hasOutput = true; | |
| } | |
| } else if (cleanLine.includes('fmt.Printf')) { | |
| logToConsole("[Formatted Output Simulation]", 'success'); | |
| hasOutput = true; | |
| } | |
| }); | |
| if (!hasOutput) { | |
| // Check for basic logic simulation | |
| if(code.includes('i <= 3')) { | |
| logToConsole("1", 'success'); | |
| logToConsole("2", 'success'); | |
| logToConsole("3", 'success'); | |
| logToConsole("Two", 'success'); | |
| hasOutput = true; | |
| } | |
| } | |
| if (!hasOutput) { | |
| logToConsole("Program exited with code 0", 'info'); | |
| } else { | |
| logToConsole("Program exited with code 0", 'info'); | |
| } | |
| }, 800); | |
| } | |
| function logToConsole(message, type = 'normal') { | |
| const outputDiv = document.getElementById('console-output'); | |
| const entry = document.createElement('div'); | |
| entry.className = `log-entry ${type}`; | |
| entry.textContent = message; | |
| outputDiv.appendChild(entry); | |
| outputDiv.scrollTop = outputDiv.scrollHeight; | |
| } | |
| function clearConsole() { | |
| const outputDiv = document.getElementById('console-output'); | |
| outputDiv.innerHTML = ''; | |
| } | |
| // Initialize on load | |
| window.addEventListener('DOMContentLoaded', init); | |
| </script> | |
| </body> | |
| </html> |