FBMP Listing Manager

The ultimate Facebook Marketplace listing deletion machine - now with AI-powered evasion and ninja-like stealth

// ==UserScript==
// @name         FBMP Listing Manager
// @namespace    http://tampermonkey.net/
// @version      3.9
// @description  The ultimate Facebook Marketplace listing deletion machine - now with AI-powered evasion and ninja-like stealth
// @author       The Phantom Deleter
// @match        https://www.facebook.com/marketplace/you/selling?order=*
// @grant        none
// @license      MIT
// ==/UserScript==

console.log("🧪 [FBMP Terminator] Script loaded.");
(function() {
    'use strict';

    // Mission Control Configuration
    const config = {
        running: false,
        cycle: 0,
        maxCycles: 50,
        coolDown: 5,
        stealthMode: true,
        aiBehavior: "random", // "random", "sold", "unsold", "no_answer"
        maxFailures: 3,
        version: "3.9"
    };

    // AI Response Bank
    const aiResponses = {
        deletion: [
            "Terminating listing with extreme prejudice",
            "Making listing disappear like magic",
            "Sending listing to the shadow realm",
            "Executing order 66 on this listing"
        ],
        failure: [
            "Target evaded deletion!",
            "The listing fought back!",
            "Mission failed, we'll get 'em next time",
            "Facebook countermeasures detected!"
        ],
        waiting: [
            "Maintaining operational security",
            "Hiding from Facebook's watchful eyes",
            "Simulating human browsing patterns",
            "Calculating next move..."
        ]
    };

    // Stealth Operations
    function getRandomDelay() {
        return config.stealthMode ?
            1000 + Math.random() * 2000 : // Random delay between 1-5s in stealth mode
        500 + Math.random() * 700; // Faster operation when stealth is off
    }

    function getAIResponse(type) {
        const responses = aiResponses[type];
        return responses[Math.floor(Math.random() * responses.length)];
    }

    // Tactical UI Elements
    function createTerminatorUI() {
        const panel = document.createElement('div');
        panel.id = 'terminator-panel';
        panel.style.cssText = `
            position: fixed;
            bottom: 10px;
            left: 10px;
            z-index: 9999;
            padding: 15px;
            background: linear-gradient(135deg, #1a1a1a 0%, #000 100%);
            border-radius: 10px;
            color: #ffffff;
            font-family: 'Courier New', monospace;
            font-size: 13px;
            border: 1px solid #00ff00;
            box-shadow: 0 0 15px rgba(0, 255, 0, 0.3);
        `;

        panel.innerHTML = `
            <h3 style="margin-top:0;border-bottom:1px solid #fff;padding-bottom:5px;color:#fff;text-align: center;">
                Listing Manager v${config.version}
            </h3>
            <div style="margin-bottom:10px;">
                <label style="color:#fff;">Listing yang dihapus: <input type="number" id="maxCycles" value="${config.maxCycles}" style="width:60px;background:#111;color:#0f0;border:1px solid #333;"></label><br>
                <label style="color:#fff;">Cool Down: <input type="number" id="coolDown" value="${config.coolDown}" style="width:60px;background:#111;color:#0f0;border:1px solid #333;">s</label><br>
                <label style="display:block;margin-top:5px;color:#fff;">
                    <input type="checkbox" id="stealthMode" ${config.stealthMode ? 'checked' : ''}> Stealth Mode
                </label>
                <select id="aiBehavior" style="margin-top:5px;background:#111;color:#0f0;border:1px solid #333;width:100%">
                    <option value="random">Random Behavior</option>
                    <option value="sold">Mark as Sold</option>
                    <option value="unsold">Mark as Unsold</option>
                    <option value="no_answer">No Answer</option>
                </select>
                    <select id="operationMode" style="margin-top:5px;background:#111;color:#0f0;border:1px solid #333;width:100%">
                    <option value="terminator">TERMINATOR MODE</option>
                    <option value="update">UPDATE MODE</option>
                    <option value="repost">REPOST MODE</option>
                </select>
            </div>
            <button id="toggleButton" style="background:linear-gradient(180deg, #00cc00 0%, #009900 100%);border:none;color:white;padding:5px 10px;border-radius:3px;cursor:pointer;font-weight:bold;">
                ▶ START
            </button>
            <div style="margin-top:10px;font-size:12px;">
                Status: <span id="statusIndicator" style="color:#ff0;">STANDBY</span>
            </div>
            <textarea id="terminator-log" rows="10" cols="35" readonly style="width:100%;resize:none;background:#111;color:#fff;border:1px solid #333;margin-top:10px;font-family:monospace;"></textarea>
        `;

        const style = document.createElement('style');
        style.textContent = `
    @keyframes pulse {
        0% { transform: scale(1); }
        50% { transform: scale(0.98); }
        100% { transform: scale(1); }
    }
`;

        document.body.appendChild(panel);

        document.getElementById('toggleButton').addEventListener('click', () => {
            config.running = !config.running;
            const status = document.getElementById('statusIndicator');
            const button = document.getElementById('toggleButton');

            if (config.running) {
                button.innerHTML = '⏹ HENTIKAN';
                button.style.background = 'linear-gradient(180deg, #ff3300 0%, #cc0000 100%)';
                status.textContent = 'ACTIVE';
                status.style.color = '#0f0';
                log('DIAKTIFKAN ULANG');

                const mode = document.getElementById('operationMode').value;
                log(`MODE: ${mode.toUpperCase()}`);

                if (mode === 'terminator') {
                    startTerminationSequence();
                } else if (mode === 'repost') {
                    startRepostSequence(); // ← pastikan kamu membuat fungsi ini
                }else if (mode === 'update') {
                    startUpdateSequence(); // ← pastikan kamu membuat fungsi ini
                }
            }else {
                button.innerHTML = '▶ START';
                button.style.background = 'linear-gradient(180deg, #00cc00 0%, #009900 100%)';
                status.textContent = 'STANDBY';
                status.style.color = '#ff0';
                log('SCRIPT DIJEDA');
            }
        });

        document.getElementById('stealthMode').addEventListener('change', (e) => {
            config.stealthMode = e.target.checked;
            log(`STEALTH MODE ${config.stealthMode ? 'ENABLED' : 'DISABLED'}`);
        });

        document.getElementById('aiBehavior').addEventListener('change', (e) => {
            config.aiBehavior = e.target.value;
            log(`AI BEHAVIOR SET TO: ${e.target.value.toUpperCase()}`);
        });

        // Perbarui coolDown secara langsung saat input berubah
        document.getElementById('coolDown').addEventListener('input', (e) => {
            const val = parseInt(e.target.value);
            if (!isNaN(val) && val > 0) {
                config.coolDown = val;
                log(`⏳ CoolDown diubah menjadi: ${val} detik`);
            }
        });

    }

    // Mission Logging System
    function log(message) {
        const logBox = document.getElementById('terminator-log');
        if (logBox) {
            const timestamp = new Date().toLocaleTimeString();
            logBox.value += `[${timestamp}] ${message}\n`;
            logBox.scrollTop = logBox.scrollHeight;
        }
    }

    async function sleep(ms) {
        for (let i = 0; i < ms; i += 200) {
            if (!config.running) throw new Error("TERMINATED");
            await new Promise(resolve => setTimeout(resolve, 200));
        }
    }

    // Tactical Element Location
    function isVisible(elem) {
        return !!(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
    }

    function humanLikeClick(elem) {
        if (!elem) return false;
        const rect = elem.getBoundingClientRect();
        const x = rect.left + rect.width / 2;
        const y = rect.top + rect.height / 2;
        const options = {
            bubbles: true,
            cancelable: true,
            composed: true,
            clientX: x,
            clientY: y,
            pointerType: 'mouse'
        };
        elem.dispatchEvent(new PointerEvent('pointerdown', options));
        elem.dispatchEvent(new PointerEvent('pointerup', options));
        elem.dispatchEvent(new PointerEvent('click', options));
        return true;
    }

    // ====== START OF startTerminationSequence() ====== //
    async function startTerminationSequence() {
        try {
            config.maxCycles = parseInt(document.getElementById("maxCycles").value) || 50;
            config.coolDown = parseInt(document.getElementById("coolDown").value) || 5;
            log("Cooldown dari input:", config.coolDown);

            log(`Memulai Urutan Penghapusan - ${config.maxCycles} TARGETS`);
            log(`STRATEGY: ${config.aiBehavior.toUpperCase()} | STEALTH: ${config.stealthMode ? 'ON' : 'OFF'}`);

            // Beralih ke Tampilan Daftar (List View)
            const listButton = [...document.querySelectorAll('div[aria-label="Tampilan Daftar"]')].find(isVisible);
            if (listButton && listButton.getAttribute('aria-pressed') === 'false') {
                humanLikeClick(listButton);
                log("📃 Beralih ke Tampilan Daftar...");
                await sleep(1000);
            }

            let consecutiveFailures = 0;

            for (config.cycle = 1; config.cycle <= config.maxCycles; config.cycle++) {
                if (!config.running) break;

                log(`MISSION ${config.cycle} OF ${config.maxCycles}`);

                // Phase 1: Engage ellipsis
                if (!await engageEllipsis()) {
                    consecutiveFailures++;
                    log(`WARNING: TARGET MENGHINDAR (${consecutiveFailures}/${config.maxFailures})`);

                    if (consecutiveFailures >= config.maxFailures) {
                        log("CRITICAL FAILURE - MEMULAI PENGELAKAN");
                        window.location.href = "/marketplace/you/selling";
                        return;
                    }
                    continue;
                } else {
                    consecutiveFailures = 0;
                }

                await sleep(500);

                // Phase 2: Engage deletion
                if (!await engageElement("Hapus tawaran")) {
                    log("DIHENTIKAN - TARGET TERTUTUP");
                    continue;
                }

                await sleep(500);

                // Phase 3: Confirm deletion
                if (!await engageDeleteConfirmation("Hapus")) {
                    log("KONFIRMASI GAGAL - MUNGKIN MASIH AKTIF");
                    continue;
                }

                // Phase 4: AI Reason Step (conditional)
                await sleep(300);
                const reasonExists = Array.from(document.querySelectorAll('span'))
                .some(span => ["Ya, terjual di Facebook", "Ya, terjual di tempat lain", "Tidak, belum terjual", "Memilih tidak menjawab"]
                      .includes(span.textContent.trim()));

                if (reasonExists) {
                    const responseText = getStrategicResponse();
                    await engageElement(responseText);
                    await engageElement("Berikutnya");
                } else {
                    const nextBtn = Array.from(document.querySelectorAll('span'))
                    .find(span => span.textContent.trim() === "Berikutnya" && isVisible(span));

                    if (nextBtn) {
                        executeClick(nextBtn);
                        log("KONFIRMASI : TERHAPUS");
                        await sleep(getRandomDelay());
                    } else {
                        log("⚠️ Tidak ada alasan penawaran. Menganggap listing sudah dihapus.");
                    }
                }

                await sleep(1000);

                // Phase 5: AI Response (lagi, jika muncul ulang)
                const responseText = getStrategicResponse();
                if (await engageElement(responseText)) {
                    await engageElement("Berikutnya");
                } else {
                    const confirmBtn = Array.from(document.querySelectorAll('span'))
                    .find(span => span.textContent.trim() === "Berikutnya" && isVisible(span));

                    if (confirmBtn) {
                        executeClick(confirmBtn);
                        log("KONFIRMASI : TERHAPUS");
                        await sleep(getRandomDelay());
                    }
                }

                // Cool down period
                const waitingMsg = getAIResponse('waiting');
                log(`${waitingMsg} (${config.coolDown} detik)...`);
                for (let s = 1; s <= config.coolDown; s++) {
                    if (!config.running) {
                        log("🛑 PROSES Dihentikan oleh pengguna.");
                        return;
                    }
                    log(`🕒 ${s}`);
                    await sleep(1000);
                }
            }

            log("PROSES HAPUS BERHASIL");
            //        log("ALL TARGETS NEUTRALIZED OR MISSION ABORTED");
        } catch (e) {
            if (e.message === "TERMINATED") {
                log("🛑 PROSES DIHENTIKAN LANGSUNG OLEH PENGGUNA");
            } else {
                log(`❌ ERROR: ${e.message}`);
            }
        }
    }

    // ====== HELPER FUNCTIONS startTerminationSequence() ====== //

    function findZeroClickListingButton() {
        // Temukan semua elemen yang berisi teks "0 klik tawaran"
        const zeroClickElements = Array.from(document.querySelectorAll("div.x78zum5.x1q0g3np.xg7h5cd"))
        .filter(el => el.textContent.includes("0 klik tawaran"));

        for (const el of zeroClickElements) {
            // Naik ke atas sampai container listing
            let current = el;
            for (let i = 0; i < 10; i++) {
                if (!current) break;
                if (current.querySelector("div[aria-label^='Opsi lainnya untuk']")) {
                    const ellipsisBtn = current.querySelector("div[aria-label^='Opsi lainnya untuk']");
                    if (ellipsisBtn) return ellipsisBtn;
                }
                current = current.parentElement;
            }
        }
        // Jika tidak ada tombol ⋯ ditemukan dalam listing dengan 0 klik tawaran
        return null;
    }

    // Advanced Click Simulation
    function executeClick(elem) {
        if (!elem) return false;

        const rect = elem.getBoundingClientRect();
        const mouseEventInit = {
            bubbles: true,
            cancelable: true,
            view: window,
            clientX: rect.left + rect.width/2,
            clientY: rect.top + rect.height/2
        };

        ['mousedown', 'mouseup', 'click'].forEach(type => {
            elem.dispatchEvent(new MouseEvent(type, mouseEventInit));
        });

        return true;
    }

    async function engageDeleteConfirmation() {
        // Cari semua tombol "Hapus" yang terlihat
        const candidates = Array.from(document.querySelectorAll('div[role="dialog"] span'))
        .filter(span => span.textContent.trim() === "Hapus" && isVisible(span));

        if (candidates.length === 0) {
            log("❌ Tidak menemukan tombol 'Hapus' di dalam dialog.");
            return false;
        }

        // Ambil yang paling bawah (biasanya tombol konfirmasi biru)
        const button = candidates[candidates.length - 1];
        button.scrollIntoView({ behavior: "smooth", block: "center" });
        await sleep(getRandomDelay());
        executeClick(button);
        log(`🧨 Konfirmasi 'Hapus' dieksekusi.`);
        await sleep(1000);
        return true;
    }

    // Strategic Element Engagement
    async function engageElement(text, tag = 'span') {
        const elements = Array.from(document.querySelectorAll(tag));
        const lowerText = text.toLowerCase();

        const target = elements.find(el => {
            const match = el.textContent.trim().toLowerCase() === lowerText;
            const visible = isVisible(el);
            return match && visible;
        });

        if (target) {
            target.scrollIntoView({ behavior: "smooth", block: "center" });
            await sleep(getRandomDelay());
            executeClick(target);
            log(`${getAIResponse('deletion')}: "${text}"`);
            await sleep(getRandomDelay());
            return true;
        } else {
            log(`${getAIResponse('failure')} - Target tidak ditemukan: "${text}"`);
            return false;
        }
    }

    // Special Ops: Ellipsis Engagement
    async function engageEllipsis() {
        const target = findZeroClickListingButton();
        if (!target) {
            log("❌ Tidak ada listing dengan '0 klik tawaran' ditemukan.");
            return false;
        }

        target.scrollIntoView({ behavior: "smooth", block: "center" });
        await sleep(1000);
        executeClick(target);
        log("🎯 Target '0 klik tawaran' ditemukan dan diserang.");
        await sleep(getRandomDelay());
        return true;
    }

    // AI-Powered Response Selection
    function getStrategicResponse() {
        switch(config.aiBehavior) {
            case "sold":
                return Math.random() > 0.5 ? "Ya, terjual di Facebook" : "Ya, terjual di tempat lain";
            case "unsold":
                return "Tidak, belum terjual";
            case "no_answer":
                return "Memilih tidak menjawab";
            default:{
                const options = [
                    "Memilih tidak menjawab",
                    "Ya, terjual di Facebook",
                    "Ya, terjual di tempat lain",
                    "Tidak, belum terjual",
                ];
                return options[Math.floor(Math.random() * options.length)];
            }
        }
    }

    // ====== END OF startTerminationSequence() ====== //

    // ====== START OF startRepostSequence() ====== //
    async function startRepostSequence() {
        try {
            log("🔄 MEMULAI REPOST SEQUENCE - Mencari listing dengan 'Hapus & Tawarkan Ulang'");

            // Switch to list view for better scanning
            if (!(await switchToListViewRepost())) {
                log("⚠️ Gagal beralih ke tampilan daftar, melanjutkan dengan tampilan saat ini");
            }

            let totalProcessed = 0;
            let scrollAttempts = 0;
            const maxScrollAttempts = 50;
            let consecutiveFails = 0;
            const maxConsecutiveFails = 5;
            let lastButtonCount = 0;
            let sameButtonCountOccurrences = 0;

            // Initial load wait
            await sleep(5000);

            while (scrollAttempts < maxScrollAttempts && consecutiveFails < maxConsecutiveFails) {
                // Find all unprocessed buttons with fresh scan
                const allButtons = await comprehensiveButtonScanRepost();
                const unprocessedButtons = allButtons.filter(btn =>
                                                             isVisibleRepost(btn) &&
                                                             isClickableRepost(btn) &&
                                                             !btn.hasAttribute('data-processed')
                                                            );

                // Check if we're seeing the same number of buttons repeatedly (possible infinite loop)
                if (unprocessedButtons.length === lastButtonCount) {
                    sameButtonCountOccurrences++;
                    if (sameButtonCountOccurrences > 3) {
                        log("⚠️ Deteksi kemungkinan infinite loop, melakukan reset...");
                        sameButtonCountOccurrences = 0;
                        await reloadPage();
                        continue;
                    }
                } else {
                    sameButtonCountOccurrences = 0;
                    lastButtonCount = unprocessedButtons.length;
                }

                if (unprocessedButtons.length === 0) {
                    log(`ℹ️ Tidak menemukan tombol baru (scroll ${scrollAttempts + 1}/${maxScrollAttempts})`);

                    // Special handling when no buttons found
                    if (totalProcessed === 0 && scrollAttempts > 10) {
                        log("⚠️ Tidak menemukan tombol sama sekali setelah beberapa scroll");
                        break;
                    }

                    let prevListingCount = await countListingsRepost();
                    await aggressiveScrollRepost();
                    await sleep(1000); // beri waktu loading
                    let newListingCount = await countListingsRepost();

                    if (newListingCount > prevListingCount) {
                        log(`📈 Ditemukan ${newListingCount - prevListingCount} listing baru setelah scroll`);
                        continue; // skip ke atas untuk scan ulang
                    } else {
                        log("📉 Tidak ada listing baru setelah scroll");
                    }

//                    await aggressiveScrollRepost();
//                    scrollAttempts++;
//                    consecutiveFails++;
//                    await sleep(4000);
//                    continue;
                }

                log(`🔍 Ditemukan ${unprocessedButtons.length} tombol aktif yang belum diproses`);
                consecutiveFails = 0; // Reset fail counter

                // Process all unprocessed buttons in this batch
                for (let i = 0; i < unprocessedButtons.length; i++) {
                    const button = unprocessedButtons[i];

                    // Verify button still exists and is clickable
                    if (!document.contains(button) || !isClickableRepost(button)) {
                        log("ℹ️ Tombol tidak valid lagi, melanjutkan...");
                        continue;
                    }

                    const listing = findParentListingRepost(button);

                    if (!listing) {
                        log("⚠️ Tidak dapat menemukan parent listing, menandai tombol sebagai gagal");
                        button.setAttribute('data-processed', 'failed');
                        continue;
                    }

                    log(`🔄 Memproses listing ${totalProcessed + 1}`);
                    highlightButtonRepost(button, 'processing');

                    // More robust clicking with multiple fallbacks
                    const success = await robustButtonClickRepost(button, listing);

                    if (success) {
                        totalProcessed++;
                        highlightButtonRepost(button, 'success');
                        // More permanent marking of processed buttons
                        button.setAttribute('data-processed', 'true');
                        button.setAttribute('data-processed-time', Date.now());
                        log(`✅ Berhasil memproses (Total: ${totalProcessed})`);

                        // After successful processing, check if listing disappeared
                        if (!document.contains(listing)) {
                            log("ℹ️ Listing menghilang setelah diproses");
                        }
                    } else {
                        highlightButtonRepost(button, 'failed');
                        button.setAttribute('data-processed', 'failed');
                        log("⚠️ Gagal memproses tombol ini");
                    }

                    // Randomized delay between buttons (1-4 seconds)
                    await sleep(1000 + Math.random() * 3000);
                }
                await sleep(2000);
                // Final verification scan
                const remainingButtons = (await comprehensiveButtonScanRepost()).filter(btn =>
                                                                                        isVisibleRepost(btn) &&
                                                                                        isClickableRepost(btn) &&
                                                                                        !btn.hasAttribute('data-processed')
                                                                                       );

                if (remainingButtons.length > 0) {
                    log(`ℹ️ Masih ada ${remainingButtons.length} tombol yang belum diproses`);

                    // More aggressive scroll if we still have unprocessed buttons
                    await aggressiveScrollRepost();
                    scrollAttempts++;
                    await sleep(3000);
                } else {
                    log("✔️ Semua tombol telah diproses");
                    break;
                }
            }

            log(`🎉 Selesai! Total tombol berhasil diklik: ${totalProcessed}`);

        } catch (e) {
            log(`❌ ERROR: ${e.message}`);
            console.error(e);
        }
    }

    // ====== HELPER FUNCTIONS startRepostSequence() ====== //

    async function reloadPage() {
        log("🔄 Memuat ulang halaman...");
        window.scrollTo(0, 0);
        await sleep(2000);
        window.location.reload();
    }

    async function robustButtonClickRepost(button, listing) {
        try {
            // Double-check button state
            if (!isVisibleRepost(button) || !isClickableRepost(button)) {
                return false;
            }

            // Store initial state
            const initialButtonState = isClickableRepost(button);
            const initialListingExists = document.contains(listing);
            const initialButtonText = button.textContent;
            const initialButtonHTML = button.outerHTML;

            // Scroll to button with offset to account for headers
            const yOffset = -100; // Adjust for fixed headers
            const buttonRect = button.getBoundingClientRect();
            window.scrollTo({
                top: window.scrollY + buttonRect.top + yOffset,
                behavior: 'smooth'
            });
            await sleep(800);

            // Try multiple click methods with visual feedback
            const clickMethods = [
                () => {
                    button.style.transform = 'scale(0.98)';
                    button.click();
                },
                () => humanLikeClickRepost(button),
                () => simulateMouseClickRepost(button),
                () => {
                    const rect = button.getBoundingClientRect();
                    const clickEvent = new MouseEvent('click', {
                        bubbles: true,
                        cancelable: true,
                        clientX: rect.left + rect.width/2,
                        clientY: rect.top + rect.height/2
                    });
                    button.dispatchEvent(clickEvent);
                }
            ];

            let clickSuccess = false;
            for (const method of clickMethods) {
                if (clickSuccess) break;
                try {
                    method();
                    await sleep(300 + Math.random() * 700); // Vary delay between attempts

                    // Immediate verification
                    if (verifyClickSuccessRepost(button, listing, initialButtonState, initialListingExists, initialButtonText)) {
                        clickSuccess = true;
                        break;
                    }
                } catch (e) {
                    console.log(`Click method failed: ${e.message}`);
                }
            }

            // Reset button style
            button.style.transform = '';

            if (!clickSuccess) return false;

            // Progressive verification with multiple checks
            const verificationChecks = [
                // Immediate check
                () => verifyClickSuccessRepost(button, listing, initialButtonState, initialListingExists, initialButtonText),
                // Delayed check
                async () => {
                    await sleep(1500);
                    return verifyClickSuccessRepost(button, listing, initialButtonState, initialListingExists, initialButtonText);
                },
                // DOM change check
                () => button.outerHTML !== initialButtonHTML
            ];

            for (const check of verificationChecks) {
                if (await check()) {
                    return true;
                }
            }

            return false;

        } catch (e) {
            log(`⚠️ Click error: ${e.message}`);
            return false;
        }
    }

    function verifyClickSuccessRepost(button, listing, initialButtonState, initialListingExists, initialButtonText) {
        return (
            (initialButtonState && !isClickableRepost(button)) ||
            (initialListingExists && !document.contains(listing)) ||
            (button.textContent !== initialButtonText) ||
            (window.getComputedStyle(button).opacity < 0.5) ||
            (button.getAttribute('aria-disabled') === 'true')
        );
    }

    async function aggressiveScrollRepost() {
        // Scroll further than viewport height to ensure loading
        const scrollDistance = window.innerHeight * 2;
        window.scrollBy({
            top: scrollDistance,
            behavior: 'smooth'
        });

        // Additional micro-scrolls to trigger loading
        await sleep(1000);
        window.scrollBy(0, 300);
        await sleep(500);
        window.scrollBy(0, 100);
    }

    async function comprehensiveButtonScanRepost() {
        const scanMethods = [
            () => document.querySelectorAll('div[aria-label="Hapus & Tawarkan Ulang"]'),
            () => document.querySelectorAll('span:contains("Hapus & Tawarkan Ulang")'),
            () => {
                const xpath = "//*[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'hapus & tawarkan ulang')]";
                const result = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
                const elements = [];
                for (let i = 0; i < result.snapshotLength; i++) {
                    elements.push(result.snapshotItem(i));
                }
                return elements;
            },
            () => document.querySelectorAll('div.x1i10hfl.xjbqb8w.x6umtig') // Common FB button class
        ];

        const allButtons = new Set();
        const now = Date.now();

        for (const method of scanMethods) {
            try {
                const buttons = method();
                for (const btn of buttons) {
                    try {
                        // Skip buttons processed in the last 5 minutes to handle Facebook re-rendering
                        const processedTime = btn.getAttribute('data-processed-time');
                        if (processedTime && (now - parseInt(processedTime)) < 300000) {
                            continue;
                        }

                        if (btn.textContent &&
                            btn.textContent.toLowerCase().includes('hapus') &&
                            btn.textContent.toLowerCase().includes('tawarkan ulang')) {
                            allButtons.add(btn);
                        }
                    } catch (e) {
                        console.log('Error processing button:', e);
                    }
                }
            } catch (e) {
                console.log(`Scan method error: ${e.message}`);
            }
        }

        return Array.from(allButtons);
    }

    async function xpathFindButtonsRepost() {
        const buttons = [];
        const xpathResult = document.evaluate(
            "//*[contains(text(), 'Hapus & Tawarkan Ulang')]",
            document,
            null,
            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
            null
        );

        for (let i = 0; i < xpathResult.snapshotLength; i++) {
            const element = xpathResult.snapshotItem(i);
            if (isVisibleRepost(element) && isClickableRepost(element)) {
                buttons.push(element);
            }
        }

        return buttons;
    }

    async function scrollToVeryBottomRepost() {
        const startPosition = window.pageYOffset;
        window.scrollTo({
            top: document.body.scrollHeight,
            behavior: 'smooth'
        });
        await sleep(3000);

        // Additional check to ensure we're not stuck
        if (window.pageYOffset <= startPosition + 500) {
            log("⚠️ Scroll tidak berpengaruh, mencoba alternatif...");
            // Alternative scroll method
            for (let i = 0; i < 5; i++) {
                window.scrollBy(0, window.innerHeight * 2);
                await sleep(1000);
            }
        }
    }

    function simulateMouseClickRepost(element) {
        if (!element || !isVisibleRepost(element)) return false;

        try {
            const rect = element.getBoundingClientRect();
            const mouseEventInit = {
                bubbles: true,
                cancelable: true,
                view: window,
                clientX: rect.left + rect.width/2,
                clientY: rect.top + rect.height/2
            };

            ['mouseover', 'mousedown', 'mouseup', 'click'].forEach(type => {
                element.dispatchEvent(new MouseEvent(type, mouseEventInit));
            });
            return true;
        } catch (e) {
            console.error('Mouse simulation failed:', e);
            return false;
        }
    }

    function hasVisualChangeRepost(element) {
        if (!element) return false;

        try {
            // Store current visual properties
            const currentStyle = window.getComputedStyle(element);
            const currentProps = {
                backgroundColor: currentStyle.backgroundColor,
                borderColor: currentStyle.borderColor,
                color: currentStyle.color,
                opacity: currentStyle.opacity
            };

            // Wait briefly for potential changes
            return new Promise(resolve => {
                setTimeout(() => {
                    const newStyle = window.getComputedStyle(element);
                    const changed = (
                        newStyle.backgroundColor !== currentProps.backgroundColor ||
                        newStyle.borderColor !== currentProps.borderColor ||
                        newStyle.color !== currentProps.color ||
                        newStyle.opacity !== currentProps.opacity
                    );
                    resolve(changed);
                }, 500);
            });
        } catch (e) {
            console.error('Visual change check failed:', e);
            return false;
        }
    }

    async function findRepostButtonsDeepScanRepost() {
        // Try multiple scanning methods
        const buttons = [];

        // Method 1: Standard selector search
        buttons.push(...await findClickableRepostButtons());

        // Method 2: Visual scanning for button text
        if (buttons.length < 5) {
            buttons.push(...await visualScanForButtonsRepost());
        }

        // Method 3: XPath search as fallback
        if (buttons.length < 5) {
            buttons.push(...await xpathFindButtonsRepost());
        }

        // Filter out duplicates and failed buttons
        const uniqueButtons = [];
        const seen = new Set();

        for (const button of buttons) {
            if (!seen.has(button) &&
                isVisibleRepost(button) &&
                isClickableRepost(button) &&
                !button.hasAttribute('data-processed')) {
                seen.add(button);
                uniqueButtons.push(button);
            }
        }

        return uniqueButtons;
    }

    async function visualScanForButtonsRepost() {
        const buttons = [];
        const textNodes = document.evaluate(
            "//text()[contains(., 'Hapus') and contains(., 'Tawarkan Ulang')]",
            document,
            null,
            XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
            null
        );

        for (let i = 0; i < textNodes.snapshotLength; i++) {
            const node = textNodes.snapshotItem(i);
            let element = node.parentElement;

            // Walk up the DOM to find clickable container
            while (element && element !== document.body) {
                if (element.getAttribute('role') === 'button' ||
                    element.tagName === 'BUTTON' ||
                    element.onclick) {
                    buttons.push(element);
                    break;
                }
                element = element.parentElement;
            }
        }

        return buttons.filter(btn => isVisibleRepost(btn) && isClickableRepost(btn));
    }

    async function enhancedClickAndVerifyRepost(button, listing) {
        try {
            // Store initial state
            const initialHtml = listing.innerHTML;
            const initialButtonText = button.textContent;

            // Scroll to center the button
            button.scrollIntoView({ behavior: 'smooth', block: 'center' });
            await sleep(800);

            // Try different click methods
            const clickMethods = [
                () => button.click(),
                () => humanLikeClickRepost(button),
                () => simulateMouseClickRepost(button)
            ];

            let clickSuccess = false;
            for (const method of clickMethods) {
                try {
                    method();
                    clickSuccess = true;
                    break;
                } catch (e) {
                    console.log(`Click method failed: ${e.message}`);
                }
            }

            if (!clickSuccess) return false;

            // Wait for changes
            await sleep(2000);

            // Verification methods
            const verificationChecks = [
                // Button became disabled
                !isClickableRepost(button),
                // Listing disappeared
                !document.contains(listing),
                // Listing HTML changed significantly
                listing.innerHTML !== initialHtml,
                // Button text changed
                button.textContent !== initialButtonText,
                // Button visually changed (color, etc)
                hasVisualChangeRepost(button)
            ];

            return verificationChecks.some(check => check);
        } catch (e) {
            log(`⚠️ Verification error: ${e.message}`);
            return false;
        }
    }

    // Modified smart scroll to be more aggressive when needed
    async function smartScrollRepost(processedCount, scrollAttempts) {
        // Base scroll distance
        let scrollDistance = window.innerHeight * 1.8; // Increased from 1.5

        // Increase scroll distance based on progress
        if (processedCount > 15) scrollDistance *= 1.3;
        if (scrollAttempts > 8) scrollDistance *= 1.5;

        // Add random variation
        scrollDistance *= 0.9 + Math.random() * 0.2;

        window.scrollBy({
            top: scrollDistance,
            behavior: 'smooth'
        });

        // Additional micro-scrolls with random delays
        await sleep(800 + Math.random() * 1000);
        window.scrollBy(0, 200 + Math.random() * 100);
        await sleep(400 + Math.random() * 500);
        window.scrollBy(0, 50 + Math.random() * 50);
    }

    // Enhanced button highlighting
    function highlightButtonRepost(button, state) {
        const colors = {
            processing: 'hsl(30, 100%, 50%)', // Orange
            success: 'hsl(120, 100%, 40%)', // Green
            failed: 'hsl(0, 100%, 45%)' // Red
        };

        button.style.border = `2px solid ${colors[state]}`;
        button.style.borderRadius = '6px';
        button.style.transition = 'all 0.3s ease';
        button.style.padding = '2px';

        if (state === 'processing') {
            button.style.boxShadow = '0 0 0 3px rgba(255,165,0,0.3)';
            button.style.animation = 'pulse 0.5s 2';
        } else {
            button.style.boxShadow = 'none';
            button.style.animation = 'none';
        }

        // Create temporary highlight effect
        const highlight = document.createElement('div');
        highlight.style.position = 'absolute';
        highlight.style.backgroundColor = state === 'success' ? 'rgba(76, 175, 80, 0.2)' :
        state === 'failed' ? 'rgba(244, 67, 54, 0.2)' :
        'rgba(255, 165, 0, 0.2)';
        highlight.style.borderRadius = 'inherit';
        highlight.style.inset = '0';
        highlight.style.pointerEvents = 'none';
        highlight.style.zIndex = '9999';

        button.style.position = 'relative';
        button.appendChild(highlight);

        setTimeout(() => {
            highlight.style.opacity = '0';
            highlight.style.transition = 'opacity 0.5s';
            setTimeout(() => {
                button.removeChild(highlight);
                button.style.border = '';
                button.style.borderRadius = '';
                button.style.padding = '';
            }, 500);
        }, 1000);
    }
    // ======== ESSENTIAL HELPER FUNCTIONS ======== //

    async function switchToListViewRepost() {
        try {
            const listButton = [...document.querySelectorAll('div[aria-label="Tampilan Daftar"]')]
            .find(btn => isVisibleRepost(btn) && btn.getAttribute('aria-pressed') === 'false');

            if (listButton) {
                humanLikeClickRepost(listButton);
                log("📃 Beralih ke Tampilan Daftar...");
                await sleep(2000);
                return true;
            }
            return false;
        } catch (e) {
            log(`⚠️ Gagal beralih ke tampilan daftar: ${e.message}`);
            return false;
        }
    }

    async function clickAndVerifyRepost(button, listing) {
        try {
            // Scroll to ensure visibility
            if (listing && listing.scrollIntoView) {
                listing.scrollIntoView({ behavior: 'auto', block: 'center' });
                await sleep(800);
            }

            // Store initial state
            const initialButtonState = isClickableRepost(button);
            const initialListingExists = document.contains(listing);
            const initialButtonText = button.textContent;

            // Perform click
            let clickSuccess = false;
            try {
                if (typeof button.click === 'function') {
                    button.click();
                    clickSuccess = true;
                } else if (humanLikeClickRepost(button)) {
                    clickSuccess = true;
                } else if (executeClickRepost(button)) {
                    clickSuccess = true;
                }
            } catch (e) {
                log(`⚠️ Click error: ${e.message}`);
            }

            await sleep(1500);

            // Verification
            const isSuccessful =
                  (initialButtonState && !isClickableRepost(button)) ||
                  (initialListingExists && !document.contains(listing)) ||
                  (initialButtonText !== button.textContent);

            return clickSuccess && isSuccessful;
        } catch (e) {
            log(`⚠️ Verification error: ${e.message}`);
            return false;
        }
    }

    function isVisibleRepost(elem) {
        if (!elem) return false;
        const style = window.getComputedStyle(elem);
        return style.display !== 'none' &&
            style.visibility !== 'hidden' &&
            elem.offsetWidth > 0 &&
            elem.offsetHeight > 0 &&
            elem.getClientRects().length;
    }

    function isClickableRepost(element) {
        if (!element || !isVisibleRepost(element)) return false;
        try {
            const style = window.getComputedStyle(element);
            return !(style.pointerEvents === 'none' ||
                     style.cursor === 'not-allowed' ||
                     parseFloat(style.opacity) < 0.6 ||
                     element.disabled);
        } catch (e) {
            console.log('Error checking clickable:', e);
            return false;
        }
    }

    // ======== OTHER REQUIRED FUNCTIONS ======== //

    function humanLikeClickRepost(elem) {
        if (!elem) return false;
        const rect = elem.getBoundingClientRect();
        const x = rect.left + rect.width/2;
        const y = rect.top + rect.height/2;

        const events = [
            new MouseEvent('mouseover', { bubbles: true }),
            new MouseEvent('mousedown', { bubbles: true }),
            new MouseEvent('mouseup', { bubbles: true }),
            new MouseEvent('click', { bubbles: true })
        ];

        events.forEach(evt => {
            elem.dispatchEvent(evt);
        });

        return true;
    }

    function executeClickRepost(elem) {
        if (!elem) return false;
        const rect = elem.getBoundingClientRect();
        const mouseEventInit = {
            bubbles: true,
            cancelable: true,
            view: window,
            clientX: rect.left + rect.width/2,
            clientY: rect.top + rect.height/2
        };

        ['mousedown', 'mouseup', 'click'].forEach(type => {
            elem.dispatchEvent(new MouseEvent(type, mouseEventInit));
        });
        return true;
    }

    async function findRepostButtonsWithRetry() {
        let buttons = [];
        let attempts = 0;
        while (attempts < 3 && buttons.length === 0) {
            buttons = await findClickableRepostButtons();
            if (buttons.length > 0) break;
            attempts++;
            await sleep(1000);
        }
        return buttons;
    }

    async function findClickableRepostButtons() {
        const selectors = [
            'div[aria-label="Hapus & Tawarkan Ulang"]',
            'span[dir="auto"]',
            'div.x1i10hfl.xjbqb8w.x6umtig'
        ];

        const allButtons = [];
        for (const selector of selectors) {
            try {
                const buttons = Array.from(document.querySelectorAll(selector))
                .filter(btn => {
                    if (!isVisibleRepost(btn)) return false;
                    const text = btn.textContent?.trim() || '';
                    if (!text.includes("Hapus") || !text.includes("Tawarkan Ulang")) return false;
                    return isClickableRepost(btn);
                });
                allButtons.push(...buttons);
            } catch (e) {
                console.log(`Selector error: ${e.message}`);
            }
        }
        return [...new Set(allButtons)];
    }

    async function scrollDownRepost() {
        window.scrollBy({
            top: window.innerHeight * 1.5,
            behavior: 'smooth'
        });
        await sleep(1000);
        window.scrollBy(0, 100);
    }

    async function countListingsRepost() {
        const selectors = [
            '[data-testid="marketplace_your_listing_card"]',
            'div.x1lliihq.x1n2onr6.x1jchvi3',
            'div[role="article"]'
        ];
        for (const selector of selectors) {
            const listings = document.querySelectorAll(selector);
            if (listings.length > 0) return listings.length;
        }
        return 0;
    }

    function findParentListingRepost(element) {
        const selectors = [
            'div[data-testid="marketplace_your_listing_card"]',
            'div.x1lliihq.x1n2onr6.x1jchvi3',
            'div[role="article"]',
            'div.x1qjc9v5.x78zum5.x1q0g3np.x1a02dak.x1qughib'
        ];
        for (const selector of selectors) {
            const parent = element.closest(selector);
            if (parent) return parent;
        }
        return element.closest('div[role="button"]') ||
            element.closest('a[href*="/marketplace/item/"]');
    }

    // ====== END OF startRepostSequence() ====== //

    // ====== START OF startUpdateSequence() ====== //
    async function startUpdateSequence() {
        try {
            log("🔄 MEMULAI UPDATE MODE - Memindai dan memperbarui listing...");

            // Verify correct page
            if (!window.location.href.includes('/marketplace/you/selling')) {
                window.location.href = 'https://www.facebook.com/marketplace/you/selling?order=CREATION_TIMESTAMP';
                await sleep(3000);
                return;
            }

            // Switch to grid view
            const gridButton = [...document.querySelectorAll('div[aria-label="Tampilan Kisi"]')].find(isVisibleUpdate);
            if (gridButton && gridButton.getAttribute('aria-pressed') === 'false') {
                humanLikeClickUpdate(gridButton);
                log("Beralih ke Tampilan Kisi...");
                await sleep(1000);
            }

            let totalProcessed = 0;
            let scrollAttempts = 0;
            const maxScrollAttempts = 50;
            let consecutiveFails = 0;
            const maxConsecutiveFails = 5;

            // Main processing loop
            while (scrollAttempts < maxScrollAttempts && consecutiveFails < maxConsecutiveFails) {
                // Find listings with tips text
                const listingsWithTips = await findListingsWithTipsText();

                if (listingsWithTips.length === 0) {
                    log(`ℹ️ Tidak menemukan listing dengan tips (scroll ${scrollAttempts + 1}/${maxScrollAttempts})`);

                    if (totalProcessed === 0 && scrollAttempts > 10) {
                        log("⚠️ Tidak menemukan listing dengan tips sama sekali");
                        break;
                    }

                    await smartScrollUpdate();
                    scrollAttempts++;
                    consecutiveFails++;
                    await sleep(3000);
                    continue;
                }

                log(`🔍 Ditemukan ${listingsWithTips.length} listing dengan tips`);
                consecutiveFails = 0;

                // Process each listing
                for (let i = 0; i < listingsWithTips.length; i++) {
                    const listing = listingsWithTips[i];
                   log(`🔄 Memproses listing (${totalProcessed + 1}${listingsWithTips.length})`);
                   // log(`🔄 Memproses listing ${totalProcessed + 1}/${listingsWithTips.length}`);

                    try {
                        const success = await processListing(listing);

                        if (success) {
                            totalProcessed++;
                            log(`✅ Berhasil memproses (Total: ${totalProcessed}/${listingsWithTips.length})`);
                        } else {
                            log("⚠️ Gagal memproses listing ini");
                        }
                    } catch (e) {
                        log(`❌ Error: ${e.message}`);
                    }

                    await sleep(500 + Math.random() * 2000);
                }

                await sleep(1000);
            }

            log(`🎉 Selesai! Total listing berhasil diperbarui: ${totalProcessed}`);
        } catch (e) {
            log(`❌ FATAL ERROR: ${e.message}`);
        }
    }

    // ====== MISSING FUNCTION NOW INCLUDED ====== //

    async function findListingsWithTipsText() {
        // Find all elements containing the tips text
        const tipElements = Array.from(document.querySelectorAll('div'))
        .filter(div => div.textContent.includes("Tips: Perbarui tawaran Anda?") && isVisibleUpdate(div));

        // Get unique parent listings
        const listings = [];
        const seen = new Set();

        for (const tipElement of tipElements) {
            const listing = findParentListingUpdate(tipElement);
            if (listing && !seen.has(listing) && !listing.hasAttribute('data-processed')) {
                seen.add(listing);
                listings.push(listing);
            }
        }

        return listings;
    }

    async function processListing(listing) {
        try {
            // 1. Highlight and scroll to listing
            highlightListingUpdate(listing, 'processing');
            listing.scrollIntoView({ behavior: 'smooth', block: 'center' });
            await sleep(1000);

            // 2. Click to open listing
//            const listingLink = listing.querySelector('a[href*="/marketplace/item/"]') ||
//                  listing.querySelector('div[role="button"]');
 //           if (!listingLink) {
//                throw new Error("Tidak bisa menemukan link listing");
//            }

            const mainDiv = listing.querySelector('div[role="button"]') ||
                  listing.querySelector('a[href*="/marketplace/item/"]');
            if (!mainDiv || !isVisibleUpdate(mainDiv)) {
                log("⚠️ Gagal menemukan area yang bisa diklik pada listing");
                return false;
            }

            humanLikeClickUpdate(mainDiv);
            log("Mencoba membuka listing...");
            await sleep(3000);

            // 3. Find and click update button
            const updateBtn = await findAndClickUpdateButton();
            await sleep(1000);
            if (!updateBtn) {
                throw new Error("Tombol update tidak ditemukan");
            }
            await sleep(1000);

            // 4. Close dialog if still open
            closeAllDialogs();

            highlightListingUpdate(listing, 'success');
            listing.setAttribute('data-processed', 'true');
            return true;
        } catch (e) {
            highlightListingUpdate(listing, 'failed');
            closeAllDialogs();
            throw e;
        }
    }

    async function findAndClickUpdateButton() {
        // Try multiple ways to find the update button
        const updateBtn = [...document.querySelectorAll('div[aria-label="Perbarui penawaran"]')]
        .find(isVisibleUpdate);
        if (updateBtn) {
         //   let success = false;
            humanLikeClickUpdate(updateBtn);
            log("✅ Berhasil klik 'Perbarui penawaran'");
            await sleep(500);
            return true;
        } else {
            log("⚠️ Gagal menemukan tombol perbarui setelah membuka listing");
            return false;
        }
    }

    function closeAllDialogs() {
        const closeBtns = [...document.querySelectorAll('div[aria-label="Tutup"], svg[aria-label="Tutup"]')];
        closeBtns.forEach(btn => {
            if (isVisibleUpdate(btn)) humanLikeClickUpdate(btn);
        });
    }

    async function smartScrollUpdate() {
        window.scrollBy({
            top: window.innerHeight * 1.5,
            behavior: 'smooth'
        });
        await sleep(1000);
        window.scrollBy(0, 200);
    }

   function findParentListingUpdate(element) {
    const selectors = [
        'div[data-testid="marketplace_your_listing_card"]',
        'div.x1lliihq.x1n2onr6.x1jchvi3',
        'div.x9f619.x78zum5.x1r8uery',
        'div[role="article"]',
        'div.x1qjc9v5.x78zum5.x1q0g3np.x1a02dak.x1qughib'
    ];

    for (const selector of selectors) {
        const parent = element.closest(selector);
        if (parent) return parent;
    }
    return element.closest('div[style*="position: relative"]')||
            element.closest('div.x1lliihq.x1n2onr6.x1jchvi3') ||
            element.closest('div[role="button"]') ||
            element.closest('a[href*="/marketplace/item/"]') ||
            element.closest('div.x9f619.x78zum5.x1r8uery') ||
            element.closest('div[style*="position: relative"]');
}

function isVisibleUpdate(element) {
    if (!element) return false;
    const style = window.getComputedStyle(element);
    return style.display !== 'none' &&
        style.visibility !== 'hidden' &&
        element.offsetWidth > 0;
}

function isClickableUpdate(element) {
    if (!element || !isVisibleUpdate(element)) return false;
    const style = window.getComputedStyle(element);
    return !(style.pointerEvents === 'none' ||
             style.cursor === 'not-allowed' ||
             parseFloat(style.opacity) < 0.6);
}

function highlightListingUpdate(element, state) {
    const colors = {
        processing: 'orange',
        success: 'green',
        failed: 'red'
    };
    element.style.border = `2px solid ${colors[state]}`;
    element.style.borderRadius = '8px';
    setTimeout(() => {element.style.border = ''}, 2000);
}

function humanLikeClickUpdate(element) {
    if (!element || !isVisibleUpdate(element)) return false;
    const rect = element.getBoundingClientRect();
    const clickEvent = new MouseEvent('click', {
        bubbles: true,
        clientX: rect.left + rect.width/2,
        clientY: rect.top + rect.height/2
    });
    element.dispatchEvent(clickEvent);
    return true;
}

// Activation Protocol
(function waitForPageReady() {
    if (document.readyState !== 'complete') {
        return setTimeout(waitForPageReady, 500);
    }

    createTerminatorUI();
    log("SYSTEM ONLINE");
    log("MENUNGGU PERINTAH");

})();
window.createTerminatorUI = createTerminatorUI;
window.startTerminationSequence = startTerminationSequence;
window.startUpdateSequence = startUpdateSequence;
window.startRepostSequence = startRepostSequence;
window.log = log;
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址