Analise o seguinte script e identifique soluções para reduzir o atraso nas vozes online utilizadas para leitura de legendas, a fim de otimizar a dublagem automática de vídeos: 

// ==UserScript==
// @name         Multi-Platform AutoDub Enhanced Com Translator 000
// @version      8.200
// @description  Automatic dubbing for YouTube and Coursera videos with advanced UI, synchronization, language-based dubbing, and multiple narration modes
// @match        https://www.youtube.com/*
// @match        https://www.coursera.org/learn/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @require      https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js
// ==/UserScript==

(function () {
    'use strict';

    // Estilos CSS para a interface do usuário
    GM_addStyle(`
        @import url('https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css');
        @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css');

        #auto-dub-floating-btn {
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 9999;
            width: 50px;
            height: 50px;
            font-size: 24px;
            border-radius: 50%;
            box-shadow: 0 2px 5px rgba(0,0,0,0.3);
            color: white;
            border: none;
            opacity: 0.30;
            transition: opacity 0.3s ease;
        }

        #auto-dub-floating-btn:hover {
            opacity: 1;
        }

        #auto-dub-popup {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            z-index: 10000;
            width: 320px;
            height: 580px;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            overflow-y: auto;
            transition: opacity 0.3s ease;
        }

        #auto-dub-popup:hover {
            opacity: 1;
        }

        #auto-dub-popup .card {
            border: none;
            height: 100%;
        }

        #auto-dub-popup .card-header {
            color: white;
            border-bottom: none;
            border-radius: 8px 8px 0 0;
        }

        #auto-dub-popup .card-body {
            padding: 1rem;
            height: calc(100% - 130px);
            overflow-y: auto;
        }

        #auto-dub-popup .form-label {
            font-weight: 500;
            margin-bottom: 0.25rem;
        }

        #auto-dub-popup .form-select,
        #auto-dub-popup .form-control {
            border-radius: 4px;
        }

        .custom-range-container {
            display: flex;
            align-items: center;
        }

        .custom-range-container input[type="range"] {
            flex-grow: 1;
            margin-right: 10px;
        }

        .custom-range-container input[type="number"] {
            width: 60px;
        }

        /* Estilos para o tema padrão */
        #auto-dub-popup.default {
            background-color: #f8f9fa;
            color: #333;
        }

        #auto-dub-popup.default .card {
            background: linear-gradient(to right, #ee7724, #d8363a, #7a082f);
        }

        #auto-dub-popup.default .card-header {
            background-color: #007bff;
        }

        /* Estilos para o tema futurista */
        #auto-dub-popup.futuristic {
            background-color: #000;
            color: #0ff;
            border: 2px solid #0ff;
        }

        #auto-dub-popup.futuristic .card {
            background: linear-gradient(to right, #000, #001, #002);
        }

        #auto-dub-popup.futuristic .card-header {
            background-color: #0ff;
            color: #000;
        }

        #auto-dub-popup.futuristic .btn {
            background-color: #0ff;
            color: #000;
            border: none;
        }

        /* Estilos para o tema minimalista */
        #auto-dub-popup.minimalist {
            background-color: #fff;
            color: #333;
            border: 1px solid #ddd;
        }

        #auto-dub-popup.minimalist .card {
            background: #fff;
        }

        #auto-dub-popup.minimalist .card-header {
            background-color: #f8f9fa;
            color: #333;
        }

        #auto-dub-popup.minimalist .btn {
            background-color: #f8f9fa;
            color: #333;
            border: 1px solid #ddd;
        }

        /* Estilos para o tema gamer */
        #auto-dub-popup.gamer {
            background-color: #1a1a1a;
            color: #0f0;
            border: 3px solid #0f0;
        }

        #auto-dub-popup.gamer .card {
            background: linear-gradient(to right, #1a1a1a, #2a2a2a, #3a3a3a);
        }

        #auto-dub-popup.gamer .card-header {
            background-color: #0f0;
            color: #000;
        }

        #auto-dub-popup.gamer .btn {
            background-color: #0f0;
            color: #000;
            border: none;
            text-transform: uppercase;
            font-weight: bold;
        }

        #auto-dub-subtitles {
            position: absolute;
            bottom: 60px;
            left: 50%;
            transform: translateX(-50%);
            color: white;
            text-shadow: 1px 1px 1px black;
            font-size: 24px;
            text-align: center;
            z-index: 1000;
            padding: 5px 10px;
            background-color: rgba(0, 0, 0, 0.7);
            border-radius: 5px;
        }

        .mode-indicator {
            position: fixed;
            top: 10px;
            right: 10px;
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 5px 10px;
            border-radius: 5px;
            z-index: 9999;
        }

        /* Estilos específicos para o Coursera */
        .rc-VideoContainer #auto-dub-popup {
            font-size: 14px;
        }

        .rc-VideoContainer #auto-dub-popup .mb-3 {
            margin-bottom: 0.75rem !important;
        }

        /* Estilos para os botões flutuantes */
        .floating-button {
            position: absolute;
            z-index: 9998;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            opacity: 0; /* Inicialmente invisível */
            transition: opacity 0.3s ease;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
        }

        .floating-button:hover {
            opacity: 1; /* Visível ao passar o mouse */
        }

        #play-button {
            top: 10px;
            right: 60px;
        }

        #settings-button {
            top: 10px;
            right: 10px;
        }

        /* Aplica a opacidade aos botões quando o mouse estiver sobre o player */
        #movie_player:hover .floating-button,
        .rc-VideoContainer:hover .floating-button {
            opacity: 1;
        }
    `);

    class AudioSync {
        constructor(audioElement) {
            this.audio = audioElement;
            this.playbackRate = 1;
            this.MIN_PLAYBACK_RATE = 0.85;
            this.MAX_PLAYBACK_RATE = 1.15;
            this.playbackRateAdjustments = [];
            this.MAX_ADJUSTMENT_HISTORY = 10;
        }

        adjustPlaybackRate(timeDifference) {
            let rateAdjustment = timeDifference / 1000;
            rateAdjustment = Math.max(rateAdjustment, this.MIN_PLAYBACK_RATE - this.playbackRate);
            rateAdjustment = Math.min(rateAdjustment, this.MAX_PLAYBACK_RATE - this.playbackRate);
            this.playbackRate += rateAdjustment;
            this.playbackRateAdjustments.push(rateAdjustment);
            if (this.playbackRateAdjustments.length > this.MAX_ADJUSTMENT_HISTORY) {
                this.playbackRateAdjustments.shift();
            }
            this.audio.playbackRate = this.playbackRate;
        }

        getAveragePlaybackRateAdjustment() {
            if (this.playbackRateAdjustments.length === 0) {
                return 0;
            }
            return this.playbackRateAdjustments.reduce((sum, adjustment) => sum + adjustment, 0) / this.playbackRateAdjustments.length;
        }
    }

    class EnhancedAutoDubbing {
        constructor() {
            this.captionData = [];
            this.isActive = false;
            this.currentVoice = null;
            this.currentLanguage = '';
            this.audioContext = null;
            this.gainNode = null;
            this.video = null;
            this.speechQueue = [];
            this.lastSpeechEndTime = 0;
            this.subtitlesEnabled = false;
            this.subtitleContainer = null;
            this.originalPlaybackRate = 1;
            this.speakingControlMode = 'speedUp';
            this.narrationMode = 'simple';
            this.dubbingMode = 'normal';
            this.modeIndicator = null;
            this.normalPlaybackRate = 0.85;
            this.platform = this.detectPlatform();
            this.isDarkMode = GM_getValue('isDarkMode', false);
            this.perfectDubbingEnabled = false;
            this.audio = new Audio();
            this.videoSubtitles = { list: [] };
            this.lipSyncInterval = null;
            this.maxSpeed = 1;
            this.userConfiguredSpeed = 1;
            this.audioSync = null;
            this.lastSyncTime = 0;
            this.isDragging = false;
            this.dragStartX = 0;
            this.dragStartY = 0;
            this.isDraggingCourseraBtn = false;
            this.courseraBtnDragStartX = 0;
            this.courseraBtnDragStartY = 0;

            this.targetLanguageSelect = null;
            this.translateCaptionsCheckbox = null;

            this.currentTheme = 'default'; // Propriedade para armazenar o tema atual

            this.initializeAudioContext();
            this.createUI();
            this.setupVoices();
            this.addEventListeners();
            this.setupMutationObserver();
        }

        detectPlatform() {
            if (window.location.hostname.includes('youtube.com')) {
                return 'youtube';
            } else if (window.location.hostname.includes('coursera.org')) {
                return 'coursera';
            }
            return 'unknown';
        }

        initializeAudioContext() {
            this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
            this.gainNode = this.audioContext.createGain();
            this.gainNode.connect(this.audioContext.destination);
        }

        async setupVoices() {
            if (speechSynthesis.getVoices().length === 0) {
                await new Promise(resolve => speechSynthesis.onvoiceschanged = resolve);
            }
            this.populateVoiceList();
            this.loadLastUsedVoice();
            this.loadSettings();
            this.updateCurrentLanguage();
        }

        updateCurrentLanguage() {
            this.currentLanguage = this.currentVoice.lang.split('-')[0];
        }

        async fetchCaptionData() {
            if (this.platform === 'youtube') {
                try {
                    const videoId = this.getVideoId();
                    const url = await this.fetchCaptionDataUrl(this.currentLanguage);
                    if (!url) {
                        throw new Error("Caption URL not found");
                    }

                    const response = await fetch(url);
                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }

                    const json = await response.json();
                    this.processCaptions(json.events);
                } catch (error) {
                    console.error("Error fetching caption data:", error);
                }
            } else if (this.platform === 'coursera') {
                let activeCaption = this.getActiveCaption();
                if (!activeCaption) {
                    console.log("Nenhuma legenda ativa encontrada!");
                    return;
                }
                this.captionData = Array.from(activeCaption.track.cues).map(cue => ({
                    tStartMs: cue.startTime * 1000,
                    tEndMs: cue.endTime * 1000,
                    segment: cue.text
                }));
            }

            if (this.translateCaptionsCheckbox.checked) {
                this.captionData = await this.translateCaptions(this.captionData, this.currentLanguage, this.targetLanguageSelect.value);
            }
        }

        getActiveCaption() {
            let captions = document.querySelectorAll('track[kind="captions"]');
            for (let caption of captions) {
                if (caption.track.mode === "showing") {
                    return caption;
                }
            }
            return null;
        }

        getTexts(cues) {
            return cues.map(cue => cue.segment.replace(/\n/g, " ")).join(" z~~~z ");
        }

        processCaptions(events) {
            this.captionData = events.reduce((acc, event) => {
                if (event.segs && Array.isArray(event.segs)) {
                    const segment = event.segs.reduce((text, seg) => text + (seg.utf8 || ''), '').trim();
                    if (segment) {
                        acc.push({
                            tStartMs: event.tStartMs,
                            tEndMs: event.tStartMs + (event.dDurationMs || 0),
                            segment
                        });
                    }
                }
                return acc;
            }, []);
        }

        async translateCaptions(captions, sourceLang, targetLang) {
            try {
                const MAX_LENGTH = 1500;
                const textArrays = [];
                let arrayIndex = 0;

                if (sourceLang === targetLang) {
                    return captions;
                }

                captions.forEach((caption) => {
                    const text = `\n\n${caption.segment}`;
                    const currentArray = textArrays[arrayIndex];
                    const combinedText = currentArray ? currentArray + text : text;

                    if (combinedText.length < MAX_LENGTH) {
                        textArrays[arrayIndex] = combinedText;
                    } else {
                        arrayIndex += 1;
                        textArrays[arrayIndex] = text;
                    }
                });

                const requestUrls = textArrays.map(
                    (text) =>
                        `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sourceLang}&tl=${targetLang}&dt=t&q=${encodeURIComponent(
                            text
                        )}`
                );

                const delay = (ms = 1300) => new Promise((resolve) => setTimeout(resolve, ms));

                const responses = await Promise.all(
                    requestUrls.map(async (url) => {
                        await delay();
                        return fetch(url);
                    })
                );

                const translatedTexts = (
                    await Promise.all(responses.map((response) => response.json()))
                )
                    .map((data) => data[0].map((item) => item[0]).join(''))
                    .join('\n\n')
                    .split('\n\n');

                return translatedTexts.map((text, index) => {
                    const originalCaption = captions[index];
                    return {
                        ...originalCaption,
                        segment: text,
                    };
                });
            } catch (error) {
                console.error('Error translating captions:', error);
                return captions;
            }
        }

        handleTimeUpdate() {
            if (!this.isActive) return;

            let currentTime = this.video.currentTime * 1000;

            if (this.enableDubAdvance.checked) {
                currentTime += parseFloat(this.dubAdvanceControl.value) * 1000;
            }

            if (this.subtitlesEnabled) {
                this.updateSubtitles(currentTime);
            }

            if (this.dubbingMode === 'perfect') {
                this.handlePerfectDubbing(currentTime);
            } else if (this.dubbingMode === 'normal') {
                this.handleNormalDubbing(currentTime);
            } else if (this.dubbingMode === 'advanced') {
                if (this.narrationMode === 'simple') {
                    this.handleSimpleNarration(currentTime);
                } else if (this.narrationMode === 'interactive') {
                    this.handleInteractiveNarration(currentTime);
                }
                this.adjustSynchronization(currentTime);
            }
        }

        handlePerfectDubbing(currentTime) {
            while (this.speechQueue.length > 0 && this.speechQueue[0].startTime <= currentTime) {
                const nextSpeech = this.speechQueue.shift();
                this.speakCaption(nextSpeech.caption);
            }

            if (this.speechQueue.length === 0) {
                const nextCaption = this.getNextCaption(currentTime);
                if (nextCaption) {
                    this.speechQueue.push({ caption: nextCaption, startTime: nextCaption.tStartMs });
                }
            }

            this.lipSync();
        }

        handleNormalDubbing(currentTime) {
            while (this.speechQueue.length > 0 && this.speechQueue[0].startTime <= currentTime) {
                const nextSpeech = this.speechQueue.shift();
                this.speakCaption(nextSpeech.caption);
            }

            if (this.speechQueue.length === 0) {
                const nextCaption = this.getNextCaption(currentTime);
                if (nextCaption) {
                    this.speechQueue.push({ caption: nextCaption, startTime: nextCaption.tStartMs });
                }
            }
        }

        handleSimpleNarration(currentTime) {
            while (this.speechQueue.length > 0 && this.speechQueue[0].startTime <= currentTime) {
                const nextSpeech = this.speechQueue.shift();
                this.speakCaption(nextSpeech.caption);
            }

            if (this.speechQueue.length === 0) {
                const nextCaption = this.getNextCaption(currentTime);
                if (nextCaption) {
                    this.speechQueue.push({ caption: nextCaption, startTime: nextCaption.tStartMs });
                }
            }
        }

        handleInteractiveNarration(currentTime) {
            if (this.speechQueue.length === 0) {
                const nextCaption = this.getNextCaption(currentTime);
                if (nextCaption) {
                    this.speechQueue.push({ caption: nextCaption, startTime: nextCaption.tStartMs });
                    this.video.pause();
                    this.speakCaption(nextCaption);
                }
            }
        }

        adjustSynchronization(currentTime) {
            if (this.speechQueue.length > 0) {
                const nextSpeechTime = this.speechQueue[0].startTime;
                const timeDifference = nextSpeechTime - currentTime;

                if (this.dubbingMode === 'advanced') {
                    const currentSpeed = parseFloat(this.speedControl.value);
                    const maxSpeed = parseFloat(this.maxSpeedControl.value);

                    if (timeDifference < 500) {
                        if (this.speakingControlMode === 'speedUp') {
                            this.speedControl.value = Math.min(currentSpeed + 0.1, maxSpeed);
                        } else {
                            this.video.playbackRate = Math.max(this.video.playbackRate - 0.1, 0.5);
                        }
                    } else if (timeDifference > 1000) {
                        if (this.speakingControlMode === 'speedUp') {
                            this.speedControl.value = Math.max(currentSpeed - 0.1, 1);
                        } else {
                            this.video.playbackRate = Math.min(this.video.playbackRate + 0.1, 1);
                        }
                    } else {
                        this.speedControl.value = this.userConfiguredSpeed;
                    }
                    this.updateRangeValue('speed');
                }
            }
        }

        updateSubtitles(currentTime) {
            const currentCaption = this.captionData.find(caption =>
                caption.tStartMs <= currentTime && caption.tEndMs > currentTime
            );
            if (currentCaption) {
                this.subtitleContainer.textContent = currentCaption.segment;
            } else {
                this.subtitleContainer.textContent = '';
            }
        }

        getNextCaption(currentTime) {
            return this.captionData.find(caption => caption.tStartMs > currentTime);
        }

        speakCaption(caption) {
            const utterance = new SpeechSynthesisUtterance(caption.segment);
            utterance.voice = this.currentVoice;
            utterance.volume = parseFloat(this.volumeControl.value);

            if (this.dubbingMode === 'perfect' && this.audioSync) {
                utterance.rate = this.audioSync.playbackRate;
            } else {
                utterance.rate = parseFloat(this.speedControl.value);
            }

            utterance.pitch = parseFloat(this.pitchControl.value);

            if (this.dubbingMode === 'advanced' && this.narrationMode === 'interactive') {
                utterance.onend = () => {
                    this.video.play();
                };
            }

            speechSynthesis.speak(utterance);
        }

        lipSync() {
            if (!this.video || !this.audio) return;

            const currentTime = this.video.currentTime;
            const currentCaption = this.captionData.find(caption =>
                currentTime * 1000 >= caption.tStartMs && currentTime * 1000 < caption.tEndMs
            );

            if (currentCaption) {
                const elapsedTime = (currentTime * 1000) - currentCaption.tStartMs;

                if (this.audioSync) {
                    this.audioSync.adjustPlaybackRate(elapsedTime);
                }
            }
        }


        startDubbing() {
            this.video = document.querySelector('video');
            if (!this.video) return;

            this.isActive = true;
            this.originalPlaybackRate = this.video.playbackRate;

            if (this.dubbingMode === 'normal') {
                this.video.playbackRate = this.normalPlaybackRate;
            }

            this.video.addEventListener('timeupdate', this.handleTimeUpdate.bind(this));
            this.showModeIndicator();

            if (this.dubbingMode === 'perfect') {
                this.audioSync = new AudioSync(this.audio);
            }
        }

        stopDubbing() {
            if (!this.video) return;

            this.isActive = false;
            this.video.playbackRate = this.originalPlaybackRate;
            speechSynthesis.cancel();
            this.video.removeEventListener('timeupdate', this.handleTimeUpdate.bind(this));
            this.speechQueue = [];
            this.hideModeIndicator();

            if (this.audioSync) {
                this.audioSync = null;
            }
        }

        async fetchCaptionDataUrl(locale) {
            try {
                const playerResponse = await this.fetchYoutubePlayerData();
                if (!playerResponse) {
                    return undefined;
                }
                const captionTracks = playerResponse?.captions?.playerCaptionsTracklistRenderer?.captionTracks;

                const manualCaptions = captionTracks?.filter(track => track.kind !== "asr");
                const autoCaptions = captionTracks?.filter(track => track.kind === "asr");

                const prioritizedTracks = [...(manualCaptions || []), ...(autoCaptions || [])];

                const playLocales = [locale, ...this.getAlternativeLanguages(locale)];

                for (const playLocale of playLocales) {
                    const localeCaptionBaseUrl = prioritizedTracks?.find(track => track.languageCode.startsWith(playLocale))?.baseUrl;
                    if (localeCaptionBaseUrl) return `${localeCaptionBaseUrl}&fmt=json3`;
                }

                if (!prioritizedTracks?.length) {
                    console.log("No captions found", playerResponse);
                    return undefined;
                }

                const baseUrl = prioritizedTracks[0]?.baseUrl;
                if (!baseUrl) {
                    console.log("Unable to get base URL", playerResponse);
                    return undefined;
                }

                return `${baseUrl.replace(/,/g, "%2C")}&fmt=json3&xorb=2&xobt=3&xovt=3&tlang=${locale}`;
            } catch (err) {
                console.log("fetchCaptionDataUrl got error", err);
                return undefined;
            }
        }

        async fetchYoutubePlayerData() {
            try {
                const ytCfgScript = document.evaluate("//script[@nonce and contains(text(),'INNERTUBE_API_KEY')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
                if (!ytCfgScript) {
                    console.log("ERROR: ytcfg.set({\"CLIENT_CANARY_STATE... not found");
                    return undefined;
                }
                const ytCfgJSON = ytCfgScript.innerText.replace(/^[\s\S]*ytcfg\.set\({/g, '{').replace(/}\);\s*window\.ytcfg\.obfuscatedData_ [\s\S]*/, '}');
                const ytConfig = JSON.parse(ytCfgJSON);
                const key = ytConfig?.INNERTUBE_API_KEY;
                const payload = JSON.stringify({
                    context: ytConfig?.INNERTUBE_CONTEXT,
                    videoId: this.getVideoId()
                });
                const targetUrl = `https://www.youtube.com/youtubei/v1/player?key=${key}&prettyPrint=false`;
                const res = await fetch(targetUrl, {
                    method: "POST",
                    body: payload,
                    headers: {
                        "content-type": "application/json"
                    }
                });
                return await res.json();
            } catch (err) {
                console.log("fetchYoutubePlayerData got error", err);
                return undefined;
            }
        }

        getVideoId() {
            const videoIDMatched = window?.location?.href?.match(/\/watch\?v=([^&]*)/);
            if (videoIDMatched && videoIDMatched.length > 0) return videoIDMatched[1];
            const embedIDMatched = window?.location?.href?.match(/\/embed\/([^?]*)/);
            if (embedIDMatched && embedIDMatched.length > 0) return embedIDMatched[1];
            return undefined;
        }

        getAlternativeLanguages(baseLang) {
            const alternatives = {
                pt: ['pt-BR', 'pt-PT'],
                en: ['en-US', 'en-GB', 'en-AU', 'en-CA'],
                es: ['es-ES', 'es-MX', 'es-US'],
                fr: ['fr-FR', 'fr-CA'],
            };
            return alternatives[baseLang] || [];
        }

        createUI() {
            this.createFloatingButton();
            this.createPopup();
            this.createPlayerButtons();
            this.createCourseraToggleButton();
        }

        createFloatingButton() {
            const button = document.createElement('button');
            button.id = 'auto-dub-floating-btn';
            button.className = 'btn btn-primary';
            button.innerHTML = '<i class="fas fa-microphone-alt"></i>';
            button.title = 'AutoDub Settings';
            button.addEventListener('click', () => this.togglePopup());
            document.body.appendChild(button);

            const savedPosition = GM_getValue('autoDubFloatingBtnPosition', null);
            if (savedPosition) {
                button.style.left = savedPosition.left;
                button.style.top = savedPosition.top;
                button.style.right = 'auto';
                button.style.bottom = 'auto';
            } else if (this.platform === 'coursera') {
                button.style.bottom = '80px';
            }

            this.makeDraggable(button);
        }

        createPopup() {
            const popup = document.createElement('div');
            popup.id = 'auto-dub-popup';
            popup.className = `card ${this.currentTheme}`; // Adicionar a classe do tema atual

            if (this.isDarkMode) {
                popup.classList.add('dark-mode');
            }

            popup.style.cssText = `
                display: none;
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                z-index: 10000;
                width: 320px;
                height: 550px;
                border-radius: 8px;
                box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
                overflow-y: auto;
                transition: opacity 0.3s ease;
            `;

            popup.innerHTML = `
                <div class="card-header">
                    <h5 class="mb-0"><i class="fas fa-microphone-alt me-2"></i> AutoDub Settings</h5>
                </div>
                <div class="card-body" style="height: calc(100% - 130px); overflow-y: auto;">
                    <div class="mb-3">
                        <label for="theme-select" class="form-label"><i class="fas fa-palette me-2"></i> Tema:</label>
                        <select id="theme-select" class="form-select">
                            <option value="default">Padrão</option>
                            <option value="futuristic">Futurista</option>
                            <option value="minimalist">Minimalista</option>
                            <option value="gamer">Gamer</option>
                        </select>
                    </div>
                    <div class="mb-3">
                        <label for="voice-select" class="form-label"><i class="fas fa-user-voice me-2"></i> Voice Selection:</label>
                        <select id="voice-select" class="form-select"></select>
                    </div>
                    <div class="mb-3">
                        <label for="volume-control" class="form-label"><i class="fas fa-volume-up me-2"></i> Volume:</label>
                        <div class="custom-range-container">
                            <input type="range" class="form-range" id="volume-control" min="0" max="1" step="0.1" value="1">
                            <input type="number" id="volume-value" class="form-control" min="0" max="1" step="0.1" value="1">
                        </div>
                    </div>
                    <div class="mb-3">
                        <label for="speed-control" class="form-label"><i class="fas fa-tachometer-alt me-2"></i> Speed:</label>
                        <div class="custom-range-container">
                            <input type="range" class="form-range" id="speed-control" min="0.5" max="2" step="0.1" value="1">
                            <input type="number" id="speed-value" class="form-control" min="0.5" max="2" step="0.1" value="1">
                        </div>
                    </div>
                    <div class="mb-3">
                        <label for="pitch-control" class="form-label"><i class="fas fa-music me-2"></i> Pitch:</label>
                        <div class="custom-range-container">
                            <input type="range" class="form-range" id="pitch-control" min="0.5" max="2" step="0.1" value="1">
                            <input type="number" id="pitch-value" class="form-control" min="0.5" max="2" step="0.1" value="1">
                        </div>
                    </div>
                    <div id="advanced-controls" class="mb-3" style="display: none;">
                        <div class="mb-3">
                            <label for="max-speed-control" class="form-label"><i class="fas fa-rocket me-2"></i> Velocidade máxima:</label>
                            <div class="custom                           -range-container">
                                <input type="range" class="form-range" id="max-speed-control" min="0.5" max="2" step="0.1" value="1">
                                <input type="number" id="max-speed-value" class="form-control" min="0.5" max="2" step="0.1" value="1">
                            </div>
                        </div>
                    </div>
                    <div class="mb-3">
                        <label for="speaking-control" class="form-label"><i class="fas fa-sync-alt me-2"></i> Synchronization Control:</label>
                        <select id="speaking-control" class="form-select">
                            <option value="speedUp">Speed Up Voice</option>
                            <option value="slowDown">Slow Down Video</option>
                        </select>
                    </div>
                    <div class="mb-3">
                        <label for="narration-mode" class="form-label"><i class="fas fa-book-reader me-2"></i> Narration Mode:</label>
                        <select id="narration-mode" class="form-select">
                            <option value="simple">Simple</option>
                            <option value="interactive">Interactive</option>
                        </select>
                    </div>
                    <div class="mb-3">
                        <label for="subtitle-settings" class="form-label"><i class="fas fa-closed-captioning me-2"></i> Subtitle Settings:</label>
                        <div class="input-group">
                            <input type="color" class="form-control form-control-color" id="subtitle-color" value="#ffffff">
                            <input type="number" class="form-control" id="subtitle-size" min="12" max="48" value="24">
                            <select class="form-select" id="subtitle-position">
                                <option value="bottom">Bottom</option>
                                <option value="top">Top</option>
                            </select>
                        </div>
                    </div>
                    <div class="mb-3">
                        <label for="dubbing-mode" class="form-label"><i class="fas fa-film me-2"></i> Dubbing Mode:</label>
                        <select id="dubbing-mode" class="form-select">
                            <option value="normal">Normal</option>
                            <option value="advanced">Advanced</option>
                            <option value="perfect">Perfect Dubbing</option>
                        </select>
                    </div>
                    <div id="normal-speed-control" class="mb-3" style="display: none;">
                        <label for="normal-speed-select" class="form-label"><i class="fas fa-play-circle me-2"></i> Normal Mode Playback Speed:</label>
                        <select id="normal-speed-select" class="form-select">
                            <option value="0.50">0.50x</option>
                            <option value="0.75">0.75x</option>
                            <option value="0.80">0.80x</option>
                            <option value="0.85" selected>0.85x</option>
                            <option value="0.90">0.90x</option>
                            <option value="1">1x</option>
                        </select>
                    </div>
                    <div id="perfect-dubbing-controls" class="mb-3" style="display: none;">
                        <label for="lip-sync-tolerance" class="form-label"><i class="fas fa-lips me-2"></i> Lip Sync Tolerance (ms):</label>
                        <input type="number" id="lip-sync-tolerance" class="form-control" min="0" max="1000" value="50">
                    </div>
                    <div class="mb-3">
                        <label for="dub-advance-control" class="form-label"><i class="fas fa-fast-forward me-2"></i> Dub Advance:</label>
                        <div class="custom-range-container">
                            <input type="range" class="form-range" id="dub-advance-control" min="0" max="5" step="0.1" value="0">
                            <input type="number" id="dub-advance-value" class="form-control" min="0" max="5" step="0.1" value="0">
                        </div>
                    </div>
                    <div class="form-check mb-3">
                        <input class="form-check-input" type="checkbox" id="enable-dub-advance">
                        <label class="form-check-label" for="enable-dub-advance">
                            Enable Dub Advance
                        </label>
                    </div>

                    <div class="mb-3">
                        <label for="target-language-select" class="form-label"><i class="fas fa-language me-2"></i> Target Language:</label>
                        <select id="target-language-select" class="form-select"></select>
                    </div>
                    <div class="form-check mb-3">
                        <input class="form-check-input" type="checkbox" id="translate-captions-checkbox">
                        <label class="form-check-label" for="translate-captions-checkbox">
                            Translate Captions
                        </label>
                    </div>
                </div>
                <div class="card-footer text-center">
                    <button id="toggle-dark-mode-btn" class="btn btn-secondary me-2"><i class="fas fa-${this.isDarkMode ? 'sun' : 'moon'}"></i></button>
                    <button id="toggle-dub-btn" class="btn btn-primary me-2"><i class="fas fa-play me-2"></i> Enable AutoDub</button>
                    <button id="toggle-subtitles-btn" class="btn btn-secondary"><i class="fas fa-closed-captioning me-2"></i> Enable Subtitles</button>
                </div>
            `;

            const courseraContainer = document.querySelector('.rc-VideoContainer');
            if (courseraContainer) {
                courseraContainer.appendChild(popup);
            } else {
                document.body.appendChild(popup);
            }

            // Obter os elementos da UI
            this.voiceSelect = document.getElementById('voice-select');
            this.volumeControl = document.getElementById('volume-control');
            this.speedControl = document.getElementById('speed-control');
            this.pitchControl = document.getElementById('pitch-control');
            this.speakingControl = document.getElementById('speaking-control');
            this.narrationModeSelect = document.getElementById('narration-mode');
            this.subtitleColor = document.getElementById('subtitle-color');
            this.subtitleSize = document.getElementById('subtitle-size');
            this.subtitlePosition = document.getElementById('subtitle-position');
            this.dubbingModeSelect = document.getElementById('dubbing-mode');
            this.normalSpeedSelect = document.getElementById('normal-speed-select');
            this.lipSyncTolerance = document.getElementById('lip-sync-tolerance');
            this.maxSpeedControl = document.getElementById('max-speed-control');
            this.dubAdvanceControl = document.getElementById('dub-advance-control');
            this.dubAdvanceValue = document.getElementById('dub-advance-value');
            this.enableDubAdvance = document.getElementById('enable-dub-advance');
            this.themeSelect = document.getElementById('theme-select');

            // Seletores para tradução de legendas
            this.targetLanguageSelect = document.getElementById('target-language-select');
            this.translateCaptionsCheckbox = document.getElementById('translate-captions-checkbox');

            const toggleDubBtn = document.getElementById('toggle-dub-btn');
            const toggleSubtitlesBtn = document.getElementById('toggle-subtitles-btn');
            const toggleDarkModeBtn = document.getElementById('toggle-dark-mode-btn');

            // Adicionar ouvintes de eventos para os elementos da UI
            toggleDarkModeBtn.addEventListener('click', () => this.toggleDarkMode());
            toggleDubBtn.addEventListener('click', () => this.toggleDubbing());
            toggleSubtitlesBtn.addEventListener('click', () => this.toggleSubtitles());
            this.voiceSelect.addEventListener('change', () => this.updateVoice());
            this.volumeControl.addEventListener('input', () => this.updateRangeValue('volume'));
            this.speedControl.addEventListener('input', () => this.updateRangeValue('speed'));
            this.pitchControl.addEventListener('input', () => this.updateRangeValue('pitch'));
            this.speakingControl.addEventListener('change', () => this.updateSpeakingControl());
            this.narrationModeSelect.addEventListener('change', () => this.updateNarrationMode());
            this.subtitleColor.addEventListener('input', () => this.updateSubtitleStyles());
            this.subtitleSize.addEventListener('input', () => this.updateSubtitleStyles());
            this.subtitlePosition.addEventListener('change', () => this.updateSubtitleStyles());
            this.dubbingModeSelect.addEventListener('change', () => this.updateDubbingMode());
            this.normalSpeedSelect.addEventListener('change', () => this.updateNormalPlaybackRate());
            this.lipSyncTolerance.addEventListener('change', () => this.updateLipSyncTolerance());
            this.maxSpeedControl.addEventListener('input', () => this.updateRangeValue('max-speed'));
            this.dubAdvanceControl.addEventListener('input', () => this.updateRangeValue('dub-advance'));
            this.dubAdvanceValue.addEventListener('input', (e) => this.updateRangeFromValue('dub-advance', e.target.value));
            this.enableDubAdvance.addEventListener('change', () => this.saveSettings());
            this.themeSelect.addEventListener('change', (e) => this.changeTheme(e.target.value)); // Ouvinte para o seletor de tema

            // Adicionar ouvintes de eventos para os elementos de tradução
            this.targetLanguageSelect.addEventListener('change', () => this.saveTranslationSettings());
            this.translateCaptionsCheckbox.addEventListener('change', () => this.saveTranslationSettings());

            document.getElementById('volume-value').addEventListener('input', (e) => this.updateRangeFromValue('volume', e.target.value));
            document.getElementById('speed-value').addEventListener('input', (e) => this.updateRangeFromValue('speed', e.target.value));
            document.getElementById('pitch-value').addEventListener('input', (e) => this.updateRangeFromValue('pitch', e.target.value));
            document.getElementById('max-speed-value').addEventListener('input', (e) => this.updateRangeFromValue('max-speed', e.target.value));

            this.populateLanguageList();
        }

        createPlayerButtons() {
            const player = document.querySelector(this.platform === 'youtube' ? '#movie_player' : '.rc-VideoPlayer');
            if (!player) return;

            const playButton = document.createElement('div');
            playButton.id = 'play-button';
            playButton.className = 'floating-button';
            playButton.innerHTML = '<i class="fas fa-play"></i>';
            playButton.title = 'Ativar/Desativar Dublagem';
            playButton.addEventListener('click', () => this.toggleDubbing());
            player.appendChild(playButton);

            const settingsButton = document.createElement('div');
            settingsButton.id = 'settings-button';
            settingsButton.className = 'floating-button';
            settingsButton.innerHTML = '<i class="fas fa-cog"></i>';
            settingsButton.title = 'Configurações do AutoDub';
            settingsButton.addEventListener('click', () => this.togglePopup());
            player.appendChild(settingsButton);

            player.addEventListener('mouseover', () => {
                playButton.style.opacity = 1;
                settingsButton.style.opacity = 1;
            });

            player.addEventListener('mouseout', () => {
                playButton.style.opacity = 0;
                settingsButton.style.opacity = 0;
            });
        }

        createCourseraToggleButton() {
            if (this.platform !== 'coursera') return;

            const button = document.createElement('button');
            button.id = 'coursera-autodub-toggle-btn';
            button.className = 'btn btn-primary coursera-floating-btn';
            button.innerHTML = '<i class="fas fa-play"></i>';
            button.title = 'Toggle AutoDub';
            button.style.cssText = `
                position: fixed;
                bottom: 20px;
                right: 20px;
                z-index: 9998;
                width: 50px;
                height: 50px;
                font-size: 24px;
                border-radius: 50%;
                box-shadow: 0 2px 5px rgba(0,0,0,0.3);
                color: white;
                border: none;
                opacity: 0.5;
                transition: opacity 0.3s ease;
                background-color: rgba(0, 123, 255, 0.7);
            `;
            button.addEventListener('click', () => this.toggleDubbing());
            button.addEventListener('mouseover', () => button.style.opacity = '1');
            button.addEventListener('mouseout', () => button.style.opacity = '0.5');
            document.body.appendChild(button);

            const savedPosition = GM_getValue('courseraToggleBtnPosition', null);
            if (savedPosition) {
                button.style.left = savedPosition.left;
                button.style.top = savedPosition.top;
                button.style.right = 'auto';
                button.style.bottom = 'auto';
            }

            this.makeCourseraBtnDraggable(button);
        }

        updateRangeValue(controlName) {
            const control = document.getElementById(`${controlName}-control`);
            const valueInput = document.getElementById(`${controlName}-value`);
            valueInput.value = control.value;
            if (controlName === 'max-speed') {
                this[controlName.replace('-', '')] = parseFloat(control.value);
            }
            if (controlName === 'speed') {
                this.userConfiguredSpeed = parseFloat(control.value);
            }
            this.saveSettings();
        }

        updateRangeFromValue(controlName, value) {
            const control = document.getElementById(`${controlName}-control`);
            control.value = value;
            if (controlName === 'max-speed') {
                this[controlName.replace('-', '')] = parseFloat(value);
            }
            if (controlName === 'speed') {
                this.userConfiguredSpeed = parseFloat(value);
            }
            this.saveSettings();
        }

        togglePopup() {
            const popup = document.getElementById('auto-dub-popup');
            if (popup.style.display === 'none') {
                popup.style.display = 'block';
                setTimeout(() => {
                    popup.style.opacity = '0.85';
                }, 10);

                const courseraContainer = document.querySelector('.rc-VideoContainer');
                if (courseraContainer) {
                    const containerRect = courseraContainer.getBoundingClientRect();
                    popup.style.top = `${containerRect.top + window.scrollY + 20}px`;
                    popup.style.left = `${containerRect.left + window.scrollX + (containerRect.width - popup.offsetWidth) / 2}px`;
                    popup.style.transform = 'none';
                }
            } else {
                popup.style.opacity = '0';
                setTimeout(() => {
                    popup.style.display = 'none';
                }, 300);
            }
        }

        toggleDubbing() {
            this.isActive = !this.isActive;
            const toggleDubBtn = document.getElementById('toggle-dub-btn');
            if (this.isActive) {
                toggleDubBtn.innerHTML = '<i class="fas fa-pause me-2"></i> Disable AutoDub';
                this.fetchCaptionData().then(() => {
                    this.startDubbing();
                });
            } else {
                toggleDubBtn.innerHTML = '<i class="fas fa-play me-2"></i> Enable AutoDub';
                this.stopDubbing();
            }

            const courseraToggleBtn = document.getElementById('coursera-autodub-toggle-btn');
            if (courseraToggleBtn) {
                courseraToggleBtn.innerHTML = this.isActive ? '<i class="fas fa-pause"></i>' : '<i class="fas fa-play"></i>';
            }
        }

        toggleSubtitles() {
            this.subtitlesEnabled = !this.subtitlesEnabled;
            const toggleSubtitlesBtn = document.getElementById('toggle-subtitles-btn');
            if (this.subtitlesEnabled) {
                this.createSubtitleContainer();
                toggleSubtitlesBtn.innerHTML = '<i class="fas fa-closed-captioning-off me-2"></i> Disable Subtitles';
            } else {
                this.removeSubtitleContainer();
                toggleSubtitlesBtn.innerHTML = '<i class="fas fa-closed-captioning me-2"></i> Enable Subtitles';
            }
        }

        createSubtitleContainer() {
            if (!this.subtitleContainer) {
                this.subtitleContainer = document.createElement('div');
                this.subtitleContainer.id = 'auto-dub-subtitles';
                document.querySelector(this.platform === 'youtube' ? '#movie_player' : '.rc-VideoPlayer').appendChild(this.subtitleContainer);
                this.updateSubtitleStyles();
            }
        }

        removeSubtitleContainer() {
            if (this.subtitleContainer) {
                this.subtitleContainer.remove();
                this.subtitleContainer = null;
            }
        }

        updateSubtitleStyles() {
            if (this.subtitleContainer) {
                this.subtitleContainer.style.color = this.subtitleColor.value;
                this.subtitleContainer.style.fontSize = `${this.subtitleSize.value}px`;
                this.subtitleContainer.style.bottom = this.subtitlePosition.value === 'bottom' ? '60px' : 'auto';
                this.subtitleContainer.style.top = this.subtitlePosition.value === 'top' ? '60px' : 'auto';
            }
            this.saveSettings();
        }

        populateVoiceList() {
            const voices = speechSynthesis.getVoices();
            this.voiceSelect.innerHTML = voices.map((voice, i) =>
                `<option value="${i}" ${voice.lang === this.narrationLanguage ? 'selected' : ''}>${voice.name} (${voice.lang})</option>`
            ).join('');
        }

        populateLanguageList() {
            const languages = [
                { code: 'en', label: 'English' },
                { code: 'pt', label: 'Portuguese' },
                { code: 'es', label: 'Spanish' },
                { code: 'fr', label: 'French' },
                { code: 'de', label: 'German' },
                { code: 'it', label: 'Italian' },
                { code: 'ru', label: 'Russian' },
                { code: 'ja', label: 'Japanese' },
                { code: 'ko', label: 'Korean' },
                { code: 'zh-CN', label: 'Chinese (Simplified)' },
                { code: 'zh-TW', label: 'Chinese (Traditional)' },
            ];
            this.targetLanguageSelect.innerHTML = languages.map((lang) =>
                `<option value="${lang.code}">${lang.label}</option>`
            ).join('');
        }

        updateVoice() {
            const selectedIndex = this.voiceSelect.value;
            this.currentVoice = speechSynthesis.getVoices()[selectedIndex];
            this.updateCurrentLanguage();
            this.saveLastUsedVoice();

            if (this.isActive) {
                this.stopDubbing();
                this.fetchCaptionData().then(() => {
                    this.startDubbing();
                });
            }
        }

        updateSpeakingControl() {
            this.speakingControlMode = this.speakingControl.value;
            this.saveSettings();
        }

        updateNarrationMode() {
            this.narrationMode = this.narrationModeSelect.value;
            this.saveSettings();
        }

        updateDubbingMode() {
            this.dubbingMode = this.dubbingModeSelect.value;
            this.updateUIBasedOnMode();
            this.saveSettings();

            if (this.isActive) {
                this.stopDubbing();
                this.startDubbing();
            }
        }

        updateNormalPlaybackRate() {
            this.normalPlaybackRate = parseFloat(this.normalSpeedSelect.value);
            this.saveSettings();
            if (this.isActive && this.dubbingMode === 'normal') {
                this.video.playbackRate = this.normalPlaybackRate;
            }
        }

        updateUIBasedOnMode() {
            const advancedControls = document.getElementById('advanced-controls');
            const speakingControl = document.getElementById('speaking-control').parentElement;
            const narrationModeSelect = document.getElementById('narration-mode').parentElement;
            const normalSpeedControl = document.getElementById('normal-speed-control');
            const perfectDubbingControls = document.getElementById('perfect-dubbing-controls');

            if (this.dubbingMode === 'normal') {
                speakingControl.style.display = 'none';
                narrationModeSelect.style.display = 'none';
                advancedControls.style.display = 'none';
                normalSpeedControl.style.display = 'block';
                perfectDubbingControls.style.display = 'none';
            } else if (this.dubbingMode === 'advanced') {
                speakingControl.style.display = 'block';
                narrationModeSelect.style.display = 'block';
                advancedControls.style.display = 'block';
                normalSpeedControl.style.display = 'none';
                perfectDubbingControls.style.display = 'none';
            } else if (this.dubbingMode === 'perfect') {
                speakingControl.style.display = 'none';
                narrationModeSelect.style.display = 'none';
                advancedControls.style.display = 'none';
                normalSpeedControl.style.display = 'none';
                perfectDubbingControls.style.display = 'block';
            }
        }

        loadLastUsedVoice() {
            const lastUsedVoiceIndex = GM_getValue('lastUsedVoiceIndex', 0);
            const voices = speechSynthesis.getVoices();
            this.currentVoice = voices[lastUsedVoiceIndex] || voices[0];
            this.voiceSelect.value = lastUsedVoiceIndex;
        }

        saveLastUsedVoice() {
            const voices = speechSynthesis.getVoices();
            const index = voices.findIndex(voice => voice.name === this.currentVoice.name);
            GM_setValue('lastUsedVoiceIndex', index);
        }

        loadSettings() {
            this.volumeControl.value = GM_getValue('volume', 1);
            this.speedControl.value = GM_getValue('speed', 1);
            this.userConfiguredSpeed = parseFloat(GM_getValue('userConfiguredSpeed', '1'));
            this.pitchControl.value = GM_getValue('pitch', 1);
            this.speakingControl.value = GM_getValue('speakingControlMode', 'speedUp');
            this.narrationModeSelect.value = GM_getValue('narrationMode', 'simple');
            this.subtitleColor.value = GM_getValue('subtitleColor', '#ffffff');
            this.subtitleSize.value = GM_getValue('subtitleSize', '24');
            this.subtitlePosition.value = GM_getValue('subtitlePosition', 'bottom');
            this.dubbingMode = GM_getValue('dubbingMode', 'normal');
            this.dubbingModeSelect.value = this.dubbingMode;
            this.normalPlaybackRate = parseFloat(GM_getValue('normalPlaybackRate', '0.85'));
            this.normalSpeedSelect.value = this.normalPlaybackRate.toString();
            this.lipSyncTolerance.value = GM_getValue('lipSyncTolerance', 50);
            this.maxSpeed = parseFloat(GM_getValue('maxSpeed', '1'));
            this.dubAdvanceControl.value = GM_getValue('dubAdvance', '0');
            this.enableDubAdvance.checked = GM_getValue('enableDubAdvance', false);
            this.currentTheme = GM_getValue('currentTheme', 'default'); // Carregar o tema salvo
            this.changeTheme(this.currentTheme); // Aplicar o tema carregado
            this.themeSelect.value = this.currentTheme;

            this.loadTranslationSettings();

            this.speakingControlMode = this.speakingControl.value;
            this.narrationMode = this.narrationModeSelect.value;

            this.updateRangeValue('volume');
            this.updateRangeValue('speed');
            this.updateRangeValue('pitch');
            this.updateUIBasedOnMode();
            this.maxSpeedControl.value = this.maxSpeed;
            document.getElementById('max-speed-value').value = this.maxSpeed;
            this.updateRangeValue('dub-advance');
        }

        loadTranslationSettings() {
            this.targetLanguageSelect.value = GM_getValue('targetLanguage', 'en');
            this.translateCaptionsCheckbox.checked = GM_getValue('translateCaptions', false);
        }

        saveSettings() {
            GM_setValue('volume', this.volumeControl.value);
            GM_setValue('speed', this.speedControl.value);
            GM_setValue('userConfiguredSpeed', this.userConfiguredSpeed.toString());
            GM_setValue('pitch', this.pitchControl.value);
            GM_setValue('speakingControlMode', this.speakingControlMode);
            GM_setValue('narrationMode', this.narrationMode);
            GM_setValue('subtitleColor', this.subtitleColor.value);
            GM_setValue('subtitleSize', this.subtitleSize.value);
            GM_setValue('subtitlePosition', this.subtitlePosition.value);
            GM_setValue('dubbingMode', this.dubbingMode);
            GM_setValue('normalPlaybackRate', this.normalPlaybackRate.toString());
            GM_setValue('lipSyncTolerance', this.lipSyncTolerance.value);
            GM_setValue('maxSpeed', this.maxSpeed.toString());
            GM_setValue('dubAdvance', this.dubAdvanceControl.value);
            GM_setValue('enableDubAdvance', this.enableDubAdvance.checked);
            GM_setValue('currentTheme', this.currentTheme); // Salvar o tema atual

            this.saveTranslationSettings();
        }

        saveTranslationSettings() {
            GM_setValue('targetLanguage', this.targetLanguageSelect.value);
            GM_setValue('translateCaptions', this.translateCaptionsCheckbox.checked);
        }

        addEventListeners() {
            window.speechSynthesis.onvoiceschanged = this.populateVoiceList.bind(this);
        }

        setupMutationObserver() {
            const videoObserver = new MutationObserver((mutations) => {
                mutations.forEach((mutation) => {
                    if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
                        this.handleVideoChange();
                    }
                });
            });

            const observeVideo = () => {
                const video = document.querySelector('video');
                if (video) {
                    videoObserver.observe(video, { attributes: true, attributeFilter: ['src'] });
                } else {
                    setTimeout(observeVideo, 1000);
                }
            };

            observeVideo();
        }

        handleVideoChange() {
            if (this.isActive) {
                this.stopDubbing();
                this.fetchCaptionData().then(() => {
                    this.startDubbing();
                });
            }
        }

        showModeIndicator() {
            if (!this.modeIndicator) {
                this.modeIndicator = document.createElement('div');
                this.modeIndicator.className = 'mode-indicator';
                document.body.appendChild(this.modeIndicator);
            }
            this.modeIndicator.textContent = `AutoDub: ${this.dubbingMode.charAt(0).toUpperCase() + this.dubbingMode.slice(1)} Mode`;
            this.modeIndicator.style.display = 'block';
        }

        hideModeIndicator() {
            if (this.modeIndicator) {
                this.modeIndicator.style.display = 'none';
            }
        }

        updateLipSyncTolerance() {
            this.saveSettings();
        }

        toggleDarkMode() {
            this.isDarkMode = !this.isDarkMode;
            GM_setValue('isDarkMode', this.isDarkMode);

            const popup = document.getElementById('auto-dub-popup');
            if (this.isDarkMode) {
                popup.classList.add('dark-mode');
                document.getElementById('toggle-dark-mode-btn').innerHTML = '<i class="fas fa-sun"></i>';
            } else {
                popup.classList.remove('dark-mode');
                document.getElementById('toggle-dark-mode-btn').innerHTML = '<i class="fas fa-moon"></i>';
            }
        }

        makeDraggable(element) {
            element.addEventListener('mousedown', (e) => {
                if (e.ctrlKey) {
                    this.isDragging = true;
                    this.dragStartX = e.clientX - element.offsetLeft;
                    this.dragStartY = e.clientY - element.offsetTop;
                    e.preventDefault();
                }
            });

            document.addEventListener('mousemove', (e) => {
                if (this.isDragging) {
                    const left = e.clientX - this.dragStartX;
                    const top = e.clientY - this.dragStartY;
                    element.style.left = `${left}px`;
                    element.style.top = `${top}px`;
                    element.style.right = 'auto';
                    element.style.bottom = 'auto';
                }
            });

            document.addEventListener('mouseup', () => {
                if (this.isDragging) {
                    this.isDragging = false;
                    this.saveButtonPosition(element);
                }
            });
        }

        makeCourseraBtnDraggable(element) {
            element.addEventListener('mousedown', (e) => {
                if (e.ctrlKey) {
                    this.isDraggingCourseraBtn = true;
                    this.courseraBtnDragStartX = e.clientX - element.offsetLeft;
                    this.courseraBtnDragStartY = e.clientY - element.offsetTop;
                    e.preventDefault();
                }
            });

            document.addEventListener('mousemove', (e) => {
                if (this.isDraggingCourseraBtn) {
                    const left = e.clientX - this.courseraBtnDragStartX;
                    const top = e.clientY - this.courseraBtnDragStartY;
                    element.style.left = `${left}px`;
                    element.style.top = `${top}px`;
                    element.style.right = 'auto';
                    element.style.bottom = 'auto';
                }
            });

            document.addEventListener('mouseup', () => {
                if (this.isDraggingCourseraBtn) {
                    this.isDraggingCourseraBtn = false;
                    this.saveCourseraBtnPosition(element);
                }
            });
        }

        saveButtonPosition(element) {
            const position = {
                left: element.style.left,
                top: element.style.top
            };
            if (element.id === 'auto-dub-floating-btn') {
                GM_setValue('autoDubFloatingBtnPosition', position);
            }
        }

        saveCourseraBtnPosition(element) {
            const position = {
                left: element.style.left,
                top: element.style.top
            };
            GM_setValue('courseraToggleBtnPosition', position);
        }

        // Função para alterar o tema
        changeTheme(theme) {
            const popup = document.getElementById('auto-dub-popup');
            popup.className = popup.className.replace(/\b(default|futuristic|minimalist|gamer)\b/g, '');
            popup.classList.add(theme);
            this.currentTheme = theme;
            GM_setValue('currentTheme', theme);
        }
    }

    const autoDubbing = new EnhancedAutoDubbing();
})();