Streamer Mode for skribbl.io

Add on for streaming skribbl.io - Safe streaming everyone!

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Streamer Mode for skribbl.io
// @namespace    http://tampermonkey.net/
// @version      1.0
// @license      MIT
// @description  Add on for streaming skribbl.io - Safe streaming everyone!
// @author       Alpha
// @match        https://skribbl.io/*
// @exclude      https://skribbl.io/credits
// @grant        none
// @run-at        document-end
// ==/UserScript==

    (function() {
        'use strict';

        const style = document.createElement('style');
        style.textContent = `
        body{
        background-image: url("https://imgur.com/xVBUecv.png");
        }

        #home .button-create{
        background-color: #403483;
}
        #home .button-create:hover:not(:disabled){
        background-color: #1d1648;
        }
        #home .button-play{
        background-color: #6441A4;
        }

        #home .button-play:hover:not(:disabled){
        background-color:rgb(48, 27, 90);
        }
    `;
        document.documentElement.style.setProperty('--COLOR_PANEL_BG', '#1e006480');
        document.documentElement.style.setProperty('--COLOR_PANEL_LO', '#403483');
        document.documentElement.style.setProperty('--COLOR_PANEL_HI', '#ffffff');
        document.documentElement.style.setProperty('--COLOR_PANEL_BUTTON', '#6441A4');
        document.documentElement.style.setProperty('--COLOR_TOOL_TIP_BG', '#6441A4');
        document.documentElement.style.setProperty('--COLOR_CHAT_TEXT_JOIN', '#5a5dff');
        document.documentElement.style.setProperty('--COLOR_CHAT_TEXT_GUESSCHAT', '#3f47ad');
        document.documentElement.style.setProperty('--COLOR_PLAYER_BG_GUESSED_BASE', '#8b72d6');
        document.documentElement.style.setProperty('--COLOR_PLAYER_BG_GUESSED_ALT', '#6441A4');
        document.documentElement.style.setProperty('--COLOR_PANEL_BUTTON_HOVER', 'rgb(48, 27, 90)');
        document.documentElement.style.setProperty('--COLOR_CHAT_BG_GUESSED_BASE', '#ac91ff');
        document.documentElement.style.setProperty('--COLOR_CHAT_BG_GUESSED_ALT', '#c0bdff');
        document.documentElement.style.setProperty('--COLOR_PLAYER_ME_GUESSED', '#c0bdff');
        document.documentElement.style.setProperty('--COLOR_PLAYER_ME', '#6549ff');
        document.head.appendChild(style);

        const logoImg = document.querySelector("#home > div.logo-big > a > img");
        if (logoImg) {
            logoImg.src = "https://imgur.com/gIKOKSJ.gif";
        }

        const logoImgSmol = document.querySelector("#game-logo > a > img");
        if (logoImgSmol) {
            logoImgSmol.src = "https://imgur.com/gIKOKSJ.gif";
        }

        const buttonContainer = document.createElement('div');
        buttonContainer.style.position = 'fixed';
        buttonContainer.style.top = '10px';
        buttonContainer.style.right = '10px';
        buttonContainer.style.padding = '15px';
        buttonContainer.style.backgroundColor = 'var(--COLOR_PANEL_BG)';
        buttonContainer.style.zIndex = '999';
        buttonContainer.style.display = 'flex';
        buttonContainer.style.flexDirection = 'column';
        buttonContainer.style.gap = '10px';
        buttonContainer.style.borderRadius = 'var(--BORDER_RADIUS)';
        buttonContainer.style.alignItems = 'center';

        const streamingButton = document.createElement('button');
        streamingButton.textContent = '';
        streamingButton.style.cssText = `
            z-index: 1000;
            width: 32px;
            height: 32px;
            background-image: url('https://imgur.com/1n1H9g7.gif');
            cursor: pointer;
            filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, .3));
            background-color: transparent;
            background-size: contain;
            background-repeat: no-repeat;
            position: relative;
            opacity: 0.6;
            transition: opacity .15s ease, transform .15s ease;
        `;



        // Button Tooltip Creation

        function createTooltip(button, tooltipText) {

            button.textContent = '';

            const tooltip = document.createElement('div');
            tooltip.className = 'tooltip W';
            tooltip.style.cssText = `
                position: absolute;
                z-index: 10000;
                filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, .15));
                animation: tooltip_introduce 0.2s ease-in-out;
                visibility: hidden;
                opacity: 0;
                transition: opacity 0.3s;
            `;

            const tooltipContent = document.createElement('div');
            tooltipContent.className = 'tooltip-content';
            tooltipContent.textContent = tooltipText;
            tooltipContent.style.cssText = `
                color: var(--COLOR_PANEL_TEXT);
                background-color: var(--COLOR_TOOL_TIP_BG);
                border-radius: var(--BORDER_RADIUS);
                padding: 7px;
                font-size: 11.5px;
                white-space: nowrap;
                text-align: center;
                text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.22);
            `;

            const tooltipArrow = document.createElement('div');
            tooltipArrow.className = 'tooltip-arrow';
            tooltipArrow.style.cssText = `
                position: absolute;
                top: 50%;
                left: -14px;
                border-top: 10px solid transparent;
                border-bottom: 10px solid transparent;
                border-left: 10px solid var(--COLOR_TOOL_TIP_BG);
                transform: translateY(-50%);
            `;

            tooltip.appendChild(tooltipContent);
            tooltip.appendChild(tooltipArrow);

            button.style.position = 'relative';
            button.appendChild(tooltip);

            button.addEventListener('mouseenter', () => {
                tooltip.style.visibility = 'visible';
                tooltip.style.opacity = '1';
                button.style.opacity = '1';
                button.style.transform = 'scale(1.2)';
            });

            button.addEventListener('mouseleave', () => {
                tooltip.style.visibility = 'hidden';
                tooltip.style.opacity = '0';
                button.style.opacity = '0.6';
                button.style.transform = 'scale(1)';
            });
        }

        createTooltip(streamingButton, 'Streamer Mode!');

        const styleSheet = document.createElement("style");
        styleSheet.type = "text/css";
        styleSheet.innerText = `
        @keyframes tooltip_introduce {
            0% {
                opacity: 0;
                transform: scale(0.8);
            }
            100% {
                opacity: 1;
                transform: scale(1);
            }
        }
    `;
        document.head.appendChild(styleSheet);
        buttonContainer.appendChild(streamingButton);
        document.body.appendChild(buttonContainer);

        // Streamer Mode

        let streamerModeEnabled = false;
        let popupWindow = null;
        let observer = null;
        let hintsObserver = null;
        let chatObserver = null;
        let bannedWords = [];
        let standardBannedWords = ["nigger", "niger", "negro", "horny", "nigga", "blowjob", "jackoff", "jack off", "fuck", "20cm", "6 inch", "handjob", "whore", "cunt", "卐", "88", "cock", "viagra", "neger", "afd", "cdu", "csu", "dick", "👉👌", "asesinato", "asno", "bastardo", "bollera", "cabrón", "caca", "chupada", "chupapollas", "chupetón", "concha", "concha de tu madre", "coño", "coprofagía", "culo", "drogas", "esperma", "fiesta de salchichas", "follador", "follar", "gilipichis", "gilipollas", "hacer una paja", "haciendo el amor", "heroína", "idiota", "imbécil", "infierno", "jilipollas", "kapullo", "lameculos", "maciza", "macizorra", "maldito", "mamada", "marica", "maricón", "mariconazo", "martillo", "mierda", "nazi", "orina", "pedo", "pendejo", "pervertido", "pezón", "pinche", "pis", "prostituta", "puta", "racista", "ramera", "sádico", "semen", "sexo", "sexo oral", "soplagaitas", "soplapollas", "tetas grandes", "tía buena", "travesti", "trio", "verga", "vete a la mierda", "fucker", "tribadism", "two girls one cup", "topless", "vibrator", "twink", "voyeur", "swastika", "schwuchtel", "schlong", "threesome", "lolita", "throat", "swinger", "tubgirl", "upskirt", "urethra", "wet", "philia", "orgasm", "panty", "orgy", "bitch", "doggy", "gangbang", "gang bang", "genital", "homoerotic", "golden shower", "dildo", "penis", "pedo", "pegg", "nsfw", "nig nog", "vagina", "kys", "fuck you", "suicid", "sucker", "2 girls 1 cup", "suck", "2g1c", "tit", "🖕", "bdsm", "milf", "gilf", "nud", "anus", "scissoring", "slut", "sex", "hitler", "adolf", "hoe", "fucking", "piece of shit", "rectum", "boob", "jerk", "masturbat", "xx", "porn", "rape", "rosy", "camgirl", "sodom", "rapi", "pube", "fuck me", "strap", "strip", "prostit", "gay sex", "ape", "blonde on blonde", "bastar", "coprolagnia", "fucking gay", "eat my", "cream pie", "creampie", "creaming", "cum", "puss", "lewd", "hentai", "gya", "shut the fuck up", "卍", "ꖦ", "✙", "ᛋᛋ", "☭", "deez", "squirt", "dumbass", "nutt", "nut in", "thicc", "moan", "blow job", "anal", "rectal", "oral", "jew", "biggers", "booty", "glans", "vulva", "twat", "boner", "booti", "wank", "jizz", "doggie", "asshole", "arse", "gore", "missionary", "bang", "fecal", "eroti", "fellatio", "femdom", "mia kh", "groom", "mös", "kanak", "kanack", "fresse", "lesbe", "prick", "hure", "wichs", "pthc", "wix", "fick", "arsch", "undress", "hundeso", "leck m", "flittchen", "kack", "gefickt"];
        const wordsContainerSelector = "#game-canvas > div.overlay-content > div.words";
        const currentWordSelector = "#game-word > div.word";

        function saveBannedWords() {
            const allBannedWords = [...new Set(bannedWords)];
            localStorage.setItem("bannedWords", JSON.stringify(allBannedWords));
        }

        function loadBannedWords() {
            const storedWords = localStorage.getItem("bannedWords");
            if (storedWords) {
                bannedWords = JSON.parse(storedWords);
            }
            console.log(bannedWords)
        }

        function openStreamerWindow() {
            if (!popupWindow || popupWindow.closed) {
                popupWindow = window.open(
                    "",
                    "StreamerMode",
                    "width=600,height=800,scrollbars=no,resizable=yes,top=100,left=100"
                );

                if (popupWindow) {
                    popupWindow.document.title = "Streamer Mode";
                    popupWindow.document.body.style.cssText = `
                            font-family: "Nunito", sans-serif;
                            padding: 10px;
                            margin: 0;
                            background-image: url("https://imgur.com/xVBUecv.png");
                            background-size: 350px;
                            background-repeat: repeat;
                            color: #fff;
                            user-select: none;
                            display: flex;
                            flex-direction: column;
                            width: 100%;
                            height: 100%;
                        `;
                    popupWindow.document.body.innerHTML = `
                            <h2 style="filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, .3));">Words:</h2>
                            <div id="streamer-words" style="display: flex; flex-wrap: wrap; gap: 8px; background: #35394A; font-weight: bold;"></div>
                            <h2 style="filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, .3));">Current Word:</h2>
                            <div id="streamer-current-word" style="font-size: 1.2em; font-weight: bold; color: black; background: white; border-radius: 4px; width: 300px; height: 50px; display: flex; justify-content: center; align-items: center;"></div>
                            <div class="filterHeader" style="display: flex; align-items: center; gap: 8px; flex: 0 1 auto;"><img src="https://imgur.com/iSRTj2U.gif" alt="icon" style="width: 32px; height: 32px; filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, .3));"><h2 style="filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, .3));">Banned Words/Phrases</h2></div>
                            <textarea id="banned-words-input" spellcheck="false" placeholder="Words/phrases separated by a , (comma)" style="width: 90%; height: 200px; border: 1px solid #707070; filter: blur(8px); flex: 1 1 auto; resize: none; font: inherit; padding: .2em .5em; border-radius: 3px; font-size: 1.1em;"></textarea>
                            <label style="margin-top: 10px; display: flex; align-items: center; gap: 8px;">
                                <input type="checkbox" id="use-standard-words" style="aspect-ratio: 1; width: auto; height: 100%; margin: 0; padding: 0; transition: none; display: grid; place-content: center; background-color: white; color: rgb(44, 44, 44); "> Use/Add standard banned words
                            </label>
                        `;

                    const textarea = popupWindow.document.getElementById("banned-words-input");
                    const standardCheckbox = popupWindow.document.getElementById("use-standard-words");

                    textarea.style.cssText += `
    outline: none;
`;

                    textarea.addEventListener("focus", () => {
                        textarea.style.borderColor = "#56b2fd";
                        textarea.style.boxShadow = "0 0 10px -4px #56b2fd";
                        textarea.style.filter = "none";
                    });

                    textarea.addEventListener("blur", () => {
                        textarea.style.borderColor = "#707070";
                        textarea.style.boxShadow = "none";
                        textarea.style.filter = "blur(8px)";
                    });

                    standardCheckbox.style.cssText += `
                            &:focus {
                                outline: 0;
                                border-color: #56b2fd;
                                box-shadow: 0 0 10px -4px #56b2fd;
                                font-style: normal;
                            }
                        `;

                    textarea.addEventListener("input", () => {
                        bannedWords = textarea.value.split(",").map(word => word.trim().toLowerCase());
                        saveBannedWords();
                    });

                    standardCheckbox.addEventListener("change", () => {
                        bannedWords = bannedWords || [];
                        if (standardCheckbox.checked) {
                            bannedWords = bannedWords.length > 1 ? [...new Set([...bannedWords, ...standardBannedWords])] : [...standardBannedWords];

                        } else {
                            bannedWords = bannedWords.filter(word => !standardBannedWords.includes(word));
                        }
                        saveBannedWords();
                        loadBannedWords();
                        textarea.value = bannedWords.join(", ");
                    });

                    loadBannedWords();
                    textarea.value = bannedWords.join(", ");

                    startPopupMonitor();
                } else {
                    console.error("Failed to create popup window. Please allow popups for this site.");
                }
            }
        }

        function observePlayerBubbles(streamerModeEnabled, bannedWords) {
            const playersContainer = document.querySelector("#game-players > div");

            if (!playersContainer) {
                console.error("Players container not found.");
                return null;
            }

            const observer = new MutationObserver(() => {
                if (!streamerModeEnabled) return;

                const textElements = playersContainer.querySelectorAll(
                    "div.player > div.player-bubble > div.content > div.text"
                );

                textElements.forEach((textElement) => {
                    const text = textElement.textContent || "";

                    console.log("Processing text:", text);

                    if (bannedWords.some((word) => text.includes(word))) {
                        console.log("Banned word found:", text);

                        textElement.style.filter = "blur(8px)";
                        console.log(`Applied blur to element:`, textElement);
                    } else {
                        textElement.style.filter = "none";
                        console.log(`Removed blur from element:`, textElement);
                    }
                });
            });

            observer.observe(playersContainer, {
                childList: true,
                subtree: true,
            });

            return observer;
        }

        function observeChat() {
            const chatContainer = document.querySelector("#game-chat > div.chat-content");
            if (!chatContainer) {
                console.error("Chat content not found.");
                return;
            }

            chatObserver = new MutationObserver(() => {
                const lastMessage = chatContainer.querySelector("p:last-child");

                if (lastMessage) {
                    const targetElements = lastMessage.querySelectorAll("b, span");

                    targetElements.forEach((element) => {
                        const text = element.textContent.trim().toLowerCase();
                        if (streamerModeEnabled && bannedWords.length > 1 && bannedWords.some(word => text.includes(word))) {
                            if (!element.classList.contains("censored")) {
                                element.classList.add("censored");

                                element.style.filter = "blur(4px)";

                                element.addEventListener("mouseover", () => {
                                    if (streamerModeEnabled) {
                                        element.style.filter = "none";
                                    }
                                });

                                element.addEventListener("mouseout", () => {
                                    if (streamerModeEnabled) {
                                        element.style.filter = "blur(4px)";
                                    }
                                });
                            }
                        } else {
                            element.style.filter = "none";
                            element.classList.remove("censored");
                        }
                    });
                }

                const playerNames = document.querySelectorAll("div.player-name");
                playerNames.forEach((playerName) => {
                    const text = playerName.textContent.trim().toLowerCase();
                    if (streamerModeEnabled && bannedWords.length > 1 && bannedWords.some(word => text.includes(word))) {
                        if (!playerName.classList.contains("censored")) {
                            playerName.classList.add("censored");

                            playerName.style.filter = "blur(4px)";

                            playerName.addEventListener("mouseover", () => {
                                if (streamerModeEnabled) {
                                    playerName.style.filter = "none";
                                }
                            });

                            playerName.addEventListener("mouseout", () => {
                                if (streamerModeEnabled) {
                                    playerName.style.filter = "blur(4px)";
                                }
                            });
                        }
                    } else {
                        playerName.style.filter = "none";
                        playerName.classList.remove("censored");
                    }
                });

                const playerNames2 = document.querySelectorAll("div.name");
                playerNames2.forEach((playerName) => {
                    const text = playerName.textContent.trim().toLowerCase();
                    if (streamerModeEnabled && bannedWords.length > 1 && bannedWords.some(word => text.includes(word))) {
                        if (!playerName.classList.contains("censored")) {
                            playerName.classList.add("censored");

                            playerName.style.filter = "blur(4px)";

                            playerName.addEventListener("mouseover", () => {
                                if (streamerModeEnabled) {
                                    playerName.style.filter = "none";
                                }
                            });

                            playerName.addEventListener("mouseout", () => {
                                if (streamerModeEnabled) {
                                    playerName.style.filter = "blur(4px)";
                                }
                            });
                        }
                    } else {
                        playerName.style.filter = "none";
                        playerName.classList.remove("censored");
                    }
                });

                const playerNames3 = document.querySelectorAll("div.rank-name");
                playerNames3.forEach((playerName) => {
                    const text = playerName.textContent.trim().toLowerCase();
                    if (streamerModeEnabled && bannedWords.length > 1 && bannedWords.some(word => text.includes(word))) {
                        if (!playerName.classList.contains("censored")) {
                            playerName.classList.add("censored");

                            playerName.style.filter = "blur(4px)";

                            playerName.addEventListener("mouseover", () => {
                                if (streamerModeEnabled) {
                                    playerName.style.filter = "none";
                                }
                            });

                            playerName.addEventListener("mouseout", () => {
                                if (streamerModeEnabled) {
                                    playerName.style.filter = "blur(4px)";
                                }
                            });
                        }
                    } else {
                        playerName.style.filter = "none";
                        playerName.classList.remove("censored");
                    }
                });

            });

            chatObserver.observe(chatContainer, {
                childList: true
            });
        }

        function cleanupBlurEffects() {
            const blurredElements = document.querySelectorAll(".censored");
            blurredElements.forEach((element) => {
                element.style.filter = "none";
                element.classList.remove("censored");

                element.onmouseover = null;
                element.onmouseout = null;
            });
        }


        function disconnectChatObserver() {
            if (chatObserver) {
                chatObserver.disconnect();
                chatObserver = null;
            }
        }


        function closeStreamerWindow() {
            if (popupWindow && !popupWindow.closed) {
                popupWindow.close();
            }
            popupWindow = null;
            stopPopupMonitor();
        }

        function updateStreamerWindow(wordsContainer, currentWord) {
            if (popupWindow && !popupWindow.closed) {
                const wordsDiv = popupWindow.document.querySelector("#streamer-words");
                const currentWordDiv = popupWindow.document.querySelector("#streamer-current-word");

                if (wordsDiv) {
                    wordsDiv.innerHTML = "";
                    if (wordsContainer) {
                        const wordElements = wordsContainer.querySelectorAll(".word");
                        wordElements.forEach((wordElement, index) => {
                            const word = wordElement.textContent.trim();
                            const wordBox = document.createElement("div");
                            wordBox.textContent = word;
                            wordBox.style.cssText = `
                                    padding: 8px;
                                    margin: 1em;
                                    border: white solid;
                                    border-radius: 4px;
                                    font-size: 1em;
                                    cursor: pointer;
                                    transition: background 0.3s, color 0.3s;
                                `;
                            wordBox.addEventListener("mouseover", () => {
                                wordBox.style.background = "white";
                                wordBox.style.color = "#35394A";
                            });
                            wordBox.addEventListener("mouseout", () => {
                                wordBox.style.background = "transparent";
                                wordBox.style.color = "white";
                            });
                            wordBox.addEventListener("click", () => {
                                wordElement.click();
                            });
                            wordsDiv.appendChild(wordBox);
                        });
                    } else {
                        wordsDiv.textContent = "No words available.";
                    }
                }

                if (currentWordDiv) {
                    if (currentWord) {
                        const wordLengthString = currentWord.split(/\s/).map(word => word.replace(/-/g, '').length);
                        const wordLength = wordLengthString.join(" ");
                        currentWordDiv.innerHTML = `${currentWord} <sup style="transform: scale(0.7);margin-bottom: 8px;">${wordLength}</sup>`;
                    } else {
                        currentWordDiv.textContent = "No word available.";
                    }
                }
            }
        }

        let popupMonitorInterval = null;

        function startPopupMonitor() {
            if (popupMonitorInterval) return;

            popupMonitorInterval = setInterval(() => {
                if (popupWindow && popupWindow.closed) {
                    toggleStreamerMode();
                }
            }, 500);
        }

        function stopPopupMonitor() {
            if (popupMonitorInterval) {
                clearInterval(popupMonitorInterval);
                popupMonitorInterval = null;
            }
        }

        function observeHints() {
            const hintsContainer = document.querySelector("#game-word > div.hints > div.container");

            if (!hintsContainer) {
                console.error("Could not find hints container.");
                return;
            }

            hintsObserver = new MutationObserver(() => {
                const hints = hintsContainer.querySelectorAll(".hint");

                const allUncovered = Array.from(hints).every(
                    (hint) => hint.classList.contains("uncover")
                );

                if (allUncovered) {
                    const guessedWord = Array.from(hints)
                        .map((hint) =>
                            hint.textContent.trim() === "" && hint.classList.contains("uncover") ?
                            " " :
                            hint.textContent.trim()
                        )
                        .join("");

                    updateStreamerWindow(null, guessedWord);

                    hints.forEach((hint) => {
                        if (hint.classList.contains("uncover") && hint.textContent.trim() !== "") {
                            hint.textContent = "_";
                        }
                    });

                    hintsObserver.disconnect();
                    hintsObserver.observe(hintsContainer, {
                        childList: true,
                        subtree: true
                    });
                }
            });

            hintsObserver.observe(hintsContainer, {
                childList: true,
                subtree: true
            });
        }




        function disconnectObservers() {
            if (observer) {
                observer.disconnect();
            }
            if (hintsObserver) {
                hintsObserver.disconnect();
            }
            observer = null;
            hintsObserver = null;
        }

        function observeWords() {
            const wordsContainer = document.querySelector(wordsContainerSelector);
            const currentWord = document.querySelector(currentWordSelector);

            if (!wordsContainer || !currentWord) {
                console.error("Could not find words container or current word element.");
                return;
            }

            wordsContainer.style.visibility = "hidden";
            currentWord.style.visibility = "hidden";

            observer = new MutationObserver(() => {
                const currentWordText = currentWord.textContent.trim();
                updateStreamerWindow(wordsContainer, currentWordText);
            });

            observer.observe(wordsContainer, {
                childList: true,
                subtree: true
            });
            observer.observe(currentWord, {
                childList: true,
                subtree: true
            });
        }

        let bubblesObserver;

        function toggleStreamerMode() {
            streamerModeEnabled = !streamerModeEnabled;

            if (streamingButton) {
                streamingButton.style.filter = streamerModeEnabled ? "none" : "grayscale(100%)";
            }

            if (streamerModeEnabled) {
                openStreamerWindow();
                observeWords();
                disconnectChatObserver();
                observeHints();
                observeChat();

                bubblesObserver = observePlayerBubbles(streamerModeEnabled, bannedWords);

                console.log("Streamer Mode enabled.");
                addBlurToggleButton();
            } else {
                disconnectObservers();
                closeStreamerWindow();
                cleanupBlurEffects();

                if (bubblesObserver) {
                    bubblesObserver.disconnect();
                    bubblesObserver = null;
                }

                const wordsContainer = document.querySelector(wordsContainerSelector);
                const currentWord = document.querySelector(currentWordSelector);
                if (wordsContainer) wordsContainer.style.visibility = "";
                if (currentWord) currentWord.style.visibility = "";

                console.log("Streamer Mode disabled.");
            }
        }



        let blurButton = null;
        let isBlurred = false;

        function addBlurToggleButton() {
            const gameCanvas = document.querySelector("#game-canvas > canvas");

            if (!gameCanvas) {
                console.error("Canvas element not found.");
                return;
            }

            if (blurButton) {
                console.warn("Blur button already exists.");
                return;
            }

            blurButton = document.createElement('button');
            blurButton.textContent = '';
            blurButton.className = 'blurButton';
            blurButton.style.cssText = `
        z-index: 1000;
        width: 48px;
        height: 48px;
        background-image: url('https://imgur.com/lGaaS9h.gif');
        cursor: pointer;
        filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, .3));
        background-color: transparent;
        background-size: contain;
        background-repeat: no-repeat;
        position: absolute;
        opacity: 0.6;
        transition: opacity .15s ease, transform .15s ease;
        top: 4px;
        left: 4px;
    `;

            const style = document.createElement('style');
            style.textContent = `
        .blurButton:hover {
            opacity: 1 !important;
            transform: scale(1.1);
        }
    `;
            document.head.appendChild(style);

            const gameCanvasContainer = document.querySelector("#game-canvas");
            if (gameCanvasContainer) {
                gameCanvasContainer.style.position = "relative";
                gameCanvasContainer.appendChild(blurButton);
            } else {
                console.error("Game canvas container not found.");
                return;
            }

            blurButton.addEventListener("click", () => {
                isBlurred = !isBlurred;
                gameCanvas.style.filter = isBlurred ? "blur(50px)" : "none";
            });
        }




        streamingButton.addEventListener('click', toggleStreamerMode);
    })();