00Boobs00 commited on
Commit
365c40e
·
verified ·
1 Parent(s): 0ea2453

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +636 -19
index.html CHANGED
@@ -1,19 +1,636 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Gradio Context & Dockerizer</title>
7
+ <!-- Importing Phosphor Icons for modern UI iconography -->
8
+ <script src="https://unpkg.com/@phosphor-icons/web"></script>
9
+
10
+ <style>
11
+ /* --- CSS VARIABLES & RESET --- */
12
+ :root {
13
+ --bg-body: #0f1115;
14
+ --bg-panel: #161b22;
15
+ --bg-input: #0d1117;
16
+ --border-color: #30363d;
17
+ --primary: #238636;
18
+ --primary-hover: #2ea043;
19
+ --accent: #58a6ff;
20
+ --text-main: #c9d1d9;
21
+ --text-muted: #8b949e;
22
+ --font-stack: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
23
+ --font-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
24
+ --radius-md: 8px;
25
+ --radius-lg: 12px;
26
+ --shadow: 0 4px 12px rgba(0,0,0,0.5);
27
+ }
28
+
29
+ * {
30
+ box-sizing: border-box;
31
+ margin: 0;
32
+ padding: 0;
33
+ }
34
+
35
+ body {
36
+ background-color: var(--bg-body);
37
+ color: var(--text-main);
38
+ font-family: var(--font-stack);
39
+ height: 100vh;
40
+ display: flex;
41
+ flex-direction: column;
42
+ overflow: hidden;
43
+ }
44
+
45
+ /* --- HEADER --- */
46
+ header {
47
+ height: 60px;
48
+ background-color: var(--bg-panel);
49
+ border-bottom: 1px solid var(--border-color);
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: space-between;
53
+ padding: 0 20px;
54
+ flex-shrink: 0;
55
+ }
56
+
57
+ .brand {
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 10px;
61
+ font-weight: 600;
62
+ font-size: 1.1rem;
63
+ }
64
+
65
+ .brand i {
66
+ color: var(--accent);
67
+ font-size: 1.4rem;
68
+ }
69
+
70
+ .anycoder-link {
71
+ font-size: 0.85rem;
72
+ color: var(--text-muted);
73
+ text-decoration: none;
74
+ background: rgba(255,255,255,0.05);
75
+ padding: 6px 12px;
76
+ border-radius: 20px;
77
+ transition: all 0.2s;
78
+ border: 1px solid transparent;
79
+ }
80
+
81
+ .anycoder-link:hover {
82
+ color: var(--accent);
83
+ border-color: var(--border-color);
84
+ background: rgba(255,255,255,0.1);
85
+ }
86
+
87
+ /* --- LAYOUT --- */
88
+ .layout {
89
+ display: grid;
90
+ grid-template-columns: 320px 1fr;
91
+ flex: 1;
92
+ overflow: hidden;
93
+ }
94
+
95
+ /* --- SIDEBAR (CONFIGURATION) --- */
96
+ aside {
97
+ background-color: var(--bg-panel);
98
+ border-right: 1px solid var(--border-color);
99
+ padding: 20px;
100
+ overflow-y: auto;
101
+ display: flex;
102
+ flex-direction: column;
103
+ gap: 24px;
104
+ }
105
+
106
+ .config-group h3 {
107
+ font-size: 0.8rem;
108
+ text-transform: uppercase;
109
+ letter-spacing: 0.5px;
110
+ color: var(--text-muted);
111
+ margin-bottom: 12px;
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 8px;
115
+ }
116
+
117
+ .form-control {
118
+ margin-bottom: 16px;
119
+ }
120
+
121
+ .form-control label {
122
+ display: block;
123
+ font-size: 0.9rem;
124
+ margin-bottom: 6px;
125
+ color: var(--text-main);
126
+ }
127
+
128
+ .form-control input[type="text"],
129
+ .form-control select,
130
+ .form-control textarea {
131
+ width: 100%;
132
+ background-color: var(--bg-input);
133
+ border: 1px solid var(--border-color);
134
+ color: var(--text-main);
135
+ padding: 8px 12px;
136
+ border-radius: var(--radius-md);
137
+ font-family: inherit;
138
+ font-size: 0.9rem;
139
+ transition: border-color 0.2s;
140
+ }
141
+
142
+ .form-control input:focus,
143
+ .form-control select:focus,
144
+ .form-control textarea:focus {
145
+ outline: none;
146
+ border-color: var(--accent);
147
+ }
148
+
149
+ .range-wrapper {
150
+ display: flex;
151
+ align-items: center;
152
+ gap: 10px;
153
+ }
154
+
155
+ .range-wrapper input {
156
+ flex: 1;
157
+ }
158
+
159
+ .range-value {
160
+ font-family: var(--font-mono);
161
+ font-size: 0.85rem;
162
+ color: var(--accent);
163
+ width: 30px;
164
+ text-align: right;
165
+ }
166
+
167
+ /* --- MAIN CONTENT AREA --- */
168
+ main {
169
+ padding: 20px;
170
+ overflow-y: auto;
171
+ display: flex;
172
+ flex-direction: column;
173
+ gap: 20px;
174
+ background-image: radial-gradient(var(--border-color) 1px, transparent 1px);
175
+ background-size: 24px 24px;
176
+ }
177
+
178
+ .card {
179
+ background-color: var(--bg-panel);
180
+ border: 1px solid var(--border-color);
181
+ border-radius: var(--radius-lg);
182
+ padding: 20px;
183
+ box-shadow: var(--shadow);
184
+ }
185
+
186
+ .card-header {
187
+ display: flex;
188
+ justify-content: space-between;
189
+ align-items: center;
190
+ margin-bottom: 16px;
191
+ border-bottom: 1px solid var(--border-color);
192
+ padding-bottom: 12px;
193
+ }
194
+
195
+ .card-title {
196
+ font-weight: 600;
197
+ display: flex;
198
+ align-items: center;
199
+ gap: 8px;
200
+ }
201
+
202
+ /* --- DOCKERFILE PREVIEW --- */
203
+ .code-block {
204
+ background-color: #0d1117;
205
+ border-radius: var(--radius-md);
206
+ padding: 16px;
207
+ font-family: var(--font-mono);
208
+ font-size: 0.85rem;
209
+ color: #a5d6ff;
210
+ overflow-x: auto;
211
+ white-space: pre;
212
+ position: relative;
213
+ }
214
+
215
+ .copy-btn {
216
+ position: absolute;
217
+ top: 10px;
218
+ right: 10px;
219
+ background: rgba(255,255,255,0.1);
220
+ border: none;
221
+ color: var(--text-main);
222
+ padding: 4px 8px;
223
+ border-radius: 4px;
224
+ font-size: 0.75rem;
225
+ cursor: pointer;
226
+ opacity: 0;
227
+ transition: opacity 0.2s;
228
+ }
229
+
230
+ .code-block:hover .copy-btn {
231
+ opacity: 1;
232
+ }
233
+
234
+ /* --- TERMINAL / LOGS --- */
235
+ .terminal {
236
+ background-color: #000;
237
+ border: 1px solid var(--border-color);
238
+ border-radius: var(--radius-md);
239
+ padding: 12px;
240
+ font-family: var(--font-mono);
241
+ font-size: 0.85rem;
242
+ height: 200px;
243
+ overflow-y: auto;
244
+ color: #d2a8ff;
245
+ }
246
+
247
+ .log-line {
248
+ margin-bottom: 4px;
249
+ display: flex;
250
+ gap: 8px;
251
+ }
252
+
253
+ .log-time {
254
+ color: var(--text-muted);
255
+ }
256
+
257
+ .log-success { color: var(--primary); }
258
+ .log-info { color: var(--accent); }
259
+ .log-warn { color: #d29922; }
260
+
261
+ /* --- ACTION BUTTONS --- */
262
+ .btn {
263
+ display: inline-flex;
264
+ align-items: center;
265
+ justify-content: center;
266
+ gap: 8px;
267
+ padding: 10px 20px;
268
+ border-radius: var(--radius-md);
269
+ font-weight: 600;
270
+ cursor: pointer;
271
+ border: none;
272
+ transition: all 0.2s;
273
+ font-size: 0.95rem;
274
+ }
275
+
276
+ .btn-primary {
277
+ background-color: var(--primary);
278
+ color: white;
279
+ }
280
+
281
+ .btn-primary:hover {
282
+ background-color: var(--primary-hover);
283
+ }
284
+
285
+ .btn-primary:disabled {
286
+ background-color: #23863680;
287
+ cursor: not-allowed;
288
+ }
289
+
290
+ .btn-secondary {
291
+ background-color: transparent;
292
+ border: 1px solid var(--border-color);
293
+ color: var(--text-main);
294
+ }
295
+
296
+ .btn-secondary:hover {
297
+ border-color: var(--text-muted);
298
+ background-color: rgba(255,255,255,0.05);
299
+ }
300
+
301
+ /* --- GRADIO PREVIEW --- */
302
+ .gradio-sim {
303
+ border: 2px dashed var(--border-color);
304
+ border-radius: var(--radius-lg);
305
+ padding: 30px;
306
+ text-align: center;
307
+ color: var(--text-muted);
308
+ position: relative;
309
+ background: rgba(255,255,255,0.02);
310
+ }
311
+
312
+ .gradio-active {
313
+ border-style: solid;
314
+ border-color: var(--accent);
315
+ background: rgba(88, 166, 255, 0.05);
316
+ color: var(--text-main);
317
+ }
318
+
319
+ .status-badge {
320
+ display: inline-flex;
321
+ align-items: center;
322
+ gap: 6px;
323
+ padding: 4px 10px;
324
+ border-radius: 12px;
325
+ font-size: 0.75rem;
326
+ font-weight: 600;
327
+ background: rgba(110, 118, 129, 0.2);
328
+ }
329
+
330
+ .status-running {
331
+ background: rgba(46, 160, 67, 0.2);
332
+ color: #3fb950;
333
+ }
334
+
335
+ /* --- RESPONSIVE --- */
336
+ @media (max-width: 768px) {
337
+ .layout {
338
+ grid-template-columns: 1fr;
339
+ grid-template-rows: auto 1fr;
340
+ }
341
+ aside {
342
+ border-right: none;
343
+ border-bottom: 1px solid var(--border-color);
344
+ max-height: 300px;
345
+ }
346
+ }
347
+ </style>
348
+ </head>
349
+ <body>
350
+
351
+ <header>
352
+ <div class="brand">
353
+ <i class="ph ph-cube-transparent"></i>
354
+ <span>AutoDockerizer</span>
355
+ </div>
356
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
357
+ Built with anycoder <i class="ph ph-arrow-up-right"></i>
358
+ </a>
359
+ </header>
360
+
361
+ <div class="layout">
362
+ <!-- SIDEBAR: CONFIGURATION -->
363
+ <aside>
364
+ <div class="config-group">
365
+ <h3><i class="ph ph-gear"></i> Environment</h3>
366
+ <div class="form-control">
367
+ <label>Python Version</label>
368
+ <select id="pythonVersion">
369
+ <option value="3.10">Python 3.10</option>
370
+ <option value="3.11" selected>Python 3.11</option>
371
+ <option value="3.12">Python 3.12</option>
372
+ </select>
373
+ </div>
374
+ <div class="form-control">
375
+ <label>Base Image</label>
376
+ <select id="baseImage">
377
+ <option value="python/slim">Python Slim</option>
378
+ <option value="nvidia/cuda">CUDA (GPU)</option>
379
+ <option value="ubuntu">Ubuntu Latest</option>
380
+ </select>
381
+ </div>
382
+ </div>
383
+
384
+ <div class="config-group">
385
+ <h3><i class="ph ph-brackets-curly"></i> Gradio Config</h3>
386
+ <div class="form-control">
387
+ <label>App Title</label>
388
+ <input type="text" id="appTitle" value="My AI Demo">
389
+ </div>
390
+ <div class="form-control">
391
+ <label>Model ID (Hugging Face)</label>
392
+ <input type="text" id="modelId" placeholder="e.g. gpt2">
393
+ </div>
394
+ </div>
395
+
396
+ <div class="config-group">
397
+ <h3><i class="ph ph-sliders"></i> Parameters</h3>
398
+ <div class="form-control">
399
+ <label>Max Tokens</label>
400
+ <div class="range-wrapper">
401
+ <input type="range" min="64" max="4096" value="512" id="maxTokens">
402
+ <span class="range-value" id="val-maxTokens">512</span>
403
+ </div>
404
+ </div>
405
+ <div class="form-control">
406
+ <label>Temperature</label>
407
+ <div class="range-wrapper">
408
+ <input type="range" min="0" max="1" step="0.1" value="0.7" id="temperature">
409
+ <span class="range-value" id="val-temperature">0.7</span>
410
+ </div>
411
+ </div>
412
+ </div>
413
+
414
+ <div class="config-group">
415
+ <h3><i class="ph ph-file-code"></i> Actions</h3>
416
+ <button class="btn btn-primary" style="width: 100%" onclick="runDeployment()">
417
+ <i class="ph ph-rocket-launch"></i> Build & Deploy
418
+ </button>
419
+ </div>
420
+ </aside>
421
+
422
+ <!-- MAIN CONTENT -->
423
+ <main>
424
+ <!-- Dockerfile Preview -->
425
+ <section class="card">
426
+ <div class="card-header">
427
+ <div class="card-title">
428
+ <i class="ph ph-docker-logo"></i> Generated Dockerfile
429
+ </div>
430
+ <div class="status-badge">Auto-generated</div>
431
+ </div>
432
+ <div class="code-block" id="dockerfileOutput">
433
+ <button class="copy-btn" onclick="copyDockerfile()">Copy</button>
434
+ <!-- Content injected via JS -->
435
+ </div>
436
+ </section>
437
+
438
+ <!-- Terminal & Status -->
439
+ <section class="card">
440
+ <div class="card-header">
441
+ <div class="card-title">
442
+ <i class="ph ph-terminal-window"></i> Build Terminal
443
+ </div>
444
+ <div id="buildStatus" class="status-badge">Waiting for input...</div>
445
+ </div>
446
+ <div class="terminal" id="terminalOutput">
447
+ <div class="log-line"><span class="log-time">[System]</span> Ready to initialize build process.</div>
448
+ </div>
449
+ </section>
450
+
451
+ <!-- Gradio Simulation -->
452
+ <section class="card">
453
+ <div class="card-header">
454
+ <div class="card-title">
455
+ <i class="ph ph-monitor-play"></i> Gradio Live Preview
456
+ </div>
457
+ </div>
458
+ <div class="gradio-sim" id="gradioPreview">
459
+ <i class="ph ph-cloud-arrow-up" style="font-size: 3rem; margin-bottom: 10px; display: block;"></i>
460
+ <p>Click "Build & Deploy" to start the container and launch the Gradio interface.</p>
461
+ <div style="margin-top: 15px; opacity: 0.5; font-size: 0.8rem;">
462
+ Running on http://127.0.0.1:7860
463
+ </div>
464
+ </div>
465
+ </section>
466
+ </main>
467
+ </div>
468
+
469
+ <script>
470
+ // --- DOM ELEMENTS ---
471
+ const inputs = {
472
+ python: document.getElementById('pythonVersion'),
473
+ base: document.getElementById('baseImage'),
474
+ title: document.getElementById('appTitle'),
475
+ model: document.getElementById('modelId'),
476
+ tokens: document.getElementById('maxTokens'),
477
+ temp: document.getElementById('temperature')
478
+ };
479
+
480
+ const displays = {
481
+ tokens: document.getElementById('val-maxTokens'),
482
+ temp: document.getElementById('val-temperature')
483
+ };
484
+
485
+ const outputs = {
486
+ dockerfile: document.getElementById('dockerfileOutput'),
487
+ terminal: document.getElementById('terminalOutput'),
488
+ status: document.getElementById('buildStatus'),
489
+ preview: document.getElementById('gradioPreview')
490
+ };
491
+
492
+ // --- EVENT LISTENERS FOR LIVE UPDATES ---
493
+ Object.values(inputs).forEach(input => {
494
+ input.addEventListener('input', updateDockerfile);
495
+ });
496
+
497
+ // Update slider values immediately
498
+ inputs.tokens.addEventListener('input', (e) => displays.tokens.textContent = e.target.value);
499
+ inputs.temp.addEventListener('input', (e) => displays.temp.textContent = e.target.value);
500
+
501
+ // --- CORE FUNCTIONS ---
502
+
503
+ function updateDockerfile() {
504
+ const pyVer = inputs.python.value;
505
+ const base = inputs.base.value;
506
+ const title = inputs.title.value || 'My AI Demo';
507
+ const model = inputs.model.value || 'gpt2';
508
+
509
+ // Logic to select appropriate base image string
510
+ let fromString = `python:${pyVer}-slim`;
511
+ if (base.includes('cuda')) fromString = `nvidia/cuda:11.8.0-runtime-ubuntu${pyVer > 11 ? '22.04' : '20.04'}`;
512
+ if (base.includes('ubuntu')) fromString = `ubuntu:latest`;
513
+
514
+ const dockerfileContent = `# Auto-generated Dockerfile for Gradio App
515
+ FROM ${fromString}
516
+
517
+ # Set working directory
518
+ WORKDIR /app
519
+
520
+ # Install system dependencies
521
+ RUN apt-get update && apt-get install -y \\
522
+ git \\
523
+ git-lfs \\
524
+ && rm -rf /var/lib/apt/lists/*
525
+
526
+ # Copy requirements file (simulated)
527
+ RUN pip install --no-cache-dir -U pip
528
+ RUN pip install gradio torch transformers accelerate
529
+
530
+ # Set environment variables
531
+ ENV MODEL_ID="${model}"
532
+ ENV MAX_TOKENS=${inputs.tokens.value}
533
+ ENV TEMPERATURE=${inputs.temp.value}
534
+ APP_TITLE="${title}"
535
+
536
+ # Copy application code
537
+ COPY app.py .
538
+
539
+ # Expose port
540
+ EXPOSE 7860
541
+
542
+ # Run Gradio app
543
+ CMD ["python", "app.py"]
544
+ `;
545
+
546
+ // Preserve the copy button, replace text content
547
+ const btn = outputs.dockerfile.querySelector('.copy-btn');
548
+ outputs.dockerfile.innerHTML = '';
549
+ outputs.dockerfile.appendChild(btn);
550
+ outputs.dockerfile.appendChild(document.createTextNode(dockerfileContent));
551
+ }
552
+
553
+ function copyDockerfile() {
554
+ const text = outputs.dockerfile.textContent.replace('Copy', '').trim();
555
+ navigator.clipboard.writeText(text).then(() => {
556
+ const btn = outputs.dockerfile.querySelector('.copy-btn');
557
+ const originalText = btn.textContent;
558
+ btn.textContent = 'Copied!';
559
+ setTimeout(() => btn.textContent = originalText, 2000);
560
+ });
561
+ }
562
+
563
+ function addLog(message, type = 'info') {
564
+ const line = document.createElement('div');
565
+ line.className = 'log-line';
566
+
567
+ const time = new Date().toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute:'2-digit', second:'2-digit' });
568
+
569
+ let typeClass = 'log-info';
570
+ if(type === 'success') typeClass = 'log-success';
571
+ if(type === 'warn') typeClass = 'log-warn';
572
+
573
+ line.innerHTML = `<span class="log-time">[${time}]</span> <span class="${typeClass}">${message}</span>`;
574
+ outputs.terminal.appendChild(line);
575
+ outputs.terminal.scrollTop = outputs.terminal.scrollHeight;
576
+ }
577
+
578
+ async function runDeployment() {
579
+ // Reset state
580
+ outputs.terminal.innerHTML = '';
581
+ outputs.status.textContent = 'Building...';
582
+ outputs.status.className = 'status-badge';
583
+ outputs.preview.classList.remove('gradio-active');
584
+ outputs.preview.innerHTML = `
585
+ <i class="ph ph-spinner ph-spin" style="font-size: 3rem; margin-bottom: 10px; display: block;"></i>
586
+ <p>Initializing Container...</p>
587
+ `;
588
+
589
+ const steps = [
590
+ { msg: "Pulling base image...", delay: 800 },
591
+ { msg: "Installing system dependencies (git, lfs)...", delay: 1500 },
592
+ { msg: "Upgrading pip...", delay: 1000 },
593
+ { msg: "Installing Python packages (gradio, torch)...", delay: 2500 },
594
+ { msg: "Downloading model weights...", delay: 2000 },
595
+ { msg: "Exposing port 7860...", delay: 500 },
596
+ { msg: "Starting Gradio interface...", delay: 800, type: 'success' }
597
+ ];
598
+
599
+ for (let step of steps) {
600
+ await new Promise(r => setTimeout(r, step.delay));
601
+ addLog(step.msg, step.type || 'info');
602
+ }
603
+
604
+ // Final State
605
+ outputs.status.textContent = 'Running';
606
+ outputs.status.className = 'status-badge status-running';
607
+
608
+ // Update Preview UI
609
+ const title = inputs.title.value;
610
+ outputs.preview.classList.add('gradio-active');
611
+ outputs.preview.innerHTML = `
612
+ <div style="text-align: left; max-width: 600px; margin: 0 auto;">
613
+ <h2 style="margin-bottom: 20px; color: var(--accent);">${title}</h2>
614
+ <div style="background: var(--bg-input); padding: 15px; border-radius: 8px; border: 1px solid var(--border-color); margin-bottom: 15px;">
615
+ <label style="display:block; margin-bottom:5px; font-size:0.8rem;">Input Prompt</label>
616
+ <input type="text" placeholder="Type something here..." style="width:100%; background:transparent; border:none; color:white; outline:none;">
617
+ </div>
618
+ <button class="btn btn-secondary" style="width:100%;">Submit</button>
619
+ <div style="margin-top: 20px; padding: 15px; background: rgba(46, 160, 67, 0.1); border: 1px solid var(--primary); border-radius: 8px; color: var(--primary);">
620
+ <i class="ph ph-check-circle"></i> Output will appear here.
621
+ </div>
622
+ </div>
623
+ <div style="margin-top: 20px; font-size: 0.8rem; color: var(--text-muted);">
624
+ <i class="ph ph-share-network"></i> Public URL: https://huggingface.co/spaces/user/${title.replace(/\s+/g, '-').toLowerCase()}
625
+ </div>
626
+ `;
627
+
628
+ addLog("Application successfully deployed.", "success");
629
+ }
630
+
631
+ // Initialize on load
632
+ updateDockerfile();
633
+
634
+ </script>
635
+ </body>
636
+ </html>