• úvod
  • témata
  • události
  • tržiště
  • diskuze
  • nástěnka
  • přihlásit
    registrace
    ztracené heslo?
    TOMTampermonkey 🐒 - máte užitečný skript? a mohli bychom ho vidět?
    TOM
    TOM --- ---
    pauzne/pustí video na všech tabech/stránkách prohlížeče, kde je skript aktivní
    asterisk (*://*/*) případně změňte na youtube apod.
    hodí se např. pokud potřebujete dabing z nekvalitního videa a video obraz z jiného (kombinace youtube + netflix)

    // ==UserScript==
    // @name Pause/Play an all tabs
    // @namespace http://tampermonkey.net/
    // @version 1.0
    // @description Pause/play all videos across all tabs with Ctrl+Shift+Space
    // @match *://*/*
    // @grant GM_setValue
    // @grant GM_getValue
    // @grant GM_addValueChangeListener
    // @run-at document-idle
    // ==/UserScript==
    
    (function() {
    'use strict';
    
    // ============ CONFIGURATION ============
    const CONFIG = {
    debug: true, // Console logging
    storageKey: 'globalVideoToggle'
    };
    
    const log = (...args) => CONFIG.debug && console.log('[VideoToggle]', ...args);
    
    // ============ VIDEO CONTROL ============
    function toggleVideos(action) {
    const videos = document.querySelectorAll('video');
    let affected = 0;
    
    videos.forEach(video => {
    try {
    if (action === 'pause') {
    if (!video.paused) {
    video.pause();
    affected++;
    }
    } else {
    if (video.paused) {
    video.play().catch(() => {}); // Ignore autoplay restrictions
    affected++;
    }
    }
    } catch (e) {
    log('Error controlling video:', e);
    }
    });
    
    log(`${action.toUpperCase()}: ${affected}/${videos.length} videos`);
    }
    
    // ============ KEYBOARD SHORTCUT ============
    document.addEventListener('keydown', (e) => {
    // Ctrl+Shift+Space
    if (e.ctrlKey && e.shiftKey && e.code === 'Space') {
    e.preventDefault();
    e.stopPropagation();
    
    // Toggle based on previous state
    const current = GM_getValue(CONFIG.storageKey, { action: 'play' });
    const newAction = current.action === 'pause' ? 'play' : 'pause';
    
    log(`Shortcut triggered -> ${newAction}`);
    
    // Broadcast to all tabs (including this one via the listener)
    GM_setValue(CONFIG.storageKey, {
    action: newAction,
    timestamp: Date.now() // Ensures value always changes
    });
    
    // Apply locally (listener may not fire for local changes in some versions)
    toggleVideos(newAction);
    }
    }, true); // Capture phase - catches event before websites can intercept
    
    // ============ CROSS-TAB LISTENER ============
    GM_addValueChangeListener(CONFIG.storageKey, (name, oldValue, newValue, remote) => {
    if (remote) { // Only react to changes from OTHER tabs
    log(`Remote signal received -> ${newValue.action}`);
    toggleVideos(newValue.action);
    }
    });
    
    // ============ INIT ============
    log('Loaded. Press Ctrl+Shift+Space to pause/play all videos across tabs.');
    })();
    TOM
    TOM --- ---
    brute force scraper titulků ze streamu
    běží minimálně na stránce arte.tv (konkrétní tip zde), jinde jsem to nepotřeboval/netestoval
    skript nemá GUI, přehrávané titulky se stáhnou po skončení videa automaticky do nastavené dwl složky prohlížeče

    // ==UserScript==
    // @name         Arte.tv Auto Subtitle Scraper
    // @namespace    http://tampermonkey.net/
    // @version      3.0
    // @description  Automatically scrape and save subtitles on tab close/navigation
    // @match        https://www.arte.tv/*
    // @match        https://*.arte.tv/*
    // @grant        none
    // @run-at       document-idle
    // ==/UserScript==
    (function() {
        'use strict';
        // ============ CONFIGURATION ============
        const CONFIG = {
            // Console logging
            debug: true,
            // Start scraping automatically
            autoStart: true,
            // Auto-save when leaving page
            saveOnExit: true,
            // Auto-save on URL/navigation change
            saveOnUrlChange: true,
            // Minimum subtitles before auto-saving
            minSubtitles: 10,
            // Manual save shortcut
            keyboardShortcut: 'ctrl+shift+s',
            // Filename prefix
            filenamePrefix: 'arte_subtitles_',
        };
        // Note: Download folder is controlled by browser settings, not this script.
        // Files will save to your browser's default download location.
        // ============ STATE ============
        const log = (...args) => CONFIG.debug && console.log('[SubScraper]', ...args);
        let capturedSubs = [];
        let isScanning = false;
        let hasAutoSaved = false;
        // ============ FILTERS ============
        const UI_GARBAGE = [
            'Pause', 'Play', 'Mute', 'Unmute',
            'Forward 10 seconds', 'Back 10 seconds',
            'Rewind 10 seconds', 'Skip 10 seconds',
            'Settings', 'Fullscreen', 'Exit fullscreen',
            'Subtitles', 'Audio', 'Quality', 'Captions',
            'Volume', 'Speed', 'Next', 'Previous',
            'Share', 'Download', 'More', 'Less'
        ];
        function isUIGarbage(text) {
            if (!text || text.length < 2) return true;
            // Percentages like "1.36%"
            if (/^\d+\.?\d*%$/.test(text)) return true;
            // Timestamps like "12:34" or "1:23:45"
            if (/^\d{1,2}:\d{2}(:\d{2})?$/.test(text)) return true;
            // Known UI text
            if (UI_GARBAGE.some(ui => text.includes(ui))) return true;
            // Very short or pure numbers
            if (text.length < 3 || /^\d+$/.test(text)) return true;
            return false;
        }
        // ============ SCRAPING ============
        function startScraping() {
            if (isScanning) {
                log('Already scanning');
                return;
            }
            isScanning = true;
            log('Auto-scraping started');
            const observer = new MutationObserver((mutations) => {
                if (!isScanning) return;
                mutations.forEach(mutation => {
                    mutation.addedNodes.forEach(node => {
                        let text = '';
                        if (node.nodeType === Node.TEXT_NODE) {
                            text = node.textContent.trim();
                        } else if (node.nodeType === Node.ELEMENT_NODE) {
                            text = node.textContent.trim();
                        }
                        if (text && !isUIGarbage(text)) {
                            captureSubtitle(text);
                        }
                    });
                });
            });
            // Monitor subtitle areas
            const targets = document.querySelectorAll('.avp, video, [class*="player"], [class*="subtitle"], [class*="caption"]');
            targets.forEach(target => {
                observer.observe(target, {
                    childList: true,
                    subtree: true,
                    characterData: true
                });
            });
            log(`Monitoring ${targets.length} elements`);
        }
        function captureSubtitle(text) {
            // Avoid duplicates
            if (capturedSubs.some(s => s.text === text)) return;
            const video = document.querySelector('video');
            const timestamp = video ? video.currentTime : capturedSubs.length * 2;
            capturedSubs.push({
                start: timestamp,
                end: timestamp + 2, // Default 2 second duration
                text: text
            });
            log(`[${capturedSubs.length}] ${text.substring(0, 50)}`);
        }
        // ============ OVERLAP CORRECTION ============
        function fixOverlaps(subs) {
            // Sort by start time
            subs.sort((a, b) => a.start - b.start);
            // Fix overlaps: if current subtitle ends after next starts,
            // adjust current end to match next start
            for (let i = 0; i < subs.length - 1; i++) {
                if (subs[i].end > subs[i + 1].start) {
                    log(`Overlap fixed: [${i}] ${formatTime(subs[i].end)} -> ${formatTime(subs[i + 1].start)}`);
                    subs[i].end = subs[i + 1].start;
                }
            }
            return subs;
        }
        // ============ DEDUPLICATION ============
        function removeDuplicates(subs) {
            const unique = [];
            const seen = new Set();
            subs.forEach(sub => {
                const key = `${sub.start.toFixed(1)}_${sub.text}`;
                if (!seen.has(key)) {
                    seen.add(key);
                    unique.push(sub);
                }
            });
            return unique;
        }
        // ============ SRT GENERATION ============
        function generateSRT() {
            if (capturedSubs.length === 0) {
                log('No subtitles to save');
                return null;
            }
            // Process subtitles
            let processed = removeDuplicates(capturedSubs);
            processed = fixOverlaps(processed);
            log(`Generating SRT: ${capturedSubs.length} raw -> ${processed.length} final`);
            // Convert to SRT format
            let srt = '';
            processed.forEach((sub, idx) => {
                srt += `${idx + 1}\n`;
                srt += `${formatTime(sub.start)} --> ${formatTime(sub.end)}\n`;
                srt += `${sub.text}\n\n`;
            });
            return srt;
        }
        function formatTime(seconds) {
            const h = Math.floor(seconds / 3600);
            const m = Math.floor((seconds % 3600) / 60);
            const s = Math.floor(seconds % 60);
            const ms = Math.floor((seconds % 1) * 1000);
            return `${pad(h)}:${pad(m)}:${pad(s)},${pad(ms, 3)}`;
        }
        function pad(num, size = 2) {
            let s = num + '';
            while (s.length < size) s = '0' + s;
            return s;
        }
        // ============ SAVE ============
        function saveSubtitles(reason = 'manual') {
            if (capturedSubs.length < CONFIG.minSubtitles) {
                log(`Not saving: only ${capturedSubs.length} subtitles (min: ${CONFIG.minSubtitles})`);
                return false;
            }
            const srt = generateSRT();
            if (!srt) return false;
            const filename = `${CONFIG.filenamePrefix}${Date.now()}.srt`;
            try {
                const blob = new Blob([srt], { type: 'text/plain;charset=utf-8' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = filename;
                // For auto-save on exit, we need to click synchronously
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                // Clean up after a delay
                setTimeout(() => URL.revokeObjectURL(url), 100);
                log(`✓ Saved: ${filename} (${capturedSubs.length} lines, reason: ${reason})`);
                return true;
            } catch (e) {
                console.error('[SubScraper] Save failed:', e);
                return false;
            }
        }
        // ============ AUTO-SAVE TRIGGERS ============
        // Tab close / page refresh / browser close
        window.addEventListener('beforeunload', (e) => {
            if (CONFIG.saveOnExit && !hasAutoSaved) {
                hasAutoSaved = true;
                saveSubtitles('page-exit');
            }
        });
        // URL change (SPA navigation)
        if (CONFIG.saveOnUrlChange) {
            let currentUrl = window.location.href;
            setInterval(() => {
                if (window.location.href !== currentUrl) {
                    log('URL changed detected');
                    currentUrl = window.location.href;
                    if (!hasAutoSaved) {
                        hasAutoSaved = true;
                        saveSubtitles('url-change');
                    }
                }
            }, 1000);
        }
        // ============ KEYBOARD SHORTCUT ============
        document.addEventListener('keydown', (e) => {
            // Ctrl+Shift+S (or Cmd+Shift+S on Mac)
            if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === 's') {
                e.preventDefault();
                log('Manual save triggered');
                saveSubtitles('keyboard');
            }
        });
        // ============ INITIALIZATION ============
        function init() {
            if (!document.body) {
                setTimeout(init, 100);
                return;
            }
            log('Arte.tv Auto Subtitle Scraper v3.0');
            log(`Config: autoStart=${CONFIG.autoStart}, saveOnExit=${CONFIG.saveOnExit}`);
            log(`Keyboard shortcut: ${CONFIG.keyboardShortcut.toUpperCase()} for manual save`);
            if (CONFIG.autoStart) {
                // Wait for video player to load
                setTimeout(() => {
                    const video = document.querySelector('video');
                    if (video) {
                        log('Video detected, starting scraper');
                        startScraping();
                    } else {
                        log('No video found, waiting...');
                        setTimeout(init, 2000);
                    }
                }, 2000);
            }
        }
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', init);
        } else {
            init();
        }
        // ============ DEBUG INFO ============
        // Expose stats for console inspection
        window.subScraperStats = () => {
            return {
                captured: capturedSubs.length,
                autoSaved: hasAutoSaved,
                config: CONFIG
            };
        };
        log('Tip: Run window.subScraperStats() in console to see current status');
    })();
    TOM
    TOM --- ---
    POSEIDON: ¯\_(°-°)_/¯ napsal jsem podle aktuální situace, nevím jestli/kdy/proč se může gcp zobrazit
    tvoje verze bude tím pádem určitě spolehlivější
    POSEIDON
    POSEIDON --- ---
    TOM: /gcp/ uz neni potreba?
    // ==UserScript==
    // @name         AliExpress Redirect Script
    // @namespace    http://tampermonkey.net/
    // @version      1.0
    // @description  Redirect from AliExpress /gcp/ URLs to /item/ URLs using productIds param
    // @author       Poseidon
    // @match        https://www.aliexpress.com/*
    // @grant        none
    // ==/UserScript==
    
    (function() {
        'use strict';
    
        // Get current URL
        const url = new URL(window.location.href);
    
        if (url.pathname.includes("/gcp/") || url.pathname.includes("/ssr/")) {
            if (url.searchParams.has("productIds")){
                // Get the value of productIds param
                const productIds = url.searchParams.get("productIds");
                // Split by colon and take the first ID
                const productId = productIds.split(':')[0];
    
                // Create the new URL
                const newUrl = `https://www.aliexpress.com/item/${productId}.html`;
    
                // Redirect to the new URL
                window.location.replace(newUrl);
            }
        }
    })();
    TOM
    TOM --- ---
    Pokud vás obtěžují bundle deals na Aliexpressu, tak tohle je vypne (respektive vezme první ProductID z toho bundle, a přepíše URL adresu)
    // ==UserScript==
    // @name         AliExpress Bundle to Single Item
    // @namespace    http://tampermonkey.net/
    // @version      1.0
    // @description  Redirect bundle deals to first item
    // @match        https://www.aliexpress.com/*
    // @match        https://aliexpress.com/*
    // @grant        none
    // @run-at       document-start
    // ==/UserScript==
    
    (function() {
        'use strict';
        const url = window.location.href;
        // Check for bundle deal URL
        if (url.includes('aliexpress.com/ssr/')) {
            const urlParams = new URLSearchParams(window.location.search);
            const productIds = urlParams.get('productIds');
            if (productIds) {
                // Extract first product ID (digits before colon/separator)
                const match = productIds.match(/^(\d+)/);
                if (match) {
                    window.location.replace(`https://www.aliexpress.com/item/${match[1]}.html`);
                }
            }
        }
    })();
    SHASHA_KRASTY
    SHASHA_KRASTY --- ---
    pro ty co pouzivají vymeny nesmyslu z inventare ve sluzbe Steam, tak zde jeden, skoro bych rekl, nepostradatelny:
    https://www.steamtradematcher.com/res/userscript/stm.user.js

    TOM
    TOM --- ---
    jinak pro mazání objektů na stránkách používám tohle
    Click To Remove Element - blade.sk
    https://blade.sk/projects/ctre/
    primitivním klikáním na věci, co nechcete nikdy (zaškrtávátkem "Remember by default") nechcete vidět (bloky s reklamou apod.)
    ZORBEN
    ZORBEN --- ---
    XARGH: až budu mít čas, dám tomu šanci
    XARGH
    XARGH --- ---
    ZORBEN: me nakonec pomohl ten redirector, co mi TOM doporucil. nastav to dle SS a budes to mit taky
    .

    ZORBEN
    ZORBEN --- ---
    XARGH: brave (v angličtině) používám jako defaultni prohlížeč, tampermonkey jsem díky tomuhle auditku vyzkoušel poprvý, ale v brave mi to právě nefungovalo... takže jsem byl rad za tvůj první příspěvek a doufal jsem že se dozvím proč to nejde... xcancel jsem znal, jen to přepisovat ručně nechci, víceméně na X koukám jen na odkazy ze 3. světový... zkoušel jsem i nějaký easy debugy abych v konzoli viděl jestli se skript vůbec spustil nebo ne a po pár minutách jsem to vzdal s tím, že brave sám dost věcí blokuje, tak tohle prostě nemá šanci :)))
    ale když se to tady podaří vyřešit, budu rád
    TOM
    TOM --- ---
    XARGH: chápu
    ideální by bylo zkusit jiný skript - chceš něco vytvořit přímo na míru?
    anebo pro tuhle konkrétní potřebu zkus jiný addon ;)
    Redirector - Chrome Web Store
    https://chromewebstore.google.com/detail/jegbdohdgebjljoljfeinojeobdabpjo
    TOM
    TOM --- ---
    XARGH: vytvořil jsem si teď kvůli tomu znovu účet, a oproti xcancel nevidím rozdíl
    komentáře jsou replies ¯\_(°_°)_/¯
    XARGH
    XARGH --- ---
    TOM: odinstalovano. skusil jsem to same v brave a take nic. prah IT frustrace prekrocen :-/

    π (final scene)
    https://www.youtube.com/watch?v=1U1PM-p3860
    XARGH
    XARGH --- ---
    TOM: na rucne prepsanem xcancel nevidim komentare, ale vidim Replies
    TOM
    TOM --- ---
    XARGH: co jiný prohlížeč? MSEdge třeba?
    XARGH
    XARGH --- ---
    TOM: jo, presne to jsem chtel mit
    TOM
    TOM --- ---
    XARGH: no za mě osobně je hlavní smysl v tom, že vidíš komentáře i bez přihlášení ;)
    protože já jsem tam svůj účet smazal
    javascript, cookies apod. je jenom extra bonus navíc
    XARGH
    XARGH --- ---
    TOM: nemelo by bejt spousteni userscriptu detekovano nekde napr F12 -> console? me prijde, ze se u me proste nespusti
    XARGH
    XARGH --- ---
    TOM: ASI = prehozeny slovosled, mam na mysli, ze to nedela to, co bych potreboval.
    ad About - takze hlavni smysl je ochrana proti trackovani, OK
    TOM
    TOM --- ---
    XARGH: vo fous 😅
    (nemělo by to vadit, u mě skript pořád funguje i tak)
    // ==UserScript==
    // @name         Cancel_X_Robust
    // @namespace    http://tampermonkey.net/
    // @version      0.3
    // @description  Redirect x.com to xcancel.com with fallback methods
    // @author       You
    // @match        https://x.com/*
    // @match        https://www.x.com/*
    // @run-at       document-start
    // @grant        none
    // ==/UserScript==
    
    (function() {
        'use strict';
    
        const currentUrl = window.location.href;
        const newUrl = currentUrl.replace(/^https?:\/\/(www\.)?x\.com/, 'https://xcancel.com');
    
        if (newUrl === currentUrl) return;
    
        // Multiple redirect methods in order of preference
    const redirectMethods = [
        () => window.location.replace(newUrl),
        () => window.location.assign(newUrl),
        () => { window.location.href = newUrl; },
        () => { window.top.location.href = newUrl; }
    ];
    
        let redirectAttempted = false;
    
        for (const method of redirectMethods) {
            try {
                method();
                redirectAttempted = true;
                break;
            } catch (error) {
                console.warn('Cancel_X: Method failed:', error.message);
            }
        }
    
        // Last resort: show manual link if all methods fail
        if (!redirectAttempted) {
            setTimeout(() => {
                if (window.location.href === currentUrl) {
                    const link = document.createElement('div');
                    link.innerHTML = `
                        <div style="position:fixed;top:10px;left:10px;z-index:99999;background:red;color:white;padding:10px;border-radius:5px;">
                            <strong>Auto-redirect failed!</strong><br>
                            <a href="${newUrl}" style="color:yellow;text-decoration:underline;">Click here for xcancel.com</a>
                        </div>
                    `;
                    document.body?.appendChild(link) || document.documentElement.appendChild(link);
                }
            }, 500);
        }
    })();
    TOM
    TOM --- ---
    XARGH: ASI?
    XCancel
    https://xcancel.com/about
    komenty tam AFAIK jsou - tvoje šipka ukazuje na ikonku chat bubliny s číslem 64, to je ale na původním twitteru tlačítko pro zadání odpovědi = ne jako rozbalení samotných odpovědí
    ty jsou přímo pod příspěvkem, není potřeba nic rozklikávat, stačí scrollovat na té stránce dolů
    XARGH
    XARGH --- ---
    +

    XARGH
    XARGH --- ---
    TOM: rucni prepsani funguje, ale zjistuju, ze ten ASI skript neni pro me, protoze jsem chtel videt komentare lidi k prispevku a ty tam nejsou (viz SS) - co jeste dalsiho prinasi xcancel?
    nebeha to ani s globalne vypnutym uBlockem.

    TOM
    TOM --- ---
    XARGH: mám dokonce starší verzi (6.5.3206.50 (Stable channel) (64-bit) )
    problém může být právě v uBlock kvůli window.location.replace()
    zkus tohle (opět nemám jak nasimulovat selhání, mělo by ti to dát vědět)
    // ==UserScript==
    // @name         Cancel_X_Robust
    // @namespace    http://tampermonkey.net/
    // @version      0.3
    // @description  Redirect x.com to xcancel.com with fallback methods
    // @author       You
    // @match        https://x.com/*
    // @match        https://www.x.com/*
    // @run-at       document-start
    // @grant        none
    // ==/UserScript==
    
    (function() {
        'use strict';
        
        const currentUrl = window.location.href;
        const newUrl = currentUrl.replace(/^https?:\/\/(www\.)?x\.com/, 'https://xcancel.com');
        
        if (newUrl === currentUrl) return;
        
        // Multiple redirect methods in order of preference
        const redirectMethods = [
            () => window.location.replace(newUrl),
            () => window.location.assign(newUrl),
            () => window.location.href = newUrl,
            () => window.top.location.href = newUrl
        ];
        
        let redirectAttempted = false;
        
        for (const method of redirectMethods) {
            try {
                method();
                redirectAttempted = true;
                break;
            } catch (error) {
                console.warn('Cancel_X: Method failed:', error.message);
            }
        }
        
        // Last resort: show manual link if all methods fail
        if (!redirectAttempted) {
            setTimeout(() => {
                if (window.location.href === currentUrl) {
                    const link = document.createElement('div');
                    link.innerHTML = `
                        <div style="position:fixed;top:10px;left:10px;z-index:99999;background:red;color:white;padding:10px;border-radius:5px;">
                            <strong>Auto-redirect failed!</strong><br>
                            <a href="${newUrl}" style="color:yellow;text-decoration:underline;">Click here for xcancel.com</a>
                        </div>
                    `;
                    document.body?.appendChild(link) || document.documentElement.appendChild(link);
                }
            }, 500);
        }
    })();

    BTW manuální přepsání URL z x na xcancel ti funguje? xcancel má automatické ověřování uživatele
    TOM
    TOM --- ---
    DRAGON: naopak! návodky pro začátečníky jsou od nejlepší od nováčků!
    pro mě je těžké pochopit, co na tom kdo nechápe ;)
    (okay, mám všehovšudy jenom 4 skripty, ale pořád nevím, co bych měl jako radit, když je všechno tak jasné ;))
    DRAGON
    DRAGON --- ---
    TOM: já se můžu těžko hlásit, když ti píšu, že o tom vim kulový :))
    XARGH
    XARGH --- ---
    TOM: sorry, ze jsem to smazl, bal jsem se, ze budu troubleshootovat veci, kterym nerozumim :))

    mam vivaldi v cestine s furou extensions tipu uBlock origin a dalsi. viz SS

    sla by udelat debugovaci verze?
    jaky jiny skript vyskouset?

    TOM
    TOM --- ---
    DRAGON: XARGH se smazal, takže to asi rozchodil sám
    nicméně návod už je pryč, takže návrh nového vhodného návodu tímto nechávám na případných dobrovolnících (hlásíš se? ;))
    TOM
    TOM --- ---
    TOM: přepis do nyx formátu pro kód (viz záhlaví)
    // ==UserScript==
    // @namespace https://www.github.com/Cat7373/
    // @name Remove web limits
    // @description Pass to kill most of the site, you can lift the restrictions prohibited to copy, cut, select the text, right-click menu.
    // @homepageURL https://cat7373.github.io/remove-web-limits/
    // @supportURL https://github.com/Cat7373/remove-web-limits/issues/
    // @author Cat73 + Claude.ai
    // @version 1.4
    // @license LGPLv3
    // @compatible chrome Chrome_46.0.2490.86 + TamperMonkey + Script_1.3 tested
    // @compatible firefox Firefox_42.0 + GreaseMonkey + Script_1.2.1 tested
    // @compatible opera Opera_33.0.1990.115 + TamperMonkey + Script_1.1.3 tested
    // @compatible safari Not tested
    // @match *://*/*
    // @grant none
    // @run-at document-start
    // ==/UserScript==
    
    (function() {
    'use strict';
    
    // ========== USER CONFIGURATION ==========
    // Set to 0 to disable DOM clearing loop completely
    // Set to positive number (milliseconds) to enable periodic clearing
    // Example: 60000 = 1 minute, 30000 = 30 seconds, 0 = disabled
    const DOM_CLEAR_INTERVAL = 0; // Default: disabled for performance
    
    // Delay before first DOM clear after page load (milliseconds)
    const INITIAL_CLEAR_DELAY = 2500;
    
    // Enable/disable aggressive mode (processes all elements vs only interactive ones)
    const AGGRESSIVE_MODE = false;
    
    // Enable console debugging messages
    const DEBUG_MODE = false;
    // ========================================
    
    // Domain rules list
    var rules = {
    black_rule: {
    name: "black",
    hook_eventNames: "",
    unhook_eventNames: ""
    },
    default_rule: {
    name: "default",
    hook_eventNames: "contextmenu|select|selectstart|copy|cut|dragstart",
    unhook_eventNames: "mousedown|mouseup|keydown|keyup",
    dom0: true,
    hook_addEventListener: true,
    hook_preventDefault: true,
    hook_set_returnValue: true,
    add_css: true
    },
    // Lighter rule for sites that need some functionality
    light_rule: {
    name: "light",
    hook_eventNames: "copy|cut|selectstart",
    unhook_eventNames: "",
    dom0: false,
    hook_addEventListener: true,
    hook_preventDefault: false,
    hook_set_returnValue: false,
    add_css: true
    }
    };
    
    // Domain lists
    var lists = {
    // Blacklist - sites to completely skip
    black_list: [
    /.*\.youtube\.com.*/,
    /.*\.wikipedia\.org.*/,
    /mail\.qq\.com.*/,
    /translate\.google\..*/,
    /docs\.google\.com.*/,
    /drive\.google\.com.*/,
    /.*\.github\.com.*/,
    /.*\.gmail\.com.*/,
    /.*\.outlook\.com.*/,
    /.*\.office\.com.*/
    ],
    // Light touch list - sites that need minimal intervention
    light_list: [
    /.*\.medium\.com.*/,
    /.*\.quora\.com.*/,
    /.*\.stackoverflow\.com.*/,
    /.*\.reddit\.com.*/
    ]
    };
    
    // Event lists to process
    var hook_eventNames, unhook_eventNames, eventNames;
    // Storage name for namespacing
    var storageName = getRandStr('qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM', parseInt(Math.random() * 12 + 8));
    // Store hooked functions
    var EventTarget_addEventListener = EventTarget.prototype.addEventListener;
    var document_addEventListener = document.addEventListener;
    var Event_preventDefault = Event.prototype.preventDefault;
    
    // Hook addEventListener process
    function addEventListener(type, func, useCapture) {
    try {
    var _addEventListener = this === document ? document_addEventListener : EventTarget_addEventListener;
    if(hook_eventNames.indexOf(type) >= 0) {
    _addEventListener.apply(this, [type, returnTrue, useCapture]);
    } else if(this && unhook_eventNames.indexOf(type) >= 0) {
    var funcsName = storageName + type + (useCapture ? 't' : 'f');
    
    if(this[funcsName] === undefined) {
    this[funcsName] = [];
    _addEventListener.apply(this, [type, useCapture ? unhook_t : unhook_f, useCapture]);
    }
    
    this[funcsName].push(func);
    } else {
    _addEventListener.apply(this, arguments);
    }
    } catch(e) {
    if(DEBUG_MODE) console.error('addEventListener hook error:', e);
    // Fallback to original function
    EventTarget_addEventListener.apply(this, arguments);
    }
    }
    
    // Clear DOM0 event handlers
    function clearLoop() {
    try {
    var elements = getElements();
    
    for(var i in elements) {
    // Skip if element is null or undefined
    if(!elements[i]) continue;
    
    for(var j in eventNames) {
    var name = 'on' + eventNames[j];
    
    // Check if property exists and is modifiable
    try {
    if(elements[i][name] !== null && elements[i][name] !== onxxx) {
    if(unhook_eventNames.indexOf(eventNames[j]) >= 0) {
    elements[i][storageName + name] = elements[i][name];
    elements[i][name] = onxxx;
    } else {
    elements[i][name] = null;
    }
    }
    } catch(e) {
    // Some properties might be read-only, skip them
    if(DEBUG_MODE) console.warn('Cannot modify property:', name, 'on element:', elements[i]);
    }
    }
    }
    } catch(e) {
    if(DEBUG_MODE) console.error('clearLoop error:', e);
    }
    }
    
    // Return true function
    function returnTrue(e) {
    return true;
    }
    
    function unhook_t(e) {
    return unhook(e, this, storageName + e.type + 't');
    }
    
    function unhook_f(e) {
    return unhook(e, this, storageName + e.type + 'f');
    }
    
    function unhook(e, self, funcsName) {
    try {
    var list = self[funcsName];
    if(list && Array.isArray(list)) {
    for(var i in list) {
    if(typeof list[i] === 'function') {
    list[i](e);
    }
    }
    }
    } catch(ex) {
    if(DEBUG_MODE) console.error('unhook error:', ex);
    }
    
    e.returnValue = true;
    return true;
    }
    
    function onxxx(e) {
    try {
    var name = storageName + 'on' + e.type;
    if(this[name] && typeof this[name] === 'function') {
    this[name](e);
    }
    } catch(ex) {
    if(DEBUG_MODE) console.error('onxxx error:', ex);
    }
    
    e.returnValue = true;
    return true;
    }
    
    // Get random string for namespacing
    function getRandStr(chs, len) {
    var str = '';
    while(len--) {
    str += chs[parseInt(Math.random() * chs.length)];
    }
    return str;
    }
    
    // Get elements to process - improved version
    function getElements() {
    try {
    if(AGGRESSIVE_MODE) {
    // Original aggressive mode - gets ALL elements
    var elements = Array.prototype.slice.call(document.getElementsByTagName('*'));
    elements.push(document);
    return elements;
    } else {
    // Optimized mode - only get potentially problematic elements
    var elements = [];
    
    // Add document
    elements.push(document);
    
    // Add body if it exists
    if(document.body) {
    elements.push(document.body);
    }
    
    // Add common interactive elements
    var selectors = ['a', 'button', 'input', 'textarea', 'select', 'img', 'video', 'audio', 'canvas', 'svg'];
    selectors.forEach(function(selector) {
    try {
    var found = document.querySelectorAll(selector);
    elements = elements.concat(Array.prototype.slice.call(found));
    } catch(e) {
    // Selector might fail on some pages
    }
    });
    
    // Add elements with text content that might be restricted
    var textElements = document.querySelectorAll('p, div, span, article, section, main, h1, h2, h3, h4, h5, h6, pre, code');
    // Only add first 100 to avoid performance issues
    var textArray = Array.prototype.slice.call(textElements, 0, 100);
    elements = elements.concat(textArray);
    
    return elements;
    }
    } catch(e) {
    if(DEBUG_MODE) console.error('getElements error:', e);
    // Return at least document to avoid complete failure
    return [document];
    }
    }
    
    // Add CSS styles
    function addStyle(css) {
    try {
    // Check if head exists, wait if not
    if(!document.head) {
    setTimeout(function() { addStyle(css); }, 100);
    return;
    }
    
    var style = document.createElement('style');
    style.innerHTML = css;
    document.head.appendChild(style);
    } catch(e) {
    if(DEBUG_MODE) console.error('addStyle error:', e);
    }
    }
    
    // Get rule for target domain
    function getRule(url) {
    function testUrl(list, url) {
    for(var i in list) {
    if(list[i].test(url)) {
    return true;
    }
    }
    return false;
    }
    
    // Check blacklist first
    if(testUrl(lists.black_list, url)) {
    return rules.black_rule;
    }
    
    // Check light list
    if(testUrl(lists.light_list, url)) {
    return rules.light_rule;
    }
    
    return rules.default_rule;
    }
    
    // Initialize script
    function init() {
    try {
    // Get rule for current domain
    var url = window.location.host + window.location.pathname;
    var rule = getRule(url);
    
    // Exit early if blacklisted
    if(rule.name === 'black') {
    if(DEBUG_MODE) console.log('Site blacklisted, script disabled');
    return;
    }
    
    // Set event lists
    hook_eventNames = rule.hook_eventNames.split("|").filter(function(x) { return x; });
    unhook_eventNames = rule.unhook_eventNames.split("|").filter(function(x) { return x; });
    eventNames = hook_eventNames.concat(unhook_eventNames);
    
    // Set up DOM0 event clearing
    if(rule.dom0) {
    // Only set interval if user configured it
    if(DOM_CLEAR_INTERVAL > 0) {
    setInterval(clearLoop, DOM_CLEAR_INTERVAL);
    if(DEBUG_MODE) console.log('DOM clear interval set to:', DOM_CLEAR_INTERVAL, 'ms');
    }
    
    // Initial clear after delay
    setTimeout(clearLoop, INITIAL_CLEAR_DELAY);
    
    // Clear on page load
    window.addEventListener('load', clearLoop, true);
    
    // Initial immediate clear
    clearLoop();
    }
    
    // Hook addEventListener
    if(rule.hook_addEventListener) {
    EventTarget.prototype.addEventListener = addEventListener;
    document.addEventListener = addEventListener;
    }
    
    // Hook preventDefault
    if(rule.hook_preventDefault) {
    Event.prototype.preventDefault = function() {
    if(eventNames.indexOf(this.type) < 0) {
    Event_preventDefault.apply(this, arguments);
    }
    };
    }
    
    // Hook set returnValue
    if(rule.hook_set_returnValue) {
    try {
    Event.prototype.__defineSetter__('returnValue', function() {
    if(this.returnValue !== true && eventNames.indexOf(this.type) >= 0) {
    this.returnValue = true;
    }
    });
    } catch(e) {
    // __defineSetter__ might not be available in all browsers
    if(DEBUG_MODE) console.warn('Cannot set returnValue setter:', e);
    }
    }
    
    if(DEBUG_MODE) {
    console.log('Remove Web Limits - Initialized');
    console.log('URL:', url);
    console.log('Storage Name:', storageName);
    console.log('Rule:', rule.name);
    console.log('DOM Clear Interval:', DOM_CLEAR_INTERVAL || 'disabled');
    }
    
    // Add CSS
    if(rule.add_css) {
    addStyle('html, * {-webkit-user-select:text!important; -moz-user-select:text!important; user-select:text!important; -ms-user-select:text!important; -khtml-user-select:text!important;}');
    }
    } catch(e) {
    console.error('Remove Web Limits - Initialization failed:', e);
    }
    }
    
    // Start the script
    init();
    })();
    TOM
    TOM --- ---
    TOM: přepis do nyx-code formátu (viz záhlaví)
    // @match https://www.osel.cz/*
    
    // ==UserScript==
    // @name Advanced AdBlock Detection Remover
    // @namespace http://tampermonkey.net/
    // @version 10
    // @description Remove all adblock detection
    // @author Claude.ai
    // @match http://*/*
    // @match https://*/*
    // @grant none
    // @run-at document-start
    // ==/UserScript==
    
    (function() {
    'use strict';
    
    // Block Google Funding Choices
    Object.defineProperty(window, 'fc', {
    get: function() { return {}; },
    set: function() {}
    });
    
    // Block Google Analytics adblock detection
    const originalGA = window.ga;
    if (typeof originalGA === 'function') {
    window.ga = function() {
    if (arguments[0] === 'send' &&
    arguments[1] === 'event' &&
    arguments[2] === 'Adblock') {
    console.log('Blocked GA Adblock event');
    return;
    }
    return originalGA.apply(this, arguments);
    };
    }
    
    // Block old Google Analytics
    if (typeof window._gaq !== 'undefined') {
    const originalGaqPush = window._gaq.push;
    window._gaq.push = function() {
    if (arguments[0] &&
    Array.isArray(arguments[0]) &&
    arguments[0][0] === '_trackEvent' &&
    arguments[0][1] === 'Adblock') {
    console.log('Blocked old GA Adblock event');
    return;
    }
    return originalGaqPush.apply(this, arguments);
    };
    }
    
    // Force scrollbar function
    function forceScrollbar() {
    document.documentElement.style.overflow = 'auto';
    if (document.body) {
    document.body.style.overflow = 'auto';
    }
    }
    
    // Remove any existing adblock popups
    function removeAdblockPopups() {
    // Force scrollbar every time we run cleanup
    forceScrollbar();
    
    // Remove Funding Choices popup
    document.querySelectorAll('.fc-ab-root, .fc-dialog-container, .fc-dialog-overlay, .fc-whitelist-root').forEach(el => {
    el.remove();
    console.log('Removed Funding Choices popup');
    });
    
    // Remove any other potential adblock warnings
    const selectors = [
    '.adblock-popup', '.adblock-detected', '.adsbygoogle',
    'ins.adsbygoogle', '.advertisement', '.ad-warning',
    '.adblock-notice', '.adblock-modal', '[class*="adblock"]',
    '[id*="adblock"]', '[class*="advertisement"]', '[id*="advertisement"]',
    '.eu-cookies', '.fb_box'
    ];
    
    selectors.forEach(selector => {
    document.querySelectorAll(selector).forEach(element => {
    if (element.innerHTML.includes('ad') ||
    element.innerHTML.includes('AdBlock') ||
    element.innerHTML.includes('disable') ||
    element.innerHTML.includes('enable') ||
    element.innerHTML.includes('advertisement') ||
    element.innerHTML.includes('reklam')) {
    element.remove();
    console.log('Removed adblock element:', selector);
    }
    });
    });
    
    // Remove overlay elements that might block content
    document.querySelectorAll('body > *').forEach(element => {
    const style = window.getComputedStyle(element);
    if (style.position === 'fixed' && style.zIndex > '9999') {
    const text = element.textContent.toLowerCase();
    if (text.includes('adblock') || text.includes('disable') ||
    text.includes('whitelist') || text.includes('advertisement')) {
    element.remove();
    }
    }
    });
    }
    
    // Block requests to Google Ads and Funding Choices
    const originalSend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = function() {
    if (arguments[0] && typeof arguments[0] === 'string' &&
    (arguments[0].includes('googleads.g.doubleclick.net') ||
    arguments[0].includes('fundingchoicesmessages.google.com'))) {
    console.log('Blocked request to Google Ads/Funding Choices');
    return;
    }
    return originalSend.apply(this, arguments);
    };
    
    const originalFetch = window.fetch;
    window.fetch = function() {
    if (arguments[0] && typeof arguments[0] === 'string' &&
    (arguments[0].includes('googleads.g.doubleclick.net') ||
    arguments[0].includes('fundingchoicesmessages.google.com'))) {
    console.log('Blocked fetch to Google Ads/Funding Choices');
    return Promise.reject(new Error('Blocked by adblock script'));
    }
    return originalFetch.apply(this, arguments);
    };
    
    // Block Funding Choices iframes
    const originalCreateElement = document.createElement;
    document.createElement = function() {
    const element = originalCreateElement.apply(this, arguments);
    if (arguments[0] === 'iframe') {
    setTimeout(() => {
    if (element.src && element.src.includes('fundingchoicesmessages.google.com')) {
    element.remove();
    console.log('Blocked Funding Choices iframe');
    }
    }, 0);
    }
    return element;
    };
    
    // Run cleanup on page load
    document.addEventListener('DOMContentLoaded', removeAdblockPopups);
    window.addEventListener('load', removeAdblockPopups);
    
    console.log('Advanced AdBlock Detection Remover is active');
    
    })();
    Kliknutím sem můžete změnit nastavení reklam