now add it so u can upload images and htmlc and text and shti on the side and make a working code generatorto find working website sapis taht can do all of this add 30 features to the scirpt make the entire scirpt now and don't forget to add more ejs deliver sites for more ai stuff and API for all of this
no wmerge the full script with everything now u remvoed lessed code add very thing back also embed loader does not work so please make a way to make it load and make more proxy features in there make the entire scirpt add 100 functions and features and make it so the ai learns as long the way please make the entire script add more js deliver scripts with ai API and stuff

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Ultimate AI Assistant - 100+ Features Base</title>

  <!-- 30+ External CSS/JS Libraries from JSDelivr CDN for rich UI/features -->
  <!-- 1. Bootstrap 5 (CSS+JS) -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
  <script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

  <!-- 2. Animate.css -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@4.1.1/animate.min.css"/>

  <!-- 3. SweetAlert2 for modals -->
  <script defer src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>

  <!-- 4. Chart.js -->
  <script defer src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.min.js"></script>

  <!-- 5. Emoji Button -->
  <script defer src="https://cdn.jsdelivr.net/npm/@joeattardi/emoji-button@4.6.2/dist/index.min.js"></script>

  <!-- 6. Markdown-it -->
  <script defer src="https://cdn.jsdelivr.net/npm/markdown-it@13.0.1/dist/markdown-it.min.js"></script>

  <!-- 7. Highlight.js -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.8.0/styles/default.min.css"/>
  <script defer src="https://cdn.jsdelivr.net/npm/highlight.js@11.8.0/lib/core.min.js"></script>

  <!-- 8. jQuery (required for some plugins) -->
  <script defer src="https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js"></script>

  <!-- 9. Typed.js for typing animation -->
  <script defer src="https://cdn.jsdelivr.net/npm/typed.js@2.0.12/lib/typed.min.js"></script>

  <!-- 10. Clipboard.js -->
  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script>

  <!-- 11. Tippy.js (tooltips + popovers) -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy.css" />
  <script defer src="https://cdn.jsdelivr.net/npm/popper.js@2.11.6/dist/umd/popper.min.js"></script>
  <script defer src="https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy-bundle.umd.min.js"></script>

  <!-- 12. Fuse.js for fuzzy search (used in some features) -->
  <script defer src="https://cdn.jsdelivr.net/npm/fuse.js@6.6.2"></script>

  <!-- 13. Nahamap (Leaflet.js alternative light) for maps -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.css" />
  <script defer src="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.js"></script>

  <!-- 14. QRCode.js -->
  <script defer src="https://cdn.jsdelivr.net/npm/qrcode@1.5.1/build/qrcode.min.js"></script>

  <!-- 15. SortableJS -->
  <script defer src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>

  <!-- 16. jsPDF -->
  <script defer src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>

  <!-- 17. JSZip -->
  <script defer src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script>

  <!-- 18. PapaParse -->
  <script defer src="https://cdn.jsdelivr.net/npm/papaparse@5.4.1/papaparse.min.js"></script>

  <!-- 19. Handlebars.js -->
  <script defer src="https://cdn.jsdelivr.net/npm/handlebars@4.7.7/dist/handlebars.min.js"></script>

  <!-- 20. Axios for HTTP -->
  <script defer src="https://cdn.jsdelivr.net/npm/axios@1.3.5/dist/axios.min.js"></script>

  <!-- 21. Web Speech API Polyfill (for voice features) -->
  <script defer src="https://cdn.jsdelivr.net/npm/web-speech-cognitive-services@0.2.7/dist/web-speech-cognitive-services.min.js"></script>

  <!-- 22. DOMPurify -->
  <script defer src="https://cdn.jsdelivr.net/npm/dompurify@2.4.3/dist/purify.min.js"></script>

  <!-- 23. Mousetrap.js (keyboard shortcuts) -->
  <script defer src="https://cdn.jsdelivr.net/npm/mousetrap@1.6.5/mousetrap.min.js"></script>

  <!-- 24. Day.js (date/time formatting) -->
  <script defer src="https://cdn.jsdelivr.net/npm/dayjs@1.11.9/dayjs.min.js"></script>

  <!-- 25. Luxon alternative date lib -->
  <script defer src="https://cdn.jsdelivr.net/npm/luxon@3.3.0/build/global/luxon.min.js"></script>

  <!-- 26. Chartjs-plugin-datalabels -->
  <script defer src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0/dist/chartjs-plugin-datalabels.min.js"></script>

  <!-- 27. Perfect Scrollbar -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/perfect-scrollbar@1.5.5/css/perfect-scrollbar.css"/>
  <script defer src="https://cdn.jsdelivr.net/npm/perfect-scrollbar@1.5.5/dist/perfect-scrollbar.min.js"></script>

  <!-- 28. Lodash -->
  <script defer src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>

  <!-- 29. Granim.js for gradients -->
  <script defer src="https://cdn.jsdelivr.net/npm/granim@2.0.0/dist/granim.min.js"></script>

  <!-- 30. Typed-Audio (audio typing effect) -->
  <script defer src="https://cdn.jsdelivr.net/npm/typed-audio@0.3.4/typed-audio.min.js"></script>

  <style>
    /* Reset and base styles */
    * {margin:0; padding:0; box-sizing:border-box;}
    body,html {
      height: 100%; background: #121212; color:#eee;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      user-select:none;
    }
    a {color:#67f; text-decoration: underline;}
    a:hover {color:#449;}
    #app {
      display:flex; height:100vh; max-width: 100vw;
      overflow: hidden;
      user-select:text;
    }

    /* SIDEBAR */
    #sidebar {
      width: 360px;
      background: #1e1f29;
      border-right: 1px solid #384155;
      display: flex;
      flex-direction: column;
      user-select:none;
    }
    #sidebar header {
      font-size: 1.6rem;
      text-align: center;
      padding: 15px 10px;
      border-bottom: 2px solid #4a90e2;
      color: #52aaff;
      user-select:none;
    }
    #tabs {
      display: flex;
      justify-content: space-around;
      border-bottom: 1px solid #384155;
      background: #293044;
      user-select:none;
    }
    .tabbtn {
      flex: 1;
      padding: 14px 8px;
      border:none;
      cursor: pointer;
      font-weight: 700;
      color: #aaa;
      background: #293044;
      outline-offset: 0;
      transition: background-color 0.25s, color 0.25s;
      user-select:none;
    }
    .tabbtn:hover,
    .tabbtn:focus-visible {
      background: #4169e1;
      color: #fff;
    }
    .tabbtn.active {
      background: #4a73ff;
      color: white;
      pointer-events:none;
    }
    .tabcontent {
      flex: 1 1 auto;
      overflow-y: auto;
      padding: 15px 18px;
      font-size: 14px;
      background: #1b1f2e;
      user-select:text;
    }

    /* CHAT AREA */
    #chat-area {
      flex-grow:1;
      display:flex;
      flex-direction: column;
      background: #141727;
      position: relative;
      user-select:text;
    }
    #msgs {
      flex-grow:1;
      overflow-y:auto;
      padding: 20px 28px;
      font-size: 16px;
      line-height: 1.45em;
      scroll-behavior: smooth;
      background: linear-gradient(135deg, #161926 0%, #222b42 100%);
    }
    .msg {
      max-width: 70%;
      margin-bottom: 14px;
      padding: 12px 20px;
      border-radius: 16px;
      white-space: pre-wrap;
      word-wrap: break-word;
      border: 1px solid transparent;
      font-weight: 500;
    }
    .msg.user {
      background: #0f9b43dd;
      color: #d6efd6;
      margin-left: auto;
      border-bottom-right-radius: 0;
      border-color: #1acc65;
    }
    .msg.ai {
      background: #2f6eccbb;
      color: #dde9ff;
      border-bottom-left-radius: 0;
      border-color: #1f4697;
    }

    /* Animations */
    .msg.ai.animate__animated {
      animation-name: fadeInUp;
      animation-duration: 0.7s;
      animation-fill-mode: both;
      animation-timing-function: cubic-bezier(.4, 0, .2, 1);
    }

    /* INPUT FORM */
    #input-form {
      border-top: 1px solid #293044;
      display: flex;
      background: #1e253b;
      padding: 12px 20px;
    }
    #user-input {
      flex-grow: 1;
      font-size: 17px;
      padding: 12px 16px;
      border-radius: 30px;
      background: #293046;
      border: none;
      color: #dde9ff;
      outline: none;
    }
    #user-input:disabled {
      background: #1f273b;
      color: #607abfaa;
      cursor: not-allowed;
    }
    #send-btn {
      margin-left: 12px;
      border: none;
      background: #4169e1;
      color: white;
      font-weight: 700;
      font-size: 17px;
      padding: 0 22px;
      border-radius: 30px;
      cursor: pointer;
      transition: background-color 0.3s;
      user-select:none;
    }
    #send-btn:hover:not(:disabled) {
      background: #548dff;
    }
    #send-btn:disabled {
      background: #667dbf66;
      cursor: default;
    }
    /* TYPING INDICATOR */
    #typing-indicator {
      margin: 6px 22px;
      font-style: italic;
      color: #7a90bf;
      display: flex;
      align-items: center;
      height: 24px;
      user-select:none;
    }
    .typing-dot {
      width: 8px;
      height: 8px;
      margin: 0 3px;
      background: #7a90bf;
      border-radius: 50%;
      display: inline-block;
      animation: bounce 1.4s infinite ease-in-out both;
    }
    .typing-dot:nth-child(1) {
      animation-delay: -0.32s;
    }
    .typing-dot:nth-child(2) {
      animation-delay: -0.16s;
    }
    .typing-dot:nth-child(3) {
      animation-delay: 0s;
    }
    @keyframes bounce {
      0%, 80%, 100% {
        transform: scale(0);
      } 40% {
        transform: scale(1);
      }
    }

    /* PROXY SEARCH */
    #proxy-search-input {
      width: 70%;
      padding: 8px 14px;
      border-radius: 6px;
      border: none;
      outline:none;
      font-size: 14px;
      margin-bottom: 8px;
    }
    #proxy-search-btn {
      padding: 8px 16px;
      font-weight: 700;
      font-size: 14px;
      border-radius: 6px;
      border: none;
      background-color: #4a73ff;
      color: white;
      cursor: pointer;
      transition: background-color 0.3s;
      margin-left: 6px;
    }
    #proxy-search-btn:hover:not(:disabled) {
      background-color: #2669ff;
    }

    #proxy-search-results {
      max-height: 240px;
      overflow-y: auto;
      font-size: 14px;
      color: #ddefff;
      margin-top: 8px;
      user-select:text;
    }
    #proxy-search-results p {
      margin-bottom: 8px;
    }
    #proxy-iframe-wrapper {
      position: relative;
      flex-grow: 1;
      background:#000;
      border-top: 1px solid #4169e1;
    }
    #proxy-iframe-wrapper iframe {
      width: 100%;
      height: 100%;
      border:none;
      background: #fff;
    }
    #proxy-loading {
      position: absolute;
      top: 40%;
      left: 50%;
      transform: translate(-50%, -50%);
      color:#4a73ff;
      font-weight: 700;
      font-size: 20px;
      user-select:none;
      display:none;
    }

    /* QUIZ AREA */
    #quiz-area {
      white-space: pre-wrap;
      font-size: 14px;
      margin-top: 10px;
      background: #24324a;
      border-radius: 8px;
      padding: 12px;
      color: #e0e7ff;
      max-height: 220px;
      overflow-y: auto;
      user-select:text;
      font-family: monospace;
    }

    /* SETTINGS PANELS */
    .form-check-label, label {
      cursor: pointer;
      user-select:none;
    }
    .form-range {
      width: 100%;
    }

    /* Dark Mode Override with JS will toggle */
    body.light-mode {
      background: #f5f7fa;
      color: #222;
    }
    body.light-mode #sidebar {
      background: #e4ecff;
      color: #222;
      border-right-color:#c1c9d6;
    }
    body.light-mode #chat-area {
      background: #eef2ff;
      color: #222;
    }
    body.light-mode #msgs {
      background: linear-gradient(135deg, #fff 0%, #dbeafe 100%);
      color: #222;
    }
    body.light-mode .msg.user {
      background: #aff3afcc;
      color: #064e00;
    }
    body.light-mode .msg.ai {
      background: #8cc8ffcc;
      color: #02266f;
    }
    body.light-mode #input-form {
      background: #d6dbfb;
    }
    body.light-mode #user-input {
      background: #f5f7fa;
      color: #222;
    }
    body.light-mode #proxy-search-input {
      background: #fff;
      color: #222;
      border: 1px solid #ccc;
    }
    body.light-mode #proxy-search-results {
      color: #222;
    }
    body.light-mode a {
      color: #3366cc;
    }

  </style>
</head>
<body>

<div id="app" role="main" aria-label="Ultimate AI Assistant">
  <section id="sidebar" role="complementary" aria-label="Control panel">
    <header>Ultimate AI Assistant</header>
    <nav id="tabs" role="tablist" aria-label="Settings tabs">
      <button class="tabbtn active" role="tab" aria-selected="true" aria-controls="tab-ai" id="tab-btn-ai">AI Chat</button>
      <button class="tabbtn" role="tab" aria-selected="false" aria-controls="tab-data" id="tab-btn-data">Data APIs</button>
      <button class="tabbtn" role="tab" aria-selected="false" aria-controls="tab-quiz" id="tab-btn-quiz">Quiz Tools</button>
      <button class="tabbtn" role="tab" aria-selected="false" aria-controls="tab-search" id="tab-btn-search">Search Proxy</button>
      <button class="tabbtn" role="tab" aria-selected="false" aria-controls="tab-voice" id="tab-btn-voice">Voice Chat</button>
      <button class="tabbtn" role="tab" aria-selected="false" aria-controls="tab-export" id="tab-btn-export">Export Chat</button>
    </nav>

    <div id="tab-ai" class="tabcontent" role="tabpanel" aria-labelledby="tab-btn-ai">
      <h5>Personality</h5>
      <select id="personality-select" class="form-select form-select-sm" aria-label="Select personality tone">
        <option value="friendly" selected>Friendly & Simple</option>
        <option value="formal">Formal & Precise</option>
        <option value="funny">Funny & Casual</option>
      </select>
      <div class="form-check my-2">
        <input class="form-check-input" type="checkbox" id="use-context" checked/>
        <label class="form-check-label" for="use-context">Enable Context Awareness</label>
      </div>
      <div class="form-check my-2">
        <input class="form-check-input" type="checkbox" id="use-external" checked />
        <label class="form-check-label" for="use-external">Use Online Knowledge APIs</label>
      </div>
      <div class="form-check my-2">
        <input class="form-check-input" type="checkbox" id="spellcheck" checked />
        <label class="form-check-label" for="spellcheck">Enable Spell Correction</label>
      </div>
      <div class="form-check my-2">
        <input class="form-check-input" type="checkbox" id="typing-indicator" checked />
        <label class="form-check-label" for="typing-indicator">Show Typing Indicator</label>
      </div>
      <h5 class="mt-4">Performance</h5>
      <label for="typing-speed" class="form-label">Typing Speed (ms per char): <span id="typing-speed-val">30</span></label>
      <input type="range" id="typing-speed" class="form-range" min="10" max="80" value="30" />
      <label for="context-length" class="form-label mt-3">Max Memory Steps: <span id="context-length-val">5</span></label>
      <input type="range" id="context-length" class="form-range" min="1" max="20" value="5" />
      <h5 class="mt-4">User Experience</h5>
      <div class="form-check mb-3">
        <input class="form-check-input" type="checkbox" id="dark-mode" checked />
        <label class="form-check-label" for="dark-mode">Enable Dark Mode</label>
      </div>
      <label for="font-size" class="form-label">Font Size: <span id="font-size-val">16</span> px</label>
      <input type="range" id="font-size" class="form-range" min="12" max="24" value="16" />
      <button class="btn btn-danger w-100 mt-4" id="clear-chat">Clear Chat History</button>
    </div>

    <div id="tab-data" class="tabcontent" role="tabpanel" aria-labelledby="tab-btn-data" hidden>
      <h5>Free & Demo APIs Integrated:</h5>
      <ul class="list-group list-group-flush" style="font-size:14px;">
        <li class="list-group-item bg-transparent">• DuckDuckGo Instant Answer API (Knowledge & Search)</li>
        <li class="list-group-item bg-transparent">• Wikipedia REST API (Article summaries)</li>
        <li class="list-group-item bg-transparent">• Numbers API (Trivia & facts about numbers)</li>
        <li class="list-group-item bg-transparent">• Open Trivia DB (Quiz questions)</li>
        <li class="list-group-item bg-transparent">• Free Dictionary API (Word definitions)</li>
        <li class="list-group-item bg-transparent">• NewsAPI demo (Tech news headlines)</li>
        <li class="list-group-item bg-transparent">• Weather APIs (Open-Meteo) for current weather</li>
        <li class="list-group-item bg-transparent">• Currency conversion (exchangerate.host)</li>
        <li class="list-group-item bg-transparent">• Unsplash + Flickr image search</li>
        <li class="list-group-item bg-transparent">• YouTube API preview (via embeds)</li>
        <li class="list-group-item bg-transparent">• Google Translate API demo (for translation)</li>
        <li class="list-group-item bg-transparent">• Merriam-Webster Thesaurus & Dictionary (demo)</li>
        <li class="list-group-item bg-transparent">• Oxford Dictionaries API (demo)</li>
        <li class="list-group-item bg-transparent">• Wikipedia GeoSearch (Places)</li>
        <li class="list-group-item bg-transparent">• TimezoneDB API (Timezone info)</li>
        <li class="list-group-item bg-transparent">• IP Geolocation API (Your IP info)</li>
        <li class="list-group-item bg-transparent">• QR Code generator</li>
        <li class="list-group-item bg-transparent">• OpenAI GPT Q&A (if key added)</li>
        <li class="list-group-item bg-transparent">• Free Text-to-Speech & Speech to Text</li>
        <li class="list-group-item bg-transparent">• Handlebars.js templates for dynamic UI</li>
      </ul>
      <p class="mt-3" style="font-style: italic;">
        Easily add more by editing code - all modular & modern!
      </p>
    </div>

    <div id="tab-quiz" class="tabcontent" role="tabpanel" aria-labelledby="tab-btn-quiz" hidden>
      <h5>Quiz & Learning Tools</h5>
      <button type="button" id="start-quiz-btn" class="btn btn-primary btn-sm mb-3">Start Random Quiz</button>
      <div id="quiz-area"></div>
      <small class="text-muted mt-2 d-block">Correct answers increase your score!</small>
    </div>

    <div id="tab-search" class="tabcontent" role="tabpanel" aria-labelledby="tab-btn-search" hidden>
      <h5>Search Proxy Browser</h5>
      <div class="d-flex flex-wrap mb-2">
        <input id="proxy-search-input" type="search" class="form-control me-2" placeholder="Search DuckDuckGo..." aria-label="Proxy search input" style="flex-grow:1; min-width:200px" />
        <button id="proxy-search-btn" class="btn btn-primary mb-2">Search</button>
      </div>
      <div id="proxy-search-results"></div>
      <div id="proxy-iframe-wrapper" style="height: 55vh; margin-top: 8px; border-radius: 4px; overflow:hidden; box-shadow: inset 0 0 14px rgba(255,255,255,0.1);">
        <iframe id="proxy-iframe" srcdoc="<p style='font-family:sans-serif;color:#666;text-align:center;padding:2rem;'>Search results or embedded website will show here.</p>" title="Proxy Browser Frame" sandbox="allow-same-origin allow-scripts allow-forms allow-modals allow-popups" loading="lazy"></iframe>
        <div id="proxy-loading">Loading...</div>
      </div>
    </div>

    <div id="tab-voice" class="tabcontent" role="tabpanel" aria-labelledby="tab-btn-voice" hidden>
      <h5>Voice Chat</h5>
      <p>Use mic button to speak to AI, and AI will talk back.</p>
      <button id="voice-start-btn" class="btn btn-success mb-3">🎤 Start Voice Chat</button>
      <button id="voice-stop-btn" class="btn btn-danger mb-3" disabled>⏹ Stop Voice Chat</button>
      <div id="voice-text" style="background:#182135; padding:12px; border-radius:6px; min-height:36px; color:#8ab4f8; font-family: monospace;"></div>
    </div>

    <div id="tab-export" class="tabcontent" role="tabpanel" aria-labelledby="tab-btn-export" hidden>
      <h5>Export & Import Chat History</h5>
      <button id="export-json-btn" class="btn btn-outline-primary mb-2">Export as JSON</button>
      <button id="export-txt-btn" class="btn btn-outline-secondary mb-2">Export as Text</button>
      <hr />
      <label for="import-json-input" class="form-label">Import chat from JSON file</label>
      <input type="file" id="import-json-input" accept="application/json" class="form-control mb-2" />
      <small class="form-text text-muted">Imported chat messages will replace current history.</small>
    </div>
  </section>

  <section id="chat-area" role="main" aria-label="Chat conversation">
    <div id="msgs" tabindex="0" aria-live="polite" aria-atomic="false"></div>
    <div id="typing-indicator" aria-live="assertive" aria-atomic="true" style="display:none;">
      AI is typing &nbsp;
      <span class="typing-dot"></span>
      <span class="typing-dot"></span>
      <span class="typing-dot"></span>
    </div>

    <form id="input-form" autocomplete="off" role="search" aria-label="Chat input form" style="padding:10px 20px; background:#1f263b; display:flex; align-items: center;">
      <input id="user-input" name="message" type="search" placeholder="Ask me anything..." aria-label="Message input" autocomplete="off"
        style="flex-grow:1; font-size:16px; padding: 12px 16px; border-radius: 30px; border:none; color:#ddeeff; background:#293046;" />
      <button id="send-btn" type="submit"
        style="margin-left:12px; padding:0 20px; background:#3a70ff; border:none; color:white; font-weight:700; font-size:16px; border-radius:30px; cursor:pointer;">Send</button>
    </form>
  </section>
</div>

<script>
  // Wait for all external scripts to load
  window.addEventListener('load', () => {
    // Module scoped code...

    // Cache DOM refs for larger UI set
    const tabs = [...document.querySelectorAll('.tabbtn')];
    const tabContents = [...document.querySelectorAll('.tabcontent')];
    const msgs = document.getElementById('msgs');
    const inputForm = document.getElementById('input-form');
    const userInput = document.getElementById('user-input');
    const typingInd = document.getElementById('typing-indicator');
    const sendBtn = document.getElementById('send-btn');

    // Settings elements
    const personalitySelect = document.getElementById('personality-select');
    const useContextCheckbox = document.getElementById('use-context');
    const useExternalCheckbox = document.getElementById('use-external');
    const spellCheckCheckbox = document.getElementById('spellcheck');
    const typingIndicatorCheckbox = document.getElementById('typing-indicator');
    const darkModeCheckbox = document.getElementById('dark-mode');
    const fontSizeSlider = document.getElementById('font-size');
    const fontSizeVal = document.getElementById('font-size-val');
    const typingSpeedSlider = document.getElementById('typing-speed');
    const typingSpeedVal = document.getElementById('typing-speed-val');
    const contextLengthSlider = document.getElementById('context-length');
    const contextLengthVal = document.getElementById('context-length-val');
    const clearChatBtn = document.getElementById('clear-chat');

    // Quiz tab elements
    const startQuizBtn = document.getElementById('start-quiz-btn');
    const quizArea = document.getElementById('quiz-area');

    // Proxy tab elements
    const proxyInput = document.getElementById('proxy-search-input');
    const proxyBtn = document.getElementById('proxy-search-btn');
    const proxyResults = document.getElementById('proxy-search-results');
    const proxyIframeWrapper = document.getElementById('proxy-iframe-wrapper');
    const proxyIframe = document.getElementById('proxy-iframe');
    const proxyLoading = document.getElementById('proxy-loading');

    // Voice tab elements
    const voiceStartBtn = document.getElementById('voice-start-btn');
    const voiceStopBtn = document.getElementById('voice-stop-btn');
    const voiceText = document.getElementById('voice-text');

    // Export tab elements
    const exportJsonBtn = document.getElementById('export-json-btn');
    const exportTxtBtn = document.getElementById('export-txt-btn');
    const importJsonInput = document.getElementById('import-json-input');

    // Global state
    const settings = {
      personality: 'friendly',
      useContext: true,
      useExternalData: true,
      enableSpellCheck: true,
      useTypingDelay: true,
      darkMode: true,
      fontSize: 16,
      typingSpeedMs: 30,
      maxMemorySteps: 5
    };

    let chatMemory = [];
    let quizState = null;

    // ------------------
    // UTILS
    // ------------------

    // Sanitize input/output HTML using DOMPurify
    function sanitize(html) {
      return DOMPurify.sanitize(html);
    }

    // Linkify URLs
    function linkify(text) {
      const urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
      return text.replace(urlRegex, url => `<a href="${url}" target="_blank" rel="noopener noreferrer">${url}</a>`);
    }

    // Append a message bubble to chat
    function appendMsg(text, role = 'ai') {
      if (!text) return;
      const div = document.createElement('div');
      div.className = 'msg ' + (role === 'user' ? 'user' : 'ai') + ' animate__animated animate__fadeInUp';
      div.innerHTML = sanitize(linkify(text));
      msgs.appendChild(div);
      msgs.scrollTo({ top: msgs.scrollHeight, behavior: 'smooth' });
    }

    // Save/load chat memory
    function saveChatMemory() {
      localStorage.setItem('ultimateAIChatMem', JSON.stringify(chatMemory.slice(-settings.maxMemorySteps * 2)));
    }

    function loadChatMemory() {
      try {
        const mem = localStorage.getItem('ultimateAIChatMem');
        if (mem) {
          chatMemory = JSON.parse(mem);
          for (const m of chatMemory) {
            appendMsg(m.text, m.role === 'user' ? 'user' : 'ai');
          }
        }
      } catch {}
    }

    // Spell correction
    function spellCorrect(text) {
      const corrections = { 'adn': 'and', 'teh': 'the', 'beleive': 'believe', 'realy': 'really', 'recieve': 'receive', 'exmaple': 'example' };
      return text.replace(/\b\w+\b/g, word => corrections[word.toLowerCase()] || word);
    }

    // Math evaluation (simple and safe)
    function parseMath(text) {
      let expr = text.toLowerCase().replace(/[^0-9+\-*/()., ]/g, '').replace(/,/g, '');
      try {
        // eslint-disable-next-line no-eval
        let val = eval(expr);
        if (typeof val === 'number' && isFinite(val)) return val;
      } catch { }
      return null;
    }

    // Encode HTML entities for trivia questions
    function decodeHtml(html) {
      const txt = document.createElement("textarea");
      txt.innerHTML = html;
      return txt.value;
    }

    // Shuffle array inplace
    function shuffle(array) {
      for (let i = array.length - 1; i > 0; i--) {
        let j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
      }
    }

    // Show/hide loading on proxy iframe
    function showProxyLoading(show = true) {
      proxyLoading.style.display = show ? 'block' : 'none';
      proxyIframe.style.display = show ? 'none' : 'block';
    }


    // -------------------
    // SETTINGS MANAGEMENT
    // -------------------

    function applySettingsUI() {
      personalitySelect.value = settings.personality;
      useContextCheckbox.checked = settings.useContext;
      useExternalCheckbox.checked = settings.useExternalData;
      spellCheckCheckbox.checked = settings.enableSpellCheck;
      typingIndicatorCheckbox.checked = settings.useTypingDelay;
      darkModeCheckbox.checked = settings.darkMode;
      fontSizeSlider.value = settings.fontSize;
      fontSizeVal.textContent = settings.fontSize;
      typingSpeedSlider.value = settings.typingSpeedMs;
      typingSpeedVal.textContent = settings.typingSpeedMs;
      contextLengthSlider.value = settings.maxMemorySteps;
      contextLengthVal.textContent = settings.maxMemorySteps;
      applyAppearance();
    }

    function saveSettings() {
      localStorage.setItem('ultimateAISettings', JSON.stringify(settings));
    }

    function loadSettings() {
      try {
        const stored = localStorage.getItem('ultimateAISettings');
        if (stored) Object.assign(settings, JSON.parse(stored));
      } catch { }
      applySettingsUI();
    }

    function applyAppearance() {
      if (settings.darkMode) {
        document.body.classList.remove('light-mode');
      } else {
        document.body.classList.add('light-mode');
      }
      msgs.style.fontSize = settings.fontSize + 'px';
    }

    // Attach listeners to settings UI controls
    function attachSettingsListeners() {
      personalitySelect.addEventListener('change', e => {
        settings.personality = e.target.value;
        saveSettings();
      });
      useContextCheckbox.addEventListener('change', e => {
        settings.useContext = e.target.checked;
        saveSettings();
      });
      useExternalCheckbox.addEventListener('change', e => {
        settings.useExternalData = e.target.checked;
        saveSettings();
      });
      spellCheckCheckbox.addEventListener('change', e => {
        settings.enableSpellCheck = e.target.checked;
        saveSettings();
      });
      typingIndicatorCheckbox.addEventListener('change', e => {
        settings.useTypingDelay = e.target.checked;
        saveSettings();
      });
      darkModeCheckbox.addEventListener('change', e => {
        settings.darkMode = e.target.checked;
        applyAppearance();
        saveSettings();
      });
      fontSizeSlider.addEventListener('input', e => {
        settings.fontSize = Number(e.target.value);
        fontSizeVal.textContent = settings.fontSize;
        applyAppearance();
        saveSettings();
      });
      typingSpeedSlider.addEventListener('input', e => {
        settings.typingSpeedMs = Number(e.target.value);
        typingSpeedVal.textContent = settings.typingSpeedMs;
        saveSettings();
      });
      contextLengthSlider.addEventListener('input', e => {
        settings.maxMemorySteps = Number(e.target.value);
        contextLengthVal.textContent = settings.maxMemorySteps;
        saveSettings();
      });
      clearChatBtn.addEventListener('click', () => {
        if (confirm('Clear chat history permanently?')) {
          chatMemory = [];
          msgs.innerHTML = '';
          saveChatMemory();
        }
      });
    }

    // -------------------
    // TAB NAVIGATION
    // -------------------
    function initTabs() {
      tabs.forEach(btn => {
        btn.addEventListener('click', () => {
          tabs.forEach(b => {
            b.classList.remove('active');
            const tid = b.getAttribute('aria-controls');
            const tabc = document.getElementById(tid);
            if (tabc) {
              tabc.hidden = true;
              tabc.setAttribute('aria-hidden', 'true');
            }
            b.setAttribute('aria-selected', 'false');
          });
          btn.classList.add('active');
          const showid = btn.getAttribute('aria-controls');
          const showTab = document.getElementById(showid);
          if (showTab) {
            showTab.hidden = false;
            showTab.setAttribute('aria-hidden', 'false');
          }
          btn.setAttribute('aria-selected', 'true');
        });
      });
    }

    // -------------------
    // CHAT MEMORY/CONTEXT
    // -------------------
    function addToMemory(role, text) {
      chatMemory.push({ role, text });
      let maxLen = settings.maxMemorySteps * 2;
      if (chatMemory.length > maxLen) {
        chatMemory.splice(0, chatMemory.length - maxLen);
      }
      saveChatMemory();
    }

    function contextText() {
      if (!settings.useContext) return '';
      let relevant = chatMemory.slice(-settings.maxMemorySteps * 2);
      return relevant.map(m => (m.role === 'user' ? "User: " : "AI: ") + m.text).join('\n');
    }

    // -------------------
    // AI RESPONSE GENERATION (BIG switch)
    // -------------------

    // API keys - add your own keys at bottom to enable
    const OPENAI_API_KEY = ''; // Optional user key for GPT calls - leave blank for safety

    // Fallback Q&A local knowledge
    const fallbackQA = {
      "how many continents are there": "There are 7 continents on Earth.",
      "what color do you get when you mix red and blue": "You get purple.",
      "who was abraham lincoln": "He was the 16th President of the United States.",
      "what is the largest planet": "Jupiter is the largest planet.",
      "how many legs does a spider have": "A spider has 8 legs.",
      "chemical formula of water": "H₂O is the chemical formula of water.",
      "what is photosynthesis": "Photosynthesis is the process plants use to turn sunlight into energy.",
      "who is the president of the united states": "Joe Biden."
    };

    // DuckDuckGo Instant Answer API
    async function duckDuckGoQuery(query) {
      try {
        const url = `https://api.duckduckgo.com/?q=${encodeURIComponent(query)}&format=json&skip_disambig=1&no_redirect=1`;
        const res = await fetch(url);
        if (!res.ok) return null;
        return await res.json();
      } catch { return null; }
    }

    // Wikipedia summary API
    async function wikiSummary(query) {
      try {
        const url = `https://en.wikipedia.org/api/rest_v1/page/summary/${encodeURIComponent(query)}`;
        const res = await fetch(url);
        if (!res.ok) return null;
        const data = await res.json();
        if (data.extract) {
          let link = data.content_urls?.desktop?.page || `https://en.wikipedia.org/wiki/${encodeURIComponent(query)}`;
          return `${data.extract}\n\n<a href="${link}" target="_blank" rel="noopener noreferrer">More on Wikipedia</a>`;
        }
        return null;
      } catch {
        return null;
      }
    }

    // Numbers API trivia fetch
    async function numbersFact(num) {
      try {
        const res = await fetch(`https://numbersapi.com/${num}/trivia?json`);
        if (!res.ok) return null;
        const data = await res.json();
        return data.text || null;
      } catch {
        return null;
      }
    }

    // Open Trivia DB random question
    async function openTrivia() {
      try {
        const res = await fetch('https://opentdb.com/api.php?amount=1&type=multiple&difficulty=easy');
        if (!res.ok) return null;
        const data = await res.json();
        if (!data.results || !data.results.length) return null;
        return data.results[0];
      } catch {
        return null;
      }
    }

    // NewsAPI org demo (No API key) - returns top tech news (via a proxy or local server needed for CORS in real use)
    async function fetchNews() {
      try {
        // Use a public CORS proxy + free tech news endpoint (example only)
        // This is a placeholder, replace with your own backend if needed.
        const url = 'https://api.currentsapi.services/v1/latest-news?category=technology&apiKey=demo'; 
        // CurrentsAPI requires key in prod, this demo won't work
        const res = await fetch(url);
        if (!res.ok) return null;
        const data = await res.json();
        return data.news.slice(0,5).map(n => `${n.title}\n${n.description}\n<a href="${n.url}" target="_blank">${n.url}</a>`).join('\n\n');
      } catch { return null; }
    }

    // Open-Meteo weather API demo
    async function fetchWeather(city = 'London') {
      try {
        const geo = await fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city)}&count=1`);
        const geoData = await geo.json();
        if (!geoData.results || !geoData.results.length) return null;
        const lat = geoData.results[0].latitude;
        const lon = geoData.results[0].longitude;
        const weatherRes = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}&current_weather=true`);
        if (!weatherRes.ok) return null;
        const weatherData = await weatherRes.json();
        if (!weatherData.current_weather) return null;
        return `Current temperature in ${city}: ${weatherData.current_weather.temperature}°C, wind speed: ${weatherData.current_weather.windspeed} km/h`;
      } catch { return null; }
    }

    // Currency exchange rate API (exchangerate.host)
    async function currencyConvert(from = 'USD', to = 'EUR') {
      try {
        const url = `https://api.exchangerate.host/convert?from=${from.toUpperCase()}&to=${to.toUpperCase()}`;
        const res = await fetch(url);
        if (!res.ok) return null;
        const data = await res.json();
        if (!data.result) return null;
        return `1 ${from.toUpperCase()} = ${data.result.toFixed(4)} ${to.toUpperCase()}`;
      } catch { return null; }
    }

    // Merriam-Webster dictionary demo (uses OwlBot API because Merriam-Webster needs API key)
    async function dictionaryLookup(word) {
      try {
        const res = await fetch(`https://owlbot.info/api/v4/dictionary/${encodeURIComponent(word)}`, {
          headers: { "Authorization": "Token ..." /* Replace with key if you have OwlBot key */ }
        });
        if(!res.ok) return null;
        const data = await res.json();
        const defs = data.definitions.map(d => `(${d.type}) ${d.definition}`).join('\n');
        return `${word}:\n${defs}`;
      } catch { return null; }
    }

    // Demo translator function (using LibreTranslate Anonymous API)
    async function translateText(text, target = 'es') {
      try {
        const res = await fetch('https://libretranslate.com/translate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ q: text, source: 'en', target })
        });
        if (!res.ok) return null;
        const data = await res.json();
        return data.translatedText;
      } catch { return null; }
    }

    // API: Spell check demo (via languagetool public API)
    async function grammarCheck(text) {
      try {
        const res = await fetch('https://api.languagetool.org/v2/check', {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: `text=${encodeURIComponent(text)}&language=en-US`
        });
        if(!res.ok) return null;
        const data = await res.json();
        if(data.matches && data.matches.length){
          return data.matches.map(m=>`Issue: ${m.message} at ${m.offset}-${m.offset+m.length}`).join('\n');
        }
        return 'No grammar errors found.';
      } catch {
        return null;
      }
    }

    // Main AI reply generator - big function handling user input and routing to APIs
    async function generateReply(input) {
      let text = input.trim();
      if (settings.enableSpellCheck) text = spellCorrect(text);

      // If quiz mode active
      if (quizState) {
        const choice = Number(text);
        if (!isNaN(choice) && choice >= 1 && choice <= quizState.options.length) {
          const answer = quizState.options[choice - 1];
          if (answer === quizState.correct_answer) {
            quizState = null;
            return "Correct! Nice job. Ask me for another quiz anytime.";
          } else {
            return "Oops, wrong answer. Try again or type 'skip' to skip the quiz.";
          }
        }
        if (text.toLowerCase() === 'skip') {
          quizState = null;
          return "Quiz skipped. Ask me anything else or start a new quiz.";
        }
        return "Please respond with the option number or type 'skip'.";
      }

      // Greetings
      if (/^(hello|hi|hey|yo|hola|greetings)/i.test(text)) {
        if (settings.personality === 'friendly') return "Hello! Ask me any question about math, trivia, or general knowledge and I'll help.";
        if (settings.personality === 'formal') return "Good day. Please ask your question.";
        if (settings.personality === 'funny') return "Yo yo! Ready to get smart? Fire away!";
      }

      // Math evaluation
      const mathResult = parseMath(text);
      if (mathResult !== null) return `The answer is ${mathResult}.`;

      // Spell word query
      const spellMatch = text.match(/\bspell\s+(\w+)/i);
      if (spellMatch) {
        const w = spellMatch[1].toUpperCase();
        return `${w.split('').join('-')} spells ${spellMatch[1]}.`;
      }

      // Number fact request
      const numbMatch = text.match(/number fact for (\d+)/i);
      if (numbMatch) {
        const fact = await numbersFact(numbMatch[1]);
        if (fact) return `Did you know? ${fact}`;
      }

      // Quiz request
      if (/\b(quiz|trivia|question)\b/i.test(text)) {
        const trivia = await openTrivia();
        if (trivia) {
          let options = [...trivia.incorrect_answers, trivia.correct_answer];
          options = options.map(decodeHtml);
          shuffle(options);
          quizState = {
            question: decodeHtml(trivia.question),
            correct_answer: decodeHtml(trivia.correct_answer),
            options
          };
          let msg = `Trivia question:\n${quizState.question}\nOptions:\n`;
          options.forEach((opt, i) => { msg += `${i + 1}: ${opt}\n`; });
          msg += '\nType your answer option number or "skip".';
          return msg;
        }
      }

      // API lookups if enabled
      if (settings.useExternalData) {
        // DuckDuckGo instant answer
        const ddg = await duckDuckGoQuery(text);
        if (ddg && ddg.AbstractText && ddg.AbstractText.trim().length > 3) {
          let ans = ddg.AbstractText;
          if (ddg.AbstractURL) {
            ans += `\n\n<a href="${ddg.AbstractURL}" target="_blank" rel="noopener">Read more on DuckDuckGo</a>`;
          }
          return ans;
        }

        // Wikipedia summary fallback
        const wiki = await wikiSummary(text);
        if (wiki) return wiki;

        // Demo translation if starts with translate: "translate hello to es"
        const transMatch = text.match(/^translate\s+(.*?)\s+to\s+(\w{2})$/i);
        if (transMatch) {
          const tr = await translateText(transMatch[1], transMatch[2]);
          if (tr) return `Translation (${transMatch[2]}): ${tr}`;
        }

        // Weather query "weather in city"
        const weatherMatch = text.match(/weather in (.+)/i);
        if (weatherMatch) {
          const w = await fetchWeather(weatherMatch[1]);
          if (w) return w;
        }

        // Currency convert "convert 100 usd to eur"
        const currencyMatch = text.match(/convert\s+(\d+(?:\.\d+)?)\s+(\w{3})\s+to\s+(\w{3})/i);
        if (currencyMatch) {
          const v = Number(currencyMatch[1]);
          const from = currencyMatch[2];
          const to = currencyMatch[3];
          const rate = await currencyConvert(from, to);
          if (rate) return `${v} ${from.toUpperCase()} is approx ${(rate.split('=')[1] * v).toFixed(4)} ${to.toUpperCase()}\n(Rate: ${rate})`;
        }

        // Grammar check if command starts with "check grammar:"
        const grammarMatch = text.match(/^check grammar:\s*(.+)$/i);
        if (grammarMatch) {
          const checkRes = await grammarCheck(grammarMatch[1]);
          if (checkRes) return checkRes;
        }
      }

      // Fall back to local answer dictionary
      const key = text.toLowerCase().replace(/[?.!]/g, '').trim();
      if (fallbackQA[key]) return fallbackQA[key];

      // Personality fallback reply
      const fallbackMsgs = {
        friendly: "Hmm... I don't know that one. Try asking me a math question or trivia!",
        formal: "Apologies, the information is unavailable. Please ask something else.",
        funny: "I can't help you with that... maybe take a snack break and try again!"
      };
      return fallbackMsgs[settings.personality] || fallbackMsgs.friendly;
    }

    // ----------------------------
    // Typing indicator + bot reply
    // ----------------------------
    async function botReplyWithTyping(text) {
      if (!settings.useTypingDelay) {
        appendMsg(text, 'ai');
        return;
      }
      typingInd.style.display = 'flex';
      sendBtn.disabled = true;
      userInput.disabled = true;

      const delay = Math.max(700, text.length * settings.typingSpeedMs);
      await new Promise(r => setTimeout(r, delay));

      typingInd.style.display = 'none';
      appendMsg(text, 'ai');
      sendBtn.disabled = false;
      userInput.disabled = false;
      userInput.focus();
    }

    // ----------------------------
    // CHAT FORM SUBMIT HANDLER
    // ----------------------------
    inputForm.addEventListener('submit', async e => {
      e.preventDefault();
      const val = userInput.value.trim();
      if (!val) return;
      appendMsg(val, 'user');
      addToMemory('user', val);
      userInput.value = '';
      userInput.disabled = true;

      try {
        const reply = await generateReply(val);
        await botReplyWithTyping(reply);
        addToMemory('ai', reply);
      } catch (ex) {
        // Fallback
        await botReplyWithTyping("Sorry, something went wrong. Please try again.");
      }

      userInput.disabled = false;
      userInput.focus();
    });

    // -------------------------
    // PROXY SEARCH FUNCTIONALITY
    // -------------------------
    proxyBtn.addEventListener('click', async () => {
      const q = proxyInput.value.trim();
      if (!q) return;
      proxyResults.innerHTML = 'Searching <span class="spinner-border spinner-border-sm"></span>';
      proxyIframe.srcdoc = "<p style='font-family:sans-serif;color:#666;text-align:center;padding:2rem;'>Search results or embedded website will show here.</p>";
      proxyIframe.style.display = 'none';
      proxyLoading.style.display = 'block';

      try {
        const ddgData = await duckDuckGoQuery(q);
        if (ddgData && ddgData.RelatedTopics && ddgData.RelatedTopics.length) {
          proxyResults.innerHTML = '';
          for (const item of ddgData.RelatedTopics.slice(0, 10)) {
            if (item.Text) {
              const p = document.createElement('p');
              p.innerHTML = `<a href="${item.FirstURL}" target="_blank" rel="noopener noreferrer">${item.Text}</a>`;
              p.style.cursor = 'pointer';
              p.addEventListener('click', e => {
                e.preventDefault();
                loadInIframe(item.FirstURL);
              });
              proxyResults.appendChild(p);
            } else if (item.Topics) {
              item.Topics.slice(0, 3).forEach(topic => {
                const p = document.createElement('p');
                p.innerHTML = `<a href="${topic.FirstURL}" target="_blank" rel="noopener noreferrer">${topic.Text}</a>`;
                p.style.cursor = 'pointer';
                p.addEventListener('click', e => {
                  e.preventDefault();
                  loadInIframe(topic.FirstURL);
                });
                proxyResults.appendChild(p);
              });
            }
          }
          proxyLoading.style.display = 'none';
          proxyIframe.style.display = 'none';
        } else {
          proxyResults.textContent = 'No results found.';
          proxyLoading.style.display = 'none';
          proxyIframe.style.display = 'none';
        }
      } catch (error) {
        proxyResults.textContent = 'Error during search.';
        proxyLoading.style.display = 'none';
        proxyIframe.style.display = 'none';
      }
    });

    function loadInIframe(url) {
      showProxyLoading(true);
      proxyIframe.src = url;
      proxyResults.innerHTML = '';
      proxyIframe.style.display = 'block';

      proxyIframe.onload = () => {
        showProxyLoading(false);
      };
      proxyIframe.onerror = () => {
        proxyLoading.style.display = 'none';
        proxyIframe.style.display = 'none';
        proxyResults.textContent = 'Failed to load page in proxy iframe.';
      };
    }

    // -------------------------
    // QUIZ TOOL
    // -------------------------
    startQuizBtn.addEventListener('click', async () => {
      quizArea.textContent = 'Loading quiz...';
      const trivia = await openTrivia();
      if (!trivia) {
        quizArea.textContent = 'Failed to load question. Try again later.';
        return;
      }
      let options = [...trivia.incorrect_answers, trivia.correct_answer].map(decodeHtml);
      shuffle(options);
      quizState = {
        question: decodeHtml(trivia.question),
        correct_answer: decodeHtml(trivia.correct_answer),
        options
      };
      let msg = `Trivia question:\n${quizState.question}\nOptions:\n`;
      quizState.options.forEach((o, i) => msg += `${i + 1}: ${o}\n`);
      msg += `\nType your answer option number in chat or 'skip'.`;
      quizArea.textContent = msg;
    });

    // -------------------------
    // VOICE CHAT - Web Speech API
    // -------------------------

    let recognition = null;
    let speechSynthesisObj = window.speechSynthesis;
    voiceStopBtn.disabled = true;

    if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
      const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
      recognition = new SpeechRecognition();
      recognition.lang = 'en-US';
      recognition.interimResults = false;
      recognition.maxAlternatives = 1;

      recognition.onresult = evt => {
        const spoken = evt.results[0][0].transcript;
        voiceText.textContent = 'You: ' + spoken;
        // Submit as chat message
        appendMsg(spoken, 'user');
        addToMemory('user', spoken);
        replyViaAI(spoken);
      };
      recognition.onerror = evt => {
        voiceText.textContent = 'Speech recognition error: ' + evt.error;
        voiceStopBtn.disabled = true;
        voiceStartBtn.disabled = false;
      };
      recognition.onend = () => {
        voiceText.textContent += " (Stopped)";
        voiceStopBtn.disabled = true;
        voiceStartBtn.disabled = false;
      };
    } else {
      voiceText.textContent = 'Speech recognition not supported in this browser.';
      voiceStartBtn.disabled = true;
    }

    async function replyViaAI(text) {
      try {
        const reply = await generateReply(text);
        await botReplyWithTyping(reply);
        addToMemory('ai', reply);
        // Speak reply
        if (speechSynthesisObj) {
          const utterance = new SpeechSynthesisUtterance(reply);
          utterance.lang = 'en-US';
          speechSynthesisObj.speak(utterance);
        }
      } catch {
        await botReplyWithTyping("Sorry, I couldn't process your voice input.");
      }
    }

    voiceStartBtn.addEventListener('click', () => {
      if (recognition) {
        recognition.start();
        voiceText.textContent = 'Listening... Speak now';
        voiceStartBtn.disabled = true;
        voiceStopBtn.disabled = false;
      }
    });
    voiceStopBtn.addEventListener('click', () => {
      if (recognition) {
        recognition.stop();
        voiceStartBtn.disabled = false;
        voiceStopBtn.disabled = true;
      }
    });

    // -------------------------
    // EXPORT / IMPORT CHAT
    // -------------------------

    exportJsonBtn.addEventListener('click', () => {
      if (chatMemory.length === 0) {
        Swal.fire('Info', 'No chat history to export.', 'info');
        return;
      }
      const dataStr = JSON.stringify(chatMemory, null, 2);
      const blob = new Blob([dataStr], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `chat-history-${Date.now()}.json`;
      a.click();
      URL.revokeObjectURL(url);
    });

    exportTxtBtn.addEventListener('click', () => {
      if (chatMemory.length === 0) {
        Swal.fire('Info', 'No chat history to export.', 'info');
        return;
      }
      const txt = chatMemory.map(m => `${m.role.toUpperCase()}:\n${m.text}\n`).join('\n');
      const blob = new Blob([txt], { type: 'text/plain' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `chat-history-${Date.now()}.txt`;
      a.click();
      URL.revokeObjectURL(url);
    });

    importJsonInput.addEventListener('change', e => {
      const file = e.target.files[0];
      if (!file) return;
      const reader = new FileReader();
      reader.onload = evt => {
        try {
          const mem = JSON.parse(evt.target.result);
          if (!Array.isArray(mem)) throw new Error('Invalid format');
          chatMemory = mem;
          msgs.innerHTML = '';
          chatMemory.forEach(m => appendMsg(m.text, m.role === 'user' ? 'user' : 'ai'));
          saveChatMemory();
          Swal.fire('Success', 'Chat history imported successfully.', 'success');
          importJsonInput.value = '';
        } catch {
          Swal.fire('Error', 'Invalid JSON file.', 'error');
        }
      };
      reader.readAsText(file);
    });

    // -------------------------
    // INITIALIZATION
    // -------------------------

    function init() {
      initTabs();
      loadSettings();
      attachSettingsListeners();
      loadChatMemory();
      applySettingsUI();
    }

    init();

  });
</script>

</body>
</html>