Web3 OKX Color Theme Addon

Automaticly color theme changer

// ==UserScript==
// @name         Web3 OKX Color Theme Addon
// @namespace    http://tampermonkey.net/
// @version      2
// @description  Automaticly color theme changer
// @author       mamiis
// @match        https://web3.okx.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function(){
    'use strict';

    let UP_COLOR = {r:37,  g:167, b:80};
    let DOWN_COLOR = {r:202,g:63,  b:100};

    // Chart filters artık UP_COLOR ve DOWN_COLOR'dan bağımsız
    let CHART_FILTERS = {
        green: { hue: 210, saturation: 1.6, brightness: 1.05 },
        red: { hue: 280, saturation: 1.3, brightness: 1.1 }
    };

    let activeModal = null;
    let currentColorType = null;

    function loadUserSettings() {
        try {
            const saved = localStorage.getItem('okx_color_settings');
            if (saved) {
                const settings = JSON.parse(saved);
                if (settings.upColor) UP_COLOR = settings.upColor;
                if (settings.downColor) DOWN_COLOR = settings.downColor;
                if (settings.filters) CHART_FILTERS = settings.filters;
            }
        } catch (e) {
            console.log('Settings not loaded, using defaults');
        }
    }

    function saveUserSettings() {
        try {
            const settings = {
                upColor: UP_COLOR,
                downColor: DOWN_COLOR,
                filters: CHART_FILTERS
            };
            localStorage.setItem('okx_color_settings', JSON.stringify(settings));
        } catch (e) {
            console.log('Settings not saved');
        }
    }

    function applySettings() {
        kickAll();
        applyChartColorFilters();
    }

    function refreshPage() {
        window.location.reload();
    }

    function toggleThemeForRefresh() {
        const themeButtons = document.querySelectorAll('.nav-r-theme-item');
        if (themeButtons.length >= 3) {
            const currentTheme = document.querySelector('.nav-r-theme-item.nav-r-th-it-sel');
            if (currentTheme) {
                const lightTheme = themeButtons[1];
                if (lightTheme && !lightTheme.classList.contains('nav-r-th-it-sel')) {
                    lightTheme.click();
                    setTimeout(() => {
                        currentTheme.click();
                        setTimeout(() => {
                            applySettings();
                            setTimeout(refreshPage, 100);
                        }, 100);
                    }, 100);
                } else {
                    const darkTheme = themeButtons[2];
                    if (darkTheme && !darkTheme.classList.contains('nav-r-th-it-sel')) {
                        darkTheme.click();
                        setTimeout(() => {
                            currentTheme.click();
                            setTimeout(() => {
                                applySettings();
                                setTimeout(refreshPage, 100);
                            }, 100);
                        }, 100);
                    } else {
                        applySettings();
                        setTimeout(refreshPage, 100);
                    }
                }
            } else {
                applySettings();
                setTimeout(refreshPage, 100);
            }
        } else {
            applySettings();
            setTimeout(refreshPage, 100);
        }
    }

    /* ---------- IMPROVED COLOR PICKER MENU ---------- */

    function addColorPickerToMenu() {
        const themeSection = document.querySelector('.nav-r-pan-item:has(.nav-r-item-name)');
        if (!themeSection || !themeSection.querySelector('.nav-r-theme-box')) {
            setTimeout(addColorPickerToMenu, 1000);
            return;
        }

        if (document.querySelector('.nav-r-color-picker-item')) {
            return;
        }

        const colorPickerHTML = `
            <div class="nav-r-pan-item nav-r-color-picker-item" style="margin: 8px 0;">
                <span class="nav-r-item-name">Chart Colors</span>
                <div class="nav-r-theme-box" style="display: flex; align-items: center; gap: 4px; margin: 0 -2px;">

                    <button type="button" class="nav-r-theme-item nav-r-color-item" data-color="up" title="Up Color">
                        <div class="color-swatch" style="width: 100%; height: 100%; background-color: rgb(${UP_COLOR.r}, ${UP_COLOR.g}, ${UP_COLOR.b})"></div>
                    </button>

                    <button type="button" class="nav-r-theme-item nav-r-color-item" data-color="down" title="Down Color">
                        <div class="color-swatch" style="width: 100%; height: 100%; background-color: rgb(${DOWN_COLOR.r}, ${DOWN_COLOR.g}, ${DOWN_COLOR.b})"></div>
                    </button>

                    <button type="button" class="nav-r-theme-item nav-r-color-item" data-color="reset" title="Reset to Default Colors">
                        <i class="icon okx-header-footer-reset"></i>
                    </button>

                    <button type="button" class="nav-r-theme-item nav-r-apply-item" data-action="apply" title="Apply and Refresh">
                        <i class="icon okx-header-footer-check"></i>
                    </button>

                </div>
            </div>
        `;

        themeSection.insertAdjacentHTML('afterend', colorPickerHTML);
        addColorPickerStyles();
        addColorPickerEvents();
    }

    function addColorPickerStyles() {
        const style = document.createElement('style');
        style.textContent = `
            .nav-r-color-picker-item {
                min-height: 36px !important;
                padding: 2px 0 !important;
            }

            .nav-r-color-picker-item .nav-r-item-name {
                margin-bottom: 2px !important;
                display: block;
            }

            .nav-r-color-picker-item .nav-r-theme-box {
                display: flex !important;
                align-items: center !important;
                gap: 4px !important;
                margin: 0 -2px !important;
                margin-top: 2px !important;
            }

            .nav-r-color-picker-item .nav-r-theme-item {
                position: relative;
                width: 30px !important;
                height: 30px !important;
                border-radius: 6px;
                border: 2px solid var(--border-color, #2a2a2a);
                background: transparent;
                cursor: pointer;
                display: flex;
                align-items: center;
                justify-content: center;
                transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                padding: 0 !important;
                margin: 0 !important;
                overflow: hidden;
                flex-shrink: 0;
                box-sizing: border-box !important;
            }

            .nav-r-color-picker-item .nav-r-theme-item:hover {
                border-color: #cccccc;
                transform: translateY(-2px);
                box-shadow: 0 4px 12px rgba(204, 204, 204, 0.3);
            }

            .nav-r-color-picker-item .color-swatch {
                width: 100% !important;
                height: 100% !important;
                border-radius: 4px;
                border: 1px solid rgba(255,255,255,0.3);
                transition: all 0.3s ease;
                display: block !important;
                box-sizing: border-box !important;
                margin: 0 !important;
                padding: 0 !important;
                min-width: 100% !important;
                min-height: 100% !important;
            }

            .nav-r-color-picker-item .nav-r-theme-item:hover .color-swatch {
                transform: scale(1.01);
            }

            .nav-r-color-picker-item .nav-r-theme-item i {
                font-size: 14px;
                color: var(--text-color, #fff);
                transition: all 0.3s ease;
                display: flex;
                align-items: center;
                justify-content: center;
                width: 100%;
                height: 100%;
            }

            .nav-r-color-picker-item .nav-r-theme-item:hover i {
                color: #cccccc;
            }

            .nav-r-apply-item {
                background: linear-gradient(135deg, #666666, #888888) !important;
                border: none !important;
            }

            .nav-r-apply-item:hover {
                background: linear-gradient(135deg, #888888, #aaaaaa) !important;
                transform: translateY(-2px) scale(1.05);
            }

            /* Improved Color Picker Modal */
            .color-picker-modal {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                display: flex;
                align-items: center;
                justify-content: center;
                z-index: 10000;
                opacity: 0;
                animation: modalFadeIn 0.3s ease forwards;
            }

            @keyframes modalFadeIn {
                from { opacity: 0; }
                to { opacity: 1; }
            }

            @keyframes modalFadeOut {
                from { opacity: 1; }
                to { opacity: 0; }
            }

            .color-picker-content {
                background: #1a1a1a;
                border-radius: 16px;
                padding: 20px;
                width: 350px;
                max-width: 90vw;
                border: 1px solid #333;
                box-shadow: 0 20px 40px rgba(0,0,0,0.5);
                transform: scale(0.9);
                animation: contentSlideIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
            }

            @keyframes contentSlideIn {
                from { transform: scale(0.9); opacity: 0; }
                to { transform: scale(1); opacity: 1; }
            }

            @keyframes contentSlideOut {
                from { transform: scale(1); opacity: 1; }
                to { transform: scale(0.9); opacity: 0; }
            }

            .color-picker-title {
                color: white;
                margin-bottom: 12px;
                font-size: 16px;
                text-align: center;
                font-weight: 600;
            }

            .color-type-switcher {
                display: flex;
                gap: 6px;
                margin-bottom: 12px;
                justify-content: center;
            }

            .color-type-btn {
                padding: 6px 10px;
                border: 1px solid #333;
                background: #2a2a2a;
                color: white;
                border-radius: 6px;
                cursor: pointer;
                transition: all 0.3s ease;
                font-size: 11px;
                flex: 1;
                max-width: 100px;
            }

            .color-type-btn:hover {
                background: #3a3a3a;
            }

            .color-type-btn.active {
                background: #444;
                border-color: #666;
            }

            .color-categories-container {
                max-height: 350px;
                overflow-y: auto;
                padding-right: 3px;
                margin-bottom: 12px;
            }

            .color-category {
                margin-bottom: 12px;
            }

            .color-category-title {
                color: white;
                font-size: 11px;
                font-weight: 600;
                margin-bottom: 5px;
                padding-bottom: 2px;
                border-bottom: 1px solid #333;
            }

            .color-category-grid {
                display: flex;
                flex-wrap: wrap;
                gap: 3px;
                margin-bottom: 6px;
            }

            .color-option {
                width: 24px;
                height: 24px;
                border-radius: 3px;
                border: 2px solid transparent;
                cursor: pointer;
                transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
                position: relative;
                flex-shrink: 0;
            }

            .color-option:hover {
                transform: scale(1.15);
                border-color: #cccccc;
                box-shadow: 0 4px 8px rgba(204, 204, 204, 0.3);
            }

            .color-option.selected {
                border-color: #cccccc;
                border-width: 2px;
                box-shadow: 0 0 0 2px rgba(204, 204, 204, 0.3);
            }

            .color-picker-actions {
                display: flex;
                gap: 8px;
                margin-top: 10px;
            }

            .color-action-btn {
                flex: 1;
                padding: 8px 12px;
                border: none;
                border-radius: 6px;
                cursor: pointer;
                font-size: 12px;
                font-weight: 600;
                transition: all 0.3s ease;
                text-align: center;
            }

            .color-apply-btn {
                background: linear-gradient(135deg, #666666, #888888);
                color: white;
            }

            .color-apply-btn:hover {
                background: linear-gradient(135deg, #888888, #aaaaaa);
                transform: translateY(-1px);
            }

            .color-default-btn {
                background: linear-gradient(135deg, #444444, #666666);
                color: white;
            }

            .color-default-btn:hover {
                background: linear-gradient(135deg, #666666, #888888);
                transform: translateY(-1px);
            }

            /* Scrollbar styling */
            .color-categories-container::-webkit-scrollbar {
                width: 4px;
            }

            .color-categories-container::-webkit-scrollbar-track {
                background: #2a2a2a;
                border-radius: 2px;
            }

            .color-categories-container::-webkit-scrollbar-thumb {
                background: #555;
                border-radius: 2px;
            }

            .color-categories-container::-webkit-scrollbar-thumb:hover {
                background: #777;
            }
        `;
        document.head.appendChild(style);
    }

    function addColorPickerEvents() {
        document.addEventListener('click', function(e) {
            if (e.target.closest('.nav-r-color-item')) {
                const btn = e.target.closest('.nav-r-color-item');
                e.stopPropagation();
                const colorType = btn.getAttribute('data-color');
                if (colorType === 'reset') {
                    resetToDefaultColors();
                } else {
                    closeActiveModal();
                    setTimeout(() => {
                        showColorPicker(colorType);
                    }, 50);
                }
            }

            if (e.target.closest('.nav-r-apply-item')) {
                const btn = e.target.closest('.nav-r-apply-item');
                toggleThemeForRefresh();
                showNotification('Colors applied successfully!');
            }
        });
    }

    function showNotification(message) {
        const oldNotifications = document.querySelectorAll('.okx-color-notification');
        oldNotifications.forEach(notif => notif.remove());

        const notification = document.createElement('div');
        notification.className = 'okx-color-notification';
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 24px;
            background: #4CAF50;
            color: white;
            padding: 10px 20px;
            border-radius: 4px;
            z-index: 10001;
            font-size: 14px;
            animation: slideIn 0.3s ease;
        `;
        notification.textContent = message;
        document.body.appendChild(notification);

        setTimeout(() => {
            notification.remove();
        }, 3000);
    }

    function closeActiveModal() {
        if (activeModal) {
            const escapeHandler = activeModal._escapeHandler;
            if (escapeHandler) {
                document.removeEventListener('keydown', escapeHandler);
            }

            activeModal.style.animation = 'modalFadeOut 0.2s ease forwards';
            const content = activeModal.querySelector('.color-picker-content');
            if (content) {
                content.style.animation = 'contentSlideOut 0.2s ease forwards';
            }

            setTimeout(() => {
                if (activeModal && activeModal.parentNode) {
                    activeModal.parentNode.removeChild(activeModal);
                }
                activeModal = null;
                currentColorType = null;
            }, 200);
        }
    }

    function showColorPicker(colorType) {
        if (activeModal) {
            closeActiveModal();
            setTimeout(() => {
                createColorPickerModal(colorType);
            }, 250);
        } else {
            createColorPickerModal(colorType);
        }
    }

    function createColorPickerModal(colorType) {
        currentColorType = colorType;

        const colorCategories = [
            {
                name: "Red",
                colors: ["#8B0000","#A52A2A","#B22222","#DC143C","#FF0000","#FF4D4D","#FF6666","#FF8080","#FF9999"]
            },
            {
                name: "Orange",
                colors: ["#FF4500","#FF5500","#FF6600","#FF7518","#FF7F50","#FF8C42","#FFA500","#FFB347","#FFC966"]
            },
            {
                name: "Yellow",
                colors: ["#FFD700","#FFE135","#FFE600","#FFEA00","#FFF200","#FFF700","#FFFC00","#FFFF33","#FFFF66"]
            },
            {
                name: "Green",
                colors: ["#006400","#008000","#228B22","#2E8B57","#3CB371","#66CDAA","#7FFF00","#90EE90","#98FB98"]
            },
            {
                name: "Blue",
                colors: ["#00008B","#0000CD","#0000FF","#1E90FF","#4169E1","#4682B4","#5F9EA0","#6495ED","#87CEFA"]
            },
            {
                name: "Purple",
                colors: ["#4B0082","#6A0DAD","#7B68EE","#8A2BE2","#9400D3","#9932CC","#BA55D3","#DA70D6","#EE82EE"]
            },
            {
                name: "Gray",
                colors: ["#2F4F4F","#4F4F4F","#696969","#808080","#A9A9A9","#B0B0B0","#C0C0C0","#D3D3D3","#E0E0E0"]
            },
            {
                name: "Brown",
                colors: ["#4B3621","#5C4033","#6B4226","#8B4513","#A0522D","#A0522D","#CD853F","#D2691E","#F4A460"]
            },
            {
                name: "Light Gray",
                colors: ["#DCDCDC","#E0E0E0","#E5E5E5","#EBEBEB","#F0F0F0","#F5F5F5","#FAFAFA","#FCFCFC","#FFFFFF"]
            }
        ];

        const currentColor = colorType === 'up' ? UP_COLOR : DOWN_COLOR;

        activeModal = document.createElement('div');
        activeModal.className = 'color-picker-modal';

        activeModal.innerHTML = `
        <div class="color-picker-content">
            <div class="color-picker-title">
                Select ${colorType === 'up' ? 'Up Color' : 'Down Color'}
            </div>
            <div class="color-type-switcher">
                <button class="color-type-btn ${colorType === 'up' ? 'active' : ''}" data-type="up">Up Color</button>
                <button class="color-type-btn ${colorType === 'down' ? 'active' : ''}" data-type="down">Down Color</button>
            </div>
            <div class="color-categories-container">
                ${colorCategories.map(category => `
                    <div class="color-category">
                        <div class="color-category-title">${category.name}</div>
                        <div class="color-category-grid">
                            ${category.colors.map((color, index) => {
            const isSelected = color === rgbToHex(currentColor.r, currentColor.g, currentColor.b);
            return `
                                    <div class="color-option ${isSelected ? 'selected' : ''}"
                                         style="background-color: ${color}"
                                         data-color="${color}"
                                         title="${color}">
                                    </div>
                                `;
        }).join('')}
                        </div>
                    </div>
                `).join('')}
            </div>
            <div class="color-picker-actions">
                <button class="color-action-btn color-default-btn" data-action="default">Default Colors</button>
                <button class="color-action-btn color-apply-btn" data-action="apply">Apply Colors</button>
            </div>
        </div>
    `;

        document.body.appendChild(activeModal);

        // Color type switcher events
        activeModal.querySelectorAll('.color-type-btn').forEach(btn => {
            btn.addEventListener('click', function(e) {
                e.stopPropagation();
                const newType = this.getAttribute('data-type');
                if (newType !== currentColorType) {
                    closeActiveModal();
                    setTimeout(() => {
                        showColorPicker(newType);
                    }, 50);
                }
            });
        });

        // Selection events - BU KISIM DEĞİŞTİ: Artık CHART_FILTERS güncellenmiyor
        activeModal.querySelectorAll('.color-option').forEach((option) => {
            option.addEventListener('click', function(e) {
                e.stopPropagation();
                const selectedHex = this.getAttribute('data-color');
                const parsedColor = parseHexColor(selectedHex);

                // Apply the color directly without affecting chart filters
                if (currentColorType === 'up') {
                    UP_COLOR = parsedColor;
                } else {
                    DOWN_COLOR = parsedColor;
                }

                // Update selection visually
                activeModal.querySelectorAll('.color-option').forEach(opt => {
                    opt.classList.remove('selected');
                });
                this.classList.add('selected');

                // Immediately update swatches and apply settings
                updateColorSwatches();
                applySettings();
                saveUserSettings();

                showNotification(`${currentColorType === 'up' ? 'Up' : 'Down'} color updated to ${selectedHex}`);
            });
        });

        // Action buttons
        activeModal.querySelectorAll('.color-action-btn').forEach(btn => {
            btn.addEventListener('click', function(e) {
                e.stopPropagation();
                const action = this.getAttribute('data-action');
                if (action === 'apply') {
                    applySettings();
                    updateColorSwatches();
                    saveUserSettings();
                    showNotification('Applying colors and refreshing page...');
                    closeActiveModal();
                    setTimeout(() => {
                        toggleThemeForRefresh();
                    }, 500);
                } else if (action === 'default') {
                    resetToDefaultColors();
                    closeActiveModal();
                }
            });
        });

        // Close on background click
        activeModal.addEventListener('click', function(e) {
            if (e.target === activeModal) {
                closeActiveModal();
            }
        });

        // Close on Escape key
        const escapeHandler = function(e) {
            if (e.key === 'Escape') {
                closeActiveModal();
            }
        };
        document.addEventListener('keydown', escapeHandler);
        activeModal._escapeHandler = escapeHandler;
    }

    function rgbToHex(r, g, b) {
        return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
    }

    function resetToDefaultColors() {
        UP_COLOR = { r: 37, g: 167, b: 80 };
        DOWN_COLOR = { r: 202, g: 63, b: 100 };

        // Chart filters artık dinamik olduğu için sabit değerlere gerek yok
        // CHART_FILTERS değişkenini kaldırabilirsiniz veya boş bırakabilirsiniz

        saveUserSettings();
        applySettings();
        updateColorSwatches();
        showNotification('Default colors restored!');
        setTimeout(() => {
            toggleThemeForRefresh();
        }, 1000);
    }

    function updateColorSwatches() {
        const upSwatch = document.querySelector('.nav-r-color-item[data-color="up"] .color-swatch');
        const downSwatch = document.querySelector('.nav-r-color-item[data-color="down"] .color-swatch');

        if (upSwatch) {
            upSwatch.style.backgroundColor = `rgb(${UP_COLOR.r}, ${UP_COLOR.g}, ${UP_COLOR.b})`;
        }
        if (downSwatch) {
            downSwatch.style.backgroundColor = `rgb(${DOWN_COLOR.r}, ${DOWN_COLOR.g}, ${DOWN_COLOR.b})`;
        }
    }

    /* ---------- EXISTING FUNCTIONS (Fixed) ---------- */

    const hexRegex = /#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g;
    const rgbRegex = /rgba?\([^\)]+\)/gi;
    const hslRegex = /hsla?\([^\)]+\)/gi;

    const _tmp = document.createElement('div');
    _tmp.style.position = 'absolute';
    _tmp.style.left = '-9999px';
    _tmp.style.width = _tmp.style.height = '1px';
    document.documentElement.appendChild(_tmp);

    function clamp(v, a=0, b=255){ return Math.max(a, Math.min(b, v)); }

    function parseHexColor(str){
        let s = str.replace('#','');
        if(s.length === 3) s = s.split('').map(ch => ch+ch).join('');
        else if(s.length === 4) s = s.split('').map(ch => ch+ch).join('');
        let r=0,g=0,b=0,a=1;
        if(s.length === 6){
            r = parseInt(s.substr(0,2),16); g = parseInt(s.substr(2,2),16); b = parseInt(s.substr(4,2),16);
        } else if(s.length === 8){
            r = parseInt(s.substr(0,2),16); g = parseInt(s.substr(2,2),16); b = parseInt(s.substr(4,2),16);
            a = parseInt(s.substr(6,2),16) / 255;
        }
        return {r,g,b,a};
    }

    function parseRgbString(str){
        const nums = str.match(/[\d\.%]+/g);
        if(!nums) return null;
        let [r,g,b,a] = [0,0,0,1];
        if(nums.length >= 3){
            const parseComponent = (v) => v.endsWith('%') ? Math.round(parseFloat(v) * 2.55) : Math.round(parseFloat(v));
            r = parseComponent(nums[0]); g = parseComponent(nums[1]); b = parseComponent(nums[2]);
        }
        if(nums.length >= 4) a = parseFloat(nums[3]);
        return {r,g,b,a};
    }

    function parseHslString(str){
        const parts = str.match(/[\d\.%]+/g);
        if(!parts) return null;
        let h = parseFloat(parts[0]), s = parseFloat(parts[1]) / 100, l = parseFloat(parts[2]) / 100;
        let a = parts.length >= 4 ? parseFloat(parts[3]) : 1;
        const rgb = hslToRgb(h, s, l);
        return {r: Math.round(rgb.r), g: Math.round(rgb.g), b: Math.round(rgb.b), a};
    }

    function hslToRgb(h, s, l){
        h = ((h % 360) + 360) % 360;
        const c = (1 - Math.abs(2*l - 1)) * s;
        const x = c * (1 - Math.abs((h / 60) % 2 - 1));
        const m = l - c/2;
        let r=0,g=0,b=0;
        if(h < 60) { r=c; g=x; b=0; } else if(h < 120) { r=x; g=c; b=0; } else if(h < 180) { r=0; g=c; b=x; }
        else if(h < 240) { r=0; g=x; b=c; } else if(h < 300) { r=x; g=0; b=c; } else { r=c; g=0; b=x; }
        return { r: (r+m)*255, g: (g+m)*255, b: (b+m)*255 };
    }

    function rgbToHsl(r,g,b){
        r/=255; g/=255; b/=255;
        const max = Math.max(r,g,b), min = Math.min(r,g,b);
        let h=0,s=0,l=(max+min)/2;
        if(max !== min){
            const d = max - min;
            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
            switch(max){
                case r: h = ((g - b) / d + (g < b ? 6 : 0)) * 60; break;
                case g: h = ((b - r) / d + 2) * 60; break;
                case b: h = ((r - g) / d + 4) * 60; break;
            }
        }
        return {h, s, l};
    }

    function parseColorString(str){
        if(!str) return null; str = str.trim();
        if(str.toLowerCase() === 'transparent' || str === 'none') return {r:0,g:0,b:0,a:0};
        try{
            if(str[0] === '#') return parseHexColor(str);
            if(str.toLowerCase().startsWith('rgb')) return parseRgbString(str);
            if(str.toLowerCase().startsWith('hsl')) return parseHslString(str);
            _tmp.style.color = ''; _tmp.style.color = str;
            const cs = getComputedStyle(_tmp).color;
            return parseRgbString(cs);
        }catch(e){ return null; }
    }

    function rgbaToCss(o){
        const a = (typeof o.a === 'number') ? o.a : 1;
        return `rgba(${Math.round(o.r)}, ${Math.round(o.g)}, ${Math.round(o.b)}, ${+a.toFixed(3)})`;
    }

    // BU FONKSİYON DEĞİŞTİ: Artık UP_COLOR ve DOWN_COLOR doğrudan kullanılıyor
    function shouldConvertByHue(rgba){
        if(!rgba || rgba.a === 0) return null;

        // Özel div için istisna - bu renk değişmesin
        const {h,s,l} = rgbToHsl(rgba.r, rgba.g, rgba.b);
        if(rgba.r === 230 && rgba.g === 181 && rgba.b === 117) return null;

        if(s > 0.08 && h >= 70 && h <= 170) return 'greenish';
        if(s > 0.08 && (h <= 25 || h >= 335)) return 'reddish';
        return null;
    }

    // BU FONKSİYON DEĞİŞTİ: Artık CHART_FILTERS yerine UP_COLOR ve DOWN_COLOR kullanılıyor
    function convertBasedOnDetection(rgba){
        const det = shouldConvertByHue(rgba);
        if(!det) return rgba;

        if(det === 'greenish'){
            return { ...UP_COLOR, a: rgba.a };
        } else if(det === 'reddish'){
            return { ...DOWN_COLOR, a: rgba.a };
        }
        return rgba;
    }

    function replaceColorTokensInText(text){
        if(!text || typeof text !== 'string') return text;
        let out = text;
        out = out.replace(hexRegex, (m) => {
            const p = parseColorString(m); if(!p) return m;
            const conv = convertBasedOnDetection(p);
            if(conv && (conv.r !== p.r || conv.g !== p.g || conv.b !== p.b || conv.a !== p.a)) return rgbaToCss(conv);
            return m;
        }).replace(rgbRegex, (m) => {
            const p = parseColorString(m); if(!p) return m;
            const conv = convertBasedOnDetection(p);
            if(conv && (conv.r !== p.r || conv.g !== p.g || conv.b !== p.b || conv.a !== p.a)) return rgbaToCss(conv);
            return m;
        }).replace(hslRegex, (m) => {
            const p = parseColorString(m); if(!p) return m;
            const conv = convertBasedOnDetection(p);
            if(conv && (conv.r !== p.r || conv.g !== p.g || conv.b !== p.b || conv.a !== p.a)) return rgbaToCss(conv);
            return m;
        });
        return out;
    }

    function processCssRuleList(rules){
        for(let i=0;i<rules.length;i++){
            const rule = rules[i];
            try{
                if(rule.type === CSSRule.STYLE_RULE){
                    const style = rule.style;
                    for(let j=0;j<style.length;j++){
                        const prop = style[j], val = style.getPropertyValue(prop);
                        const newVal = replaceColorTokensInText(val);
                        if(newVal !== val) try{ style.setProperty(prop, newVal, style.getPropertyPriority(prop)); }catch(e){}
                    }
                } else if(rule.cssRules) processCssRuleList(rule.cssRules);
            }catch(e){ continue; }
        }
    }

    function processStyleSheets(){ for(const sheet of document.styleSheets){ try{ if(sheet.cssRules) processCssRuleList(sheet.cssRules); }catch(e){} } }
    function processStyleTags(){ document.querySelectorAll('style').forEach(tag=>{ try{ const old = tag.textContent, neu = replaceColorTokensInText(old); if(neu !== old) tag.textContent = neu; }catch(e){} }); }
    function processInlineAndSvg(root=document){
        root.querySelectorAll('[style]').forEach(el=>{ try{ const old = el.getAttribute('style'), neu = replaceColorTokensInText(old); if(neu !== old) el.setAttribute('style', neu); }catch(e){} });
        root.querySelectorAll('[fill],[stroke]').forEach(el=>{ ['fill','stroke'].forEach(attr=>{ try{ if(el.hasAttribute(attr)){ const old = el.getAttribute(attr), neu = replaceColorTokensInText(old); if(neu !== old) el.setAttribute(attr, neu); } }catch(e){} }); });
    }

    const computedCheckProps = ['background-color','color','border-top-color','border-right-color','border-bottom-color','border-left-color','outline-color','caret-color','column-rule-color'];
    function isTransparentValue(v){ if(!v) return true; v = v.trim(); return v === 'transparent' || v === 'rgba(0, 0, 0, 0)' || v === 'initial' || v === 'none'; }

    function processComputedStylesBatch(elements, start=0){
        const batch = 250, end = Math.min(elements.length, start + batch);
        for(let i=start;i<end;i++){
            const el = elements[i];
            try{
                const cs = getComputedStyle(el);
                computedCheckProps.forEach(prop=>{
                    try{
                        const val = cs.getPropertyValue(prop);
                        if(!val || isTransparentValue(val)) return;
                        const parsed = parseColorString(val);
                        if(!parsed) return;
                        const conv = convertBasedOnDetection(parsed);
                        if(conv && (conv.r !== parsed.r || conv.g !== parsed.g || conv.b !== parsed.b || conv.a !== parsed.a)) el.style.setProperty(prop, rgbaToCss(conv), 'important');
                    }catch(e){}
                });
                try{ const bs = cs.getPropertyValue('box-shadow'); if(bs && bs !== 'none' && /#|rgba?\(|hsla?\(/i.test(bs)){ const newBs = replaceColorTokensInText(bs); if(newBs !== bs) el.style.setProperty('box-shadow', newBs, 'important'); } }catch(e){}
                try{ const bg = cs.getPropertyValue('background-image'); if(bg && bg !== 'none' && /#|rgba?\(|hsla?\(/i.test(bg)){ const newBg = replaceColorTokensInText(bg); if(newBg !== bg) el.style.setProperty('background-image', newBg, 'important'); } }catch(e){}
            }catch(e){}
        }
        if(end < elements.length) setTimeout(()=> processComputedStylesBatch(elements, end), 20);
    }

    function processAllComputedStylesRoot(root=document){ const elements = Array.from(root.querySelectorAll('*')); processComputedStylesBatch(elements, 0); }

    function patchCanvasContext(ctx){
        try{
            if(!ctx || ctx.__colorPatched) return;
            ctx.__colorPatched = true;
            const convertMaybe = (v) => {
                if(typeof v !== 'string') return v;
                const parsed = parseColorString(v); if(!parsed) return v;
                const conv = convertBasedOnDetection(parsed);
                if(conv && (conv.r !== parsed.r || conv.g !== parsed.g || conv.b !== parsed.b || conv.a !== parsed.a)) return rgbaToCss(conv);
                return v;
            };
            let _fill = ctx.fillStyle, _stroke = ctx.strokeStyle, _shadow = ctx.shadowColor;
            Object.defineProperty(ctx, 'fillStyle', { get(){ return _fill; }, set(v){ _fill = convertMaybe(v); } });
            Object.defineProperty(ctx, 'strokeStyle', { get(){ return _stroke; }, set(v){ _stroke = convertMaybe(v); } });
            Object.defineProperty(ctx, 'shadowColor', { get(){ return _shadow; }, set(v){ _shadow = convertMaybe(v); } });
        }catch(e){}
    }

    const origGetCtx = HTMLCanvasElement.prototype.getContext;
    HTMLCanvasElement.prototype.getContext = function(type, ...args){
        const ctx = origGetCtx.apply(this, [type, ...args]);
        try{ if(type === '2d' && ctx && (!this.closest || !this.closest('.tv-lightweight-charts'))) patchCanvasContext(ctx); }catch(e){}
        return ctx;
    };

    // Yeni fonksiyon: Chart canvas'ını direkt override et
    function overrideChartCanvas() {
        setTimeout(() => {
            const canvases = document.querySelectorAll('.tv-lightweight-charts canvas');
            canvases.forEach(canvas => {
                const ctx = canvas.getContext('2d');
                if (ctx && !ctx.__colorOverridden) {
                    ctx.__colorOverridden = true;

                    const origFill = ctx.fill;
                    const origStroke = ctx.stroke;
                    const origFillRect = ctx.fillRect;
                    const origStrokeRect = ctx.strokeRect;

                    // Fill override
                    ctx.fill = function() {
                        if (this.fillStyle) {
                            if (this.fillStyle === '#26a69a' || this.fillStyle === '#25a750' ||
                                this.fillStyle === 'rgb(38, 166, 154)' || this.fillStyle === 'rgb(37, 167, 80)') {
                                this.fillStyle = rgbaToCss(UP_COLOR);
                            } else if (this.fillStyle === '#ef5350' || this.fillStyle === '#ca3f64' ||
                                       this.fillStyle === 'rgb(239, 83, 80)' || this.fillStyle === 'rgb(202, 63, 100)') {
                                this.fillStyle = rgbaToCss(DOWN_COLOR);
                            }
                        }
                        return origFill.apply(this, arguments);
                    };

                    // Stroke override
                    ctx.stroke = function() {
                        if (this.strokeStyle) {
                            if (this.strokeStyle === '#26a69a' || this.strokeStyle === '#25a750' ||
                                this.strokeStyle === 'rgb(38, 166, 154)' || this.strokeStyle === 'rgb(37, 167, 80)') {
                                this.strokeStyle = rgbaToCss(UP_COLOR);
                            } else if (this.strokeStyle === '#ef5350' || this.strokeStyle === '#ca3f64' ||
                                       this.strokeStyle === 'rgb(239, 83, 80)' || this.strokeStyle === 'rgb(202, 63, 100)') {
                                this.strokeStyle = rgbaToCss(DOWN_COLOR);
                            }
                        }
                        return origStroke.apply(this, arguments);
                    };

                    // FillRect override
                    ctx.fillRect = function(x, y, w, h) {
                        if (this.fillStyle) {
                            if (this.fillStyle === '#26a69a' || this.fillStyle === '#25a750' ||
                                this.fillStyle === 'rgb(38, 166, 154)' || this.fillStyle === 'rgb(37, 167, 80)') {
                                this.fillStyle = rgbaToCss(UP_COLOR);
                            } else if (this.fillStyle === '#ef5350' || this.fillStyle === '#ca3f64' ||
                                       this.fillStyle === 'rgb(239, 83, 80)' || this.fillStyle === 'rgb(202, 63, 100)') {
                                this.fillStyle = rgbaToCss(DOWN_COLOR);
                            }
                        }
                        return origFillRect.apply(this, arguments);
                    };
                }
            });
        }, 1000);
    }

    // Chart observer'ı ekle - chart değişikliklerini takip et
    function observeChartChanges() {
        const chartObserver = new MutationObserver(() => {
            const charts = document.querySelectorAll('.tv-lightweight-charts');
            if (charts.length > 0) {
                applyChartColorFilters();
            }
        });

        chartObserver.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // BU FONKSİYON DEĞİŞTİ: Chart filtreleri artık UP_COLOR ve DOWN_COLOR'a göre dinamik olarak hesaplanıyor
    // BU FONKSİYON TAMAMEN DEĞİŞTİ: Chart renkleri için daha etkili bir yaklaşım
    function applyChartColorFilters() {
        try {
            const oldStyle = document.getElementById('okx-chart-colors-style');
            if (oldStyle) oldStyle.remove();

            const chartStyle = document.createElement('style');
            chartStyle.id = 'okx-chart-colors-style';
            chartStyle.textContent = `
            /* TradingView chart renklerini komple değiştir */
            .tv-lightweight-charts * {
                fill: ${rgbaToCss(UP_COLOR)} !important;
                stroke: ${rgbaToCss(UP_COLOR)} !important;
                color: ${rgbaToCss(UP_COLOR)} !important;
            }

            /* Yeşil/Yukarı renkli elemanlar */
            .tv-lightweight-charts [fill="#26a69a"],
            .tv-lightweight-charts [fill="#25a750"],
            .tv-lightweight-charts [fill*="26a69a"],
            .tv-lightweight-charts [fill*="25a750"],
            .tv-lightweight-charts [stroke="#26a69a"],
            .tv-lightweight-charts [stroke="#25a750"],
            .tv-lightweight-charts [stroke*="26a69a"],
            .tv-lightweight-charts [stroke*="25a750"],
            .tv-lightweight-charts [style*="26a69a"],
            .tv-lightweight-charts [style*="25a750"] {
                fill: ${rgbaToCss(UP_COLOR)} !important;
                stroke: ${rgbaToCss(UP_COLOR)} !important;
            }

            /* Kırmızı/Aşağı renkli elemanlar */
            .tv-lightweight-charts [fill="#ef5350"],
            .tv-lightweight-charts [fill="#ca3f64"],
            .tv-lightweight-charts [fill*="ef5350"],
            .tv-lightweight-charts [fill*="ca3f64"],
            .tv-lightweight-charts [stroke="#ef5350"],
            .tv-lightweight-charts [stroke="#ca3f64"],
            .tv-lightweight-charts [stroke*="ef5350"],
            .tv-lightweight-charts [stroke*="ca3f64"],
            .tv-lightweight-charts [style*="ef5350"],
            .tv-lightweight-charts [style*="ca3f64"] {
                fill: ${rgbaToCss(DOWN_COLOR)} !important;
                stroke: ${rgbaToCss(DOWN_COLOR)} !important;
            }

            /* Canvas filtreleri - daha agresif yaklaşım */
            .tv-lightweight-charts canvas {
                filter: none !important;
            }

            /* Özel olarak chart çubukları için */
            .tv-lightweight-charts [fill="rgba(38, 166, 154, 0.2)"],
            .tv-lightweight-charts [fill="rgba(37, 167, 80, 0.2)"] {
                fill: ${rgbaToCss({...UP_COLOR, a: 0.2})} !important;
            }

            .tv-lightweight-charts [fill="rgba(239, 83, 80, 0.2)"],
            .tv-lightweight-charts [fill="rgba(202, 63, 100, 0.2)"] {
                fill: ${rgbaToCss({...DOWN_COLOR, a: 0.2})} !important;
            }

            /* Chart arkaplanındaki metin renkleri */
            .tv-lightweight-charts text,
            .tv-lightweight-charts tspan {
                fill: ${rgbaToCss(UP_COLOR)} !important;
                color: ${rgbaToCss(UP_COLOR)} !important;
            }
        `;
            document.head.appendChild(chartStyle);

            // Canvas context'ini de override et
            overrideChartCanvas();

        } catch (e) {
            console.error('Chart style error:', e);
        }
    }

    function monitorChartColors() {
        const origFill = CanvasRenderingContext2D.prototype.fill;
        const origStroke = CanvasRenderingContext2D.prototype.stroke;
        const origFillRect = CanvasRenderingContext2D.prototype.fillRect;

        CanvasRenderingContext2D.prototype.fill = function() {
            if (this.fillStyle && typeof this.fillStyle === 'string') {
                const parsed = parseColorString(this.fillStyle);
                if (parsed) {
                    const converted = convertBasedOnDetection(parsed);
                    if (converted && (converted.r !== parsed.r || converted.g !== parsed.g || converted.b !== parsed.b)) this.fillStyle = rgbaToCss(converted);
                }
            }
            origFill.apply(this, arguments);
        };

        CanvasRenderingContext2D.prototype.stroke = function() {
            if (this.strokeStyle && typeof this.strokeStyle === 'string') {
                const parsed = parseColorString(this.strokeStyle);
                if (parsed) {
                    const converted = convertBasedOnDetection(parsed);
                    if (converted && (converted.r !== parsed.r || converted.g !== parsed.g || converted.b !== parsed.b)) this.strokeStyle = rgbaToCss(converted);
                }
            }
            origStroke.apply(this, arguments);
        };

        CanvasRenderingContext2D.prototype.fillRect = function(x, y, w, h) {
            if (this.fillStyle && typeof this.fillStyle === 'string') {
                const parsed = parseColorString(this.fillStyle);
                if (parsed) {
                    const converted = convertBasedOnDetection(parsed);
                    if (converted && (converted.r !== parsed.r || converted.g !== parsed.g || converted.b !== parsed.b)) this.fillStyle = rgbaToCss(converted);
                }
            }
            origFillRect.apply(this, arguments);
        };
    }

    function processNodeAndChildren(node){
        try{ if(node.nodeType !== 1) return; processInlineAndSvg(node); processAllComputedStylesRoot(node); }catch(e){}
    }

    const mo = new MutationObserver((mutations)=>{
        const added = [];
        for(const m of mutations){
            if(m.type === 'attributes'){
                const target = m.target;
                try{ if(['style','class','fill','stroke'].includes(m.attributeName)) processNodeAndChildren(target); }catch(e){}
            }
            if(m.addedNodes) m.addedNodes.forEach(n => { if(n.nodeType === 1) added.push(n); });
        }
        if(added.length) setTimeout(()=> added.forEach(n => processNodeAndChildren(n)), 10);
    });

    function kickAll(){
        try{
            processStyleSheets(); processStyleTags(); processInlineAndSvg(document); processAllComputedStylesRoot(document);
            applyChartColorFilters();
        }catch(e){}
    }

    function init() {
        loadUserSettings();
        kickAll();

        mo.observe(document.body || document.documentElement, {
            childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class', 'fill', 'stroke']
        });

        monitorChartColors();
        addColorPickerToMenu();
        observeChartChanges(); // BU SATIRI EKLEYİN

        const menuObserver = new MutationObserver(() => addColorPickerToMenu());
        menuObserver.observe(document.body, { childList: true, subtree: true });

        window.addEventListener('load', () => {
            setTimeout(kickAll, 500);
            setTimeout(kickAll, 2000);
            setTimeout(kickAll, 5000);
            setTimeout(addColorPickerToMenu, 1000);
            setTimeout(applyChartColorFilters, 1500); // BU SATIRI EKLEYİN
        });

        let lastUrl = location.href;
        setInterval(() => {
            if (location.href !== lastUrl) {
                lastUrl = location.href;
                setTimeout(() => {
                    kickAll();
                    addColorPickerToMenu();
                    applyChartColorFilters(); // BU SATIRI EKLEYİN
                }, 1000);
            }
        }, 1000);
    }
    if(document.body) init();
    else window.addEventListener('DOMContentLoaded', init);

})();