commit b3493bb2946933665405d4eacebef3881d10c5b3
parent 25989dde2e1a5495a75c670d85736fedd76316ae
Author: Amit Dutta <amitdutta4255@gmail.com>
Date: Mon, 12 Jan 2026 11:21:34 +0530
[2025-01-12]
Diffstat:
| A | .firebaserc | | | 5 | +++++ |
| A | .gitignore | | | 69 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | backend.py | | | 226 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | firebase.json | | | 11 | +++++++++++ |
| A | public/404.html | | | 149 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | public/c.html | | | 529 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | public/cpp.html | | | 527 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | public/docs.html | | | 348 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | public/index.html | | | 424 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | public/logo.png | | | 0 | |
| A | public/python.html | | | 499 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | public/sitemap.xml | | | 28 | ++++++++++++++++++++++++++++ |
| A | requirements.txt | | | 3 | +++ |
13 files changed, 2818 insertions(+), 0 deletions(-)
diff --git a/.firebaserc b/.firebaserc
@@ -0,0 +1,5 @@
+{
+ "projects": {
+ "default": "compiler-aranag-site"
+ }
+}
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,69 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+firebase-debug.log*
+firebase-debug.*.log*
+
+# Firebase cache
+.firebase/
+
+# Firebase config
+
+# Uncomment this if you'd like others to create their own Firebase project.
+# For a team working on the same Firebase project(s), it is recommended to leave
+# it commented so all members can deploy to the same project(s) in .firebaserc.
+# .firebaserc
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+
+# dataconnect generated files
+.dataconnect
diff --git a/backend.py b/backend.py
@@ -0,0 +1,225 @@
+import asyncio
+from aiohttp import web
+import json
+import subprocess
+import os
+import sys
+import threading
+import re
+import importlib.util
+import platform # <--- FIXED: Added missing import
+
+# ==================================================================================
+# CLOUD COMPILER SERVER (AIOHTTP) - RENDER COMPATIBLE
+# ==================================================================================
+
+def install_package(package_name, ws=None, loop=None):
+ """Attempt to install a python package via pip."""
+ try:
+ if importlib.util.find_spec(package_name) is not None:
+ return
+
+ msg = f"Installing missing package: {package_name}..."
+ print(msg)
+ if ws and loop:
+ asyncio.run_coroutine_threadsafe(
+ ws.send_json({'type': 'status', 'msg': msg}),
+ loop
+ )
+
+ subprocess.check_call([sys.executable, "-m", "pip", "install", package_name])
+ except Exception as e:
+ error_msg = f"Failed to install {package_name}: {e}"
+ print(error_msg)
+ if ws and loop:
+ asyncio.run_coroutine_threadsafe(
+ ws.send_json({'type': 'stdout', 'data': f"\n[Error] {error_msg}\n"}),
+ loop
+ )
+
+def check_and_install_packages(code, ws=None, loop=None):
+ """Scan Python code for imports and install them if missing."""
+ imports = re.findall(r'^\s*import\s+(\w+)', code, re.MULTILINE)
+ from_imports = re.findall(r'^\s*from\s+(\w+)', code, re.MULTILINE)
+ unique_packages = set(imports + from_imports)
+ for pkg in unique_packages:
+ if pkg in ['os', 'sys', 'time', 'random', 'math', 'json', 'asyncio', 'threading', 'platform', 'subprocess', 're']:
+ continue
+ install_package(pkg, ws, loop)
+
+async def handle_client(request):
+ # --- HEALTH CHECK HANDLING ---
+ # Render sends HEAD/GET to root. If not a websocket upgrade, return OK.
+ if request.headers.get("Upgrade", "").lower() != "websocket":
+ return web.Response(text="OK")
+
+ # --- WEBSOCKET HANDLING ---
+ ws = web.WebSocketResponse()
+ await ws.prepare(request)
+
+ print(f"Client connected: {request.remote}")
+ process = None
+
+ # Helper to read output stream in a separate thread
+ def read_stream(stream, loop):
+ try:
+ while True:
+ # Read 1 byte/char at a time
+ char = stream.read(1)
+ if not char:
+ break
+ # aiohttp's send_json is a coroutine
+ asyncio.run_coroutine_threadsafe(
+ ws.send_json({'type': 'stdout', 'data': char}),
+ loop
+ )
+
+ # --- SIGNAL FINISH ---
+ # When stream ends (process exits), tell frontend
+ asyncio.run_coroutine_threadsafe(
+ ws.send_json({'type': 'status', 'msg': 'Program finished'}),
+ loop
+ )
+
+ except Exception:
+ pass
+
+ try:
+ async for msg in ws:
+ if msg.type == web.WSMsgType.TEXT:
+ data = json.loads(msg.data)
+
+ if data.get('type') == 'run':
+ code = data.get('code')
+ language = data.get('language', 'python')
+
+ # --- PYTHON HANDLING ---
+ if language == 'python':
+ await ws.send_json({'type': 'status', 'msg': 'Checking dependencies...'})
+ loop = asyncio.get_running_loop()
+ await loop.run_in_executor(None, check_and_install_packages, code, ws, loop)
+
+ filename = "temp_script.py"
+ with open(filename, "w", encoding="utf-8") as f:
+ f.write(code)
+
+ env = os.environ.copy()
+ env["PYTHONIOENCODING"] = "utf-8"
+
+ process = subprocess.Popen(
+ [sys.executable, "-u", filename],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True,
+ bufsize=0,
+ encoding='utf-8',
+ env=env
+ )
+ await ws.send_json({'type': 'status', 'msg': 'Running Python...'})
+
+ # --- C HANDLING ---
+ elif language == 'c':
+ filename = "temp_code.c"
+ executable = "./a.out" if platform.system() != "Windows" else "a.exe"
+
+ with open(filename, "w", encoding="utf-8") as f:
+ f.write(code)
+
+ await ws.send_json({'type': 'status', 'msg': 'Compiling C...'})
+
+ compile_process = subprocess.run(
+ ["gcc", filename, "-o", executable],
+ capture_output=True,
+ text=True
+ )
+
+ if compile_process.returncode != 0:
+ await ws.send_json({'type': 'stdout', 'data': f"Compilation Error:\n{compile_process.stderr}"})
+ continue
+
+ await ws.send_json({'type': 'status', 'msg': 'Running C Binary...'})
+
+ process = subprocess.Popen(
+ [executable],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True,
+ bufsize=0,
+ encoding='utf-8'
+ )
+
+ # --- C++ HANDLING ---
+ elif language == 'cpp':
+ filename = "temp_code.cpp"
+ executable = "./a.out" if platform.system() != "Windows" else "a.exe"
+
+ with open(filename, "w", encoding="utf-8") as f:
+ f.write(code)
+
+ await ws.send_json({'type': 'status', 'msg': 'Compiling C++...'})
+
+ compile_process = subprocess.run(
+ ["g++", filename, "-o", executable],
+ capture_output=True,
+ text=True
+ )
+
+ if compile_process.returncode != 0:
+ await ws.send_json({'type': 'stdout', 'data': f"Compilation Error:\n{compile_process.stderr}"})
+ continue
+
+ await ws.send_json({'type': 'status', 'msg': 'Running C++ Binary...'})
+
+ process = subprocess.Popen(
+ [executable],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True,
+ bufsize=0,
+ encoding='utf-8'
+ )
+
+ if process:
+ loop = asyncio.get_running_loop()
+ thread = threading.Thread(target=read_stream, args=(process.stdout, loop))
+ thread.daemon = True
+ thread.start()
+
+ elif data.get('type') == 'input':
+ if process and process.poll() is None:
+ user_input = data.get('data')
+ try:
+ process.stdin.write(user_input)
+ process.stdin.flush()
+ except Exception:
+ pass
+
+ elif msg.type == web.WSMsgType.ERROR:
+ print(f'ws connection closed with exception {ws.exception()}')
+
+ finally:
+ if process: process.kill()
+ print("Client disconnected")
+
+ return ws
+
+async def main():
+ port = int(os.environ.get("PORT", 8765))
+ app = web.Application()
+ # Route root path to the unified handler (handles both HTTP checks and WS upgrades)
+ app.add_routes([web.get('/', handle_client)])
+
+ runner = web.AppRunner(app)
+ await runner.setup()
+ site = web.TCPSite(runner, '0.0.0.0', port)
+ print(f"AIOHTTP Server started on port {port}...")
+ await site.start()
+
+ # Keep the server running
+ await asyncio.Event().wait()
+
+if __name__ == "__main__":
+ asyncio.run(main())+
\ No newline at end of file
diff --git a/firebase.json b/firebase.json
@@ -0,0 +1,11 @@
+{
+ "hosting": {
+ "public": "public",
+ "ignore": [
+ "firebase.json",
+ "**/.*",
+ "**/node_modules/**"
+ ],
+ "cleanUrls": true
+ }
+}
diff --git a/public/404.html b/public/404.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css'>
+<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Arvo'>
+ <!-- The font was updated to 'Inter' as requested. -->
+<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
+</head>
+
+<style>
+ body{
+ margin:0;
+ padding:0;
+ font-family: 'Inter', sans-serif;
+ height:100vh;
+background-image: linear-gradient(to top, #2e1753, #1f1746, #131537, #0d1028, #050819);
+ display:flex;
+ justify-content:center;
+ align-items:center;
+ overflow:hidden;
+}
+.text{
+ position:absolute;
+ top:10%;
+ color:#fff;
+ text-align:center;
+}
+h1{
+ font-size:50px;
+}
+.star{
+ position:absolute;
+ width:2px;
+ height:2px;
+ background:#fff;
+ right:0;
+ animation:starTwinkle 3s infinite linear;
+}
+.astronaut img{
+ width:100px;
+ position:absolute;
+ top:55%;
+ animation:astronautFly 6s infinite linear;
+}
+@keyframes astronautFly{
+ 0%{
+ left:-100px;
+ }
+ 25%{
+ top:50%;
+ transform:rotate(30deg);
+ }
+ 50%{
+ transform:rotate(45deg);
+ top:55%;
+ }
+ 75%{
+ top:60%;
+ transform:rotate(30deg);
+ }
+ 100%{
+ left:110%;
+ transform:rotate(45deg);
+ }
+}
+@keyframes starTwinkle{
+ 0%{
+ background:rgba(255,255,255,0.4);
+ }
+ 25%{
+ background:rgba(255,255,255,0.8);
+ }
+ 50%{
+ background:rgba(255,255,255,1);
+ }
+ 75%{
+ background:rgba(255,255,255,0.8);
+ }
+ 100%{
+ background:rgba(255,255,255,0.4);
+ }
+}
+
+
+
+@media (max-width: 768px) {
+ .four_zero_four_bg {
+ height: 200px;
+ }
+ .four_zero_four_bg h1 {
+ font-size: 40px;
+ }
+ .four_zero_four_bg h3 {
+ font-size: 40px;
+ }
+ .button a {
+ font-size: 16px;
+ padding: 15px 30px;
+ }
+}
+</style>
+
+<body>
+
+ <div class="text">
+ <div>ERROR</div>
+ <h1>404</h1>
+ <hr>
+ <div>Page Not Found</div><br>
+ <div><a href="https://compiler.aranag.site" style="color: #fff; text-decoration: none;"><u>Go to Homepage</u></a></div>
+</div>
+
+<div class="astronaut">
+ <img src="https://images.vexels.com/media/users/3/152639/isolated/preview/506b575739e90613428cdb399175e2c8-space-astronaut-cartoon-by-vexels.png" alt="" class="src">
+</div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
+</body>
+<script>
+ document.addEventListener("DOMContentLoaded",function(){
+
+ var body=document.body;
+ setInterval(createStar,100);
+ function createStar(){
+ var right=Math.random()*500;
+ var top=Math.random()*screen.height;
+ var star=document.createElement("div");
+ star.classList.add("star")
+ body.appendChild(star);
+ setInterval(runStar,10);
+ star.style.top=top+"px";
+ function runStar(){
+ if(right>=screen.width){
+ star.remove();
+ }
+ right+=3;
+ star.style.right=right+"px";
+ }
+ }
+})
+</script>
+</html>
diff --git a/public/c.html b/public/c.html
@@ -0,0 +1,528 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <title>Amit Dutta // C Compiler</title>
+ <link rel="icon" type="image/x-icon" href="https://compiler.aranag.site/logo.png">
+
+ <!-- Fonts & Icons -->
+ <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=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500&family=JetBrains+Mono:wght@400&display=swap" rel="stylesheet">
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
+
+ <!-- Tailwind CSS -->
+ <script src="https://cdn.tailwindcss.com"></script>
+
+ <!-- Xterm.js -->
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css" />
+ <script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
+
+ <style>
+ :root {
+ --bg-main: #050505;
+ --accent: #bef264; /* Lime 300 */
+ --text-muted: #737373;
+ --border-color: rgba(255, 255, 255, 0.1);
+ }
+
+ body {
+ font-family: 'Inter', sans-serif;
+ background-color: var(--bg-main);
+ color: #f5f5f5;
+ height: 100vh;
+ height: 100dvh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ }
+
+ /* Portfolio Aesthetic */
+ .font-mono { font-family: 'JetBrains Mono', monospace; }
+ .font-heading { font-family: 'Space Grotesk', sans-serif; }
+
+ /* Noise Overlay */
+ .bg-noise {
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%;
+ pointer-events: none; z-index: 0; opacity: 0.03;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
+ }
+
+ /* CRT Scanline */
+ .crt-scanline {
+ position: fixed; top: 0; left: 0; width: 100%; height: 2px;
+ background: rgba(190, 242, 100, 0.1); opacity: 0.5;
+ pointer-events: none; z-index: 50;
+ animation: scanline 8s linear infinite;
+ }
+ @keyframes scanline { 0% { top: -10vh; } 100% { top: 110vh; } }
+
+ /* Custom Editor Styles */
+ .editor-container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ font-family: 'JetBrains Mono', monospace;
+ font-size: 13px;
+ line-height: 1.5;
+ }
+
+ /* The actual textarea for typing */
+ #code-input {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ padding: 1rem;
+ border: none;
+ outline: none;
+ background: transparent;
+ color: #e2e8f0; /* Visible Text */
+ caret-color: #fff; /* Cursor visible */
+ z-index: 1;
+ resize: none;
+ white-space: pre;
+ overflow: auto;
+ }
+
+ .xterm-viewport { overflow-y: auto !important; }
+
+ ::selection { background: var(--accent); color: black; }
+
+ .custom-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; }
+ .custom-scrollbar::-webkit-scrollbar-track { background: #050505; }
+ .custom-scrollbar::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }
+
+ /* Toast Notification */
+ .toast {
+ position: fixed;
+ bottom: 2rem;
+ left: 50%;
+ transform: translateX(-50%) translateY(100px);
+ background: #1a1a1a;
+ border: 1px solid var(--accent);
+ color: var(--accent);
+ padding: 0.5rem 1.5rem;
+ border-radius: 9999px;
+ font-family: 'JetBrains Mono', monospace;
+ font-size: 0.8rem;
+ transition: transform 0.3s ease;
+ z-index: 100;
+ }
+ .toast.show { transform: translateX(-50%) translateY(0); }
+
+ /* Connection Dot Pulse */
+ .pulse-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ display: inline-block;
+ box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7);
+ animation: pulse-white 2s infinite;
+ }
+ .pulse-dot.connected {
+ background-color: #bef264; /* Lime */
+ box-shadow: 0 0 0 0 rgba(190, 242, 100, 0.7);
+ animation: pulse-lime 2s infinite;
+ }
+ .pulse-dot.disconnected {
+ background-color: #ef4444; /* Red */
+ box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
+ animation: pulse-red 2s infinite;
+ }
+
+ @keyframes pulse-lime {
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(190, 242, 100, 0.7); }
+ 70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(190, 242, 100, 0); }
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(190, 242, 100, 0); }
+ }
+ @keyframes pulse-red {
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
+ 70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
+ }
+ </style>
+</head>
+<body class="antialiased selection:bg-lime-300 selection:text-black">
+
+ <div class="bg-noise"></div>
+ <div class="crt-scanline"></div>
+ <div id="toast" class="toast">Link Copied to Clipboard!</div>
+
+ <!-- Header (Responsive) -->
+ <header class="h-auto md:h-16 flex flex-col md:flex-row items-center justify-between px-4 py-3 md:px-6 shrink-0 border-b border-white/10 z-20 bg-neutral-900/50 backdrop-blur-md gap-3 md:gap-4">
+
+ <!-- Top Row: Title & Status -->
+ <div class="flex items-center justify-between w-full md:w-auto">
+ <h1 class="text-lg md:text-xl font-heading font-bold text-white tracking-tight flex items-center">
+ <span class="text-lime-300 mr-2">//</span>C.COMPILER
+ <span id="conn-dot" class="pulse-dot disconnected ml-3" title="Disconnected"></span>
+ </h1>
+
+ <!-- Mobile Only: Exit Link -->
+ <a href="./index.html" class="md:hidden font-mono text-[10px] text-neutral-500 hover:text-white uppercase tracking-wider transition-colors">[ EXIT ]</a>
+ </div>
+
+ <!-- Middle: Connection Text -->
+ <div class="hidden md:flex items-center gap-2 font-mono text-xs text-neutral-500">
+ <span id="connection-status">Connecting to server...</span>
+ </div>
+
+ <!-- Bottom/Right: Buttons -->
+ <div class="flex items-center gap-2 w-full md:w-auto justify-end">
+ <a href="./index.html" class="hidden md:inline font-mono text-[10px] text-neutral-500 hover:text-white uppercase tracking-wider transition-colors mr-2">[ EXIT ]</a>
+
+ <button id="reset-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Reset Terminal">
+ <i class="fas fa-rotate-left"></i>
+ </button>
+
+ <button id="share-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Share Code">
+ <i class="fas fa-share-alt"></i>
+ </button>
+
+ <button id="copy-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Copy Output">
+ <i class="fas fa-copy"></i>
+ </button>
+
+ <button id="run-btn" disabled class="bg-white/5 hover:bg-lime-300 hover:text-black disabled:opacity-50 disabled:cursor-not-allowed text-white border border-white/10 px-4 py-2 rounded font-mono text-xs font-bold uppercase tracking-wider flex items-center gap-2 transition-all flex-1 md:flex-none justify-center shadow-lg shadow-black/50">
+ <i class="fas fa-play text-[10px]"></i> <span class="md:hidden lg:inline">EXECUTE</span><span class="hidden md:inline lg:hidden">RUN</span>
+ </button>
+ </div>
+ </header>
+
+ <!-- Main Workspace -->
+ <div class="flex-1 flex flex-col md:flex-row min-h-0 z-10 relative">
+
+ <!-- Code Editor -->
+ <div class="flex-1 flex flex-col h-[60%] md:h-auto min-h-0 border-b md:border-b-0 md:border-r border-white/10 relative group">
+ <div class="bg-black/20 px-4 py-2 text-[10px] font-mono text-lime-300 uppercase border-b border-white/10 flex justify-between items-center shrink-0">
+ <span>SRC // main.c</span>
+ <span class="text-neutral-600">GCC 11.2</span>
+ </div>
+
+ <!-- Custom Editor Area -->
+ <div class="editor-container relative bg-[#0c0f16]">
+ <textarea id="code-input" spellcheck="false" autocapitalize="off" autocomplete="off" autocorrect="off" class="custom-scrollbar">#include <stdio.h>
+
+int main() {
+ int n, i;
+ printf("Enter count: ");
+ // Manual flush required for buffered environments
+ fflush(stdout);
+
+ if (scanf("%d", &n)) {
+ printf("Counting to %d:\n", n);
+ for(i=1; i<=n; i++) {
+ printf("%d ", i);
+ }
+ printf("\nDone.");
+ }
+ return 0;
+}</textarea>
+ </div>
+
+ <!-- AI Fix Button -->
+ <button id="ai-fix-btn" class="hidden absolute bottom-4 right-4 bg-red-500/10 border border-red-500/50 text-red-400 hover:bg-red-500 hover:text-white px-3 py-1.5 rounded-lg text-xs font-mono transition-all items-center gap-2 backdrop-blur-md z-20">
+ <i class="fas fa-magic"></i> Fix with AI
+ </button>
+ </div>
+
+ <!-- Terminal -->
+ <div class="flex-1 flex flex-col h-[40%] md:h-auto min-h-0 bg-[#050505]">
+ <div class="bg-black/20 px-4 py-2 text-[10px] font-mono text-lime-300 uppercase border-b border-white/10 flex justify-between items-center shrink-0">
+ <span>OUT // TERMINAL</span>
+ <span class="text-neutral-600">XTERM.JS</span>
+ </div>
+ <div class="flex-1 relative">
+ <div id="terminal-container" class="absolute inset-0 w-full h-full p-2 overflow-hidden"></div>
+ </div>
+ </div>
+ </div>
+
+ <script>
+ // --- DOM Elements ---
+ const runBtn = document.getElementById('run-btn');
+ const resetBtn = document.getElementById('reset-btn');
+ const shareBtn = document.getElementById('share-btn');
+ const copyBtn = document.getElementById('copy-btn');
+ const aiFixBtn = document.getElementById('ai-fix-btn');
+ const connDot = document.getElementById('conn-dot');
+ const connectionStatus = document.getElementById('connection-status');
+ const codeInput = document.getElementById('code-input');
+ const toast = document.getElementById('toast');
+
+ // --- State ---
+ let socket = null;
+ let currentLine = "";
+ let startTime = 0;
+
+ // --- EDITOR LOGIC ---
+ codeInput.addEventListener('keydown', function(e) {
+ if (e.key === 'Tab') {
+ e.preventDefault();
+ const start = this.selectionStart;
+ const end = this.selectionEnd;
+ this.setRangeText(' ', start, end, 'end');
+ } else if (e.key === 'Enter') {
+ e.preventDefault();
+ const start = this.selectionStart;
+ const end = this.selectionEnd;
+ const value = this.value;
+ const lineStart = value.lastIndexOf('\n', start - 1) + 1;
+ const currentLineText = value.substring(lineStart, start);
+ let match = currentLineText.match(/^(\s*)/);
+ let indent = match ? match[1] : "";
+ if (currentLineText.trim().endsWith('{')) indent += " ";
+ this.setRangeText('\n' + indent, start, end, 'end');
+ this.blur(); this.focus();
+ } else if (e.key === '}') {
+ const start = this.selectionStart;
+ const end = this.selectionEnd;
+ const value = this.value;
+ const lineStart = value.lastIndexOf('\n', start - 1) + 1;
+ const currentLineText = value.substring(lineStart, start);
+ if (/^\s+$/.test(currentLineText) && currentLineText.length >= 4) {
+ const newIndent = currentLineText.substring(0, currentLineText.length - 4);
+ this.setSelectionRange(lineStart, start);
+ this.setRangeText(newIndent, this.selectionStart, this.selectionEnd, 'end');
+ }
+ }
+ });
+
+ window.addEventListener('load', () => {
+ const params = new URLSearchParams(window.location.search);
+ const sharedCode = params.get('code');
+ if (sharedCode) {
+ try { codeInput.value = atob(sharedCode); }
+ catch(e) {}
+ }
+ setTimeout(connect, 500);
+ });
+
+ // --- Terminal Setup ---
+ const term = new Terminal({
+ theme: {
+ background: '#050505',
+ foreground: '#f5f5f5',
+ cursor: '#bef264',
+ selectionBackground: 'rgba(190, 242, 100, 0.3)',
+ black: '#050505',
+ green: '#bef264',
+ yellow: '#facc15',
+ red: '#ef4444',
+ },
+ fontFamily: "'JetBrains Mono', monospace",
+ fontSize: 12,
+ cursorBlink: true,
+ convertEol: true
+ });
+ const fitAddon = new FitAddon.FitAddon();
+ term.loadAddon(fitAddon);
+ term.open(document.getElementById('terminal-container'));
+ fitAddon.fit();
+ window.addEventListener('resize', () => fitAddon.fit());
+
+ // Custom Key Handler for Ctrl+C Copy
+ term.attachCustomKeyEventHandler((arg) => {
+ if (arg.ctrlKey && arg.code === "KeyC" && arg.type === "keydown") {
+ const selection = term.getSelection();
+ if (selection) {
+ fallbackCopyTextToClipboard(selection);
+ return false;
+ }
+ }
+ return true;
+ });
+
+ term.write('\x1b[38;2;115;115;115m> SYSTEM READY.\r\n> ATTEMPTING CONNECTION...\x1b[0m\r\n');
+
+ // --- WebSocket Logic ---
+ function connect() {
+ const url = "wss://compiler-z4x4.onrender.com";
+ try { socket = new WebSocket(url); } catch (e) {
+ term.write(`\r\n\x1b[31m> INVALID URL.\x1b[0m\r\n`);
+ return;
+ }
+
+ socket.onopen = () => {
+ connDot.className = "pulse-dot connected ml-3";
+ if(connectionStatus) connectionStatus.textContent = "Connected to Server";
+ if(connectionStatus) connectionStatus.className = "hidden md:flex items-center gap-2 font-mono text-xs text-lime-300";
+
+ term.write(`\x1b[38;2;190;242;100m> CONNECTION ESTABLISHED.\x1b[0m\r\n> ./a.out\r\n`);
+ runBtn.disabled = false;
+ };
+
+ socket.onclose = () => {
+ connDot.className = "pulse-dot disconnected ml-3";
+ if(connectionStatus) connectionStatus.textContent = "Disconnected";
+ if(connectionStatus) connectionStatus.className = "hidden md:flex items-center gap-2 font-mono text-xs text-red-500";
+
+ term.write(`\r\n\x1b[31m> CONNECTION LOST. RECONNECTING...\x1b[0m\r\n`);
+ runBtn.disabled = true;
+ setTimeout(connect, 3000);
+ socket = null;
+ };
+
+ socket.onmessage = (event) => {
+ const msg = JSON.parse(event.data);
+ if (msg.type === 'stdout') {
+ let text = msg.data;
+
+ if (text.toLowerCase().includes("error:") || text.toLowerCase().includes("warning:")) {
+ aiFixBtn.classList.remove('hidden');
+ }
+
+ if (!text.includes('\r')) {
+ text = text.replace(/\n/g, '\r\n');
+ }
+ term.write(text);
+ } else if (msg.type === 'status') {
+ // Detect "Program finished" signal from backend
+ if (msg.msg.includes("Program finished")) {
+ const duration = (Date.now() - startTime) / 1000;
+ term.write(`\r\n\x1b[38;2;115;115;115m[Finished in ${duration.toFixed(3)}s]\x1b[0m\r\n`);
+ }
+ }
+ };
+ }
+
+ // --- Run Logic ---
+ runBtn.addEventListener('click', () => {
+ if (!socket || socket.readyState !== WebSocket.OPEN) return;
+
+ document.activeElement.blur();
+ term.reset();
+ currentLine = "";
+ aiFixBtn.classList.add('hidden');
+
+ let code = codeInput.value;
+ code = code.replace(/\u00A0/g, " ").replace(/[\u2018\u2019]/g, "'").replace(/[\u201C\u201D]/g, '"');
+
+ function injectAutoFlush(source) {
+ const mainRegex = /(int|void)\s+main\s*\([^)]*\)\s*\{/;
+ const match = source.match(mainRegex);
+ if (match) {
+ const insertionPoint = match.index + match[0].length;
+ return source.slice(0, insertionPoint) + "\n setbuf(stdout, NULL);" + source.slice(insertionPoint);
+ }
+ return source;
+ }
+ code = injectAutoFlush(code);
+
+ startTime = Date.now();
+ term.write('\x1b[32m> ./a.out\x1b[0m\r\n');
+
+ socket.send(JSON.stringify({
+ type: 'run',
+ code: code,
+ language: 'c'
+ }));
+
+ term.focus();
+ });
+
+ // --- Reset Logic ---
+ resetBtn.addEventListener('click', () => {
+ term.reset();
+ currentLine = "";
+ term.write(`\x1b[38;2;190;242;100m> CONNECTION ESTABLISHED.\x1b[0m\r\n> ./a.out\r\n`);
+ });
+
+ // --- Share Functionality with Native Share API ---
+ shareBtn.addEventListener('click', async () => {
+ const code = codeInput.value;
+ const encoded = btoa(code);
+ const url = new URL(window.location.href);
+ url.searchParams.set('code', encoded);
+ const shareUrl = url.toString();
+
+ // Try native sharing first (Mobile/Supported Browsers)
+ if (navigator.share) {
+ try {
+ await navigator.share({
+ title: document.title,
+ text: 'Check out my C code!',
+ url: shareUrl
+ });
+ } catch (err) {
+ // Ignore cancellation or errors, no fallback needed if cancelled
+ }
+ } else {
+ // Fallback to clipboard copy
+ fallbackCopyTextToClipboard(shareUrl);
+ }
+ });
+
+ function showToast(msg) {
+ toast.textContent = msg;
+ toast.classList.add('show');
+ setTimeout(() => toast.classList.remove('show'), 3000);
+ }
+
+ // --- Smart Copy Function ---
+ copyBtn.addEventListener('click', () => {
+ const buffer = term.buffer.active;
+ let text = "";
+ for (let i = 0; i < buffer.length; i++) {
+ const line = buffer.getLine(i);
+ if (line) {
+ let lineText = line.translateToString(true);
+ if(lineText.trim().startsWith("> [") || lineText.trim().startsWith("> ./a.out") || lineText.includes("SYSTEM READY") || lineText.includes("ATTEMPTING") || lineText.includes("CONNECTION")) {
+ continue;
+ }
+ text += lineText + "\n";
+ }
+ }
+ text = text.trim();
+ fallbackCopyTextToClipboard(text);
+ });
+
+ function fallbackCopyTextToClipboard(text) {
+ const textArea = document.createElement("textarea");
+ textArea.value = text;
+ textArea.style.position = "fixed";
+ textArea.style.top = "0";
+ textArea.style.left = "0";
+ textArea.style.opacity = "0";
+ document.body.appendChild(textArea);
+ textArea.focus();
+ textArea.select();
+ try {
+ document.execCommand('copy');
+ showToast("Copied to Clipboard!");
+ } catch (err) {
+ showToast("Copy Failed");
+ }
+ document.body.removeChild(textArea);
+ }
+
+ aiFixBtn.addEventListener('click', () => {
+ alert("AI Feature: Coming Soon via Backend Update");
+ });
+
+ // Terminal Input
+ term.onData((data) => {
+ if (!socket || socket.readyState !== WebSocket.OPEN) return;
+
+ if (data === '\r') {
+ term.write('\r\n');
+ socket.send(JSON.stringify({ type: 'input', data: currentLine + '\n' }));
+ currentLine = "";
+ } else if (data === '\x7f' || data === '\b') {
+ if (currentLine.length > 0) {
+ currentLine = currentLine.slice(0, -1);
+ term.write('\b \b');
+ }
+ } else {
+ currentLine += data;
+ term.write(data);
+ }
+ });
+ </script>
+</body>
+</html>+
\ No newline at end of file
diff --git a/public/cpp.html b/public/cpp.html
@@ -0,0 +1,526 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <title>Amit Dutta // C++ Compiler</title>
+ <link rel="icon" type="image/x-icon" href="https://compiler.aranag.site/logo.png">
+
+ <!-- Fonts & Icons -->
+ <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=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500&family=JetBrains+Mono:wght@400&display=swap" rel="stylesheet">
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
+
+ <!-- Tailwind CSS -->
+ <script src="https://cdn.tailwindcss.com"></script>
+
+ <!-- Xterm.js -->
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css" />
+ <script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
+
+ <style>
+ :root {
+ --bg-main: #050505;
+ --accent: #bef264; /* Lime 300 */
+ --text-muted: #737373;
+ --border-color: rgba(255, 255, 255, 0.1);
+ }
+
+ body {
+ font-family: 'Inter', sans-serif;
+ background-color: var(--bg-main);
+ color: #f5f5f5;
+ height: 100vh;
+ height: 100dvh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ }
+
+ /* Portfolio Aesthetic */
+ .font-mono { font-family: 'JetBrains Mono', monospace; }
+ .font-heading { font-family: 'Space Grotesk', sans-serif; }
+
+ /* Noise Overlay */
+ .bg-noise {
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%;
+ pointer-events: none; z-index: 0; opacity: 0.03;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
+ }
+
+ /* CRT Scanline */
+ .crt-scanline {
+ position: fixed; top: 0; left: 0; width: 100%; height: 2px;
+ background: rgba(190, 242, 100, 0.1); opacity: 0.5;
+ pointer-events: none; z-index: 50;
+ animation: scanline 8s linear infinite;
+ }
+ @keyframes scanline { 0% { top: -10vh; } 100% { top: 110vh; } }
+
+ /* Custom Editor Styles */
+ .editor-container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ font-family: 'JetBrains Mono', monospace;
+ font-size: 13px;
+ line-height: 1.5;
+ }
+
+ /* The actual textarea for typing */
+ #code-input {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ padding: 1rem;
+ border: none;
+ outline: none;
+ background: transparent;
+ color: #e2e8f0; /* Visible Text */
+ caret-color: #fff; /* Cursor visible */
+ z-index: 1;
+ resize: none;
+ white-space: pre;
+ overflow: auto;
+ }
+
+ .xterm-viewport { overflow-y: auto !important; }
+
+ ::selection { background: var(--accent); color: black; }
+
+ .custom-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; }
+ .custom-scrollbar::-webkit-scrollbar-track { background: #050505; }
+ .custom-scrollbar::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }
+
+ /* Toast Notification */
+ .toast {
+ position: fixed;
+ bottom: 2rem;
+ left: 50%;
+ transform: translateX(-50%) translateY(100px);
+ background: #1a1a1a;
+ border: 1px solid var(--accent);
+ color: var(--accent);
+ padding: 0.5rem 1.5rem;
+ border-radius: 9999px;
+ font-family: 'JetBrains Mono', monospace;
+ font-size: 0.8rem;
+ transition: transform 0.3s ease;
+ z-index: 100;
+ }
+ .toast.show { transform: translateX(-50%) translateY(0); }
+
+ /* Connection Dot Pulse */
+ .pulse-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ display: inline-block;
+ box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7);
+ animation: pulse-white 2s infinite;
+ }
+ .pulse-dot.connected {
+ background-color: #bef264; /* Lime */
+ box-shadow: 0 0 0 0 rgba(190, 242, 100, 0.7);
+ animation: pulse-lime 2s infinite;
+ }
+ .pulse-dot.disconnected {
+ background-color: #ef4444; /* Red */
+ box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
+ animation: pulse-red 2s infinite;
+ }
+
+ @keyframes pulse-lime {
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(190, 242, 100, 0.7); }
+ 70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(190, 242, 100, 0); }
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(190, 242, 100, 0); }
+ }
+ @keyframes pulse-red {
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
+ 70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
+ }
+ </style>
+</head>
+<body class="antialiased selection:bg-lime-300 selection:text-black">
+
+ <div class="bg-noise"></div>
+ <div class="crt-scanline"></div>
+ <div id="toast" class="toast">Link Copied to Clipboard!</div>
+
+ <!-- Header (Responsive) -->
+ <header class="h-auto md:h-16 flex flex-col md:flex-row items-center justify-between px-4 py-3 md:px-6 shrink-0 border-b border-white/10 z-20 bg-neutral-900/50 backdrop-blur-md gap-3 md:gap-4">
+
+ <!-- Top Row: Title & Status -->
+ <div class="flex items-center justify-between w-full md:w-auto">
+ <h1 class="text-lg md:text-xl font-heading font-bold text-white tracking-tight flex items-center">
+ <span class="text-lime-300 mr-2">//</span>CPP.COMPILER
+ <span id="conn-dot" class="pulse-dot disconnected ml-3" title="Disconnected"></span>
+ </h1>
+
+ <!-- Mobile Only: Exit Link -->
+ <a href="./index.html" class="md:hidden font-mono text-[10px] text-neutral-500 hover:text-white uppercase tracking-wider transition-colors">[ EXIT ]</a>
+ </div>
+
+ <!-- Middle: Connection Text -->
+ <div class="hidden md:flex items-center gap-2 font-mono text-xs text-neutral-500">
+ <span id="connection-status">Connecting to server...</span>
+ </div>
+
+ <!-- Bottom/Right: Buttons -->
+ <div class="flex items-center gap-2 w-full md:w-auto justify-end">
+ <a href="./index.html" class="hidden md:inline font-mono text-[10px] text-neutral-500 hover:text-white uppercase tracking-wider transition-colors mr-2">[ EXIT ]</a>
+
+ <button id="reset-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Reset Terminal">
+ <i class="fas fa-rotate-left"></i>
+ </button>
+
+ <button id="share-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Share Code">
+ <i class="fas fa-share-alt"></i>
+ </button>
+
+ <button id="copy-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Copy Output">
+ <i class="fas fa-copy"></i>
+ </button>
+
+ <button id="run-btn" disabled class="bg-white/5 hover:bg-lime-300 hover:text-black disabled:opacity-50 disabled:cursor-not-allowed text-white border border-white/10 px-4 py-2 rounded font-mono text-xs font-bold uppercase tracking-wider flex items-center gap-2 transition-all flex-1 md:flex-none justify-center shadow-lg shadow-black/50">
+ <i class="fas fa-play text-[10px]"></i> <span class="md:hidden lg:inline">EXECUTE</span><span class="hidden md:inline lg:hidden">RUN</span>
+ </button>
+ </div>
+ </header>
+
+ <!-- Main Workspace -->
+ <div class="flex-1 flex flex-col md:flex-row min-h-0 z-10 relative">
+
+ <!-- Code Editor -->
+ <div class="flex-1 flex flex-col h-[60%] md:h-auto min-h-0 border-b md:border-b-0 md:border-r border-white/10 relative group">
+ <div class="bg-black/20 px-4 py-2 text-[10px] font-mono text-lime-300 uppercase border-b border-white/10 flex justify-between items-center shrink-0">
+ <span>SRC // main.cpp</span>
+ <span class="text-neutral-600">G++ 11.2</span>
+ </div>
+
+ <!-- Custom Editor Area -->
+ <div class="editor-container relative bg-[#0c0f16]">
+ <textarea id="code-input" spellcheck="false" autocapitalize="off" autocomplete="off" autocorrect="off" class="custom-scrollbar">#include <iostream>
+#include <string>
+
+int main() {
+ std::string name;
+
+ std::cout << "Enter your name: ";
+ // Force flush ensures prompt appears immediately in buffered environments
+ std::cout.flush();
+
+ std::cin >> name;
+ std::cout << "Hello, " << name << "!" << std::endl;
+
+ return 0;
+}</textarea>
+ </div>
+
+ <!-- AI Fix Button -->
+ <button id="ai-fix-btn" class="hidden absolute bottom-4 right-4 bg-red-500/10 border border-red-500/50 text-red-400 hover:bg-red-500 hover:text-white px-3 py-1.5 rounded-lg text-xs font-mono transition-all items-center gap-2 backdrop-blur-md z-20">
+ <i class="fas fa-magic"></i> Fix with AI
+ </button>
+ </div>
+
+ <!-- Terminal -->
+ <div class="flex-1 flex flex-col h-[40%] md:h-auto min-h-0 bg-[#050505]">
+ <div class="bg-black/20 px-4 py-2 text-[10px] font-mono text-lime-300 uppercase border-b border-white/10 flex justify-between items-center shrink-0">
+ <span>OUT // TERMINAL</span>
+ <span class="text-neutral-600">XTERM.JS</span>
+ </div>
+ <div class="flex-1 relative">
+ <div id="terminal-container" class="absolute inset-0 w-full h-full p-2 overflow-hidden"></div>
+ </div>
+ </div>
+ </div>
+
+ <script>
+ // --- DOM Elements ---
+ const runBtn = document.getElementById('run-btn');
+ const resetBtn = document.getElementById('reset-btn');
+ const shareBtn = document.getElementById('share-btn');
+ const copyBtn = document.getElementById('copy-btn');
+ const aiFixBtn = document.getElementById('ai-fix-btn');
+ const connDot = document.getElementById('conn-dot');
+ const connectionStatus = document.getElementById('connection-status');
+ const codeInput = document.getElementById('code-input');
+ const toast = document.getElementById('toast');
+
+ // --- State ---
+ let socket = null;
+ let currentLine = "";
+ let startTime = 0;
+
+ // --- EDITOR LOGIC (Indentation) ---
+ codeInput.addEventListener('keydown', function(e) {
+ if (e.key === 'Tab') {
+ e.preventDefault();
+ const start = this.selectionStart;
+ const end = this.selectionEnd;
+ this.setRangeText(' ', start, end, 'end');
+ } else if (e.key === 'Enter') {
+ e.preventDefault();
+ const start = this.selectionStart;
+ const end = this.selectionEnd;
+ const value = this.value;
+ const lineStart = value.lastIndexOf('\n', start - 1) + 1;
+ const currentLineText = value.substring(lineStart, start);
+ let match = currentLineText.match(/^(\s*)/);
+ let indent = match ? match[1] : "";
+ if (currentLineText.trim().endsWith('{')) indent += " ";
+ this.setRangeText('\n' + indent, start, end, 'end');
+ this.blur(); this.focus();
+ } else if (e.key === '}') {
+ const start = this.selectionStart;
+ const end = this.selectionEnd;
+ const value = this.value;
+ const lineStart = value.lastIndexOf('\n', start - 1) + 1;
+ const currentLineText = value.substring(lineStart, start);
+ if (/^\s+$/.test(currentLineText) && currentLineText.length >= 4) {
+ const newIndent = currentLineText.substring(0, currentLineText.length - 4);
+ this.setSelectionRange(lineStart, start);
+ this.setRangeText(newIndent, this.selectionStart, this.selectionEnd, 'end');
+ }
+ }
+ });
+
+ window.addEventListener('load', () => {
+ const params = new URLSearchParams(window.location.search);
+ const sharedCode = params.get('code');
+ if (sharedCode) {
+ try { codeInput.value = atob(sharedCode); }
+ catch(e) {}
+ }
+ setTimeout(connect, 500);
+ });
+
+ // --- Terminal Setup ---
+ const term = new Terminal({
+ theme: {
+ background: '#050505',
+ foreground: '#f5f5f5',
+ cursor: '#bef264',
+ selectionBackground: 'rgba(190, 242, 100, 0.3)',
+ black: '#050505',
+ green: '#bef264',
+ yellow: '#facc15',
+ red: '#ef4444',
+ },
+ fontFamily: "'JetBrains Mono', monospace",
+ fontSize: 12,
+ cursorBlink: true,
+ convertEol: true
+ });
+ const fitAddon = new FitAddon.FitAddon();
+ term.loadAddon(fitAddon);
+ term.open(document.getElementById('terminal-container'));
+ fitAddon.fit();
+ window.addEventListener('resize', () => fitAddon.fit());
+
+ // Custom Key Handler for Ctrl+C Copy
+ term.attachCustomKeyEventHandler((arg) => {
+ if (arg.ctrlKey && arg.code === "KeyC" && arg.type === "keydown") {
+ const selection = term.getSelection();
+ if (selection) {
+ fallbackCopyTextToClipboard(selection);
+ return false;
+ }
+ }
+ return true;
+ });
+
+ term.write('\x1b[38;2;115;115;115m> SYSTEM READY.\r\n> ATTEMPTING CONNECTION...\x1b[0m\r\n');
+
+ // --- WebSocket Logic ---
+ function connect() {
+ const url = "wss://compiler-z4x4.onrender.com";
+ try { socket = new WebSocket(url); } catch (e) {
+ term.write(`\r\n\x1b[31m> INVALID URL.\x1b[0m\r\n`);
+ return;
+ }
+
+ socket.onopen = () => {
+ connDot.className = "pulse-dot connected ml-3";
+ if(connectionStatus) connectionStatus.textContent = "Connected to Server";
+ if(connectionStatus) connectionStatus.className = "hidden md:flex items-center gap-2 font-mono text-xs text-lime-300";
+
+ term.write(`\x1b[38;2;190;242;100m> CONNECTION ESTABLISHED.\x1b[0m\r\n> ./a.out\r\n`);
+ runBtn.disabled = false;
+ };
+
+ socket.onclose = () => {
+ connDot.className = "pulse-dot disconnected ml-3";
+ if(connectionStatus) connectionStatus.textContent = "Disconnected";
+ if(connectionStatus) connectionStatus.className = "hidden md:flex items-center gap-2 font-mono text-xs text-red-500";
+
+ term.write(`\r\n\x1b[31m> CONNECTION LOST. RECONNECTING...\x1b[0m\r\n`);
+ runBtn.disabled = true;
+ setTimeout(connect, 3000);
+ socket = null;
+ };
+
+ socket.onmessage = (event) => {
+ const msg = JSON.parse(event.data);
+ if (msg.type === 'stdout') {
+ let text = msg.data;
+
+ if (text.toLowerCase().includes("error:") || text.toLowerCase().includes("warning:")) {
+ aiFixBtn.classList.remove('hidden');
+ }
+
+ if (!text.includes('\r')) {
+ text = text.replace(/\n/g, '\r\n');
+ }
+ term.write(text);
+ } else if (msg.type === 'status') {
+ if (msg.msg.includes("Program finished")) {
+ const duration = (Date.now() - startTime) / 1000;
+ term.write(`\r\n\x1b[38;2;115;115;115m[Finished in ${duration.toFixed(3)}s]\x1b[0m\r\n`);
+ }
+ }
+ };
+ }
+
+ // --- Run Logic ---
+ runBtn.addEventListener('click', () => {
+ if (!socket || socket.readyState !== WebSocket.OPEN) return;
+
+ document.activeElement.blur();
+ term.reset();
+ currentLine = "";
+ aiFixBtn.classList.add('hidden');
+
+ let code = codeInput.value;
+ code = code.replace(/\u00A0/g, " ").replace(/[\u2018\u2019]/g, "'").replace(/[\u201C\u201D]/g, '"');
+
+ // Auto-inject std::cout.setf(std::ios::unitbuf); for C++
+ function injectAutoFlush(source) {
+ const mainRegex = /(int|void)\s+main\s*\([^)]*\)\s*\{/;
+ const match = source.match(mainRegex);
+ if (match) {
+ const insertionPoint = match.index + match[0].length;
+ return source.slice(0, insertionPoint) + "\n std::cout.setf(std::ios::unitbuf); // Auto-injected" + source.slice(insertionPoint);
+ }
+ return source;
+ }
+ code = injectAutoFlush(code);
+
+ startTime = Date.now();
+ term.write('\x1b[32m> ./a.out\x1b[0m\r\n');
+
+ socket.send(JSON.stringify({
+ type: 'run',
+ code: code,
+ language: 'cpp'
+ }));
+
+ term.focus();
+ });
+
+ // --- Reset Logic ---
+ resetBtn.addEventListener('click', () => {
+ term.reset();
+ currentLine = "";
+ term.write(`\x1b[38;2;190;242;100m> CONNECTION ESTABLISHED.\x1b[0m\r\n> ./a.out\r\n`);
+ });
+
+ // --- Share Functionality with Native Share API ---
+ shareBtn.addEventListener('click', async () => {
+ const code = codeInput.value;
+ const encoded = btoa(code);
+ const url = new URL(window.location.href);
+ url.searchParams.set('code', encoded);
+ const shareUrl = url.toString();
+
+ // Try native sharing first (Mobile/Supported Browsers)
+ if (navigator.share) {
+ try {
+ await navigator.share({
+ title: document.title,
+ text: 'Check out my C++ code!',
+ url: shareUrl
+ });
+ } catch (err) {
+ // Ignore cancellation or errors
+ }
+ } else {
+ // Fallback to clipboard copy
+ fallbackCopyTextToClipboard(shareUrl);
+ }
+ });
+
+ function showToast(msg) {
+ toast.textContent = msg;
+ toast.classList.add('show');
+ setTimeout(() => toast.classList.remove('show'), 3000);
+ }
+
+ // --- Smart Copy Function ---
+ copyBtn.addEventListener('click', () => {
+ const buffer = term.buffer.active;
+ let text = "";
+ for (let i = 0; i < buffer.length; i++) {
+ const line = buffer.getLine(i);
+ if (line) {
+ let lineText = line.translateToString(true);
+ if(lineText.trim().startsWith("> [") || lineText.trim().startsWith("> ./a.out") || lineText.includes("SYSTEM READY") || lineText.includes("ATTEMPTING") || lineText.includes("CONNECTION")) {
+ continue;
+ }
+ text += lineText + "\n";
+ }
+ }
+ text = text.trim();
+ fallbackCopyTextToClipboard(text);
+ });
+
+ function fallbackCopyTextToClipboard(text) {
+ const textArea = document.createElement("textarea");
+ textArea.value = text;
+ textArea.style.position = "fixed";
+ textArea.style.top = "0";
+ textArea.style.left = "0";
+ textArea.style.opacity = "0";
+ document.body.appendChild(textArea);
+ textArea.focus();
+ textArea.select();
+ try {
+ document.execCommand('copy');
+ showToast("Copied to Clipboard!");
+ } catch (err) {
+ showToast("Copy Failed");
+ }
+ document.body.removeChild(textArea);
+ }
+
+ aiFixBtn.addEventListener('click', () => {
+ showToast("AI Feature: Coming Soon via Backend Update");
+ });
+
+ // Terminal Input
+ term.onData((data) => {
+ if (!socket || socket.readyState !== WebSocket.OPEN) return;
+
+ if (data === '\r') {
+ term.write('\r\n');
+ socket.send(JSON.stringify({ type: 'input', data: currentLine + '\n' }));
+ currentLine = "";
+ } else if (data === '\x7f' || data === '\b') {
+ if (currentLine.length > 0) {
+ currentLine = currentLine.slice(0, -1);
+ term.write('\b \b');
+ }
+ } else {
+ currentLine += data;
+ term.write(data);
+ }
+ });
+ </script>
+</body>
+</html>+
\ No newline at end of file
diff --git a/public/docs.html b/public/docs.html
@@ -0,0 +1,347 @@
+<!DOCTYPE html>
+<html lang="en" class="scroll-smooth">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Documentation // Cloud Code Compiler</title>
+ <link rel="icon" type="image/x-icon" href="https://compiler.amit.is-a.dev/logo.png">
+
+ <!-- Fonts -->
+ <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=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500&family=JetBrains+Mono:wght@400&display=swap" rel="stylesheet">
+
+ <!-- Libraries -->
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
+ <script src="https://cdn.tailwindcss.com"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
+
+ <style>
+ :root {
+ --bg-main: #050505;
+ --accent: #bef264; /* Lime 300 */
+ --text-muted: #737373;
+ --border-color: rgba(255, 255, 255, 0.1);
+ }
+
+ body {
+ font-family: 'Inter', sans-serif;
+ background-color: var(--bg-main);
+ color: #f5f5f5;
+ line-height: 1.6;
+ }
+
+ .font-mono { font-family: 'JetBrains Mono', monospace; }
+ .font-heading { font-family: 'Space Grotesk', sans-serif; }
+
+ /* Custom Scrollbar */
+ ::-webkit-scrollbar { width: 8px; }
+ ::-webkit-scrollbar-track { background: #050505; }
+ ::-webkit-scrollbar-thumb { background: #333; border-radius: 4px; }
+ ::-webkit-scrollbar-thumb:hover { background: #555; }
+
+ /* Doc Sections */
+ .doc-section {
+ margin-bottom: 4rem;
+ scroll-margin-top: 6rem;
+ }
+
+ .code-block {
+ background: #0f1115;
+ border: 1px solid var(--border-color);
+ border-radius: 0.75rem;
+ padding: 1rem;
+ margin: 1.5rem 0;
+ font-size: 0.9rem;
+ }
+
+ .nav-link {
+ display: block;
+ padding: 0.5rem 1rem;
+ color: var(--text-muted);
+ border-left: 2px solid transparent;
+ transition: all 0.2s;
+ }
+ .nav-link:hover, .nav-link.active {
+ color: var(--accent);
+ border-left-color: var(--accent);
+ background: rgba(190, 242, 100, 0.05);
+ }
+
+ /* Noise Overlay */
+ .bg-noise {
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%;
+ pointer-events: none; z-index: 0; opacity: 0.03;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
+ }
+ </style>
+</head>
+<body class="antialiased selection:bg-lime-300 selection:text-black">
+
+ <div class="bg-noise"></div>
+
+ <!-- Layout Grid -->
+ <div class="max-w-7xl mx-auto px-6 py-12 grid grid-cols-1 lg:grid-cols-4 gap-12 relative z-10">
+
+ <!-- Sidebar Navigation -->
+ <aside class="hidden lg:block col-span-1 sticky top-12 h-[calc(100vh-6rem)] overflow-y-auto pr-4">
+ <div class="mb-8">
+ <a href="./index.html" class="flex items-center gap-2 group">
+ <i class="fas fa-arrow-left text-neutral-500 group-hover:text-white transition-colors"></i>
+ <span class="font-heading font-bold text-xl text-white">Back to Home</span>
+ </a>
+ </div>
+
+ <nav class="space-y-1">
+ <p class="px-4 text-xs font-mono text-neutral-500 uppercase tracking-widest mb-2">Contents</p>
+ <a href="#architecture" class="nav-link font-mono text-sm">Architecture</a>
+ <a href="#communication" class="nav-link font-mono text-sm">WebSocket Protocol</a>
+ <a href="#python-engine" class="nav-link font-mono text-sm">Python Engine</a>
+ <a href="#cpp-engine" class="nav-link font-mono text-sm">C / C++ Engine</a>
+ <a href="#security" class="nav-link font-mono text-sm">Security & Sandbox</a>
+ <a href="#privacy" class="nav-link font-mono text-sm">Privacy & Data</a>
+ <a href="#disclaimer" class="nav-link font-mono text-sm">Legal & Disclaimer</a>
+ </nav>
+
+ <div class="mt-12 p-4 rounded-xl bg-white/5 border border-white/10">
+ <p class="text-xs text-neutral-400 mb-2">Powered by</p>
+ <div class="flex flex-wrap gap-2">
+ <span class="text-xs px-2 py-1 rounded bg-black border border-white/10 text-lime-300 font-mono">aiohttp</span>
+ <span class="text-xs px-2 py-1 rounded bg-black border border-white/10 text-lime-300 font-mono">Python 3.10</span>
+ <span class="text-xs px-2 py-1 rounded bg-black border border-white/10 text-lime-300 font-mono">GCC 11</span>
+ </div>
+ </div>
+ </aside>
+
+ <!-- Main Content -->
+ <main class="col-span-1 lg:col-span-3">
+
+ <!-- Mobile Header -->
+ <div class="lg:hidden mb-12">
+ <a href="./index.html" class="flex items-center gap-2 text-neutral-400 hover:text-white mb-6">
+ <i class="fas fa-arrow-left"></i> Return Home
+ </a>
+ <h1 class="text-4xl font-heading font-bold text-white">System Documentation</h1>
+ </div>
+
+ <!-- Intro -->
+ <div class="mb-16 border-b border-white/10 pb-12">
+ <h1 class="hidden lg:block text-5xl font-heading font-bold text-white mb-6">System Documentation</h1>
+ <p class="text-xl text-neutral-400 leading-relaxed max-w-3xl">
+ A technical deep-dive into the Cloud Code Compiler. Learn how we achieve low-latency remote execution, handle real-time I/O streams, and manage dynamic dependency resolution.
+ </p>
+ </div>
+
+ <!-- Architecture -->
+ <section id="architecture" class="doc-section">
+ <h2 class="text-2xl font-heading font-bold text-lime-300 mb-6 flex items-center">
+ <span class="mr-3">01.</span> Architecture
+ </h2>
+ <p class="text-neutral-300 mb-4">
+ The compiler uses a client-server model optimized for persistent connections. Unlike traditional stateless REST APIs which require polling for output, we utilize <strong>WebSockets</strong> to maintain a full-duplex communication channel between the browser's xterm.js terminal and the backend process.
+ </p>
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6 my-8">
+ <div class="p-6 rounded-xl bg-white/5 border border-white/10">
+ <h3 class="text-white font-bold mb-2"><i class="fas fa-desktop text-lime-300 mr-2"></i> Frontend</h3>
+ <p class="text-sm text-neutral-400">Xterm.js renders a TTY-like interface. User keystrokes are captured and sent as binary/text frames.</p>
+ </div>
+ <div class="p-6 rounded-xl bg-white/5 border border-white/10">
+ <h3 class="text-white font-bold mb-2"><i class="fas fa-server text-lime-300 mr-2"></i> Backend</h3>
+ <p class="text-sm text-neutral-400">Python <code>aiohttp</code> server running on Linux. Spawns <code>subprocess</code> threads for isolation.</p>
+ </div>
+ </div>
+ </section>
+
+ <!-- WebSocket Protocol -->
+ <section id="communication" class="doc-section">
+ <h2 class="text-2xl font-heading font-bold text-lime-300 mb-6 flex items-center">
+ <span class="mr-3">02.</span> WebSocket Protocol
+ </h2>
+ <p class="text-neutral-300 mb-4">
+ Communication occurs via JSON payloads. The server handles two main event types: <strong>execution</strong> and <strong>input streaming</strong>.
+ </p>
+
+ <h3 class="text-lg font-bold text-white mt-6 mb-2">Client -> Server</h3>
+ <div class="code-block">
+ <pre><code class="language-json">// 1. Initiate Execution
+{
+ "type": "run",
+ "language": "python", // or "c", "cpp"
+ "code": "print('Hello World')"
+}
+
+// 2. Send User Input (stdin)
+{
+ "type": "input",
+ "data": "user_input_string\n"
+}</code></pre>
+ </div>
+
+ <h3 class="text-lg font-bold text-white mt-6 mb-2">Server -> Client</h3>
+ <div class="code-block">
+ <pre><code class="language-json">// 1. Standard Output/Error Stream (sent character-by-character or chunked)
+{
+ "type": "stdout",
+ "data": "H"
+}
+
+// 2. Status Updates
+{
+ "type": "status",
+ "msg": "Compiling..."
+}</code></pre>
+ </div>
+ </section>
+
+ <!-- Python Engine -->
+ <section id="python-engine" class="doc-section">
+ <h2 class="text-2xl font-heading font-bold text-lime-300 mb-6 flex items-center">
+ <span class="mr-3">03.</span> Python Engine & Auto-Pip
+ </h2>
+ <p class="text-neutral-300 mb-4">
+ The Python runner is equipped with a dynamic dependency resolver. Before execution, the backend statically analyzes the code imports using RegEx.
+ </p>
+
+ <div class="p-6 rounded-xl border border-lime-300/20 bg-lime-300/5 mb-6">
+ <h4 class="font-bold text-white mb-2">Feature: Dynamic Installation</h4>
+ <p class="text-sm text-neutral-300">
+ If a user imports a non-standard library (e.g., <code>import numpy</code>), the server automatically runs <code>pip install numpy</code> before executing the script. This allows for rich script execution without pre-configuration.
+ </p>
+ </div>
+
+ <div class="code-block">
+ <pre><code class="language-python"># Backend Logic Snippet
+def check_and_install_packages(code):
+ imports = re.findall(r'^\s*import\s+(\w+)', code, re.MULTILINE)
+ for pkg in imports:
+ if pkg not in standard_libs:
+ subprocess.check_call([sys.executable, "-m", "pip", "install", pkg])</code></pre>
+ </div>
+ </section>
+
+ <!-- C / C++ Engine -->
+ <section id="cpp-engine" class="doc-section">
+ <h2 class="text-2xl font-heading font-bold text-lime-300 mb-6 flex items-center">
+ <span class="mr-3">04.</span> C / C++ Compilation
+ </h2>
+ <p class="text-neutral-300 mb-4">
+ For compiled languages, the server performs a two-step process. Source code is written to a temporary file, compiled via GCC/G++, and then executed.
+ </p>
+ <ul class="list-disc list-inside text-neutral-400 space-y-2 mb-6 ml-4">
+ <li><strong>C:</strong> <code>gcc temp.c -o a.out</code></li>
+ <li><strong>C++:</strong> <code>g++ temp.cpp -o a.out</code></li>
+ </ul>
+ <p class="text-neutral-300">
+ Standard Input buffer flushing is handled automatically to ensure prompts (like <code>cin >> var</code>) appear immediately in the terminal before blocking for input.
+ </p>
+ </section>
+
+ <!-- Security -->
+ <section id="security" class="doc-section">
+ <h2 class="text-2xl font-heading font-bold text-lime-300 mb-6 flex items-center">
+ <span class="mr-3">05.</span> Security & Limitations
+ </h2>
+ <p class="text-neutral-300 mb-4">
+ The current implementation runs code directly on the host instance. While effective for a portfolio demonstration or trusted environment, this setup is <strong>not sandboxed</strong>.
+ </p>
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
+ <div class="p-4 border border-red-500/30 bg-red-500/5 rounded-lg">
+ <h4 class="text-red-400 font-bold mb-2">Current Limitations</h4>
+ <ul class="text-xs text-neutral-400 space-y-1">
+ <li>• No containerization (Docker)</li>
+ <li>• No CPU/RAM usage quotas</li>
+ <li>• File system access is unrestricted within user scope</li>
+ </ul>
+ </div>
+ <div class="p-4 border border-lime-300/30 bg-lime-300/5 rounded-lg">
+ <h4 class="text-lime-300 font-bold mb-2">Future Roadmap</h4>
+ <ul class="text-xs text-neutral-400 space-y-1">
+ <li>• Docker container per session</li>
+ <li>• Timeouts for infinite loops</li>
+ <li>• Network access restrictions</li>
+ </ul>
+ </div>
+ </div>
+ </section>
+
+ <!-- Privacy & Data Handling -->
+ <section id="privacy" class="doc-section">
+ <h2 class="text-2xl font-heading font-bold text-lime-300 mb-6 flex items-center">
+ <span class="mr-3">06.</span> Privacy & Data Handling
+ </h2>
+ <p class="text-neutral-300 mb-4">
+ We believe in complete transparency regarding how your data is handled. As a demonstration platform, we prioritize privacy and ephemeral execution.
+ </p>
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6 my-8">
+ <div class="p-6 rounded-xl bg-white/5 border border-white/10">
+ <h3 class="text-white font-bold mb-2"><i class="fas fa-trash-alt text-lime-300 mr-2"></i> No Storage</h3>
+ <p class="text-sm text-neutral-400">
+ Your code is processed in volatile memory or temporary files that are <strong>immediately deleted</strong> after execution. We do not maintain a database of user code.
+ </p>
+ </div>
+ <div class="p-6 rounded-xl bg-white/5 border border-white/10">
+ <h3 class="text-white font-bold mb-2"><i class="fas fa-user-secret text-lime-300 mr-2"></i> Anonymous</h3>
+ <p class="text-sm text-neutral-400">
+ No user accounts, cookies, or personal identifiers are required to use the compiler. Usage is completely anonymous.
+ </p>
+ </div>
+ <div class="p-6 rounded-xl bg-white/5 border border-white/10">
+ <h3 class="text-white font-bold mb-2"><i class="fab fa-github text-lime-300 mr-2"></i> Open Source</h3>
+ <p class="text-sm text-neutral-400">
+ The entire backend infrastructure is open source. You can audit the code yourself on <a href="https://github.com/notamitgamer" target="_blank" class="text-lime-300 hover:underline">GitHub</a>.
+ </p>
+ </div>
+ </div>
+ </section>
+
+ <!-- Legal & Disclaimer -->
+ <section id="disclaimer" class="doc-section">
+ <h2 class="text-2xl font-heading font-bold text-lime-300 mb-6 flex items-center">
+ <span class="mr-3">07.</span> Legal & Disclaimer
+ </h2>
+ <div class="p-6 rounded-xl border border-red-500/20 bg-red-500/5">
+ <p class="text-neutral-300 mb-4">
+ This compiler infrastructure has been extensively refactored by <strong>Gemini 3 Pro</strong>. For bug reports or inquiries, please contact us via:
+ </p>
+ <ul class="text-lime-300 font-mono text-sm mb-6 space-y-1">
+ <li><i class="fas fa-envelope mr-2"></i> <a href="mailto:amitdutta4255@gmail.com" class="hover:underline">amitdutta4255@gmail.com</a></li>
+ <li><i class="fas fa-envelope mr-2"></i> <a href="mailto:mail@amit.is-a.dev" class="hover:underline">mail@amit.is-a.dev</a></li>
+ <li><i class="fab fa-github mr-2"></i> <a href="https://github.com/notamitgamer" target="_blank" class="hover:underline">@notamitgamer</a></li>
+ </ul>
+ <div class="text-neutral-400 text-sm border-t border-white/10 pt-4 leading-relaxed">
+ <p class="mb-2"><strong class="text-red-400">Disclaimer of Liability:</strong> Amit Dutta assumes no responsibility or liability for any consequences, errors, or data loss arising from the use of this compiler. This project is provided for demonstration purposes only.</p>
+ <p class="italic opacity-80">"I explicitly disclaim any affiliation with or responsibility for the ongoing operation of this project. I reserve the absolute right to modify, suspend, or permanently delete this compiler and its associated services at any time, for any reason, without prior notice."</p>
+ </div>
+ </div>
+ </section>
+
+ </main>
+ </div>
+
+ <script>
+ hljs.highlightAll();
+
+ // Simple scroll spy for nav
+ window.addEventListener('scroll', () => {
+ const sections = document.querySelectorAll('.doc-section');
+ const navLinks = document.querySelectorAll('.nav-link');
+
+ let current = '';
+ sections.forEach(section => {
+ const sectionTop = section.offsetTop;
+ if (pageYOffset >= sectionTop - 150) {
+ current = section.getAttribute('id');
+ }
+ });
+
+ navLinks.forEach(link => {
+ link.classList.remove('active');
+ if (link.getAttribute('href').includes(current)) {
+ link.classList.add('active');
+ }
+ });
+ });
+ </script>
+</body>
+</html>+
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
@@ -0,0 +1,423 @@
+<!DOCTYPE html>
+<html lang="en" class="scroll-smooth">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="google-site-verification" content="pwteHw44Ax3N2B1zkFzVJB7NIK0-xgQGRihK_vtZTF4" />
+ <title>Cloud Code Compiler // Amit Dutta</title>
+ <link rel="canonical" href="https://compiler.amit.is-a.dev/" />
+ <link rel="icon" type="image/x-icon" href="https://compiler.amit.is-a.dev/logo.png">
+
+ <!-- Fonts -->
+ <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=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500&family=JetBrains+Mono:wght@400&display=swap" rel="stylesheet">
+
+ <!-- Libraries -->
+ <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
+ <script src="https://cdn.tailwindcss.com"></script>
+
+ <style>
+ :root {
+ --bg-main: #050505;
+ --accent: #bef264; /* Lime 300 */
+ --text-muted: #737373;
+ --border-color: rgba(255, 255, 255, 0.1);
+ }
+
+ body {
+ font-family: 'Inter', sans-serif;
+ background-color: var(--bg-main);
+ color: #f5f5f5;
+ overflow-x: hidden;
+ }
+
+ /* Portfolio Aesthetic */
+ .font-mono { font-family: 'JetBrains Mono', monospace; }
+ .font-heading { font-family: 'Space Grotesk', sans-serif; }
+
+ /* Noise Overlay */
+ .bg-noise {
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%;
+ pointer-events: none; z-index: 0; opacity: 0.03;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
+ }
+
+ /* CRT Scanline */
+ .crt-scanline {
+ position: fixed; top: 0; left: 0; width: 100%; height: 2px;
+ background: rgba(190, 242, 100, 0.1); opacity: 0.5;
+ pointer-events: none; z-index: 50;
+ animation: scanline 8s linear infinite;
+ }
+ @keyframes scanline { 0% { top: -10vh; } 100% { top: 110vh; } }
+
+ /* Compiler Card Styling */
+ .compiler-card {
+ background: rgba(255, 255, 255, 0.02);
+ border: 1px solid var(--border-color);
+ border-radius: 1.5rem;
+ position: relative;
+ overflow: hidden;
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
+ z-index: 10;
+ }
+
+ .compiler-card:hover {
+ transform: translateY(-5px);
+ border-color: var(--accent);
+ box-shadow: 0 0 20px rgba(190, 242, 100, 0.1);
+ }
+
+ .compiler-card::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(800px circle at var(--mouse-x) var(--mouse-y), rgba(255, 255, 255, 0.06), transparent 40%);
+ opacity: 0;
+ transition: opacity 0.5s;
+ pointer-events: none;
+ }
+
+ .compiler-card:hover::before {
+ opacity: 1;
+ }
+
+ .icon-container {
+ background: rgba(255, 255, 255, 0.03);
+ border: 1px solid var(--border-color);
+ transition: all 0.3s ease;
+ }
+
+ .compiler-card:hover .icon-container {
+ border-color: var(--accent);
+ background: rgba(190, 242, 100, 0.1);
+ }
+
+ /* Buttons */
+ .btn-primary {
+ background-color: var(--accent);
+ color: #000;
+ font-family: 'Space Grotesk', sans-serif;
+ font-weight: 700;
+ transition: all 0.3s ease;
+ }
+ .btn-primary:hover {
+ background-color: #d9f99d; /* Lime 200 */
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(190, 242, 100, 0.3);
+ }
+
+ /* Animations */
+ .floating-code {
+ position: absolute;
+ font-family: 'JetBrains Mono', monospace;
+ font-size: 0.8rem;
+ color: var(--text-muted);
+ opacity: 0.2;
+ pointer-events: none;
+ animation: float 10s infinite ease-in-out;
+ }
+ @keyframes float {
+ 0%, 100% { transform: translateY(0); }
+ 50% { transform: translateY(-20px); }
+ }
+
+ /* Social Links */
+ .social-link {
+ background: rgba(255, 255, 255, 0.03);
+ border: 1px solid var(--border-color);
+ color: #a3a3a3;
+ transition: all 0.3s ease;
+ }
+ .social-link:hover {
+ color: var(--accent);
+ border-color: var(--accent);
+ transform: translateY(-3px);
+ }
+
+ ::selection { background: var(--accent); color: black; }
+
+ .typewriter h1 {
+ border-right: none;
+ }
+
+ /* Fade in animation for "Create." */
+ .fade-in-create {
+ animation: fadeIn 1s ease-in forwards;
+ opacity: 0;
+ }
+ @keyframes fadeIn {
+ to { opacity: 1; }
+ }
+ </style>
+</head>
+<body class="antialiased selection:bg-lime-300 selection:text-black">
+
+ <div class="bg-noise"></div>
+ <div class="crt-scanline"></div>
+
+ <!-- Background Elements -->
+ <div class="fixed inset-0 z-0 overflow-hidden pointer-events-none">
+ <div class="floating-code" style="top: 15%; left: 10%; animation-delay: 0s;">print("Hello World")</div>
+ <div class="floating-code" style="top: 25%; right: 15%; animation-delay: 2s;">#include <stdio.h></div>
+ <div class="floating-code" style="bottom: 20%; left: 20%; animation-delay: 4s;">std::cout << "Code";</div>
+ <div class="floating-code" style="bottom: 30%; right: 10%; animation-delay: 1s;">const int MAX = 100;</div>
+ </div>
+
+ <!-- Hero Section -->
+ <div class="relative min-h-screen flex flex-col items-center justify-center p-6 z-10">
+
+ <header class="text-center mb-16" data-aos="fade-up">
+ <div class="inline-block mb-4 px-4 py-1 rounded-full border border-white/10 bg-white/5 backdrop-blur-sm">
+ <span class="text-xs font-mono text-lime-300 tracking-wider">/// REAL-TIME CLOUD COMPILER</span>
+ </div>
+ <div class="typewriter max-w-4xl mx-auto">
+ <h1 class="text-4xl sm:text-6xl md:text-7xl font-heading font-bold text-white mb-6 tracking-tight leading-tight">
+ <span id="type-text"></span><br />
+ <span id="create-text" class="text-lime-300 fade-in-create hidden">Create.</span>
+ </h1>
+ </div>
+ <p class="sub-text-fade opacity-0 text-base sm:text-lg md:text-xl text-gray-400 max-w-3xl mx-auto leading-relaxed mt-4 font-light">
+ Experience powerful, server-side code execution with low-latency WebSocket connections. No simulations, just pure performance.
+ </p>
+ </header>
+
+ <!-- Compiler Cards -->
+ <main class="w-full max-w-6xl mx-auto px-4" data-aos="fade-up" data-aos-delay="200">
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6" id="compiler-grid">
+
+ <!-- C Compiler -->
+ <a href="./c.html" class="compiler-card p-8 group block">
+ <div class="icon-container w-14 h-14 rounded-xl flex items-center justify-center mb-6">
+ <span class="font-heading font-bold text-2xl text-white">C</span>
+ </div>
+ <h2 class="text-2xl font-heading font-bold text-white mb-2 group-hover:text-lime-300 transition-colors">Standard C</h2>
+ <p class="text-sm text-neutral-500 mb-6 leading-relaxed">
+ Compile standard C programs on a remote server using GCC. Supports pointers and memory logic.
+ </p>
+ <div class="flex items-center text-xs font-mono text-lime-300 uppercase tracking-widest">
+ Launch <i class="fas fa-arrow-right ml-2 group-hover:translate-x-1 transition-transform"></i>
+ </div>
+ </a>
+
+ <!-- C++ Compiler -->
+ <a href="./cpp.html" class="compiler-card p-8 group block">
+ <div class="icon-container w-14 h-14 rounded-xl flex items-center justify-center mb-6">
+ <span class="font-heading font-bold text-2xl text-white">C++</span>
+ </div>
+ <h2 class="text-2xl font-heading font-bold text-white mb-2 group-hover:text-lime-300 transition-colors">Modern C++</h2>
+ <p class="text-sm text-neutral-500 mb-6 leading-relaxed">
+ Execute C++ code via G++. Features standard input/output streaming and STL support.
+ </p>
+ <div class="flex items-center text-xs font-mono text-lime-300 uppercase tracking-widest">
+ Launch <i class="fas fa-arrow-right ml-2 group-hover:translate-x-1 transition-transform"></i>
+ </div>
+ </a>
+
+ <!-- Python Compiler -->
+ <a href="./python.html" class="compiler-card p-8 group block">
+ <div class="icon-container w-14 h-14 rounded-xl flex items-center justify-center mb-6">
+ <i class="fab fa-python text-2xl text-white"></i>
+ </div>
+ <h2 class="text-2xl font-heading font-bold text-white mb-2 group-hover:text-lime-300 transition-colors">Python 3</h2>
+ <p class="text-sm text-neutral-500 mb-6 leading-relaxed">
+ Full Python 3 environment with automatic package installation (pip) and interactive shell.
+ </p>
+ <div class="flex items-center text-xs font-mono text-lime-300 uppercase tracking-widest">
+ Launch <i class="fas fa-arrow-right ml-2 group-hover:translate-x-1 transition-transform"></i>
+ </div>
+ </a>
+
+ </div>
+
+ <div class="text-center mt-8">
+ <p class="text-[10px] font-mono text-neutral-600 uppercase tracking-widest">More languages loading...</p>
+ </div>
+ </main>
+
+ <a href="#features" class="absolute bottom-10 animate-bounce text-neutral-600 hover:text-white transition-colors">
+ <i class="fas fa-chevron-down text-xl"></i>
+ </a>
+ </div>
+
+ <!-- Features Section -->
+ <section id="features" class="py-32 px-6 border-t border-white/5 bg-black/20 z-10">
+ <div class="max-w-6xl mx-auto">
+ <div class="text-center mb-20" data-aos="fade-up">
+ <h2 class="text-3xl sm:text-4xl font-heading font-bold text-white mb-4">Engineered for <span class="text-lime-300">Performance</span></h2>
+ <p class="text-neutral-400 max-w-xl mx-auto">A robust platform designed for real development tasks.</p>
+ </div>
+
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
+ <!-- Feature 1 -->
+ <div class="compiler-card p-8" data-aos="fade-up" data-aos-delay="100">
+ <i class="fas fa-server text-2xl text-lime-300 mb-6"></i>
+ <h3 class="text-xl font-bold text-white mb-3">Real Backend</h3>
+ <p class="text-sm text-neutral-500 leading-relaxed">Code is executed on a live Linux server instance, ensuring accurate runtime behavior.</p>
+ </div>
+ <!-- Feature 2 -->
+ <div class="compiler-card p-8" data-aos="fade-up" data-aos-delay="200">
+ <i class="fas fa-bolt text-2xl text-lime-300 mb-6"></i>
+ <h3 class="text-xl font-bold text-white mb-3">Low Latency</h3>
+ <p class="text-sm text-neutral-500 leading-relaxed">WebSockets provide a persistent connection for instant input/output streaming.</p>
+ </div>
+ <!-- Feature 3 -->
+ <div class="compiler-card p-8" data-aos="fade-up" data-aos-delay="300">
+ <i class="fas fa-box-open text-2xl text-lime-300 mb-6"></i>
+ <h3 class="text-xl font-bold text-white mb-3">Auto-Pip Install</h3>
+ <p class="text-sm text-neutral-500 leading-relaxed">The server detects missing Python libraries and installs them on the fly.</p>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <!-- AI Generator Section -->
+ <section class="py-32 px-6 border-t border-white/5 z-10">
+ <div class="max-w-4xl mx-auto text-center" data-aos="fade-up">
+ <h2 class="text-3xl font-heading font-bold text-white mb-8">Generate Code Instantly</h2>
+
+ <div class="compiler-card p-1 rounded-2xl bg-gradient-to-br from-white/10 to-transparent p-[1px]">
+ <div class="bg-[#0a0a0a] rounded-2xl p-8">
+ <textarea id="ai-prompt-input" class="w-full h-32 bg-transparent text-white font-mono text-sm placeholder-neutral-600 focus:outline-none resize-none" placeholder="// Describe the function you need... e.g. Write a Python script to scrape a website using BeautifulSoup"></textarea>
+ <div class="flex justify-between items-center mt-6 border-t border-white/10 pt-6">
+ <span class="text-xs text-neutral-500 font-mono">POWERED BY GEMINI</span>
+ <button id="ai-generate-btn" class="btn-primary py-2 px-6 rounded-lg text-sm uppercase tracking-wide">
+ Generate <i class="fas fa-sparkles ml-2"></i>
+ </button>
+ </div>
+ </div>
+ </div>
+
+ <div id="ai-response-container" class="mt-8 hidden text-left">
+ <div class="compiler-card p-6 bg-[#0a0a0a]">
+ <pre id="ai-response-text" class="text-sm font-mono text-neutral-300 whitespace-pre-wrap"></pre>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <!-- Footer -->
+ <footer class="py-12 border-t border-white/5 z-10 bg-black/40">
+ <div class="max-w-6xl mx-auto px-6 text-center">
+
+ <!-- Documentation Link Added Here -->
+ <div class="mb-8">
+ <a href="./docs.html" class="inline-flex items-center gap-2 text-sm font-mono text-neutral-500 hover:text-lime-300 transition-colors uppercase tracking-widest border border-white/10 px-4 py-2 rounded-full bg-white/5 hover:bg-white/10">
+ <i class="fas fa-book"></i> Read Documentation
+ </a>
+ </div>
+
+ <h3 class="text-xl font-heading font-bold text-white mb-8">Connect with Me</h3>
+
+ <div class="flex flex-wrap justify-center gap-4 mb-12">
+ <a href="https://github.com/notamitgamer" target="_blank" class="social-link w-12 h-12 rounded-full flex items-center justify-center text-lg">
+ <i class="fab fa-github"></i>
+ </a>
+ <a href="https://linkedin.com/in/notamitgamer" target="_blank" class="social-link w-12 h-12 rounded-full flex items-center justify-center text-lg">
+ <i class="fab fa-linkedin-in"></i>
+ </a>
+ <a href="https://twitter.com/notamitgamer" target="_blank" class="social-link w-12 h-12 rounded-full flex items-center justify-center text-lg">
+ <i class="fab fa-twitter"></i>
+ </a>
+ <a href="https://instagram.com/notamitgamer" target="_blank" class="social-link w-12 h-12 rounded-full flex items-center justify-center text-lg">
+ <i class="fab fa-instagram"></i>
+ </a>
+ </div>
+
+ <div class="text-neutral-600 text-sm font-mono space-y-2">
+ <p>© 2025 Amit Dutta. All rights reserved.</p>
+ <p><a href="https://amit.is-a.dev" class="hover:text-lime-300 transition-colors">amit.is-a.dev</a></p>
+ </div>
+ </div>
+ </footer>
+
+ <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
+ <script>
+ document.addEventListener('DOMContentLoaded', () => {
+ AOS.init({
+ duration: 800,
+ once: true,
+ offset: 50
+ });
+
+ // Card Hover Effect (Mouse tracking)
+ const cards = document.querySelectorAll('.compiler-card');
+ document.getElementById('compiler-grid').onmousemove = e => {
+ for(const card of cards) {
+ const rect = card.getBoundingClientRect();
+ const x = e.clientX - rect.left;
+ const y = e.clientY - rect.top;
+ card.style.setProperty('--mouse-x', `${x}px`);
+ card.style.setProperty('--mouse-y', `${y}px`);
+ }
+ };
+
+ // Typewriter logic
+ const typeTextElement = document.getElementById('type-text');
+ const createTextElement = document.getElementById('create-text');
+ const textToType = "Code. Compile.";
+ let i = 0;
+ const speed = 75; // ms per char
+
+ function typeWriter() {
+ if (i < textToType.length) {
+ typeTextElement.textContent += textToType.charAt(i);
+ i++;
+ setTimeout(typeWriter, speed);
+ } else {
+ // Typing done, show "Create." with fade-in
+ createTextElement.classList.remove('hidden');
+
+ // Trigger subtext fade
+ document.querySelector('.sub-text-fade').style.animation = 'fadeInDown 2s ease-in-out forwards 0.5s';
+ }
+ }
+
+ // Start typing after a short delay
+ setTimeout(typeWriter, 500);
+
+ // AI Generator Logic
+ const generateBtn = document.getElementById('ai-generate-btn');
+ const promptInput = document.getElementById('ai-prompt-input');
+ const responseContainer = document.getElementById('ai-response-container');
+ const responseText = document.getElementById('ai-response-text');
+
+ generateBtn.addEventListener('click', async () => {
+ const userPrompt = promptInput.value.trim();
+ if (!userPrompt) return;
+
+ generateBtn.innerHTML = '<i class="fas fa-circle-notch fa-spin"></i>';
+ generateBtn.disabled = true;
+ responseContainer.classList.remove('hidden');
+ responseText.textContent = '// Thinking...';
+
+ const systemPrompt = "You are an expert code assistant. Provide concise, clean, and well-commented code based on the user request. Use markdown format.";
+ const apiKey = "AIzaSyAi1FdeIJ4PzihkCrOGztdVHIyJ7xIoVQ0";
+ const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`;
+
+ try {
+ const response = await fetch(apiUrl, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ contents: [{ parts: [{ text: userPrompt }] }],
+ systemInstruction: { parts: [{ text: systemPrompt }] }
+ })
+ });
+
+ const data = await response.json();
+ const text = data.candidates?.[0]?.content?.parts?.[0]?.text || "// Error: No response generated.";
+ responseText.textContent = text;
+ } catch (error) {
+ responseText.textContent = `// Error: ${error.message}`;
+ } finally {
+ generateBtn.innerHTML = 'Generate <i class="fas fa-sparkles ml-2"></i>';
+ generateBtn.disabled = false;
+ }
+ });
+ });
+ </script>
+</body>
+</html>+
\ No newline at end of file
diff --git a/public/logo.png b/public/logo.png
Binary files differ.
diff --git a/public/python.html b/public/python.html
@@ -0,0 +1,498 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <title>Amit Dutta // Python Compiler</title>
+ <link rel="icon" type="image/x-icon" href="https://compiler.aranag.site/logo.png">
+
+ <!-- Fonts & Icons -->
+ <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=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500&family=JetBrains+Mono:wght@400&display=swap" rel="stylesheet">
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
+
+ <!-- Tailwind CSS -->
+ <script src="https://cdn.tailwindcss.com"></script>
+
+ <!-- Xterm.js -->
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css" />
+ <script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
+
+ <style>
+ :root {
+ --bg-main: #050505;
+ --accent: #bef264; /* Lime 300 */
+ --text-muted: #737373;
+ --border-color: rgba(255, 255, 255, 0.1);
+ }
+
+ body {
+ font-family: 'Inter', sans-serif;
+ background-color: var(--bg-main);
+ color: #f5f5f5;
+ height: 100vh;
+ height: 100dvh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ }
+
+ /* Portfolio Aesthetic */
+ .font-mono { font-family: 'JetBrains Mono', monospace; }
+ .font-heading { font-family: 'Space Grotesk', sans-serif; }
+
+ /* Noise Overlay */
+ .bg-noise {
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%;
+ pointer-events: none; z-index: 0; opacity: 0.03;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
+ }
+
+ /* CRT Scanline */
+ .crt-scanline {
+ position: fixed; top: 0; left: 0; width: 100%; height: 2px;
+ background: rgba(190, 242, 100, 0.1); opacity: 0.5;
+ pointer-events: none; z-index: 50;
+ animation: scanline 8s linear infinite;
+ }
+ @keyframes scanline { 0% { top: -10vh; } 100% { top: 110vh; } }
+
+ /* Custom Editor Styles */
+ .editor-container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ font-family: 'JetBrains Mono', monospace;
+ font-size: 13px;
+ line-height: 1.5;
+ }
+
+ /* The actual textarea for typing */
+ #code-input {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ padding: 1rem;
+ border: none;
+ outline: none;
+ background: transparent;
+ color: #e2e8f0; /* Visible Text */
+ caret-color: #fff; /* Cursor visible */
+ z-index: 1;
+ resize: none;
+ white-space: pre;
+ overflow: auto;
+ }
+
+ .xterm-viewport { overflow-y: auto !important; }
+
+ ::selection { background: var(--accent); color: black; }
+
+ .custom-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; }
+ .custom-scrollbar::-webkit-scrollbar-track { background: #050505; }
+ .custom-scrollbar::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }
+
+ /* Toast Notification */
+ .toast {
+ position: fixed;
+ bottom: 2rem;
+ left: 50%;
+ transform: translateX(-50%) translateY(100px);
+ background: #1a1a1a;
+ border: 1px solid var(--accent);
+ color: var(--accent);
+ padding: 0.5rem 1.5rem;
+ border-radius: 9999px;
+ font-family: 'JetBrains Mono', monospace;
+ font-size: 0.8rem;
+ transition: transform 0.3s ease;
+ z-index: 100;
+ }
+ .toast.show { transform: translateX(-50%) translateY(0); }
+
+ /* Connection Dot Pulse */
+ .pulse-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ display: inline-block;
+ box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7);
+ animation: pulse-white 2s infinite;
+ }
+ .pulse-dot.connected {
+ background-color: #bef264; /* Lime */
+ box-shadow: 0 0 0 0 rgba(190, 242, 100, 0.7);
+ animation: pulse-lime 2s infinite;
+ }
+ .pulse-dot.disconnected {
+ background-color: #ef4444; /* Red */
+ box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
+ animation: pulse-red 2s infinite;
+ }
+
+ @keyframes pulse-lime {
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(190, 242, 100, 0.7); }
+ 70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(190, 242, 100, 0); }
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(190, 242, 100, 0); }
+ }
+ @keyframes pulse-red {
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
+ 70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
+ }
+ </style>
+</head>
+<body class="antialiased selection:bg-lime-300 selection:text-black">
+
+ <div class="bg-noise"></div>
+ <div class="crt-scanline"></div>
+ <div id="toast" class="toast">Link Copied to Clipboard!</div>
+
+ <!-- Header (Responsive) -->
+ <header class="h-auto md:h-16 flex flex-col md:flex-row items-center justify-between px-4 py-3 md:px-6 shrink-0 border-b border-white/10 z-20 bg-neutral-900/50 backdrop-blur-md gap-3 md:gap-4">
+
+ <!-- Top Row: Title & Status -->
+ <div class="flex items-center justify-between w-full md:w-auto">
+ <h1 class="text-lg md:text-xl font-heading font-bold text-white tracking-tight flex items-center">
+ <span class="text-lime-300 mr-2">//</span>PY.COMPILER
+ <span id="conn-dot" class="pulse-dot disconnected ml-3" title="Disconnected"></span>
+ </h1>
+
+ <!-- Mobile Only: Exit Link -->
+ <a href="./index.html" class="md:hidden font-mono text-[10px] text-neutral-500 hover:text-white uppercase tracking-wider transition-colors">[ EXIT ]</a>
+ </div>
+
+ <!-- Middle: Connection Text -->
+ <div class="hidden md:flex items-center gap-2 font-mono text-xs text-neutral-500">
+ <span id="connection-status">Connecting to server...</span>
+ </div>
+
+ <!-- Bottom/Right: Buttons -->
+ <div class="flex items-center gap-2 w-full md:w-auto justify-end">
+ <a href="./index.html" class="hidden md:inline font-mono text-[10px] text-neutral-500 hover:text-white uppercase tracking-wider transition-colors mr-2">[ EXIT ]</a>
+
+ <button id="reset-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Reset Terminal">
+ <i class="fas fa-rotate-left"></i>
+ </button>
+
+ <button id="share-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Share Code">
+ <i class="fas fa-share-alt"></i>
+ </button>
+
+ <button id="copy-btn" class="bg-white/5 hover:bg-neutral-800 text-white border border-white/10 px-3 py-2 rounded font-mono text-[10px] font-bold uppercase tracking-wider flex items-center justify-center transition-all" title="Copy Output">
+ <i class="fas fa-copy"></i>
+ </button>
+
+ <button id="run-btn" disabled class="bg-white/5 hover:bg-lime-300 hover:text-black disabled:opacity-50 disabled:cursor-not-allowed text-white border border-white/10 px-4 py-2 rounded font-mono text-xs font-bold uppercase tracking-wider flex items-center gap-2 transition-all flex-1 md:flex-none justify-center shadow-lg shadow-black/50">
+ <i class="fas fa-play text-[10px]"></i> <span class="md:hidden lg:inline">EXECUTE</span><span class="hidden md:inline lg:hidden">RUN</span>
+ </button>
+ </div>
+ </header>
+
+ <!-- Main Workspace -->
+ <div class="flex-1 flex flex-col md:flex-row min-h-0 z-10 relative">
+
+ <!-- Code Editor -->
+ <div class="flex-1 flex flex-col h-[60%] md:h-auto min-h-0 border-b md:border-b-0 md:border-r border-white/10 relative group">
+ <div class="bg-black/20 px-4 py-2 text-[10px] font-mono text-lime-300 uppercase border-b border-white/10 flex justify-between items-center shrink-0">
+ <span>SRC // main.py</span>
+ <span class="text-neutral-600">PYTHON 3</span>
+ </div>
+
+ <!-- Custom Editor Area -->
+ <div class="editor-container relative bg-[#0c0f16]">
+ <textarea id="code-input" spellcheck="false" autocapitalize="off" autocomplete="off" autocorrect="off" class="custom-scrollbar">import time
+
+# Simple Clock Preview
+print("Current Time:")
+print(time.strftime("%H:%M:%S"))
+print("Done.")</textarea>
+ </div>
+
+ <!-- AI Fix Button -->
+ <button id="ai-fix-btn" class="hidden absolute bottom-4 right-4 bg-red-500/10 border border-red-500/50 text-red-400 hover:bg-red-500 hover:text-white px-3 py-1.5 rounded-lg text-xs font-mono transition-all items-center gap-2 backdrop-blur-md z-20">
+ <i class="fas fa-magic"></i> Fix with AI
+ </button>
+ </div>
+
+ <!-- Terminal -->
+ <div class="flex-1 flex flex-col h-[40%] md:h-auto min-h-0 bg-[#050505]">
+ <div class="bg-black/20 px-4 py-2 text-[10px] font-mono text-lime-300 uppercase border-b border-white/10 flex justify-between items-center shrink-0">
+ <span>OUT // TERMINAL</span>
+ <span class="text-neutral-600">XTERM.JS</span>
+ </div>
+ <div class="flex-1 relative">
+ <div id="terminal-container" class="absolute inset-0 w-full h-full p-2 overflow-hidden"></div>
+ </div>
+ </div>
+ </div>
+
+ <script>
+ // --- DOM Elements ---
+ const runBtn = document.getElementById('run-btn');
+ const resetBtn = document.getElementById('reset-btn');
+ const shareBtn = document.getElementById('share-btn');
+ const copyBtn = document.getElementById('copy-btn');
+ const aiFixBtn = document.getElementById('ai-fix-btn');
+ const connDot = document.getElementById('conn-dot');
+ const connectionStatus = document.getElementById('connection-status');
+ const codeInput = document.getElementById('code-input');
+ const toast = document.getElementById('toast');
+
+ // --- State ---
+ let socket = null;
+ let currentLine = "";
+ let startTime = 0;
+
+ // --- EDITOR LOGIC (Indentation for Python) ---
+ codeInput.addEventListener('keydown', function(e) {
+ if (e.key === 'Tab') {
+ e.preventDefault();
+ const start = this.selectionStart;
+ const end = this.selectionEnd;
+ this.setRangeText(' ', start, end, 'end');
+ } else if (e.key === 'Enter') {
+ e.preventDefault();
+ const start = this.selectionStart;
+ const end = this.selectionEnd;
+ const value = this.value;
+ const lineStart = value.lastIndexOf('\n', start - 1) + 1;
+ const currentLineText = value.substring(lineStart, start);
+ let match = currentLineText.match(/^(\s*)/);
+ let indent = match ? match[1] : "";
+
+ // Python specific: indent if line ends with colon
+ if (currentLineText.trim().endsWith(':')) indent += " ";
+
+ this.setRangeText('\n' + indent, start, end, 'end');
+ this.blur(); this.focus();
+ }
+ });
+
+ window.addEventListener('load', () => {
+ const params = new URLSearchParams(window.location.search);
+ const sharedCode = params.get('code');
+ if (sharedCode) {
+ try { codeInput.value = atob(sharedCode); }
+ catch(e) {}
+ }
+ setTimeout(connect, 500);
+ });
+
+ // --- Terminal Setup ---
+ const term = new Terminal({
+ theme: {
+ background: '#050505',
+ foreground: '#f5f5f5',
+ cursor: '#bef264',
+ selectionBackground: 'rgba(190, 242, 100, 0.3)',
+ black: '#050505',
+ green: '#bef264',
+ yellow: '#facc15',
+ red: '#ef4444',
+ },
+ fontFamily: "'JetBrains Mono', monospace",
+ fontSize: 12,
+ cursorBlink: true,
+ convertEol: true
+ });
+ const fitAddon = new FitAddon.FitAddon();
+ term.loadAddon(fitAddon);
+ term.open(document.getElementById('terminal-container'));
+ fitAddon.fit();
+ window.addEventListener('resize', () => fitAddon.fit());
+
+ // Custom Key Handler for Ctrl+C Copy
+ term.attachCustomKeyEventHandler((arg) => {
+ if (arg.ctrlKey && arg.code === "KeyC" && arg.type === "keydown") {
+ const selection = term.getSelection();
+ if (selection) {
+ fallbackCopyTextToClipboard(selection);
+ return false;
+ }
+ }
+ return true;
+ });
+
+ term.write('\x1b[38;2;115;115;115m> SYSTEM READY.\r\n> ATTEMPTING CONNECTION...\x1b[0m\r\n');
+
+ // --- WebSocket Logic ---
+ function connect() {
+ const url = "wss://compiler-z4x4.onrender.com";
+ try { socket = new WebSocket(url); } catch (e) {
+ term.write(`\r\n\x1b[31m> INVALID URL.\x1b[0m\r\n`);
+ return;
+ }
+
+ socket.onopen = () => {
+ connDot.className = "pulse-dot connected ml-3";
+ if(connectionStatus) connectionStatus.textContent = "Connected to Server";
+ if(connectionStatus) connectionStatus.className = "hidden md:flex items-center gap-2 font-mono text-xs text-lime-300";
+
+ term.write(`\x1b[38;2;190;242;100m> CONNECTION ESTABLISHED.\x1b[0m\r\n> python3 main.py\r\n`);
+ runBtn.disabled = false;
+ };
+
+ socket.onclose = () => {
+ connDot.className = "pulse-dot disconnected ml-3";
+ if(connectionStatus) connectionStatus.textContent = "Disconnected";
+ if(connectionStatus) connectionStatus.className = "hidden md:flex items-center gap-2 font-mono text-xs text-red-500";
+
+ term.write(`\r\n\x1b[31m> CONNECTION LOST. RECONNECTING...\x1b[0m\r\n`);
+ runBtn.disabled = true;
+ setTimeout(connect, 3000);
+ socket = null;
+ };
+
+ socket.onmessage = (event) => {
+ const msg = JSON.parse(event.data);
+ if (msg.type === 'stdout') {
+ let text = msg.data;
+
+ if (text.toLowerCase().includes("error") || text.toLowerCase().includes("traceback")) {
+ aiFixBtn.classList.remove('hidden');
+ }
+
+ if (!text.includes('\r')) {
+ text = text.replace(/\n/g, '\r\n');
+ }
+ term.write(text);
+ } else if (msg.type === 'status') {
+ if (msg.msg.includes("Program finished")) {
+ const duration = (Date.now() - startTime) / 1000;
+ term.write(`\r\n\x1b[38;2;115;115;115m[Finished in ${duration.toFixed(3)}s]\x1b[0m\r\n`);
+ }
+ }
+ };
+ }
+
+ // --- Run Logic ---
+ runBtn.addEventListener('click', () => {
+ if (!socket || socket.readyState !== WebSocket.OPEN) return;
+
+ document.activeElement.blur();
+ term.reset();
+ currentLine = "";
+ aiFixBtn.classList.add('hidden');
+
+ let code = codeInput.value;
+ // Basic sanitization
+ code = code.replace(/\u00A0/g, " ").replace(/[\u2018\u2019]/g, "'").replace(/[\u201C\u201D]/g, '"');
+
+ startTime = Date.now();
+ term.write('\x1b[32m> python3 main.py\x1b[0m\r\n');
+
+ socket.send(JSON.stringify({
+ type: 'run',
+ code: code,
+ language: 'python'
+ }));
+
+ term.focus();
+ });
+
+ // --- Reset Logic ---
+ resetBtn.addEventListener('click', () => {
+ term.reset();
+ currentLine = "";
+ term.write(`\x1b[38;2;190;242;100m> CONNECTION ESTABLISHED.\x1b[0m\r\n> python3 main.py\r\n`);
+ });
+
+ // --- Share Functionality with Native Share API ---
+ shareBtn.addEventListener('click', async () => {
+ const code = codeInput.value;
+ const encoded = btoa(code);
+ const url = new URL(window.location.href);
+ url.searchParams.set('code', encoded);
+ const shareUrl = url.toString();
+
+ // Try native sharing first (Mobile/Supported Browsers)
+ if (navigator.share) {
+ try {
+ await navigator.share({
+ title: document.title,
+ text: 'Check out my Python code!',
+ url: shareUrl
+ });
+ } catch (err) {
+ // Ignore cancellation or errors
+ }
+ } else {
+ // Fallback to clipboard copy
+ fallbackCopyTextToClipboard(shareUrl);
+ }
+ });
+
+ function showToast(msg) {
+ toast.textContent = msg;
+ toast.classList.add('show');
+ setTimeout(() => toast.classList.remove('show'), 3000);
+ }
+
+ // --- Smart Copy Function ---
+ copyBtn.addEventListener('click', () => {
+ const buffer = term.buffer.active;
+ let text = "";
+ for (let i = 0; i < buffer.length; i++) {
+ const line = buffer.getLine(i);
+ if (line) {
+ let lineText = line.translateToString(true);
+ if(lineText.trim().startsWith("> [") || lineText.trim().startsWith("> python") || lineText.includes("SYSTEM READY") || lineText.includes("ATTEMPTING") || lineText.includes("CONNECTION")) {
+ continue;
+ }
+ text += lineText + "\n";
+ }
+ }
+ text = text.trim();
+ fallbackCopyTextToClipboard(text);
+ });
+
+ function fallbackCopyTextToClipboard(text) {
+ const textArea = document.createElement("textarea");
+ textArea.value = text;
+ textArea.style.position = "fixed";
+ textArea.style.top = "0";
+ textArea.style.left = "0";
+ textArea.style.opacity = "0";
+ document.body.appendChild(textArea);
+ textArea.focus();
+ textArea.select();
+ try {
+ document.execCommand('copy');
+ showToast("Copied to Clipboard!");
+ } catch (err) {
+ showToast("Copy Failed");
+ }
+ document.body.removeChild(textArea);
+ }
+
+ aiFixBtn.addEventListener('click', () => {
+ showToast("AI Feature: Coming Soon via Backend Update");
+ });
+
+ // Terminal Input
+ term.onData((data) => {
+ if (!socket || socket.readyState !== WebSocket.OPEN) return;
+
+ if (data === '\r') {
+ term.write('\r\n');
+ socket.send(JSON.stringify({ type: 'input', data: currentLine + '\n' }));
+ currentLine = "";
+ } else if (data === '\x7f' || data === '\b') {
+ if (currentLine.length > 0) {
+ currentLine = currentLine.slice(0, -1);
+ term.write('\b \b');
+ }
+ } else {
+ currentLine += data;
+ term.write(data);
+ }
+ });
+ </script>
+</body>
+</html>+
\ No newline at end of file
diff --git a/public/sitemap.xml b/public/sitemap.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<urlset
+ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
+ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
+
+
+<url>
+ <loc>https://compiler.amit.is-a.dev/</loc>
+ <lastmod>2026-01-05T13:27:42+00:00</lastmod>
+</url>
+<url>
+ <loc>https://compiler.amit.is-a.dev/c/</loc>
+ <lastmod>2026-01-05T13:27:42+00:00</lastmod>
+</url>
+<url>
+ <loc>https://compiler.amit.is-a.dev/cpp/</loc>
+ <lastmod>2026-01-05T13:27:42+00:00</lastmod>
+</url>
+<url>
+ <loc>https://compiler.amit.is-a.dev/python/</loc>
+ <lastmod>2026-01-05T13:27:42+00:00</lastmod>
+</url>
+
+
+</urlset>+
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
@@ -0,0 +1,2 @@
+aiohttp
+websockets+
\ No newline at end of file