YouTube All-in-One: Premium Logo, HD, Downloader & Telegram (Stable)

Combines Premium Logo, HD quality lock, Native Downloader, Settings Menu, and replaces "Thanks" with a Telegram link. Fixed freezing issues.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         YouTube All-in-One: Premium Logo, HD, Downloader & Telegram (Stable)
// @name:ru      YouTube Всё-в-одном: Premium Лого, HD, Скачивание и Телеграм (Стабильный)
// @namespace    electroknight22_youhou_premium_logo_telegram_v13
// @version      2025.1.13
// @description  Combines Premium Logo, HD quality lock, Native Downloader, Settings Menu, and replaces "Thanks" with a Telegram link. Fixed freezing issues.
// @description:ru Исправлены фризы и ошибки 500. Меняет лого на Premium, фиксирует HD (без спама), добавляет скачивание и ссылку на Telegram.
// @author       Evreu1pro
// @match        *://www.youtube.com/*
// @match        *://m.youtube.com/*
// @match        *://www.youtube-nocookie.com/*
// @exclude      *://www.youtube.com/live_chat*
// @grant        GM_addStyle
// @run-at       document-idle
// @license      MIT
// @icon         https://www.youtube.com/s/desktop/2731d6a3/img/favicon_48x48.png
// ==/UserScript==

(function () {
    'use strict';

    // ==========================================
    // ЧАСТЬ 1: ПРЕМИУМ ЛОГОТИП (CSS)
    // ==========================================
    const premiumLogoCSS = `
        #logo-container .logo, .footer-logo-icon, #logo-icon, #logo-icon-container {
            width: 98px !important; margin-left: 5px; margin-right: 5px;
            content: url("data:image/svg+xml,%3Csvg xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns%23' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns%23' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' id='SVGRoot' version='1.1' viewBox='0 0 846 174' height='80px' width='391px'%3E%3Cdefs id='defs855'%3E%3Cstyle id='style2' /%3E%3C/defs%3E%3Cg id='layer1'%3E%3Cg transform='translate(0,0.36)' data-name='Layer 2' id='Layer_2'%3E%3Cg data-name='Layer 1' id='Layer_1-2'%3E%3Cpath style='fill:%23ff0000' id='path6' d='M 242.88,27.11 A 31.07,31.07 0 0 0 220.95,5.18 C 201.6,0 124,0 124,0 124,0 46.46,0 27.11,5.18 A 31.07,31.07 0 0 0 5.18,27.11 C 0,46.46 0,86.82 0,86.82 c 0,0 0,40.36 5.18,59.71 a 31.07,31.07 0 0 0 21.93,21.93 c 19.35,5.18 96.92,5.18 96.92,5.18 0,0 77.57,0 96.92,-5.18 a 31.07,31.07 0 0 0 21.93,-21.93 c 5.18,-19.35 5.18,-59.71 5.18,-59.71 0,0 0,-40.36 -5.18,-59.71 z' /%3E%3Cpath style='fill:%23ffffff' id='path8' d='M 99.22,124.03 163.67,86.82 99.22,49.61 Z' /%3E%3Cpath style='fill:%23282828' id='path10' d='m 358.29,55.1 v 6 c 0,30 -13.3,47.53 -42.39,47.53 h -4.43 v 52.5 H 287.71 V 12.36 H 318 c 27.7,0 40.29,11.71 40.29,42.74 z m -25,2.13 c 0,-21.64 -3.9,-26.78 -17.38,-26.78 h -4.43 v 60.48 h 4.08 c 12.77,0 17.74,-9.22 17.74,-29.26 z m 81.22,-6.56 -1.24,28.2 c -10.11,-2.13 -18.45,-0.53 -22.17,6 v 76.26 H 367.52 V 52.44 h 18.8 L 388.45,76 h 0.89 c 2.48,-17.2 10.46,-25.89 20.75,-25.89 a 22.84,22.84 0 0 1 4.42,0.56 z M 441.64,115 v 5.5 c 0,19.16 1.06,25.72 9.22,25.72 7.8,0 9.58,-6 9.75,-18.44 l 21.1,1.24 c 1.6,23.41 -10.64,33.87 -31.39,33.87 -25.18,0 -32.63,-16.49 -32.63,-46.46 v -19 c 0,-31.57 8.34,-47 33.34,-47 25.18,0 31.57,13.12 31.57,45.93 V 115 Z m 0,-22.35 v 7.8 h 17.91 V 92.7 c 0,-20 -1.42,-25.72 -9,-25.72 -7.58,0 -8.91,5.86 -8.91,25.72 z M 604.45,79 v 82.11 H 580 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8.16,2.48 -10.82,7.09 a 35.59,35.59 0 0 1 0.18,4.43 v 82.11 H 537.24 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8,2.48 -10.64,6.92 v 86.72 H 494.5 V 52.44 h 19.33 L 516,66.28 h 0.35 c 5.5,-10.46 14.37,-16.14 24.83,-16.14 10.29,0 16.14,5.14 18.8,14.37 5.68,-9.4 14.19,-14.37 23.94,-14.37 14.86,0 20.53,10.64 20.53,28.86 z m 12.24,-54.4 c 0,-11.71 4.26,-15.07 13.3,-15.07 9.22,0 13.3,3.9 13.3,15.07 0,12.06 -4.08,15.08 -13.3,15.08 -9.04,-0.01 -13.3,-3.02 -13.3,-15.08 z m 1.42,27.84 h 23.41 v 108.72 h -23.41 z m 103.39,0 v 108.72 h -19.15 l -2.13,-13.3 h -0.53 c -5.5,10.64 -13.48,15.07 -23.41,15.07 -14.54,0 -21.11,-9.22 -21.11,-29.26 V 52.44 h 24.47 v 79.81 c 0,9.58 2,13.48 6.92,13.48 A 12.09,12.09 0 0 0 697,138.81 V 52.44 Z M 845.64,79 v 82.11 H 821.17 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8.16,2.48 -10.82,7.09 A 35.59,35.59 0 0 1 802.9,79 v 82.11 H 778.43 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8,2.48 -10.64,6.92 v 86.72 H 735.69 V 52.44 H 755 l 2.13,13.83 h 0.35 c 5.5,-10.46 14.37,-16.14 24.83,-16.14 10.29,0 16.14,5.14 18.8,14.37 5.68,-9.4 14.19,-14.37 23.94,-14.37 14.95,0.01 20.59,10.65 20.59,28.87 z' /%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E") !important;
        }
        html[dark] #logo-icon, html[dark] #logo-icon-container {
            width: 98px !important;
            content: url("data:image/svg+xml,%3Csvg xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns%23' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns%23' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' id='SVGRoot' version='1.1' viewBox='0 0 846 174' height='24px' width='98px'%3E%3Cdefs id='defs855'%3E%3Cstyle id='style2' /%3E%3C/defs%3E%3Cg id='layer1'%3E%3Cg transform='translate(0,0.36)' data-name='Layer 2' id='Layer_2'%3E%3Cg data-name='Layer 1' id='Layer_1-2'%3E%3Cpath style='fill:%23ff0000' id='path6' d='M 242.88,27.11 A 31.07,31.07 0 0 0 220.95,5.18 C 201.6,0 124,0 124,0 124,0 46.46,0 27.11,5.18 A 31.07,31.07 0 0 0 5.18,27.11 C 0,46.46 0,86.82 0,86.82 c 0,0 0,40.36 5.18,59.71 a 31.07,31.07 0 0 0 21.93,21.93 c 19.35,5.18 96.92,5.18 96.92,5.18 0,0 77.57,0 96.92,-5.18 a 31.07,31.07 0 0 0 21.93,-21.93 c 5.18,-19.35 5.18,-59.71 5.18,-59.71 0,0 0,-40.36 -5.18,-59.71 z' /%3E%3Cpath style='fill:%23ffffff' id='path8' d='M 99.22,124.03 163.67,86.82 99.22,49.61 Z' /%3E%3Cpath style='fill:%23ffffff' id='path10' d='m 358.29,55.1 v 6 c 0,30 -13.3,47.53 -42.39,47.53 h -4.43 v 52.5 H 287.71 V 12.36 H 318 c 27.7,0 40.29,11.71 40.29,42.74 z m -25,2.13 c 0,-21.64 -3.9,-26.78 -17.38,-26.78 h -4.43 v 60.48 h 4.08 c 12.77,0 17.74,-9.22 17.74,-29.26 z m 81.22,-6.56 -1.24,28.2 c -10.11,-2.13 -18.45,-0.53 -22.17,6 v 76.26 H 367.52 V 52.44 h 18.8 L 388.45,76 h 0.89 c 2.48,-17.2 10.46,-25.89 20.75,-25.89 a 22.84,22.84 0 0 1 4.42,0.56 z M 441.64,115 v 5.5 c 0,19.16 1.06,25.72 9.22,25.72 7.8,0 9.58,-6 9.75,-18.44 l 21.1,1.24 c 1.6,23.41 -10.64,33.87 -31.39,33.87 -25.18,0 -32.63,-16.49 -32.63,-46.46 v -19 c 0,-31.57 8.34,-47 33.34,-47 25.18,0 31.57,13.12 31.57,45.93 V 115 Z m 0,-22.35 v 7.8 h 17.91 V 92.7 c 0,-20 -1.42,-25.72 -9,-25.72 -7.58,0 -8.91,5.86 -8.91,25.72 z M 604.45,79 v 82.11 H 580 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8.16,2.48 -10.82,7.09 a 35.59,35.59 0 0 1 0.18,4.43 v 82.11 H 537.24 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8,2.48 -10.64,6.92 v 86.72 H 494.5 V 52.44 h 19.33 L 516,66.28 h 0.35 c 5.5,-10.46 14.37,-16.14 24.83,-16.14 10.29,0 16.14,5.14 18.8,14.37 5.68,-9.4 14.19,-14.37 23.94,-14.37 14.86,0 20.53,10.64 20.53,28.86 z m 12.24,-54.4 c 0,-11.71 4.26,-15.07 13.3,-15.07 9.22,0 13.3,3.9 13.3,15.07 0,12.06 -4.08,15.08 -13.3,15.08 -9.04,-0.01 -13.3,-3.02 -13.3,-15.08 z m 1.42,27.84 h 23.41 v 108.72 h -23.41 z m 103.39,0 v 108.72 h -19.15 l -2.13,-13.3 h -0.53 c -5.5,10.64 -13.48,15.07 -23.41,15.07 -14.54,0 -21.11,-9.22 -21.11,-29.26 V 52.44 h 24.47 v 79.81 c 0,9.58 2,13.48 6.92,13.48 A 12.09,12.09 0 0 0 697,138.81 V 52.44 Z M 845.64,79 v 82.11 H 821.17 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8.16,2.48 -10.82,7.09 A 35.59,35.59 0 0 1 802.9,79 v 82.11 H 778.43 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8,2.48 -10.64,6.92 v 86.72 H 735.69 V 52.44 H 755 l 2.13,13.83 h 0.35 c 5.5,-10.46 14.37,-16.14 24.83,-16.14 10.29,0 16.14,5.14 18.8,14.37 5.68,-9.4 14.19,-14.37 23.94,-14.37 14.95,0.01 20.59,10.65 20.59,28.87 z' /%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E") !important;
        }
    `;

    if (typeof GM_addStyle === 'function') {
        GM_addStyle(premiumLogoCSS);
    } else {
        const style = document.createElement('style');
        style.textContent = premiumLogoCSS;
        document.head.append(style);
    }

    // ==========================================
    // ЧАСТЬ 2: ХРАНИЛИЩЕ И УТИЛИТЫ
    // ==========================================
    const PREF_KEY = 'yt_target_quality_v13';

    const Storage = {
        get: (key, def) => localStorage.getItem(key) || def,
        set: (key, val) => localStorage.setItem(key, val)
    };

    const safeEmpty = (element) => {
        while (element.firstChild) element.removeChild(element.firstChild);
    };

    const createSVG = (dPath) => {
        const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        svg.setAttribute("height", "24");
        svg.setAttribute("width", "24");
        svg.setAttribute("viewBox", "0 0 24 24");
        svg.setAttribute("fill", "currentColor");
        const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
        path.setAttribute("d", dPath);
        svg.appendChild(path);
        return svg;
    };

    const createElem = (tag, className, text = null) => {
        const el = document.createElement(tag);
        if (className) el.className = className;
        if (text) el.textContent = text;
        return el;
    };

    const ICONS_PATHS = {
        pin: "M16,12V4H17V2H7V4H8V12L6,14V16H11.5V22H12.5V16H18V14L16,12Z",
        check: "M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z",
        back: "M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z",
        download: "M17 18v1H6v-1h11zm-.5-6.6-.7-.7-3.8 3.7V4h-1v10.4l-3.8-3.8-.7.7 5 5 5-4.9z",
        telegram: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.64 6.8c-.15 1.58-.8 5.42-1.13 7.19-.14.75-.42 1-.68 1.03-.58.05-1.02-.38-1.58-.75-.88-.58-1.38-.94-2.23-1.5-.99-.65-.35-1.01.22-1.59.15-.15 2.71-2.48 2.76-2.69.01-.03.01-.14-.07-.2-.08-.06-.19-.04-.27-.02-.12.02-1.96 1.25-5.54 3.69-.52.36-1 .53-1.42.52-.47-.01-1.37-.26-2.03-.48-.82-.27-1.47-.42-1.42-.88.03-.24.29-.48.79-.74 3.08-1.34 5.15-2.23 6.21-2.66 2.95-1.23 3.56-1.43 3.97-1.43.09 0 .28.02.41.12.13.1.16.23.17.38z",
        thanks: "M16.25 2"
    };

    const I18N = {
        'en': { download: 'Download', quality: 'Preferred Quality', scripts: 'Scripts' },
        'ru': { download: 'Скачать', quality: 'Качество видео', scripts: 'Скрипты' },
        'de': { download: 'Herunterladen', quality: 'Videoqualität', scripts: 'Skripte' },
        'es': { download: 'Descargar', quality: 'Calidad preferida', scripts: 'Scripts' },
        'fr': { download: 'Télécharger', quality: 'Qualité préférée', scripts: 'Scripts' },
        'ja': { download: 'ダウンロード', quality: '希望する画質', scripts: 'スクリプト' },
        'zh': { download: '下载', quality: '首选画质', scripts: '脚本' },
        'uk': { download: 'Завантажити', quality: 'Бажана якість', scripts: 'Скрипти' }
    };

    function getLang() {
        const code = document.documentElement.lang || navigator.language || 'en';
        return I18N[code.split('-')[0]] || I18N['en'];
    }

    const QUALITY_LEVELS = {
        'highres': 'Max (4K/8K)',
        'hd2160': '2160p (4K)',
        'hd1440': '1440p (2K)',
        'hd1080': '1080p (HD)',
        'hd720': '720p',
        'large': '480p',
        'medium': '360p'
    };

    // ==========================================
    // ЧАСТЬ 3: МОДУЛЬ HD (БЕЗ ФРИЗОВ)
    // ==========================================
    let hasQualityBeenSet = false; // Флаг: ставили ли уже качество для этого видео

    function forceVideoQuality(isManual = false) {
        const player = document.getElementById('movie_player');
        if (!player || typeof player.setPlaybackQualityRange !== 'function') return;

        // Если автоматика уже сработала один раз, не трогаем плеер, чтобы не сбивать буфер
        if (!isManual && hasQualityBeenSet) return;

        try {
            const target = Storage.get(PREF_KEY, 'highres');
            const available = player.getAvailableQualityLevels();
            if (!available || !available.length) return;

            let targetQualityVal = (target === 'highres') ? available[0] : target;
            if (!available.includes(targetQualityVal)) targetQualityVal = available[0];

            const currentQuality = player.getPlaybackQuality();
            
            // Применяем только если отличается
            if (currentQuality !== targetQualityVal || isManual) {
                console.log(`[YouTube Script] Setting quality to: ${targetQualityVal}`);
                player.setPlaybackQualityRange(targetQualityVal, targetQualityVal);
                player.setPlaybackQuality(targetQualityVal);
                hasQualityBeenSet = true; 
            }
        } catch (e) {
            console.warn('[YouTube Script] Error setting quality', e);
        }
    }

    function initHDLogic() {
        // Сбрасываем флаг при смене видео
        let lastUrl = location.href;
        new MutationObserver(() => {
            const url = location.href;
            if (url !== lastUrl) {
                lastUrl = url;
                hasQualityBeenSet = false; // Новое видео - можно один раз поставить качество
            }
        }).observe(document, {subtree: true, childList: true});

        const observer = new MutationObserver(() => {
            const player = document.getElementById('movie_player');
            if (player) {
                if (!player.dataset.qualityLocked) {
                    player.addEventListener('onStateChange', (state) => {
                        // 1 = playing. Мы больше НЕ слушаем state === 3 (buffering), чтобы не вызывать петлю.
                        if (state === 1) {
                            setTimeout(() => forceVideoQuality(), 500);
                        }
                    });
                    player.dataset.qualityLocked = "true";
                }
                // Первая попытка при загрузке
                setTimeout(() => forceVideoQuality(), 1500);
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }

    // ==========================================
    // ЧАСТЬ 4: ИНТЕГРАЦИЯ В МЕНЮ
    // ==========================================
    function injectSettingsMenu() {
        document.addEventListener('click', (e) => {
            const settingsBtn = e.target.closest('.ytp-settings-button');
            if (settingsBtn) {
                setTimeout(addMenuItem, 50);
                setTimeout(addMenuItem, 500); 
            }
        }, true);
    }

    function addMenuItem() {
        const menu = document.querySelector('.ytp-settings-menu .ytp-panel-menu');
        if (!menu || document.getElementById('yt-pref-quality-item')) return;

        const lang = getLang();
        const currentVal = Storage.get(PREF_KEY, 'highres');
        const currentLabel = QUALITY_LEVELS[currentVal] || currentVal;

        const menuItem = createElem('div', 'ytp-menuitem');
        menuItem.id = 'yt-pref-quality-item';
        menuItem.setAttribute('role', 'menuitem');
        menuItem.setAttribute('tabindex', '0');

        const iconDiv = createElem('div', 'ytp-menuitem-icon');
        iconDiv.appendChild(createSVG(ICONS_PATHS.pin));

        const labelDiv = createElem('div', 'ytp-menuitem-label', lang.quality);
        const contentDiv = createElem('div', 'ytp-menuitem-content');
        const valueDiv = createElem('div', 'ytp-menuitem-value', currentLabel);
        contentDiv.appendChild(valueDiv);

        menuItem.appendChild(iconDiv);
        menuItem.appendChild(labelDiv);
        menuItem.appendChild(contentDiv);
        menuItem.onclick = () => openSubMenu(menu);

        if (menu.firstChild) menu.insertBefore(menuItem, menu.children[1] || menu.firstChild);
        else menu.appendChild(menuItem);
        
        const panel = menu.closest('.ytp-panel');
        if (panel) panel.style.height = ''; 
    }

    function openSubMenu(mainMenu) {
        const panel = mainMenu.closest('.ytp-panel');
        if (!panel) return;

        mainMenu.style.display = 'none';
        let subMenu = document.getElementById('yt-pref-quality-submenu');
        if (subMenu) safeEmpty(subMenu);
        else {
            subMenu = createElem('div', 'ytp-panel-menu');
            subMenu.id = 'yt-pref-quality-submenu';
            panel.appendChild(subMenu);
        }
        subMenu.style.display = 'block';

        const header = createElem('div', 'ytp-panel-header');
        header.style.cssText = 'padding: 10px 0; border-bottom: 1px solid rgba(255,255,255,0.1); display: flex; align-items: center; cursor: pointer;';
        
        const titleDiv = createElem('div', 'ytp-panel-title');
        titleDiv.style.display = 'flex'; titleDiv.style.alignItems = 'center';
        const backIconSpan = createElem('span');
        backIconSpan.style.marginRight = '10px';
        backIconSpan.appendChild(createSVG(ICONS_PATHS.back));
        titleDiv.appendChild(backIconSpan);
        titleDiv.appendChild(document.createTextNode(getLang().quality));
        header.appendChild(titleDiv);

        header.onclick = () => {
            subMenu.style.display = 'none'; mainMenu.style.display = 'block'; subMenu.remove();
            const currentVal = Storage.get(PREF_KEY, 'highres');
            const itemValue = document.querySelector('#yt-pref-quality-item .ytp-menuitem-value');
            if (itemValue) itemValue.textContent = QUALITY_LEVELS[currentVal];
        };
        subMenu.appendChild(header);

        const currentVal = Storage.get(PREF_KEY, 'highres');
        Object.keys(QUALITY_LEVELS).forEach(key => {
            const option = createElem('div', 'ytp-menuitem');
            option.setAttribute('role', 'menuitemradio'); option.setAttribute('tabindex', '0');
            const isChecked = currentVal === key;
            option.setAttribute('aria-checked', isChecked);
            const label = createElem('div', 'ytp-menuitem-label', QUALITY_LEVELS[key]);
            label.style.paddingLeft = '15px';
            const content = createElem('div', 'ytp-menuitem-content');
            if (isChecked) content.appendChild(createSVG(ICONS_PATHS.check));
            option.appendChild(label); option.appendChild(content);
            option.onclick = () => { 
                Storage.set(PREF_KEY, key); 
                forceVideoQuality(true); // Manual override
                header.click(); 
            };
            subMenu.appendChild(option);
        });
        panel.style.height = `${subMenu.scrollHeight}px`;
    }

    // ==========================================
    // ЧАСТЬ 5: МОДУЛЬ КНОПОК (СКАЧАТЬ И TELEGRAM)
    // ==========================================
    function getDownloadUrl() { return window.location.href.replace('youtube.com', 'addyoutube.com'); }

    function modifyButton(buttonElement, type) {
        const lang = getLang();
        buttonElement.onclick = (e) => {
            e.preventDefault(); e.stopPropagation();
            if (type === 'download') window.open(getDownloadUrl(), '_blank');
            if (type === 'telegram') window.open('https://t.me/gostibissi', '_blank');
        };

        const svg = buttonElement.querySelector('svg');
        if (svg) {
            safeEmpty(svg);
            const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
            path.setAttribute("d", type === 'download' ? ICONS_PATHS.download : ICONS_PATHS.telegram);
            path.setAttribute("fill", "currentColor");
            svg.appendChild(path);
        }

        const textSpan = buttonElement.querySelector('yt-formatted-string') || 
                         buttonElement.querySelector('.yt-spec-button-shape-next__button-text-content span');
        if (textSpan) textSpan.textContent = type === 'download' ? lang.download : lang.scripts;

        const tooltip = buttonElement.closest(type === 'download' ? 'ytd-download-button-renderer' : 'ytd-button-renderer, yt-button-view-model')?.querySelector('tp-yt-paper-tooltip');
        if (tooltip && tooltip.textContent) tooltip.textContent = type === 'download' ? lang.download : lang.scripts;

        const anchor = buttonElement.querySelector('a');
        if (anchor) { anchor.removeAttribute('href'); anchor.removeAttribute('target'); }
    }

    function processButtons() {
        // 1. Download Button
        const nativeDownload = document.querySelector('ytd-download-button-renderer');
        if (nativeDownload) {
            if (nativeDownload.dataset.replaced !== "true") {
                const originalButton = nativeDownload.querySelector('button');
                if (originalButton) {
                    const newButton = originalButton.cloneNode(true);
                    modifyButton(newButton, 'download');
                    originalButton.parentNode.replaceChild(newButton, originalButton);
                    nativeDownload.dataset.replaced = "true";
                }
            }
        } else {
            if (!document.getElementById('custom-download-btn')) createCustomButton('download');
        }

        // 2. Telegram Button (Replace Thanks or Add New)
        const buttonsContainer = document.querySelector('#top-level-buttons-computed');
        if (!buttonsContainer) return;
        
        let thanksButton = null;
        
        // ПОИСК: Ищем среди всех возможных контейнеров кнопок (включая новые view-model)
        const candidates = buttonsContainer.querySelectorAll('ytd-button-renderer, yt-button-view-model');
        
        for (const btn of candidates) {
            // Проверка по иконке
            const path = btn.querySelector('path');
            if (path && path.getAttribute('d') && path.getAttribute('d').startsWith(ICONS_PATHS.thanks)) {
                thanksButton = btn;
                break;
            }
        }

        if (thanksButton && thanksButton.dataset.replaced !== "true") {
            // Замена
            const newTelegram = thanksButton.cloneNode(true);
            const innerBtn = newTelegram.querySelector('button');
            if (innerBtn) modifyButton(innerBtn, 'telegram');
            
            thanksButton.parentNode.replaceChild(newTelegram, thanksButton);
            newTelegram.dataset.replaced = "true";
        } else if (!thanksButton && !document.getElementById('custom-telegram-btn')) {
            // Если кнопки Спасибо нет вообще, добавляем свою
            createCustomButton('telegram');
        }
    }

    function createCustomButton(type) {
        const id = type === 'download' ? 'custom-download-btn' : 'custom-telegram-btn';
        if (document.getElementById(id)) return;

        const menuRenderer = document.querySelector('ytd-menu-renderer');
        if (!menuRenderer) return;
        
        const baseButton = menuRenderer.querySelector('ytd-button-renderer button') || 
                           menuRenderer.querySelector('yt-button-view-model button');
        if (!baseButton) return;

        const buttonRenderer = baseButton.closest('ytd-button-renderer') || baseButton.closest('yt-button-view-model');
        const newRenderer = buttonRenderer.cloneNode(true);
        newRenderer.id = id;
        const innerBtn = newRenderer.querySelector('button');
        if(innerBtn) modifyButton(innerBtn, type);

        const buttonsContainer = menuRenderer.querySelector('#top-level-buttons-computed');
        if (buttonsContainer) {
            buttonsContainer.appendChild(newRenderer);
        }
    }

    function initButtons() {
        const observer = new MutationObserver(() => {
            if (window.location.pathname.includes('/watch')) {
                processButtons();
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });
        if (window.location.pathname.includes('/watch')) {
            setTimeout(processButtons, 1000); setTimeout(processButtons, 3000);
        }
    }

    // --- ЗАПУСК ---
    initHDLogic();
    initButtons();
    injectSettingsMenu();

})();