Crunchyroll Auto Skip with Settings

Auto skip the intro and ending if it is available. Some parameter with lot langague.

目前为 2024-10-30 提交的版本。查看 最新版本

// ==UserScript==
// @name         Crunchyroll Auto Skip with Settings
// @namespace    https://gf.qytechs.cn/scripts/513644
// @version      1.5
// @description  Auto skip the intro and ending if it is available. Some parameter with lot langague.
// @author       MASTERD
// @match        *://*.crunchyroll.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=crunchyroll.com
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Langues prises en charge
    const supportedLanguages = ['ar', 'ca', 'zh', 'en', 'fr', 'de', 'hi', 'id', 'it', 'ja', 'ms', 'pl', 'pt', 'ru', 'es', 'ta', 'te', 'th', 'tr', 'vi'];
    // Détecter la langue de l'utilisateur
    const userLanguage = supportedLanguages.find(lang => navigator.language.startsWith(lang)) || 'en';

    ['active', 'delay', 'exsave', 'show'].forEach((key, index) => {
        if (localStorage.getItem(key) === null) {
            localStorage.setItem(key, ['true', '0', 'false', 'true'][index]);
        }
    });

    // Variables pour gérer les paramètres stockés
    let settings = {
        active: localStorage.getItem('active') === 'true',
        delay: parseInt(localStorage.getItem('delay'), 10) || 0,
        exsave: localStorage.getItem('exsave') === 'true',
        show: localStorage.getItem('show') === 'true'
    };
    let previousDelay = localStorage.getItem('delay') || '0';
    let previousActive = localStorage.getItem('active') || 'true';
    let firstLoad = true;

    // Observer les changements de la page
    const observer = new MutationObserver(() => {
        observeSkipButton();
    });
    observer.observe(document.body, { childList: true, subtree: true });

    // Fonction pour ajouter le bouton engrenage (Paramètres)
    function addSettingsButton() {
        const settingsButton = document.createElement('div');
        settingsButton.id = 'settingsButton';
        settingsButton.style.position = 'fixed';
        settingsButton.style.top = '10px';
        settingsButton.style.right = '10px';
        settingsButton.style.width = '2rem';
        settingsButton.style.height = '2rem';
        settingsButton.style.cursor = 'pointer';
        settingsButton.style.zIndex = '9990';
        settingsButton.style.backgroundImage = 'url(https://cdn.icon-icons.com/icons2/272/PNG/512/Settings_30027.png)';
        settingsButton.style.backgroundSize = 'contain';
        settingsButton.style.backgroundRepeat = 'no-repeat';

        document.body.appendChild(settingsButton);
        settingsButton.addEventListener('click', showSettingsWindow);
    }

    // Fonction pour afficher la fenêtre de paramètres
    function showSettingsWindow() {
        const overlay = document.createElement('div');
        overlay.id = 'settingsOverlay';
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.4)';
        overlay.style.zIndex = '9994';

        const settingsWindow = document.createElement('div');
        settingsWindow.id = 'settingsWindow';
        settingsWindow.style.position = 'fixed';
        settingsWindow.style.top = '10%';
        settingsWindow.style.left = '25%';
        settingsWindow.style.width = '50%';
        settingsWindow.style.backgroundColor = 'white';
        settingsWindow.style.zIndex = '9995';
        settingsWindow.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.5)';
        settingsWindow.style.borderRadius = '10px';
        settingsWindow.style.padding = '20px';

        // Bouton de fermeture "X"
        const closeButton = document.createElement('span');
        closeButton.textContent = 'X';
        closeButton.style.position = 'absolute';
        closeButton.style.top = '10px';
        closeButton.style.right = '20px';
        closeButton.style.cursor = 'pointer';
        closeButton.style.fontSize = '200%';
        closeButton.style.color = 'black';
        closeButton.style.backgroundColor = 'lightgray';
        closeButton.style.padding = '5px';
        closeButton.style.borderRadius = '5px';
        closeButton.style.padding = '20px';

        //langue a traduire

        // Formulaire de paramètres
        const activeToggle = createToggle(translations[userLanguage].activeToggle, settings.active, (value) => settings.active = value);
        const showToggle = createToggle(translations[userLanguage].showToggle, settings.show, (value) => settings.show = value);
        const exsaveToggle = createToggle(translations[userLanguage].exsaveToggle, settings.exsave, (value) => settings.exsave = value);
        const delayInput = createInput(translations[userLanguage].delayInput, settings.delay, (value) => settings.delay = parseInt(value, 10));

        // Boutons de gestion des paramètres
        const saveButton = createButton(translations[userLanguage].saveButton, saveAndClose);
        const cancelButton = createButton(translations[userLanguage].cancelButton, hideSettingsWindow);
        const defaultButton = createButton(translations[userLanguage].defaultButton, resetDefaults);

        // Ajouter les éléments à la fenêtre
        settingsWindow.appendChild(closeButton);
        settingsWindow.appendChild(activeToggle);
        settingsWindow.appendChild(delayInput);
        settingsWindow.appendChild(document.createElement("br"));
        settingsWindow.appendChild(showToggle);
        settingsWindow.appendChild(exsaveToggle);
        settingsWindow.appendChild(document.createElement("br"));
        settingsWindow.appendChild(saveButton);
        settingsWindow.appendChild(cancelButton);
        settingsWindow.appendChild(defaultButton);

        document.body.appendChild(overlay);
        document.body.appendChild(settingsWindow);

        // Gestion des événements
        closeButton.addEventListener('click', hideSettingsWindow);
        overlay.addEventListener('click', handleOverlayClick);
    }

    // Création des éléments de formulaire
    function createToggle(labelText, isChecked, onChange) {
        const container = document.createElement('div');
        const label = document.createElement('label');
        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = isChecked;

        checkbox.addEventListener('change', () => onChange(checkbox.checked));

        label.textContent = labelText;
        label.style.color = 'black';
        label.style.padding = '0 10px';
        container.appendChild(label);
        container.appendChild(checkbox);

        return container;
    }

    function createInput(labelText, value, onChange) {
        const container = document.createElement('div');
        const label = document.createElement('label');
        const input = document.createElement('input');
        input.type = 'text';
        input.value = value;

        input.addEventListener('input', () => onChange(input.value));

        label.textContent = labelText;
        label.style.color = 'black';
        label.style.padding = '0 10px';
        container.appendChild(label);
        container.appendChild(input);

        return container;
    }

    function createButton(text, onClick) {
        const button = document.createElement('button');
        button.textContent = text;
        button.style.padding = '10px';
        button.style.margin = '3px';
        button.style.border = 'revert';
        button.style.borderRadius = 'inherit';
        button.style.backgroundColor = 'lightgrey';
        button.addEventListener('click', onClick);

        return button;
    }

    // Gérer les actions du formulaire
    function saveAndClose() {
        saveSettings();
        hideSettingsWindow();
    }

    function resetDefaults() {
        settings.active = true;
        settings.delay = 0;
        settings.exsave = false;
        settings.show = true;
        saveSettings();
        hideSettingsWindow();
    }

    function hideSettingsWindow() {
        const overlay = document.getElementById('settingsOverlay');
        const settingsWindow = document.getElementById('settingsWindow');

        if (overlay) {
            document.body.removeChild(overlay);
        }
        if (settingsWindow) {
            document.body.removeChild(settingsWindow);
        }
        settings = {
            active: localStorage.getItem('active') === 'true',
            delay: parseInt(localStorage.getItem('delay'), 10) || 0,
            exsave: localStorage.getItem('exsave') === 'true',
            show: localStorage.getItem('show') === 'true'
        };
    }

    // Fonction pour sauvegarder les paramètres dans localStorage
    function saveSettings() {
        localStorage.setItem('active', settings.active);
        localStorage.setItem('delay', settings.delay);
        localStorage.setItem('exsave', settings.exsave);
        localStorage.setItem('show', settings.show);
        waitForIframe();
    }

    // Gérer le clic sur l'overlay
    function handleOverlayClick() {

        if (localStorage.getItem('show') === 'true') {
            // Créer l'overlay
            const overlay = document.createElement('div');
            overlay.id = 'customOverlay';
            overlay.style.position = 'fixed';
            overlay.style.top = '0';
            overlay.style.left = '0';
            overlay.style.width = '100%';
            overlay.style.height = '100%';
            overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; // Fond semi-transparent
            overlay.style.zIndex = '9998'; // Derrière la boîte de dialogue

            // Créer le conteneur pour l'alerte
            const alertDiv = document.createElement('div');
            alertDiv.id = 'customAlert';
            alertDiv.style.position = 'fixed';
            alertDiv.style.top = '50%';
            alertDiv.style.left = '50%';
            alertDiv.style.transform = 'translate(-50%, -50%)';
            alertDiv.style.padding = '20px';
            alertDiv.style.backgroundColor = '#fff';
            alertDiv.style.border = '1px solid #ccc';
            alertDiv.style.zIndex = '9999';
            alertDiv.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.1)';
            alertDiv.style.color = '#000'; // Texte noir

            // Ajouter le texte du message
            const message = document.createElement('p');
            //langue a traduire
            message.textContent = translations[userLanguage].confirmExit;
            alertDiv.appendChild(message);

            // Ajouter une checkbox avec le texte "Sauvegarder votre choix"
            const checkboxDiv = document.createElement('div');
            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.id = 'saveChoiceCheckbox';
            checkboxDiv.appendChild(checkbox);

            const checkboxLabel = document.createElement('label');
            checkboxLabel.htmlFor = 'saveChoiceCheckbox';
            //langue a traduire
            checkboxLabel.textContent = translations[userLanguage].saveChoice;
            checkboxLabel.style.padding = '0 10px';
            checkboxDiv.appendChild(checkboxLabel);

            alertDiv.appendChild(checkboxDiv);

            // Ajouter les boutons Oui et Non
            const buttonContainer = document.createElement('div');
            buttonContainer.style.marginTop = '10px';
            buttonContainer.style.display = 'flex';
            buttonContainer.style.justifyContent = 'space-between';

            // Bouton Oui
            const yesButton = document.createElement('button');
            //langue a traduire
            yesButton.textContent = translations[userLanguage].yes;
            yesButton.onclick = function() {
                if (checkbox.checked) {
                    settings.show = false;
                }
                settings.exsave = true;
                saveSettings();
                hideSettingsWindow();
                closeAlert();
            };

            // Bouton Non
            const noButton = document.createElement('button');
            //langue a traduire
            noButton.textContent = translations[userLanguage].no;
            noButton.onclick = function() {
                if (checkbox.checked) {
                    settings.show = false;
                    localStorage.setItem('show', settings.show);
                }
                settings.exsave = false;
                localStorage.setItem('exsave', settings.exsave);
                hideSettingsWindow();
                closeAlert();
                settings = {
                    active: localStorage.getItem('active') === 'true',
                    delay: parseInt(localStorage.getItem('delay'), 10) || 0,
                    exsave: localStorage.getItem('exsave') === 'true',
                    show: localStorage.getItem('show') === 'true'
                };
            };

            // Ajouter les boutons au conteneur
            buttonContainer.appendChild(yesButton);
            buttonContainer.appendChild(noButton);
            alertDiv.appendChild(buttonContainer);

            // Ajouter la boîte de dialogue et l'overlay à la page
            document.body.appendChild(overlay);
            document.body.appendChild(alertDiv);

            // Fonction pour fermer l'alerte
            function closeAlert() {
                document.body.removeChild(alertDiv);
                document.body.removeChild(overlay);
            }
        } else {
            if (settings.exsave) {
                saveSettings();
            }
            hideSettingsWindow();
        }
    }

    // Observer les changements de style sur le bouton "Passer l'intro"
    function observeSkipButton() {
        const skipButton = document.querySelector('div[data-testid="skipButton"]');

        if (skipButton) {
            const delay = parseInt(localStorage.getItem('delay'), 10) || 0;
            let noSkipButton = document.querySelector('#noSkipButton');

            if (!noSkipButton) {
                noSkipButton = document.createElement('button');
                noSkipButton.id = 'noSkipButton';
                //langue a traduire
                noSkipButton.textContent = translations[userLanguage].AutoSkOff;
                noSkipButton.style.position = 'absolute';
                noSkipButton.style.right = '200px';
                noSkipButton.style.bottom = '100px';
                noSkipButton.style.height = '40px';
                noSkipButton.style.padding = '0 16px';
                noSkipButton.style.zIndex = '1';
                noSkipButton.style.display = 'block';
                noSkipButton.classList.add("css-1dbjc4n");
                noSkipButton.style.cursor = 'pointer';
                noSkipButton.value = '0';
                skipButton.parentNode.insertBefore(noSkipButton, skipButton);

                // Gérer le clic sur le bouton "no skip"
                noSkipButton.addEventListener('click', () => {
                    if (noSkipButton.value === "0") {
                        noSkipButton.value = '1';
                        //langue a traduire
                        noSkipButton.textContent = translations[userLanguage].AutoSkON;
                        const message = { type: 'noskip', value: noSkipButton.value };
                        sendMessageToParent(message);
                    } else {
                        noSkipButton.value = '0';
                        //langue a traduire
                        noSkipButton.textContent = translations[userLanguage].AutoSkOff;
                        const message = { type: 'noskip', value: noSkipButton.value };
                        sendMessageToParent(message);
                    }
                });

                // Variable pour stocker temporairement l'observateur
                let mutationObserverActive = true;

                // Observer les changements de style du bouton "Passer l'intro"
                const observer = new MutationObserver((mutations) => {


                    mutations.forEach((mutation) => {
                        if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
                            if (!skipButton.style.opacity || skipButton.style.opacity !== '0') {
                                const innerButton = skipButton.querySelector('div[tabindex="0"]');
                                if (innerButton) {
                                    if (localStorage.getItem('active') === 'true' && noSkipButton.value === "0") {
                                        const x = parseInt(localStorage.getItem('delay'), 10) || 0;
                                        setTimeout(function() {
                                            if (noSkipButton.value === "0") {
                                                innerButton.click(); // Ne pas exécuter si "no skip" est activé
                                            }
                                        }, x);
                                    }
                                }
                            }
                            if (!mutationObserverActive) return; // Désactiver les mutations pendant le survol du bouton "No Skip"
                            // Gérer l'affichage du bouton "no skip"
                            if (skipButton.style.opacity === '0') {
                                if (noSkipButton) {
                                    noSkipButton.style.display = 'none';
                                }
                            } else {
                                if (noSkipButton) {
                                    noSkipButton.style.display = 'block';
                                }
                            }
                        }
                    });
                });

                observer.observe(skipButton, { attributes: true });

                // Observer si le bouton "Passer l'intro" est supprimé du DOM
                const skipButtonRemovalObserver = new MutationObserver((mutations) => {
                    mutations.forEach((mutation) => {
                        mutation.removedNodes.forEach((removedNode) => {
                            if (removedNode === skipButton) {
                                if (noSkipButton) {
                                    noSkipButton.remove(); // Supprimer le bouton "No Skip" quand "skipButton" disparaît
                                }
                            }
                        });
                    });
                });

                skipButtonRemovalObserver.observe(document.body, { childList: true, subtree: true });

                // Désactiver temporairement l'observateur lorsque la souris est sur "noSkipButton"
                noSkipButton.addEventListener('mouseover', () => {
                    mutationObserverActive = false; // Désactive l'observateur temporairement
                    if (skipButton) {
                        skipButton.style.opacity = '1'; // Forcer l'affichage du bouton "skipButton"
                    }
                });

                noSkipButton.addEventListener('mouseout', () => {
                    mutationObserverActive = true; // Réactiver l'observateur après avoir quitté "noSkipButton"
                    if (skipButton) {
                        skipButton.style.opacity = ''; // Rétablir l'état initial
                    }
                });
            }
        }

        // Écouteur de messages pour recevoir les mises à jour
        window.addEventListener('message', function(event) {
            if (event.origin !== 'https://www.crunchyroll.com' && event.origin !== 'https://static.crunchyroll.com') {
                console.log('Message ignoré, origine incorrecte:', event.origin);
                return;
            }

            const receivedMessage = event.data;

            if (receivedMessage.type === 'noskip') {
                const noSkipButton = document.getElementById('noSkipButton');
                if (noSkipButton) {
                    noSkipButton.value = receivedMessage.value;
                    console.log('Valeur du bouton No Skip mise à jour:', noSkipButton.value);
                } else {
                    console.log('Bouton No Skip non trouvé.');
                }
            }
        });
    }

    // Fonction pour envoyer un message au parent
    function sendMessageToParent(message) {
        window.parent.postMessage(message, '*');
    }

    // Ne pas exécuter dans les iframes
    if (window.self === window.top) {
        addSettingsButton();
    }

    // Fonction pour envoyer les valeurs de delay et active à l'iframe
    function sendValuesToIframe(iframe) {
        const delayValue = localStorage.getItem('delay') || '0'; // Valeur de delay
        const activeValue = localStorage.getItem('active') || 'true'; // Valeur de active

        // Envoyer seulement si la valeur de delay a changé
        if (delayValue !== previousDelay || firstLoad == true) {
            const message = {
                type: 'delay',
                value: delayValue
            };

            iframe.contentWindow.postMessage(message, 'https://static.crunchyroll.com');
            previousDelay = delayValue; // Mettre à jour la valeur précédente
        }

        // Envoyer seulement si la valeur de active a changé
        if (activeValue !== previousActive || firstLoad == true) {
            const message = {
                type: 'active',
                value: activeValue
            };

            iframe.contentWindow.postMessage(message, 'https://static.crunchyroll.com');
            previousActive = activeValue; // Mettre à jour la valeur précédente
            firstLoad = false;
        }
    }

    // Vérifier si l'iframe est chargé et disponible
    function waitForIframe() {
        const iframe = document.querySelector('.video-player');
        if (iframe && iframe.src.includes('https://static.crunchyroll.com')) {

            // Envoyer les valeurs lors du premier chargement de l'iframe
            iframe.onload = function() {
                sendValuesToIframe(iframe);
            };

            // Vérifier périodiquement si les valeurs de delay ou active ont changé
            setInterval(function() {
                sendValuesToIframe(iframe); // Envoyer à chaque changement de delay ou active
            }, 1000); // Vérifier toutes les secondes
        } else {
            setTimeout(waitForIframe, 500); // Réessayer après 500 ms si l'iframe n'est pas trouvé
        }
    }

    // Lancer la fonction de vérification lorsque la page est complètement chargée
    window.addEventListener('load', waitForIframe);

    // Écouter les messages provenant de l'iframe
    window.addEventListener('message', function(event) {
        // Vérifier que l'origine du message est correcte
        if (event.origin !== 'https://www.crunchyroll.com') {
            return;
        }

        // Récupérer les données envoyées par le parent (qui est un objet structuré)
        const receivedMessage = event.data;

        // Vérifier que le type de message est bien 'delay'
        if (receivedMessage.type === 'delay') {
            const delay = receivedMessage.value;

            // Enregistrer la valeur dans le localStorage de l'iframe
            localStorage.setItem('delay', delay);
        }

        // Vérifier que le type de message est bien 'active'
        if (receivedMessage.type === 'active') {
            const active = receivedMessage.value;

            // Enregistrer la valeur dans le localStorage de l'iframe
            localStorage.setItem('active', active);
        }
    });

    //traduction traduire
    const translations = {
        ar: {
            activeToggle: "تفعيل التخطي التلقائي",
            showToggle: "عرض تنبيه التراكب",
            exsaveToggle: "حفظ عند الخروج من التراكب",
            delayInput: "التأخير قبل التخطي (مللي ثانية)",
            saveButton: "حفظ",
            cancelButton: "إلغاء",
            defaultButton: "الإفتراضي",
            confirmExit: "هل تريد الخروج وحفظ الإعدادات؟",
            saveChoice: "حفظ اختيارك",
            yes: "نعم",
            no: "لا",
            AutoSkOff: "تعطيل التخطي التلقائي",
            AutoSkON: "إعادة تفعيل التخطي التلقائي"
        },
        ca: {
            activeToggle: "Activar el salt automàtic",
            showToggle: "Mostra l'alerta de superposició",
            exsaveToggle: "Desa en sortir de la superposició",
            delayInput: "Retard abans de saltar (ms)",
            saveButton: "Desa",
            cancelButton: "Cancel·lar",
            defaultButton: "Per defecte",
            confirmExit: "Vols sortir i desar la configuració?",
            saveChoice: "Desa la teva elecció",
            yes: "Sí",
            no: "No",
            AutoSkOff: "Desactivar Salt Automàtic",
            AutoSkON: "Reactivar Salt Automàtic"
        },
        zh: {
            activeToggle: "启用自动跳过",
            showToggle: "显示覆盖警报",
            exsaveToggle: "退出覆盖时保存",
            delayInput: "跳过前的延迟(毫秒)",
            saveButton: "保存",
            cancelButton: "取消",
            defaultButton: "默认",
            confirmExit: "是否要退出并保存设置?",
            saveChoice: "保存您的选择",
            yes: "是",
            no: "否",
            AutoSkOff: "禁用自动跳过",
            AutoSkON: "重新启用自动跳过"
        },
        en: {
            activeToggle: "Enable automatic skip",
            showToggle: "Show overlay alert",
            exsaveToggle: "Save when exiting overlay",
            delayInput: "Delay before skipping (ms)",
            saveButton: "Save",
            cancelButton: "Cancel",
            defaultButton: "Default",
            confirmExit: "Do you want to quit and save the settings?",
            saveChoice: "Save your choice",
            yes: "Yes",
            no: "No",
            AutoSkOff: "Disable Auto Skip",
            AutoSkON: "Re-enable Auto Skip"
        },
        fr: {
            activeToggle: "Activer le skip automatique",
            showToggle: "Afficher l'alerte de l'overlay",
            exsaveToggle: "Sauvegarder en quittant l'overlay",
            delayInput: "Délai avant de skip (ms)",
            saveButton: "Sauvegarder",
            cancelButton: "Annuler",
            defaultButton: "Défaut",
            confirmExit: "Voulez-vous quitter et sauvegarder les paramètres?",
            saveChoice: "Sauvegarder votre choix",
            yes: "Oui",
            no: "Non",
            AutoSkOff: "Désactiver Auto Skip",
            AutoSkON: "Réactiver Auto Skip"
        },
        de: {
            activeToggle: "Automatisches Überspringen aktivieren",
            showToggle: "Overlay-Warnung anzeigen",
            exsaveToggle: "Beim Verlassen des Overlays speichern",
            delayInput: "Verzögerung vor dem Überspringen (ms)",
            saveButton: "Speichern",
            cancelButton: "Abbrechen",
            defaultButton: "Standard",
            confirmExit: "Möchten Sie beenden und die Einstellungen speichern?",
            saveChoice: "Speichern Sie Ihre Wahl",
            yes: "Ja",
            no: "Nein",
            AutoSkOff: "Automatisches Überspringen deaktivieren",
            AutoSkON: "Automatisches Überspringen erneut aktivieren"
        },
        hi: {
            activeToggle: "स्वचालित स्किप सक्षम करें",
            showToggle: "ओवरले चेतावनी दिखाएं",
            exsaveToggle: "ओवरले से बाहर निकलते समय सहेजें",
            delayInput: "स्किप करने से पहले विलंब (मिलीसेकंड)",
            saveButton: "सहेजें",
            cancelButton: "रद्द करें",
            defaultButton: "डिफ़ॉल्ट",
            confirmExit: "क्या आप बाहर निकलना और सेटिंग्स सहेजना चाहते हैं?",
            saveChoice: "अपनी पसंद सहेजें",
            yes: "हां",
            no: "नहीं",
            AutoSkOff: "स्वचालित स्किप अक्षम करें",
            AutoSkON: "स्वचालित स्किप फिर से सक्षम करें"
        },
        id: {
            activeToggle: "Aktifkan lewati otomatis",
            showToggle: "Tampilkan peringatan overlay",
            exsaveToggle: "Simpan saat keluar dari overlay",
            delayInput: "Tunda sebelum melewati (ms)",
            saveButton: "Simpan",
            cancelButton: "Batal",
            defaultButton: "Default",
            confirmExit: "Apakah Anda ingin keluar dan menyimpan pengaturan?",
            saveChoice: "Simpan pilihan Anda",
            yes: "Ya",
            no: "Tidak",
            AutoSkOff: "Nonaktifkan Lewati Otomatis",
            AutoSkON: "Aktifkan kembali Lewati Otomatis"
        },
        it: {
            activeToggle: "Abilita salto automatico",
            showToggle: "Mostra avviso sovrapposizione",
            exsaveToggle: "Salva quando esci dalla sovrapposizione",
            delayInput: "Ritardo prima del salto (ms)",
            saveButton: "Salva",
            cancelButton: "Annulla",
            defaultButton: "Predefinito",
            confirmExit: "Vuoi uscire e salvare le impostazioni?",
            saveChoice: "Salva la tua scelta",
            yes: "Sì",
            no: "No",
            AutoSkOff: "Disabilita Salto Automatico",
            AutoSkON: "Riattiva Salto Automatico"
        },
        ja: {
            activeToggle: "自動スキップを有効にする",
            showToggle: "オーバーレイ警告を表示",
            exsaveToggle: "オーバーレイを終了するときに保存",
            delayInput: "スキップ前の遅延 (ミリ秒)",
            saveButton: "保存",
            cancelButton: "キャンセル",
            defaultButton: "デフォルト",
            confirmExit: "終了して設定を保存しますか?",
            saveChoice: "選択を保存する",
            yes: "はい",
            no: "いいえ",
            AutoSkOff: "自動スキップを無効にする",
            AutoSkON: "自動スキップを再度有効にする"
        },
        ms: {
            activeToggle: "Aktifkan lompat automatik",
            showToggle: "Tunjukkan amaran overlay",
            exsaveToggle: "Simpan apabila keluar dari overlay",
            delayInput: "Kelewatan sebelum melompat (ms)",
            saveButton: "Simpan",
            cancelButton: "Batal",
            defaultButton: "Lalai",
            confirmExit: "Adakah anda mahu keluar dan menyimpan tetapan?",
            saveChoice: "Simpan pilihan anda",
            yes: "Ya",
            no: "Tidak",
            AutoSkOff: "Lumpuhkan Lompat Automatik",
            AutoSkON: "Dayakan semula Lompat Automatik"
        },
        pl: {
            activeToggle: "Włącz automatyczne pomijanie",
            showToggle: "Pokaż alert nakładki",
            exsaveToggle: "Zapisz przy wychodzeniu z nakładki",
            delayInput: "Opóźnienie przed pominięciem (ms)",
            saveButton: "Zapisz",
            cancelButton: "Anuluj",
            defaultButton: "Domyślnie",
            confirmExit: "Czy chcesz zakończyć i zapisać ustawienia?",
            saveChoice: "Zapisz swój wybór",
            yes: "Tak",
            no: "Nie",
            AutoSkOff: "Wyłącz automatyczne pomijanie",
            AutoSkON: "Włącz ponownie automatyczne pomijanie"
        },
        pt: {
            activeToggle: "Ativar pulo automático",
            showToggle: "Mostrar alerta de sobreposição",
            exsaveToggle: "Salvar ao sair da sobreposição",
            delayInput: "Atraso antes de pular (ms)",
            saveButton: "Salvar",
            cancelButton: "Cancelar",
            defaultButton: "Padrão",
            confirmExit: "Deseja sair e salvar as configurações?",
            saveChoice: "Salve sua escolha",
            yes: "Sim",
            no: "Não",
            AutoSkOff: "Desativar Pulo Automático",
            AutoSkON: "Reativar Pulo Automático"
        },
        ru: {
            activeToggle: "Включить автоматический пропуск",
            showToggle: "Показать предупреждение наложения",
            exsaveToggle: "Сохранить при выходе из наложения",
            delayInput: "Задержка перед пропуском (мс)",
            saveButton: "Сохранить",
            cancelButton: "Отмена",
            defaultButton: "По умолчанию",
            confirmExit: "Вы хотите выйти и сохранить настройки?",
            saveChoice: "Сохраните свой выбор",
            yes: "Да",
            no: "Нет",
            AutoSkOff: "Отключить автоматический пропуск",
            AutoSkON: "Повторно включить автоматический пропуск"
        },
        es: {
            activeToggle: "Habilitar omisión automática",
            showToggle: "Mostrar alerta de superposición",
            exsaveToggle: "Guardar al salir de la superposición",
            delayInput: "Retraso antes de omitir (ms)",
            saveButton: "Guardar",
            cancelButton: "Cancelar",
            defaultButton: "Por defecto",
            confirmExit: "¿Quieres salir y guardar la configuración?",
            saveChoice: "Guarda tu elección",
            yes: "Sí",
            no: "No",
            AutoSkOff: "Desactivar Omisión Automática",
            AutoSkON: "Reactivar Omisión Automática"
        },
        ta: {
            activeToggle: "தானியங்கி குதிப்பை இயக்கவும்",
            showToggle: "மேல்பட வருகையை காட்டவும்",
            exsaveToggle: "மேல்பட வருகையை விட்டு வெளியேறும்போது சேமிக்கவும்",
            delayInput: "குதிக்கும் முன் தாமதம் (மில்லி வினாடிகள்)",
            saveButton: "சேமிக்கவும்",
            cancelButton: "ரத்துசெய்",
            defaultButton: "இயல்புநிலை",
            confirmExit: "வெளியேறி அமைப்புகளைச் சேமிக்க விரும்புகிறீர்களா?",
            saveChoice: "உங்கள் தேர்வைச் சேமிக்கவும்",
            yes: "ஆம்",
            no: "இல்லை",
            AutoSkOff: "தானியங்கி குதிப்பை முடக்கு",
            AutoSkON: "தானியங்கி குதிப்பை மீண்டும் இயக்கவும்"
        },
        te: {
            activeToggle: "ఆటోమేటిక్ స్కిప్‌ని ఎనేబుల్ చేయండి",
            showToggle: "ఓవర్‌లే అలర్ట్‌ను చూపించండి",
            exsaveToggle: "ఓవర్‌లే నుండి నిష్క్రమించే సమయంలో సేవ్ చేయండి",
            delayInput: "స్కిప్ చేయడానికి ముందు ఆలస్యం (మిల్లీసెకన్లు)",
            saveButton: "సేవ్ చేయండి",
            cancelButton: "రద్దు చేయండి",
            defaultButton: "డిఫాల్ట్",
            confirmExit: "మీరు నిష్క్రమించి సెట్టింగ్‌లను సేవ్ చేయాలనుకుంటున్నారా?",
            saveChoice: "మీ ఎంపికను సేవ్ చేయండి",
            yes: "అవును",
            no: "కాదు",
            AutoSkOff: "ఆటోమేటిక్ స్కిప్‌ని ఆపివేయండి",
            AutoSkON: "ఆటోమేటిక్ స్కిప్‌ని తిరిగి ఎనేబుల్ చేయండి"
        },
        th: {
            activeToggle: "เปิดใช้งานข้ามอัตโนมัติ",
            showToggle: "แสดงการแจ้งเตือนซ้อนทับ",
            exsaveToggle: "บันทึกเมื่อออกจากการซ้อนทับ",
            delayInput: "ความล่าช้าก่อนข้าม (ms)",
            saveButton: "บันทึก",
            cancelButton: "ยกเลิก",
            defaultButton: "ค่าเริ่มต้น",
            confirmExit: "คุณต้องการออกและบันทึกการตั้งค่าหรือไม่?",
            saveChoice: "บันทึกการเลือกของคุณ",
            yes: "ใช่",
            no: "ไม่",
            AutoSkOff: "ปิดใช้งานการข้ามอัตโนมัติ",
            AutoSkON: "เปิดใช้งานการข้ามอัตโนมัติอีกครั้ง"
        },
        tr: {
            activeToggle: "Otomatik atlamayı etkinleştir",
            showToggle: "Bindirme uyarısını göster",
            exsaveToggle: "Bindirmeden çıkarken kaydet",
            delayInput: "Atlamadan önce gecikme (ms)",
            saveButton: "Kaydet",
            cancelButton: "İptal",
            defaultButton: "Varsayılan",
            confirmExit: "Çıkmak ve ayarları kaydetmek istiyor musunuz?",
            saveChoice: "Seçiminizi kaydedin",
            yes: "Evet",
            no: "Hayır",
            AutoSkOff: "Otomatik Atlama'yı devre dışı bırak",
            AutoSkON: "Otomatik Atlama'yı yeniden etkinleştir"
        },
        vi: {
            activeToggle: "Bật bỏ qua tự động",
            showToggle: "Hiển thị cảnh báo lớp phủ",
            exsaveToggle: "Lưu khi thoát lớp phủ",
            delayInput: "Độ trễ trước khi bỏ qua (ms)",
            saveButton: "Lưu",
            cancelButton: "Hủy bỏ",
            defaultButton: "Mặc định",
            confirmExit: "Bạn có muốn thoát và lưu cài đặt không?",
            saveChoice: "Lưu lựa chọn của bạn",
            yes: "Có",
            no: "Không",
            AutoSkOff: "Tắt bỏ qua tự động",
            AutoSkON: "Bật lại bỏ qua tự động"
        }
    };

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址