您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
View items you are searching for in registered bazaars!
当前为
// ==UserScript== // @name Bazaar Item Search powered by IronNerd // @namespace [email protected] // @version 0.3.3 // @description View items you are searching for in registered bazaars! // @author Nurv [669537] // @match https://www.torn.com/page.php?sid=ItemMarket* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @run-at document-end // @license Copyright IronNerd.me // @connect ironnerd.me // ==/UserScript== (function() { 'use strict'; console.log('IronNerd Bazaar Enhancements script started.'); init(); async function init() { injectAdditionalStyles(); addSettingsButton(); addOneDollarButton(); addShowBazaarButton(); const apiKey = await GM_getValue('tornApiKey', ''); if (apiKey) { checkBazaarStatus(apiKey); } detectSearch(); // Retain the old auto-fetch functionality observeDarkMode(); // Ensure UI adapts dynamically to dark mode } // ------------------ Settings Button ------------------ function addSettingsButton() { const intervalId = setInterval(() => { const linksContainer = document.querySelector('.linksContainer___LiOTN'); if (linksContainer) { clearInterval(intervalId); const button = document.createElement('button'); button.setAttribute('type', 'button'); button.className = 'linkContainer___X16y4 inRow___VfDnd greyLineV___up8VP iconActive___oAum9'; button.style.cursor = 'pointer'; button.style.display = 'flex'; button.style.alignItems = 'center'; button.style.justifyContent = 'center'; button.style.padding = '8px'; const iconWrapper = document.createElement('span'); iconWrapper.className = 'iconWrapper___x3ZLe iconWrapper___COKJD svgIcon___IwbJV'; iconWrapper.style.display = 'flex'; iconWrapper.style.alignItems = 'center'; iconWrapper.style.justifyContent = 'center'; const gearIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); gearIcon.setAttribute('width', '24'); gearIcon.setAttribute('height', '24'); gearIcon.setAttribute('viewBox', '0 0 24 24'); gearIcon.setAttribute('fill', 'currentColor'); gearIcon.innerHTML = ` <path d="M19.14,12.936l1.843-1.061a0.5,0.5,0,0,0,.11-0.63l-1.741-3.012a0.5,0.5,0,0,0-.61-0.22l-2.169,0.875a7.056,7.056,0,0,0-1.607-0.93l-0.33-2.313A0.5,0.5,0,0,0,13.5,4H10.5a0.5,0.5,0,0,0-.49,0.42l-0.33,2.313a7.056,7.056,0,0,0-1.607,0.93l-2.169-0.875a0.5,0.5,0,0,0-.61,0.22L3.56,11.245a0.5,0.5,0,0,0,.11,0.63l1.843,1.061a7.154,7.154,0,0,0,0,1.872L3.67,16.936a0.5,0.5,0,0,0-.11,0.63l1.741,3.012a0.5,0.5,0,0,0,.61,0.22l2.169-0.875a7.056,7.056,0,0,0,1.607,0.93l0.33,2.313a0.5,0.5,0,0,0,.49,0.42h3a0.5,0.5,0,0,0,.49-0.42l0.33-2.313a7.056,7.056,0,0,0,1.607-0.93l2.169,0.875a0.5,0.5,0,0,0,.61-0.22l1.741-3.012a0.5,0.5,0,0,0-.11-0.63Zm-7.14,2.064A3,3,0,1,1,15,12,3,3,0,0,1,12,15Z"/> `; iconWrapper.appendChild(gearIcon); button.appendChild(iconWrapper); button.addEventListener('click', openSettingsModal); linksContainer.appendChild(button); console.log('IronNerd Bazaar Enhancements: Settings button added.'); } }, 500); } // ------------------ Modal Theme Application ------------------ function applyThemeToModal(modal) { const isDarkMode = document.body.classList.contains('dark-mode'); const modalContent = modal.querySelector('#modal-content'); if (isDarkMode) { modalContent.style.backgroundColor = '#1c1c1c'; modalContent.style.color = '#f0f0f0'; modalContent.querySelectorAll('button').forEach(btn => { btn.style.backgroundColor = '#333'; btn.style.color = '#f0f0f0'; btn.style.border = 'none'; }); modalContent.querySelector('h2').style.color = '#ddd'; } else { modalContent.style.backgroundColor = '#fff'; modalContent.style.color = '#000'; modalContent.querySelectorAll('button').forEach(btn => { btn.style.backgroundColor = '#f9f9f9'; btn.style.color = '#000'; btn.style.border = '1px solid #ccc'; }); modalContent.querySelector('h2').style.color = '#333'; } } // ------------------ Inject Additional Styles ------------------ function injectAdditionalStyles() { const style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = ` @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Ensure modals and tables are responsive */ @media screen and (max-width: 768px) { .one-dollar-table, .bazaar-table { width: 100%; font-size: 12px; } .one-dollar-table td, .bazaar-table td { padding: 5px; } #bazaar-enhancer-modal #modal-content, #oneDollarModal #modal-content, #showBazaarModal #modal-content { width: 90%; padding: 15px; } } /* General Modal Styling */ #bazaar-enhancer-modal, #oneDollarModal, #showBazaarModal { background-color: rgba(0, 0, 0, 0.7); display: flex; align-items: center; justify-content: center; } #bazaar-enhancer-modal #modal-content, #oneDollarModal #modal-content, #showBazaarModal #modal-content { background-color: #fff; color: #000; padding: 20px; border-radius: 8px; max-width: 600px; width: 90%; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); } /* Title Styling */ #bazaar-enhancer-modal h2, #oneDollarModal h2, #showBazaarModal h2 { text-align: center; font-size: 1.5em; margin-bottom: 20px; color: #333; } /* Dark Mode Enhancements */ .dark-mode #bazaar-enhancer-modal #modal-content, .dark-mode #oneDollarModal #modal-content, .dark-mode #showBazaarModal #modal-content { background-color: #1c1c1c; color: #f0f0f0; } .dark-mode #bazaar-enhancer-modal h2, .dark-mode #oneDollarModal h2, .dark-mode #showBazaarModal h2 { color: #ddd; } /* Table Styling */ table { width: 100%; border-collapse: collapse; margin-top: 10px; } table th, table td { text-align: center; padding: 10px; border: 1px solid #ccc; } .dark-mode table th, .dark-mode table td { background-color: #2a2a2a; color: #f0f0f0; } .dark-mode table th { background-color: #333; } /* Responsive table design */ @media screen and (max-width: 600px) { table { display: block; overflow-x: auto; } table th, table td { white-space: nowrap; } } /* Button Enhancements */ button { padding: 10px 15px; font-size: 14px; border-radius: 4px; margin: 5px; } button:hover { opacity: 0.9; } `; document.head.appendChild(style); } // ------------------ Observe Dark Mode Changes ------------------ function observeDarkMode() { const observer = new MutationObserver(() => { const modals = document.querySelectorAll('#bazaar-enhancer-modal, #oneDollarModal, #showBazaarModal'); modals.forEach(modal => applyThemeToModal(modal)); }); observer.observe(document.body, { attributes: true, attributeFilter: ['class'] }); } async function openSettingsModal() { let existingModal = document.getElementById('bazaar-enhancer-modal'); if (existingModal) { document.body.removeChild(existingModal); } const savedApiKey = await GM_getValue('tornApiKey', ''); const modal = document.createElement('div'); modal.id = 'bazaar-enhancer-modal'; modal.setAttribute('role', 'dialog'); modal.setAttribute('aria-labelledby', 'modal-title'); modal.setAttribute('aria-modal', 'true'); modal.style = 'position: fixed; top: 0; left: 0; width: 100%; height: 100%;' + 'background-color: rgba(0,0,0,0.5); z-index: 1001; display: flex; align-items: center; justify-content: center;'; modal.innerHTML = ` <div id="modal-content" style="background-color: #fff; padding: 20px; border-radius: 5px; width: 400px; position: relative;"> <h2 id="modal-title">Bazaar Enhancer Settings</h2> <label for="apiKey">Your Torn API Key:</label><br> <input type="password" id="apiKey" style="width: 100%; border: 1px solid #ccc; border-radius: 5px;" value="${savedApiKey}"><br> <input type="checkbox" id="toggleVisibility"> <label for="toggleVisibility">Show API Key</label><br><br> <button id="saveApiKey">Save API Key</button> <button id="registerBazaar">Register Bazaar</button> <button id="removeBazaar">Remove Bazaar</button><br><br> <div id="statusMessage" style="margin-top: 10px; font-weight: bold;"></div> <button id="closeModal" style="position: absolute; top: 10px; right: 10px;" aria-label="Close Modal">×</button> </div> `; document.body.appendChild(modal); applyThemeToModal(modal); trapFocus(modal); const toggleVisibility = modal.querySelector('#toggleVisibility'); const apiKeyInput = modal.querySelector('#apiKey'); toggleVisibility.addEventListener('change', () => { apiKeyInput.type = toggleVisibility.checked ? 'text' : 'password'; }); modal.querySelector('#saveApiKey').addEventListener('click', async () => { const apiKey = apiKeyInput.value.trim(); const saveButton = modal.querySelector('#saveApiKey'); if (apiKey) { if (!isValidApiKey(apiKey)) { displayStatusMessage('error', 'Invalid API key format. Please check and try again.'); return; } saveButton.disabled = true; const spinner = createLoadingSpinner(); saveButton.parentNode.insertBefore(spinner, saveButton.nextSibling); try { await GM_setValue('tornApiKey', apiKey); displayStatusMessage('success', 'API key saved successfully.'); checkBazaarStatus(apiKey); } catch (error) { displayStatusMessage('error', 'Failed to save API key.'); console.error(error); } finally { saveButton.disabled = false; spinner.remove(); } } else { displayStatusMessage('error', 'Please enter a valid API key.'); } }); modal.querySelector('#registerBazaar').addEventListener('click', async () => { const apiKey = await GM_getValue('tornApiKey', ''); if (apiKey) { registerApiKey(apiKey); } else { displayStatusMessage('error', 'Please save your API key first.'); } }); modal.querySelector('#removeBazaar').addEventListener('click', async () => { const apiKey = await GM_getValue('tornApiKey', ''); if (apiKey) { unregisterApiKey(apiKey); } else { displayStatusMessage('error', 'No API key found to remove.'); } }); modal.querySelector('#closeModal').addEventListener('click', () => { closeSettingsModal(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { const modal = document.getElementById('bazaar-enhancer-modal'); if (modal) { closeSettingsModal(); } } }); const observer = new MutationObserver(() => { applyThemeToModal(modal); }); observer.observe(document.body, { attributes: true, attributeFilter: ['class'] }); apiKeyInput.focus(); } function closeSettingsModal() { const modal = document.getElementById('bazaar-enhancer-modal'); if (modal) { document.body.removeChild(modal); console.log('IronNerd Bazaar Enhancements: Settings modal closed.'); } } function trapFocus(modal) { const focusableElements = modal.querySelectorAll('a[href], button, textarea, input, select'); if (focusableElements.length === 0) return; // No focusable elements const firstFocusable = focusableElements[0]; const lastFocusable = focusableElements[focusableElements.length - 1]; modal.addEventListener('keydown', function(e) { const isTabPressed = (e.key === 'Tab' || e.keyCode === 9); if (!isTabPressed) return; if (e.shiftKey) { // shift + tab if (document.activeElement === firstFocusable) { lastFocusable.focus(); e.preventDefault(); } } else { // tab if (document.activeElement === lastFocusable) { firstFocusable.focus(); e.preventDefault(); } } }); } function createLoadingSpinner() { const spinner = document.createElement('div'); spinner.className = 'loading-spinner'; spinner.style.border = '4px solid #f3f3f3'; spinner.style.borderTop = '4px solid #3498db'; spinner.style.borderRadius = '50%'; spinner.style.width = '24px'; spinner.style.height = '24px'; spinner.style.animation = 'spin 2s linear infinite'; spinner.style.display = 'inline-block'; spinner.style.marginLeft = '10px'; return spinner; } // ------------------ $1 Items Button ------------------ function addOneDollarButton() { const intervalId = setInterval(() => { const linksContainer = document.querySelector('.linksContainer___LiOTN'); if (linksContainer) { clearInterval(intervalId); const button = document.createElement('button'); button.id = 'oneDollarSearchBtn'; button.innerText = '1'; button.style.cursor = 'pointer'; button.style.padding = '8px 12px'; button.style.marginLeft = '10px'; button.style.backgroundColor = '#ff5722'; button.style.color = '#fff'; button.style.border = 'none'; button.style.borderRadius = '4px'; button.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.2)'; button.style.fontSize = '14px'; const dollarIcon = document.createElement('span'); dollarIcon.innerHTML = '$'; dollarIcon.style.marginRight = '5px'; button.prepend(dollarIcon); linksContainer.appendChild(button); button.addEventListener('click', openOneDollarModal); console.log('IronNerd Bazaar Enhancements: "$1 Items" button added.'); } }, 500); } // ------------------ Show Bazaar Button ------------------ function addShowBazaarButton() { const intervalId = setInterval(() => { const linksContainer = document.querySelector('.linksContainer___LiOTN'); if (linksContainer) { clearInterval(intervalId); const button = document.createElement('button'); button.id = 'showBazaarSearchBtn'; button.innerText = 'Bazaar'; button.style.cursor = 'pointer'; button.style.padding = '8px 12px'; button.style.marginLeft = '10px'; button.style.backgroundColor = '#4caf50'; button.style.color = '#fff'; button.style.border = 'none'; button.style.borderRadius = '4px'; button.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.2)'; button.style.fontSize = '14px'; const bazaarIcon = document.createElement('span'); bazaarIcon.innerHTML = '🛒'; // Shopping cart icon bazaarIcon.style.marginRight = '5px'; button.prepend(bazaarIcon); linksContainer.appendChild(button); button.addEventListener('click', openShowBazaarModal); console.log('IronNerd Bazaar Enhancements: "Show Bazaar" button added.'); } }, 500); } // ------------------ $1 Items Modal ------------------ function openOneDollarModal() { console.log('IronNerd Bazaar Enhancements: "$1 Items" button clicked.'); createOneDollarModal(); const modal = document.getElementById('oneDollarModal'); if (modal) { modal.style.display = 'block'; fetchOneDollarItems(); trapFocus(modal); } else { console.error('IronNerd Bazaar Enhancements: oneDollarModal element not found.'); } } function createOneDollarModal() { if (document.getElementById('oneDollarModal')) { console.log('IronNerd Bazaar Enhancements: $1 Items modal already exists.'); return; } console.log('IronNerd Bazaar Enhancements: Creating $1 Items modal.'); const overlay = document.createElement('div'); overlay.id = 'oneDollarModal'; overlay.style.position = 'fixed'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.height = '100%'; overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; overlay.style.display = 'none'; overlay.style.zIndex = '10000'; overlay.style.overflowY = 'auto'; const modalContent = document.createElement('div'); modalContent.style.backgroundColor = '#fff'; modalContent.style.margin = '50px auto'; modalContent.style.padding = '20px'; modalContent.style.borderRadius = '8px'; modalContent.style.width = '90%'; modalContent.style.maxWidth = '800px'; modalContent.style.position = 'relative'; modalContent.style.boxShadow = '0 5px 15px rgba(0,0,0,0.3)'; const closeBtn = document.createElement('span'); closeBtn.innerHTML = '×'; closeBtn.style.position = 'absolute'; closeBtn.style.top = '10px'; closeBtn.style.right = '20px'; closeBtn.style.fontSize = '30px'; closeBtn.style.fontWeight = 'bold'; closeBtn.style.cursor = 'pointer'; closeBtn.style.color = '#aaa'; closeBtn.addEventListener('mouseover', () => { closeBtn.style.color = '#000'; }); closeBtn.addEventListener('mouseout', () => { closeBtn.style.color = '#aaa'; }); closeBtn.addEventListener('click', closeOneDollarModal); const title = document.createElement('h2'); title.innerText = '$1 Items in Bazaar'; title.style.textAlign = 'center'; title.style.marginBottom = '20px'; const sortContainer = document.createElement('div'); sortContainer.style.textAlign = 'right'; sortContainer.style.marginBottom = '10px'; const sortLabel = document.createElement('label'); sortLabel.innerText = 'Sort by Market Price: '; sortLabel.setAttribute('for', 'sortSelect'); const sortSelect = document.createElement('select'); sortSelect.id = 'sortSelect'; sortSelect.style.padding = '5px'; sortSelect.style.marginLeft = '10px'; const optionAsc = document.createElement('option'); optionAsc.value = 'market_price_asc'; optionAsc.text = 'Low to High'; const optionDesc = document.createElement('option'); optionDesc.value = 'market_price_desc'; optionDesc.text = 'High to Low'; sortSelect.add(optionAsc); sortSelect.add(optionDesc); sortContainer.appendChild(sortLabel); sortContainer.appendChild(sortSelect); const resultsContainer = document.createElement('div'); resultsContainer.id = 'oneDollarResults'; resultsContainer.style.marginTop = '20px'; modalContent.appendChild(closeBtn); modalContent.appendChild(title); modalContent.appendChild(sortContainer); modalContent.appendChild(resultsContainer); overlay.appendChild(modalContent); document.body.appendChild(overlay); console.log('IronNerd Bazaar Enhancements: $1 Items modal created and appended to the DOM.'); } function closeOneDollarModal() { const modal = document.getElementById('oneDollarModal'); if (modal) { modal.style.display = 'none'; console.log('IronNerd Bazaar Enhancements: $1 Items modal closed.'); } } // ------------------ Show Bazaar Modal ------------------ function openShowBazaarModal() { console.log('IronNerd Bazaar Enhancements: "Show Bazaar" button clicked.'); createShowBazaarModal(); const modal = document.getElementById('showBazaarModal'); if (modal) { modal.style.display = 'block'; // Automatically fetch based on current search term const currentSearchTerm = getCurrentSearchTerm(); const searchInput = modal.querySelector('#showBazaarSearchInput'); if (currentSearchTerm) { searchInput.value = currentSearchTerm; fetchShowBazaarItems(currentSearchTerm); } trapFocus(modal); } else { console.error('IronNerd Bazaar Enhancements: showBazaarModal element not found.'); } } function createShowBazaarModal() { if (document.getElementById('showBazaarModal')) { console.log('IronNerd Bazaar Enhancements: Show Bazaar modal already exists.'); return; } console.log('IronNerd Bazaar Enhancements: Creating Show Bazaar modal.'); const overlay = document.createElement('div'); overlay.id = 'showBazaarModal'; overlay.style.position = 'fixed'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.height = '100%'; overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; overlay.style.display = 'none'; overlay.style.zIndex = '10000'; overlay.style.overflowY = 'auto'; const modalContent = document.createElement('div'); modalContent.style.backgroundColor = '#fff'; modalContent.style.margin = '50px auto'; modalContent.style.padding = '20px'; modalContent.style.borderRadius = '8px'; modalContent.style.width = '90%'; modalContent.style.maxWidth = '800px'; modalContent.style.position = 'relative'; modalContent.style.boxShadow = '0 5px 15px rgba(0,0,0,0.3)'; const closeBtn = document.createElement('span'); closeBtn.innerHTML = '×'; closeBtn.style.position = 'absolute'; closeBtn.style.top = '10px'; closeBtn.style.right = '20px'; closeBtn.style.fontSize = '30px'; closeBtn.style.fontWeight = 'bold'; closeBtn.style.cursor = 'pointer'; closeBtn.style.color = '#aaa'; closeBtn.addEventListener('mouseover', () => { closeBtn.style.color = '#000'; }); closeBtn.addEventListener('mouseout', () => { closeBtn.style.color = '#aaa'; }); closeBtn.addEventListener('click', closeShowBazaarModal); const title = document.createElement('h2'); title.innerText = 'Show Bazaar Items'; title.style.textAlign = 'center'; title.style.marginBottom = '20px'; // Add input for search term const searchContainer = document.createElement('div'); searchContainer.style.textAlign = 'center'; searchContainer.style.marginBottom = '10px'; const searchLabel = document.createElement('label'); searchLabel.innerText = 'Enter Item Name: '; searchLabel.setAttribute('for', 'showBazaarSearchInput'); const searchInput = document.createElement('input'); searchInput.type = 'text'; searchInput.id = 'showBazaarSearchInput'; searchInput.style.width = '70%'; searchInput.style.padding = '8px'; searchInput.style.border = '1px solid #ccc'; searchInput.style.borderRadius = '4px'; const searchButton = document.createElement('button'); searchButton.innerText = 'Search'; searchButton.style.marginLeft = '10px'; searchButton.style.padding = '8px 12px'; searchButton.style.cursor = 'pointer'; searchButton.style.backgroundColor = '#2196f3'; searchButton.style.color = '#fff'; searchButton.style.border = 'none'; searchButton.style.borderRadius = '4px'; searchButton.addEventListener('click', () => { const itemName = searchInput.value.trim(); if (itemName) { fetchShowBazaarItems(itemName); } else { displayShowBazaarStatusMessage('error', 'Please enter an item name to search.'); } }); searchContainer.appendChild(searchLabel); searchContainer.appendChild(searchInput); searchContainer.appendChild(searchButton); const resultsContainer = document.createElement('div'); resultsContainer.id = 'showBazaarResults'; resultsContainer.style.marginTop = '20px'; const statusDiv = document.createElement('div'); statusDiv.id = 'showBazaarStatusMessage'; statusDiv.style.marginTop = '10px'; statusDiv.style.fontWeight = 'bold'; modalContent.appendChild(closeBtn); modalContent.appendChild(title); modalContent.appendChild(searchContainer); modalContent.appendChild(resultsContainer); modalContent.appendChild(statusDiv); overlay.appendChild(modalContent); document.body.appendChild(overlay); console.log('IronNerd Bazaar Enhancements: Show Bazaar modal created and appended to the DOM.'); } function closeShowBazaarModal() { const modal = document.getElementById('showBazaarModal'); if (modal) { modal.style.display = 'none'; console.log('IronNerd Bazaar Enhancements: Show Bazaar modal closed.'); } } // ------------------ Fetch $1 Items ------------------ function fetchOneDollarItems() { const backendUrl = 'https://www.ironnerd.me/search_one_dollar'; let sortOrder = 'market_price_asc'; getOneDollarItems(sortOrder); const sortSelect = document.getElementById('sortSelect'); sortSelect.addEventListener('change', () => { sortOrder = sortSelect.value; getOneDollarItems(sortOrder); }); } function getOneDollarItems(sortOrder) { const resultsContainer = document.getElementById('oneDollarResults'); resultsContainer.innerHTML = '<p>Loading...</p>'; GM_xmlhttpRequest({ method: 'GET', url: `https://www.ironnerd.me/search_one_dollar?sort=${sortOrder}`, headers: { 'Accept': 'application/json' }, onload: function(response) { if (response.status === 200) { try { const data = JSON.parse(response.responseText); displayOneDollarItems(data.bazaar_items); console.log('IronNerd Bazaar Enhancements: $1 Items data fetched successfully.'); } catch (e) { resultsContainer.innerHTML = '<p>Error parsing server response.</p>'; console.error('IronNerd Bazaar Enhancements: Parsing Error:', e); } } else { resultsContainer.innerHTML = `<p>Error: ${response.status} - ${response.statusText}</p>`; console.error('IronNerd Bazaar Enhancements: Fetch $1 Items Error:', response.responseText); } }, onerror: function(error) { resultsContainer.innerHTML = '<p>Network error occurred. Please try again later.</p>'; console.error('IronNerd Bazaar Enhancements: Network Error:', error); } }); } // ------------------ Display $1 Items ------------------ function displayOneDollarItems(items) { const resultsContainer = document.getElementById('oneDollarResults'); resultsContainer.innerHTML = ''; if (!items || items.length === 0) { resultsContainer.innerHTML = '<p>No $1 items found.</p>'; return; } // Group items by owner const groupedItems = items.reduce((acc, itemData) => { const ownerKey = `${itemData.owner}||${itemData.user_id}`; // Unique key combining owner name and user_id if (!acc[ownerKey]) { acc[ownerKey] = { owner: itemData.owner, user_id: itemData.user_id, items: [] }; } acc[ownerKey].items.push(itemData.item); return acc; }, {}); // Create table const table = document.createElement('table'); table.className = 'one-dollar-table'; table.style.width = '100%'; table.style.borderCollapse = 'collapse'; const thead = document.createElement('thead'); const headerRow = document.createElement('tr'); const headers = ['Owner', 'Total Items', 'Higest Item Value','Actions']; headers.forEach(headerText => { const th = document.createElement('th'); th.innerText = headerText; th.style.border = '1px solid #ddd'; th.style.padding = '8px'; th.style.backgroundColor = '#f2f2f2'; th.style.textAlign = 'center'; headerRow.appendChild(th); }); thead.appendChild(headerRow); table.appendChild(thead); const tbody = document.createElement('tbody'); Object.keys(groupedItems).forEach(ownerKey => { const group = groupedItems[ownerKey]; const ownerRow = document.createElement('tr'); // Owner Name Cell const ownerTd = document.createElement('td'); ownerTd.textContent = group.owner; ownerTd.setAttribute('data-label', 'Owner'); ownerTd.style.border = '1px solid #ddd'; ownerTd.style.padding = '8px'; ownerTd.style.textAlign = 'center'; ownerRow.appendChild(ownerTd); // Total Items Cell const totalItemsTd = document.createElement('td'); totalItemsTd.textContent = group.items.length; totalItemsTd.setAttribute('data-label', 'Total Items'); totalItemsTd.style.border = '1px solid #ddd'; totalItemsTd.style.padding = '8px'; totalItemsTd.style.textAlign = 'center'; ownerRow.appendChild(totalItemsTd); // Highest Market Price Cell const highestMarketPriceTd = document.createElement('td'); // Calculate the highest market price among the owner's items let highestMarketPrice = 0; if (group.items.length > 0) { highestMarketPrice = group.items.reduce((max, item) => { return item.market_price > max ? item.market_price : max; }, 0); } // Set the text content with proper formatting highestMarketPriceTd.textContent = highestMarketPrice > 0 ? `$${highestMarketPrice.toLocaleString()}` : 'N/A'; highestMarketPriceTd.setAttribute('data-label', 'Highest Market Price'); highestMarketPriceTd.style.border = '1px solid #ddd'; highestMarketPriceTd.style.padding = '8px'; highestMarketPriceTd.style.textAlign = 'center'; ownerRow.appendChild(highestMarketPriceTd); // Actions Cell with Expand/Collapse Button const actionsTd = document.createElement('td'); actionsTd.setAttribute('data-label', 'Actions'); actionsTd.style.border = '1px solid #ddd'; actionsTd.style.padding = '8px'; actionsTd.style.textAlign = 'center'; const expandBtn = document.createElement('button'); expandBtn.textContent = 'Expand'; // Toggle Functionality expandBtn.addEventListener('click', () => { const isExpanded = expandBtn.textContent === 'Collapse'; expandBtn.textContent = isExpanded ? 'Expand' : 'Collapse'; detailsRow.style.display = isExpanded ? 'none' : 'table-row'; }); actionsTd.appendChild(expandBtn); ownerRow.appendChild(actionsTd); tbody.appendChild(ownerRow); // Details Row containing the list of items const detailsRow = document.createElement('tr'); detailsRow.style.display = 'none'; // Initially hidden const detailsTd = document.createElement('td'); detailsTd.colSpan = headers.length; detailsTd.style.border = '1px solid #ddd'; detailsTd.style.padding = '8px'; // Create a nested table for items const nestedTable = document.createElement('table'); nestedTable.style.width = '100%'; nestedTable.style.borderCollapse = 'collapse'; const nestedThead = document.createElement('thead'); const nestedHeaderRow = document.createElement('tr'); const nestedHeaders = ['Item Name', 'Type', 'Quantity', 'Price ($)', 'Market Price ($)', 'Visit Bazaar']; nestedHeaders.forEach(headerText => { const th = document.createElement('th'); th.innerText = headerText; th.style.border = '1px solid #ddd'; th.style.padding = '6px'; th.style.backgroundColor = '#f9f9f9'; th.style.textAlign = 'center'; nestedHeaderRow.appendChild(th); }); nestedThead.appendChild(nestedHeaderRow); nestedTable.appendChild(nestedThead); const nestedTbody = document.createElement('tbody'); group.items.forEach(item => { const tr = document.createElement('tr'); // Item Name const nameTd = document.createElement('td'); nameTd.innerText = item.name; nameTd.setAttribute('data-label', 'Item Name'); nameTd.style.border = '1px solid #ddd'; nameTd.style.padding = '6px'; nameTd.style.textAlign = 'center'; tr.appendChild(nameTd); // Type const typeTd = document.createElement('td'); typeTd.innerText = item.type || 'N/A'; typeTd.setAttribute('data-label', 'Type'); typeTd.style.border = '1px solid #ddd'; typeTd.style.padding = '6px'; typeTd.style.textAlign = 'center'; tr.appendChild(typeTd); // Quantity const quantityTd = document.createElement('td'); quantityTd.innerText = item.quantity; quantityTd.setAttribute('data-label', 'Quantity'); quantityTd.style.border = '1px solid #ddd'; quantityTd.style.padding = '6px'; quantityTd.style.textAlign = 'center'; tr.appendChild(quantityTd); // Price ($) const priceTd = document.createElement('td'); priceTd.innerText = `$${item.price.toLocaleString()}`; priceTd.setAttribute('data-label', 'Price ($)'); priceTd.style.border = '1px solid #ddd'; priceTd.style.padding = '6px'; priceTd.style.textAlign = 'center'; tr.appendChild(priceTd); // Market Price ($) const marketPriceTd = document.createElement('td'); marketPriceTd.innerText = item.market_price ? `$${item.market_price.toLocaleString()}` : 'N/A'; marketPriceTd.setAttribute('data-label', 'Market Price ($)'); marketPriceTd.style.border = '1px solid #ddd'; marketPriceTd.style.padding = '6px'; marketPriceTd.style.textAlign = 'center'; tr.appendChild(marketPriceTd); // Visit Bazaar const visitTd = document.createElement('td'); visitTd.style.border = '1px solid #ddd'; visitTd.style.padding = '6px'; visitTd.style.textAlign = 'center'; const visitLink = document.createElement('a'); visitLink.href = `https://www.torn.com/bazaar.php?userID=${group.user_id}`; visitLink.textContent = 'Visit'; visitLink.target = '_blank'; visitLink.style.color = '#007bff'; visitLink.style.textDecoration = 'none'; visitLink.addEventListener('mouseover', () => { visitLink.style.textDecoration = 'underline'; }); visitLink.addEventListener('mouseout', () => { visitLink.style.textDecoration = 'none'; }); visitTd.appendChild(visitLink); visitTd.setAttribute('data-label', 'Visit Bazaar'); tr.appendChild(visitTd); nestedTbody.appendChild(tr); }); nestedTable.appendChild(nestedTbody); detailsTd.appendChild(nestedTable); detailsRow.appendChild(detailsTd); tbody.appendChild(detailsRow); }); table.appendChild(tbody); resultsContainer.appendChild(table); adjustOneDollarTableTheme(); } // ------------------ Fetch Show Bazaar Items ------------------ function fetchShowBazaarItems(itemName = '') { const resultsContainer = document.getElementById('showBazaarResults'); const statusDiv = document.getElementById('showBazaarStatusMessage'); if (itemName) { resultsContainer.innerHTML = '<p>Loading...</p>'; statusDiv.innerHTML = ''; GM_xmlhttpRequest({ method: 'GET', url: `https://www.ironnerd.me/search_bazaar_items?item_name=${encodeURIComponent(itemName)}`, headers: { 'Accept': 'application/json' }, onload: function(response) { if (response.status === 200) { try { const data = JSON.parse(response.responseText); displayShowBazaarItems(data.bazaar_items, itemName); console.log('IronNerd Bazaar Enhancements: Show Bazaar Items data fetched successfully.'); } catch (e) { resultsContainer.innerHTML = '<p>Error parsing server response.</p>'; console.error('IronNerd Bazaar Enhancements: Parsing Error:', e); } } else { resultsContainer.innerHTML = `<p>Error: ${response.status} - ${response.statusText}</p>`; console.error('IronNerd Bazaar Enhancements: Fetch Show Bazaar Items Error:', response.responseText); } }, onerror: function(error) { resultsContainer.innerHTML = '<p>Network error occurred. Please try again later.</p>'; console.error('IronNerd Bazaar Enhancements: Network Error:', error); } }); } else { resultsContainer.innerHTML = '<p>Please enter an item name to search.</p>'; } } // ------------------ Display Show Bazaar Items ------------------ function displayShowBazaarItems(items, itemName = '') { const resultsContainer = document.getElementById('showBazaarResults'); resultsContainer.innerHTML = ''; if (!items || items.length === 0) { resultsContainer.innerHTML = '<p>No items found in registered bazaars.</p>'; return; } // Create table const table = document.createElement('table'); table.className = 'bazaar-table'; table.style.width = '100%'; table.style.borderCollapse = 'collapse'; table.style.minWidth = '600px'; // Ensures table has a minimum width const thead = document.createElement('thead'); const headerRow = document.createElement('tr'); const headers = ['Image', 'Item Name', 'Owner', 'Price ($)', 'Quantity', 'Visit Bazaar']; headers.forEach(header => { const th = document.createElement('th'); th.innerText = header; th.style.border = '1px solid #ccc'; th.style.padding = '8px'; th.style.backgroundColor = '#f2f2f2'; th.style.textAlign = 'center'; headerRow.appendChild(th); }); thead.appendChild(headerRow); table.appendChild(thead); const tbody = document.createElement('tbody'); items.forEach(itemData => { const item = itemData.item; const tr = document.createElement('tr'); // Image const imgCell = document.createElement('td'); imgCell.style.border = '1px solid #ccc'; imgCell.style.padding = '4px'; imgCell.style.textAlign = 'center'; const img = document.createElement('img'); img.src = `/images/items/${item.ID}/small.png`; img.alt = item.name; img.style.height = '30px'; imgCell.appendChild(img); tr.appendChild(imgCell); // Item Name const nameCell = document.createElement('td'); nameCell.innerText = item.name; nameCell.setAttribute('data-label', 'Item Name'); nameCell.style.border = '1px solid #ccc'; nameCell.style.padding = '8px'; nameCell.style.textAlign = 'center'; tr.appendChild(nameCell); // Owner const ownerCell = document.createElement('td'); ownerCell.innerText = itemData.owner; ownerCell.setAttribute('data-label', 'Owner'); ownerCell.style.border = '1px solid #ccc'; ownerCell.style.padding = '8px'; ownerCell.style.textAlign = 'center'; tr.appendChild(ownerCell); // Price ($) const priceTd = document.createElement('td'); priceTd.innerText = `$${item.price.toLocaleString()}`; priceTd.setAttribute('data-label', 'Price ($)'); priceTd.style.border = '1px solid #ccc'; priceTd.style.padding = '8px'; priceTd.style.textAlign = 'center'; tr.appendChild(priceTd); // Quantity const quantityTd = document.createElement('td'); quantityTd.innerText = item.quantity; quantityTd.setAttribute('data-label', 'Quantity'); quantityTd.style.border = '1px solid #ccc'; quantityTd.style.padding = '8px'; quantityTd.style.textAlign = 'center'; tr.appendChild(quantityTd); // Visit Bazaar const bazaarTd = document.createElement('td'); bazaarTd.style.border = '1px solid #ccc'; bazaarTd.style.padding = '8px'; bazaarTd.style.textAlign = 'center'; const bazaarLink = document.createElement('a'); bazaarLink.href = `https://www.torn.com/bazaar.php?userID=${itemData.user_id}`; bazaarLink.textContent = 'Visit'; bazaarLink.target = '_blank'; bazaarLink.style.color = '#007bff'; bazaarLink.style.textDecoration = 'none'; bazaarLink.addEventListener('mouseover', () => { bazaarLink.style.textDecoration = 'underline'; }); bazaarLink.addEventListener('mouseout', () => { bazaarLink.style.textDecoration = 'none'; }); bazaarTd.appendChild(bazaarLink); bazaarTd.setAttribute('data-label', 'Visit Bazaar'); tr.appendChild(bazaarTd); tbody.appendChild(tr); }); table.appendChild(tbody); const tableWrapper = document.createElement('div'); tableWrapper.style.overflowX = 'auto'; tableWrapper.style.webkitOverflowScrolling = 'touch'; // Smooth scrolling on iOS tableWrapper.appendChild(table); resultsContainer.appendChild(tableWrapper); adjustOneDollarTableTheme(); } // ------------------ API Key Management ------------------ function registerApiKey(apiKey) { console.log('IronNerd Bazaar Enhancements: Registering API Key:', apiKey); const modal = document.getElementById('bazaar-enhancer-modal'); const registerButton = modal.querySelector('#registerBazaar'); registerButton.disabled = true; const spinner = createLoadingSpinner(); registerButton.parentNode.insertBefore(spinner, registerButton.nextSibling); GM_xmlhttpRequest({ method: 'POST', url: 'https://www.ironnerd.me/add_bazaar_api_key', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ api_key: apiKey }), onload: function(response) { spinner.remove(); registerButton.disabled = false; console.log('IronNerd Bazaar Enhancements: Response Status:', response.status); console.log('IronNerd Bazaar Enhancements: Response Text:', response.responseText); try { const data = JSON.parse(response.responseText); if (response.status === 201) { displayStatusMessage('success', 'Bazaar registered successfully.'); } else if (response.status === 200) { if (data.status === 'info') { displayStatusMessage('info', data.message); } else { displayStatusMessage('error', data.message || 'Error registering bazaar.'); } } else if (response.status === 403) { displayStatusMessage('error', data.message || 'Registration forbidden.'); } else { displayStatusMessage('error', 'Error registering bazaar.'); console.error('IronNerd Bazaar Enhancements: Register Bazaar Error:', response.responseText); } } catch (e) { displayStatusMessage('error', 'Unexpected response format.'); console.error('IronNerd Bazaar Enhancements: Parsing Error:', e); } }, onerror: function(error) { spinner.remove(); registerButton.disabled = false; displayStatusMessage('error', 'Network error occurred. Please try again later.'); console.error('IronNerd Bazaar Enhancements: Network Error:', error); } }); } function unregisterApiKey(apiKey) { console.log('IronNerd Bazaar Enhancements: Unregistering API Key:', apiKey); const modal = document.getElementById('bazaar-enhancer-modal'); const removeButton = modal.querySelector('#removeBazaar'); removeButton.disabled = true; const spinner = createLoadingSpinner(); removeButton.parentNode.insertBefore(spinner, removeButton.nextSibling); GM_xmlhttpRequest({ method: 'POST', url: 'https://www.ironnerd.me/remove_bazaar_api_key', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ api_key: apiKey }), onload: function(response) { spinner.remove(); removeButton.disabled = false; console.log('IronNerd Bazaar Enhancements: Response Status:', response.status); console.log('IronNerd Bazaar Enhancements: Response Text:', response.responseText); try { const data = JSON.parse(response.responseText); if (response.status === 200) { displayStatusMessage('success', 'Bazaar removed successfully.'); GM_setValue('tornApiKey', ''); modal.querySelector('#apiKey').value = ''; } else { displayStatusMessage('error', data.message || 'Error removing bazaar.'); console.error('IronNerd Bazaar Enhancements: Unregister Bazaar Error:', response.responseText); } } catch (e) { displayStatusMessage('error', 'Unexpected response format.'); console.error('IronNerd Bazaar Enhancements: Parsing Error:', e); } }, onerror: function(error) { spinner.remove(); removeButton.disabled = false; displayStatusMessage('error', 'Network error occurred. Please try again later.'); console.error('IronNerd Bazaar Enhancements: Network Error:', error); } }); } // ------------------ Check Bazaar Status ------------------ function checkBazaarStatus(apiKey) { console.log('IronNerd Bazaar Enhancements: Checking Bazaar Status for API Key:', apiKey); GM_xmlhttpRequest({ method: 'POST', url: 'https://www.ironnerd.me/check_bazaar_status', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ api_key: apiKey }), onload: function(response) { console.log('IronNerd Bazaar Enhancements: Check Status Response Status:', response.status); console.log('IronNerd Bazaar Enhancements: Check Status Response Text:', response.responseText); try { const data = JSON.parse(response.responseText); if (response.status === 200) { if (data.status === 'info') { displayStatusMessage('info', data.message); } else { displayStatusMessage('error', data.message || 'Error checking bazaar status.'); } } else { displayStatusMessage('error', 'Error checking bazaar status.'); console.error('IronNerd Bazaar Enhancements: Check Bazaar Status Error:', response.responseText); } } catch (e) { displayStatusMessage('error', 'Unexpected response format.'); console.error('IronNerd Bazaar Enhancements: Parsing Error:', e); } }, onerror: function(error) { displayStatusMessage('error', 'Network error occurred. Please try again later.'); console.error('IronNerd Bazaar Enhancements: Network Error:', error); } }); } // ------------------ Display Status Messages ------------------ function displayStatusMessage(status, message) { const modal = document.getElementById('bazaar-enhancer-modal'); const statusDiv = modal.querySelector('#statusMessage'); if (!statusDiv) return; statusDiv.innerHTML = ''; const icon = document.createElement('span'); icon.style.marginRight = '8px'; if (status === 'success') { icon.textContent = '✅'; statusDiv.style.color = '#155724'; statusDiv.style.backgroundColor = '#d4edda'; } else if (status === 'error') { icon.textContent = '❌'; statusDiv.style.color = '#721c24'; statusDiv.style.backgroundColor = '#f8d7da'; } else if (status === 'info') { icon.textContent = 'ℹ️'; statusDiv.style.color = '#004085'; statusDiv.style.backgroundColor = '#cce5ff'; } const messageSpan = document.createElement('span'); messageSpan.textContent = message; statusDiv.appendChild(icon); statusDiv.appendChild(messageSpan); statusDiv.style.padding = '5px'; statusDiv.style.borderRadius = '3px'; statusDiv.style.display = 'flex'; statusDiv.style.alignItems = 'center'; statusDiv.style.transition = 'background-color 0.3s, color 0.3s'; setTimeout(() => { statusDiv.textContent = ''; statusDiv.style.display = 'none'; }, 5000); } function displayShowBazaarStatusMessage(status, message) { const statusDiv = document.getElementById('showBazaarStatusMessage'); if (!statusDiv) return; statusDiv.innerHTML = ''; const icon = document.createElement('span'); icon.style.marginRight = '8px'; if (status === 'success') { icon.textContent = '✅'; statusDiv.style.color = '#155724'; statusDiv.style.backgroundColor = '#d4edda'; } else if (status === 'error') { icon.textContent = '❌'; statusDiv.style.color = '#721c24'; statusDiv.style.backgroundColor = '#f8d7da'; } else if (status === 'info') { icon.textContent = 'ℹ️'; statusDiv.style.color = '#004085'; statusDiv.style.backgroundColor = '#cce5ff'; } const messageSpan = document.createElement('span'); messageSpan.textContent = message; statusDiv.appendChild(icon); statusDiv.appendChild(messageSpan); statusDiv.style.padding = '5px'; statusDiv.style.borderRadius = '3px'; statusDiv.style.display = 'flex'; statusDiv.style.alignItems = 'center'; statusDiv.style.transition = 'background-color 0.3s, color 0.3s'; setTimeout(() => { statusDiv.textContent = ''; statusDiv.style.display = 'none'; }, 5000); } function displayErrorMessage(message) { displayStatusMessage('error', message); } // ------------------ Detect Search (Old Functionality) ------------------ function detectSearch() { window.addEventListener('hashchange', onHashChange, false); window.addEventListener('popstate', onHashChange, false); onHashChange(); } function onHashChange() { const itemName = getItemNameFromUrl(); if (itemName) { fetchBazaarItems(itemName); } } function getItemNameFromUrl() { let itemName = null; const hash = window.location.hash; if (hash && hash.includes('itemName=')) { const hashParams = new URLSearchParams(hash.substring(hash.indexOf('?') + 1)); itemName = hashParams.get('itemName'); console.log('IronNerd Bazaar Enhancements: Extracted itemName from hash:', itemName); } if (!itemName) { const searchParams = new URLSearchParams(window.location.search); itemName = searchParams.get('itemName'); console.log('IronNerd Bazaar Enhancements: Extracted itemName from search:', itemName); } if (itemName) { return decodeURIComponent(itemName.replace(/\+/g, ' ')); } return null; } function fetchBazaarItems(itemName) { console.log('IronNerd Bazaar Enhancements: Fetching bazaar items for:', itemName); GM_xmlhttpRequest({ method: 'GET', url: `https://www.ironnerd.me/search_bazaar_items?item_name=${encodeURIComponent(itemName)}`, onload: function(response) { if (response.status === 200) { try { const data = JSON.parse(response.responseText); displayBazaarItems(data.bazaar_items, itemName); } catch (e) { displayErrorMessage('Error parsing server response.'); console.error('IronNerd Bazaar Enhancements: Parse Error:', e); } } else { displayErrorMessage('Error fetching bazaar items.'); console.error('IronNerd Bazaar Enhancements: Fetch Bazaar Items Error:', response.responseText); } }, onerror: function(error) { displayErrorMessage('Network error occurred. Please try again later.'); console.error('IronNerd Bazaar Enhancements: Network Error:', error); } }); } // ------------------ Display Bazaar Items (Old Functionality) ------------------ function displayBazaarItems(items, itemName = '') { console.log('IronNerd Bazaar Enhancements: displayBazaarItems - itemName:', itemName); let container = document.getElementById('bazaar-enhancer-container'); if (!container) { container = document.createElement('div'); container.id = 'bazaar-enhancer-container'; container.style.marginTop = '20px'; const delimiter = document.querySelector('.delimiter___zFh2E'); if (delimiter && delimiter.parentNode) { delimiter.parentNode.insertBefore(container, delimiter.nextSibling); } else { document.body.appendChild(container); } } container.innerHTML = ''; const title = document.createElement('h2'); title.textContent = `Bazaar Listings for "${itemName}"`; title.style.textAlign = 'center'; container.appendChild(title); if (items.length === 0) { const noItemsMessage = document.createElement('p'); noItemsMessage.textContent = 'No items found in registered bazaars.'; noItemsMessage.style.textAlign = 'center'; container.appendChild(noItemsMessage); return; } const tableWrapper = document.createElement('div'); tableWrapper.style.overflowX = 'auto'; tableWrapper.style.webkitOverflowScrolling = 'touch'; const table = document.createElement('table'); table.style.width = '100%'; table.style.borderCollapse = 'collapse'; table.style.minWidth = '600px'; const thead = document.createElement('thead'); const headerRow = document.createElement('tr'); const headers = ['Image', 'Item Name', 'Owner', 'Type', 'Quantity', 'Price ($)', 'Market Price ($)', 'Visit Bazaar']; headers.forEach(headerText => { const th = document.createElement('th'); th.textContent = headerText; th.style.color = 'black'; th.style.border = '1px solid #ccc'; th.style.padding = '6px'; th.style.backgroundColor = '#f2f2f2'; th.style.textAlign = 'center'; headerRow.appendChild(th); }); thead.appendChild(headerRow); table.appendChild(thead); const tbody = document.createElement('tbody'); items.forEach(itemData => { const item = itemData.item; const tr = document.createElement('tr'); // Image const imgCell = document.createElement('td'); imgCell.style.border = '1px solid #ccc'; imgCell.style.padding = '4px'; imgCell.style.textAlign = 'center'; const img = document.createElement('img'); img.src = `/images/items/${item.ID}/small.png`; img.alt = item.name; img.style.height = '30px'; imgCell.appendChild(img); tr.appendChild(imgCell); // Item Name const nameCell = document.createElement('td'); nameCell.innerText = item.name; nameCell.setAttribute('data-label', 'Item Name'); nameCell.style.border = '1px solid #ccc'; nameCell.style.padding = '6px'; nameCell.style.textAlign = 'center'; tr.appendChild(nameCell); // Owner const ownerCell = document.createElement('td'); ownerCell.setAttribute('data-label', 'Owner'); ownerCell.style.border = '1px solid #ccc'; ownerCell.style.padding = '6px'; ownerCell.style.textAlign = 'center'; const ownerLink = document.createElement('a'); ownerLink.href = `https://www.torn.com/profiles.php?XID=${itemData.user_id}`; ownerLink.textContent = itemData.owner; ownerLink.target = '_blank'; ownerLink.style.color = 'inherit'; ownerCell.appendChild(ownerLink); tr.appendChild(ownerCell); // Type const typeCell = document.createElement('td'); typeCell.innerText = item.type || 'N/A'; typeCell.setAttribute('data-label', 'Type'); typeCell.style.border = '1px solid #ccc'; typeCell.style.padding = '6px'; typeCell.style.textAlign = 'center'; tr.appendChild(typeCell); // Quantity const quantityCell = document.createElement('td'); quantityCell.innerText = item.quantity; quantityCell.setAttribute('data-label', 'Quantity'); quantityCell.style.border = '1px solid #ccc'; quantityCell.style.padding = '6px'; quantityCell.style.textAlign = 'center'; tr.appendChild(quantityCell); // Price ($) const priceTd = document.createElement('td'); priceTd.innerText = `$${item.price.toLocaleString()}`; priceTd.setAttribute('data-label', 'Price ($)'); priceTd.style.border = '1px solid #ccc'; priceTd.style.padding = '6px'; priceTd.style.textAlign = 'center'; tr.appendChild(priceTd); // Market Price ($) const marketPriceTd = document.createElement('td'); marketPriceTd.innerText = item.market_price ? `$${item.market_price.toLocaleString()}` : 'N/A'; marketPriceTd.setAttribute('data-label', 'Market Price ($)'); marketPriceTd.style.border = '1px solid #ccc'; marketPriceTd.style.padding = '6px'; marketPriceTd.style.textAlign = 'center'; tr.appendChild(marketPriceTd); // Visit Bazaar const bazaarTd = document.createElement('td'); bazaarTd.style.border = '1px solid #ccc'; bazaarTd.style.padding = '6px'; bazaarTd.style.textAlign = 'center'; const bazaarLink = document.createElement('a'); bazaarLink.href = `https://www.torn.com/bazaar.php?userID=${itemData.user_id}`; bazaarLink.textContent = 'Visit'; bazaarLink.target = '_blank'; bazaarLink.style.color = '#007bff'; bazaarLink.style.textDecoration = 'none'; bazaarLink.addEventListener('mouseover', () => { bazaarLink.style.textDecoration = 'underline'; }); bazaarLink.addEventListener('mouseout', () => { bazaarLink.style.textDecoration = 'none'; }); bazaarTd.appendChild(bazaarLink); bazaarTd.setAttribute('data-label', 'Visit Bazaar'); tr.appendChild(bazaarTd); tbody.appendChild(tr); }); table.appendChild(tbody); tableWrapper.appendChild(table); container.appendChild(tableWrapper); adjustOneDollarTableTheme(); } // ------------------ API Key Validation ------------------ function isValidApiKey(apiKey) { const apiKeyPattern = /^[A-Za-z0-9]{16}$/; return apiKeyPattern.test(apiKey); } // ------------------ Theme Adjustment ------------------ function adjustOneDollarTableTheme() { const isDarkMode = document.body.classList.contains('darkMode___3kucI'); const oneDollarTable = document.querySelector('.one-dollar-table'); const bazaarTable = document.querySelector('.bazaar-table'); if (isDarkMode) { if (oneDollarTable) { oneDollarTable.style.backgroundColor = '#1c1c1c'; oneDollarTable.style.color = '#f0f0f0'; oneDollarTable.querySelectorAll('th').forEach(th => { th.style.backgroundColor = '#444'; th.style.color = '#ffffff'; }); oneDollarTable.querySelectorAll('tr:nth-child(even)').forEach(tr => { tr.style.backgroundColor = '#2a2a2a'; }); oneDollarTable.querySelectorAll('tr:nth-child(odd)').forEach(tr => { tr.style.backgroundColor = '#1e1e1e'; }); oneDollarTable.querySelectorAll('td a').forEach(a => { a.style.color = '#4ea8de'; }); } if (bazaarTable) { bazaarTable.style.backgroundColor = '#1c1c1c'; bazaarTable.style.color = '#f0f0f0'; bazaarTable.querySelectorAll('th').forEach(th => { th.style.backgroundColor = '#444'; th.style.color = '#ffffff'; }); bazaarTable.querySelectorAll('tr:nth-child(even)').forEach(tr => { tr.style.backgroundColor = '#2a2a2a'; }); bazaarTable.querySelectorAll('tr:nth-child(odd)').forEach(tr => { tr.style.backgroundColor = '#1e1e1e'; }); bazaarTable.querySelectorAll('td a').forEach(a => { a.style.color = '#4ea8de'; }); } } else { if (oneDollarTable) { oneDollarTable.style.backgroundColor = '#fff'; oneDollarTable.style.color = '#000'; oneDollarTable.querySelectorAll('th').forEach(th => { th.style.backgroundColor = '#f2f2f2'; th.style.color = '#000'; }); oneDollarTable.querySelectorAll('tr:nth-child(even)').forEach(tr => { tr.style.backgroundColor = '#f9f9f9'; }); oneDollarTable.querySelectorAll('tr:nth-child(odd)').forEach(tr => { tr.style.backgroundColor = '#fff'; }); oneDollarTable.querySelectorAll('td a').forEach(a => { a.style.color = '#007bff'; }); } if (bazaarTable) { bazaarTable.style.backgroundColor = '#fff'; bazaarTable.style.color = '#000'; bazaarTable.querySelectorAll('th').forEach(th => { th.style.backgroundColor = '#f2f2f2'; th.style.color = '#000'; }); bazaarTable.querySelectorAll('tr:nth-child(even)').forEach(tr => { tr.style.backgroundColor = '#f9f9f9'; }); bazaarTable.querySelectorAll('tr:nth-child(odd)').forEach(tr => { tr.style.backgroundColor = '#fff'; }); bazaarTable.querySelectorAll('td a').forEach(a => { a.style.color = '#007bff'; }); } } } // ------------------ Get Current Search Term ------------------ function getCurrentSearchTerm() { const urlParams = new URLSearchParams(window.location.search); let itemName = urlParams.get('itemName'); if (!itemName) { const searchInput = document.querySelector('input[type="text"][name="itemName"], input#itemName'); if (searchInput) { itemName = searchInput.value.trim(); } } console.log('IronNerd Bazaar Enhancements: Current search term:', itemName); return itemName; } })();