Twitter (X) & YouTube Refresh with Scroll Top/Bottom

Adds circular buttons with '顶' (top) and '底' (bottom) text, centered on gradient background, for scrolling to page top/bottom. On Twitter (X), top button scrolls up, shows ring animation, and reliably refreshes timeline by simulating home button click and verifying content update

// ==UserScript==
// @name               Twitter (X) & YouTube Refresh with Scroll Top/Bottom
// @name:zh-CN         Twitter & YouTube v1
// @namespace          https://gist.github.com/4lrick/bedb39b069be0e4c94dc20214137c9f5
// @version            2.58
// @description        Adds circular buttons with '顶' (top) and '底' (bottom) text, centered on gradient background, for scrolling to page top/bottom. On Twitter (X), top button scrolls up, shows ring animation, and reliably refreshes timeline by simulating home button click and verifying content update
// @description:zh-CN  添加圆形按钮,显示“顶”和“底”文字,居中于渐变背景,滚动到页面顶部/底部。Twitter (X) 首页点击“顶”按钮滚动顶部、显示圆环动画并通过模拟主页按钮点击和验证
// @author             jiang
// @match              https://x.com/*
// @match              https://www.youtube.com/*
// @match              https://m.youtube.com/*
// @icon               https://www.google.com/s2/favicons?sz=64&domain=twitter.com
// @grant              GM_getValue
// @grant              GM_setValue
// @grant              GM_registerMenuCommand
// @grant              GM_unregisterMenuCommand
// @license            GPL-3.0-only
// ==/UserScript==

(function() {
    'use strict';

    // Prevent duplicate script execution
    const key = encodeURIComponent('RefreshAndScroll:执行判断');
    if (window[key]) { return; }
    window[key] = true;

    try {
        // Twitter (X) refresh interval configuration
        let refreshInterval = GM_getValue('refreshInterval', 5);
        let menuCommandId = null;

        // Display a loading spinner animation
        function showSpinner() {
            const spinner = document.createElement('div');
            spinner.id = 'refresh-spinner';
            spinner.innerHTML = `
                <div class="neon-ring"></div>
                <div class="neon-ring inner-ring" style="animation-delay: 0.1s;"></div>
                <div class="spark"></div>
                <div class="spark" style="animation-delay: 0.2s; transform: rotate(90deg);"></div>
                <div class="spark" style="animation-delay: 0.4s; transform: rotate(180deg);"></div>
                <div class="spark" style="animation-delay: 0.6s; transform: rotate(270deg);"></div>
            `;
            spinner.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 100px;
                height: 100px;
                display: flex;
                justify-content: center;
                align-items: center;
                z-index: 10000;
            `;
            document.body.appendChild(spinner);
            return spinner;
        }

        // Remove the spinner animation
        function hideSpinner(spinner) {
            if (spinner) spinner.remove();
        }

        // Refresh Twitter (X) timeline
        function refreshTimeline() {
            if (window.location.href.startsWith('https://x.com/home')) {
                // Expanded selectors for Twitter home button
                const refreshButton = document.querySelector(
                    '[href="/home"], [aria-label*="Home"], [data-testid="AppTabBar_Home_Link"], ' +
                    '[role="link"][href="/home"], [aria-label*="Timeline"], [data-testid*="home"], ' +
                    '[aria-label="Home timeline"], a[href="/home"]'
                );
                if (refreshButton) {
                    const spinner = showSpinner();
                    window.scrollTo({ top: 0, behavior: 'smooth' });

                    // Store initial top tweet ID to verify refresh
                    const initialTopTweet = document.querySelector('article[data-testid="tweet"]');
                    const initialTweetId = initialTopTweet ? initialTopTweet.querySelector('a[href*="/status/"]')?.href : null;

                    // Simulate click to refresh timeline
                    refreshButton.click();

                    // Verify content update
                    let attempts = 0;
                    const maxAttempts = 5;
                    const checkInterval = setInterval(() => {
                        const newTopTweet = document.querySelector('article[data-testid="tweet"]');
                        const newTweetId = newTopTweet ? newTopTweet.querySelector('a[href*="/status/"]')?.href : null;

                        if (newTweetId && newTweetId !== initialTweetId || attempts >= maxAttempts) {
                            clearInterval(checkInterval);
                            hideSpinner(spinner);
                        } else {
                            // Retry click if no update
                            refreshButton.click();
                            attempts++;
                        }
                    }, 1000);
                } else {
                    console.log('RefreshAndScroll: Refresh button not found');
                    const spinner = showSpinner();
                    window.scrollTo({ top: 0, behavior: 'smooth' });
                    setTimeout(() => hideSpinner(spinner), 1500);
                }
            }
        }

        // Refresh non-Twitter pages (including YouTube)
        function refreshPage() {
            const spinner = showSpinner();
            window.scrollTo({ top: 0, behavior: 'smooth' });
            const reloadPromise = new Promise((resolve) => {
                window.addEventListener('load', resolve, { once: true });
                window.location.reload();
            });
            reloadPromise.then(() => {
                setTimeout(() => hideSpinner(spinner), 100);
            });
        }

        // YouTube preloading and layout logic
        function customizeYouTubeLayout() {
            if (!window.location.href.startsWith('https://www.youtube.com/') && !window.location.href.startsWith('https://m.youtube.com/')) return;

            // Preloading logic
            const preloadThreshold = window.innerHeight * 2; // Two screen heights
            let isLoading = false;

            const scrollHandler = () => {
                if (isLoading) return;

                const scrollPosition = window.scrollY + window.innerHeight;
                const pageHeight = document.documentElement.scrollHeight;

                if (pageHeight - scrollPosition < preloadThreshold) {
                    isLoading = true;
                    const lastVideo = document.querySelector('ytd-rich-item-renderer:last-of-type:not([is-shorts])') ||
                                     document.querySelector('ytd-video-renderer:last-of-type:not([is-shorts])') ||
                                     document.querySelector('ytd-grid-video-renderer:last-of-type:not([is-shorts])');
                    if (lastVideo) {
                        lastVideo.scrollIntoView({ behavior: 'instant' });
                        window.dispatchEvent(new Event('scroll'));
                        setTimeout(() => window.dispatchEvent(new Event('scroll')), 100);
                        setTimeout(() => window.dispatchEvent(new Event('scroll')), 200);
                        const observer = new MutationObserver(() => {
                            isLoading = false;
                            observer.disconnect();
                        });
                        const target = document.querySelector('#contents') || document.body;
                        observer.observe(target, { childList: true, subtree: true });
                        setTimeout(() => {
                            if (isLoading) {
                                isLoading = false;
                                observer.disconnect();
                            }
                        }, 5000);
                    } else {
                        isLoading = false;
                    }
                }
            };

            let isThrottled = false;
            window.addEventListener('scroll', () => {
                if (!isThrottled) {
                    isThrottled = true;
                    scrollHandler();
                    setTimeout(() => { isThrottled = false; }, 200);
                }
            });

            // Video layout and Shorts removal logic
            const style = document.createElement('style');
            style.textContent = `
                #contents.ytd-rich-grid-renderer {
                    display: grid !important;
                    grid-template-columns: repeat(auto-fill, minmax(50%, 1fr)) !important;
                    gap: 10px !important;
                    padding: 10px !important;
                    box-sizing: border-box !important;
                }
                ytd-rich-item-renderer:not([is-shorts]), ytd-video-renderer:not([is-shorts]), ytd-grid-video-renderer:not([is-shorts]) {
                    height: ${window.innerHeight / 4}px !important;
                    margin: 0 !important;
                    overflow: hidden !important;
                    border-radius: 8px !important;
                    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;
                }
                ytd-rich-item-renderer:not([is-shorts]):nth-child(3n), ytd-video-renderer:not([is-shorts]):nth-child(3n), ytd-grid-video-renderer:not([is-shorts]):nth-child(3n) {
                    grid-column: span 2 !important;
                    width: 100% !important;
                }
                ytd-rich-item-renderer:not([is-shorts]) #thumbnail, ytd-video-renderer:not([is-shorts]) #thumbnail, ytd-grid-video-renderer:not([is-shorts]) #thumbnail {
                    width: 100% !important;
                    height: 100% !important;
                    object-fit: cover !important;
                }
                ytd-rich-item-renderer:not([is-shorts]) #details, ytd-video-renderer:not([is-shorts]) #details, ytd-grid-video-renderer:not([is-shorts]) #details {
                    display: none !important;
                }
                /* Shorts removal */
                ytd-reel-shelf-renderer,
                ytd-rich-shelf-renderer[is-shorts],
                ytd-shorts,
                ytd-reel-item-renderer,
                ytd-rich-item-renderer[is-shorts],
                ytd-video-renderer[is-shorts],
                ytd-grid-video-renderer[is-shorts],
                ytd-guide-entry-renderer:has(a[href*="/shorts"]),
                ytd-mini-guide-entry-renderer:has(a[href*="/shorts"]),
                ytm-pivot-bar-item-renderer:has(.pivot-shorts),
                ytm-pivot-bar-item-renderer[tab-identifier="FEshorts"],
                ytd-guide-entry-renderer:has([title="Shorts"]),
                ytd-mini-guide-entry-renderer:has([title="Shorts"]),
                ytm-rich-item-renderer:has([data-style="SHORTS"]),
                ytm-reel-shelf-renderer,
                ytm-rich-section-renderer:has(ytm-reel-shelf-renderer),
                #chips-wrapper yt-chip-cloud-chip-renderer[chip-style*="STYLE_HOME_FILTER"]:has(a[href*="/shorts"]),
                ytd-rich-section-renderer:has(#rich-shelf-header:contains("Shorts")),
                ytd-item-section-renderer:has([overlay-style="SHORTS"]),
                ytd-browse[page-subtype="shorts"],
                ytd-rich-grid-row:empty,
                #contents.ytd-rich-grid-row:empty {
                    display: none !important;
                }
                /* Fix grid layout after removing Shorts */
                ytd-rich-grid-row, #contents.ytd-rich-grid-row {
                    display: contents !important;
                }
            `;
            document.head.appendChild(style);

            // Apply layout and remove Shorts dynamically
            const applyLayoutAndRemoveShorts = () => {
                // Apply video layout
                const contents = document.querySelector('#contents.ytd-rich-grid-renderer');
                if (contents) {
                    contents.style.display = 'grid';
                    const videos = document.querySelectorAll('ytd-rich-item-renderer:not([is-shorts]), ytd-video-renderer:not([is-shorts]), ytd-grid-video-renderer:not([is-shorts])');
                    videos.forEach((video, index) => {
                        video.style.height = `${window.innerHeight / 4}px`;
                        if ((index + 1) % 3 === 0) {
                            video.style.gridColumn = 'span 2';
                            video.style.width = '100%';
                        } else {
                            video.style.gridColumn = 'auto';
                            video.style.width = 'auto';
                        }
                    });
                }

                // Remove Shorts elements
                const shortsSelectors = [
                    'ytd-reel-shelf-renderer',
                    'ytd-rich-shelf-renderer[is-shorts]',
                    'ytd-shorts',
                    'ytd-reel-item-renderer',
                    'ytd-rich-item-renderer[is-shorts]',
                    'ytd-video-renderer[is-shorts]',
                    'ytd-grid-video-renderer[is-shorts]',
                    'ytd-guide-entry-renderer:has(a[href*="/shorts"])',
                    'ytd-mini-guide-entry-renderer:has(a[href*="/shorts"])',
                    'ytm-pivot-bar-item-renderer:has(.pivot-shorts)',
                    'ytm-pivot-bar-item-renderer[tab-identifier="FEshorts"]',
                    'ytd-guide-entry-renderer:has([title="Shorts"])',
                    'ytd-mini-guide-entry-renderer:has([title="Shorts"])',
                    'ytm-rich-item-renderer:has([data-style="SHORTS"])',
                    'ytm-reel-shelf-renderer',
                    'ytm-rich-section-renderer:has(ytm-reel-shelf-renderer)',
                    '#chips-wrapper yt-chip-cloud-chip-renderer[chip-style*="STYLE_HOME_FILTER"]:has(a[href*="/shorts"])',
                    'ytd-rich-section-renderer:has(#rich-shelf-header:contains("Shorts"))',
                    'ytd-item-section-renderer:has([overlay-style="SHORTS"])',
                    'ytd-browse[page-subtype="shorts"]'
                ];
                const shortsElements = document.querySelectorAll(shortsSelectors.join(','));
                shortsElements.forEach(el => el.remove());

                // Clean up empty grid rows
                const emptyRows = document.querySelectorAll('ytd-rich-grid-row:empty, #contents.ytd-rich-grid-row:empty');
                emptyRows.forEach(row => row.remove());
            };

            // Observe DOM changes to reapply layout and Shorts removal
            const observer = new MutationObserver(() => {
                applyLayoutAndRemoveShorts();
            });
            const target = document.body;
            observer.observe(target, { childList: true, subtree: true });

            // Redirect /shorts/ URLs to /watch?v=
            const redirectShorts = () => {
                if (window.location.href.includes('youtube.com/shorts/')) {
                    const newUrl = window.location.href.replace('/shorts/', '/watch?v=');
                    window.location.replace(newUrl);
                }
            };
            redirectShorts();
            window.addEventListener('popstate', redirectShorts);

            // Initial application
            applyLayoutAndRemoveShorts();
        }

        // Set custom refresh interval for Twitter (X)
        function setCustomInterval() {
            const newInterval = prompt("Enter refresh interval in seconds:", refreshInterval);
            if (newInterval !== null) {
                const parsedInterval = parseInt(newInterval);
                if (!isNaN(parsedInterval) && parsedInterval > 0) {
                    refreshInterval = parsedInterval;
                    GM_setValue('refreshInterval', refreshInterval);
                    updateMenuCommand();
                } else {
                    alert("Please enter a valid positive number.");
                }
            }
        }

        // Update the menu command for refresh interval
        function updateMenuCommand() {
            if (menuCommandId) {
                GM_unregisterMenuCommand(menuCommandId);
            }
            menuCommandId = GM_registerMenuCommand(`Set Refresh Interval (current: ${refreshInterval}s)`, setCustomInterval);
        }

        // Scroll to top or bottom with conditional refresh
        function scrollToPosition(y, isTopButton = false) {
            window.scrollTo({ top: y, behavior: 'smooth' });
            if (y === 0) {
                if (window.location.href.startsWith('https://x.com/home')) {
                    setTimeout(() => refreshTimeline(), 500);
                } else if (isTopButton) {
                    setTimeout(() => refreshPage(), 500);
                }
            }
        }

        // Create a visual click effect
        function createClickEffect(x, y) {
            const effect = document.createElement('div');
            effect.style.cssText = `
                position: fixed;
                left: ${x}px;
                top: ${y}px;
                width: 10px;
                height: 10px;
                background: transparent;
                border: 2px solid #00ff88;
                border-radius: 50%;
                pointer-events: none;
                z-index: 10000;
                animation: shockwave 0.5s ease-out forwards;
                box-shadow: 0 0 10px #00ccff, 0 0 20px #00ff88;
            `;
            document.body.appendChild(effect);
            setTimeout(() => effect.remove(), 500);
        }

        // Inject CSS styles for buttons and animations
        const style = document.createElement('style');
        style.textContent = `
            @keyframes pulse {
                0% { transform: scale(1); }
                50% { transform: scale(1.1); }
                100% { transform: scale(1); }
            }
            @keyframes shockwave {
                0% {
                    transform: scale(1);
                    opacity: 1;
                    border-width: 2px;
                }
                100% {
                    transform: scale(10);
                    opacity: 0;
                    border-width: 0;
                }
            }
            @keyframes neonPulse {
                0% {
                    transform: scale(1) rotate(0deg);
                    opacity: 1;
                    box-shadow: 0 0 10px #00ff88, 0 0 20px #00ccff;
                }
                50% {
                    transform: scale(1.2) rotate(180deg);
                    opacity: 0.8;
                    box-shadow: 0 0 20px #00ff88, 0 0 40px #00ccff;
                }
                100% {
                    transform: scale(1) rotate(360deg);
                    opacity: 1;
                    box-shadow: 0 0 10px #00ff88, 0 0 20px #00ccff;
                }
            }
            @keyframes sparkBurst {
                0% {
                    transform: translate(0, 0) scale(1);
                    opacity: 1;
                }
                100% {
                    transform: translate(20px, 20px) scale(0);
                    opacity: 0;
                }
            }
            .neon-ring {
                position: absolute;
                width: 80px;
                height: 80px;
                border: 4px solid transparent;
                border-top-color: #00ff88;
                border-right-color: #00ccff;
                border-radius: 50%;
                animation: neonPulse 1.5s linear infinite;
            }
            .inner-ring {
                width: 60px;
                height: 60px;
                border-top-color: #00ccff;
                border-right-color: #00ff88;
                animation-direction: reverse;
            }
            .spark {
                position: absolute;
                width: 8px;
                height: 8px;
                background: #ffffff;
                border-radius: 50%;
                box-shadow: 0 0 10px #00ff88, 0 0 15px #00ccff;
                animation: sparkBurst 1.5s ease-out infinite;
            }
            #sky-scrolltop, #sky-scrolltbtm {
                font-family: 'Microsoft YaHei', 'Arial', sans-serif !important;
                font-style: normal;
                font-weight: 700;
                font-size: 16px;
                line-height: 48px !important;
                text-align: center !important;
                background: linear-gradient(135deg, #00ff88, #00ccff) !important;
                border-radius: 50% !important;
                width: 48px !important;
                height: 48px !important;
                color: #ffffff !important;
                cursor: pointer;
                position: fixed;
                z-index: 999999;
                user-select: none;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
                transition: transform 0.2s ease, box-shadow 0.2s ease;
                animation: pulse 2s infinite;
                visibility: visible !important;
                display: flex !important;
                justify-content: center !important;
                align-items: center !important;
            }
            #sky-scrolltop:hover, #sky-scrolltbtm:hover {
                transform: scale(1.15);
                box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
            }
            #sky-scrolltop:active, #sky-scrolltbtm:active {
                transform: scale(0.95);
            }
            #sky-scrolltop.editing, #sky-scrolltbtm.editing {
                background: linear-gradient(135deg, #ff4444, #ff8888) !important;
                animation: none;
            }
        `;
        document.head.appendChild(style);

        // Create scroll buttons for top and bottom navigation
        const scrollTop = document.createElement('div');
        scrollTop.id = 'sky-scrolltop';
        scrollTop.innerText = '顶';
        scrollTop.setAttribute('data-text', '顶');
        scrollTop.style.visibility = 'visible';
        document.body.appendChild(scrollTop);
        console.log('RefreshAndScroll: Created top button with text:', scrollTop.innerText);

        const scrollBottom = document.createElement('div');
        scrollBottom.id = 'sky-scrolltbtm';
        scrollBottom.innerText = '底';
        scrollBottom.setAttribute('data-text', '底');
        scrollBottom.style.visibility = 'visible';
        document.body.appendChild(scrollBottom);
        console.log('RefreshAndScroll: Created bottom button with text:', scrollBottom.innerText);

        // Periodically check and restore button text
        setInterval(() => {
            const topButton = document.querySelector('#sky-scrolltop');
            const bottomButton = document.querySelector('#sky-scrolltbtm');
            if (topButton && topButton.innerText !== '顶') {
                console.error('RefreshAndScroll: Top button text missing, restoring...');
                topButton.innerText = topButton.getAttribute('data-text') || '顶';
            }
            if (bottomButton && bottomButton.innerText !== '底') {
                console.error('RefreshAndScroll: Bottom button text missing, restoring...');
                bottomButton.innerText = bottomButton.getAttribute('data-text') || '底';
            }
        }, 1000);

        // Initialize button positions
        let positions = GM_getValue('buttonPositions', { left: '20px', topBottom: '20%', bottomBottom: '12%' });
        scrollTop.style.left = positions.left;
        scrollTop.style.bottom = positions.topBottom;
        scrollBottom.style.left = positions.left;
        scrollBottom.style.bottom = positions.bottomBottom;

        // Position editing logic
        let isEditing = false;
        let startX, startY, initialLeft, initialBottomTop;
        const fixedSpacing = 60;

        // Start editing button positions on long press
        function startEditing(e) {
            e.preventDefault();
            isEditing = true;
            scrollTop.classList.add('editing');
            scrollBottom.classList.add('editing');
            startX = e.clientX || (e.touches && e.touches[0].clientX);
            startY = e.clientY || (e.touches && e.touches[0].clientY);
            initialLeft = parseFloat(scrollTop.style.left) || 20;
            initialBottomTop = parseFloat(scrollTop.style.bottom) || (window.innerHeight * 0.20);
            document.addEventListener('contextmenu', preventDefault, { capture: true });
            document.addEventListener('touchstart', preventDefault, { capture: true, passive: false });
        }

        // Move buttons during editing mode
        function moveButtons(e) {
            if (!isEditing) return;
            e.preventDefault();
            const clientX = e.clientX || (e.touches && e.touches[0].clientX);
            const clientY = e.clientY || (e.touches && e.touches[0].clientY);
            if (!clientX || !clientY) return;

            const deltaX = clientX - startX;
            const deltaY = startY - clientY;

            const buttonWidth = 48;
            const buttonHeight = 48;
            let newLeft = initialLeft + deltaX;
            let newBottomTop = initialBottomTop + deltaY;
            let newBottomBtm = newBottomTop - fixedSpacing;

            newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - buttonWidth));
            newBottomTop = Math.max(fixedSpacing, Math.min(newBottomTop, window.innerHeight - buttonHeight));
            newBottomBtm = newBottomTop - fixedSpacing;

            if (newBottomBtm >= 0) {
                scrollTop.style.left = `${newLeft}px`;
                scrollTop.style.bottom = `${newBottomTop}px`;
                scrollBottom.style.left = `${newLeft}px`;
                scrollBottom.style.bottom = `${newBottomBtm}px`;
            }
        }

        // Stop editing and save positions
        function stopEditing(e) {
            if (!isEditing) return;
            e.preventDefault();
            isEditing = false;
            scrollTop.classList.remove('editing');
            scrollBottom.classList.remove('editing');
            positions = {
                left: scrollTop.style.left,
                topBottom: scrollTop.style.bottom,
                bottomBottom: scrollBottom.style.bottom
            };
            GM_setValue('buttonPositions', positions);
            document.removeEventListener('contextmenu', preventDefault, { capture: true });
            document.removeEventListener('touchstart', preventDefault, { capture: true });
        }

        // Prevent default browser actions during editing
        function preventDefault(e) {
            e.preventDefault();
            e.stopPropagation();
        }

        // Long-press detection for editing mode
        let longPressTimer;
        const longPressDuration = 300;

        function handleLongPressStart(e) {
            clearTimeout(longPressTimer);
            longPressTimer = setTimeout(() => startEditing(e), longPressDuration);
        }

        function handleLongPressCancel() {
            clearTimeout(longPressTimer);
        }

        // Attach event listeners to buttons
        scrollTop.addEventListener('mousedown', handleLongPressStart);
        scrollTop.addEventListener('touchstart', handleLongPressStart, { passive: false });
        scrollTop.addEventListener('mouseup', handleLongPressCancel);
        scrollTop.addEventListener('mouseleave', handleLongPressCancel);
        scrollTop.addEventListener('touchend', handleLongPressCancel);
        scrollTop.addEventListener('click', (e) => {
            if (!isEditing) {
                const rect = scrollTop.getBoundingClientRect();
                createClickEffect(rect.left + rect.width / 2, rect.top + rect.height / 2);
                scrollToPosition(0, true);
            }
        });

        scrollBottom.addEventListener('mousedown', handleLongPressStart);
        scrollBottom.addEventListener('touchstart', handleLongPressStart, { passive: false });
        scrollBottom.addEventListener('mouseup', handleLongPressCancel);
        scrollBottom.addEventListener('mouseleave', handleLongPressCancel);
        scrollBottom.addEventListener('touchend', handleLongPressCancel);
        scrollBottom.addEventListener('click', (e) => {
            if (!isEditing) {
                const rect = scrollBottom.getBoundingClientRect();
                createClickEffect(rect.left + rect.width / 2, rect.top + rect.height / 2);
                scrollToPosition(document.body.scrollHeight);
            }
        });

        // Global event listeners for button movement
        document.addEventListener('mousemove', moveButtons);
        document.addEventListener('touchmove', moveButtons, { passive: false });
        document.addEventListener('mouseup', stopEditing);
        document.addEventListener('touchend', stopEditing);

        // Initialize Twitter (X) menu command
        if (window.location.href.startsWith('https://x.com/')) {
            updateMenuCommand();
        }

        // Initialize YouTube customizations
        customizeYouTubeLayout();
    } catch (err) {
        console.log('RefreshAndScroll:', err);
    }
})();