Update index.html
Browse files- index.html +108 -47
index.html
CHANGED
|
@@ -3,71 +3,95 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<title>
|
| 7 |
<style>
|
| 8 |
-
body { font-family:
|
| 9 |
-
h2 { text-align: center; color: #00d2ff; margin-bottom: 20px;}
|
| 10 |
-
.notebook-container { max-width: 800px; margin: auto; padding-bottom: 250px; }
|
| 11 |
-
.cell { background: #1e1e1e; margin-bottom: 15px; border-radius: 8px; border: 1px solid #333; overflow: hidden; box-shadow: 0 4px 6px rgba(0,0,0,0.3); }
|
| 12 |
-
.cell-header { padding: 10px 15px; background: #252526; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #333; font-weight: bold; color: #858585;}
|
| 13 |
-
textarea.code-input { width: 100%; height: 120px; background: #1e1e1e; color: #9cdcfe; border: none; padding: 15px; font-family: monospace; font-size: 14px; resize: vertical; outline: none; box-sizing: border-box; }
|
| 14 |
-
.output { background: #000; color: #fff; padding: 15px; font-family: monospace; font-size: 13px; min-height: 20px; white-space: pre-wrap; display: none; margin: 0; border-top: 1px solid #333;}
|
| 15 |
-
button.run-btn { background: #007acc; color: white; border: none; padding: 8px 16px; cursor: pointer; border-radius: 4px; font-weight: bold; transition: 0.2s; }
|
| 16 |
-
button.run-btn:hover { background: #005f9e; }
|
| 17 |
-
.add-cell-btn { display: block; width: 100%; max-width: 800px; margin: auto; padding: 15px; font-size: 16px; font-weight: bold; background: #2ea043; color: white; border: none; border-radius: 8px; cursor: pointer; margin-top: 10px; }
|
| 18 |
-
.add-cell-btn:hover { background: #238636; }
|
| 19 |
|
| 20 |
-
/*
|
| 21 |
-
.
|
| 22 |
-
.
|
| 23 |
-
.
|
| 24 |
-
.
|
| 25 |
-
|
| 26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
</style>
|
| 28 |
</head>
|
| 29 |
<body>
|
| 30 |
|
| 31 |
-
<
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
|
| 36 |
-
<
|
|
|
|
|
|
|
| 37 |
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
<div class="terminal-
|
| 41 |
-
|
| 42 |
-
<
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
</div>
|
| 45 |
</div>
|
| 46 |
|
| 47 |
<script>
|
| 48 |
let cellCount = 0;
|
| 49 |
|
|
|
|
| 50 |
function addCell() {
|
| 51 |
cellCount++;
|
| 52 |
const id = cellCount;
|
| 53 |
const cellHtml = `
|
| 54 |
<div class="cell" id="cell-${id}">
|
| 55 |
-
<div class="cell-
|
| 56 |
-
<span>
|
| 57 |
-
<button class="run-btn" onclick="runCode(${id})">
|
| 58 |
</div>
|
| 59 |
-
<textarea class="code-input" id="code-${id}" placeholder="Python code
|
| 60 |
-
<pre class="output" id="output-${id}"></pre>
|
| 61 |
</div>
|
| 62 |
`;
|
| 63 |
document.getElementById("notebook").insertAdjacentHTML('beforeend', cellHtml);
|
| 64 |
}
|
| 65 |
|
|
|
|
| 66 |
async function runCode(id) {
|
| 67 |
const code = document.getElementById(`code-${id}`).value;
|
| 68 |
const outputEl = document.getElementById(`output-${id}`);
|
| 69 |
outputEl.style.display = "block";
|
| 70 |
-
outputEl.innerText = "
|
| 71 |
|
| 72 |
try {
|
| 73 |
const res = await fetch("/run_code", {
|
|
@@ -76,21 +100,24 @@
|
|
| 76 |
body: JSON.stringify({ code })
|
| 77 |
});
|
| 78 |
const data = await res.json();
|
| 79 |
-
outputEl.innerText = data.output || "
|
| 80 |
} catch (err) {
|
| 81 |
-
outputEl.innerText = "Error
|
| 82 |
}
|
| 83 |
}
|
| 84 |
|
|
|
|
| 85 |
async function runTerminal(e) {
|
| 86 |
if (e.key === "Enter") {
|
| 87 |
const cmd = e.target.value;
|
| 88 |
-
if (!cmd) return;
|
| 89 |
|
| 90 |
-
const
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
|
|
|
|
|
|
| 94 |
|
| 95 |
try {
|
| 96 |
const res = await fetch("/run_terminal", {
|
|
@@ -99,15 +126,49 @@
|
|
| 99 |
body: JSON.stringify({ cmd })
|
| 100 |
});
|
| 101 |
const data = await res.json();
|
| 102 |
-
|
| 103 |
-
|
|
|
|
| 104 |
} catch (err) {
|
| 105 |
-
|
| 106 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
}
|
| 108 |
}
|
| 109 |
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
</script>
|
| 112 |
</body>
|
| 113 |
</html>
|
|
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Classic Python Notebook</title>
|
| 7 |
<style>
|
| 8 |
+
body, html { margin: 0; padding: 0; height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; background-color: #1e1e1e; color: #cccccc; overflow: hidden; display: flex; flex-direction: column; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
+
/* Top Navigation/Header */
|
| 11 |
+
.header { background-color: #333333; padding: 10px 20px; border-bottom: 1px solid #000; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 2px 4px rgba(0,0,0,0.2); z-index: 10; }
|
| 12 |
+
.header h2 { margin: 0; font-size: 18px; color: #ffffff; font-weight: 500; }
|
| 13 |
+
.add-btn { background-color: #0e639c; color: white; border: none; padding: 6px 15px; cursor: pointer; border-radius: 3px; font-size: 14px; font-weight: bold; transition: background 0.2s; }
|
| 14 |
+
.add-btn:hover { background-color: #1177bb; }
|
| 15 |
+
|
| 16 |
+
/* Main Container: Split Layout */
|
| 17 |
+
.main-container { display: flex; flex-direction: column; flex: 1; height: calc(100% - 40px); }
|
| 18 |
+
|
| 19 |
+
/* Notebook Section */
|
| 20 |
+
.notebook-panel { flex: 1; overflow-y: auto; padding: 20px; background-color: #1e1e1e; }
|
| 21 |
+
.cell { background: #252526; border: 1px solid #3c3c3c; border-radius: 4px; margin-bottom: 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
|
| 22 |
+
.cell-toolbar { background: #2d2d30; padding: 8px 12px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #3c3c3c; border-top-left-radius: 4px; border-top-right-radius: 4px; }
|
| 23 |
+
.cell-title { font-size: 12px; color: #969696; font-weight: bold; }
|
| 24 |
+
.run-btn { background: #4caf50; color: white; border: none; padding: 4px 12px; cursor: pointer; border-radius: 3px; font-size: 12px; font-weight: bold; }
|
| 25 |
+
.run-btn:hover { background: #45a049; }
|
| 26 |
+
.code-input { width: 100%; height: 100px; background: #1e1e1e; color: #d4d4d4; border: none; padding: 12px; font-family: 'Courier New', Courier, monospace; font-size: 14px; resize: vertical; outline: none; box-sizing: border-box; }
|
| 27 |
+
.code-output { background: #111111; color: #4daaf1; padding: 12px; font-family: 'Courier New', Courier, monospace; font-size: 13px; white-space: pre-wrap; border-top: 1px solid #3c3c3c; display: none; margin: 0; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; }
|
| 28 |
+
|
| 29 |
+
/* Draggable Resizer */
|
| 30 |
+
.resizer { height: 6px; background-color: #333333; cursor: ns-resize; border-top: 1px solid #000; border-bottom: 1px solid #000; display: flex; justify-content: center; align-items: center; z-index: 10; }
|
| 31 |
+
.resizer::after { content: "•••••"; color: #888; font-size: 10px; letter-spacing: 2px; }
|
| 32 |
+
.resizer:hover { background-color: #007acc; }
|
| 33 |
+
|
| 34 |
+
/* Terminal Section */
|
| 35 |
+
.terminal-panel { height: 250px; background-color: #000000; display: flex; flex-direction: column; min-height: 50px; max-height: 80vh; }
|
| 36 |
+
.terminal-header { background: #1e1e1e; color: #e7e7e7; padding: 5px 15px; font-size: 12px; border-bottom: 1px solid #333; text-transform: uppercase; letter-spacing: 1px; }
|
| 37 |
+
.terminal-content { flex: 1; overflow-y: auto; padding: 10px; font-family: 'Courier New', Courier, monospace; font-size: 13px; color: #00ff00; }
|
| 38 |
+
.terminal-history { white-space: pre-wrap; margin-bottom: 5px; }
|
| 39 |
+
.terminal-input-wrapper { display: flex; align-items: center; }
|
| 40 |
+
.terminal-prompt { color: #00ff00; margin-right: 8px; font-weight: bold; }
|
| 41 |
+
.terminal-input { flex: 1; background: transparent; border: none; color: #ffffff; font-family: 'Courier New', Courier, monospace; font-size: 13px; outline: none; caret-color: #ffffff; }
|
| 42 |
</style>
|
| 43 |
</head>
|
| 44 |
<body>
|
| 45 |
|
| 46 |
+
<div class="header">
|
| 47 |
+
<h2>🐍 Classic Notebook</h2>
|
| 48 |
+
<button class="add-btn" onclick="addCell()">+ New Cell</button>
|
| 49 |
+
</div>
|
| 50 |
|
| 51 |
+
<div class="main-container">
|
| 52 |
+
<div class="notebook-panel" id="notebook">
|
| 53 |
+
</div>
|
| 54 |
|
| 55 |
+
<div class="resizer" id="dragMe"></div>
|
| 56 |
+
|
| 57 |
+
<div class="terminal-panel" id="terminalPanel">
|
| 58 |
+
<div class="terminal-header">Terminal (Bash)</div>
|
| 59 |
+
<div class="terminal-content" id="term-content" onclick="document.getElementById('term-in').focus()">
|
| 60 |
+
<div class="terminal-history" id="term-history">Welcome to the integrated terminal...</div>
|
| 61 |
+
<div class="terminal-input-wrapper">
|
| 62 |
+
<span class="terminal-prompt">user@space:~$</span>
|
| 63 |
+
<input type="text" class="terminal-input" id="term-in" onkeydown="runTerminal(event)" autocomplete="off">
|
| 64 |
+
</div>
|
| 65 |
+
</div>
|
| 66 |
</div>
|
| 67 |
</div>
|
| 68 |
|
| 69 |
<script>
|
| 70 |
let cellCount = 0;
|
| 71 |
|
| 72 |
+
// Notebook ke andar ek cell add karne ka function
|
| 73 |
function addCell() {
|
| 74 |
cellCount++;
|
| 75 |
const id = cellCount;
|
| 76 |
const cellHtml = `
|
| 77 |
<div class="cell" id="cell-${id}">
|
| 78 |
+
<div class="cell-toolbar">
|
| 79 |
+
<span class="cell-title">In [${id}]:</span>
|
| 80 |
+
<button class="run-btn" onclick="runCode(${id})">▶ Run</button>
|
| 81 |
</div>
|
| 82 |
+
<textarea class="code-input" id="code-${id}" placeholder="Type Python code here..."></textarea>
|
| 83 |
+
<pre class="code-output" id="output-${id}"></pre>
|
| 84 |
</div>
|
| 85 |
`;
|
| 86 |
document.getElementById("notebook").insertAdjacentHTML('beforeend', cellHtml);
|
| 87 |
}
|
| 88 |
|
| 89 |
+
// Code execute karne ka logic
|
| 90 |
async function runCode(id) {
|
| 91 |
const code = document.getElementById(`code-${id}`).value;
|
| 92 |
const outputEl = document.getElementById(`output-${id}`);
|
| 93 |
outputEl.style.display = "block";
|
| 94 |
+
outputEl.innerText = "Running...";
|
| 95 |
|
| 96 |
try {
|
| 97 |
const res = await fetch("/run_code", {
|
|
|
|
| 100 |
body: JSON.stringify({ code })
|
| 101 |
});
|
| 102 |
const data = await res.json();
|
| 103 |
+
outputEl.innerText = data.output || "Execution completed. No output.";
|
| 104 |
} catch (err) {
|
| 105 |
+
outputEl.innerText = "Error connecting to server.";
|
| 106 |
}
|
| 107 |
}
|
| 108 |
|
| 109 |
+
// Terminal run karne ka logic
|
| 110 |
async function runTerminal(e) {
|
| 111 |
if (e.key === "Enter") {
|
| 112 |
const cmd = e.target.value;
|
| 113 |
+
if (!cmd.trim()) return;
|
| 114 |
|
| 115 |
+
const historyEl = document.getElementById("term-history");
|
| 116 |
+
const contentEl = document.getElementById("term-content");
|
| 117 |
+
|
| 118 |
+
historyEl.innerText += `\nuser@space:~$ ${cmd}`;
|
| 119 |
+
e.target.value = "Running...";
|
| 120 |
+
e.target.disabled = true;
|
| 121 |
|
| 122 |
try {
|
| 123 |
const res = await fetch("/run_terminal", {
|
|
|
|
| 126 |
body: JSON.stringify({ cmd })
|
| 127 |
});
|
| 128 |
const data = await res.json();
|
| 129 |
+
if(data.output.trim() !== "") {
|
| 130 |
+
historyEl.innerText += `\n${data.output.trim()}`;
|
| 131 |
+
}
|
| 132 |
} catch (err) {
|
| 133 |
+
historyEl.innerText += `\nError executing command.`;
|
| 134 |
}
|
| 135 |
+
|
| 136 |
+
e.target.value = "";
|
| 137 |
+
e.target.disabled = false;
|
| 138 |
+
e.target.focus();
|
| 139 |
+
contentEl.scrollTop = contentEl.scrollHeight; // Auto-scroll to bottom
|
| 140 |
}
|
| 141 |
}
|
| 142 |
|
| 143 |
+
// --- Terminal ko draggable (kheenchne wala) banane ka logic ---
|
| 144 |
+
const resizer = document.getElementById('dragMe');
|
| 145 |
+
const terminalPanel = document.getElementById('terminalPanel');
|
| 146 |
+
let isResizing = false;
|
| 147 |
+
|
| 148 |
+
resizer.addEventListener('mousedown', function(e) {
|
| 149 |
+
isResizing = true;
|
| 150 |
+
document.body.style.cursor = 'ns-resize';
|
| 151 |
+
});
|
| 152 |
+
|
| 153 |
+
document.addEventListener('mousemove', function(e) {
|
| 154 |
+
if (!isResizing) return;
|
| 155 |
+
// Total height calculate karke terminal ki height set kar rahe hain
|
| 156 |
+
const windowHeight = window.innerHeight;
|
| 157 |
+
const newHeight = windowHeight - e.clientY;
|
| 158 |
+
|
| 159 |
+
// Limits lagana taaki poora gayab na ho jaye
|
| 160 |
+
if (newHeight > 50 && newHeight < windowHeight - 100) {
|
| 161 |
+
terminalPanel.style.height = newHeight + 'px';
|
| 162 |
+
}
|
| 163 |
+
});
|
| 164 |
+
|
| 165 |
+
document.addEventListener('mouseup', function() {
|
| 166 |
+
isResizing = false;
|
| 167 |
+
document.body.style.cursor = 'default';
|
| 168 |
+
});
|
| 169 |
+
|
| 170 |
+
// Load hote hi ek default cell bana do
|
| 171 |
+
window.onload = addCell;
|
| 172 |
</script>
|
| 173 |
</body>
|
| 174 |
</html>
|