xd2shuffle

ARS to USD converter for shuffle.com (text + numbers)

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

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

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

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

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

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         xd2shuffle
// @namespace    http://tampermonkey.net/
// @version      7.7.7.8
// @description  ARS to USD converter for shuffle.com (text + numbers)
// @author       fusi | @loficat on tg | codedfusi on github | Modified by user
// @match        *://*.shuffle.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function () {
    // ==========================================
    // SET THE EXCHANGE RATE HERE
    // Example: 1 USD = 1400 ARS
    // ==========================================
    const USD_RATE = 1400;  // <-- CHANGE THIS NUMBER to the current rate

    // Store modified nodes to avoid double processing
    const processedTextNodes = new WeakSet();
    const processedImages = new WeakSet();

    // Helper: Convert ARS number string to USD formatted string
    function convertARStextToUSD(text) {
        // Match numbers that could be ARS amounts (including commas and decimals)
        // This looks for patterns like: 1,234,567.89 or 1.234.567,89 or just 1234
        const arsNumberPattern = /(\b[\d,]+(?:\.\d+)?\b)|(\b[\d.]+(?:,\d+)?\b)/g;

        return text.replace(arsNumberPattern, (match) => {
            // Clean the match: remove commas (for US style) or dots (for EU style)
            let cleanNumber = match.replace(/,/g, '');
            // If it has a dot and then exactly 2 digits at the end, it might be decimal
            // For EU style like 1.234,56 -> replace dot with empty and comma with dot
            if (cleanNumber.includes('.') && cleanNumber.includes(',')) {
                cleanNumber = cleanNumber.replace(/\./g, '').replace(/,/, '.');
            } else if (cleanNumber.includes(',')) {
                // If only commas, treat as decimal separator (EU)
                cleanNumber = cleanNumber.replace(/,/, '.');
            }

            const arsValue = parseFloat(cleanNumber);
            if (isNaN(arsValue)) return match;

            const usdValue = arsValue / USD_RATE;
            // Format USD with 2 decimal places, using US notation
            return usdValue.toLocaleString('en-US', {
                minimumFractionDigits: 2,
                maximumFractionDigits: 2
            });
        });
    }

    function processTextNode(node) {
        if (node.nodeType === 3 && node.nodeValue && !processedTextNodes.has(node)) {
            let original = node.nodeValue;
            let modified = false;
            let newValue = original;

            // Replace ARS symbol with $
            if (newValue.includes("ARS")) {
                newValue = newValue.replace(/ARS/g, "$");
                modified = true;
            }

            // Convert ARS numbers to USD (if text contains numbers)
            if (/\d/.test(newValue)) {
                const converted = convertARStextToUSD(newValue);
                if (converted !== newValue) {
                    newValue = converted;
                    modified = true;
                }
            }

            if (modified) {
                node.nodeValue = newValue;
                processedTextNodes.add(node);
            }
        }
    }

    function processImageElement(el) {
        if (el.nodeType === 1 && el.hasAttribute("src") && !processedImages.has(el)) {
            const src = el.getAttribute("src");
            if (src && src.includes("/icons/fiat/ARS.svg")) {
                el.setAttribute("src", src.replace("/icons/fiat/ARS.svg", "/icons/fiat/USD.svg"));
                processedImages.add(el);
            }
        }
    }

    function walkAndProcess(root) {
        if (!root) return;

        // Process text nodes
        const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
        let node;
        while ((node = walker.nextNode())) {
            processTextNode(node);
        }

        // Process image elements
        const images = root.querySelectorAll('img[src*="/icons/fiat/ARS.svg"]');
        images.forEach(img => processImageElement(img));
    }

    // MutationObserver callback to handle dynamically added content
    function onMutation(mutations) {
        for (const mutation of mutations) {
            if (mutation.type === 'childList') {
                for (const addedNode of mutation.addedNodes) {
                    if (addedNode.nodeType === 1) {
                        walkAndProcess(addedNode);
                    } else if (addedNode.nodeType === 3) {
                        processTextNode(addedNode);
                    }
                }
            }
        }
        // Also periodically re-check text nodes that might have changed value
        // (We use a weak set so we only reprocess if the node was garbage collected)
    }

    // Start the script once the DOM is ready
    document.addEventListener("DOMContentLoaded", () => {
        walkAndProcess(document.body);

        const observer = new MutationObserver(onMutation);
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
})();