// ==UserScript==
// @name         Advanced Multi-Search Engine Web Crawler with Inline Anime Viewer
// @namespace    http://tampermonkey.net/
// @version      4.4
// @description  고도화된 다중 검색 엔진 웹 크롤러. 진행률 표시, 기능 토글, 사이트 정보 수집, 로그, 중복 검사, 크롤링 속도 조절, 애니메이션 뷰어 포함. Firefox 스타일 UI.
// @author       YourName
// @match        https://www.google.com/search*
// @match        https://www.bing.com/search*
// @match        https://search.yahoo.com/search*
// @match        https://linkkf.net/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_xmlhttpRequest
// @grant        GM_openInTab
// @connect      *
// ==/UserScript==

(function() {
    'use strict';

    // CSS Styles for Firefox-like UI
    GM_addStyle(`
        #crawlerUI {
            position: fixed;
            top: 50px;
            right: 50px;
            background: #FFFFFF;
            border: 1px solid #CCC;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            z-index: 10000;
            width: 600px;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            font-size: 14px;
            max-height: 95vh;
            overflow-y: auto;
        }
        #crawlerUI h3 {
            margin-top: 0;
            text-align: center;
            color: #333;
            background: #E6E6E6;
            padding: 10px;
            border-radius: 5px;
        }
        #crawlerUI button {
            margin: 5px 5px 5px 0;
            padding: 8px 16px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        }
        #startBtn { background-color: #28a745; color: white; }
        #stopBtn { background-color: #dc3545; color: white; }
        #resetBtn { background-color: #ffc107; color: white; }
        #toggleFeaturesBtn { background-color: #17a2b8; color: white; }
        #toggleHtmlViewerBtn, #toggleAnimeViewerBtn {
            background-color: #6c757d;
            color: white;
            margin-top: 10px;
            width: 100%;
            padding: 8px;
            border-radius: 4px;
            border: none;
            cursor: pointer;
            font-size: 14px;
        }
        #crawlerUI table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
            font-size: 12px;
        }
        #crawlerUI th, #crawlerUI td {
            border: 1px solid #CCC;
            padding: 8px;
            text-align: left;
        }
        #crawlerUI th {
            background-color: #F2F2F2;
        }
        #status {
            margin-top: 15px;
            font-weight: bold;
            color: #555;
            text-align: center;
        }
        #progressContainer {
            width: 100%;
            background-color: #E0E0E0;
            border-radius: 5px;
            margin-top: 10px;
            position: relative;
        }
        #progressBar {
            width: 0%;
            height: 20px;
            background-color: #4caf50;
            border-radius: 5px;
            text-align: center;
            color: white;
            line-height: 20px;
            transition: width 0.3s;
        }
        #featuresContainer, #viewersContainer {
            margin-top: 15px;
            display: none;
        }
        #featuresContainer label {
            display: block;
            margin: 5px 0;
        }
        #logs {
            margin-top: 15px;
            max-height: 200px;
            overflow-y: auto;
            background: #F9F9F9;
            padding: 10px;
            border: 1px solid #CCC;
            font-size: 12px;
            border-radius: 4px;
        }
        #htmlViewer, #animeViewer {
            width: 100%;
            height: 300px;
            border: 1px solid #CCC;
            margin-top: 15px;
            display: none;
            border-radius: 4px;
        }
        #animeViewerContainer {
            margin-top: 15px;
            display: none;
        }
        #animeViewerContainer iframe {
            width: 100%;
            height: 400px;
            border: none;
            border-radius: 4px;
        }
    `);

    // UI 생성
    const ui = document.createElement('div');
    ui.id = 'crawlerUI';
    ui.innerHTML = `
        <h3>웹 크롤러</h3>
        <div style="text-align: center;">
            <button id="startBtn">시작</button>
            <button id="stopBtn" disabled>중지</button>
            <button id="resetBtn">초기화</button>
            <button id="toggleFeaturesBtn">기능 토글</button>
        </div>
        <div id="featuresContainer">
            <label><input type="checkbox" id="captureScreenshot" checked> 자동 스크린샷 캡처</label>
            <label><input type="checkbox" id="fetchHTML" checked> 사이트 HTML 가져오기</label>
            <label><input type="checkbox" id="excludeAds" checked> 광고 제외</label>
            <label><input type="checkbox" id="advancedLogging" checked> 고급 로그 활성화</label>
            <label><input type="checkbox" id="throttleRequests" checked> 요청 속도 조절</label>
            <label><input type="checkbox" id="duplicateCheck" checked> 중복 검사</label>
        </div>
        <div id="status">대기 중</div>
        <div id="progressContainer">
            <div id="progressBar">0%</div>
        </div>
        <table id="resultTable">
            <thead>
                <tr>
                    <th>사이트 이름</th>
                    <th>주소</th>
                    <th>설명</th>
                    <th>HTML 보기</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>
        <button id="toggleHtmlViewerBtn">HTML 뷰어 열기</button>
        <iframe id="htmlViewer" src="https://codebeautify.org/htmlviewer" sandbox="allow-scripts allow-same-origin"></iframe>
        <button id="toggleAnimeViewerBtn">애니 뷰어 열기</button>
        <div id="animeViewerContainer">
            <iframe id="animeViewer" src="https://linkkf.net/" sandbox="allow-scripts allow-same-origin"></iframe>
        </div>
        <div id="logs"></div>
    `;
    document.body.appendChild(ui);

    // 요소 참조
    const startBtn = document.getElementById('startBtn');
    const stopBtn = document.getElementById('stopBtn');
    const resetBtn = document.getElementById('resetBtn');
    const toggleFeaturesBtn = document.getElementById('toggleFeaturesBtn');
    const toggleHtmlViewerBtn = document.getElementById('toggleHtmlViewerBtn');
    const toggleAnimeViewerBtn = document.getElementById('toggleAnimeViewerBtn');
    const featuresContainer = document.getElementById('featuresContainer');
    const statusDiv = document.getElementById('status');
    const progressBar = document.getElementById('progressBar');
    const tbody = document.querySelector('#resultTable tbody');
    const logsDiv = document.getElementById('logs');
    const htmlViewer = document.getElementById('htmlViewer');
    const animeViewerContainer = document.getElementById('animeViewerContainer');

    // 기능 설정 체크박스
    const captureScreenshotCheckbox = document.getElementById('captureScreenshot');
    const fetchHTMLCheckbox = document.getElementById('fetchHTML');
    const excludeAdsCheckbox = document.getElementById('excludeAds');
    const advancedLoggingCheckbox = document.getElementById('advancedLogging');
    const throttleRequestsCheckbox = document.getElementById('throttleRequests');
    const duplicateCheckCheckbox = document.getElementById('duplicateCheck');

    // 상태 변수
    let isCrawling = false;
    let results = [];
    let visitedSites = new Set();
    let crawlConfig = {
        engine: '',
        query: '',
        nextPageURL: '',
        totalPages: 0,
        currentPage: 0
    };
    let totalResults = 0;
    let crawlDelay = 3000; // 기본 3초
    let startTime = null;

    // 중복 검사 로드
    function loadVisitedSites() {
        const stored = GM_getValue('visitedSites', []);
        visitedSites = new Set(stored);
    }

    // 중복 검사 저장
    function saveVisitedSites() {
        GM_setValue('visitedSites', Array.from(visitedSites));
    }

    // 검색어 추출 함수
    function getSearchQuery() {
        const url = new URL(window.location.href);
        let query = '';
        if (url.hostname.includes('google.com')) {
            query = url.searchParams.get('q');
        } else if (url.hostname.includes('bing.com')) {
            query = url.searchParams.get('q');
        } else if (url.hostname.includes('yahoo.com')) {
            query = url.searchParams.get('p');
        } else if (url.hostname.includes('linkkf.net')) {
            query = url.searchParams.get('q');
        }
        return query ? query.trim() : '';
    }

    // 현재 검색 엔진 식별
    function getCurrentEngine() {
        const hostname = window.location.hostname;
        if (hostname.includes('google.com')) return 'google';
        if (hostname.includes('bing.com')) return 'bing';
        if (hostname.includes('yahoo.com')) return 'yahoo';
        if (hostname.includes('linkkf.net')) return 'linkkf';
        return 'unknown';
    }

    const currentEngine = getCurrentEngine();
    if (currentEngine === 'unknown') {
        console.warn('지원되지 않는 검색 엔진입니다.');
        ui.style.display = 'none';
        animeViewerContainer.style.display = 'none';
        return;
    }

    // 검색 엔진별 파서 정의
    const parsers = {
        google: {
            parseResults: function() {
                const items = document.querySelectorAll('div.g');
                items.forEach(item => {
                    if (excludeAdsCheckbox.checked) {
                        const adLabel = item.querySelector('.uEierd');
                        if (adLabel) return; // Skip ads
                    }
                    const name = item.querySelector('h3')?.innerText.trim() || 'N/A';
                    const url = item.querySelector('a')?.href || 'N/A';
                    const description = item.querySelector('.IsZvec')?.innerText.trim() || 'N/A';
                    if (url !== 'N/A' && url.startsWith('http') && (!duplicateCheckCheckbox.checked || !visitedSites.has(url))) {
                        results.push({ name, url, description, html: '' });
                        if (duplicateCheckCheckbox.checked) visitedSites.add(url);
                        totalResults++;
                    }
                });
            },
            getNextPage: function() {
                const nextButton = document.querySelector('#pnnext');
                return nextButton ? nextButton.href : null;
            },
            getTotalPages: function() {
                const total = document.querySelector('#result-stats')?.innerText;
                if (total) {
                    const match = total.match(/of\s+([\d,]+)/i);
                    return match ? Math.min(Math.floor(parseInt(match[1].replace(/,/g, '')) / 10), 100) : 1;
                }
                return 1;
            }
        },
        bing: {
            parseResults: function() {
                const items = document.querySelectorAll('li.b_algo');
                items.forEach(item => {
                    if (excludeAdsCheckbox.checked) {
                        const adLabel = item.querySelector('.b_ad');
                        if (adLabel) return; // Skip ads
                    }
                    const name = item.querySelector('h2')?.innerText.trim() || 'N/A';
                    const url = item.querySelector('a')?.href || 'N/A';
                    const description = item.querySelector('.b_caption p')?.innerText.trim() || 'N/A';
                    if (url !== 'N/A' && url.startsWith('http') && (!duplicateCheckCheckbox.checked || !visitedSites.has(url))) {
                        results.push({ name, url, description, html: '' });
                        if (duplicateCheckCheckbox.checked) visitedSites.add(url);
                        totalResults++;
                    }
                });
            },
            getNextPage: function() {
                const nextButton = document.querySelector('a.sb_pagN');
                return nextButton ? nextButton.href : null;
            },
            getTotalPages: function() {
                const total = document.querySelector('#b_tween .sb_count')?.innerText;
                if (total) {
                    const match = total.match(/of\s+([\d,]+)/i);
                    return match ? Math.min(Math.floor(parseInt(match[1].replace(/,/g, '')) / 10), 100) : 1;
                }
                return 1;
            }
        },
        yahoo: {
            parseResults: function() {
                const items = document.querySelectorAll('div.dd.algo');
                items.forEach(item => {
                    if (excludeAdsCheckbox.checked) {
                        const adLabel = item.querySelector('.MjjYud');
                        if (adLabel) return; // Skip ads
                    }
                    const name = item.querySelector('h3.title a')?.innerText.trim() || 'N/A';
                    const url = item.querySelector('h3.title a')?.href || 'N/A';
                    const description = item.querySelector('div.compText')?.innerText.trim() || 'N/A';
                    if (url !== 'N/A' && url.startsWith('http') && (!duplicateCheckCheckbox.checked || !visitedSites.has(url))) {
                        results.push({ name, url, description, html: '' });
                        if (duplicateCheckCheckbox.checked) visitedSites.add(url);
                        totalResults++;
                    }
                });
            },
            getNextPage: function() {
                const nextButton = document.querySelector('a.next');
                return nextButton ? nextButton.href : null;
            },
            getTotalPages: function() {
                const total = document.querySelector('.compPagination span.omnIs')?.innerText;
                if (total) {
                    const match = total.match(/of\s+([\d,]+)/i);
                    return match ? Math.min(Math.floor(parseInt(match[1].replace(/,/g, '')) / 10), 100) : 1;
                }
                return 1;
            }
        },
        linkkf: {
            parseResults: function() {
                const items = document.querySelectorAll('.anime-item'); // 실제 클래스명으로 변경 필요
                items.forEach(item => {
                    const name = item.querySelector('.anime-title')?.innerText.trim() || 'N/A';
                    const url = item.querySelector('a')?.href || 'N/A';
                    const description = item.querySelector('.anime-description')?.innerText.trim() || 'N/A';
                    if (url !== 'N/A' && url.startsWith('http') && (!duplicateCheckCheckbox.checked || !visitedSites.has(url))) {
                        results.push({ name, url, description, html: '' });
                        if (duplicateCheckCheckbox.checked) visitedSites.add(url);
                        totalResults++;
                    }
                });
            },
            getNextPage: function() {
                const nextButton = document.querySelector('a.next');
                return nextButton ? nextButton.href : null;
            },
            getTotalPages: function() {
                const total = document.querySelector('.pagination .total')?.innerText;
                if (total) {
                    const match = total.match(/of\s+([\d,]+)/i);
                    return match ? Math.min(Math.floor(parseInt(match[1].replace(/,/g, '')) / 10), 50) : 1;
                }
                return 1;
            }
        }
    };

    // 버튼 이벤트 리스너
    startBtn.addEventListener('click', startCrawling);
    stopBtn.addEventListener('click', stopCrawling);
    resetBtn.addEventListener('click', resetCrawling);
    toggleFeaturesBtn.addEventListener('click', toggleFeatures);
    toggleHtmlViewerBtn.addEventListener('click', toggleHtmlViewer);
    toggleAnimeViewerBtn.addEventListener('click', toggleAnimeViewer);

    // 기능 토글 함수
    function toggleFeatures() {
        if (featuresContainer.style.display === 'none') {
            featuresContainer.style.display = 'block';
        } else {
            featuresContainer.style.display = 'none';
        }
    }

    // HTML 뷰어 토글 함수
    function toggleHtmlViewer() {
        if (htmlViewer.style.display === 'none') {
            animeViewerContainer.style.display = 'none';
            htmlViewer.style.display = 'block';
            toggleHtmlViewerBtn.style.backgroundColor = '#17a2b8';
            toggleAnimeViewerBtn.style.backgroundColor = '#6c757d';
        } else {
            htmlViewer.style.display = 'none';
            toggleHtmlViewerBtn.style.backgroundColor = '#6c757d';
        }
    }

    // 애니 뷰어 토글 함수
    function toggleAnimeViewer() {
        if (animeViewerContainer.style.display === 'none') {
            htmlViewer.style.display = 'none';
            animeViewerContainer.style.display = 'block';
            toggleAnimeViewerBtn.style.backgroundColor = '#17a2b8';
            toggleHtmlViewerBtn.style.backgroundColor = '#6c757d';
        } else {
            animeViewerContainer.style.display = 'none';
            toggleAnimeViewerBtn.style.backgroundColor = '#6c757d';
        }
    }

    // 로그 메시지 추가 함수
    function logMessage(message) {
        if (advancedLoggingCheckbox.checked) {
            const timestamp = new Date().toLocaleTimeString();
            logsDiv.innerHTML += `[${timestamp}] ${message}<br/>`;
            logsDiv.scrollTop = logsDiv.scrollHeight;
        }
    }

    // 크롤링 상태 저장 함수
    function saveState() {
        GM_setValue('isCrawling', isCrawling);
        GM_setValue('results', results);
        GM_setValue('crawlConfig', crawlConfig);
        GM_setValue('visitedSites', Array.from(visitedSites));
    }

    // 크롤링 상태 불러오기 함수
    function loadState() {
        isCrawling = GM_getValue('isCrawling', false);
        results = GM_getValue('results', []);
        crawlConfig = GM_getValue('crawlConfig', { engine: '', query: '', nextPageURL: '', totalPages: 0, currentPage: 0 });
        const storedVisitedSites = GM_getValue('visitedSites', []);
        visitedSites = new Set(storedVisitedSites);
    }

    // 크롤링 상태 초기화 함수
    function clearState() {
        GM_deleteValue('isCrawling');
        GM_deleteValue('results');
        GM_deleteValue('crawlConfig');
        GM_deleteValue('visitedSites');
    }

    // 크롤링 시작 함수
    function startCrawling() {
        if (isCrawling) return;
        const query = getSearchQuery();
        if (!query) {
            alert('검색어를 감지할 수 없습니다. 검색을 먼저 수행해주세요.');
            return;
        }
        isCrawling = true;
        crawlConfig = {
            engine: currentEngine,
            query: query,
            nextPageURL: '',
            totalPages: parsers[currentEngine].getTotalPages(),
            currentPage: 1
        };
        totalResults = 0;
        results = [];
        tbody.innerHTML = '';
        logsDiv.innerHTML = '';
        startBtn.disabled = true;
        stopBtn.disabled = false;
        resetBtn.disabled = false;
        toggleFeaturesBtn.disabled = true;
        toggleHtmlViewerBtn.disabled = true;
        toggleAnimeViewerBtn.disabled = true;
        statusDiv.innerHTML = `크롤링 시작...`;
        updateProgress();
        logMessage('크롤링이 시작되었습니다.');
        saveState();
        startTime = new Date();
        crawlCurrentPage();
    }

    // 크롤링 중지 함수
    function stopCrawling() {
        if (!isCrawling) return;
        isCrawling = false;
        startBtn.disabled = false;
        stopBtn.disabled = true;
        resetBtn.disabled = false;
        toggleFeaturesBtn.disabled = false;
        toggleHtmlViewerBtn.disabled = false;
        toggleAnimeViewerBtn.disabled = false;
        statusDiv.innerHTML = `크롤링 중지됨`;
        logMessage('크롤링이 중지되었습니다.');
        saveState();
    }

    // 크롤링 초기화 함수
    function resetCrawling() {
        stopCrawling();
        results = [];
        totalResults = 0;
        tbody.innerHTML = '';
        logsDiv.innerHTML = '';
        statusDiv.innerHTML = `대기 중`;
        progressBar.style.width = '0%';
        progressBar.innerText = '0%';
        clearState();
        logMessage('크롤링이 초기화되었습니다.');
    }

    // 진행률 업데이트 함수
    function updateProgress() {
        const percentage = crawlConfig.totalPages ? Math.min((crawlConfig.currentPage / crawlConfig.totalPages) * 100, 100).toFixed(2) : 0;
        progressBar.style.width = `${percentage}%`;
        progressBar.innerText = `${percentage}%`;
        const elapsedTime = (new Date() - startTime) / 1000; // 초 단위
        const estimatedTotalTime = (elapsedTime / crawlConfig.currentPage) * crawlConfig.totalPages;
        const remainingTime = estimatedTotalTime - elapsedTime;
        statusDiv.innerHTML = `크롤링 중... 페이지 ${crawlConfig.currentPage} / ${crawlConfig.totalPages} | 진행률: ${percentage}% | 남은 시간: ${formatTime(remainingTime)}`;
    }

    // 시간 포맷 함수
    function formatTime(seconds) {
        const hrs = Math.floor(seconds / 3600);
        const mins = Math.floor((seconds % 3600) / 60);
        const secs = Math.floor(seconds % 60);
        return `${hrs}h ${mins}m ${secs}s`;
    }

    // 크롤링 현재 페이지 함수
    function crawlCurrentPage() {
        if (!isCrawling) return;

        logMessage(`페이지 ${crawlConfig.currentPage} 크롤링 중...`);
        updateProgress();

        // 데이터 추출
        parsers[currentEngine].parseResults();
        displayResults();
        updateProgress();
        saveState();

        // HTML 가져오기
        if (fetchHTMLCheckbox.checked) {
            results.slice(totalResults - results.length).forEach((result, index) => {
                fetchHTML(result.url, totalResults - results.length + index);
            });
        }

        // 스크린샷 캡처
        if (captureScreenshotCheckbox.checked) {
            results.slice(totalResults - results.length).forEach((result) => {
                captureScreenshot(result.url);
            });
        }

        // 중복 검사 저장
        if (duplicateCheckCheckbox.checked) {
            saveVisitedSites();
        }

        // 다음 페이지 이동
        const nextPageURL = parsers[currentEngine].getNextPage();
        if (nextPageURL && crawlConfig.currentPage < crawlConfig.totalPages && isCrawling) {
            crawlConfig.nextPageURL = nextPageURL;
            crawlConfig.currentPage++;
            saveState();
            logMessage(`다음 페이지로 이동: ${nextPageURL}`);
            setTimeout(() => {
                window.location.href = nextPageURL;
            }, throttleRequestsCheckbox.checked ? crawlDelay : 1000);
        } else {
            // 크롤링 완료
            isCrawling = false;
            startBtn.disabled = false;
            stopBtn.disabled = true;
            resetBtn.disabled = false;
            toggleFeaturesBtn.disabled = false;
            toggleHtmlViewerBtn.disabled = false;
            toggleAnimeViewerBtn.disabled = false;
            progressBar.style.width = '100%';
            progressBar.innerText = '100%';
            statusDiv.innerHTML = `크롤링 완료 (${results.length}개 결과 수집)`;
            logMessage('크롤링이 완료되었습니다.');
            saveState();
            // 애니 뷰어 자동 표시하지 않음
        }
    }

    // HTML 가져오기 함수
    function fetchHTML(url, index) {
        GM_xmlhttpRequest({
            method: "GET",
            url: url,
            onload: function(response) {
                if (response.status === 200) {
                    results[index].html = response.responseText;
                    appendHtmlToRow(index, response.responseText);
                    logMessage(`HTML 가져오기 성공: ${url}`);
                } else {
                    logMessage(`HTML 가져오기 실패 (${response.status}): ${url}`);
                }
                saveState();
            },
            onerror: function() {
                logMessage(`HTML 가져오기 에러: ${url}`);
            }
        });
    }

    // HTML을 테이블에 추가하는 함수
    function appendHtmlToRow(index, html) {
        const row = tbody.children[index];
        if (row) {
            const htmlCell = row.querySelector('.htmlView');
            if (htmlCell && html) {
                htmlCell.innerHTML = `<button class="viewHtmlBtn">보기</button>`;
                const viewBtn = htmlCell.querySelector('.viewHtmlBtn');
                viewBtn.addEventListener('click', () => {
                    htmlViewer.src = `data:text/html;base64,${btoa(unescape(encodeURIComponent(html)))}`;
                    htmlViewer.style.display = 'block';
                    animeViewerContainer.style.display = 'none';
                });
            }
        }
    }

    // 스크린샷 캡처 함수 (제한된 기능)
    function captureScreenshot(url) {
        // Tampermonkey는 브라우저의 스크린샷 API에 접근할 수 없습니다.
        // 대안으로, 사용자에게 스크린샷을 수동으로 캡처하도록 요청할 수 있습니다.
        logMessage(`스캔된 사이트의 스크린샷을 캡처하려면 수동으로 캡처해주세요: ${url}`);
    }

    // 결과를 UI에 표시하는 함수
    function displayResults() {
        results.forEach((result, index) => {
            if (index >= tbody.children.length) { // 새로운 결과만 추가
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${truncateText(result.name, 50)}</td>
                    <td><a href="${result.url}" target="_blank">${truncateText(result.url, 50)}</a></td>
                    <td>${truncateText(result.description, 100)}</td>
                    <td class="htmlView"></td>
                `;
                tbody.appendChild(row);
            }
        });
    }

    // 텍스트를 지정된 길이로 잘라내는 함수
    function truncateText(text, maxLength) {
        return text.length > maxLength ? text.substring(0, maxLength-3) + '...' : text;
    }

    // 페이지 로드 시 크롤링 상태 복원 및 진행
    window.addEventListener('load', () => {
        loadVisitedSites();
        loadState();
        if (isCrawling && crawlConfig.engine === currentEngine && getSearchQuery() === crawlConfig.query) {
            startBtn.disabled = true;
            stopBtn.disabled = false;
            resetBtn.disabled = false;
            toggleFeaturesBtn.disabled = true;
            toggleHtmlViewerBtn.disabled = false;
            toggleAnimeViewerBtn.disabled = false;
            statusDiv.innerHTML = `크롤링 중...`;
            updateProgress();
            crawlCurrentPage();
        } else {
            // 크롤링이 아닌 경우 상태 초기화
            if (!isCrawling) {
                statusDiv.innerHTML = `대기 중`;
                startBtn.disabled = false;
                stopBtn.disabled = true;
                toggleFeaturesBtn.disabled = false;
                toggleHtmlViewerBtn.disabled = false;
                toggleAnimeViewerBtn.disabled = false;
            }
        }
    });

    // 크롤링 상태를 저장하고 페이지를 이동할 때 호출
    function handleBeforeUnload(event) {
        if (isCrawling) {
            saveState();
        } else {
            clearState();
        }
    }

    window.addEventListener('beforeunload', handleBeforeUnload);

})();             여기에서 다음  페이지로 넘어가지 않는 현상이 발생함 이 현상을 해결 하셈 코드만 쓰셈