// ==UserScript==
// @name         141 Auto-rate and Duplicate Title Checker
// @namespace    http://tampermonkey.net/
// @version      1.31
// @description  Separate auto-rate and duplicate title checking functionalities for 141love.net
// @author       Your Name
// @match        https://141love.net/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // Function for Auto-rating Functionality
    const currentIndex = { value: 0 }; // Object to keep track of the current index of the rate button, allows pass by reference
    const maxRetries = 5; // Max retries for score input fields
    const retryDelay = 500; // Delay between retries in milliseconds

    // User-specific ratings logic
    const ratingLogic = {
        "Juven": { score1: 5, score2: 50, score4: 5 },
        "力王ER": { score1: 5, score2: 50, score4: 5 },
        // Add more usernames and ratings as needed
    };

    // Default rating if username is not found
    const defaultRating = { score1: 2, score2: 20, score4: 2 };

    // Function to update inputs and submit the rating form
    function updateInputsAndSubmit(button, retries = 0) {
        const postElement = button.closest('.plhin');
        if (!postElement) {
            console.error('Could not find the post element associated with this button.');
            return;
        }

        const score1 = document.querySelector('input#score1.px.z');
        const score2 = document.querySelector('input#score2.px.z');
        const score4 = document.querySelector('input#score4.px.z');

        const usernameElement = postElement.querySelector('div.authi a.xw1');
        const username = usernameElement ? usernameElement.innerText.trim() : '';
        let rating = ratingLogic[username] || defaultRating;

        if (score1 && score2 && score4) {
            score1.value = rating.score1;
            score2.value = rating.score2;
            score4.value = rating.score4;

            console.log(`Setting scores for user: ${username}`);

            // Simulate form submission
            const form = document.querySelector('form#rateform');
            if (form) {
                form.dispatchEvent(new Event('submit', { cancelable: true }));
            } else {
                console.error('Form not found.');
            }
        } else {
            console.error('Score input fields are missing.');
            if (retries < maxRetries) {
                console.log(`Retrying to find score inputs... (${retries + 1}/${maxRetries})`);
                setTimeout(() => updateInputsAndSubmit(button, retries + 1), retryDelay);
            } else {
                console.warn('Max retries exceeded for finding score input fields. Moving to next rate button.');
                currentIndex.value++;
                setTimeout(clickNextRateButton, 1000);
            }
        }
    }

    // Click next rate button and handle logic
    function clickNextRateButton() {
        const rateButtons = Array.from(document.querySelectorAll('a.rateb'));
        if (currentIndex.value >= rateButtons.length) {
            console.log('All replies have been rated.');
            return;
        }

        const button = rateButtons[currentIndex.value];
        const postElement = button.closest('.plhin');

        if (shouldIgnoreMessage(postElement)) {
            console.log(`Ignoring post ${currentIndex.value + 1}.`);
            currentIndex.value++;
            setTimeout(clickNextRateButton, 1000);
            return;
        }

        updateInputsAndSubmit(button);
        currentIndex.value++;

        // Schedule the next iteration after a delay
        setTimeout(clickNextRateButton, 1000);
    }

    // Function to decide if a message should be ignored
    function shouldIgnoreMessage(postElement) {
        const messageElement = postElement.querySelector('.t_f');
        const messageHTML = messageElement ? messageElement.innerHTML.trim() : '';

        // Define ignore patterns for common phrases
        const ignorePatterns = [
            /^[^\W_]{0,5}感[谢謝].*?分享(?!\s)([^\W_]{0,5}|.*)$/i,
            /^[^\W_]{0,5}多[谢謝].*?分享(?!\s)([^\W_]{0,5}|.*)$/i,
            /^[^\W_]{0,5}(多?[谢謝]{2})(?!\s)([^\W_]{0,5}|.*)$/i,
            /非常精彩/i,
            /無撚得頂/i,
            /(thx|thanks|thank\s+you)\s+for\s+sharing.*$/i,
            /(T.*?Q|thx|thanks).*$/i,
            /^[^\W_]{0,5}nice\s*([^\W_]{0,5}|.*)$/i,
            /^[^\W_]{0,5}good\s*([^\W_]{0,5}|.*)$/i,
        ];

        // Clean up message for analysis
        const cleanedMessage = messageHTML
            .replace(/<br\s*\/?>/g, ' ')           // Normalize break tags
            .replace(/<img[^>]*src="[^"]*\.gif"[^>]*>/g, ' ') // Remove GIF images
            .replace(/<img[^>]*>/g, ' ')            // Replace other images with space
            .replace(/&nbsp;/g, ' ')                // Normalize non-breaking spaces
            .replace(/\s+/g, ' ')                   // Collapse multiple spaces into a single space
            .trim();                                // Trim leading/trailing whitespace

        const hasMeaningfulContent = cleanedMessage.length > 0; // Check for meaningful content
        return !hasMeaningfulContent; // Ignore if no meaningful content
    }

    // Part 2: Duplicate Title Detection
    function checkForDuplicateTitles() {
        const titles = Array.from(document.querySelectorAll('div.bm_c tbody[id^="normalthread_"] a.s.xst'));
        const titleCounts = {};
        const duplicateTitles = [];

        titles.forEach(titleElement => {
            const title = titleElement.innerText.trim();
            titleCounts[title] = (titleCounts[title] || 0) + 1;
            if (titleCounts[title] > 1 && !duplicateTitles.includes(title)) {
                duplicateTitles.push(title);
            }
        });

        if (duplicateTitles.length > 0) {
            alert('Warning: There are duplicate thread titles on this page!');
            highlightDuplicates(duplicateTitles);
        }
    }

    // Function to highlight duplicate titles
    function highlightDuplicates(duplicateTitles) {
        const titles = document.querySelectorAll('div.bm_c tbody[id^="normalthread_"] a.s.xst');
        titles.forEach(titleElement => {
            if (duplicateTitles.includes(titleElement.innerText.trim())) {
                titleElement.style.backgroundColor = 'yellow'; // Highlight duplicate titles
            }
        });
    }

    // Function to initiate auto-rating
    function automateRating() {
        currentIndex.value = 0; // Reset the index
        clickNextRateButton(); // Start clicking buttons for auto-rating
    }

    // Function to add automation button to the UI
    function addAutomationButton(container, buttonText, styles, buttonClass) {
        if (container) {
            const autoButton = document.createElement('button');
            autoButton.innerText = buttonText;
            autoButton.onclick = automateRating;
            Object.assign(autoButton.style, styles);
            autoButton.className = buttonClass;
            container.appendChild(autoButton);
        }
    }

    // Add custom button styles
    const style = document.createElement('style');
    style.textContent = `
        .main-button {
            background-color: #FE9510;
            color: white;
            border: none;
            border-radius: 4px;
            padding: 7px 10px;
            font-size: 14.5px;
            cursor: pointer;
            margin: 0px;
            transition: background-color 0.3s, color 0.3s;
        }

        .main-button:hover {
            background-color: #E78F1B;
            color: #FFF;
        }
    `;
    document.head.appendChild(style);

    // Adding automation buttons after the page loads
    window.addEventListener('load', () => {
        if (window.location.href.includes("thread") && document.querySelector('a.rateb')) {
            // On pages with rating buttons, add auto-rate button
            addAutomationButton(document.querySelector('div#pgt.pgs.cl'), '自動評分', {}, 'main-button');
        } else if (document.querySelector('div.bm_c')) {
            // On pages with div.bm_c, perform duplicate check
            checkForDuplicateTitles();
            addAutomationButton(document.querySelector('div.bm_c'), '檢查重複標題', {}, 'main-button'); // Button for duplicate check if needed
        } else {
            console.log('Not a valid page for auto-rating or duplicate checking. Buttons will not be added.');
        }
    });
})();

Please help me extract the title duplication check section of this script and put it in a new script.