Vedika commited on
Commit
7c7c340
·
verified ·
1 Parent(s): 9a6dab9

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +182 -285
index.html CHANGED
@@ -1,3 +1,4 @@
 
1
  <!DOCTYPE html>
2
  <html lang="en" dir="ltr">
3
  <head>
@@ -65,7 +66,7 @@
65
  --border-light: rgba(255, 255, 255, 0.12);
66
  --border-medium: rgba(255, 255, 255, 0.25);
67
 
68
- /* Shadows & Elevation (Dark mode needs tighter shadows) */
69
  --shadow-xs: 0 1px 2px rgba(0,0,0,0.5);
70
  --shadow-sm: 0 4px 12px rgba(0,0,0,0.5);
71
  --shadow-md: 0 8px 24px rgba(0,0,0,0.6);
@@ -75,7 +76,6 @@
75
  /* Font Families */
76
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
77
  --font-mono: 'Geist Mono', Consolas, Monaco, monospace;
78
- --font-serif: 'Instrument Serif', Georgia, serif;
79
 
80
  /* Radii */
81
  --radius-sm: 8px;
@@ -98,7 +98,6 @@
98
  --z-workspace: 200;
99
  --z-modal: 5000;
100
  --z-toast: 9000;
101
- --z-live: 9999;
102
  }
103
 
104
  /* ---------------------------------------------------------------------------------------
@@ -283,12 +282,6 @@
283
  .pulse-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--brand-green); box-shadow: 0 0 0 3px rgba(19, 136, 8, 0.3); animation: statusPulse 2s infinite; }
284
  @keyframes statusPulse { 0% { box-shadow: 0 0 0 0 rgba(19,136,8,0.6); } 70% { box-shadow: 0 0 0 6px rgba(19,136,8,0); } 100% { box-shadow: 0 0 0 0 rgba(19,136,8,0); } }
285
 
286
- /* LIVE MODE ACTIVATOR */
287
- .btn-activate-live { background: linear-gradient(135deg, #ff453a 0%, #c41e15 100%); color: white; border: none; padding: 10px 22px; border-radius: var(--radius-full); font-size: 14px; font-weight: 800; display: flex; align-items: center; gap: 8px; cursor: pointer; box-shadow: 0 4px 15px rgba(255, 69, 58, 0.4); transition: var(--ease-spring); letter-spacing: 0.5px; border: 1px solid rgba(255,255,255,0.2); }
288
- .btn-activate-live:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 8px 25px rgba(255, 69, 58, 0.6); }
289
- .btn-activate-live svg { width: 18px; height: 18px; animation: liveBlink 1.5s infinite; }
290
- @keyframes liveBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
291
-
292
  /* Chat Scrollable Area */
293
  .chat-scroll-area { flex: 1; overflow-y: auto; padding: 40px 10%; display: flex; flex-direction: column; gap: 36px; scroll-behavior: smooth; position: relative; }
294
 
@@ -350,9 +343,6 @@
350
  .btn-bot-action { background: rgba(255,255,255,0.05); border: 1px solid var(--border-light); color: var(--text-secondary); font-size: 13px; font-weight: 700; cursor: pointer; display: flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: var(--radius-full); transition: var(--ease-fast); backdrop-filter: blur(10px); }
351
  .btn-bot-action:hover { background: rgba(255,255,255,0.15); color: var(--text-primary); transform: translateY(-2px); box-shadow: var(--shadow-sm); border-color: rgba(255,255,255,0.3); }
352
  .btn-bot-action svg { width: 16px; height: 16px; }
353
-
354
- .btn-bot-action.action-tts { color: #32d74b; border-color: rgba(50, 215, 75, 0.3); background: rgba(50, 215, 75, 0.1); }
355
- .btn-bot-action.action-tts:hover { background: rgba(50, 215, 75, 0.2); }
356
 
357
  /* Markdown Rendering inside Bubbles */
358
  .chat-bubble p { margin-bottom: 16px; }
@@ -438,14 +428,25 @@
438
 
439
  .bottom-branding-text { text-align: center; font-size: 12px; color: var(--text-tertiary); margin-top: 16px; font-weight: 600; letter-spacing: 0.5px; }
440
 
 
 
 
 
 
441
  /* ---------------------------------------------------------------------------------------
442
- J. WORKSPACE PRO (DARK COMPILER PANEL)
443
  --------------------------------------------------------------------------------------- */
444
  .code-workspace-panel { width: 0; background: #000000; border-left: 1px solid var(--border-light); display: flex; flex-direction: column; transition: width var(--ease-smooth); overflow: hidden; box-shadow: -15px 0 40px rgba(0,0,0,0.8); z-index: var(--z-workspace); }
445
  .code-workspace-panel.expanded { width: 55%; }
446
 
447
- .workspace-header-bar { padding: 16px 24px; border-bottom: 1px solid #333; background: #111; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; }
448
- .workspace-title-group { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 10px; color: #abb2bf; font-family: var(--font-mono); letter-spacing: 0.5px;}
 
 
 
 
 
 
449
  .workspace-tools { display: flex; gap: 10px; }
450
 
451
  .btn-workspace-tool { padding: 8px 16px; border-radius: var(--radius-sm); background: #222; border: 1px solid #333; cursor: pointer; display: flex; align-items: center; gap: 8px; color: #fff; transition: var(--ease-fast); font-size: 13px; font-weight: 600; }
@@ -456,42 +457,16 @@
456
 
457
  .workspace-editor-surface { flex: 1; overflow-y: auto; background: #000; padding: 24px; position: relative; }
458
  .workspace-editor-surface pre { margin: 0; padding: 0; background: transparent; font-family: var(--font-mono); font-size: 15px; line-height: 1.6; overflow-x: auto; color: #abb2bf; border: none; box-shadow: none;}
459
-
460
- /* ---------------------------------------------------------------------------------------
461
- K. LIVE MODE FULLSCREEN OVERLAY
462
- --------------------------------------------------------------------------------------- */
463
- .live-mode-viewport { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.95); backdrop-filter: blur(40px); z-index: var(--z-live); display: flex; flex-direction: column; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity var(--ease-smooth); }
464
- .live-mode-viewport.active { opacity: 1; pointer-events: auto; }
465
- .btn-close-live { position: absolute; top: 40px; right: 40px; background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); width: 56px; height: 56px; border-radius: 50%; font-size: 24px; cursor: pointer; transition: var(--ease-spring); display: flex; align-items: center; justify-content: center; color: var(--text-primary); }
466
- .btn-close-live:hover { background: rgba(255, 69, 58, 0.2); color: var(--text-error); transform: rotate(90deg); border-color: transparent; }
467
 
468
- .pulsing-orb-wrapper { position: relative; width: 250px; height: 250px; display: flex; align-items: center; justify-content: center; margin-bottom: 50px; }
469
- .energy-core { width: 120px; height: 120px; border-radius: 50%; background: linear-gradient(135deg, var(--brand-saffron), var(--brand-green)); box-shadow: 0 0 50px rgba(19, 136, 8, 0.8); position: relative; z-index: 2; transition: transform 0.15s ease-out; }
470
- .energy-core.speaking { animation: coreSpeak 0.5s infinite alternate; }
471
- @keyframes coreSpeak { 0% { transform: scale(1); box-shadow: 0 0 30px rgba(19,136,8,0.6); } 100% { transform: scale(1.1); box-shadow: 0 0 60px rgba(255,153,51,0.8); } }
472
-
473
- .energy-ring { position: absolute; inset: 0; border: 3px solid var(--brand-saffron); border-radius: 50%; opacity: 0; animation: energyRipple 2.5s cubic-bezier(0.4, 0, 0.2, 1) infinite; }
474
- .energy-ring:nth-child(2) { animation-delay: 0.8s; border-color: var(--brand-green); }
475
- .energy-ring:nth-child(3) { animation-delay: 1.6s; border-color: rgba(255,255,255,0.5); }
476
- @keyframes energyRipple { 0% { transform: scale(0.4); opacity: 1; border-width: 6px; } 100% { transform: scale(1.6); opacity: 0; border-width: 1px; } }
477
-
478
- .live-feedback-status { font-size: 28px; font-weight: 900; color: var(--text-primary); margin-bottom: 16px; font-family: var(--font-sans); letter-spacing: -0.5px; text-shadow: 0 2px 10px rgba(0,0,0,0.5); }
479
- .live-feedback-text { font-size: 18px; color: var(--text-secondary); max-width: 700px; text-align: center; line-height: 1.6; min-height: 60px; font-weight: 500; padding: 0 20px; }
480
-
481
- .live-control-deck { display: flex; gap: 24px; margin-top: 50px; }
482
- .btn-live-deck { width: 80px; height: 80px; border-radius: 50%; border: none; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: var(--shadow-lg); transition: var(--ease-spring); }
483
- .btn-live-deck.mic-control { background: rgba(255,255,255,0.1); border: 2px solid rgba(255,255,255,0.3); color: var(--text-primary); backdrop-filter: blur(10px); }
484
- .btn-live-deck.mic-control:hover { transform: translateY(-6px); border-color: var(--brand-saffron); color: var(--brand-saffron); box-shadow: var(--shadow-xl); background: rgba(255,255,255,0.2); }
485
- .btn-live-deck.mic-control.is-recording { background: var(--text-error); color: white; border-color: var(--text-error); animation: pulseMicLive 1.2s infinite; }
486
- @keyframes pulseMicLive { 0% { box-shadow: 0 0 0 0 rgba(255,69,58,0.6); } 70% { box-shadow: 0 0 0 20px rgba(255,69,58,0); } 100% { box-shadow: 0 0 0 0 rgba(255,69,58,0); } }
487
-
488
- /* Scroll Trigger Button */
489
- .btn-scroll-trigger { position: absolute; bottom: 150px; left: 50%; width: 48px; height: 48px; border-radius: 50%; background: rgba(28, 28, 30, 0.8); backdrop-filter: blur(25px); border: 1px solid var(--border-medium); box-shadow: var(--shadow-xl); display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--text-primary); opacity: 0; pointer-events: none; transform: translateX(-50%) translateY(20px); transition: var(--ease-smooth); z-index: 20; }
490
- .btn-scroll-trigger.visible { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
491
- .btn-scroll-trigger:hover { background: var(--text-primary); color: var(--text-inverse); transform: translateX(-50%) translateY(-5px); }
492
 
493
  /* ---------------------------------------------------------------------------------------
494
- L. AUTHENTICATION SECURE GATEWAY (MODAL)
495
  --------------------------------------------------------------------------------------- */
496
  .secure-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.8); backdrop-filter: blur(20px); z-index: var(--z-modal); display: none; justify-content: center; align-items: center; animation: fadeIn 0.3s ease; }
497
  .secure-modal-surface { background: rgba(28, 28, 30, 0.95); padding: 44px; border-radius: var(--radius-xl); width: 90%; max-width: 460px; box-shadow: 0 25px 50px -12px rgba(0,0,0,1); position: relative; border: 1px solid rgba(255,255,255,0.15); backdrop-filter: blur(30px); }
@@ -528,7 +503,7 @@
528
  @keyframes dotBounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } }
529
 
530
  /* ---------------------------------------------------------------------------------------
531
- M. RESPONSIVE DESIGN (MOBILE & TABLET ADAPTATIONS)
532
  --------------------------------------------------------------------------------------- */
533
  @media (max-width: 1024px) {
534
  .code-workspace-panel.expanded { width: 100%; position: absolute; top: 0; left: 0; height: 100%; z-index: 2000; }
@@ -570,38 +545,13 @@
570
  <img src="https://i.ibb.co/MxKsrXDj/TIRANGA-20260525-172109-0000.png" alt="CODE VED Core Identity">
571
  </div>
572
  <h1 class="startup-title">Welcome to CODE VED</h1>
573
- <p class="startup-desc">Premium AI Workspace. Experience secure code generation, high-fidelity visual rendering, and zero-latency live conversational mode.</p>
574
  <button class="btn-startup-launch" id="btnLaunchSystem">
575
  Initialize Workspace
576
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>
577
  </button>
578
  </div>
579
 
580
- <!-- =========================================================================================
581
- DOM STRUCTURE: LIVE MODE FULLSCREEN OVERLAY
582
- ========================================================================================= -->
583
- <div class="live-mode-viewport" id="liveOverlay">
584
- <button class="btn-close-live" id="btnExitLiveMode" title="Exit Live Mode">
585
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
586
- </button>
587
-
588
- <div class="pulsing-orb-wrapper">
589
- <div class="energy-ring"></div>
590
- <div class="energy-ring"></div>
591
- <div class="energy-ring"></div>
592
- <div class="energy-core" id="liveOrb"></div>
593
- </div>
594
-
595
- <div class="live-feedback-status" id="liveStatusText">Initializing Audio Stream...</div>
596
- <div class="live-feedback-text" id="liveTranscriptText">Speak directly to CODE VED. Natural language processing active.</div>
597
-
598
- <div class="live-control-deck">
599
- <button class="btn-live-deck mic-control" id="liveMicBtn">
600
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" x2="12" y1="19" y2="22"></line></svg>
601
- </button>
602
- </div>
603
- </div>
604
-
605
  <!-- =========================================================================================
606
  DOM STRUCTURE: AMBIENT BACKGROUND
607
  ========================================================================================= -->
@@ -679,12 +629,6 @@
679
  System Online
680
  </div>
681
  </div>
682
-
683
- <!-- LIVE MODE ACTIVATOR -->
684
- <button class="btn-activate-live" id="btnStartLiveMode">
685
- <svg viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5" fill="none"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="4" fill="currentColor"></circle></svg>
686
- LIVE MODE
687
- </button>
688
  </header>
689
 
690
  <!-- Scrollable Conversation Area -->
@@ -779,7 +723,7 @@
779
  <input type="file" id="sys-inp-document" class="stealth-input" accept=".pdf,.doc,.docx,.txt,.md,.csv,.json,.py,.js,.html,.css,.cpp,.c,.java">
780
  </div>
781
 
782
- <!-- Smart Language Toggle Button (Bilingual STT logic) -->
783
  <button class="language-toggle-chip" id="smartLangToggle" title="Toggle Voice Engine Language">
784
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
785
  <span id="langDisplayBadge">EN</span>
@@ -803,26 +747,39 @@
803
  </div>
804
  </main>
805
 
806
- <!-- C. WORKSPACE CODE EDITOR PANEL -->
807
  <aside class="code-workspace-panel" id="workspacePanel">
808
  <div class="workspace-header-bar">
809
- <div class="workspace-title-group">
810
- <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
811
- <span id="wsTitleText">Workspace Logic</span>
 
 
 
 
 
 
812
  </div>
813
  <div class="workspace-tools">
814
  <button class="btn-workspace-tool" id="btnWsCopy">
815
  <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
816
- Copy Source
817
  </button>
818
  <button class="btn-workspace-tool close" id="btnWsClose" title="Close Editor">
819
  <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
820
  </button>
821
  </div>
822
  </div>
823
- <div class="workspace-editor-surface">
 
 
824
  <pre><code id="workspaceCodeBlock" class="hljs"></code></pre>
825
  </div>
 
 
 
 
 
826
  </aside>
827
  </div>
828
 
@@ -881,7 +838,7 @@
881
  GAS_URL: "https://script.google.com/macros/s/AKfycbz5vrlB4GrfkfBVYdQ52IQweIXC1cNDwKuTUorxdAiOdSSIrH55mzJlaz9kq1Y94ot5/exec",
882
  LOGO_URL: "https://i.ibb.co/MxKsrXDj/TIRANGA-20260525-172109-0000.png",
883
  PDF_WORKER: 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js',
884
- API_ENDPOINT: '/api/chat', // Change to your local or deployed endpoint
885
  };
886
 
887
  pdfjsLib.GlobalWorkerOptions.workerSrc = Config.PDF_WORKER;
@@ -896,22 +853,9 @@
896
  generatedCodeBlocks: [],
897
  currentWorkspaceId: null,
898
  isStreamingActive: false,
899
- isLiveModeEngaged: false,
900
- gradioClient: null,
901
  isMicRecording: false
902
  };
903
 
904
- window.initGradioEngine = async function() {
905
- try {
906
- const module = await import("https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js");
907
- AppState.gradioClient = await module.Client.connect("Vedika66/Edge-TTS");
908
- console.log("Neural TTS Engine connected successfully to Gradio.");
909
- } catch(err) {
910
- console.error("Gradio Connection Error:", err);
911
- }
912
- };
913
- window.initGradioEngine();
914
-
915
  // =======================================================================================
916
  // 2. UTILITY ENGINE
917
  // =======================================================================================
@@ -929,21 +873,6 @@
929
  return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
930
  },
931
 
932
- cleanTextForVoice: (rawText) => {
933
- if(!rawText) return "";
934
- let cleaned = rawText;
935
-
936
- cleaned = cleaned.replace(/```[\s\S]*?```/g, '');
937
- cleaned = cleaned.replace(/`.*?`/g, '');
938
- cleaned = cleaned.replace(/!\[.*?\]\(.*?\)/g, '');
939
- cleaned = cleaned.replace(/\[(.*?)\]\(.*?\)/g, '$1');
940
- cleaned = cleaned.replace(/<think>[\s\S]*?<\/think>/gi, '');
941
- cleaned = cleaned.replace(/https?:\/\/[^\s]+/g, '');
942
- cleaned = cleaned.replace(/[*_~#]/g, '');
943
-
944
- return cleaned.trim();
945
- },
946
-
947
  executeFallbackCopy: (text, btnElement) => {
948
  const textArea = document.createElement("textarea");
949
  textArea.value = text;
@@ -982,7 +911,7 @@
982
  };
983
 
984
  // =======================================================================================
985
- // 3. AUTHENTICATION & SYNC MANAGER
986
  // =======================================================================================
987
  const AuthManager = {
988
  initUI: () => {
@@ -1050,9 +979,9 @@
1050
  triggerBtn.innerText = 'Establishing Connection...';
1051
 
1052
  try {
 
1053
  const response = await fetch(Config.GAS_URL, {
1054
- method: 'POST',
1055
- mode: 'cors',
1056
  headers: { 'Content-Type': 'text/plain;charset=utf-8' },
1057
  body: JSON.stringify(payload)
1058
  });
@@ -1068,12 +997,13 @@
1068
  localStorage.setItem('codeved_user', AppState.currentUser);
1069
  AuthManager.closeModal();
1070
  AuthManager.initUI();
1071
- ChatEngine.syncHistoryFromCloud();
1072
  }
1073
  } else {
1074
  Utils.showToast(result.message);
1075
  }
1076
  } catch (error) {
 
1077
  Utils.showToast("Encrypted gateway error. Check network.");
1078
  }
1079
 
@@ -1127,7 +1057,7 @@
1127
  };
1128
 
1129
  // =======================================================================================
1130
- // 5. SPEECH & TTS ENGINE
1131
  // =======================================================================================
1132
  const VoiceEngine = {
1133
  recognition: null,
@@ -1149,14 +1079,7 @@
1149
  if(VoiceEngine.sessionTranscript && !VoiceEngine.sessionTranscript.endsWith(' ')) {
1150
  VoiceEngine.sessionTranscript += ' ';
1151
  }
1152
-
1153
  document.getElementById('masterVoiceBtn').classList.add('active-listening');
1154
- if (AppState.isLiveModeEngaged) {
1155
- document.getElementById('liveMicBtn').classList.add('is-recording');
1156
- document.getElementById('liveStatusText').innerText = "Listening...";
1157
- document.getElementById('liveOrb').classList.remove('speaking');
1158
- document.getElementById('liveOrb').style.transform = "scale(1.25)";
1159
- }
1160
  };
1161
 
1162
  VoiceEngine.recognition.onresult = (event) => {
@@ -1176,35 +1099,19 @@
1176
  currentDictation = currentDictation.charAt(0).toUpperCase() + currentDictation.slice(1);
1177
  }
1178
 
1179
- if (AppState.isLiveModeEngaged) {
1180
- document.getElementById('liveTranscriptText').innerText = `"${currentDictation}"`;
1181
- if(finalTranscript.trim().length > 0) {
1182
- document.getElementById('liveStatusText').innerText = "Synthesizing...";
1183
- document.getElementById('mainChatInput').value = finalTranscript.trim();
1184
- VoiceEngine.recognition.stop();
1185
- ChatEngine.initiateDispatch();
1186
- }
1187
- } else {
1188
- const inputField = document.getElementById('mainChatInput');
1189
- inputField.value = VoiceEngine.sessionTranscript + currentDictation;
1190
- UIManager.autoGrowTextArea(inputField);
1191
-
1192
- if(finalTranscript.trim().length > 0) {
1193
- VoiceEngine.sessionTranscript = inputField.value;
1194
- if(!VoiceEngine.sessionTranscript.endsWith(' ')) VoiceEngine.sessionTranscript += ' ';
1195
- }
1196
  }
1197
  };
1198
 
1199
  VoiceEngine.recognition.onend = () => {
1200
  AppState.isMicRecording = false;
1201
  document.getElementById('masterVoiceBtn').classList.remove('active-listening');
1202
-
1203
- if (AppState.isLiveModeEngaged && !AppState.isProcessing) {
1204
- document.getElementById('liveMicBtn').classList.remove('is-recording');
1205
- document.getElementById('liveStatusText').innerText = "Tap mic to interact";
1206
- document.getElementById('liveOrb').style.transform = "scale(1)";
1207
- }
1208
  };
1209
 
1210
  VoiceEngine.recognition.onerror = (event) => {
@@ -1213,10 +1120,6 @@
1213
  Utils.showToast("Voice module error: " + event.error);
1214
  }
1215
  document.getElementById('masterVoiceBtn').classList.remove('active-listening');
1216
- if (AppState.isLiveModeEngaged) {
1217
- document.getElementById('liveMicBtn').classList.remove('is-recording');
1218
- document.getElementById('liveStatusText').innerText = "Audio Failure. Retry.";
1219
- }
1220
  };
1221
  },
1222
 
@@ -1254,89 +1157,11 @@
1254
  VoiceEngine.recognition.start();
1255
  }
1256
  } catch (e) { console.error("Mic Start Error", e); }
1257
- },
1258
-
1259
- executeTTS: async (rawText) => {
1260
- const cleanSpeechText = Utils.cleanTextForVoice(rawText);
1261
-
1262
- if(!cleanSpeechText.trim()) {
1263
- if (AppState.isLiveModeEngaged) {
1264
- document.getElementById('liveOrb').classList.remove('speaking');
1265
- document.getElementById('liveStatusText').innerText = "Tap mic to respond";
1266
- setTimeout(()=> VoiceEngine.toggleDictation(), 800);
1267
- }
1268
- return;
1269
- }
1270
-
1271
- Utils.showToast("🔊 Linking with Neural Voice Matrix...");
1272
- if (AppState.isLiveModeEngaged) {
1273
- document.getElementById('liveOrb').classList.add('speaking');
1274
- }
1275
-
1276
- try {
1277
- if(!AppState.gradioClient) {
1278
- const module = await import("https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js");
1279
- AppState.gradioClient = await module.Client.connect("Vedika66/Edge-TTS");
1280
- }
1281
-
1282
- const result = await AppState.gradioClient.predict("/smart_hybrid_tts", {
1283
- text: cleanSpeechText,
1284
- voice_type: "प्रभात (भारी और प्राकृतिक आवाज़ - हिंग्लिश के लिए)"
1285
- });
1286
-
1287
- if (result.data && result.data[0]) {
1288
- const audioUrl = typeof result.data[0] === 'string' ? result.data[0] : result.data[0].url;
1289
- const audio = new Audio(audioUrl);
1290
-
1291
- audio.onended = () => {
1292
- if (AppState.isLiveModeEngaged) {
1293
- document.getElementById('liveOrb').classList.remove('speaking');
1294
- document.getElementById('liveStatusText').innerText = "Listening...";
1295
- VoiceEngine.toggleDictation();
1296
- }
1297
- };
1298
-
1299
- audio.play().catch(e => {
1300
- Utils.showToast("Autoplay blocked. Please interact with the page.");
1301
- if (AppState.isLiveModeEngaged) document.getElementById('liveOrb').classList.remove('speaking');
1302
- });
1303
- } else {
1304
- throw new Error("No audio payload returned.");
1305
- }
1306
- } catch (error) {
1307
- Utils.showToast("Voice Neural Matrix is currently overloaded.");
1308
- console.error("Gradio TTS Error:", error);
1309
- if (AppState.isLiveModeEngaged) {
1310
- document.getElementById('liveOrb').classList.remove('speaking');
1311
- }
1312
- }
1313
- }
1314
- };
1315
-
1316
- // =======================================================================================
1317
- // 6. LIVE MODE CONTROLLER
1318
- // =======================================================================================
1319
- const LiveModeController = {
1320
- initialize: () => {
1321
- AppState.isLiveModeEngaged = true;
1322
- document.getElementById('liveOverlay').classList.add('active');
1323
- if (VoiceEngine.recognition && !AppState.isMicRecording) {
1324
- setTimeout(() => {
1325
- try { VoiceEngine.recognition.start(); } catch(e){}
1326
- }, 500);
1327
- }
1328
- },
1329
- terminate: () => {
1330
- AppState.isLiveModeEngaged = false;
1331
- document.getElementById('liveOverlay').classList.remove('active');
1332
- if (VoiceEngine.recognition && AppState.isMicRecording) {
1333
- try { VoiceEngine.recognition.stop(); } catch(e){}
1334
- }
1335
  }
1336
  };
1337
 
1338
  // =======================================================================================
1339
- // 7. FILE PROCESSOR
1340
  // =======================================================================================
1341
  const FileProcessor = {
1342
  triggerFileSelector: (type) => {
@@ -1440,14 +1265,101 @@
1440
  };
1441
 
1442
  // =======================================================================================
1443
- // 8. WORKSPACE ENGINE & MARKDOWN
1444
  // =======================================================================================
1445
- const WorkspaceEngine = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1446
  launch: (codeBlockId) => {
1447
  AppState.currentWorkspaceId = codeBlockId;
1448
  const codeData = AppState.generatedCodeBlocks[codeBlockId];
1449
 
1450
- document.getElementById('wsTitleText').innerText = codeData.lang ? `Generated ${codeData.lang.toUpperCase()}` : "Compiled Code";
1451
  const blockDisplay = document.getElementById('workspaceCodeBlock');
1452
  blockDisplay.className = `hljs language-${codeData.lang || 'plaintext'}`;
1453
  blockDisplay.textContent = codeData.code;
@@ -1455,6 +1367,9 @@
1455
  hljs.highlightElement(blockDisplay);
1456
  document.getElementById('workspacePanel').classList.add('expanded');
1457
 
 
 
 
1458
  if (window.innerWidth <= 1024) {
1459
  document.getElementById('sidebar').classList.remove('active');
1460
  }
@@ -1508,12 +1423,12 @@
1508
  document.getElementById('msgs').addEventListener('click', function(e) {
1509
  if (e.target && e.target.classList.contains('btn-launch-ws')) {
1510
  const blockId = e.target.getAttribute('data-id');
1511
- WorkspaceEngine.launch(blockId);
1512
  }
1513
  });
1514
 
1515
  // =======================================================================================
1516
- // 9. CORE CHAT ENGINE & LLM
1517
  // =======================================================================================
1518
  const ChatEngine = {
1519
  handleKeyboard: (e) => {
@@ -1534,7 +1449,6 @@
1534
  try {
1535
  await fetch(Config.GAS_URL, {
1536
  method: 'POST',
1537
- mode: 'cors',
1538
  headers: { 'Content-Type': 'text/plain;charset=utf-8' },
1539
  body: JSON.stringify({ action: "delete_history", email: AppState.currentUser })
1540
  });
@@ -1543,6 +1457,7 @@
1543
  location.reload();
1544
  },
1545
 
 
1546
  syncHistoryFromCloud: async () => {
1547
  const messageZone = document.getElementById('msgs');
1548
  document.getElementById('welcomeState').style.display = 'none';
@@ -1550,11 +1465,11 @@
1550
 
1551
  try {
1552
  const response = await fetch(Config.GAS_URL, {
1553
- method: 'POST',
1554
- mode: 'cors',
1555
  headers: { 'Content-Type': 'text/plain;charset=utf-8' },
1556
  body: JSON.stringify({ action: "get_history", email: AppState.currentUser })
1557
  });
 
1558
  const resData = await response.json();
1559
  messageZone.innerHTML = '';
1560
 
@@ -1573,19 +1488,22 @@
1573
  document.getElementById('welcomeState').style.display = 'flex';
1574
  }
1575
  } catch (err) {
 
1576
  messageZone.innerHTML = '';
1577
  document.getElementById('welcomeState').style.display = 'flex';
1578
  }
1579
  },
1580
 
 
1581
  saveHistoryToCloud: () => {
1582
  if (AppState.currentUser) {
1583
- fetch(Config.GAS_URL, {
1584
- method: 'POST',
1585
- mode: 'cors',
1586
- headers: { 'Content-Type': 'text/plain;charset=utf-8' },
1587
- body: JSON.stringify({ action: "save_history", email: AppState.currentUser, historyJSON: JSON.stringify(AppState.history) })
1588
- });
 
1589
  }
1590
  },
1591
 
@@ -1653,26 +1571,20 @@
1653
  let actionTray = bubbleDOM.querySelector('.bot-actions-row');
1654
  if (!isCurrentlyStreaming && !actionTray && strippedMarkup.trim().length > 0) {
1655
  const safeRawCopy = strippedMarkup.replace(/"/g, '&quot;').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '');
1656
- const safeRawTTS = strippedMarkup.replace(/"/g, '&quot;').replace(/'/g, "\\'").replace(/\n/g, ' ');
1657
-
1658
  const actionsHTML = `
1659
  <div class="bot-actions-row">
1660
  <button class="btn-bot-action btn-cpy-action" data-cpy="${safeRawCopy}">
1661
  <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
1662
  Copy Data
1663
  </button>
1664
- <button class="btn-bot-action action-tts btn-tts-action" data-tts="${safeRawTTS}">
1665
- <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path></svg>
1666
- Read Aloud
1667
- </button>
1668
  </div>`;
1669
  bubbleDOM.querySelector('.msg-content-column').insertAdjacentHTML('beforeend', actionsHTML);
1670
-
1671
  bubbleDOM.querySelector('.btn-cpy-action').addEventListener('click', function() { Utils.copyToClipboard(this, this.getAttribute('data-cpy')); });
1672
- bubbleDOM.querySelector('.btn-tts-action').addEventListener('click', function() { VoiceEngine.executeTTS(this.getAttribute('data-tts')); });
1673
  }
1674
  },
1675
 
 
1676
  initiateDispatch: async () => {
1677
  if (AppState.isProcessing) return;
1678
 
@@ -1745,11 +1657,6 @@
1745
  Available Models: flux, flux-realism, flux-anime, flux-3d.
1746
  CRITICAL: The seed parameter is mandatory to bypass cache mechanics. Always render this markdown node.`;
1747
 
1748
- if (AppState.isLiveModeEngaged) {
1749
- cognitivePrompt += `\n\n[LIVE ACOUSTIC OVERRIDE]: You are currently engaged in a LIVE, REAL-TIME VOCAL INTERFACE.
1750
- MANDATORY direct answers. Maximum brevity. Eliminate complex markdown, massive code blocks, or extended lists. Replicate human telephonic brevity perfectly.`;
1751
- }
1752
-
1753
  const secureHistory = AppState.history.slice(0, -1).map(h => ({ role: h.role, content: h.content }));
1754
 
1755
  const transmissionPayload = {
@@ -1757,10 +1664,11 @@
1757
  attachments: payloadAttachments,
1758
  system_prompt: cognitivePrompt,
1759
  history: secureHistory,
1760
- max_tokens: AppState.isLiveModeEngaged ? 150 : 4096,
1761
  temperature: 0.75
1762
  };
1763
 
 
1764
  try {
1765
  const fetchOp = await fetch(Config.API_ENDPOINT, {
1766
  method: 'POST',
@@ -1808,27 +1716,21 @@
1808
  AppState.history.push({ role: 'bot', content: responseBuffer });
1809
  ChatEngine.saveHistoryToCloud();
1810
 
1811
- if (AppState.isLiveModeEngaged) {
1812
- document.getElementById('liveStatusText').innerText = "CODE VED Transmitting...";
1813
- await VoiceEngine.executeTTS(responseBuffer);
1814
- }
1815
-
1816
  } catch(error) {
 
1817
  AppState.isStreamingActive = false;
1818
- ChatEngine.updateBotBubble(activeBotBubble, `**System Error:** Communication array offline. Verification needed.`, false);
1819
- if (AppState.isLiveModeEngaged) {
1820
- document.getElementById('liveStatusText').innerText = "Neural Link Severed.";
1821
- }
 
 
1822
  }
1823
-
1824
- AppState.isProcessing = false;
1825
- document.getElementById('masterSendBtn').disabled = false;
1826
- UIManager.autoScroll();
1827
  }
1828
  };
1829
 
1830
  // =======================================================================================
1831
- // 10. EVENT DELEGATION & BOOTSTRAP INVOCATION
1832
  // =======================================================================================
1833
 
1834
  window.startCODEVEDApp = function() {
@@ -1890,15 +1792,10 @@
1890
  // Voice & STT Options
1891
  document.getElementById('smartLangToggle')?.addEventListener('click', VoiceEngine.switchLanguage);
1892
  document.getElementById('masterVoiceBtn')?.addEventListener('click', VoiceEngine.toggleDictation);
1893
-
1894
- // Live Mode Options
1895
- document.getElementById('btnStartLiveMode')?.addEventListener('click', LiveModeController.initialize);
1896
- document.getElementById('btnExitLiveMode')?.addEventListener('click', LiveModeController.terminate);
1897
- document.getElementById('liveMicBtn')?.addEventListener('click', VoiceEngine.toggleDictation);
1898
 
1899
  // Workspace Logic Hooks
1900
- document.getElementById('btnWsClose')?.addEventListener('click', WorkspaceEngine.closePanel);
1901
- document.getElementById('btnWsCopy')?.addEventListener('click', function() { WorkspaceEngine.executeCopy(this); });
1902
 
1903
  // Interaction Scroll Listeners
1904
  document.getElementById('msgs')?.addEventListener('scroll', UIManager.checkScrollState);
@@ -1921,4 +1818,4 @@
1921
 
1922
  </script>
1923
  </body>
1924
- </html>
 
1
+
2
  <!DOCTYPE html>
3
  <html lang="en" dir="ltr">
4
  <head>
 
66
  --border-light: rgba(255, 255, 255, 0.12);
67
  --border-medium: rgba(255, 255, 255, 0.25);
68
 
69
+ /* Shadows & Elevation */
70
  --shadow-xs: 0 1px 2px rgba(0,0,0,0.5);
71
  --shadow-sm: 0 4px 12px rgba(0,0,0,0.5);
72
  --shadow-md: 0 8px 24px rgba(0,0,0,0.6);
 
76
  /* Font Families */
77
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
78
  --font-mono: 'Geist Mono', Consolas, Monaco, monospace;
 
79
 
80
  /* Radii */
81
  --radius-sm: 8px;
 
98
  --z-workspace: 200;
99
  --z-modal: 5000;
100
  --z-toast: 9000;
 
101
  }
102
 
103
  /* ---------------------------------------------------------------------------------------
 
282
  .pulse-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--brand-green); box-shadow: 0 0 0 3px rgba(19, 136, 8, 0.3); animation: statusPulse 2s infinite; }
283
  @keyframes statusPulse { 0% { box-shadow: 0 0 0 0 rgba(19,136,8,0.6); } 70% { box-shadow: 0 0 0 6px rgba(19,136,8,0); } 100% { box-shadow: 0 0 0 0 rgba(19,136,8,0); } }
284
 
 
 
 
 
 
 
285
  /* Chat Scrollable Area */
286
  .chat-scroll-area { flex: 1; overflow-y: auto; padding: 40px 10%; display: flex; flex-direction: column; gap: 36px; scroll-behavior: smooth; position: relative; }
287
 
 
343
  .btn-bot-action { background: rgba(255,255,255,0.05); border: 1px solid var(--border-light); color: var(--text-secondary); font-size: 13px; font-weight: 700; cursor: pointer; display: flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: var(--radius-full); transition: var(--ease-fast); backdrop-filter: blur(10px); }
344
  .btn-bot-action:hover { background: rgba(255,255,255,0.15); color: var(--text-primary); transform: translateY(-2px); box-shadow: var(--shadow-sm); border-color: rgba(255,255,255,0.3); }
345
  .btn-bot-action svg { width: 16px; height: 16px; }
 
 
 
346
 
347
  /* Markdown Rendering inside Bubbles */
348
  .chat-bubble p { margin-bottom: 16px; }
 
428
 
429
  .bottom-branding-text { text-align: center; font-size: 12px; color: var(--text-tertiary); margin-top: 16px; font-weight: 600; letter-spacing: 0.5px; }
430
 
431
+ /* Scroll Trigger Button */
432
+ .btn-scroll-trigger { position: absolute; bottom: 150px; left: 50%; width: 48px; height: 48px; border-radius: 50%; background: rgba(28, 28, 30, 0.8); backdrop-filter: blur(25px); border: 1px solid var(--border-medium); box-shadow: var(--shadow-xl); display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--text-primary); opacity: 0; pointer-events: none; transform: translateX(-50%) translateY(20px); transition: var(--ease-smooth); z-index: 20; }
433
+ .btn-scroll-trigger.visible { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
434
+ .btn-scroll-trigger:hover { background: var(--text-primary); color: var(--text-inverse); transform: translateX(-50%) translateY(-5px); }
435
+
436
  /* ---------------------------------------------------------------------------------------
437
+ J. WORKSPACE PRO (DARK COMPILER PANEL WITH TABS)
438
  --------------------------------------------------------------------------------------- */
439
  .code-workspace-panel { width: 0; background: #000000; border-left: 1px solid var(--border-light); display: flex; flex-direction: column; transition: width var(--ease-smooth); overflow: hidden; box-shadow: -15px 0 40px rgba(0,0,0,0.8); z-index: var(--z-workspace); }
440
  .code-workspace-panel.expanded { width: 55%; }
441
 
442
+ .workspace-header-bar { padding: 12px 24px; border-bottom: 1px solid #333; background: #111; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; }
443
+
444
+ .workspace-tabs { display: flex; background: #222; border-radius: var(--radius-sm); padding: 4px; gap: 4px; }
445
+ .ws-tab { padding: 6px 16px; border-radius: 6px; font-size: 13px; font-weight: 700; color: #888; cursor: pointer; transition: 0.2s; display: flex; align-items: center; gap: 8px; }
446
+ .ws-tab:hover { color: #fff; }
447
+ .ws-tab.active { background: #444; color: #fff; box-shadow: 0 2px 5px rgba(0,0,0,0.5); }
448
+ .ws-tab svg { width: 14px; height: 14px; }
449
+
450
  .workspace-tools { display: flex; gap: 10px; }
451
 
452
  .btn-workspace-tool { padding: 8px 16px; border-radius: var(--radius-sm); background: #222; border: 1px solid #333; cursor: pointer; display: flex; align-items: center; gap: 8px; color: #fff; transition: var(--ease-fast); font-size: 13px; font-weight: 600; }
 
457
 
458
  .workspace-editor-surface { flex: 1; overflow-y: auto; background: #000; padding: 24px; position: relative; }
459
  .workspace-editor-surface pre { margin: 0; padding: 0; background: transparent; font-family: var(--font-mono); font-size: 15px; line-height: 1.6; overflow-x: auto; color: #abb2bf; border: none; box-shadow: none;}
 
 
 
 
 
 
 
 
460
 
461
+ .workspace-preview-surface { display: none; flex: 1; flex-direction: column; background: #000; overflow: hidden; position: relative; }
462
+ .console-output { background: #0c0c0c; color: #00ff00; font-family: var(--font-mono); padding: 20px; flex: 1; overflow-y: auto; font-size: 14px; line-height: 1.5; white-space: pre-wrap; margin:0;}
463
+ .console-output.error { color: #ff453a; }
464
+ .compiling-loader { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--brand-saffron); font-weight: bold; font-family: var(--font-mono); gap: 10px; }
465
+ .compiling-loader::after { content: ''; width: 16px; height: 16px; border: 2px solid var(--brand-saffron); border-top-color: transparent; border-radius: 50%; animation: spin 1s linear infinite; }
466
+ @keyframes spin { to { transform: rotate(360deg); } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
 
468
  /* ---------------------------------------------------------------------------------------
469
+ K. AUTHENTICATION SECURE GATEWAY (MODAL)
470
  --------------------------------------------------------------------------------------- */
471
  .secure-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.8); backdrop-filter: blur(20px); z-index: var(--z-modal); display: none; justify-content: center; align-items: center; animation: fadeIn 0.3s ease; }
472
  .secure-modal-surface { background: rgba(28, 28, 30, 0.95); padding: 44px; border-radius: var(--radius-xl); width: 90%; max-width: 460px; box-shadow: 0 25px 50px -12px rgba(0,0,0,1); position: relative; border: 1px solid rgba(255,255,255,0.15); backdrop-filter: blur(30px); }
 
503
  @keyframes dotBounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } }
504
 
505
  /* ---------------------------------------------------------------------------------------
506
+ L. RESPONSIVE DESIGN (MOBILE & TABLET ADAPTATIONS)
507
  --------------------------------------------------------------------------------------- */
508
  @media (max-width: 1024px) {
509
  .code-workspace-panel.expanded { width: 100%; position: absolute; top: 0; left: 0; height: 100%; z-index: 2000; }
 
545
  <img src="https://i.ibb.co/MxKsrXDj/TIRANGA-20260525-172109-0000.png" alt="CODE VED Core Identity">
546
  </div>
547
  <h1 class="startup-title">Welcome to CODE VED</h1>
548
+ <p class="startup-desc">Premium AI Workspace. Experience secure multi-language code generation and high-fidelity visual rendering.</p>
549
  <button class="btn-startup-launch" id="btnLaunchSystem">
550
  Initialize Workspace
551
  <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>
552
  </button>
553
  </div>
554
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  <!-- =========================================================================================
556
  DOM STRUCTURE: AMBIENT BACKGROUND
557
  ========================================================================================= -->
 
629
  System Online
630
  </div>
631
  </div>
 
 
 
 
 
 
632
  </header>
633
 
634
  <!-- Scrollable Conversation Area -->
 
723
  <input type="file" id="sys-inp-document" class="stealth-input" accept=".pdf,.doc,.docx,.txt,.md,.csv,.json,.py,.js,.html,.css,.cpp,.c,.java">
724
  </div>
725
 
726
+ <!-- Smart Language Toggle Button -->
727
  <button class="language-toggle-chip" id="smartLangToggle" title="Toggle Voice Engine Language">
728
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
729
  <span id="langDisplayBadge">EN</span>
 
747
  </div>
748
  </main>
749
 
750
+ <!-- C. WORKSPACE CODE EDITOR PANEL WITH PREVIEW -->
751
  <aside class="code-workspace-panel" id="workspacePanel">
752
  <div class="workspace-header-bar">
753
+ <div class="workspace-tabs">
754
+ <div class="ws-tab active" id="ws-tab-code" onclick="CompilerEngine.switchTab('code')">
755
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
756
+ Code
757
+ </div>
758
+ <div class="ws-tab" id="ws-tab-preview" onclick="CompilerEngine.switchTab('preview')">
759
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
760
+ Preview / Run
761
+ </div>
762
  </div>
763
  <div class="workspace-tools">
764
  <button class="btn-workspace-tool" id="btnWsCopy">
765
  <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
766
+ Copy
767
  </button>
768
  <button class="btn-workspace-tool close" id="btnWsClose" title="Close Editor">
769
  <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
770
  </button>
771
  </div>
772
  </div>
773
+
774
+ <!-- Code View -->
775
+ <div class="workspace-editor-surface" id="workspaceCodeContainer">
776
  <pre><code id="workspaceCodeBlock" class="hljs"></code></pre>
777
  </div>
778
+
779
+ <!-- Preview / Execution View -->
780
+ <div class="workspace-preview-surface" id="workspacePreviewContainer">
781
+ <!-- Content injected dynamically -->
782
+ </div>
783
  </aside>
784
  </div>
785
 
 
838
  GAS_URL: "https://script.google.com/macros/s/AKfycbz5vrlB4GrfkfBVYdQ52IQweIXC1cNDwKuTUorxdAiOdSSIrH55mzJlaz9kq1Y94ot5/exec",
839
  LOGO_URL: "https://i.ibb.co/MxKsrXDj/TIRANGA-20260525-172109-0000.png",
840
  PDF_WORKER: 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js',
841
+ API_ENDPOINT: '/api/chat', // Backend AI endpoint
842
  };
843
 
844
  pdfjsLib.GlobalWorkerOptions.workerSrc = Config.PDF_WORKER;
 
853
  generatedCodeBlocks: [],
854
  currentWorkspaceId: null,
855
  isStreamingActive: false,
 
 
856
  isMicRecording: false
857
  };
858
 
 
 
 
 
 
 
 
 
 
 
 
859
  // =======================================================================================
860
  // 2. UTILITY ENGINE
861
  // =======================================================================================
 
873
  return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
874
  },
875
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
876
  executeFallbackCopy: (text, btnElement) => {
877
  const textArea = document.createElement("textarea");
878
  textArea.value = text;
 
911
  };
912
 
913
  // =======================================================================================
914
+ // 3. AUTHENTICATION & SYNC MANAGER (WITH BUG FIX FOR HISTORY SYNC)
915
  // =======================================================================================
916
  const AuthManager = {
917
  initUI: () => {
 
979
  triggerBtn.innerText = 'Establishing Connection...';
980
 
981
  try {
982
+ // Using default fetch behavior to allow GAS redirects
983
  const response = await fetch(Config.GAS_URL, {
984
+ method: 'POST',
 
985
  headers: { 'Content-Type': 'text/plain;charset=utf-8' },
986
  body: JSON.stringify(payload)
987
  });
 
997
  localStorage.setItem('codeved_user', AppState.currentUser);
998
  AuthManager.closeModal();
999
  AuthManager.initUI();
1000
+ ChatEngine.syncHistoryFromCloud(); // Safely calls the fixed function
1001
  }
1002
  } else {
1003
  Utils.showToast(result.message);
1004
  }
1005
  } catch (error) {
1006
+ console.error("Auth Error:", error);
1007
  Utils.showToast("Encrypted gateway error. Check network.");
1008
  }
1009
 
 
1057
  };
1058
 
1059
  // =======================================================================================
1060
+ // 5. SPEECH RECOGNITION ENGINE (STT ONLY)
1061
  // =======================================================================================
1062
  const VoiceEngine = {
1063
  recognition: null,
 
1079
  if(VoiceEngine.sessionTranscript && !VoiceEngine.sessionTranscript.endsWith(' ')) {
1080
  VoiceEngine.sessionTranscript += ' ';
1081
  }
 
1082
  document.getElementById('masterVoiceBtn').classList.add('active-listening');
 
 
 
 
 
 
1083
  };
1084
 
1085
  VoiceEngine.recognition.onresult = (event) => {
 
1099
  currentDictation = currentDictation.charAt(0).toUpperCase() + currentDictation.slice(1);
1100
  }
1101
 
1102
+ const inputField = document.getElementById('mainChatInput');
1103
+ inputField.value = VoiceEngine.sessionTranscript + currentDictation;
1104
+ UIManager.autoGrowTextArea(inputField);
1105
+
1106
+ if(finalTranscript.trim().length > 0) {
1107
+ VoiceEngine.sessionTranscript = inputField.value;
1108
+ if(!VoiceEngine.sessionTranscript.endsWith(' ')) VoiceEngine.sessionTranscript += ' ';
 
 
 
 
 
 
 
 
 
 
1109
  }
1110
  };
1111
 
1112
  VoiceEngine.recognition.onend = () => {
1113
  AppState.isMicRecording = false;
1114
  document.getElementById('masterVoiceBtn').classList.remove('active-listening');
 
 
 
 
 
 
1115
  };
1116
 
1117
  VoiceEngine.recognition.onerror = (event) => {
 
1120
  Utils.showToast("Voice module error: " + event.error);
1121
  }
1122
  document.getElementById('masterVoiceBtn').classList.remove('active-listening');
 
 
 
 
1123
  };
1124
  },
1125
 
 
1157
  VoiceEngine.recognition.start();
1158
  }
1159
  } catch (e) { console.error("Mic Start Error", e); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1160
  }
1161
  };
1162
 
1163
  // =======================================================================================
1164
+ // 6. FILE PROCESSOR
1165
  // =======================================================================================
1166
  const FileProcessor = {
1167
  triggerFileSelector: (type) => {
 
1265
  };
1266
 
1267
  // =======================================================================================
1268
+ // 7. COMPILER & WORKSPACE ENGINE (NEW PREVIEW / CODE LOGIC)
1269
  // =======================================================================================
1270
+ const CompilerEngine = {
1271
+ currentMode: 'code',
1272
+
1273
+ switchTab: (mode) => {
1274
+ CompilerEngine.currentMode = mode;
1275
+ document.getElementById('ws-tab-code').classList.remove('active');
1276
+ document.getElementById('ws-tab-preview').classList.remove('active');
1277
+ document.getElementById(`ws-tab-${mode}`).classList.add('active');
1278
+
1279
+ document.getElementById('workspaceCodeContainer').style.display = mode === 'code' ? 'block' : 'none';
1280
+ document.getElementById('workspacePreviewContainer').style.display = mode === 'preview' ? 'flex' : 'none';
1281
+
1282
+ if (mode === 'preview') {
1283
+ CompilerEngine.executeCurrentCode();
1284
+ }
1285
+ },
1286
+
1287
+ executeCurrentCode: async () => {
1288
+ const previewContainer = document.getElementById('workspacePreviewContainer');
1289
+ if (AppState.currentWorkspaceId === null) return;
1290
+
1291
+ const codeData = AppState.generatedCodeBlocks[AppState.currentWorkspaceId];
1292
+ const lang = (codeData.lang || 'plaintext').toLowerCase();
1293
+ const code = codeData.code;
1294
+
1295
+ previewContainer.innerHTML = '<div class="compiling-loader">Compiling execution context...</div>';
1296
+
1297
+ // Web Based Languages Render in Iframe
1298
+ if (['html', 'xml', 'javascript', 'js', 'css'].includes(lang)) {
1299
+ let finalHTML = code;
1300
+ if (lang === 'javascript' || lang === 'js') finalHTML = `<script>${code}<\/script>`;
1301
+ if (lang === 'css') finalHTML = `<style>${code}</style><div style="padding:20px; color:#fff; font-family:sans-serif;">CSS Ready. Render HTML to see effect.</div>`;
1302
+
1303
+ const iframe = document.createElement('iframe');
1304
+ iframe.style.width = '100%';
1305
+ iframe.style.height = '100%';
1306
+ iframe.style.border = 'none';
1307
+ iframe.style.background = '#ffffff';
1308
+
1309
+ previewContainer.innerHTML = '';
1310
+ previewContainer.appendChild(iframe);
1311
+ iframe.contentWindow.document.open();
1312
+ iframe.contentWindow.document.write(finalHTML);
1313
+ iframe.contentWindow.document.close();
1314
+ return;
1315
+ }
1316
+
1317
+ // Backend Languages executed via Piston API
1318
+ const pistonLangs = {
1319
+ 'python': 'python', 'py': 'python',
1320
+ 'c': 'c', 'cpp': 'c++', 'c++': 'c++',
1321
+ 'java': 'java', 'rust': 'rust',
1322
+ 'go': 'go', 'php': 'php', 'ruby': 'ruby',
1323
+ 'typescript': 'typescript', 'ts': 'typescript',
1324
+ 'swift': 'swift', 'csharp': 'csharp', 'cs': 'csharp'
1325
+ };
1326
+
1327
+ const runLang = pistonLangs[lang];
1328
+ if (!runLang) {
1329
+ previewContainer.innerHTML = `<div class="console-output error">Cannot execute language: ${lang || 'Unknown'}. Live Preview not supported.</div>`;
1330
+ return;
1331
+ }
1332
+
1333
+ try {
1334
+ const res = await fetch('https://emkc.org/api/v2/piston/execute', {
1335
+ method: 'POST',
1336
+ headers: { 'Content-Type': 'application/json' },
1337
+ body: JSON.stringify({
1338
+ language: runLang,
1339
+ version: "*",
1340
+ files: [{ content: code }]
1341
+ })
1342
+ });
1343
+ const data = await res.json();
1344
+
1345
+ let output = "";
1346
+ if (data.compile && data.compile.output) output += data.compile.output + "\n";
1347
+ if (data.run && data.run.output) output += data.run.output;
1348
+ if (data.run && data.run.stderr) output += "\n" + data.run.stderr;
1349
+
1350
+ if (!output.trim()) output = `[Process finished with exit code 0 - No Output generated]`;
1351
+
1352
+ previewContainer.innerHTML = `<pre class="console-output">${Utils.escapeHTML(output)}</pre>`;
1353
+
1354
+ } catch (e) {
1355
+ previewContainer.innerHTML = `<div class="console-output error">Compiler Error: Could not connect to remote execution server. Check internet connection.</div>`;
1356
+ }
1357
+ },
1358
+
1359
  launch: (codeBlockId) => {
1360
  AppState.currentWorkspaceId = codeBlockId;
1361
  const codeData = AppState.generatedCodeBlocks[codeBlockId];
1362
 
 
1363
  const blockDisplay = document.getElementById('workspaceCodeBlock');
1364
  blockDisplay.className = `hljs language-${codeData.lang || 'plaintext'}`;
1365
  blockDisplay.textContent = codeData.code;
 
1367
  hljs.highlightElement(blockDisplay);
1368
  document.getElementById('workspacePanel').classList.add('expanded');
1369
 
1370
+ // Always reset to code tab when opening a new workspace
1371
+ CompilerEngine.switchTab('code');
1372
+
1373
  if (window.innerWidth <= 1024) {
1374
  document.getElementById('sidebar').classList.remove('active');
1375
  }
 
1423
  document.getElementById('msgs').addEventListener('click', function(e) {
1424
  if (e.target && e.target.classList.contains('btn-launch-ws')) {
1425
  const blockId = e.target.getAttribute('data-id');
1426
+ CompilerEngine.launch(blockId);
1427
  }
1428
  });
1429
 
1430
  // =======================================================================================
1431
+ // 8. CORE CHAT ENGINE & LLM (WITH ROCK SOLID BUG FIXES)
1432
  // =======================================================================================
1433
  const ChatEngine = {
1434
  handleKeyboard: (e) => {
 
1449
  try {
1450
  await fetch(Config.GAS_URL, {
1451
  method: 'POST',
 
1452
  headers: { 'Content-Type': 'text/plain;charset=utf-8' },
1453
  body: JSON.stringify({ action: "delete_history", email: AppState.currentUser })
1454
  });
 
1457
  location.reload();
1458
  },
1459
 
1460
+ // BUG FIX: Wrapped entirely in try/catch to ensure UI doesn't break if API fails
1461
  syncHistoryFromCloud: async () => {
1462
  const messageZone = document.getElementById('msgs');
1463
  document.getElementById('welcomeState').style.display = 'none';
 
1465
 
1466
  try {
1467
  const response = await fetch(Config.GAS_URL, {
1468
+ method: 'POST',
 
1469
  headers: { 'Content-Type': 'text/plain;charset=utf-8' },
1470
  body: JSON.stringify({ action: "get_history", email: AppState.currentUser })
1471
  });
1472
+
1473
  const resData = await response.json();
1474
  messageZone.innerHTML = '';
1475
 
 
1488
  document.getElementById('welcomeState').style.display = 'flex';
1489
  }
1490
  } catch (err) {
1491
+ console.error("History Sync Failed:", err);
1492
  messageZone.innerHTML = '';
1493
  document.getElementById('welcomeState').style.display = 'flex';
1494
  }
1495
  },
1496
 
1497
+ // BUG FIX: Try/Catch for saving history silently
1498
  saveHistoryToCloud: () => {
1499
  if (AppState.currentUser) {
1500
+ try {
1501
+ fetch(Config.GAS_URL, {
1502
+ method: 'POST',
1503
+ headers: { 'Content-Type': 'text/plain;charset=utf-8' },
1504
+ body: JSON.stringify({ action: "save_history", email: AppState.currentUser, historyJSON: JSON.stringify(AppState.history) })
1505
+ }).catch(e => console.warn("Background Save Failed"));
1506
+ } catch(err) {}
1507
  }
1508
  },
1509
 
 
1571
  let actionTray = bubbleDOM.querySelector('.bot-actions-row');
1572
  if (!isCurrentlyStreaming && !actionTray && strippedMarkup.trim().length > 0) {
1573
  const safeRawCopy = strippedMarkup.replace(/"/g, '&quot;').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '');
1574
+
 
1575
  const actionsHTML = `
1576
  <div class="bot-actions-row">
1577
  <button class="btn-bot-action btn-cpy-action" data-cpy="${safeRawCopy}">
1578
  <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
1579
  Copy Data
1580
  </button>
 
 
 
 
1581
  </div>`;
1582
  bubbleDOM.querySelector('.msg-content-column').insertAdjacentHTML('beforeend', actionsHTML);
 
1583
  bubbleDOM.querySelector('.btn-cpy-action').addEventListener('click', function() { Utils.copyToClipboard(this, this.getAttribute('data-cpy')); });
 
1584
  }
1585
  },
1586
 
1587
+ // BUG FIX: Complete Try/Catch/Finally to unlock state no matter what happens
1588
  initiateDispatch: async () => {
1589
  if (AppState.isProcessing) return;
1590
 
 
1657
  Available Models: flux, flux-realism, flux-anime, flux-3d.
1658
  CRITICAL: The seed parameter is mandatory to bypass cache mechanics. Always render this markdown node.`;
1659
 
 
 
 
 
 
1660
  const secureHistory = AppState.history.slice(0, -1).map(h => ({ role: h.role, content: h.content }));
1661
 
1662
  const transmissionPayload = {
 
1664
  attachments: payloadAttachments,
1665
  system_prompt: cognitivePrompt,
1666
  history: secureHistory,
1667
+ max_tokens: 4096,
1668
  temperature: 0.75
1669
  };
1670
 
1671
+ // The complete Try/Catch/Finally block ensures UI never gets stuck
1672
  try {
1673
  const fetchOp = await fetch(Config.API_ENDPOINT, {
1674
  method: 'POST',
 
1716
  AppState.history.push({ role: 'bot', content: responseBuffer });
1717
  ChatEngine.saveHistoryToCloud();
1718
 
 
 
 
 
 
1719
  } catch(error) {
1720
+ console.error("AI Dispatch Error:", error);
1721
  AppState.isStreamingActive = false;
1722
+ ChatEngine.updateBotBubble(activeBotBubble, `**System Error:** Communication array offline. Please try again.`, false);
1723
+ } finally {
1724
+ // BUG FIX: Always release the lock
1725
+ AppState.isProcessing = false;
1726
+ document.getElementById('masterSendBtn').disabled = false;
1727
+ UIManager.autoScroll();
1728
  }
 
 
 
 
1729
  }
1730
  };
1731
 
1732
  // =======================================================================================
1733
+ // 9. EVENT DELEGATION & BOOTSTRAP INVOCATION
1734
  // =======================================================================================
1735
 
1736
  window.startCODEVEDApp = function() {
 
1792
  // Voice & STT Options
1793
  document.getElementById('smartLangToggle')?.addEventListener('click', VoiceEngine.switchLanguage);
1794
  document.getElementById('masterVoiceBtn')?.addEventListener('click', VoiceEngine.toggleDictation);
 
 
 
 
 
1795
 
1796
  // Workspace Logic Hooks
1797
+ document.getElementById('btnWsClose')?.addEventListener('click', CompilerEngine.closePanel);
1798
+ document.getElementById('btnWsCopy')?.addEventListener('click', function() { CompilerEngine.executeCopy(this); });
1799
 
1800
  // Interaction Scroll Listeners
1801
  document.getElementById('msgs')?.addEventListener('scroll', UIManager.checkScrollState);
 
1818
 
1819
  </script>
1820
  </body>
1821
+ </html>