Bulk Offer & Accept Helper

Oferta itens por nome/quantidade/preço e aceita ofertas/presentes/compras em massa por nome e preço máximo (apenas valores inteiros).

当前为 2025-09-15 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Bulk Offer & Accept Helper
// @namespace    http://tampermonkey.net/
// @version      3.3
// @description  Oferta itens por nome/quantidade/preço e aceita ofertas/presentes/compras em massa por nome e preço máximo (apenas valores inteiros).
// @author       Popper 
// @match        *://*.popmundo.com/World/Popmundo.aspx/Character/OfferItem/*
// @match        *://*.popmundo.com/World/Popmundo.aspx/Character/ItemsOffered
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @run-at       document-idle
// ==/UserScript==
(function() {
    'use strict';
    // =================================================================================
    // --- ROTEADOR PRINCIPAL ---
    // =================================================================================
    function initializeScript() {
        const currentUrl = window.location.href;
        if (currentUrl.includes('/Character/OfferItem/')) {
            console.log("Bulk Helper: Página de OFERTAR item detectada.");
            setupOfferPage();
        } else if (currentUrl.includes('/Character/ItemsOffered')) {
            console.log("Bulk Helper: Página de ACEITAR ofertas detectada.");
            setupAcceptPage();
        }
    }

    // =================================================================================
    // --- FUNCIONALIDADE 1: OFERTAR ITENS EM MASSA (CÓDIGO COMPLETO) ---
    // =================================================================================
    function setupOfferPage() {
        const ITEM_DROPDOWN_SELECTOR = '#ctl00_cphLeftColumn_ctl00_ddlItem';
        const OFFER_BUTTON_SELECTOR = '#ctl00_cphLeftColumn_ctl00_btnGive';
        const PRICE_INPUT_SELECTOR = '#ctl00_cphLeftColumn_ctl00_txtPriceTag';
        const BASE_DELAY_MS = 2000;
        const POST_PRICE_SET_DELAY_MS = 100;
        const STORAGE_KEY_ITEMS_OFFER = 'popmundo_offerItem_items_swqp';
        const STORAGE_KEY_RUNNING_OFFER = 'popmundo_offerItem_running_swqp';
        const STORAGE_KEY_PRICE_OFFER = 'popmundo_offerItem_targetPrice';
        let itemDropdown = document.querySelector(ITEM_DROPDOWN_SELECTOR);
        if (!itemDropdown) { console.warn("Bulk Offer Helper: Dropdown de itens não encontrado."); return; }

        function createOfferUI() {
            if (document.getElementById('bulkOfferUIScript')) return;
            const scriptUIArea = document.createElement('div');
            scriptUIArea.id = 'bulkOfferUIScript';
            scriptUIArea.className = 'bulk-helper-container';
            scriptUIArea.innerHTML = `
                <div class="bulk-helper-header">
                    <i class="fa-solid fa-dolly fa-fw"></i>
                    <h3>Bulk Offer Helper</h3>
                </div>
                <div class="bulk-helper-content">
                    <div class="input-grid">
                        <div class="form-group">
                            <label for="itemNameInputScript">Nome do Item:</label>
                            <input type="text" id="itemNameInputScript" placeholder="Ex: Analgésicos">
                        </div>
                        <div class="form-group">
                            <label for="itemQuantityInputScript">Quantidade:</label>
                            <input type="number" id="itemQuantityInputScript" min="1" value="1">
                        </div>
                        <div class="form-group">
                            <label for="itemPriceInputScript">Preço (M$):</label>
                            <input type="number" id="itemPriceInputScript" min="0" step="1" value="0">
                        </div>
                    </div>
                    <div class="button-group">
                        <button id="startOfferByNameQtyPriceBtnScript" type="button" class="btn-start">Ofertar Itens</button>
                        <button id="stopBulkOfferBtnScript" type="button" class="btn-stop">Parar Oferta</button>
                    </div>
                    <div id="bulkOfferStatusScript" class="status-panel">Status: Pronto.</div>
                </div>
            `;
            itemDropdown.parentNode.insertBefore(scriptUIArea, itemDropdown);
            document.getElementById('startOfferByNameQtyPriceBtnScript').addEventListener('click', startOfferByNameQuantityPrice);
            document.getElementById('stopBulkOfferBtnScript').addEventListener('click', stopOffer);
            addGlobalStyles();
        }

        async function startOfferByNameQuantityPrice() {
            const itemNameInput = document.getElementById('itemNameInputScript');
            const quantityInput = document.getElementById('itemQuantityInputScript');
            const priceInput = document.getElementById('itemPriceInputScript');
            const statusDiv = document.getElementById('bulkOfferStatusScript');
            const inputText = itemNameInput.value.trim();
            const requestedQuantity = parseInt(quantityInput.value, 10);
            const requestedPrice = parseInt(priceInput.value, 10);
            if (!inputText) { statusDiv.textContent = "Erro: Digite o início do nome do item."; return; }
            if (isNaN(requestedQuantity) || requestedQuantity < 1) { statusDiv.textContent = "Erro: Quantidade inválida."; return; }
            if (isNaN(requestedPrice) || requestedPrice < 0) { statusDiv.textContent = "Erro: Preço inválido."; return; }
            const allItemsFound = Array.from(document.querySelector(ITEM_DROPDOWN_SELECTOR).options)
                .filter(option => option.value && option.value !== "-1" && option.textContent.trim().toLowerCase().startsWith(inputText.toLowerCase()))
                .map(option => ({ value: option.value, text: option.textContent.trim() }));
            if (allItemsFound.length === 0) {
                statusDiv.textContent = `Status: Nenhum item encontrado começando com "${inputText}".`;
                return;
            }
            const itemsToOfferThisRun = allItemsFound.slice(0, requestedQuantity);
            statusDiv.textContent = `Encontrado(s) ${allItemsFound.length}. Ofertando ${itemsToOfferThisRun.length} por ${requestedPrice} M$...`;
            await GM_setValue(STORAGE_KEY_PRICE_OFFER, requestedPrice);
            await GM_setValue(STORAGE_KEY_ITEMS_OFFER, JSON.stringify(itemsToOfferThisRun));
            await GM_setValue(STORAGE_KEY_RUNNING_OFFER, true);
            disableOfferButtons(true);
            await processNextOffer();
        }
        async function stopOffer() {
            await GM_deleteValue(STORAGE_KEY_ITEMS_OFFER);
            await GM_deleteValue(STORAGE_KEY_RUNNING_OFFER);
            await GM_deleteValue(STORAGE_KEY_PRICE_OFFER);
            const statusDiv = document.getElementById('bulkOfferStatusScript');
            if (statusDiv) statusDiv.textContent = "Status: Oferta interrompida pelo usuário.";
            disableOfferButtons(false);
        }
        function disableOfferButtons(disabled) {
             document.getElementById('startOfferByNameQtyPriceBtnScript').disabled = disabled;
             document.getElementById('stopBulkOfferBtnScript').disabled = !disabled;
             document.getElementById('itemNameInputScript').disabled = disabled;
             document.getElementById('itemQuantityInputScript').disabled = disabled;
             document.getElementById('itemPriceInputScript').disabled = disabled;
        }
        async function processNextOffer() {
            const isRunning = await GM_getValue(STORAGE_KEY_RUNNING_OFFER, false);
            if (!isRunning) { disableOfferButtons(false); return; }
            let itemsToOffer = JSON.parse(await GM_getValue(STORAGE_KEY_ITEMS_OFFER, '[]'));
            const statusDiv = document.getElementById('bulkOfferStatusScript');
            if (itemsToOffer.length === 0) {
                statusDiv.textContent = "Status: Todas as ofertas foram concluídas!";
                await stopOffer();
                return;
            }
            const itemDropdown = document.querySelector(ITEM_DROPDOWN_SELECTOR);
            const offerButton = document.querySelector(OFFER_BUTTON_SELECTOR);
            const pagePriceInput = document.querySelector(PRICE_INPUT_SELECTOR);
            if (!itemDropdown || !offerButton) {
                statusDiv.textContent = "Erro Crítico: Elementos da página desapareceram.";
                await stopOffer(); return;
            }
            const itemToOffer = itemsToOffer.shift();
            const targetPrice = await GM_getValue(STORAGE_KEY_PRICE_OFFER, 0);
            if (pagePriceInput) pagePriceInput.value = String(targetPrice);
            await new Promise(resolve => setTimeout(resolve, POST_PRICE_SET_DELAY_MS));
            const initialTotalCount = JSON.parse(await GM_getValue(STORAGE_KEY_ITEMS_OFFER, '[]')).length + itemsToOffer.length + 1;
            statusDiv.textContent = `Ofertando ${initialTotalCount - itemsToOffer.length}/${initialTotalCount}: '${itemToOffer.text}'...`;
            itemDropdown.value = itemToOffer.value;
            if (itemDropdown.value !== itemToOffer.value) {
                 statusDiv.textContent = `Erro: Falha ao selecionar '${itemToOffer.text}'. Pulando...`;
                 await GM_setValue(STORAGE_KEY_ITEMS_OFFER, JSON.stringify(itemsToOffer));
                 setTimeout(processNextOffer, BASE_DELAY_MS / 2); return;
            }
            await GM_setValue(STORAGE_KEY_ITEMS_OFFER, JSON.stringify(itemsToOffer));
            await new Promise(resolve => setTimeout(resolve, BASE_DELAY_MS));
            if (!await GM_getValue(STORAGE_KEY_RUNNING_OFFER, false)) { disableOfferButtons(false); return; }
            offerButton.click();
        }
        async function checkOfferStateOnLoad() {
            createOfferUI();
            const isRunning = await GM_getValue(STORAGE_KEY_RUNNING_OFFER, false);
            if (isRunning) {
                disableOfferButtons(true);
                document.getElementById('bulkOfferStatusScript').textContent = "Status: Recarregado, continuando oferta...";
                await new Promise(resolve => setTimeout(resolve, 500));
                await processNextOffer();
            } else {
                disableOfferButtons(false);
            }
        }
        checkOfferStateOnLoad();
    }

    // =================================================================================
    // --- FUNCIONALIDADE 2: ACEITAR OFERTAS EM MASSA (CÓDIGO ATUALIZADO v3.3) ---
    // =================================================================================
    function setupAcceptPage() {
        const BASE_DELAY_MS = 2000;
        const STORAGE_KEY_RUNNING_ACCEPT = 'popmundo_acceptItem_running';
        const STORAGE_KEY_MAX_PRICE_ACCEPT = 'popmundo_acceptItem_maxPrice';
        const STORAGE_KEY_ITEM_NAME_ACCEPT = 'popmundo_acceptItem_itemName';
        const STORAGE_KEY_ACCEPTED_COUNT = 'popmundo_acceptItem_accepted_count';
        const STORAGE_KEY_TOTAL_SPENT_ACCEPT = 'popmundo_acceptItem_totalSpent'; // NOVO

        function createAcceptUI() {
            if (document.getElementById('bulkAcceptUIScript')) return;
            const offersSection = Array.from(document.querySelectorAll('.box'))
                .find(box => box.textContent.includes('Itens sendo ofertados a você'));
            if (!offersSection) {
                console.log("Bulk Accept Helper: Seção 'Itens sendo ofertados a você' não encontrada.");
                return;
            }
            const scriptUIArea = document.createElement('div');
            scriptUIArea.id = 'bulkAcceptUIScript';
            scriptUIArea.className = 'bulk-helper-container';
            scriptUIArea.innerHTML = `
                <div class="bulk-helper-header">
                    <i class="fa-solid fa-check-circle fa-fw"></i>
                    <h3>Bulk Accept Helper</h3>
                </div>
                <div class="bulk-helper-content">
                    <div class="input-grid">
                        <div class="form-group">
                            <label for="itemNameInputAcceptScript">Nome do Item:</label>
                            <input type="text" id="itemNameInputAcceptScript" placeholder="xxx">
                        </div>
                        <div class="form-group">
                            <label for="maxPriceInputScript">Preço MÁXIMO (M$):</label>
                            <input type="number" id="maxPriceInputScript" min="0" step="1" value="55000">
                        </div>
                    </div>
                    <div class="button-group">
                        <button id="startAcceptBtnScript" type="button" class="btn-start">Aceitar em Massa</button>
                        <button id="stopAcceptBtnScript" type="button" class="btn-stop">Parar</button>
                    </div>
                    <div id="bulkAcceptStatusScript" class="status-panel">Status: Pronto.</div>
                    <div id="bulkAcceptSpentScript" class="spent-panel">Gasto Total: 0 M$</div>
                </div>
            `;
            offersSection.insertBefore(scriptUIArea, offersSection.firstChild);
            document.getElementById('startAcceptBtnScript').addEventListener('click', startBulkAccept);
            document.getElementById('stopAcceptBtnScript').addEventListener('click', stopBulkAccept);
            addGlobalStyles();
        }

        async function startBulkAccept() {
            const priceInput = document.getElementById('maxPriceInputScript');
            const nameInput = document.getElementById('itemNameInputAcceptScript');
            const statusDiv = document.getElementById('bulkAcceptStatusScript');
            const maxPrice = parseInt(priceInput.value.replace(/[.,]/g, ''), 10);
            const targetName = nameInput.value.trim().toLowerCase();
            if (isNaN(maxPrice) || maxPrice < 0) {
                statusDiv.textContent = "Erro: Preço máximo inválido.";
                priceInput.focus();
                return;
            }
            statusDiv.textContent = `Iniciando... Buscando ofertas para "${targetName || 'qualquer item'}" com preço até ${maxPrice} M$.`;
            document.getElementById('bulkAcceptSpentScript').textContent = `Gasto Total: 0 M$`;
            await GM_setValue(STORAGE_KEY_MAX_PRICE_ACCEPT, maxPrice);
            await GM_setValue(STORAGE_KEY_ITEM_NAME_ACCEPT, targetName);
            await GM_setValue(STORAGE_KEY_RUNNING_ACCEPT, true);
            await GM_setValue(STORAGE_KEY_ACCEPTED_COUNT, 0);
            await GM_setValue(STORAGE_KEY_TOTAL_SPENT_ACCEPT, 0); // NOVO
            disableAcceptButtons(true);
            await processNextAccept();
        }

        async function stopBulkAccept() {
            const totalSpent = await GM_getValue(STORAGE_KEY_TOTAL_SPENT_ACCEPT, 0);
            const acceptedCount = await GM_getValue(STORAGE_KEY_ACCEPTED_COUNT, 0);
            await GM_deleteValue(STORAGE_KEY_RUNNING_ACCEPT);
            await GM_deleteValue(STORAGE_KEY_MAX_PRICE_ACCEPT);
            await GM_deleteValue(STORAGE_KEY_ITEM_NAME_ACCEPT);
            await GM_deleteValue(STORAGE_KEY_ACCEPTED_COUNT);
            await GM_deleteValue(STORAGE_KEY_TOTAL_SPENT_ACCEPT); // NOVO
            const statusDiv = document.getElementById('bulkAcceptStatusScript');
            if (statusDiv) statusDiv.textContent = `Status: Interrompido. Total aceito: ${acceptedCount}. Gasto: ${totalSpent} M$.`;
            disableAcceptButtons(false);
        }

        function disableAcceptButtons(disabled) {
            document.getElementById('startAcceptBtnScript').disabled = disabled;
            document.getElementById('stopAcceptBtnScript').disabled = !disabled;
            document.getElementById('maxPriceInputScript').disabled = disabled;
            document.getElementById('itemNameInputAcceptScript').disabled = disabled;
        }

        function parseBrazilianCurrency(valueStr) {
            let cleanStr = valueStr.replace(/[^\d.,]/g, '');
            let parts = cleanStr.split(',');
            let integerPart = parts[0].replace(/\./g, '');
            return parseInt(integerPart, 10) || 0;
        }

        async function processNextAccept() {
            if (!await GM_getValue(STORAGE_KEY_RUNNING_ACCEPT, false)) {
                disableAcceptButtons(false);
                return;
            }
            const maxPrice = await GM_getValue(STORAGE_KEY_MAX_PRICE_ACCEPT, -1);
            const targetName = await GM_getValue(STORAGE_KEY_ITEM_NAME_ACCEPT, '');
            const acceptedCount = await GM_getValue(STORAGE_KEY_ACCEPTED_COUNT, 0);
            const totalSpent = await GM_getValue(STORAGE_KEY_TOTAL_SPENT_ACCEPT, 0); // NOVO
            const statusDiv = document.getElementById('bulkAcceptStatusScript');
            const spentDiv = document.getElementById('bulkAcceptSpentScript'); // NOVO

            const offersSection = Array.from(document.querySelectorAll('.box'))
                .find(box => box.textContent.includes('Itens sendo ofertados a você'));
            if (!offersSection) {
                statusDiv.textContent = "Status: Seção de ofertas não encontrada. Concluindo.";
                await stopBulkAccept();
                return;
            }
            const offerParagraphs = Array.from(offersSection.querySelectorAll('p.nobmargin'))
                .filter(p => p.textContent.includes('Oferecido por') && p.textContent.includes('custo:'));
            if (offerParagraphs.length === 0) {
                statusDiv.textContent = `Status: Nenhuma oferta encontrada. Total aceito: ${acceptedCount}. Gasto: ${totalSpent} M$. Concluído!`;
                await stopBulkAccept();
                return;
            }

            let foundItemToAccept = false;
            for (const paragraph of offerParagraphs) {
                const itemLink = paragraph.querySelector('a[id*="lnkItem"]');
                const itemName = itemLink ? itemLink.textContent.trim() : '';
                if (!itemName) continue;

                let itemPrice = 0;
                let priceText = "Presente";
                const costMatch = paragraph.textContent.match(/custo:\s*([\d.,]+)\s*M\$/);
                if (costMatch && costMatch[1]) {
                    itemPrice = parseBrazilianCurrency(costMatch[1]);
                    priceText = `${itemPrice} M$`;
                }

                const isNameOk = (targetName === '' || itemName.toLowerCase().includes(targetName));
                const isPriceOk = (itemPrice <= maxPrice);

                if (isNameOk && isPriceOk) {
                    const newCount = acceptedCount + 1;
                    const newTotalSpent = totalSpent + itemPrice; // NOVO
                    await GM_setValue(STORAGE_KEY_ACCEPTED_COUNT, newCount);
                    await GM_setValue(STORAGE_KEY_TOTAL_SPENT_ACCEPT, newTotalSpent); // NOVO

                    statusDiv.textContent = `Aceitando #${newCount}: '${itemName}' (${priceText})...`;
                    spentDiv.textContent = `Gasto Total: ${newTotalSpent} M$`; // NOVO
                    foundItemToAccept = true;

                    let acceptButton = paragraph.querySelector('input[value="Comprar e pagar pela entrega"]') ||
                                       paragraph.querySelector('input[id*="btnAccept"]') ||
                                       paragraph.querySelector('input[name*="btnAccept"]') ||
                                       paragraph.querySelector('input[type="submit"]:not([value="Rejeitar"])');

                    if (!acceptButton) {
                        console.log("Botão de aceitar não encontrado para este item");
                        continue;
                    }

                    await new Promise(resolve => setTimeout(resolve, BASE_DELAY_MS));
                    if (!await GM_getValue(STORAGE_KEY_RUNNING_ACCEPT, false)) {
                        console.log("Processo interrompido durante o delay final.");
                        disableAcceptButtons(false);
                        return;
                    }
                    acceptButton.click();
                    break;
                }
            }

            if (!foundItemToAccept) {
                statusDiv.textContent = `Status: Nenhuma outra oferta corresponde. Total aceito: ${acceptedCount}. Gasto: ${totalSpent} M$. Concluído!`;
                await stopBulkAccept();
            }
        }

        async function checkAcceptStateOnLoad() {
            createAcceptUI();
            if (await GM_getValue(STORAGE_KEY_RUNNING_ACCEPT, false)) {
                disableAcceptButtons(true);
                const acceptedCount = await GM_getValue(STORAGE_KEY_ACCEPTED_COUNT, 0);
                const totalSpent = await GM_getValue(STORAGE_KEY_TOTAL_SPENT_ACCEPT, 0);
                document.getElementById('bulkAcceptStatusScript').textContent = `Status: Recarregado, continuando... Total aceito: ${acceptedCount}`;
                document.getElementById('bulkAcceptSpentScript').textContent = `Gasto Total: ${totalSpent} M$`;
                await new Promise(resolve => setTimeout(resolve, 500));
                await processNextAccept();
            } else {
                disableAcceptButtons(false);
            }
        }
        checkAcceptStateOnLoad();
    }

    // =================================================================================
    // --- ESTILOS GLOBAIS PARA A UI ---
    // =================================================================================
    function addGlobalStyles() {
        // Adiciona o link para o Font Awesome no cabeçalho da página
        const fontAwesomeLink = document.createElement('link');
        fontAwesomeLink.rel = 'stylesheet';
        fontAwesomeLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css';
        document.head.appendChild(fontAwesomeLink);

        GM_addStyle(`
            .bulk-helper-container {
                border: 1px solid #d1d5db;
                border-radius: 8px;
                margin: 15px 0;
                background-color: #f9fafb;
                box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
                overflow: hidden;
            }
            .bulk-helper-header {
                display: flex;
                align-items: center;
                gap: 10px;
                background-color: #4b5563;
                color: white;
                padding: 10px 15px;
            }
            .bulk-helper-header h3 {
                margin: 0;
                font-size: 1.1em;
                font-weight: 600;
            }
            .bulk-helper-header i {
                color: #9ca3af;
                font-size: 1.2em;
            }
            .bulk-helper-content {
                padding: 12px 15px;
            }
            .input-grid {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
                gap: 12px;
                margin-bottom: 15px;
            }
            .form-group label {
                display: block;
                font-weight: 500;
                color: #374151;
                margin-bottom: 4px;
                font-size: 0.9em;
            }
            .form-group input[type="text"],
            .form-group input[type="number"] {
                width: 100%;
                padding: 6px 10px;
                border: 1px solid #d1d5db;
                border-radius: 6px;
                box-sizing: border-box;
                transition: border-color 0.2s, box-shadow 0.2s;
            }
            .form-group input:focus {
                outline: none;
                border-color: #3b82f6;
                box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.25);
            }
            .button-group {
                display: flex;
                gap: 10px;
                margin-bottom: 12px;
            }
            .button-group button {
                padding: 8px 12px;
                border: none;
                border-radius: 6px;
                cursor: pointer;
                font-weight: 600;
                transition: background-color 0.2s, transform 0.1s;
                flex-grow: 1;
            }
            .button-group button:hover:not(:disabled) {
                transform: translateY(-1px);
            }
            .btn-start {
                background-color: #10b981;
                color: white;
            }
            .btn-start:hover:not(:disabled) {
                background-color: #059669;
            }
            .btn-stop {
                background-color: #ef4444;
                color: white;
            }
            .btn-stop:hover:not(:disabled) {
                background-color: #dc2626;
            }
            .button-group button:disabled {
                cursor: not-allowed;
                opacity: 0.6;
            }
            .status-panel {
                font-weight: bold;
                background-color: #e5e7eb;
                padding: 8px 10px;
                border-radius: 6px;
                font-size: 0.9em;
                color: #1f2937;
                text-align: center;
                margin-bottom: 8px;
            }
            .spent-panel {
                font-weight: bold;
                background-color: #d1fae5;
                color: #065f46;
                padding: 8px 10px;
                border-radius: 6px;
                font-size: 0.9em;
                text-align: center;
            }
        `);
    }

    // Inicia o script
    initializeScript();
})();