Greasy Fork

来自缓存

Greasy Fork is available in English.

MZ - Country Transfer Monitor

Monitors the transfer market for players from a specific country

当前为 2025-03-29 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name          MZ - Country Transfer Monitor
// @namespace     douglaskampl
// @version       1.3
// @description   Monitors the transfer market for players from a specific country
// @author        Douglas
// @match         https://www.managerzone.com/*
// @icon          https://www.google.com/s2/favicons?sz=64&domain=managerzone.com
// @grant         GM_setValue
// @grant         GM_getValue
// @grant         GM_addStyle
// @grant         GM_getResourceText
// @require       https://cdn.jsdelivr.net/npm/sweetalert2@11
// @resource      SWEETALERT2_CSS https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css
// @run-at        document-idle
// @license       MIT
// ==/UserScript==

(function () {
    'use strict';

    GM_addStyle(GM_getResourceText('SWEETALERT2_CSS'));
    GM_addStyle(`
        #country-monitor-wrapper {
            display: flex;
            align-items: center;
            margin-left: 15px;
            position: relative;
        }
        #country-monitor-flag {
            width: 22px;
            height: 17px;
            object-fit: contain;
            vertical-align: middle;
            border: 1px solid #ddd;
            border-radius: 2px;
            transition: transform 0.2s ease;
            cursor: pointer;
        }
        #country-monitor-flag:hover {
            transform: scale(1.1);
        }
        #country-monitor-name {
            margin-left: 5px;
            font-size: 12px;
            color: #666;
            display: none;
        }
        #rare-finder-btn {
            margin-left: 10px;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            background: #3498db;
            color: white;
            border-radius: 50%;
            cursor: pointer;
            transition: background 0.2s ease, transform 0.2s ease;
            font-size: 14px;
        }
        #rare-finder-btn:hover {
            background: #2980b9;
            transform: scale(1.1);
        }
        #rare-countries-results {
            display: flex;
            flex-wrap: wrap;
            margin-left: 10px;
            align-items: center;
        }
        .rare-country-result {
            display: flex;
            align-items: center;
            margin-right: 10px;
            background: rgba(52, 152, 219, 0.1);
            padding: 4px 8px;
            border-radius: 12px;
            cursor: pointer;
            transition: background 0.2s;
        }
        .rare-country-result:hover {
            background: rgba(52, 152, 219, 0.2);
        }
        .rare-country-result img {
            width: 16px;
            height: 12px;
            border: 1px solid #ddd;
            margin-right: 5px;
        }
        .rare-country-result span {
            font-size: 11px;
            color: #e74c3c;
            font-weight: bold;
        }
        #country-selector {
            position: absolute;
            top: 100%;
            right: 0;
            z-index: 9999;
            background: #2c3e50;
            color: #fff;
            border: 1px solid #34495e;
            border-radius: 4px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.2);
            width: 300px;
            max-height: 400px;
            overflow-y: auto;
            padding: 10px;
            display: none;
            opacity: 0;
            transform: translateY(-10px);
            transition: opacity 0.3s ease, transform 0.3s ease;
        }
        #country-selector.visible {
            opacity: 1;
            transform: translateY(0);
        }
        #country-selector::-webkit-scrollbar {
            width: 8px;
        }
        #country-selector::-webkit-scrollbar-track {
            background: #34495e;
            border-radius: 4px;
        }
        #country-selector::-webkit-scrollbar-thumb {
            background: #7f8c8d;
            border-radius: 4px;
        }
        #country-selector::-webkit-scrollbar-thumb:hover {
            background: #95a5a6;
        }
        #country-search {
            width: 100%;
            padding: 8px;
            margin-bottom: 10px;
            border: 1px solid #34495e;
            background-color: #34495e;
            color: white;
            border-radius: 4px;
        }
        #country-search::placeholder {
            color: #bdc3c7;
        }
        .country-option {
            display: flex;
            align-items: center;
            padding: 6px 10px;
            cursor: pointer;
            border-radius: 4px;
            color: #ecf0f1;
        }
        .country-option:hover {
            background: #34495e;
        }
        .country-option img {
            width: 24px;
            height: 16px;
            margin-right: 10px;
            object-fit: contain;
            border: 1px solid #34495e;
        }
        .country-option.selected {
            background: #3498db;
        }
        #search-status {
            margin-left: 10px;
            font-size: 12px;
            color: #95a5a6;
        }
        .rare-country-item {
            display: flex;
            align-items: center;
            margin-bottom: 8px;
            padding: 8px;
            border-radius: 4px;
            background: rgba(52, 73, 94, 0.1);
            cursor: pointer;
        }
        .rare-country-item:hover {
            background: rgba(52, 73, 94, 0.2);
        }
        .rare-country-flag {
            width: 24px;
            height: 16px;
            margin-right: 10px;
            border: 1px solid #ddd;
        }
        .rare-country-name {
            flex-grow: 1;
        }
        .rare-country-count {
            font-weight: bold;
            color: #e74c3c;
            margin-left: 10px;
        }
        .swal2-html-container {
            max-height: 400px;
            overflow-y: auto;
        }
    `);

    const CONFIG = {
        CHECK_INTERVAL_HOURS: 6,
        TOAST_DURATION: 5000,
        DEFAULT_COUNTRY_NAME: 'Country',
        DEFAULT_COUNTRY_CID: null,
        COUNTRIES_JSON_URL: 'https://pub-02de1c06eac643f992bb26daeae5c7a0.r2.dev/json/countries.json',
        MAX_RARE_PLAYERS: 15
    };

    let countries = [];
    let selectedCountry = {
        cid: GM_getValue('selectedCountryCid', CONFIG.DEFAULT_COUNTRY_CID),
        name: GM_getValue('selectedCountryName', CONFIG.DEFAULT_COUNTRY_NAME),
        code: GM_getValue('selectedCountryCode', '')
    };

    let knownPlayers = GM_getValue('knownPlayers', {});
    let lastChecked = GM_getValue('lastChecked', 0);
    let isScanning = false;

    function getFlagUrl(code) {
        const upperCode = (code || '').toUpperCase();
        if (upperCode === 'SC') {
            return 'https://cdn.jsdelivr.net/gh/lipis/flag-icons/flags/4x3/gb-sct.svg';
        } else if (upperCode === 'WL') {
            return 'https://cdn.jsdelivr.net/gh/lipis/flag-icons/flags/4x3/gb-wls.svg';
        } else if (upperCode === 'NI') {
            return 'https://cdn.jsdelivr.net/gh/lipis/flag-icons/flags/4x3/gb-nir.svg';
        } else if (upperCode === 'EN') {
            return 'https://cdn.jsdelivr.net/gh/lipis/flag-icons/flags/4x3/gb-eng.svg';
        } else if (upperCode === 'DC') {
            return 'https://placehold.co/16x12/gray/white?text=MZ';
        }
        return `https://flagcdn.com/16x12/${(code || '').toLowerCase()}.png`;
    }

    function cleanupKnownPlayers() {
        const now = Date.now();
        const threeDaysInMs = 3 * 24 * 60 * 60 * 1000;
        let modified = false;
        Object.keys(knownPlayers).forEach(playerId => {
            if (now - knownPlayers[playerId].firstSeen > threeDaysInMs) {
                delete knownPlayers[playerId];
                modified = true;
            }
        });
        if (modified) {
            GM_setValue('knownPlayers', knownPlayers);
        }
    }

    function fetchCountries() {
        fetch(CONFIG.COUNTRIES_JSON_URL)
            .then(response => response.json())
            .then(data => {
                countries = data;
                countries.sort((a, b) => a.name.localeCompare(b.name));
                buildUI();
            })
            .catch(error => {});
    }

    function buildUI() {
        if (!isTransferPage()) return;
        const searchButton = document.getElementById('tds');
        if (!searchButton) return;

        const monitorWrapper = document.createElement('div');
        monitorWrapper.id = 'country-monitor-wrapper';
        monitorWrapper.style.display = 'inline-block';
        monitorWrapper.style.marginLeft = '10px';

        const flagImg = document.createElement('img');
        flagImg.id = 'country-monitor-flag';
        flagImg.src = selectedCountry.code ? getFlagUrl(selectedCountry.code) : 'https://placehold.co/16x12/gray/white?text=?';
        flagImg.alt = selectedCountry.name;
        flagImg.title = "Select country to monitor";

        const rareFinderBtn = document.createElement('div');
        rareFinderBtn.id = 'rare-finder-btn';
        rareFinderBtn.innerHTML = '🔍';
        rareFinderBtn.title = 'Find countries with < 5 19-year-olds';

        const rareCountriesResults = document.createElement('div');
        rareCountriesResults.id = 'rare-countries-results';

        const searchStatus = document.createElement('span');
        searchStatus.id = 'search-status';
        searchStatus.style.display = 'none';

        const countryName = document.createElement('span');
        countryName.id = 'country-monitor-name';
        countryName.textContent = selectedCountry.name;

        monitorWrapper.appendChild(flagImg);
        monitorWrapper.appendChild(countryName);
        monitorWrapper.appendChild(rareFinderBtn);
        monitorWrapper.appendChild(searchStatus);
        monitorWrapper.appendChild(rareCountriesResults);

        const selector = document.createElement('div');
        selector.id = 'country-selector';

        const search = document.createElement('input');
        search.id = 'country-search';
        search.type = 'text';
        search.placeholder = 'Search country...';
        selector.appendChild(search);

        countries.forEach(country => {
            const option = document.createElement('div');
            option.className = 'country-option';
            if (selectedCountry.cid === country.cid) {
                option.classList.add('selected');
            }

            const optionImg = document.createElement('img');
            optionImg.src = getFlagUrl(country.code);
            optionImg.alt = country.name;

            const optionName = document.createElement('span');
            optionName.textContent = country.name;

            option.appendChild(optionImg);
            option.appendChild(optionName);

            option.addEventListener('click', () => {
                selectCountry(country);
                hideSelector(selector);
            });

            selector.appendChild(option);
        });

        search.addEventListener('input', function() {
            const query = this.value.toLowerCase();
            Array.from(selector.querySelectorAll('.country-option')).forEach(option => {
                const name = option.querySelector('span').textContent.toLowerCase();
                option.style.display = name.includes(query) ? 'flex' : 'none';
            });
        });

        monitorWrapper.appendChild(selector);

        flagImg.addEventListener('click', (e) => {
            if (selector.classList.contains('visible')) {
                hideSelector(selector);
            } else {
                showSelector(selector);
                search.focus();
            }
        });

        rareFinderBtn.addEventListener('click', () => {
            findRareCountriesInline();
        });

        document.addEventListener('click', (e) => {
            if (!monitorWrapper.contains(e.target) || (e.target !== flagImg && !selector.contains(e.target))) {
                hideSelector(selector);
            }
        });

        searchButton.insertAdjacentElement('afterend', monitorWrapper);

        if (selectedCountry.cid) {
            checkTransferMarket(false);
        }
    }

    function showSelector(selector) {
        selector.style.display = 'block';
        selector.offsetHeight;
        selector.classList.add('visible');
    }

    function hideSelector(selector) {
        selector.classList.remove('visible');
        setTimeout(() => {
            if (!selector.classList.contains('visible')) {
                selector.style.display = 'none';
            }
        }, 300);
    }

    function selectCountry(country) {
        selectedCountry = {
            cid: country.cid,
            name: country.name,
            code: country.code
        };
        GM_setValue('selectedCountryCid', country.cid);
        GM_setValue('selectedCountryName', country.name);
        GM_setValue('selectedCountryCode', country.code);
        const flagImg = document.getElementById('country-monitor-flag');
        if (flagImg) {
            flagImg.src = getFlagUrl(country.code);
            flagImg.alt = country.name;
            flagImg.title = "Monitor players from: " + country.name;
        }
        const countryName = document.getElementById('country-monitor-name');
        if (countryName) {
            countryName.textContent = country.name;
        }
        checkTransferMarket(true);
    }

    function isTransferPage() {
        return window.location.href.includes('p=transfer');
    }

    function isTransferSearchPage19() {
        return window.location.href.includes('p=transfer') &&
               window.location.href.includes('sub=search') &&
               window.location.href.includes('agea=19') &&
               window.location.href.includes('ageb=19');
    }

    function checkTransferMarket(forced = false) {
        if (!selectedCountry.cid) return;
        const now = Date.now();
        const checkIntervalMs = CONFIG.CHECK_INTERVAL_HOURS * 60 * 60 * 1000;
        if (!forced && (now - lastChecked < checkIntervalMs)) {
            return;
        }
        cleanupKnownPlayers();
        fetch(`https://www.managerzone.com/ajax.php?p=transfer&sub=transfer-search&sport=soccer&issearch=true&u=&nationality=${selectedCountry.cid}&deadline=0&category=&valuea=&valueb=&bida=&bidb=&agea=19&ageb=37&birth_season_low=56&birth_season_high=74&tot_low=0&tot_high=110&s0a=0&s0b=10&s1a=0&s1b=10&s2a=0&s2b=10&s3a=0&s3b=10&s4a=0&s4b=10&s5a=0&s5b=10&s6a=0&s6b=10&s7a=0&s7b=10&s8a=0&s8b=10&s9a=0&s9b=10&s10a=0&s10b=10&s11a=0&s11b=10&s12a=0&s12b=10`)
            .then(response => response.json())
            .then(data => {
                lastChecked = now;
                GM_setValue('lastChecked', lastChecked);
                if (data.totalHits && parseInt(data.totalHits) > 0) {
                    processPlayers(data);
                }
            })
            .catch(error => {});
    }

    function processPlayers(data) {
        if (!data.players || data.players.includes("No players found")) {
            return;
        }
        const playersData = data.players;
        const pidRegex = /href=["'].*?pid=(\d+)/g;
        let pidMatches = [...playersData.matchAll(pidRegex)];
        const playerIdSpanRegex = /player_id_(\d+)/g;
        let playerIdSpanMatches = [...playersData.matchAll(playerIdSpanRegex)];
        const idRegex = /id: (\d+)/g;
        let idMatches = [...playersData.matchAll(idRegex)];
        let allPlayerIds = new Set([
            ...pidMatches.map(match => match[1]),
            ...playerIdSpanMatches.map(match => match[1]),
            ...idMatches.map(match => match[1])
        ]);
        const playerNameRegex1 = /"([^"]+)"\s+([^<]+)<\/span>/g;
        const playerNameRegex2 = /player_name">([^<]+)<\/span>/g;
        let nameMatches1 = [...playersData.matchAll(playerNameRegex1)];
        let nameMatches2 = [...playersData.matchAll(playerNameRegex2)];
        let players = [];
        if (nameMatches1.length > 0) {
            nameMatches1.forEach((match, index) => {
                if (index < allPlayerIds.size) {
                    const playerName = match[2] ? match[2].trim() : match[1].trim();
                    const playerId = Array.from(allPlayerIds)[index];
                    players.push({ id: playerId, name: playerName });
                }
            });
        } else if (nameMatches2.length > 0) {
            nameMatches2.forEach((match, index) => {
                if (index < allPlayerIds.size) {
                    const playerName = match[1].trim();
                    const playerId = Array.from(allPlayerIds)[index];
                    players.push({ id: playerId, name: playerName });
                }
            });
        } else if (allPlayerIds.size > 0) {
            Array.from(allPlayerIds).forEach(id => {
                players.push({ id: id, name: id });
            });
        }
        if (players.length === 0) {
            try {
                const jsonString = JSON.stringify(data);
                const jsonIdRegex = /\d{9}/g;
                const jsonIdMatches = [...new Set([...jsonString.matchAll(jsonIdRegex)].map(m => m[0]))];
                jsonIdMatches.forEach(id => {
                    players.push({ id: id, name: id });
                });
            } catch (e) {}
        }

        if (!isScanning) {
            const newPlayers = players.filter(player => !knownPlayers[player.id]);
            if (newPlayers.length > 0) {
                showPlayerNotification(newPlayers);
                newPlayers.forEach(player => {
                    knownPlayers[player.id] = { k: player.name, firstSeen: Date.now() };
                });
                GM_setValue('knownPlayers', knownPlayers);
            }
        }

        return players.length;
    }

    function showPlayerNotification(players) {
        const htmlContent = `<p>New players from ${selectedCountry.name} found (${players.length}). Click "View" to see them on the transfer market.</p>`;
        Swal.fire({
            title: 'New Players!',
            html: htmlContent,
            icon: 'info',
            showCancelButton: true,
            confirmButtonText: 'View',
            cancelButtonText: 'Close'
        }).then((result) => {
            if (result.isConfirmed) {
                window.location.href = `https://www.managerzone.com/?p=transfer&sub=search&sport=soccer&nationality=${selectedCountry.cid}`;
            }
        });
    }

    function countPlayersFromCountry(country) {
        return new Promise((resolve, reject) => {
            fetch(`https://www.managerzone.com/ajax.php?p=transfer&sub=transfer-search&sport=soccer&issearch=true&u=&nationality=${country.cid}&deadline=0&category=&valuea=&valueb=&bida=&bidb=&agea=19&ageb=19&birth_season_low=56&birth_season_high=74&tot_low=0&tot_high=110&s0a=0&s0b=10&s1a=0&s1b=10&s2a=0&s2b=10&s3a=0&s3b=10&s4a=0&s4b=10&s5a=0&s5b=10&s6a=0&s6b=10&s7a=0&s7b=10&s8a=0&s8b=10&s9a=0&s9b=10&s10a=0&s10b=10&s11a=0&s11b=10&s12a=0&s12b=10`)
                .then(response => response.json())
                .then(data => {
                    let playerCount = 0;
                    if (data.totalHits) {
                        playerCount = parseInt(data.totalHits);
                    }
                    resolve({
                        cid: country.cid,
                        name: country.name,
                        code: country.code,
                        playerCount: playerCount
                    });
                })
                .catch(() => {
                    resolve({
                        cid: country.cid,
                        name: country.name,
                        code: country.code,
                        playerCount: 0
                    });
                });
        });
    }

    function findRareCountriesInline() {
        if (isScanning) return;
        isScanning = true;

        const rareCountriesResults = document.getElementById('rare-countries-results');
        const searchStatus = document.getElementById('search-status');

        rareCountriesResults.innerHTML = '';
        searchStatus.textContent = 'Scanning countries...';
        searchStatus.style.display = 'inline';

        const rareCountries = [];
        let processed = 0;

        async function runBatch(startIdx, batchSize) {
            const endIdx = Math.min(startIdx + batchSize, countries.length);
            const batch = countries.slice(startIdx, endIdx);

            const promises = batch.map(country => countPlayersFromCountry(country));

            try {
                const results = await Promise.all(promises);
                processed += results.length;

                searchStatus.textContent = `Scanned ${processed}/${countries.length}...`;

                results.forEach(result => {
                    if (result.playerCount > 0 && result.playerCount < CONFIG.MAX_RARE_PLAYERS) {
                        rareCountries.push(result);

                        const countryItem = document.createElement('div');
                        countryItem.className = 'rare-country-result';
                        countryItem.title = result.name;
                        countryItem.dataset.cid = result.cid;

                        const flagImg = document.createElement('img');
                        flagImg.src = getFlagUrl(result.code);
                        flagImg.alt = result.name;

                        const countSpan = document.createElement('span');
                        countSpan.textContent = result.playerCount;

                        countryItem.appendChild(flagImg);
                        countryItem.appendChild(countSpan);

                        countryItem.addEventListener('click', () => {
                            window.open(`https://www.managerzone.com/?p=transfer&sub=search&sport=soccer&nationality=${result.cid}&agea=19&ageb=19`, '_blank');
                        });

                        rareCountriesResults.appendChild(countryItem);
                    }
                });

                if (endIdx < countries.length) {
                    setTimeout(() => runBatch(endIdx, batchSize), 1000);
                } else {
                    finishScanning(rareCountries);
                }
            } catch (error) {
                if (endIdx < countries.length) {
                    setTimeout(() => runBatch(endIdx, batchSize), 1000);
                } else {
                    finishScanning(rareCountries);
                }
            }
        }

        function finishScanning(rareCountries) {
            isScanning = false;
            if (rareCountries.length === 0) {
                searchStatus.textContent = 'No rare countries found';
                setTimeout(() => {
                    searchStatus.style.display = 'none';
                }, 3000);
            } else {
                searchStatus.textContent = `Found ${rareCountries.length} countries`;
                setTimeout(() => {
                    searchStatus.style.display = 'none';
                }, 3000);
            }
        }

        runBatch(0, 5);
    }

    function findRareCountries() {
        if (isScanning) return;
        isScanning = true;

        Swal.fire({
            title: 'Scanning Countries',
            html: 'Looking for countries with fewer than 5 19-year-old players on the market.<br>This may take a while...',
            allowOutsideClick: false,
            position: 'top-end',
            didOpen: () => {
                Swal.showLoading();
            }
        });

        const rareCountries = [];
        let processed = 0;

        async function runBatch(startIdx, batchSize) {
            const endIdx = Math.min(startIdx + batchSize, countries.length);
            const batch = countries.slice(startIdx, endIdx);

            const promises = batch.map(country => countPlayersFromCountry(country));

            try {
                const results = await Promise.all(promises);
                processed += results.length;

                Swal.getHtmlContainer().innerHTML = `Scanned ${processed}/${countries.length} countries...<br>Found ${rareCountries.length} rare countries so far.`;

                results.forEach(result => {
                    if (result.playerCount > 0 && result.playerCount < CONFIG.MAX_RARE_PLAYERS) {
                        rareCountries.push(result);
                    }
                });

                if (endIdx < countries.length) {
                    setTimeout(() => runBatch(endIdx, batchSize), 1000);
                } else {
                    displayRareCountries(rareCountries);
                    isScanning = false;
                }
            } catch (error) {
                if (endIdx < countries.length) {
                    setTimeout(() => runBatch(endIdx, batchSize), 1000);
                } else {
                    displayRareCountries(rareCountries);
                    isScanning = false;
                }
            }
        }

        runBatch(0, 5);
    }

    function displayRareCountries(rareCountries) {
        if (rareCountries.length === 0) {
            Swal.fire({
                title: 'No Rare Countries Found',
                text: 'Could not find any countries with fewer than 5 19-year-old players on the market.',
                icon: 'info',
                position: 'top-end'
            });
            return;
        }

        rareCountries.sort((a, b) => a.playerCount - b.playerCount);

        let htmlContent = `<p>Found ${rareCountries.length} countries with fewer than 5 19-year-old players:</p><div style="margin-top: 15px;">`;

        rareCountries.forEach(country => {
            htmlContent += `
                <div class="rare-country-item" data-cid="${country.cid}">
                    <img src="${getFlagUrl(country.code)}" class="rare-country-flag" alt="${country.name}">
                    <span class="rare-country-name">${country.name}</span>
                    <span class="rare-country-count">${country.playerCount}</span>
                </div>
            `;
        });

        htmlContent += '</div>';

        Swal.fire({
            title: 'Rare Countries - 19-Year-Olds',
            html: htmlContent,
            icon: 'success',
            confirmButtonText: 'Close',
            width: 400,
            position: 'top-end',
            didOpen: () => {
                document.querySelectorAll('.rare-country-item').forEach(item => {
                    item.addEventListener('click', () => {
                        const cid = item.getAttribute('data-cid');
                        const url = `https://www.managerzone.com/?p=transfer&sub=search&sport=soccer&nationality=${cid}&agea=19&ageb=19`;
                        window.open(url, '_blank');
                    });
                });
            }
        });
    }

    function initAgeButtonClick() {
        if (!isTransferSearchPage19()) return;
        const x = 30;
        setTimeout(() => {
            const ageButton = document.getElementById('ageButton19');
            if (ageButton) {
                console.log('Clicking age button');
                ageButton.click();
            } else {
                console.log('Age button not found after timeout');
            }
        }, x * 1000);
    }

    function checkPageAndInit() {
        if (isTransferPage()) {
            fetchCountries();
        }

        if (isTransferSearchPage19()) {
            initAgeButtonClick();
        }
    }

    checkPageAndInit();

    setInterval(checkTransferMarket, 30 * 60 * 1000);

    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            setTimeout(checkPageAndInit, 500);
        }
    }).observe(document, {subtree: true, childList: true});
})();