JanitorAI Context Maker

Adds a Location and Character System to JanitorAI with nested grouping functionality

// ==UserScript==
// @name         JanitorAI Context Maker
// @namespace    http://tampermonkey.net/
// @version      5.6
// @license MIT
// @description  Adds a Location and Character System to JanitorAI with nested grouping functionality
// @match        https://janitorai.com/chats/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=https://janitorai.com/
// @grant        GM.setValue
// @grant        GM.getValue
// @grant        GM.xmlHttpRequest
// @connect      *
// ==/UserScript==

(async function() {
    'use strict';

    let c_radius = 300;
    let c_labelFontSize = 12;
    let c_nodeSize = 24;
    let l_radius = 300;
    let l_labelFontSize = 12;
    let l_nodeSize = 24;

    let customContextMenu;
    let initialMouseX;
    let initialMouseY;
    const hideDistance = 100; // Distance in pixels to hide the menu
    let ItemTransferTarget = null;

    //.addEventListener('contextmenu', showMenu);
    function CreateContextMenu(mainColor, textColor, optionNames, optionFunctions) {
        // Destroy existing menu if present
        DestroyContextMenu();

        // Create a new custom menu
        customContextMenu = document.createElement('div');
        customContextMenu.style.position = 'absolute';
        customContextMenu.style.background = mainColor;
        customContextMenu.style.color = textColor;
        customContextMenu.style.border = '1px solid #ccc';

        // Adjusted padding for 2/3 size
        customContextMenu.style.padding = '3.33px 6.67px';
        customContextMenu.style.display = 'none';
        customContextMenu.style.zIndex = '99999999'; // High z-index

        // Add menu items with dividers
        optionNames.forEach((name, index) => {
            const menuItem = document.createElement('div');

            // Adjusted padding and font size for 2/3 size
            menuItem.style.padding = '3.33px 0';
            menuItem.style.cursor = 'pointer';
            menuItem.style.fontSize = '0.67em';
            menuItem.textContent = name;
            menuItem.addEventListener('click', () => {
                optionFunctions[index]();
                hideMenu();
            });

            // Append menu item
            customContextMenu.appendChild(menuItem);

            // Add a divider except after the last item
            if (index < optionNames.length - 1) {
                const divider = document.createElement('div');
                divider.style.borderTop = '1px solid #ccc';
                customContextMenu.appendChild(divider);
            }
        });

        // Append the menu to the body
        document.body.appendChild(customContextMenu);

        // Check mouse distance
        document.addEventListener('mousemove', trackMouseDistance);
    }

    function DestroyContextMenu() {
        if (customContextMenu) {
            customContextMenu.remove();
            document.removeEventListener('contextmenu', showMenu);
            document.removeEventListener('click', hideMenu);
            document.removeEventListener('mousemove', trackMouseDistance);
            customContextMenu = null;
        }
    }

    function showMenu(event) {
        event.preventDefault();
        initialMouseX = event.clientX;
        initialMouseY = event.clientY;
        if (customContextMenu) {
            customContextMenu.style.top = `${event.clientY}px`;
            customContextMenu.style.left = `${event.clientX}px`;
            customContextMenu.style.display = 'block';
        }
    }

    function hideMenu() {
        if (customContextMenu) {
            customContextMenu.style.display = 'none';
        }
    }

    function trackMouseDistance(event) {
        if (customContextMenu && customContextMenu.style.display === 'block') {
            const distance = Math.sqrt(
                Math.pow(event.clientX - initialMouseX, 2) +
                Math.pow(event.clientY - initialMouseY, 2)
            );
            if (distance > hideDistance && !customContextMenu.contains(event.target)) {
                hideMenu();
            }
        }
    }

    // Define Themes
    const themes = {
        // Default Dark Theme
        dark: {
            '--bg-color': 'rgba(34, 34, 34, var(--ui-transparency))',
            '--bg-color-full': 'rgba(34, 34, 34, 1)',
            '--bg-tool': 'rgba(34, 34, 34, 0.8)',
            '--text-color': '#ffffff',
            '--text-color-darker': '#cccccc',
            '--border-color': 'rgba(68, 68, 68, var(--ui-transparency))',
            '--button-bg-color': 'rgba(0, 123, 255, var(--ui-transparency))',
            '--active-char-color': 'rgba(173, 216, 230, var(--ui-transparency))',
            '--success-bg-color': 'rgba(40, 167, 69, var(--ui-transparency))',
            '--info-bg-color': 'rgba(23, 162, 184, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 193, 7, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(108, 117, 125, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(220, 53, 69, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.5)',
            '--link-color': '#8cb3ff',
            '--code-bg-color': 'rgba(0, 0, 0, 0.3)',
            '--code-text-color': '#ff9d00'
        },

        // Default Light Theme
        light: {
            '--bg-color': 'rgba(255, 255, 255, var(--ui-transparency))',
            '--bg-color-full': 'rgba(255, 255, 255, 1)',
            '--bg-tool': 'rgba(255, 255, 255, 0.8)',
            '--text-color': '#000000',
            '--text-color-darker': '#333333',
            '--border-color': 'rgba(204, 204, 204, var(--ui-transparency))',
            '--button-bg-color': 'rgba(0, 123, 255, var(--ui-transparency))',
            '--active-char-color': 'rgba(173, 216, 230, var(--ui-transparency))',
            '--success-bg-color': 'rgba(40, 167, 69, var(--ui-transparency))',
            '--info-bg-color': 'rgba(23, 162, 184, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 193, 7, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(108, 117, 125, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(220, 53, 69, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.1)',
            '--link-color': '#007bff',
            '--code-bg-color': 'rgba(0, 0, 0, 0.05)',
            '--code-text-color': '#d63384'
        },

        // Sepia Themes
        sepia_light: {
            '--bg-color': 'rgba(244, 232, 208, var(--ui-transparency))',
            '--bg-color-full': 'rgba(244, 232, 208, 1)',
            '--bg-tool': 'rgba(244, 232, 208, 0.8)',
            '--text-color': '#2e241c',
            '--text-color-darker': '#1a140f',
            '--border-color': 'rgba(193, 154, 107, var(--ui-transparency))',
            '--button-bg-color': 'rgba(160, 82, 45, var(--ui-transparency))',
            '--active-char-color': 'rgba(210, 180, 140, var(--ui-transparency))',
            '--success-bg-color': 'rgba(107, 68, 35, var(--ui-transparency))',
            '--info-bg-color': 'rgba(194, 148, 110, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(215, 172, 116, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(160, 130, 94, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(168, 96, 50, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.3)',
            '--link-color': '#6c757d',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#a0522d'
        },
        sepia_dark: {
            '--bg-color': 'rgba(60, 45, 31, var(--ui-transparency))',
            '--bg-color-full': 'rgba(60, 45, 31, 1)',
            '--bg-tool': 'rgba(60, 45, 31, 0.8)',
            '--text-color': '#d8c6b2',
            '--text-color-darker': '#b8a493',
            '--border-color': 'rgba(102, 75, 50, var(--ui-transparency))',
            '--button-bg-color': 'rgba(139, 69, 19, var(--ui-transparency))',
            '--active-char-color': 'rgba(210, 180, 140, var(--ui-transparency))',
            '--success-bg-color': 'rgba(107, 68, 35, var(--ui-transparency))',
            '--info-bg-color': 'rgba(139, 101, 68, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(205, 133, 63, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(122, 91, 62, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(165, 42, 42, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.6)',
            '--link-color': '#d2b48c',
            '--code-bg-color': 'rgba(0, 0, 0, 0.3)',
            '--code-text-color': '#deb887'
        },

        // Solarized Themes
        solarized_light: {
            '--bg-color': 'rgba(253, 246, 227, var(--ui-transparency))',
            '--bg-color-full': 'rgba(253, 246, 227, 1)',
            '--bg-tool': 'rgba(253, 246, 227, 0.8)',
            '--text-color': '#47565c',
            '--text-color-darker': '#2c3438',
            '--border-color': 'rgba(238, 232, 213, var(--ui-transparency))',
            '--button-bg-color': 'rgba(38, 139, 210, var(--ui-transparency))',
            '--active-char-color': 'rgba(133, 153, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(133, 153, 0, var(--ui-transparency))',
            '--info-bg-color': 'rgba(38, 139, 210, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(181, 137, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(147, 161, 161, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(220, 50, 47, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.2)',
            '--link-color': '#2aa198',
            '--code-bg-color': 'rgba(0, 43, 54, 0.7)',
            '--code-text-color': '#cb4b16'
        },
        solarized_dark: {
            '--bg-color': 'rgba(0, 43, 54, var(--ui-transparency))',
            '--bg-color-full': 'rgba(0, 43, 54, 1)',
            '--bg-tool': 'rgba(0, 43, 54, 0.8)',
            '--text-color': '#eee8d5',
            '--text-color-darker': '#cdc5b0',
            '--border-color': 'rgba(7, 54, 66, var(--ui-transparency))',
            '--button-bg-color': 'rgba(38, 139, 210, var(--ui-transparency))',
            '--active-char-color': 'rgba(133, 153, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(133, 153, 0, var(--ui-transparency))',
            '--info-bg-color': 'rgba(38, 139, 210, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(181, 137, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(88, 110, 117, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(220, 50, 47, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.4)',
            '--link-color': '#2aa198',
            '--code-bg-color': 'rgba(253, 246, 227, 0.1)',
            '--code-text-color': '#cb4b16'
        },

        // Forest Themes (Green)
        forest_light: {
            '--bg-color': 'rgba(233, 245, 233, var(--ui-transparency))',
            '--bg-color-full': 'rgba(233, 245, 233, 1)',
            '--bg-tool': 'rgba(233, 245, 233, 0.8)',
            '--text-color': '#2f4f2f',
            '--text-color-darker': '#1c2f1c',
            '--border-color': 'rgba(209, 230, 209, var(--ui-transparency))',
            '--button-bg-color': 'rgba(60, 179, 113, var(--ui-transparency))',
            '--active-char-color': 'rgba(34, 139, 34, var(--ui-transparency))',
            '--success-bg-color': 'rgba(144, 238, 144, var(--ui-transparency))',
            '--info-bg-color': 'rgba(60, 179, 113, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(240, 230, 140, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(152, 251, 152, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(205, 92, 92, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.2)',
            '--link-color': '#3cb371',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#8b4513'
        },
        forest_dark: {
            '--bg-color': 'rgba(34, 49, 34, var(--ui-transparency))',
            '--bg-color-full': 'rgba(34, 49, 34, 1)',
            '--bg-tool': 'rgba(34, 49, 34, 0.8)',
            '--text-color': '#e0f7e9',
            '--text-color-darker': '#b0c7b9',
            '--border-color': 'rgba(46, 61, 46, var(--ui-transparency))',
            '--button-bg-color': 'rgba(60, 179, 113, var(--ui-transparency))',
            '--active-char-color': 'rgba(144, 238, 144, var(--ui-transparency))',
            '--success-bg-color': 'rgba(34, 139, 34, var(--ui-transparency))',
            '--info-bg-color': 'rgba(144, 238, 144, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(189, 183, 107, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(85, 107, 47, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(139, 69, 19, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.4)',
            '--link-color': '#8fbc8f',
            '--code-bg-color': 'rgba(0, 0, 0, 0.3)',
            '--code-text-color': '#ffd700'
        },

        // Ocean Themes (Blue)
        ocean_light: {
            '--bg-color': 'rgba(224, 244, 252, var(--ui-transparency))',
            '--bg-color-full': 'rgba(224, 244, 252, 1)',
            '--bg-tool': 'rgba(224, 244, 252, 0.8)',
            '--text-color': '#004766',
            '--text-color-darker': '#00334c',
            '--border-color': 'rgba(204, 232, 245, var(--ui-transparency))',
            '--button-bg-color': 'rgba(0, 123, 255, var(--ui-transparency))',
            '--active-char-color': 'rgba(173, 216, 230, var(--ui-transparency))',
            '--success-bg-color': 'rgba(60, 179, 113, var(--ui-transparency))',
            '--info-bg-color': 'rgba(23, 162, 184, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 193, 7, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(108, 117, 125, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(220, 53, 69, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.2)',
            '--link-color': '#0077b6',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#ff7f50'
        },
        ocean_dark: {
            '--bg-color': 'rgba(0, 30, 60, var(--ui-transparency))',
            '--bg-color-full': 'rgba(0, 30, 60, 1)',
            '--bg-tool': 'rgba(0, 30, 60, 0.8)',
            '--text-color': '#ffffff',
            '--text-color-darker': '#cccccc',
            '--border-color': 'rgba(0, 53, 102, var(--ui-transparency))',
            '--button-bg-color': 'rgba(0, 123, 255, var(--ui-transparency))',
            '--active-char-color': 'rgba(135, 206, 235, var(--ui-transparency))',
            '--success-bg-color': 'rgba(46, 139, 87, var(--ui-transparency))',
            '--info-bg-color': 'rgba(0, 96, 100, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 140, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(47, 79, 79, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(139, 0, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.5)',
            '--link-color': '#00ffff',
            '--code-bg-color': 'rgba(0, 0, 0, 0.4)',
            '--code-text-color': '#ff7f50'
        },

        // Sunset Themes (Red/Orange)
        sunset_light: {
            '--bg-color': 'rgba(255, 237, 219, var(--ui-transparency))',
            '--bg-color-full': 'rgba(255, 237, 219, 1)',
            '--bg-tool': 'rgba(255, 237, 219, 0.8)',
            '--text-color': '#5d1a1a',
            '--text-color-darker': '#3b0f0f',
            '--border-color': 'rgba(255, 214, 170, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 87, 34, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 152, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(255, 179, 71, var(--ui-transparency))',
            '--info-bg-color': 'rgba(255, 138, 101, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 112, 67, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(255, 224, 178, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(183, 28, 28, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.2)',
            '--link-color': '#e65100',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#d50000'
        },
        sunset_dark: {
            '--bg-color': 'rgba(66, 28, 82, var(--ui-transparency))',
            '--bg-color-full': 'rgba(66, 28, 82, 1)',
            '--bg-tool': 'rgba(66, 28, 82, 0.8)',
            '--text-color': '#fce4ec',
            '--text-color-darker': '#f8bbd0',
            '--border-color': 'rgba(127, 63, 152, var(--ui-transparency))',
            '--button-bg-color': 'rgba(233, 30, 99, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 64, 129, var(--ui-transparency))',
            '--success-bg-color': 'rgba(186, 104, 200, var(--ui-transparency))',
            '--info-bg-color': 'rgba(142, 36, 170, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(216, 27, 96, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(123, 31, 162, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(74, 20, 140, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.4)',
            '--link-color': '#d81b60',
            '--code-bg-color': 'rgba(0, 0, 0, 0.3)',
            '--code-text-color': '#f50057'
        },

        // Sunshine Themes (Yellow)
        sunshine_light: {
            '--bg-color': 'rgba(255, 249, 196, var(--ui-transparency))',
            '--bg-color-full': 'rgba(255, 249, 196, 1)',
            '--bg-tool': 'rgba(255, 249, 196, 0.8)',
            '--text-color': '#795548',
            '--text-color-darker': '#5d4037',
            '--border-color': 'rgba(255, 241, 118, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 235, 59, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 179, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(253, 216, 53, var(--ui-transparency))',
            '--info-bg-color': 'rgba(255, 202, 40, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 193, 7, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(255, 224, 130, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 152, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.2)',
            '--link-color': '#ffab00',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#ff6f00'
        },
        sunshine_dark: {
            '--bg-color': 'rgba(50, 50, 0, var(--ui-transparency))',
            '--bg-color-full': 'rgba(50, 50, 0, 1)',
            '--bg-tool': 'rgba(50, 50, 0, 0.8)',
            '--text-color': '#fff9c4',
            '--text-color-darker': '#fff59d',
            '--border-color': 'rgba(85, 85, 0, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 214, 0, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 171, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(255, 238, 88, var(--ui-transparency))',
            '--info-bg-color': 'rgba(255, 235, 59, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 193, 7, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(212, 175, 55, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 111, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.4)',
            '--link-color': '#ffab00',
            '--code-bg-color': 'rgba(0, 0, 0, 0.3)',
            '--code-text-color': '#ff6f00'
        },

        // Twilight Themes (Indigo/Violet)
        twilight_light: {
            '--bg-color': 'rgba(230, 230, 250, var(--ui-transparency))',
            '--bg-color-full': 'rgba(230, 230, 250, 1)',
            '--bg-tool': 'rgba(230, 230, 250, 0.8)',
            '--text-color': '#4b0082',
            '--text-color-darker': '#2e0047',
            '--border-color': 'rgba(216, 191, 216, var(--ui-transparency))',
            '--button-bg-color': 'rgba(75, 0, 130, var(--ui-transparency))',
            '--active-char-color': 'rgba(138, 43, 226, var(--ui-transparency))',
            '--success-bg-color': 'rgba(111, 0, 255, var(--ui-transparency))',
            '--info-bg-color': 'rgba(153, 50, 204, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(186, 85, 211, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(148, 0, 211, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(199, 21, 133, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.2)',
            '--link-color': '#8a2be2',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#9400d3'
        },
        twilight_dark: {
            '--bg-color': 'rgba(18, 10, 30, var(--ui-transparency))',
            '--bg-color-full': 'rgba(18, 10, 30, 1)',
            '--bg-tool': 'rgba(18, 10, 30, 0.8)',
            '--text-color': '#d8bfd8',
            '--text-color-darker': '#dda0dd',
            '--border-color': 'rgba(49, 24, 73, var(--ui-transparency))',
            '--button-bg-color': 'rgba(138, 43, 226, var(--ui-transparency))',
            '--active-char-color': 'rgba(153, 50, 204, var(--ui-transparency))',
            '--success-bg-color': 'rgba(186, 85, 211, var(--ui-transparency))',
            '--info-bg-color': 'rgba(148, 0, 211, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(221, 160, 221, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(123, 104, 238, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(199, 21, 133, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.4)',
            '--link-color': '#ba55d3',
            '--code-bg-color': 'rgba(0, 0, 0, 0.3)',
            '--code-text-color': '#ee82ee'
        },

        // Terminal Themes
        terminal_light: {
            '--bg-color': 'rgba(255, 255, 255, var(--ui-transparency))',
            '--bg-color-full': 'rgba(255, 255, 255, 1)',
            '--bg-tool': 'rgba(255, 255, 255, 0.8)',
            '--text-color': '#00ff00',
            '--text-color-darker': '#00cc00',
            '--border-color': 'rgba(0, 200, 0, var(--ui-transparency))',
            '--button-bg-color': 'rgba(0, 125, 0, var(--ui-transparency))',
            '--active-char-color': 'rgba(0, 75, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(0, 128, 0, var(--ui-transparency))',
            '--info-bg-color': 'rgba(0, 125, 0, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(100, 125, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(0, 128, 0, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(100, 0, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 50, 0, 0.5)',
            '--link-color': '#00ffff',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#7fff00'
        },
        terminal_dark: {
            '--bg-color': 'rgba(0, 0, 0, var(--ui-transparency))',
            '--bg-color-full': 'rgba(0, 0, 0, 1)',
            '--bg-tool': 'rgba(0, 0, 0, 0.8)',
            '--text-color': '#00ff00',
            '--text-color-darker': '#00cc00',
            '--border-color': 'rgba(0, 200, 0, var(--ui-transparency))',
            '--button-bg-color': 'rgba(0, 125, 0, var(--ui-transparency))',
            '--active-char-color': 'rgba(0, 75, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(0, 128, 0, var(--ui-transparency))',
            '--info-bg-color': 'rgba(0, 125, 0, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(100, 125, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(0, 128, 0, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(100, 0, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 50, 0, 0.5)',
            '--link-color': '#00ffff',
            '--code-bg-color': 'rgba(0, 0, 0, 0.8)',
            '--code-text-color': '#7fff00'
        },

        // Retro Themes
        retro_light: {
            '--bg-color': 'rgba(196, 182, 187, var(--ui-transparency))',
            '--bg-color-full': 'rgba(196, 182, 187, 1)',
            '--bg-tool': 'rgba(196, 182, 187, 0.8)',
            '--text-color': '#191919',
            '--text-color-darker': '#000000',
            '--border-color': 'rgba(128, 128, 128, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 105, 180, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 255, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(50, 205, 50, var(--ui-transparency))',
            '--info-bg-color': 'rgba(135, 206, 235, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 165, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(128, 128, 128, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 0, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.3)',
            '--link-color': '#1e90ff',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#ff1493'
        },
        retro_dark: {
            '--bg-color': 'rgba(34, 32, 52, var(--ui-transparency))',
            '--bg-color-full': 'rgba(34, 32, 52, 1)',
            '--bg-tool': 'rgba(34, 32, 52, 0.8)',
            '--text-color': '#c2c3c7',
            '--text-color-darker': '#8b8d90',
            '--border-color': 'rgba(69, 40, 60, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 0, 77, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 163, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(0, 232, 216, var(--ui-transparency))',
            '--info-bg-color': 'rgba(44, 232, 245, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 236, 39, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(96, 86, 107, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(172, 50, 50, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.5)',
            '--link-color': '#ff004d',
            '--code-bg-color': 'rgba(69, 40, 60, 0.8)',
            '--code-text-color': '#ff77a8'
        },

        // Neon Themes
        neon_light: {
            '--bg-color': 'rgba(255, 255, 255, var(--ui-transparency))',
            '--bg-color-full': 'rgba(255, 255, 255, 1)',
            '--bg-tool': 'rgba(255, 255, 255, 0.8)',
            '--text-color': '#000000',
            '--text-color-darker': '#333333',
            '--border-color': 'rgba(0, 0, 0, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 0, 255, var(--ui-transparency))',
            '--active-char-color': 'rgba(0, 255, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(0, 255, 0, var(--ui-transparency))',
            '--info-bg-color': 'rgba(0, 255, 255, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 255, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(128, 128, 128, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 0, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.5)',
            '--link-color': '#ff00ff',
            '--code-bg-color': 'rgba(255, 255, 255, 0.8)',
            '--code-text-color': '#00ffff'
        },
        neon_dark: {
            '--bg-color': 'rgba(0, 0, 0, var(--ui-transparency))',
            '--bg-color-full': 'rgba(0, 0, 0, 1)',
            '--bg-tool': 'rgba(0, 0, 0, 0.8)',
            '--text-color': '#ffffff',
            '--text-color-darker': '#cccccc',
            '--border-color': 'rgba(255, 255, 255, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 0, 255, var(--ui-transparency))',
            '--active-char-color': 'rgba(0, 255, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(0, 255, 0, var(--ui-transparency))',
            '--info-bg-color': 'rgba(0, 255, 255, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 255, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(255, 0, 255, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 0, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 255, 255, 0.5)',
            '--link-color': '#ff00ff',
            '--code-bg-color': 'rgba(0, 0, 0, 0.8)',
            '--code-text-color': '#00ffff'
        },

        // Vintage Themes
        vintage_light: {
            '--bg-color': 'rgba(240, 230, 140, var(--ui-transparency))',
            '--bg-color-full': 'rgba(240, 230, 140, 1)',
            '--bg-tool': 'rgba(240, 230, 140, 0.8)',
            '--text-color': '#360505',
            '--text-color-darker': '#200303',
            '--border-color': 'rgba(139, 69, 19, var(--ui-transparency))',
            '--button-bg-color': 'rgba(128, 0, 0, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 215, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(50, 205, 50, var(--ui-transparency))',
            '--info-bg-color': 'rgba(70, 130, 180, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(218, 165, 32, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(128, 128, 0, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(178, 34, 34, var(--ui-transparency))',
            '--shadow-color': 'rgba(139, 69, 19, 0.5)',
            '--link-color': '#8b0000',
            '--code-bg-color': 'rgba(245, 222, 179, 0.5)',
            '--code-text-color': '#8b0000'
        },
        vintage_dark: {
            '--bg-color': 'rgba(60, 47, 34, var(--ui-transparency))',
            '--bg-color-full': 'rgba(60, 47, 34, 1)',
            '--bg-tool': 'rgba(60, 47, 34, 0.8)',
            '--text-color': '#e0d4b3',
            '--text-color-darker': '#c0b297',
            '--border-color': 'rgba(139, 69, 19, var(--ui-transparency))',
            '--button-bg-color': 'rgba(128, 0, 0, var(--ui-transparency))',
            '--active-char-color': 'rgba(218, 165, 32, var(--ui-transparency))',
            '--success-bg-color': 'rgba(107, 142, 35, var(--ui-transparency))',
            '--info-bg-color': 'rgba(70, 130, 180, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(184, 134, 11, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(128, 128, 0, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(178, 34, 34, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.5)',
            '--link-color': '#8b0000',
            '--code-bg-color': 'rgba(245, 222, 179, 0.3)',
            '--code-text-color': '#ffa07a'
        },

        // Pastel Themes
        pastel_light: {
            '--bg-color': 'rgba(255, 228, 225, var(--ui-transparency))',
            '--bg-color-full': 'rgba(255, 228, 225, 1)',
            '--bg-tool': 'rgba(255, 228, 225, 0.8)',
            '--text-color': '#4d4d4d',
            '--text-color-darker': '#333333',
            '--border-color': 'rgba(255, 192, 203, var(--ui-transparency))',
            '--button-bg-color': 'rgba(135, 206, 235, var(--ui-transparency))',
            '--active-char-color': 'rgba(175, 238, 238, var(--ui-transparency))',
            '--success-bg-color': 'rgba(152, 251, 152, var(--ui-transparency))',
            '--info-bg-color': 'rgba(135, 206, 235, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 228, 181, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(238, 130, 238, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(240, 128, 128, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.1)',
            '--link-color': '#ff69b4',
            '--code-bg-color': 'rgba(255, 250, 205, 0.8)',
            '--code-text-color': '#dc143c'
        },
        pastel_dark: {
            '--bg-color': 'rgba(75, 75, 75, var(--ui-transparency))',
            '--bg-color-full': 'rgba(75, 75, 75, 1)',
            '--bg-tool': 'rgba(75, 75, 75, 0.8)',
            '--text-color': '#e6e6e6',
            '--text-color-darker': '#cccccc',
            '--border-color': 'rgba(105, 105, 105, var(--ui-transparency))',
            '--button-bg-color': 'rgba(176, 196, 222, var(--ui-transparency))',
            '--active-char-color': 'rgba(119, 136, 153, var(--ui-transparency))',
            '--success-bg-color': 'rgba(144, 238, 144, var(--ui-transparency))',
            '--info-bg-color': 'rgba(135, 206, 250, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 160, 122, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(205, 133, 63, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(205, 92, 92, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.5)',
            '--link-color': '#ff69b4',
            '--code-bg-color': 'rgba(255, 182, 193, 0.3)',
            '--code-text-color': '#dc143c'
        },

        // Monokai Themes
        monokai_light: {
            '--bg-color': 'rgba(248, 248, 242, var(--ui-transparency))',
            '--bg-color-full': 'rgba(248, 248, 242, 1)',
            '--bg-tool': 'rgba(248, 248, 242, 0.8)',
            '--text-color': '#272822',
            '--text-color-darker': '#49483e',
            '--border-color': 'rgba(220, 220, 217, var(--ui-transparency))',
            '--button-bg-color': 'rgba(249, 38, 114, var(--ui-transparency))',
            '--active-char-color': 'rgba(166, 226, 46, var(--ui-transparency))',
            '--success-bg-color': 'rgba(166, 226, 46, var(--ui-transparency))',
            '--info-bg-color': 'rgba(102, 217, 239, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(253, 151, 31, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(117, 113, 94, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(249, 38, 114, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.2)',
            '--link-color': '#ae81ff',
            '--code-bg-color': 'rgba(230, 230, 230, 0.8)',
            '--code-text-color': '#f92672'
        },
        monokai_dark: {
            '--bg-color': 'rgba(39, 40, 34, var(--ui-transparency))',
            '--bg-color-full': 'rgba(39, 40, 34, 1)',
            '--bg-tool': 'rgba(39, 40, 34, 0.8)',
            '--text-color': '#f8f8f2',
            '--text-color-darker': '#e6e6dc',
            '--border-color': 'rgba(73, 72, 62, var(--ui-transparency))',
            '--button-bg-color': 'rgba(249, 38, 114, var(--ui-transparency))',
            '--active-char-color': 'rgba(166, 226, 46, var(--ui-transparency))',
            '--success-bg-color': 'rgba(102, 217, 239, var(--ui-transparency))',
            '--info-bg-color': 'rgba(102, 217, 239, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(253, 151, 31, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(117, 113, 94, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(249, 38, 114, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.5)',
            '--link-color': '#ae81ff',
            '--code-bg-color': 'rgba(39, 40, 34, 0.8)',
            '--code-text-color': '#f92672'
        },

        // Dracula Themes
        dracula_light: {
            '--bg-color': 'rgba(248, 248, 242, var(--ui-transparency))',
            '--bg-color-full': 'rgba(248, 248, 242, 1)',
            '--bg-tool': 'rgba(248, 248, 242, 0.8)',
            '--text-color': '#282a36',
            '--text-color-darker': '#44475a',
            '--border-color': 'rgba(211, 212, 219, var(--ui-transparency))',
            '--button-bg-color': 'rgba(98, 114, 164, var(--ui-transparency))',
            '--active-char-color': 'rgba(189, 147, 249, var(--ui-transparency))',
            '--success-bg-color': 'rgba(80, 250, 123, var(--ui-transparency))',
            '--info-bg-color': 'rgba(139, 233, 253, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(241, 250, 140, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(98, 114, 164, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 85, 85, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.2)',
            '--link-color': '#6272a4',
            '--code-bg-color': 'rgba(225, 225, 232, 0.8)',
            '--code-text-color': '#ff79c6'
        },
        dracula_dark: {
            '--bg-color': 'rgba(40, 42, 54, var(--ui-transparency))',
            '--bg-color-full': 'rgba(40, 42, 54, 1)',
            '--bg-tool': 'rgba(40, 42, 54, 0.8)',
            '--text-color': '#f8f8f2',
            '--text-color-darker': '#e6e6dc',
            '--border-color': 'rgba(68, 71, 90, var(--ui-transparency))',
            '--button-bg-color': 'rgba(98, 114, 164, var(--ui-transparency))',
            '--active-char-color': 'rgba(189, 147, 249, var(--ui-transparency))',
            '--success-bg-color': 'rgba(80, 250, 123, var(--ui-transparency))',
            '--info-bg-color': 'rgba(139, 233, 253, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(241, 250, 140, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(98, 114, 164, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 85, 85, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.5)',
            '--link-color': '#6272a4',
            '--code-bg-color': 'rgba(68, 71, 90, 0.8)',
            '--code-text-color': '#ff79c6'
        },

        // Gruvbox Themes
        gruvbox_light: {
            '--bg-color': 'rgba(251, 241, 199, var(--ui-transparency))',
            '--bg-color-full': 'rgba(251, 241, 199, 1)',
            '--bg-tool': 'rgba(251, 241, 199, 0.8)',
            '--text-color': '#282828',
            '--text-color-darker': '#1d2021',
            '--border-color': 'rgba(213, 196, 161, var(--ui-transparency))',
            '--button-bg-color': 'rgba(184, 187, 38, var(--ui-transparency))',
            '--active-char-color': 'rgba(184, 187, 38, var(--ui-transparency))',
            '--success-bg-color': 'rgba(121, 116, 14, var(--ui-transparency))',
            '--info-bg-color': 'rgba(7, 102, 120, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(215, 153, 33, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(146, 131, 116, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(204, 36, 29, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.2)',
            '--link-color': '#458588',
            '--code-bg-color': 'rgba(235, 219, 178, 0.8)',
            '--code-text-color': '#9d0006'
        },
        gruvbox_dark: {
            '--bg-color': 'rgba(40, 40, 40, var(--ui-transparency))',
            '--bg-color-full': 'rgba(40, 40, 40, 1)',
            '--bg-tool': 'rgba(40, 40, 40, 0.8)',
            '--text-color': '#ebdbb2',
            '--text-color-darker': '#d5c4a1',
            '--border-color': 'rgba(60, 56, 54, var(--ui-transparency))',
            '--button-bg-color': 'rgba(213, 196, 161, var(--ui-transparency))',
            '--active-char-color': 'rgba(184, 187, 38, var(--ui-transparency))',
            '--success-bg-color': 'rgba(121, 116, 14, var(--ui-transparency))',
            '--info-bg-color': 'rgba(7, 102, 120, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(215, 153, 33, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(146, 131, 116, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(204, 36, 29, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.4)',
            '--link-color': '#83a598',
            '--code-bg-color': 'rgba(60, 56, 54, 0.8)',
            '--code-text-color': '#fb4934'
        },

        // Nord Themes
        nord_light: {
            '--bg-color': 'rgba(236, 239, 244, var(--ui-transparency))',
            '--bg-color-full': 'rgba(236, 239, 244, 1)',
            '--bg-tool': 'rgba(236, 239, 244, 0.8)',
            '--text-color': '#2e3440',
            '--text-color-darker': '#3b4252',
            '--border-color': 'rgba(208, 211, 216, var(--ui-transparency))',
            '--button-bg-color': 'rgba(94, 129, 172, var(--ui-transparency))',
            '--active-char-color': 'rgba(136, 192, 208, var(--ui-transparency))',
            '--success-bg-color': 'rgba(163, 190, 140, var(--ui-transparency))',
            '--info-bg-color': 'rgba(129, 161, 193, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(235, 203, 139, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(186, 190, 194, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(191, 97, 106, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.2)',
            '--link-color': '#5e81ac',
            '--code-bg-color': 'rgba(208, 211, 216, 0.8)',
            '--code-text-color': '#bf616a'
        },
        nord_dark: {
            '--bg-color': 'rgba(46, 52, 64, var(--ui-transparency))',
            '--bg-color-full': 'rgba(46, 52, 64, 1)',
            '--bg-tool': 'rgba(46, 52, 64, 0.8)',
            '--text-color': '#d8dee9',
            '--text-color-darker': '#eceff4',
            '--border-color': 'rgba(59, 66, 82, var(--ui-transparency))',
            '--button-bg-color': 'rgba(94, 129, 172, var(--ui-transparency))',
            '--active-char-color': 'rgba(136, 192, 208, var(--ui-transparency))',
            '--success-bg-color': 'rgba(163, 190, 140, var(--ui-transparency))',
            '--info-bg-color': 'rgba(129, 161, 193, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(235, 203, 139, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(76, 86, 106, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(191, 97, 106, var(--ui-transparency))',
            '--shadow-color': 'rgba(0,0,0,0.5)',
            '--link-color': '#88c0d0',
            '--code-bg-color': 'rgba(59, 66, 82, 0.8)',
            '--code-text-color': '#bf616a'
        },

        // High Contrast Themes
        high_contrast_light: {
            '--bg-color': 'rgba(255, 255, 255, var(--ui-transparency))',
            '--bg-color-full': 'rgba(255, 255, 255, 1)',
            '--bg-tool': 'rgba(255, 255, 255, 0.8)',
            '--text-color': '#000000',
            '--text-color-darker': '#333333',
            '--border-color': 'rgba(0, 0, 0, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 255, 0, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 0, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(0, 255, 0, var(--ui-transparency))',
            '--info-bg-color': 'rgba(0, 255, 255, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 255, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(128, 128, 128, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 0, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.5)',
            '--link-color': '#0000ff',
            '--code-bg-color': 'rgba(0, 0, 0, 0.1)',
            '--code-text-color': '#0000ff'
        },
        high_contrast_dark: {
            '--bg-color': 'rgba(0, 0, 0, var(--ui-transparency))',
            '--bg-color-full': 'rgba(0, 0, 0, 1)',
            '--bg-tool': 'rgba(0, 0, 0, 0.8)',
            '--text-color': '#ffffff',
            '--text-color-darker': '#cccccc',
            '--border-color': 'rgba(255, 255, 255, var(--ui-transparency))',
            '--button-bg-color': 'rgba(255, 255, 0, var(--ui-transparency))',
            '--active-char-color': 'rgba(255, 0, 0, var(--ui-transparency))',
            '--success-bg-color': 'rgba(0, 255, 0, var(--ui-transparency))',
            '--info-bg-color': 'rgba(0, 255, 255, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 255, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(128, 128, 128, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(255, 0, 0, var(--ui-transparency))',
            '--shadow-color': 'rgba(255, 255, 255, 0.5)',
            '--link-color': '#00ffff',
            '--code-bg-color': 'rgba(255, 255, 255, 0.1)',
            '--code-text-color': '#ffff00'
        },

        // Material Design Themes
        material_light: {
            '--bg-color': 'rgba(250, 250, 250, var(--ui-transparency))',
            '--bg-color-full': 'rgba(250, 250, 250, 1)',
            '--bg-tool': 'rgba(250, 250, 250, 0.8)',
            '--text-color': '#212121',
            '--text-color-darker': '#000000',
            '--border-color': 'rgba(224, 224, 224, var(--ui-transparency))',
            '--button-bg-color': 'rgba(33, 150, 243, var(--ui-transparency))',
            '--active-char-color': 'rgba(0, 188, 212, var(--ui-transparency))',
            '--success-bg-color': 'rgba(76, 175, 80, var(--ui-transparency))',
            '--info-bg-color': 'rgba(3, 169, 244, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 152, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(158, 158, 158, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(244, 67, 54, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.2)',
            '--link-color': '#009688',
            '--code-bg-color': 'rgba(238, 238, 238, .8)',
            '--code-text-color': '#ff5722'
        },
        material_dark: {
            '--bg-color': 'rgba(33, 33, 33, var(--ui-transparency))',
            '--bg-color-full': 'rgba(33, 33, 33, 1)',
            '--bg-tool': 'rgba(33, 33, 33, 0.8)',
            '--text-color': '#ffffff',
            '--text-color-darker': '#bdbdbd',
            '--border-color': 'rgba(66, 66, 66, var(--ui-transparency))',
            '--button-bg-color': 'rgba(33, 150, 243, var(--ui-transparency))',
            '--active-char-color': 'rgba(0, 188, 212, var(--ui-transparency))',
            '--success-bg-color': 'rgba(76, 175, 80, var(--ui-transparency))',
            '--info-bg-color': 'rgba(3, 169, 244, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(255, 152, 0, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(117, 117, 117, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(244, 67, 54, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.5)',
            '--link-color': '#009688',
            '--code-bg-color': 'rgba(55, 71, 79, 0.8)',
            '--code-text-color': '#ff5722'
        },

        // Desert Themes
        desert_light: {
            '--bg-color': 'rgba(250, 243, 221, var(--ui-transparency))',
            '--bg-color-full': 'rgba(250, 243, 221, 1)',
            '--bg-tool': 'rgba(250, 243, 221, 0.8)',
            '--text-color': '#5e4a1e',
            '--text-color-darker': '#3e300f',
            '--border-color': 'rgba(230, 216, 173, var(--ui-transparency))',
            '--button-bg-color': 'rgba(205, 133, 63, var(--ui-transparency))',
            '--active-char-color': 'rgba(244, 164, 96, var(--ui-transparency))',
            '--success-bg-color': 'rgba(218, 165, 32, var(--ui-transparency))',
            '--info-bg-color': 'rgba(210, 180, 140, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(184, 134, 11, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(222, 184, 135, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(139, 69, 19, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.2)',
            '--link-color': '#cd853f',
            '--code-bg-color': 'rgba(245, 222, 179, 0.8)',
            '--code-text-color': '#8b4513'
        },
        desert_dark: {
            '--bg-color': 'rgba(74, 60, 42, var(--ui-transparency))',
            '--bg-color-full': 'rgba(74, 60, 42, 1)',
            '--bg-tool': 'rgba(74, 60, 42, 0.8)',
            '--text-color': '#f0e68c',
            '--text-color-darker': '#d2b48c',
            '--border-color': 'rgba(92, 64, 51, var(--ui-transparency))',
            '--button-bg-color': 'rgba(205, 133, 63, var(--ui-transparency))',
            '--active-char-color': 'rgba(244, 164, 96, var(--ui-transparency))',
            '--success-bg-color': 'rgba(218, 165, 32, var(--ui-transparency))',
            '--info-bg-color': 'rgba(210, 180, 140, var(--ui-transparency))',
            '--warning-bg-color': 'rgba(184, 134, 11, var(--ui-transparency))',
            '--muted-bg-color': 'rgba(210, 105, 30, var(--ui-transparency))',
            '--danger-bg-color': 'rgba(139, 69, 19, var(--ui-transparency))',
            '--shadow-color': 'rgba(0, 0, 0, 0.4)',
            '--link-color': '#cd853f',
            '--code-bg-color': 'rgba(92, 64, 51, 0.8)',
            '--code-text-color': '#ffa07a'
        }
    };

    // Initialize CSS variables
    function setTheme(themeName) {
        const theme = themes[themeName];
        Object.keys(theme).forEach(key => {
            document.documentElement.style.setProperty(key, theme[key]);
        });
    }

    // Retrieve saved settings or set defaults
    const defaultTransparency = await GM.getValue('transparency', '0.9');
    const defaultTheme = await GM.getValue('theme', 'dark');

    // Initialize transparency and theme
    document.documentElement.style.setProperty('--ui-transparency', defaultTransparency);
    setTheme(defaultTheme);

    // Add placeholder styles
    const style = document.createElement('style');
    style.innerHTML = `
    input::placeholder, textarea::placeholder {
        color: var(--text-color);
    }
    input:-ms-input-placeholder, textarea:-ms-input-placeholder {
        color: var(--text-color);
    }
    input::-ms-input-placeholder, textarea::-ms-input-placeholder {
        color: var(--text-color);
    }
    input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
        color: var(--text-color);
    }
    `;
    document.head.appendChild(style);

    // --- Context Menu and Tool Buttons ---
    const menuButtonsContainer = document.createElement('div');
    menuButtonsContainer.style.cssText = `
        position: fixed;
        top: 10px;
        left: 50%;
        transform: translateX(-50%);
        display: flex;
        justify-content: center;
        z-index: 10000;
    `;
    document.body.appendChild(menuButtonsContainer);

    const contextMenuButton = document.createElement('button');
    contextMenuButton.textContent = '⚙️';
    contextMenuButton.title = 'Menu';
    contextMenuButton.style.cssText = `
        width: 40px;
        height: 40px;
        margin-right: 5px;
        padding: 0;
        border: none;
        background-color: var(--button-bg-color);
        color: var(--text-color);
        border-radius: 50%;
        font-size: 24px;
        cursor: pointer;
        z-index: 10000;
    `;
    menuButtonsContainer.appendChild(contextMenuButton);

    const toolButtonsData = [
        { emoji: '🧮', title: 'Calculator', iframeSrc: 'https://www.desmos.com/fourfunction', id: 'calculator' },
        { emoji: '🎲', title: 'Dice Roller', iframeSrc: '', id: 'dice' },
        { emoji: '🎮', title: 'Game', iframeSrc: 'https://freepacman.org/', id: 'game' },
    ];

    toolButtonsData.forEach(tool => {
        const button = document.createElement('button');
        button.textContent = tool.emoji;
        button.title = tool.title;
        button.style.cssText = `
            width: 40px;
            height: 40px;
            margin-right: 5px;
            padding: 0;
            border: none;
            background-color: var(--button-bg-color);
            color: var(--text-color);
            border-radius: 50%;
            font-size: 24px;
            cursor: pointer;
        `;
        button.addEventListener('click', () => {
            openToolWindow(tool);
        });
        menuButtonsContainer.appendChild(button);
    });

    const openWindows = new Set();

    function openToolWindow(tool) {
        if (openWindows.has(tool.id)) {
            return;
        }

        // Create the window container
        const windowContainer = document.createElement('div');
        windowContainer.style.cssText = `
        position: fixed;
        top: 100px;
        left: 100px;
        width: 500px;
        height: 400px;
        background-color: var(--bg-color);
        border: 1px solid var(--border-color);
        box-shadow: 0 0 10px var(--shadow-color);
        border-radius: 5px;
        z-index: 10002;
        display: flex;
        flex-direction: column;
    `;

        // Add a header with the title and close button
        const header = document.createElement('div');
        header.style.cssText = `
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 5px;
        background-color: var(--button-bg-color);
        color: var(--text-color);
        cursor: move;
    `;
        const title = document.createElement('span');
        title.textContent = tool.title;
        header.appendChild(title);
        const closeButton = document.createElement('button');
        closeButton.textContent = '✖️';
        closeButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
    `;
        closeButton.addEventListener('click', () => {
            document.body.removeChild(windowContainer);
            openWindows.delete(tool.id);
        });
        header.appendChild(closeButton);

        windowContainer.appendChild(header);

        // Add iframe
        const iframe = document.createElement('iframe');
        iframe.style.cssText = `
    flex-grow: 1;
    width: 100%;
    border: none;
    background-color: var(--bg-color);
    color: var(--text-color);
`;
        let src = tool.iframeSrc;

        // Adjust dice URL based on theme
        if (tool.id === 'dice') {
            const dicehex = getComputedHexValue('--button-bg-color').slice(1);
            const chromahex = getComputedHexValue('--bg-color').slice(1);
            const labelhex = getComputedHexValue('--text-color').slice(1);
            src = `https://dice.bee.ac/?dicehex=${dicehex}&chromahex=${chromahex}&labelhex=${labelhex}`;
        }

        // Adjust calculator URL based on theme
        if (tool.id === 'calculator') {
            const bgColor = getComputedHexValue('--bg-color').slice(1);
            const textColor = getComputedHexValue('--text-color').slice(1);
            const buttonBgColor = getComputedHexValue('--button-bg-color').slice(1);
            src = `https://www.desmos.com/fourfunction?backgroundColor=${bgColor}&textColor=${textColor}&buttonBackgroundColor=${buttonBgColor}`;
        }

        iframe.src = src;
        windowContainer.appendChild(iframe);

        // Make window draggable
        makeElementDraggable(windowContainer, header);

        document.body.appendChild(windowContainer);
        openWindows.add(tool.id);

        document.body.appendChild(windowContainer);
        openWindows.add(tool.id);
    }

    function getComputedHexValue(variableName) {
        const computedStyle = getComputedStyle(document.documentElement);
        const colorValue = computedStyle.getPropertyValue(variableName).trim();

        // Create a temporary div to get the computed color
        const tempDiv = document.createElement('div');
        tempDiv.style.color = colorValue;
        document.body.appendChild(tempDiv);
        const computedColor = getComputedStyle(tempDiv).color;
        document.body.removeChild(tempDiv);

        // Now computedColor is in 'rgb(r, g, b)' or 'rgba(r, g, b, a)' format
        const rgba = computedColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);

        if (rgba) {
            const r = parseInt(rgba[1]).toString(16).padStart(2, '0');
            const g = parseInt(rgba[2]).toString(16).padStart(2, '0');
            const b = parseInt(rgba[3]).toString(16).padStart(2, '0');
            return `#${r}${g}${b}`;
        } else {
            // Fallback to default
            return '#FFFFFF';
        }
    }

    function makeElementDraggable(elmnt, handle) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        if (handle) {
            handle.onmousedown = dragMouseDown;
        } else {
            elmnt.onmousedown = dragMouseDown;
        }

        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
            elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }

    // Helper functions for tooltip
    let tooltipElement = null;

    function showTooltip(event, content, set, url, imageMaxWidth = 300, imageMaxHeight = 200) {
        hideTooltip(); // Remove existing tooltip if any

        // Create new tooltip element
        tooltipElement = document.createElement('div');
        tooltipElement.style.cssText = `
        position: absolute;
        z-index: 10000;
        background-color: var(--bg-tool);
        color: var(--text-color);
        border: 1px solid var(--border-color);
        padding: 5px;
        border-radius: 5px;
        font-size: 12px;
        max-width: 600px;
        white-space: pre-wrap;
        box-shadow: 0 0 10px var(--shadow-color);
    `;
        tooltipElement.innerHTML = content;

        // Append tooltip to body first to calculate its size later
        document.body.appendChild(tooltipElement);

        // Get the parent node's bounding rectangle
        const parentRect = event.currentTarget.parentNode.parentNode.getBoundingClientRect();

        if (!set) {
            // Tooltip to the right of the parent element
            tooltipElement.style.left = `${parentRect.right + 4}px`;
            tooltipElement.style.top = `${parentRect.top}px`;
        } else {
            // Tooltip to the left of the parent element
            const tooltipWidth = tooltipElement.offsetWidth; // Get the tooltip width after it's appended
            tooltipElement.style.left = `${parentRect.left - tooltipWidth + 15}px`; // Adjust to the left
            tooltipElement.style.top = `${parentRect.top}px`;
        }

        // Adjust position if the tooltip goes off screen
        const tooltipRect = tooltipElement.getBoundingClientRect();
        if (tooltipRect.right > window.innerWidth) {
            tooltipElement.style.left = `${window.innerWidth - tooltipRect.width - 10}px`;
        }
        if (tooltipRect.left < 0) {
            tooltipElement.style.left = `10px`; // Move it a bit to the right if it goes off screen on the left
        }
        if (tooltipRect.bottom > window.innerHeight) {
            tooltipElement.style.top = `${window.innerHeight - tooltipRect.height - 10}px`;
        }

        // If a valid image URL is provided, attempt to load it
        if (url && isValidImageUrl(url)) {
            const img = document.createElement('img');
            img.src = url;

            // When the image loads, call a function to add it to the tooltip
            img.onload = () => {
                addImageToTooltip(tooltipElement, url, imageMaxWidth, imageMaxHeight);
            };

            // Optionally handle image loading errors
            img.onerror = () => {
                console.warn(`Failed to load image from URL: ${url}`);
            };
        }
    }

    function addImageToTooltip(tooltipElement, url, imageMaxWidth, imageMaxHeight) {
        // Create a container for the image with a background color
        const imgContainer = document.createElement('div');
        imgContainer.style.cssText = `
        display: block;
        margin-top: 10px;
        width: 100%; /* Match the tooltip's width */
        background-color: var(--shadow-color);
        border-radius: 5px;
        overflow: hidden; /* Ensures the image stays within the container's bounds */
        padding: 5px; /* Optional: adds padding inside the background */
    `;

        // Create the image element
        const img = document.createElement('img');
        img.src = url;
        img.style.cssText = `
        display: block; /* Behave like a block element */
        margin: 0 auto; /* Center the image horizontally */
        max-width: ${imageMaxWidth}px; /* Scale down if larger than max width */
        max-height: ${imageMaxHeight}px; /* Scale down if larger than max height */
        width: auto; /* Maintain aspect ratio based on max-width and max-height */
        height: auto; /* Maintain aspect ratio */
        border-radius: 5px; /* Optional: rounded corners for the image */
    `;

        // Append the image to the container
        imgContainer.appendChild(img);

        // Append the container to the tooltip
        tooltipElement.appendChild(imgContainer);

        // Recalculate the tooltip position if necessary (e.g., if the image changes its size)
        const tooltipRect = tooltipElement.getBoundingClientRect();

        if (tooltipRect.right > window.innerWidth) {
            tooltipElement.style.left = `${window.innerWidth - tooltipRect.width - 10}px`;
        }
        if (tooltipRect.left < 0) {
            tooltipElement.style.left = `10px`; // Move it a bit to the right if it goes off screen on the left
        }
        if (tooltipRect.bottom > window.innerHeight) {
            tooltipElement.style.top = `${window.innerHeight - tooltipRect.height - 10}px`;
        }
    }

    function hideTooltip() {
        if (tooltipElement && tooltipElement.parentNode) {
            tooltipElement.parentNode.removeChild(tooltipElement);
            tooltipElement = null; // Set to null after removing
        }
    }

    // --- Context Panel ---
    const contextPanel = document.createElement('div');
    contextPanel.id = 'context-panel';
    contextPanel.style.cssText = `
    position: fixed; /* Keep position fixed to center the panel */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 400px;
    padding: 20px;
    background-color: var(--bg-color);
    border: 1px solid var(--border-color);
    box-shadow: 0 0 10px var(--shadow-color);
    border-radius: 5px;
    display: none;
    z-index: 10001;
    /* Remove position: relative; */
`;
    document.body.appendChild(contextPanel);

    // Add close button to contextPanel
    const contextCloseButton = document.createElement('button');
    contextCloseButton.textContent = '✖️';
    contextCloseButton.style.cssText = `
        position: absolute;
        top: 10px;
        right: 10px;
        background: none;
        border: none;
        font-size: 20px;
        cursor: pointer;
        color: var(--text-color);
    `;
    contextCloseButton.addEventListener('click', () => {
        contextPanel.style.display = 'none';
    });
    contextPanel.appendChild(contextCloseButton);

    const transparencyLabel = document.createElement('label');
    transparencyLabel.textContent = 'UI Transparency';
    transparencyLabel.style.cssText = `
        color: var(--text-color);
        display: block;
        margin-bottom: 5px;
    `;
    contextPanel.appendChild(transparencyLabel);

    const transparencySlider = document.createElement('input');
    transparencySlider.type = 'range';
    transparencySlider.min = '0.1';
    transparencySlider.max = '1';
    transparencySlider.step = '0.1';
    transparencySlider.value = defaultTransparency;
    transparencySlider.style.cssText = `
        width: 100%;
        margin-bottom: 10px;
    `;
    transparencySlider.addEventListener('input', () => {
        document.documentElement.style.setProperty('--ui-transparency', transparencySlider.value);
        // Re-apply current theme to update transparency
        setTheme(themeDropdown.value);
        GM.setValue('transparency', transparencySlider.value);
    });
    contextPanel.appendChild(transparencySlider);

    const dropperLabel = document.createElement('label');
    dropperLabel.textContent = 'UI Theme';
    dropperLabel.style.cssText = `
        color: var(--text-color);
        display: block;
        margin-bottom: 5px;
    `;
    contextPanel.appendChild(dropperLabel);

    const themeDropdown = document.createElement('select');
    themeDropdown.style.cssText = `
        width: 100%;
        padding: 5px;
        margin-bottom: 10px;
        border: 1px solid var(--border-color);
        border-radius: 5px;
        background-color: var(--bg-color);
        color: var(--text-color);
    `;
    Object.keys(themes).forEach(theme => {
        const option = document.createElement('option');
        option.value = theme;
        option.textContent = theme.charAt(0).toUpperCase() + theme.slice(1);
        themeDropdown.appendChild(option);
    });

    themeDropdown.value = defaultTheme;

    themeDropdown.addEventListener('change', () => {
        setTheme(themeDropdown.value);
        GM.setValue('theme', themeDropdown.value);
    });
    contextPanel.appendChild(themeDropdown);

    // Add divider
    const divider = document.createElement('hr');
    divider.style.cssText = `
        border: none;
        border-top: 1px solid var(--border-color);
        margin: 10px 0;
    `;
    contextPanel.appendChild(divider);

    const contextLabel = document.createElement('label');
    contextLabel.textContent = 'Primary Context';
    contextLabel.style.cssText = `
        color: var(--text-color);
        display: block;
        margin-bottom: 5px;
    `;
    contextPanel.appendChild(contextLabel);

    const primaryContextInput = document.createElement('textarea');
    primaryContextInput.placeholder = 'Primary context goes here...';
    primaryContextInput.style.cssText = `
        width: 100%;
        height: 100px;
        margin-bottom: 10px;
        padding: 10px;
        border: 1px solid var(--border-color);
        border-radius: 5px;
        box-sizing: border-box;
        background-color: var(--bg-color);
        color: var(--text-color);
    `;
    contextPanel.appendChild(primaryContextInput);

    // Define the sleep function
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    const updateContextButton = document.createElement('button');
    updateContextButton.textContent = 'Update Context';
    updateContextButton.style.cssText = `
        width: 100%;
        padding: 10px;
        border: none;
        background-color: var(--success-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;

    updateContextButton.addEventListener('click', async () => {
        const primaryContext = primaryContextInput.value;
        var fullContext = `Context;\n"` + primaryContext + `"\n`;
        fullContext += `\n` + window.getContext();
        console.log("setting context; " + fullContext);

        window.manuClick('//*[@id="menu-button-:rb:"]');
        await sleep(250);

        window.manuClick('//*[@id="menu-list-:rb:-menuitem-:ru:"]');
        await sleep(250);

        window.manuWrite("/html/body/div[10]/div[3]/div/section/div/textarea", fullContext);
        await sleep(250);

        window.manuClick("/html/body/div[9]/div[3]/div/section/footer/button[2]");
    });

    window.manuWrite = function(xpath, text) {
        var result = document.evaluate(
            xpath,
            document,
            null,
            XPathResult.FIRST_ORDERED_NODE_TYPE,
            null
        );

        var node = result.singleNodeValue;

        if (node) {
            node.focus();

            // Since the node is an HTMLTextAreaElement, get the value setter from its prototype
            const nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(
                window.HTMLTextAreaElement.prototype,
                'value'
            ).set;

            nativeTextAreaValueSetter.call(node, text);

            // Dispatch the 'input' event to simulate user input
            var event = new Event('input', { bubbles: true });
            node.dispatchEvent(event);

        } else {
            console.error("Node not found for XPath:", xpath);
        }
    }

    window.manuClick = function(xpath) {
        var result = document.evaluate(
            xpath,
            document,
            null,
            XPathResult.FIRST_ORDERED_NODE_TYPE,
            null
        );

        var node = result.singleNodeValue;

        if (node) {
            node.click();
        }
    }

    contextPanel.appendChild(updateContextButton);

    contextMenuButton.addEventListener('click', () => {
        contextPanel.style.display = contextPanel.style.display === 'none' ? 'block' : 'none';
    });

    // Helper function to find the active location recursively
    function findActiveLocation(items) {
        for (const item of items) {
            if (item.active) {
                return item;
            }
            if (item.children && item.children.length > 0) {
                const activeChild = findActiveLocation(item.children);
                if (activeChild) {
                    return activeChild;
                }
            }
        }
        return null;
    }

    // Helper function to collect all active characters recursively
    function collectActiveCharacters(items, result = []) {
        for (const item of items) {
            if (item.active) {
                result.push(item);
            }
            if (item.children && item.children.length > 0) {
                collectActiveCharacters(item.children, result);
            }
        }
        return result;
    }

    // Modify the getContext function to utilize the helper functions
    window.getContext = function() {
        const activeLocation = findActiveLocation(locationGroups.flatMap(g => g.items));
        if (!activeLocation) return '';

        let context = ``;

        if (plotInput && plotInput.value.trim() !== '') {
            context += `Plot:\n"${plotInput.value}"\n`;
        } else {
            context += `Plot:\n"No specific plot."\n`;
        }

        context += `\nSetting;\n"${activeLocation.name}" (${timeInput.value}, ${weatherInput.value}):\n`
        context += `\u0009"${activeLocation.description}"\n`;

        context += `\n{{user}}'s characters;\n`;

        const activeUserCharacters = collectActiveCharacters(characterGroups.flatMap(g => g.items)).filter(char => char.characterType == 1);

        activeUserCharacters.forEach(char => {
            context += `"${char.name}" (${char.sex}, ${char.species}, ${char.age}, ${char.bodyType}, ${char.personality}):\n`;
            context += `\u0009"${char.bio}"\n`;
        });

        context += `\n{{char}}'s characters;\n`;

        const activeCharCharacters = collectActiveCharacters(characterGroups.flatMap(g => g.items)).filter(char => char.characterType == 0);

        activeCharCharacters.forEach(char => {
            context += `"${char.name}" (${char.sex}, ${char.species}, ${char.age}, ${char.bodyType}, ${char.personality}):\n`;
            context += `\u0009"${char.bio}"\n`;
        });

        return context;
    };

    // --- Character Sidebar with Groups and Nested Characters ---
    const characterSidebar = document.createElement('div');
    characterSidebar.id = 'character-sheet-sidebar';
    characterSidebar.style.cssText = `
        position: fixed;
        top: 0;
        right: -350px;
        width: 350px;
        height: 100%;
        display: flex;
        flex-direction: column;
        background-color: var(--bg-color);
        border-left: 2px solid var(--border-color);
        box-shadow: -2px 0 5px var(--shadow-color);
        box-sizing: border-box;
        transition: right 0.3s;
        z-index: 9999;
    `;
    document.body.appendChild(characterSidebar);

    const characterToggleButton = document.createElement('button');
    characterToggleButton.textContent = '☰';
    characterToggleButton.style.cssText = `
        position: fixed;
        top: 10px;
        right: 10px;
        padding: 5px 10px;
        border: none;
        background-color: var(--button-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
        transition: right 0.3s;
        z-index: 10000;
    `;
    characterToggleButton.addEventListener('click', () => {
        const isOpen = characterSidebar.style.right === '0px';
        characterSidebar.style.right = isOpen ? '-350px' : '0';
        characterToggleButton.style.right = isOpen ? '10px' : '360px';
    });
    document.body.appendChild(characterToggleButton);

    const characterHeader = document.createElement('div');
    characterHeader.style.cssText = `
        padding: 10px;
        background-color: var(--border-color);
        text-align: center;
        font-weight: bold;
        color: var(--text-color);
    `;
    characterHeader.textContent = 'Characters';
    characterSidebar.appendChild(characterHeader);

    const characterButtonBox = document.createElement('div');
    characterButtonBox.style.cssText = `
        display: flex;
        justify-content: space-between;
        padding: 10px;
        background-color: var(--bg-color);
        flex-shrink: 0;
    `;
    characterSidebar.appendChild(characterButtonBox);

    // New Character Button
    const newCharacterButton = document.createElement('button');
    newCharacterButton.textContent = 'New';
    newCharacterButton.title = 'Create New Character';
    newCharacterButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--success-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    newCharacterButton.addEventListener('click', () => {
        createNewCharacter();
    });
    characterButtonBox.appendChild(newCharacterButton);

    // Load Character Button
    const loadCharacterButton = document.createElement('button');
    loadCharacterButton.textContent = 'Load';
    loadCharacterButton.title = 'Load a Character';
    loadCharacterButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--info-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    loadCharacterButton.addEventListener('click', () => {
        loadCharacter();
    });
    characterButtonBox.appendChild(loadCharacterButton);

    // Group Character Button
    const groupCharacterButton = document.createElement('button');
    groupCharacterButton.textContent = 'Group';
    groupCharacterButton.title = 'Create New Group';
    groupCharacterButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--info-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    groupCharacterButton.addEventListener('click', () => {
        createNewCharacterGroup();
    });
    characterButtonBox.appendChild(groupCharacterButton);

    // Import Character Button
    const importCharacterButton = document.createElement('button');
    importCharacterButton.textContent = 'Import';
    importCharacterButton.title = 'Import Characters';
    importCharacterButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--warning-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    importCharacterButton.addEventListener('click', () => {
        importCharacters();
    });
    characterButtonBox.appendChild(importCharacterButton);

    // Export Character Button
    const exportCharacterButton = document.createElement('button');
    exportCharacterButton.textContent = 'Export';
    exportCharacterButton.title = 'Export Characters';
    exportCharacterButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--muted-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    exportCharacterButton.addEventListener('click', () => {
        exportCharacters();
    });
    characterButtonBox.appendChild(exportCharacterButton);

    // Add fifth button: "Load" for Character
    function loadCharacter() {
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = '.json';
        fileInput.addEventListener('change', async (event) => {
            const file = event.target.files[0];
            const reader = new FileReader();
            reader.onload = (e) => {
                try {
                    const character = JSON.parse(e.target.result);
                    if (character && character.id) {
                        // Add to Ungrouped
                        const ungrouped = characterGroups.find(g => g.name === 'Ungrouped');
                        if (ungrouped) {
                            ungrouped.items.push(character);
                        } else {
                            characterGroups[0].items.push(character);
                        }
                        renderCharacterGroups();
                    } else {
                        alert('Invalid character format.');
                    }
                } catch (error) {
                    alert('Failed to load character: ' + error.message);
                }
            };
            reader.readAsText(file);
        });
        fileInput.click();
    }

    const characterGroupList = document.createElement('div');
    characterGroupList.id = 'character-group-list';
    characterGroupList.style.cssText = `
        flex-grow: 1;
        overflow-y: auto;
        padding: 10px;
    `;
    characterSidebar.appendChild(characterGroupList);

    // Initialize Character Groups
    let characterGroups = [
        { name: 'Ungrouped', items: [], collapsed: false }
    ];

    // Function to create a new Character
    function createNewCharacter() {
        const newCharacter = {
            id: generateId(),
            active: true,
            emoji: '😀',
            avatar: 'Url goes here...',
            name: 'New Character',
            sex: '',
            species: '',
            age: '',
            bodyType: '',
            personality: '',
            bio: '',
            characterType: 0,
            children: [],
            collapsed: false
        };
        // Add to Ungrouped
        const ungrouped = characterGroups.find(g => g.name === 'Ungrouped');
        if (ungrouped) {
            ungrouped.items.push(newCharacter);
        } else {
            characterGroups[0].items.push(newCharacter);
        }
        renderCharacterGroups();
    }

    // Function to create a new Character Group
    function createNewCharacterGroup() {
        const groupName = prompt('Enter group name:', `Group ${characterGroups.length}`);
        if (groupName && groupName.trim() !== '') {
            characterGroups.push({ name: groupName.trim(), items: [], collapsed: false });
            renderCharacterGroups();
        }
    }

    // Function to render Character Groups and Items
    function renderCharacterGroups() {
        characterGroupList.innerHTML = '';

        characterGroups.forEach((group, groupIndex) => {
            // Sort items alphabetically by name
            group.items.sort((a, b) => a.name.localeCompare(b.name));

            const groupContainer = document.createElement('div');
            groupContainer.className = 'character-group';
            groupContainer.style.cssText = `
                margin-bottom: 10px;
                border: 1px solid var(--border-color);
                border-radius: 5px;
                background-color: var(--active-char-color);
            `;

            const groupHeader = document.createElement('div');
            groupHeader.style.cssText = `
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 5px 10px;
                background-color: var(--button-bg-color);
                color: var(--text-color);
                cursor: pointer;
                user-select: none;
                position: relative;
            `;
            groupHeader.textContent = group.name;
            groupHeader.addEventListener('click', () => {
                group.collapsed = !group.collapsed;
                renderCharacterGroups();
            });

            const groupActions = document.createElement('div');
            groupActions.style.cssText = `
                display: flex;
                align-items: center;
            `;

            // Activate/Deactivate All Button
            const toggleAllButton = document.createElement('button');
            toggleAllButton.title = 'Activate/Deactivate All';
            toggleAllButton.style.cssText = `
                background: none;
                border: none;
                color: var(--text-color);
                cursor: pointer;
                margin-right: 3px;
                font-size: 16px;
            `;
            updateToggleAllButton(toggleAllButton, group);
            toggleAllButton.addEventListener('click', (e) => {
                e.stopPropagation();
                toggleAllGroupCharacters(group);
                updateToggleAllButton(toggleAllButton, group);
                renderCharacterGroups();
            });
            groupActions.appendChild(toggleAllButton);

            // Rename Group Button
            const renameGroupButton = document.createElement('button');
            renameGroupButton.textContent = '✏️';
            renameGroupButton.title = 'Rename Group';
            renameGroupButton.style.cssText = `
                background: none;
                border: none;
                color: var(--text-color);
                cursor: pointer;
                margin-right: 2px;
            `;
            renameGroupButton.addEventListener('click', (e) => {
                e.stopPropagation();
                renameGroup(groupIndex);
            });
            groupActions.appendChild(renameGroupButton);

            // Delete Group Button
            const deleteGroupButton = document.createElement('button');
            deleteGroupButton.textContent = '🗑️';
            deleteGroupButton.title = 'Delete Group';
            deleteGroupButton.style.cssText = `
                background: none;
                border: none;
                color: var(--text-color);
                cursor: pointer;
            `;
            deleteGroupButton.addEventListener('click', (e) => {
                e.stopPropagation();
                deleteGroup(groupIndex);
            });
            groupActions.appendChild(deleteGroupButton);

            groupHeader.appendChild(groupActions);
            groupContainer.appendChild(groupHeader);

            if (!group.collapsed) {
                const itemsContainer = document.createElement('div');
                itemsContainer.style.cssText = `
                    padding: 5px 10px;
                    display: block;
                `;
                if (group.items.length === 0) {
                    const emptyInfo = document.createElement('div');
                    emptyInfo.className = 'character-slot';
                    emptyInfo.style.cssText = `
                        display: flex;
                        align-items: center;
                        padding: 10px;
                        border: 1px solid var(--border-color);
                        border-radius: 0px;
                        height: 20px;
                        margin-bottom: 5px;
                        background-color: var(--bg-color);
                        cursor: default;
                    `;

                    const infoText = document.createElement('span');
                    infoText.textContent = `Group is empty`;
                    infoText.style.cssText = `
                        color: var(--text-color);
                    `;

                    emptyInfo.appendChild(infoText);
                    itemsContainer.appendChild(emptyInfo);
                } else {
                    group.items.forEach((character, charIndex) => {
                        const characterSlot = createCharacterSlot(character, groupIndex);
                        itemsContainer.appendChild(characterSlot);
                    });
                }
                groupContainer.appendChild(itemsContainer);
            } else {
                const collapsedInfo = document.createElement('div');
                collapsedInfo.className = 'character-slot';
                collapsedInfo.style.cssText = `
                    display: flex;
                    align-items: center;
                    padding: 10px;
                    margin-bottom: 10px;
                    border: 1px solid var(--border-color);
                    border-radius: 5px;
                    height: 20px;
                    margin-top: 5px;
                    background-color: var(--bg-color);
                    cursor: default;
                    margin-left: 10px;
                    margin-right: 10px;
                `;
                const infoText = document.createElement('span');
                infoText.textContent = `${group.items.length} items hidden`;

                //lime
                const activeCount = countActiveCharacters(group.items);
                const totalCount = countTotalCharacters(group.items);
                if (activeCount === totalCount && totalCount > 0) {
                    // All active
                    infoText.style.cssText = `color: rgba(36, 242, 0, 0.75);`;
                } else if (activeCount === 0) {
                    // All inactive
                    infoText.style.cssText = `color: var(--text-color-darker);`;
                } else {
                    // Mixed
                    infoText.style.cssText = `color: rgba(242, 198, 0, 0.75);`;
                }

                collapsedInfo.appendChild(infoText);
                groupContainer.appendChild(collapsedInfo);
            }

            // Add dragover and drop events for grouping
            groupContainer.addEventListener('dragover', (e) => {
                e.preventDefault();
                groupContainer.style.border = `2px dashed var(--info-bg-color)`;
            });

            groupContainer.addEventListener('dragleave', (e) => {
                groupContainer.style.border = `1px solid var(--border-color)`;
            });

            groupContainer.addEventListener('drop', (e) => {
                e.preventDefault();
                groupContainer.style.border = `1px solid var(--border-color)`;
                const data = e.dataTransfer.getData('text/plain');
                const { type, id } = JSON.parse(data);
                if (type === 'character') {
                    moveCharacterToGroup(id, groupIndex);
                }
            });

            characterGroupList.appendChild(groupContainer);
        });

        // Ensure at least one group exists
        if (characterGroups.length === 0) {
            characterGroups.push({ name: 'Ungrouped', items: [], collapsed: false });
            renderCharacterGroups();
        }
    }

    // Function to update the Toggle All Button appearance
    function updateToggleAllButton(button, group) {
        const activeCount = countActiveCharacters(group.items);
        const totalCount = countTotalCharacters(group.items);
        if (activeCount === totalCount && totalCount > 0) {
            // All active
            button.textContent = '🟢';
        } else if (activeCount === 0) {
            // All inactive
            button.textContent = '🔴';
        } else {
            // Mixed
            button.textContent = '🟡';
        }
    }

    function countActiveCharacters(items) {
        let count = 0;
        items.forEach(item => {
            if (item.active) count++;
            if (item.children && item.children.length > 0) {
                count += countActiveCharacters(item.children);
            }
        });
        return count;
    }

    function countTotalCharacters(items) {
        let count = items.length;
        items.forEach(item => {
            if (item.children && item.children.length > 0) {
                count += countTotalCharacters(item.children);
            }
        });
        return count;
    }

    // Function to toggle all characters in a group
    function toggleAllGroupCharacters(group) {
        const allActive = countActiveCharacters(group.items) === countTotalCharacters(group.items);
        toggleCharacters(group.items, !allActive);
    }

    function toggleCharacters(items, state) {
        items.forEach(item => {
            item.active = state;
            if (item.children && item.children.length > 0) {
                toggleCharacters(item.children, state);
            }
        });
    }

    // Function to generate tooltip content for a character
    function getCharacterTooltipContent(character, isRadial = false) {
        if (isRadial && character.emoji === '📁') {
            // If it's a group node in the radial tree, only show the name
            return `<strong>"${character.name}"</strong>`;
        }
        var content = `<strong>"${character.name}"</strong>`;

        if(character.characterType != 2){
            content += ` <small>(${character.sex || 'Unknown'}, ${character.species || 'Unknown'}, ${character.age || 'Unknown'}, ${character.bodyType || 'Unknown'}, ${character.personality || 'Unknown'})</small>`;
        }

        content += `:<br><em>"${character.bio || 'No bio available.'}"</em>`;
        return content;
    }

    // Function to create a Character Slot DOM element (recursive)
    function createCharacterSlot(character, groupIndex, parent = null, level = 0) {
        const characterSlot = document.createElement('div');
        characterSlot.className = 'character-slot';
        characterSlot.draggable = true;
        characterSlot.dataset.id = character.id;
        characterSlot.style.cssText = `
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 5px;
            margin-bottom: 5px;
            border: 1px solid var(--border-color);
            border-radius: 5px;
            background-color: ${character.characterType == 1 ? 'var(--active-char-color)' : 'var(--bg-color)'};
            cursor: grab;
            margin-left: ${level * 20}px;
        `;

        // Drag events
        characterSlot.addEventListener('dragstart', (e) => {
            e.stopPropagation();
            e.dataTransfer.setData('text/plain', JSON.stringify({ type: 'character', id: character.id }));
            e.currentTarget.style.opacity = '0.5';
        });

        characterSlot.addEventListener('dragend', (e) => {
            e.currentTarget.style.opacity = '1';
        });

        // Click event for collapsing/expanding
        if (character.children && character.children.length > 0) {
            characterSlot.style.cursor = 'pointer';
            characterSlot.addEventListener('click', (e) => {
                e.stopPropagation();
                character.collapsed = !character.collapsed;
                renderCharacterGroups();
            });
        }

        // Left Div (Active Toggle, Emoji, Name)
        const leftDiv = document.createElement('div');
        leftDiv.style.cssText = `
            display: flex;
            align-items: center;
            flex-grow: 1;
            overflow: hidden;
        `;

        // Remove Collapse/Expand Button
        // (Not needed as per new requirement)
        const activeButton = document.createElement('button');
        activeButton.textContent = character.active ? '🟢' : '🔴';
        activeButton.title = 'Toggle Active';
        activeButton.style.cssText = `
            padding: 3px;
            border: none;
            background: none;
            cursor: pointer;
            color: var(--text-color);
            margin-right: 5px;
        `;
        activeButton.addEventListener('click', (e) => {
            e.stopPropagation();
            character.active = !character.active;
            updateAllToggleButtons();
            renderCharacterGroups();
        });
        leftDiv.appendChild(activeButton);

        if(character.characterType == 2) {
            activeButton.style.display = 'none';
        }

        const emojiSpan = document.createElement('span');
        emojiSpan.textContent = character.emoji;
        emojiSpan.style.marginRight = '5px';
        leftDiv.appendChild(emojiSpan);

        const nameSpan = document.createElement('span');
        nameSpan.textContent = character.name;
        nameSpan.style.cssText = `
            flex-grow: 1;
            min-width: 0;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            color: var(--text-color);
        `;

        // Add tooltip event listeners
        nameSpan.addEventListener('mouseenter', (e) => {
            showTooltip(e, getCharacterTooltipContent(character), true, character.avatar);
        });
        nameSpan.addEventListener('mouseleave', hideTooltip);
        nameSpan.addEventListener('dragover', hideTooltip);

        leftDiv.appendChild(nameSpan);

        characterSlot.appendChild(leftDiv);

        // Right Div (Edit, Delete, Export)
        const rightDiv = document.createElement('div');
        rightDiv.style.display = 'flex';
        rightDiv.style.alignItems = 'center';

        const editButton = document.createElement('button');
        editButton.textContent = '✏️';
        editButton.title = 'Edit Character';
        editButton.style.cssText = `
            padding: 0px;
            border: none;
            background: none;
            cursor: pointer;
            color: var(--text-color);
            margin-right: 2px;
        `;
        editButton.addEventListener('click', (e) => {
            e.stopPropagation();
            editCharacter(character);
        });
        rightDiv.appendChild(editButton);

        const deleteButton = document.createElement('button');
        deleteButton.textContent = '🗑️';
        deleteButton.title = 'Delete Character';
        deleteButton.style.cssText = `
            padding: 0px;
            border: none;
            background: none;
            cursor: pointer;
            color: var(--text-color);
            margin-right: 2px;
        `;
        deleteButton.addEventListener('click', (e) => {
            e.stopPropagation();
            deleteCharacter(character.id);
        });
        rightDiv.appendChild(deleteButton);

        const exportButton = document.createElement('button');
        exportButton.textContent = '⬇️';
        exportButton.title = 'Export Character';
        exportButton.style.cssText = `
            padding: 0px;
            border: none;
            background: none;
            cursor: pointer;
            color: var(--text-color);
        `;
        exportButton.addEventListener('click', (e) => {
            e.stopPropagation();
            exportCharacter(character);
        });
        rightDiv.appendChild(exportButton);

        characterSlot.appendChild(rightDiv);

        // Dragover and Drop events
        characterSlot.addEventListener('dragover', (e) => {
            e.preventDefault();
            e.stopPropagation();
            characterSlot.style.border = `2px dashed var(--info-bg-color)`;
        });

        characterSlot.addEventListener('dragleave', (e) => {
            characterSlot.style.border = `1px solid var(--border-color)`;
        });

        characterSlot.addEventListener('drop', (e) => {
            e.preventDefault();
            e.stopPropagation();
            characterSlot.style.border = `1px solid var(--border-color)`;
            const data = e.dataTransfer.getData('text/plain');
            const { type, id } = JSON.parse(data);
            if (type === 'character' && id !== character.id) {
                moveCharacterToParent(id, character);
            }
        });

        // Prevent click on buttons from triggering slot collapse/expand
        activeButton.addEventListener('click', (e) => e.stopPropagation());
        editButton.addEventListener('click', (e) => e.stopPropagation());
        deleteButton.addEventListener('click', (e) => e.stopPropagation());
        exportButton.addEventListener('click', (e) => e.stopPropagation());

        // Recursive rendering of children
        const container = document.createElement('div');
        container.appendChild(characterSlot);

        if (character.children && character.children.length > 0) {
            if (!character.collapsed) {
                character.children.forEach(child => {
                    const childSlot = createCharacterSlot(child, groupIndex, character, level + 1);
                    container.appendChild(childSlot);
                });
            } else {
                const collapsedInfo = document.createElement('div');
                collapsedInfo.className = 'character-slot';
                collapsedInfo.style.cssText = `
                    display: flex;
                    align-items: center;
                    padding: 10px;
                    margin-bottom: 5px;
                    border: 1px solid var(--border-color);
                    border-radius: 5px;
                    background-color: var(--bg-color);
                    height: 20px;
                    cursor: default;
                    margin-left: ${(level + 1) * 20}px;
                `;

                const infoText = document.createElement('span');
                infoText.textContent = `${character.children.length} items hidden`;

                //lime
                const activeCount = countActiveCharacters(character.children);
                const totalCount = countTotalCharacters(character.children);
                if (activeCount === totalCount && totalCount > 0) {
                    // All active
                    infoText.style.cssText = `color: rgba(36, 242, 0, 0.75);`;
                } else if (activeCount === 0) {
                    // All inactive
                    infoText.style.cssText = `color: var(--text-color-darker);`;
                } else {
                    // Mixed
                    infoText.style.cssText = `color: rgba(242, 198, 0, 0.75);`;
                }

                collapsedInfo.appendChild(infoText);
                container.appendChild(collapsedInfo);
            }
        }

        return container;
    }

    function updateAllToggleButtons() {
        characterGroups.forEach((group, groupIndex) => {
            const toggleAllButton = toggleAllButtonForGroup(groupIndex);
            if (toggleAllButton) {
                updateToggleAllButton(toggleAllButton, group);
            }
        });
    }

    // Function to get the toggle all button for a group
    function toggleAllButtonForGroup(groupIndex) {
        const groupContainer = characterGroupList.children[groupIndex];
        if (groupContainer) {
            const toggleAllButton = groupContainer.querySelector('button[title="Activate/Deactivate All"]');
            return toggleAllButton;
        }
        return null;
    }

    // Function to rename a group
    function renameGroup(groupIndex) {
        const newName = prompt('Enter new group name:', characterGroups[groupIndex].name);
        if (newName && newName.trim() !== '') {
            characterGroups[groupIndex].name = newName.trim();
            renderCharacterGroups();
        }
    }

    // Function to delete a group
    function deleteGroup(groupIndex) {
        if (characterGroups.length === 1) {
            alert('At least one group must exist.');
            return;
        }
        if (confirm(`Are you sure you want to delete the group "${characterGroups[groupIndex].name}"? All characters in this group will be moved to "Ungrouped".`)) {
            const group = characterGroups.splice(groupIndex, 1)[0];
            const ungrouped = characterGroups.find(g => g.name === 'Ungrouped');
            if (ungrouped) {
                ungrouped.items = ungrouped.items.concat(group.items);
            } else {
                characterGroups.unshift({ name: 'Ungrouped', items: group.items, collapsed: false });
            }
            renderCharacterGroups();
        }
    }

    // Default randomizer options
    const defaultRandomizerOptions = {
        emoji: {
            'Smileys': "😀%😃%😄%😁%😆%😅%😂%🤣",
            'People': "😊%😇%🙂%🙃%😉%😌%😍",
            // Add more categories if needed
        },
        name: {
            'Common': "Alex%Charlie%Sam%Jessie%Max%Taylor%Jordan%Casey%Jamie%Robin",
            'Fantasy': "Aragorn%Legolas%Gandalf%Frodo%Bilbo%Galadriel%Sauron",
            // Add more categories if needed
        },
        sex: {
            'Standard': "male*48%female*48%other*4",
            // It's possible to have other options
        },
        species: {
            'Realistic': "Human",
            'Fantasy': "Human%Elf%Dwarf%Orc%Demon",
            '25% Human | 75% Fantasy':"Human*2%Elf%Dwarf%Orc%Demon",
            '50% Human | 50% Fantasy':"Human*4%Elf%Dwarf%Orc%Demon",
            '75% Human | 25% Fantasy':"Human*12%Elf%Dwarf%Orc%Demon",
            'Sci-fi': "Human%Synth%Alien%Hybrid%Cyborg",
            '25% Human | 75% Sci-fi':"Human*2%Synth%Alien%Hybrid%Cyborg",
            '50% Human | 50% Sci-fi':"Human*4%Synth%Alien%Hybrid%Cyborg",
            '75% Human | 25% Sci-fi':"Human*12%Synth%Alien%Hybrid%Cyborg",
            'Animals':"Aardvark%Aardwolf%Abyssinian%Abyssinian Guinea Pig%Acadian Flycatcher%Achrioptera Manga%Ackie Monitor%Addax%Adélie Penguin%Admiral Butterfly%Aesculapian Snake%Affenpinscher%Afghan Hound%African Bullfrog%African Bush Elephant%African Civet%African Clawed Frog%African Elephant%African Fish Eagle%African Forest Elephant%African Golden Cat%African Grey Parrot%African Jacana%African Palm Civet%African Penguin%African Sugarcane Borer%African Tree Toad%African Wild Dog%Africanized bee (killer bee)%Agama Lizard%Agkistrodon Contortrix%Agouti%Aidi%Ainu%Airedale Terrier%Airedoodle%Akbash%Akita%Akita Shepherd%Alabai (Central Asian Shepherd)%Alaskan Husky%Alaskan Klee Kai%Alaskan Malamute%Alaskan Pollock%Alaskan Shepherd%Albacore Tuna%Albatross%Albertonectes%Albino (Amelanistic) Corn Snake%Aldabra Giant Tortoise%Alligator Gar%Allosaurus%Allosaurus%Alpaca%Alpine Dachsbracke%Alpine Goat%Alusky%Amano Shrimp%Amargasaurus%Amazon Parrot%Amazon River Dolphin (Pink Dolphin)%Amazon Tree Boa%Amazonian Royal Flycatcher%Amberjack%Ambrosia Beetle%American Alligator%American Alsatian%American Bulldog%American Bully%American Cocker Spaniel%American Cockroach%American Coonhound%American Dog Tick%American Eel%American Eskimo Dog%American Foxhound%American Hairless Terrier%American Leopard Hound%American Paddlefish%American Pit Bull Terrier%American Pugabull%American Pygmy Goat%American Robin%American Staffordshire Terrier%American Toad%American Water Spaniel%American Wirehair%Amethystine Python (Scrub Python)%Amphicoelias Fragillimus%Amur Leopard%Anaconda%Anatolian Shepherd Dog%Anchovies%Andrewsarchus%Angelfish%Angelshark%Angled Sunbeam Caterpillar%Anglerfish%Angora Ferret%Angora Goat%Anhinga%Anna’s Hummingbird%Anole Lizard%Anomalocaris%Ant%Antarctic Scale Worm%Anteater%Antelope%Anteosaurus%Antiguan Racer Snake%Aoudad Sheep%Ape%Apennine Wolf%Appenzeller Dog%Apple Head Chihuahua%Apple Moth%Arabian Cobra%Arabian Wolf%Arafura File Snake%Arambourgiania%Arapaima%Archaeoindris%Archaeopteryx%Archaeotherium%Archelon Turtle%Archerfish%Arctic Char%Arctic Fox%Arctic Hare%Arctic Wolf%Arctodus%Arctotherium%Argentavis Magnificens%Argentine Black and White Tegu%Argentine Horned Frog%Argentinosaurus%Arizona Bark Scorpion%Arizona Black Rattlesnake%Arizona Blonde Tarantula%Arizona Coral Snake%Armadillo%Armadillo Lizard%Armenian Gampr%Armored Catfish%Armyworm%Arsinoitherium%Arthropleura%Aruba Rattlesnake%Ashy Mining Bee%Asian Arowana%Asian Carp%Asian Cockroach%Asian Elephant%Asian Giant Hornet%Asian Lady Beetle%Asian Longhorn Beetle%Asian Palm Civet%Asian Vine Snake%Asian Water Monitor%Asiatic Black Bear%Asp%Assassin Bug%Assassin Snail%Atlantic Cod%Atlantic Salmon%Atlantic Sturgeon%Atlas Beetle%Atlas Moth%Aurochs%Aussiedoodle%Aussiedor%Aussiepom%Australian Bulldog%Australian Cattle Dog%Australian Cockroach%Australian Firehawk%Australian Flathead Perch%Australian Gecko%Australian Kelpie Dog%Australian Labradoodle%Australian Mist%Australian Retriever%Australian Shepherd%Australian Shepherd Mix%Australian Terrier%Australopithecus%Australorp Chicken%Avocet%Axanthic Ball Python%Axolotl%Ayam Cemani%Aye-aye%Azawakh%Babirusa%Baboon%Bactrian Camel%Badger%Bagle – Basset Hound Mix%Bagworm Moth%Bagworm Moth Caterpillar%Baird’s Rat Snake%Bald Eagle%Baleen Whale%Balinese%Balkan Lynx%Ball Python%Bamboo Rat%Bamboo Shark%Bamboo Worms%Banana Ball Python%Banana Cinnamon Ball Python%Banana Spider%Banded Krait%Banded Palm Civet%Banded Water Snake%Bandicoot%Banjo Catfish%Barb%Barbet%Barbut’s Cuckoo Bumblebee%Barinasuchus%Bark Beetle%Bark Scorpion%Barn Owl%Barn Spider%Barn Swallow%Barnacle%Barnevelder%Barosaurus%Barracuda%Barramundi Fish%Barred Owl%Barreleye Fish (Barrel Eye)%Barylambda%Basenji Dog%Basenji Mix%Basilisk Lizard%Basilosaurus%Basking Shark%Bass%Bassador%Basset Fauve de Bretagne%Basset Hound%Bassetoodle%Bat-Eared Fox%Batfish%Bavarian Mountain Hound%Baya%Bea-Tzu%Beabull%Beagador%Beagle%Beagle Mix%Beagle Shepherd%Beaglier%Beago%Bear%Bearded Collie%Bearded Dragon%Bearded Fireworm%Bearded Vulture%Beaski%Beauceron%Beauty rat snake%Beaver%Bed Bugs%Bedlington Terrier%Bee%Bee-Eater%Beefalo%Beetle%Beewolf wasp%Belgian Canary%Belgian Laekenois%Belgian Malinois%Belgian Malinois Mix%Belgian Sheepdog%Belgian Shepherd%Belgian Tervuren%Belted Kingfisher%Beluga Sturgeon%Beluga Sturgeon%Bengal Tiger%Bergamasco%Berger Blanc Suisse%Berger Picard%Bernedoodle%Bernese Mountain Dog%Bernese Mountain Dog Mix%Bernese Shepherd%Betta Fish (Siamese Fighting Fish)%Bhutan Takin%Bichir%Bichon Frise%Bichpoo%Biewer Terrier%Bigfin Reef Squid %Bighorn Sheep%Bilby%Binturong%Bird%Bird Of Paradise%Bird Snake%Birman%Biscuit Beetle%Bismarck Ringed Python%Bison%Black And Tan Coonhound%Black and White Warbler%Black Aphids%Black Bass%Black Crappie%Black Dragon Lizard%Black German Shepherd%Black Mamba%Black Marlin%Black Mouth Cur%Black Pastel Ball Python%Black Rat Snake%Black Rhinoceros%Black Russian Terrier%Black Sea Bass%Black Swallowtail Caterpillar%Black Tarantula%Black Throat Monitor%Black Wasp%Black Widow Spider%Black Witch Moth%Black-Bellied Whistling Duck%Black-Capped Chickadee%Black-Footed Ferret%Black-headed python%Black-Tailed Rattlesnake%Blackburnian Warbler%Blackfin Tuna%Blacknose Shark%Blackpoll Warbler%Blacktip Reef Shark%Blacktip Shark %Bladefin Basslet%Blanket Octopus%Blind Snake%Blister Beetle%Blister Beetle%Blobfish%Blood Python%Bloodhound%Blowfly%Blue Andalusian%Blue Belly Lizard%Blue Catfish%Blue Death Feigning Beetle%Blue Dragon Sea Slug%Blue Eyed Pleco%Blue German Shepherd%Blue Gray Gnatcatcher%Blue grosbeak%Blue Iguana%Blue Jay%Blue Lacy Dog%Blue Nose Pit Bull%Blue Picardy Spaniel%Blue Racer%Blue Shark%Blue Tanager (Blue-Grey Tanager)%Blue Tang%Blue Tit%Blue Whale%Blue-Ringed Octopus%Bluefin Tuna%Bluefish%Bluegill%Bluetick Coonhound%Boas%Bobcat%Bobolink%Boelen’s python%Boer Goat%Boerboel%Boggle%Boglen Terrier%Boiga%Bolivian Anaconda%Bolognese Dog%Bombardier Beetle%Bombay%Bonefish%Bongo%Bonito Fish%Bonnethead Shark%Bonobo%Booby%Boomslang%Booted Bantam%Borador%Border Collie%Border Collie Mix%Border Terrier%Bordoodle%Borkie%Bornean Orangutan%Borneo Elephant%Boskimo%Boston Terrier%Bottlenose Dolphin%Bouvier Des Flandres%Bowfin%Bowhead Whale%Box Jellyfish%Box Tree Moth%Box Turtle%Box-Headed Blood Bee%Boxachi%Boxador%Boxer Dog%Boxer Mix%Boxerdoodle%Boxfish%Boxsky%Boxweiler%Bracco Italiano%Brachiosaurus%Brahma Chicken%Brahminy Blindsnake%Braque du Bourbonnais%Braque Francais%Brazilian Black Tarantula%Brazilian Terrier%Brazilian Treehopper%Bredl’s Python%Briard%British Timber%Brittany%Brontosaurus%Bronze Whaler Shark%Bronze-winged Jacana%Brook Trout%Brookesia Micra%Brown Bear%Brown Dog Tick%Brown Headed Cowbird%Brown Hyena%Brown Snake%Brown Tree Snake%Brown Water Snake%Brown-banded Cockroach%Brug%Brussels Griffon%Budgerigar%Buff Orpington Chicken%Buffalo%Buffalo Fish%Bull and Terrier%Bull Shark%Bull Terrier%Bull Trout%Bullboxer%Bulldog%Bulldog Mix%Bullfrog%Bullmastiff%Bullsnake%Bumblebee%Burmese%Burmese Python%Burrowing Frog%Burrowing Owl%Bush Baby%Bush Dog%Bush Viper%Bushmaster Snake%Butterfly%Butterfly Fish%Cabbage Moth%Cactus Moth%Cactus Mouse%Cactus Wren%Caecilian%Caiman%Caiman Lizard%Cairn Terrier%California Condor%California Kingsnake%California Tarantula%Camel%Camel Cricket%Camel Spider%Campine Chicken%Canaan Dog%Canada Lynx%Canada Warbler%Canadian Eskimo Dog%Canadian Horse%Cane Corso%Cane Rat%Cane Spider%Cantil%Canvasback%Cape Lion%Capuchin%Capybara%Caracal%Cardinal%Caribbean Reef Shark%Caribou%Carolina Dog%Carolina Parakeet%Carp%Carpenter Ant%Carpet Beetle%Carpet Python%Carpet Viper%Carrion Beetle%Cascabel%Cashmere Goat%Cassowary%Cat%Cat Snake%Cat-Eyed Snake%Cat-Faced Spider%Catahoula Bulldog%Catahoula Leopard%Catalan Sheepdog%Caterpillar%Catfish%Caucasian Mountain Dog (Shepherd)%Caucasian Shepherd%Cava Tzu%Cavador%Cavalier King Charles Spaniel%Cavapoo%Cave Bear%Cave Lion%Cecropia Moth%Cedar Waxwing%Centipede%Central Ranges Taipan%Cephalaspis%Ceratopsian%Ceratosaurus%Cervalces latifrons (Broad-Fronted Moose)%Cesky Fousek%Cesky Terrier%Chain Pickerel%Chameleon%Chamois%Chartreux%Cheagle%Checkered Garter Snake%Cheetah%Chesapeake Bay Retriever%Chestnut-Sided Warbler%Chi Chi%Chickadee%Chicken%Chicken Snake%Chigger%Chihuahua%Chihuahua Mix%Children’s python%Chilean Recluse Spider%Chilean Rose Tarantula%Chilesaurus%Chimaera%Chimpanzee%Chinchilla%Chinese Alligator%Chinese Cobra%Chinese Crested Dog%Chinese Geese%Chinese Paddlefish%Chinese Shar-Pei%Chinese Water Deer%Chinook%Chinook Salmon%Chinstrap Penguin%Chipit%Chipmunk%Chipoo%Chipping Sparrow%Chiton%Chiweenie%Chorkie%Chow Chow%Chow Pom%Chow Shepherd%Christmas Beetle%Christmas Island Red Crab%Chromodoris Willani%Chusky%Cicada%Cichlid%Cinereous Vulture%Cinnamon Ball Python%Cinnamon Bear%Cinnamon Ferret%Clark’s Grebe%Clearnose Skate%Click Beetle%Clock Spider%Clothes Moth%Clouded Leopard%Clownfish%Clumber Spaniel%Coachwhip Snake%Coastal Carpet Python%Coastal Taipan%Coati%Cobalt Blue Tarantula%Cobia Fish%Cobras%Cochin Chicken%Cockalier%Cockapoo%Cockatiel%Cockatoo%Cocker Spaniel%Cockle%Cockroach%Coconut Crab %Codfish%Codling Moth%Coelacanth%Collared Peccary%Collett’s Snake%Collie%Collie Mix%Colossal Squid%Comb Jellyfish%Comb-crested Jacana%Comet Moth%Comfort Retriever%Common Buzzard%Common Carp%Common European Adder%Common Frog%Common Furniture Beetle%Common Goldeneye%Common Grackle%Common Green Magpie%Common House Spider%Common Loon%Common Raven%Common Spotted Cuscus%Common Toad%Common Yellowthroat%Compsognathus%Cone Snail%Conger Eel%Congo Snake%Conure%Cookiecutter Shark%Cooper’s Hawk%Copperhead%Coral%Coral Snake%Corella%Corgidor%Corgipoo%Corkie%Corman Shepherd%Cormorant%Corn Earworm%Corn Rex Cat (Cornish Rex)%Corn Snake%Cory Catfish%Coryphodon%Cosmic Caterpillar%Costa’s Hummingbird%Coton de Tulear%Cotton-top Tamarin%Cottonmouth%Coues Deer%Cougar%Cow%Cow Reticulated Python%Coyote%Crab%Crab Spider%Crab-Eating Fox%Crab-Eating Macaque%Crabeater Seal%Crane%Crappie Fish%Crayfish%Crested Gecko%Crested Penguin%Cricket%Croatian Sheepdog%Crocodile%Crocodile Monitor%Crocodile Shark%Crocodylomorph%Cross Fox%Cross River Gorilla%Crow%Crucian Carp%Cryolophosaurus%Cuban Boa%Cuban Cockroach%Cubera Snapper%Cuckoo%Cucumber Beetle%Curly Coated Retriever%Curly Hair Tarantula%Cuttlefish%Czechoslovakian Wolfdog%Dachsador%Dachshund%Dachshund Mix%Daeodon%Dalmadoodle%Dalmador%Dalmatian%Damselfish%Dandie Dinmont Terrier%Daniff%Danios%Danish Swedish Farmdog%Dapple Dachshund%Dark-Eyed Junco%Dark-Eyed Junco%Darkling Beetle%Darwin’s fox%Darwin’s Frog%Daug%De Brazza’s Monkey%De Kay’s Brown Snake%Death Adder%Death’s Head Cockroach%Deathwatch Beetle%Decorator Crab%Deer%Deer Head Chihuahua%Deer Mouse%Deer Tick%Deinocheirus%Deinosuchus%Desert Ghost Ball Python%Desert Kingsnake%Desert Locust%Desert Rain Frog%Desert Tortoise%Desert Wolf%Desmostylus%Deutsche Bracke%Devil’s Coach Horse Beetle%Devon Rex%Dhole%Diamond Python%Diamondback Moth%Dickcissel%Dickinsonia%Dik-Dik%Dilophosaurus%Dimetrodon%Diminutive Woodrat%Dingo%Dinocrocuta%Dinofelis%Dinopithecus%Dinosaur Shrimp%Dinosaurs%Diplodocus%Diprotodon%Dire Wolf%Disco Clam%Discus%Diving Bell Spider (Water Spider)%Diving Duck%Doberman Pinscher%Dobsonfly%Dodo%Doedicurus%Dog%Dog Tick%Dogo Argentino%Dogue De Bordeaux%Dolphin%Donkey%Dorgi%Dorkie%Dorking Chicken%Dormouse%Double Doodle%Douc%Downy Woodpecker%Doxiepoo%Doxle%Draco Volans Lizard%Dragon Eel%Dragon Snake (Javan Tubercle Snake% Javan Mudsnake)%Dragonfish%Dragonfly%Dreadnoughtus%Drever%Dried Fruit Moth%Drum Fish%Dubia Cockroach%Duck%Dugong%Dumeril’s Boa%Dung Beetle%Dungeness Crab%Dunker%Dunkleosteus%Dunnock%Dusky Dolphin%Dusky Shark%Dutch Rabbit%Dutch Shepherd%Dwarf Boa%Dwarf Crocodile%Dwarf Gourami%Dwarf Hamster%Eagle%Eagle Ray%Eared Grebe%Earless Monitor Lizard%Earthworm%Earwig%East Siberian Laika%Eastern Barred Bandicoot%Eastern Bluebird%Eastern Box Turtle%Eastern Brown Snake%Eastern Chipmunk%Eastern Coral Snake%Eastern Cottontail%Eastern Diamondback Rattlesnake%Eastern Dobsonfly%Eastern Fence Lizard%Eastern Glass Lizard%Eastern Gorilla%Eastern Gray Squirrel%Eastern Green Mamba%Eastern Hognose Snake%Eastern Indigo Snake%Eastern Kingbird%Eastern Lowland Gorilla%Eastern Meadowlark%Eastern Phoebe%Eastern Racer%Eastern Rat Snake%Eastern Tiger Snake%Eastern Turkey (Wild Turkey)%Eastern Woodrat%Echidna%Eclectus Parrot%Edible Frog%Eel%Eel catfish%Eelpout%Egret%Egyptian Cobra (Egyptian Asp)%Egyptian Goose%Egyptian Mau%Egyptian Tortoise%Egyptian Vulture%Eider%Eland%Elasmosaurus%Elasmotherium%Electric Catfish%Electric Eel%Elegant Tern%Elephant%Elephant Beetle%Elephant Bird%Elephant Fish%Elephant Seal%Elephant Shrew%Elf Owl%Elk%Ember Tetra%Embolotherium%Emerald Toucanet%Emerald Tree Boa%Emerald Tree Monitor%Emperor Angelfish%Emperor Goose%Emperor Penguin%Emperor Tamarin%Emu%Enchi Ball Python%English Angora Rabbit%English Bulldog%English Cocker Spaniel%English Cream Golden Retriever%English Crested Guinea Pig%English Foxhound%English Longhorn Cattle%English Pointer%English Setter%English Shepherd%English Springer Spaniel%English Toy Terrier%Entlebucher Mountain Dog%Epagneul Pont Audemer%Epicyon haydeni%Epidexipteryx%Equatorial Spitting Cobra%Equus giganteus%Ermine%Eryops%Escolar%Eskimo Dog%Eskipoo%Estrela Mountain Dog%Euoplocephalus%Eurasian Beaver%Eurasian Bullfinch%Eurasian Collared Dove%Eurasian Eagle-owl%Eurasian Jay%Eurasian Lynx%Eurasian Nuthatch%Eurasian Wolf%Eurasier%European Bee-Eater%European Corn Borer%European Goldfinch%European Polecat%European Robin%European Starling%European Wildcat%Eurypterus%Evening Bat%Evening Grosbeak%Executioner Wasp %Eyelash Viper%Fairy-Wren%Falcon%Fallow deer%False Cobra%False coral snake%False Killer Whale%False Water Cobra%False Widow Spider%Fancy Mouse%Fangtooth%Feather Star%Feist%Fennec Fox%Fer-de-lance Snake%Ferret%Ferruginous Hawk%Fiddler Crab%Field Cuckoo Bumblebee%Field Spaniel%Fierce Snake%Figeater Beetle%Fila Brasileiro%Fin Whale%Finch%Finnish Lapphund%Finnish Spitz%Fire Ball Python%Fire Eel%Fire Salamander%Fire-Bellied Toad%Firefly%Firefly Ball Python%Fish%Fisher%Fishing Cat%Flamingo%Flat-Coated Retriever%Flathead Catfish%Flea%Flea Beetle%Fleckvieh Cattle%Florida Gar%Florida Mouse%Florida Panther%Florida Woods Cockroach%Flounder%Flounder Fish%Flour Beetle%Flowerhorn Fish%Fluke Fish (summer flounder)%Fly%Flycatcher%Flying Fish%Flying Lemur%Flying Snake%Flying Squirrel%Football Fish%Forest Cobra%Forest Cuckoo Bumblebee%Formosan Mountain Dog%Fossa%Fox%Fox Snakes%Fox Squirrel%Fox Terrier%Freeway Ball Python%French Bulldog%French Bulldog Mix%French Lop%Frenchton%Frengle%Freshwater Crocodile%Freshwater Drum%Freshwater Eel%Freshwater Jellyfish%Freshwater Sunfish%Frigatebird%Frilled Lizard%Frilled Shark%Fritillary Butterfly%Frizzle Chicken%Frog%Frogfish%Frug%Fruit Bat%Fruit Fly%Fulvous Whistling Duck%Fur Seal%Furrow Bee%Gaboon Viper%Gadwall%Galapagos Penguin%Galapagos Shark%Galapagos Tortoise%Gar%Garden Eel%Garden Spider%Gargoyle Gecko%Garter Snake%Gastornis%Gazelle%Gecko%Genet%Gentoo Penguin%Geoffroys Tamarin%Gerberian Shepsky%Gerbil%German Cockroach%German Longhaired Pointer%German Pinscher%German Shepherd Guide%German Shepherd Mix%German Sheppit%German Sheprador%German Shorthaired Pointer%German Spitz%German Wirehaired Pointer%Gharial%Ghost Catfish%Ghost Crab%Giant African Land Snail%Giant Armadillo%Giant Beaver%Giant Clam%Giant Desert Centipede%Giant Golden Mole%Giant House Spider%Giant Isopod%Giant Leopard Moth%Giant Panda Bear%Giant Salamander%Giant Schnauzer%Giant Schnoodle%Giant Siphonophore%Giant Trevally%Giant Weta%Giant Wood Moth%Gibbon%Gigantopithecus%Gila Monster%Giraffe%Glass Frog%Glass Lizard%Glechon%Glen Of Imaal Terrier%Glowworm%Gnat%Goat%Goberian%Goblin Shark%Goby Fish%Goldador%Goldcrest%Golden Dox%Golden Eagle%Golden Irish%Golden Jackal%Golden Lancehead%Golden Lion Tamarin%Golden Masked Owl%Golden Mole%Golden Newfie%Golden Oriole%Golden Pyrenees%Golden Retriever%Golden Retriever Mix%Golden Saint%Golden Shepherd%Golden Shiner%Golden Tortoise Beetle%Golden Trout%Golden-Crowned Flying Fox%Golden-Crowned Kinglet%Goldendoodle%Goldfish%Goliath Beetle%Goliath Frog%Goliath Grouper%Goliath Tigerfish%Gollie%Gomphotherium%Goonch Catfish%Goose%Gooty Sapphire Tarantula%Gopher%Gopher Tortoise%Goral%Gordon Setter%Gorgosaurus%Gorilla%Goshawk%Gouldian Finch%Gourami%Grapevine Beetle%Grass Carp%Grass Snake%Grass Spider%Grasshopper%Grasshopper Mouse%Gray Catbird%Gray Fox%Gray Tree Frog%Great Blue Heron%Great Crested Flycatcher%Great Dane%Great Dane Mix%Great Danoodle%Great Egret%Great Hammerhead Shark%Great Kiskadee%Great Plains Rat Snake%Great Potoo Bird%Great Pyrenees%Great Pyrenees Mix%Great White Shark%Greater Swiss Mountain Dog%Grebe%Green Anaconda%Green Anole%Green Aphids%Green Bee-Eater%Green Bottle Blue Tarantula%Green Frog%Green Heron%Green June Beetle%Green Mamba%Green Rat Snake%Green Snake%Green Sunfish%Green Tree Frog%Green Tree Python%Greenland Dog%Greenland Shark%Grey Heron%Grey Mouse Lemur%Grey Reef Shark%Grey Seal%Greyhound%Griffon Vulture%Griffonshire%Grizzly Bear%Groenendael%Ground Snake%Ground Squirrel%Groundhog (Woodchuck)%Groundhog Tick%Grouper%Grouse%Grunion%Guadalupe Bass%Guinea Fowl%Guinea Pig%Gulper Catfish %Gulper Eel %Guppy%Gypsy Cuckoo Bumblebee%Gypsy Moth%Haast’s Eagle%Habu Snake%Haddock%Hagfish%Haikouichthys%Hainosaurus%Hairy Frogfish%Hairy Woodpecker%Hairy-footed Flower Bee%Halibut%Hallucigenia%Hamburg Chicken%Hammerhead Shark%Hammerhead Worm%Hammond’s flycatcher%Hamster%Harbor Porpoise%Harbor Seal%Hardhead Catfish%Hare%Harlequin Coral Snake%Harlequin Rabbit%Harp Seal%Harpy Eagle%Harrier%Harris’s Hawk%Hartebeest%Hatzegopteryx%Havamalt%Havanese%Havapoo%Havashire%Havashu%Hawaiian Crow%Hawaiian Goose (Nene)%Hawaiian Monk Seal%Hawk%Hawk Moth Caterpillar%Hedgehog%Helicoprion%Hellbender%Hepatic Tanager (Red Tanager)%Hercules Beetle%Hercules Moth%Hermit Crab%Heron%Herrerasaurus%Herring%Herring Gull%Highland Cattle%Himalayan%Hippopotamus%Hippopotamus gorgops%Hoary Bat%Hobo Spider%Hognose snake%Hokkaido%Holy Cross Frog%Honduran White Bat%Honey Badger%Honey Bee%Honey Buzzard%Hooded Oriole%Hooded Seal%Hook-Nosed Sea Snake%Hoopoe%Horgi%Horn Shark%Hornbill%Horned Adder%Horned Beetle%Horned Grebe%Horned Lizard%Horned Viper%Hornet%Horse%Horse Mackerel%Horsefly%Horseshoe Crab%Houdan Chicken%House Finch%House Sparrow (English Sparrow)%House wren%Housefly%Hovasaurus%Hovawart%Howler Monkey%Human%Humboldt Penguin%Humboldt Squid%Hummingbird%Hummingbird Hawk-Moth%Humpback Whale%Huntaway%Huntsman Spider%Huskador%Huskita%Husky%Husky Jack%Huskydoodle%Hyacinth Macaw%Hyaenodon%Hyena%Ibex%Ibis%Ibizan Hound%Icadyptes%Icelandic Sheepdog%Ichthyosaurus%Ichthyostega%Iguana%Iguanodon%IMG Boa Constrictor%Immortal Jellyfish%Impala%Imperial Moth%Inchworm%Indian Cobra%Indian Elephant%Indian Giant Squirrel%Indian Palm Squirrel%Indian python%Indian Rhinoceros%Indian Star Tortoise%Indianmeal Moth%Indigo Snake%Indochinese Tiger%Indri%Inland Taipan%Insect%Insects%Io Moth%Irish Doodle%Irish Elk%Irish Setter%Irish Terrier%Irish Water Spaniel%Irish WolfHound%Italian Greyhound%Ivory-billed woodpecker%Ivy Bee%Jabiru%Jacana%Jack Crevalle%Jack Russells%Jack-Chi%Jackabee%Jackal%Jackdaw%Jackrabbit%Jackson’s Chameleon%Jagdterrier%Jaguar%Jaguarundi Cat%Jamaican Boa%Jamaican Iguana%Japanese Bantam Chicken%Japanese Beetle%Japanese Chin%Japanese Macaque%Japanese rat snake%Japanese Spitz%Japanese Squirrel%Japanese Terrier%Javan Leopard%Javan Rhinoceros%Javanese%Jellyfish%Jerboa%Jewel Beetle %John Dory%Jonah Crab%Joro Spider%Josephoartigasia monesi%Jumping Spider%Jungle Carpet Python%Junglefowl%Kagu%Kai Ken%Kakapo%Kaluga Sturgeon%Kamehameha Butterfly%Kangal Shepherd Dog%Kangaroo%Kangaroo Mouse%Kangaroo Rat%Katydid%Kaua’i ‘Ō‘ō%Keagle%Keel-Billed Toucan%Keelback%Keeshond%Kelp Greenling%Kentucky Warbler%Kenyan Sand Boa%Kermode Bear (Spirit Bear)%Kerry Blue Terrier%Kestrel%Keta Salmon%Key Deer%Keyhole Cichlid%Khao Manee%Khapra Beetle%Kiang%Kiko Goat%Killdeer%Killer Clown Ball Python%Killer Whale%Killifish%Kinabalu Giant Red Leech%Kinder Goat%King Cobra%King Crab%King Eider%King Mackerel%King Penguin%King Rat Snake%King Salmon%King Shepherd%King Snake%King Vulture%Kingfisher%Kingklip%Kinkajou%Kirtland’s Snake%Kishu%Kissing Bugs%Kissing Gourami%Kit Fox%Kitefin Shark%Kiwi%Klipspringer%Knifefish%Knight Anole%Koala%Kodiak Bear%Kodkod%Koi Fish%Kokanee Salmon%Komodo Dragon%Komondor%Kooikerhondje%Koolie%Korean Jindo%Kori Bustard%Kouprey%Kowari%Krait%Krill%Kudu%Kudzu Bug%Kuvasz%Labahoula%Labmaraner%Labout’s Fairy Wrasse%Labrabull%Labradane%Labradoodle%Labrador Retriever%Labraheeler%Labrottie%Lace Bug%Lace Monitor%Ladybug%Ladyfish%Lagotto Romagnolo%Lake Sturgeon%Lake Trout%Lakeland Terrier%LaMancha Goat%Lamprey%Lancashire Heeler%Lancetfish%Landseer Newfoundland%Lappet-faced Vulture%Lapponian Herder%Larder Beetle%Large Munsterlander%Largemouth Bass%Laughing Kookaburra%Lavender Albino Ball Python%Lawnmower Blenny%Lazarus Lizard%Leaf-Tailed Gecko%Leafcutter Ant%Leafcutter Bee%Least Flycatcher%Leatherback Sea Turtle%Leech%Leedsichthys%Leghorn Chicken%Leichhardt’s Grasshopper%Lemming%Lemon Blast Ball Python%Lemon Cuckoo Bumblebee%Lemon Shark%Lemur%Leonberger%Leopard%Leopard Cat%Leopard Frog%Leopard Gecko%Leopard Lizard%Leopard Seal%Leopard Shark%Leopard Tortoise%Leptocephalus%Lesser Jacana%Lesser Scaup%Lhasa Apso%Lhasapoo%Liger%Limpet%Lineback Cattle%Linnet%Lion%Lion’s Mane Jellyfish%Lionfish%Liopleurodon%Liopleurodon%Lipstick Albino Boa%Little Brown Bat%Little Penguin%Livyatan%Lizard%Lizardfish%Llama%Loach%Lobster%Locust%Loggerhead Shrike%Lone Star Tick%Long-Eared Owl%Long-Haired Rottweiler%Long-Tailed Tit%Long-Winged Kite Spider%Longfin Mako Shark%Longnose Gar%Lorikeet%Loris%Lowchen%Lumpfish%Luna Moth%Luna Moth Caterpillar%Lungfish%Lurcher%Lykoi Cat%Lynx%Lyrebird%Lystrosaurus%Macaque%Macaroni Penguin%Macaw%MacGillivray’s Warbler%Machaeroides%Mackenzie Valley Wolf%Macrauchenia%Madagascar Hissing Cockroach%Madagascar Jacana%Madagascar Tree Boa%Madora Moth%Magellanic Penguin%Maggot%Magnolia Warbler%Magpie%Magyarosaurus%Mahi Mahi (Dolphin Fish)%Maiasaura%Maine Coon%Mal Shi%Malayan Civet%Malayan Krait%Malayan Tiger%Malchi%Mallard%Malteagle%Maltese%Maltese Mix%Maltese Shih Tzu%Maltipom%Maltipoo%Mamba%Mamushi Snake%Man of War Jellyfish%Manatee%Manchester Terrier%Mandarin Rat Snake%Mandrill%Maned Wolf%Mangrove Snake%Mangrove Snapper%Manta Ray%Mantella Frog%Marabou Stork%Marans Chicken%Marble Fox%Maremma Sheepdog%Margay%Marine Iguana%Marine Toad%Markhor%Marmoset%Marmot%Marsh Frog%Marsican Brown Bear%Masiakasaurus%Masked Angelfish%Masked Palm Civet%Mason Bee%Massasauga%Mastador%Mastiff%Mastiff Mix%Mauzer%May Beetle%Mayan Cichlid%Meagle%Mealworm Beetle%Mealybug%Meerkat%Megalania%Megalochelys%Megalodon%Megamouth Shark%Meganeura%Megatherium%Meiolania%Mekong Giant Catfish%Merganser%Mexican Alligator Lizard%Mexican Black Kingsnake%Mexican Eagle (Northern crested caracara)%Mexican Fireleg Tarantula%Mexican Free-Tailed Bat%Mexican Mole Lizard%Microraptor%Midget Faded Rattlesnake%Miki%Milk Snake%Milkfish%Milkweed aphids%Millipede%Mini Labradoodle%Mini Lop%Miniature Bull Terrier%Miniature Husky%Miniature Pinscher%Mink%Minke Whale%Mississippi Kite%Moccasin Snake%Mockingbird%Modern Game Chicken%Mojarra%Mojave Ball Python%Mojave Rattlesnake%Mola mola (Ocean Sunfish)%Mole%Mole Crab (Sand Flea)%Mole Cricket%Mole Snake%Mollusk%Molly%Monarch Butterfly%Mongoose%Mongrel%Monitor Lizard%Monkey%Monkfish%Monocled Cobra%Monte Iberia Eleuth%Moon Jellyfish%Moonglow Boa%Moorhen%Moose%Moray Eel%Morkie%Morpho Butterfly%Mosasaurus%Moscow Watchdog%Mosquito%Moth%Mountain Beaver%Mountain Bluebird%Mountain Cur%Mountain Feist%Mountain Gorilla%Mountain Lion%Mourning Dove%Mourning Gecko%Mourning Warbler%Mouse%Mouse Spider%Mouse-Deer (Chevrotain)%Mozambique Spitting Cobra%Mud Snake%Mudi%Mudpuppy%Mudskipper%Mule%Mule Deer%Mulga Snake%Mullet Fish%Muntjac%Muscovy Duck%Musk Deer%Muskellunge (Muskie)%Muskox%Muskrat%Mussurana Snake%Muttaburrasaurus%Muttaburrasaurus%Myna Bird%Nabarlek%Naegleria%Naked Mole Rat%Narwhal%Natterjack%Nautilus%Neanderthal%Neapolitan Mastiff%Nebelung%Needlefish%Nelore Cattle%Nematode%Neon Tetra%Neptune Grouper%Netherland Dwarf Rabbit%New Hampshire Red Chicken%Newfoundland%Newfypoo%Newt%Nguni Cattle%Nicobar pigeon%Nigerian Goat%Night Adder%Night Heron%Night Snake%Nightingale%Nightjar%Nile Crocodile%Nile Monitor%Nile Perch%Nilgai%No See Ums%Norfolk Terrier%Norrbottenspets%North American Black Bear%Northern Alligator Lizard%Northern Bobwhite%Northern Cardinal%Northern Flicker%Northern Fur Seal%Northern Harrier%Northern Inuit Dog%Northern Jacana%Northern Parula%Northern Pintail%Northern Potoo%Northern Screamer%Northern Water Snake%Norway Rat%Norwegian Buhund%Norwegian Elkhound%Norwegian Forest%Norwegian Lundehund%Norwich Terrier%Nose-Horned Viper%Nova Scotia Duck Tolling Retriever%Nubian Goat%Nudibranch%Numbat%Nuralagus%Nurse Shark%Nut Weevil%Nuthatch%Nutria%Nyala%Oak Toad%Oarfish%Ocean Perch%Ocean Pout%Ocean Whitefish%Oceanic Whitetip Shark%Ocellated Turkey%Ocelot%Octopus%Oenpelli python%Oilfish%Okapi%Old English Sheepdog%Old House Borer%Oleander Hawk Moth%Olingo%Olive Baboon%Olive python%Olive Sea Snake%Olm%Olympic Marmot%Onagadori Chicken%Onager%Opabinia%Opah%Opaleye (Rudderfish)%Opossum%Oranda Goldfish%Orange Baboon Tarantula%Orange Dream Ball Python%Orange Roughy %Orange Spider%Orange Tanager (Orange-Headed Tanager)%Orange-Crowned Warbler%Orangutan%Orb Weaver%Orchard Oriole%Orchid Dottyback%Oregon Spotted Frog%Ori-Pei%Oribi%Oriental Cockroach%Oriental Dwarf Kingfisher%Orinoco Crocodile%Ornate Bichir%Ornate Black-Tailed Rattlesnake%Ornate Box Turtle%Ornithocheirus%Ornithomimus%Ortolan Bunting%Oscar Fish%Osprey%Ostracod%Ostrich%Otter%Otterhound%Ovenbird%Oviraptor%Owl%Owl Butterfly%Owlfly (Ascalaphidae)%Ox%Oxpecker%Oyster%Oyster Toadfish%Ozark Bass%Pachycephalosaurus%Pacific Coast Tick%Pacific Sleeper Shark%Pacific Spaghetti Eel%Paddlefish%Pademelon%Painted Bunting%Painted Turtle%Palaeophis%Paleoparadoxia%Palm Rat%Palo Verde Beetle%Panda Pied Ball Python%Pangolin%Panther%Panthera atrox (American Lion)%Papillon%Papillon Mix%Paradise Flying Snake%Parakeet%Parasaurolophus%Parrot%Parrot Snake%Parrotfish%Parrotlet%Parson Russell Terrier%Parti Schnauzer%Partridge%Patagonian Cavy%Patagonian Mara%Patagotitan%Patas Monkey%Patterdale Terrier%Pea Puffer%Peacock%Peacock Bass%Peacock Butterfly%Peacock Spider%Peagle%Peekapoo%Pekingese%Pelagornis%Pelagornithidae%Pelican%Pelycosaurs%Pembroke Welsh Corgi%Penguin%Pennsylvania Wood Cockroach%Peppered Moth%Peppermint Angelfish%Perch Fish%Père David’s Deer%Peregrine Falcon%Peringuey’s Adder%Perro De Presa Canario%Persian%Peruvian Guinea Pig%Peruvian Inca Orchid%Pesquet’s Parrot (Dracula Parrot)%Petit Basset Griffon Vendéen%Petite Goldendoodle%Pharaoh Hound%Pheasant%Pheasant-tailed Jacana%Philippine Cobra%Phoenix Chicken%Phorusrhacos%Phytosaurs%Picardy Spaniel%Pictus Catfish%Piebald Dachshund%Pied Ball Python%Pied Tamarin%Pied-Billed Grebe%Pig%Pig-Nosed Turtle%Pigeon%Pika%Pike Fish%Pileated Woodpecker%Pinacate Beetle%Pine Beetle%Pine Marten%Pine Siskin%Pine Snake%Pine Snake%Pinfish%Pink Bollworm%Pink Fairy Armadillo%Pink Salmon%Pink Toed Tarantula%Pink-Necked Green Pigeon%Pipe Snake%Pipefish%Piranha%Pit Bull%Pit Viper%Pitador%Pitsky%Plains Hognose Snake%Platinum Arowana%Platybelodon%Platypus%Plesiosaur%Pliosaur%Plott Hound Mix%Plott Hounds%Plymouth Rock Chicken%Pocket Beagle%Pocket Pitbull%Podenco Canario%Pointer%Pointer Mix%Poison Dart Frog%Polacanthus%Polar Bear%Polecat%Polish Chicken%Polish Lowland Sheepdog%Polish Tatra Sheepdog%Polka Dot Stingray%Pollock Fish%Polyphemus Moth%Pomapoo%Pomchi%Pomeagle%Pomeranian%Pomeranian Mix%Pompano Fish%Pomsky%Pond Skater%Poochon%Poodle%Poogle%Pool Frog%Porbeagle Shark%Porcupine%Porcupinefish%Portuguese Podengo%Possum%Potato Beetle%Potoo%Potoroo%Powderpost Beetle%Prairie Chicken%Prairie Dog%Prairie Rattlesnake%Prawn%Praying Mantis%Proboscis Monkey%Procoptodon%Pronghorn%Psittacosaurus%Psittacosaurus%Pteranodon%Pterodactyl%Pudelpointer%Puertasaurus%Puff Adder%Pufferfish%Puffin%Pug%Pug Mix%Pugapoo%Puggle%Pugshire%Puli%Puma%Pumi%Pumpkin Patch Tarantula%Purple Emperor Butterfly%Purple Finch%Purple Gallinule%Purple Tarantula%Purussaurus%Puss Caterpillar%Puss Moth%Pygmy Hippopotamus%Pygmy Marmoset (Finger Monkey)%Pygmy python%Pygmy Rattlesnake%Pygmy Shark%Pygora Goat%Pyjama Shark%Pyrador%Pyredoodle%Pyrenean Mastiff%Pyrenean Shepherd%Pyrosome%Python%Quagga%Quahog Clam%Quail%Queen Snake%Quetzal%Quetzalcoatlus northropi%Quokka%Quoll%Rabbit%Raccoon%Raccoon Dog%Racer Snake%Radiated Tortoise%Ragamuffin%Ragdoll%Raggle%Rainbow Boa%Rainbow Grasshopper (Dactylotum bicolor)%Rainbow Kribs (Kribensis)%Rainbow Shark%Rat%Rat Snakes%Rat Terrier%Rattlesnake%Red Ackie Monitor%Red Aphids%Red Deer%Red Diamondback Rattlesnake%Red Drum Fish%Red Finch%Red Fox%Red Kite%Red Knee Tarantula%Red Nose Pit Bull%Red Panda%Red Paper Wasp%Red Racer Snake%Red Spitting Cobra%Red Squirrel%Red Star Chicken%Red Tail Boa (common boa)%Red Wolf%Red-Bellied Black Snake%Red-Bellied Woodpecker%Red-Billed Quelea Bird%Red-Eared Slider%Red-Eyed Tree Frog%Red-Footed Tortoise%Red-handed Tamarin%Red-Headed Vulture%Red-Lipped Batfish%Red-Shouldered Hawk%Red-Tailed Cuckoo Bumblebee%Red-winged blackbird%Redback Spider%Redbone Coonhound%Redcap Chicken%Redear Sunfish%Redhump Eartheater%Redstart%Redtail Catfish%Reef Shark%Regal Jumping Spider%Reindeer%Repenomamus%Reticulated python%Rex Rabbit%Rhamphosuchus%Rhea%Rhesus Macaque%Rhino Beetle%Rhino Viper%Rhinoceros%Rhode Island Red Chicken%Rhodesian Ridgeback%Rhombic Egg-Eater Snake%Ribbon Eel%Ribbon Snake%Rim Rock Crowned Snake%Ring-billed Gull%Ringed Kingfisher%Rinkhals Snake%River Otter%River Turtle%Roadrunner%Robber Flies%Robin%Rock Bass%Rock Crab%Rock Hyrax%Rock Python%Rockfish%Rockhopper Penguin%Rodents%Roe Deer%Roosevelt Elk%Rooster%Root Aphids%Rose-Breasted Grosbeak%Roseate Spoonbill%Rosy Boa%Rotterman%Rottle%Rottsky%Rottweiler%Rottweiler Mix%Rough Earth Snake%Rough Green Snake%Rough-Legged Hawk (Rough-Legged Buzzard)%Rove Beetle%Royal Penguin%Rubber Boa%Ruby-Crowned Kinglet%Ruby-Throated Hummingbird%Ruddy Duck%Ruddy Turnstone%Rufous Hummingbird%Russel’s Viper%Russell Terrier%Russian Bear Dog%Russian Blue%Russian Tortoise%Saanen Goat%Saarloos Wolfdog%Saber-Toothed Tiger%Sable%Sable Black German Shepherd%Sable Ferret%Sable German Shepherd%Saddleback Caterpillar%Saiga%Sailfish%Saint Berdoodle%Saint Bernard%Saint Shepherd%Salamander%Salmon%Salmon Shark%Saluki%Sambar%Samoyed%San Francisco Garter Snake%Sand Cat%Sand Crab%Sand Dollar%Sand Lizard%Sand Tiger Shark%Sand Viper%Sandhill Crane%Sandpiper%Sandworm%Saola%Sapsali%Sarcosuchus%Sardines%Sarkastodon%Sarplaninac%Sarus Crane%Satanic Leaf-Tailed Gecko%Saturniidae Moth%Sauropoda%Sauropoda%Savanna Goat%Savannah Monitor%Savannah Sparrow%Savu Python%Saw-scaled Viper%Sawfish%Scale-Crested Pygmy Tyrant%Scaleless Ball Python%Scallops%Scarab Beetle%Scarlet Kingsnake%Scarlet Macaw%Scarlet Tanager%Schapendoes%Schipperke%Schneagle%Schnoodle%Scimitar-horned Oryx%Scissor-tailed Flycatcher%Scorpion%Scorpion Fish%Scotch Collie%Scottish Deerhound%Scottish Fold Cat%Scottish Terrier%Scrotum Frog%Sculpin%Scutosaurus%Sea Anemone%Sea Bass%Sea Dragon%Sea Eagle%Sea Lion%Sea Otter%Sea Roach%Sea Slug%Sea Snake%Sea Spider%Sea Squirt%Sea Trout%Sea Turtle%Sea Urchin%Seagull%Seahorse%Seal%Sealyham Terrier%Sedge Warbler%Sehuencas Water Frog%Sei Whale%Senegal Parrot%Senepol Cattle%Sequined Spider%Serval%Seymouria%Shantungosaurus%Shark%Sharp-Shinned Hawk%Sharp-Tailed Snake%Shastasaurus%Sheep%Sheepadoodle%Sheepshead Fish%Shepadoodle%Shepkita%Shepweiler%Shetland Sheepdog%Shiba Inu%Shiba Inu Mix%Shichi%Shih Poo%Shih Tzu%Shih Tzu Mix%Shikoku%Shiloh Shepherd%Shiranian%Shoebill Stork%Shollie%Short-Eared Owl%Short-Faced Bear%Shortfin Mako Shark%Shrew%Shrimp%Siamese%Siberian%Siberian Husky%Siberian Ibex%Siberian Retriever%Siberian Tiger%Siberpoo%Sichuan Takin (Tibetan Takin)%Sidewinder%Sika Deer%Silken Windhound%Silkie Chicken%Silky Shark%Silky Terrier%Silver Dollar%Silver Labrador%Simbakubwa%Sinosauropteryx%Sivatherium%Sixgill shark%Skate Fish%Skeleton Tarantula%Skink Lizard%Skipjack Tuna%Skua%Skunk%Skye Terrier%Sleeper Shark%Sloth%Slovak Cuvac%Slow Worm%Slug%Smallmouth Bass%Smilosuchus%Smokybrown Cockroach%Smooth Earth Snake%Smooth Fox Terrier%Smooth Green Snake%Smooth Hammerhead Shark%Smooth Snake%Snail%Snailfish%Snake%Snapping Turtle%Snook Fish%Snorkie%Snouted Cobra%Snow Bunting%Snow Crab%Snow Goose%Snow Leopard%Snowberry Clearwing Moth%Snowflake Eel%Snowshoe%Snowshoe Hare%Snowy Owl%Sockeye Salmon%Soldier Beetle%Somali%Song Sparrow%Song Thrush%South China Tiger%Southeastern Blueberry Bee%Southern Black Racer%Southern Flannel Moth%Southern Hognose Snake%Southern House Spider%Southern Pacific Rattlesnake%Spadefoot Toad%Spalax%Spanador%Spanish Goat%Spanish Mackerel%Spanish Mastiff%Spanish Water Dog%Sparrow%Sparrowhawk%Speckled Kingsnake%Speckled Trout%Spectacled Bear%Sperm Whale%Sphynx%Spider%Spider Ball Python%Spider Beetle%Spider Monkey%Spider Wasp%Spider-Tailed Horned Viper%Spinner Shark%Spinone Italiano%Spinosaurus%Spiny bush viper%Spiny Dogfish%Spiny Hill Turtle%Spitting Cobra%Spixs Macaw%Sponge%Spongy Moth%Spongy Moth%Spotted Bass%Spotted Gar%Spotted Garden Eel%Spotted Lanternfly%Spotted python%Spotted Skunk%Springador%Springbok%Springerdoodle%Squash Bee%Squash Beetle%Squid%Squirrel%Squirrel Monkey%Squirrelfish%Sri Lankan Elephant%Stabyhoun%Staffordshire Bull Terrier%Stag Beetle%Standard Schnauzer%Star-nosed mole%Starfish%Stargazer Fish%Steelhead Salmon%Steller’s Sea Cow%Stick Insect%Stiletto Snake%Stingray%Stoat%Stone Crab%Stonechat%Stonefish%Stoplight Loosejaw%Stork%Strawberry Hermit Crab%Striped Bass%Striped Hyena%Striped Rocket Frog%Stromatolite%Stupendemys%Sturgeon%Styracosaurus%Suchomimus%Suckerfish%Sugar Glider%Sulcata Tortoise%Sultan Chicken%Sumatran Elephant%Sumatran Orangutan%Sumatran Rhinoceros%Sumatran Tiger%Summer Tanager%Sun Bear%Sunbeam Snake%Sunset Ball Python%Super Pastel Ball Python%Supersaurus%Superworm%Surgeonfish%Sussex Chicken%Swai Fish%Swainson’s Hawk%Swallow%Swallowtail Butterfly%Swallowtail Caterpillar%Swan%Swedish Elkhound%Swedish Lapphund%Swedish Vallhund%Swordfish%Syrian Hamster%Taco Terrier%Tailless Whip Scorpion%Taimen Fish%Taipan%Takin%Tamarin%Tamaskan%Tang%Tangerine Leopard Gecko%Tapanuli Orangutan%Tapir%Tarantula%Tarantula Hawk%Tarbosaurus%Tarpon%Tarsier%Tasmanian Devil%Tasmanian Tiger%Tasmanian Tiger Snake%Tawny Frogmouth%Tawny Mining Bee%Tawny Owl%Teacup Chihuahua%Teacup Maltese%Teacup Miniature Horse%Teacup Poodle%Teddy Bear Hamster%Teddy Guinea Pig%Teddy Roosevelt Terrier%Telescope Fish%Ten-Lined June Beetle%Tennessee Walking Horse%Tenrec%Tent Caterpillar%Tentacled Snake%Tenterfield Terrier%Termite%Terrier%Terror Bird%Tetra%Texas Blind Snake%Texas Brown Tarantula%Texas Coral Snake%Texas Garter Snake%Texas Heeler%Texas Indigo Snake%Texas Night Snake%Texas Rat Snake%Texas Spiny Lizard%Thai Ridgeback%Thalassomedon%Thanatosdrakon%Therizinosaurus%Theropod%Thornback Ray%Thorny Devil%Thresher Shark%Thrush%Thylacoleo%Thylacoleo carnifex%Thylacosmilus%Tibetan Fox%Tibetan Mastiff%Tibetan Spaniel%Tibetan Terrier%Tick%Tiffany%Tiger%Tiger Beetle%Tiger Moth%Tiger Muskellunge (Muskie)%Tiger Rattlesnake%Tiger Salamander%Tiger Shark%Tiger snake%Tiger Swallowtail%Tiger Swallowtail Caterpillar%Tiger Trout%Tiktaalik%Timber Rattlesnake (Canebrake Rattlesnake)%Timor python%Tire Track Eel%Titan Beetle%Titanoboa%Titanosaur%Toadfish%Tokay Gecko%Tomato Hornworm%Torkie%Tornjak%Tortoise%Tosa%Toucan%Towhee%Toxodon%Toy Fox Terrier%Toy Poodle%Transylvanian Hound%Trapdoor spider%Tree Cricket%Tree Frog%Tree Kangaroo%Tree Snake%Tree swallow%Tree Viper (Bamboo Viper)%Treecreeper%Treehopper%Treeing Tennessee Brindle%Treeing Walker Coonhound%Triggerfish%Troodon%Tropicbird%Trout%Tsetse Fly%Tuatara%Tufted Coquette%Tufted Titmouse%Tully Monster%Tuna%Tundra Swan%Turaco%Turkey%Turkey Vulture%Turkish Angora%Turnspit%Turtle Frog%Turtles%Tusoteuthis%Tussock Moth Caterpillar%Twig Snake%Tylosaurus%Tyrannosaurus Rex%Uakari%Uaru Cichlid%Uguisu%Uinta Ground Squirrel%Uintatherium%Ulysses Butterfly%Umbrellabird%Unau (Linnaeus’s Two-Toed Sloth)%Underwing Moth%Upland Sandpiper%Ural owl%Urechis unicinctus (Penis Fish)%Urial%Uromastyx (Spiny-Tailed Lizard)%Urutu Snake%Utonagan%Valley Bulldog%Vampire Bat%Vampire Crab %Vampire Squid%Vaquita%Veery%Vegavis%Velociraptor%Venus Flytrap%Vermilion Flycatcher%Vervet Monkey%Vestal Cuckoo Bumblebee%Vicuña%Vine Snake%Vinegaroon%Viper%Viper Boa%Viper Shark (dogfish)%Viperfish%Virgin Islands Dwarf Gecko%Vizsla%Volcano Snail%Vole%Volpino Italiano%Vulture%Wahoo Fish%Waimanu%Walking Catfish%Wallaby%Walleye Fish%Walrus%Wandering Albatross%Warbler%Warthog%Wasp%Water Beetle%Water Buffalo%Water Bug%Water Dragon%Water Vole%Waterbuck%Wattled Jacana%Wax Moth%Weasel%Weaver Bird%Weimaraner%Weimardoodle%Wels Catfish%Welsh Black Cattle%Welsh Corgi%Welsh Springer Spaniel%Welsh Terrier%West Highland Terrier%West Siberian Laika%Western Blacklegged Tick%Western Blind Snake%Western Diamondback Rattlesnake%Western Gorilla%Western Green Mamba%Western Hognose Snake%Western Kingbird%Western Lowland Gorilla%Western Rat Snake%Western Rattlesnake (Northern Pacific Rattlesnake)%Western Tanager%Westiepoo%Whale Shark%Wheaten Terrier%Whimbrel%Whinchat%Whippet%Whiptail Lizard%White Butterfly%White Catfish%White Crappie%White Ferret / Albino Ferrets%White German Shepherd%White Marlin%White Rhinoceros%White Shark%White Sturgeon %White Tiger%White-Crowned Sparrow%White-Eyed Vireo%White-Faced Capuchin%White-tail deer%White-Tailed Eagle%Whitetail Deer%Whiting%Whoodle%Whooping Crane%Wild Boar%Wildebeest%Willow Flycatcher%Willow Warbler%Winter Moth%Wire Fox Terrier%Wirehaired Pointing Griffon%Wirehaired Vizsla%Wiwaxia%Wolf%Wolf Eel%Wolf Snake%Wolf Spider%Wolffish%Wolverine%Woma Python%Wombat%Wood Bison%Wood Duck%Wood Frog%Wood Tick%Wood Turtle%Woodlouse%Woodlouse Spider%Woodpecker%Woodrat%Wool Carder Bee%Woolly Aphids%Woolly Bear Caterpillar%Woolly Mammoth%Woolly Monkey%Woolly Rhinoceros%Worm%Worm Snake%Wrasse%Writing Spider%Wrought Iron Butterflyfish%Wryneck%Wyandotte Chicken%Wyoming Toad%X-Ray Tetra%Xeme (Sabine’s Gull)%Xenacanthus%Xenoceratops%Xenoposeidon%Xenotarsosaurus%Xerus%Xiaosaurus%Xiaotingia%Xingu River Ray%Xiphactinus%Xoloitzcuintli%Yabby%Yak%Yakutian Laika%Yarara%Yellow Aphids%Yellow Bass%Yellow Bellied Sapsucker%Yellow Belly Ball Python%Yellow Cobra%Yellow Crazy Ant%Yellow Perch%Yellow Sac Spider%Yellow Spotted Lizard%Yellow Tanager (Black-and-Yellow Tanager)%Yellow Tang%Yellow-Bellied Sea Snake%Yellow-Eyed Penguin%Yellow-faced Bee%Yellowhammer%Yellowish Cuckoo Bumblebee (formerly Fernald’s Cuckoo Bumblebee)%Yellowjacket (Yellow Jacket)%Yellowtail Snapper%Yellowthroat%Yeti Crab%Yokohama Chicken%Yoranian%Yorkie Bichon%Yorkiepoo%Yorkshire Terrier%Zebra%Zebra Finch%Zebra Mussels%Zebra Pleco%Zebra Shark%Zebra Snake%Zebra Spitting Cobra%Zebra Tarantula%Zebrafish (Zebra Fish)%Zebu%Zokor%Zonkey%Zorse%Zuchon",
            '25% Human | 75% Animals':"",
            '50% Human | 50% Animals':"",
            '75% Human | 25% Animals':"",
            'Mythological':"Bahamut% Bake-kujira% Cetus% Devil Whale% Encantado% Glashtyn% Gveleshapi% Makara% Mug-wamp% Sea goat% Selkie% Water bull% Water Horse% Ceffyl Dŵr% Each-uisge% Enbarr% Hippocampus% Ichthyocentaurs% Kelpie% Morvarc'h% Nixie% Nuckelavee% Nuggle% Tangie% Anansi% Arachne% Carbuncle% Gold-digging ant% Iktomi% Jorōgumo% Karkinos% Khepri% Mothman% Myrmecoleon% Myrmidons% Pabilsag% Scorpion man% Selket% Tsuchigumo% Balayang% Camazotz% Leutogi% Minyades% Tjinimin% Vetala% Ababil% Adarna% Avalerion% Alicanto% Anqa% Anzû% Bare-fronted Hoodwink% Alkonost% Gumyōchō% Harpy% Aello% Ocypete% Celaeno% Podarge% Horus% Inmyeonjo% Kalavinka% Karura% Kinnara% Siren% Achelois% Aglaonoe% Agalaope% Leucosia% Ligeia% Parthenope% Pisinoe% Thelxinoë% Swan maiden% Caladrius% Chalkydri% Chamrosh% Cinnamon bird% Devil Bird% Gagana% Gandabherunda% Gamayun% Garuda% Hakawai% Hudhud% Huginn% Muninn% Itsumade% Jingwei% Lamassu% Luan% Minokawa% Nachtkrapp% Nine-headed Bird% Oozlum bird% Pamola% Paskunji% Peng% Phoenix% Bennu% Chol% Firebird% Fenghuang% Huma bird% Konrul% Toghrul% Vermilion Bird% Piasa% Qingniao% Ra% Rain Bird% Raróg% Roc% Shangyang% Shedu% Simurgh% Stymphalian birds% Tengu% Three-legged bird% Thunderbird% Thoth% Turul% Veðrfölnir% Vucub Caquix% Yatagarasu% Zhenniao% Alectryon% Basan% Cockatrice% Gallic rooster% Gullinkambi% Rooster of Barcelos% Sarimanok% Víðópnir% Aethon% Griffin% Hippogriff% Hræsvelgr% Poukai% Shahbaz% Triple-headed eagle% Wuchowsen% Ziz% Zu% Nyctimene% Owlman% Sirin% Strix% Bjarndyrakongur% Bugbear% Callisto% Stiff-Legged Bear% Adlet% Amarok% Anubis% Aralez% Asena% Axehandle hound% Black dog% Barghest% Black Shuck% Grim% Beast of Gévaudan% Cerberus% Chupacabra% Cu Sith% Crocotta% Cynocephaly% Dogs of Actaeon% Fenrir% Gelert% Hellhound% Huli jing% Kitsune% Kumiho% Huodou% Kludde% Orthrus% Penghou% Psoglav% Salawa% Sigbin% Sky Fox% Shug Monkey% Tanuki% Tulikettu% Vǎrkolak% Werewolf% Bael% Ball-tailed cat% Cactus cat% Cat-sìth% Cath Palug% Demon Cat% Kaibyō% Bakeneko% Kasha% Nekomata% Nue% Pard% Phantom cat% Blue Mountains panther% Glawackus% Tyger% Underwater panther% Vapula% Wampus cat% White Tiger% Winged cat% Arimanius% Ammit% Barong% Beast of the First Kingdom% Brunswick Lion% Chimera% Chinese guardian lions% Komainu% Shisa% Sin-you% Xiezhi% Dawon% Aker% Ȧmi-Pe% Apedemak% Bast% Hert-ketit-s% Ḥuntheth% Ipy% Maahes% Matit% Mehit% Menhit% Pakhet% Repyt% Sekhmet% Seret% Shesmetet% Taweret% Tefnut% Tutu% Urit-en-kru% Lampago% Leo% Lion of Cithaeron% Nemean lion% Lion of Al-lāt% Manticore% Manussiha% Merlion% Narasimha% Nian% Nongshāba% Pixiu% Questing Beast% Sea-lion% Serpopard% Sharabha% Simhamukha% Snow Lion% Sphinx% Criosphinx% Gopaitioshah% Hieracosphinx% Stratford Lyon% Tigris% Vaikuntha Chaturmurti% Winged lion% Yali% Yaghūth% Yaldabaoth% Werehyena% Kishi% Azeban% Gef% Ichneumon% Kamaitachi% Kushtaka% Mujina% Ramidreju% Raijū% Mermaid% Merman% Abaia% Gurangatch% Hippocamp% Ika-Roa% Il Belliegha% Isonade% Namazu% Ningyo% Kun% Salmon of Wisdom% Shachihoko% Lavellan% Drop bear% Bunyip% Akkorokamui% Lou Carcolh% Kraken% Shen% Agropelter% Bigfoot% Sasquatch% Hibagon% Jué yuán% Satori% Shōjō% Shug Monkey% Sun Wukong% Vanara% Yeren% Yeti% Yowie% Al-Mi'raj% Jackalope% Moon rabbit% Skvader% Wisakedjak% Wolpertinger% Agoa% Ammut% Bakunawa% Basilisk% Black Tortoise% Chalkydri% Chinese Dragon% Cipactli% Dragon% Dungavenhooter% Knucker% Kurma% Loch Ness Monster% Loveland frog% Mokele Mbembe% Moʻo% Morgawr% Mungoon-Gali% Peluda% Reptilian humanoids% Sewer alligator% Sobek% Taniwha% Whowie% Wyvern% Zaratan% Alicante% Amphisbaena% Amphithere% Apep% Apophis% Azhi Dahaka% Bakonawa% Biscione% Cockatrice% Drake% Echidna% Fáfnir% Feathered serpent% Garafena% Gorgon% Hoop snake% Hydra% Jaculus% Jasconius% Jörmungandr% Lamia% Lindworm% Madame White Snake% Meretseger% Mongolian Death Worm% Naga% Níðhöggr% Orm% Ouroboros% Python% Rainbow serpent% Sea serpent% Tarasque% Typhon% Ur% Yamata no Orochi% Zilant% Afanc% Ratatoskr% Rat king% Actaeon% Ceryneian Hind% Deer Woman% Eikþyrnir% Goldhorn% Jackalope% Keresh% Peryton% Qilin% Tarand% White stag% Xeglun% Auðumbla% Bai Ze% Kujata% Bicorn% Chichevache% Bonnacon% Hodag% Minotaur% Nandi% Sarangay% Shedu% Ushi-oni% Allocamelus% Heavenly Llama% Amalthea% Aries% Barometz% Capricornus% Chimera% Dahu% Faun% Goldhorn% Heiðrún% Khnum% Satyr% Sidehill gouger% Tanngrisnir% Tanngnjóstr% Chrysomallos% Anggitay% Arion% Balius% Xanthus% Buraq% Centaur% Cheval Gauvin% Cheval Mallet% Chiron% Chollima% Drapé% Gytrash% Haizum% Hippogriff% Ipotane% Karkadann% Kotobuki% Longma% Onocentaur% Pegasus% Pooka% Sleipnir% Simurgh% Sihuanaba% Tikbalang% Uchchaihshravas% Unicorn% Winged unicorn% Abath% Baku% Behemoth% Quugaarpak% Taweret% Calydonian Boar% Erymanthian Boar% Zhu Bajie% Mapinguari% Giants% Automaton% Blodeuwedd% Brazen head% Doll Woman% Frankenstein's monster% Galatea% Gingerbread man% Golem% Homunculus% Nephele% Shabti% Tokeloshe% Tilberi% Tsukumogami% Tulpa% Tupilaq% Ushabti% Alan% Dhampir% Preta% Golden Hind% Kappa% Kekkai% Lamia% Manananggal% Mandurugo% Redcap% Rokurokubi% Sigbin% Vampire% Werewolf% Yuki-onna% Bloody Bones% Gashadokuro% Grim Reaper% Skeleton% Argus Panoptes% Catoblepas% Cyclopes% Hitotsume-kozou% Lynx% Mokumokuren% Asura% Deva% Devi% Noppera-bō% Futakuchi-onna% Harionago% Medusa% Amphisbaena% Chimera% Chonchon% Double-headed eagle% Dullahan% Hekatonkheires% Hydra% Lernaean Hydra% Nine-headed Bird% Nukekubi% Orthrus% Shesha% Penanggalan% Wanyūdō% Xing Tian% Yacuruna% Yamata no Orochi% Asura% Deva% Devi% Hekatonkheires% Hinkypunk% Kui% O'nya:ten% Sleipnir% Three-legged bird% Futakuchi-onna% Kuchisake-onna% Selkie% Skin-walker% Swan maiden% Bakeneko% Kitsune% Kumiho% Hulder% Nguruvilu% Serpopard% Rokurokubi% Vampire% Manananggal% Geryon% Pixiu% Androktasiai% Erinyes% Hipag% Hysminai% Keres% Lemures% Makhai% Onryō% Phonoi% Valkyrie% Vengeful ghost% Phoenix% Ubume% Ammit% Banshee% Demon% Devil% Dullahan% Ghost% Grim Reaper% Ox-Head% Horse-Face% Phoenix% Undead% Valkyrie% Vampire% Alp% Baku% Carbuncle% Devil% Drude% Incubus% Succubus% Mermaid% Nightmare% Nue% Oni% Sandman% Satori% Zduhać% Balor% Catoblepas% Gorgon% Medusa% Euryale% Stheno% Abatwa% Alan% Boto% Faun% Gancanagh% Incubus% Succubus% Maenad% Nymph% Pombero% Popobawa% Satyr% Sileni% Silenus% Unicorn% Zemyna% Zemepatis% Simurgh% Dwarf% Egbere% Genie% Leib-Olmai% Leprechaun% Matagot% Pixiu% Sarimanok% Sigbin% Yaksha% Yakshini% Angel% Chalkydri% Deity% Lampetia% Will-o'-the-wisp% Dragon% Cupid% Eros% Cherub% Gancanagh% Madame White Snake% Melusine% Tennin% Undine% Banshee% Encantado% Fenghuang% Fossegrim% Mermaid% Nue% Siren% Gef% Satan% Chronos% Father Time% Gremlin% Baba Yaga% Bai Ze% Griffin% Salmon of Wisdom% Sphinx% Valravn% Ala% Feldgeister% Zduhać% Black dog% Bogeyman% Ghost% Grim Reaper% Wechuge% Wendigo% Shadow People% Vampire% Werewolf% Oni% Gashadokuro% Camazotz% Wild Hunt% Hell Hound% Asag% Bluecap% Elemental% Dwarf% Earth Dragon% Gargoyle% Giant% Gnome% Goblin% Golem% Knocker% Monopod% Nymph% Ogre% Oread% Ten Ten-Vilu% Troll% Basan% Bluecap% Cherufe% Chimera% Dragon% Ifrit% Hellhound% Lampad% Phoenix% Salamander% Chalkydri% Light Elf% Rainbow crow% Rainbow Serpent% Alicanto% Pixiu% Carbunclo% Chrysomallos% Cyclopes% Griffin% Gnome% Leprechaun% Bulgasari% Chinese dragon% Cyclopes% Feldgeister% Kitsune% Raijū% Thunderbird% Valkyrie% Afanc% Amefurikozō% Aspidochelone% Bloody Bones% Buggane% Bunyip% Camenae% Capricorn% Cetus% Charybdis% Cai Cai-Vilu% Crinaeae% Davy Jones' Locker% Draug% Each uisge% Fish People% Fossegrim% Fur-bearing trout% Gargouille% Grindylow% Haetae% Hippocamp% Hydra% Ichthyocentaur% Jasconius% Jengu% Kappa% Kelpie% Kraken% Lake monster% Lavellan% Leviathan% Loch Ness monster% Lorelei% Lusca% Makara% Melusine% Mami Wata% Mermaid% Merman% Merrow% Morgens% Muc-sheilch% Naiad% Näkki% Nereid% Nix% Nymph% Pisces% Ponaturi% Potamus% Rusalka% Samebito% Sea monster% Sea serpent% Selkie% Shen% Siren% Taniwha% Tiamat% Triton% Ondine% Vodyanoy% Water dragon% Water leaper% Water sprite% Yacuruna% Zaratan% Dwarf% European dragon% Gnome% Goblin% Golem% Grootslang% Leprechaun% Troll% Yaoguai% Angel% Asteriae% Chalkydri% Feathered serpent% Heavenly Llama% Pegasus% Grim Reaper% Swan Maiden% Tennin% Three-legged bird% Valkyrie% Amphisbaena% Basilisk% Cockatrice% Ghoul% Mongolian Death Worm% Sphinx% Ajatar% Bigfoot% Dryad% Elf% Green Man% Irrwurz% Leshy% Lindworm% Mavka% Moss people% Owlman% Satyr% Unicorn% Curupira% Dingonek% Mapinguari% Manticore% Saci% Fairy% Gnome% Ennedi tiger% Werehyena% Bak% Chinese dragon% Dobhar-chú% Encantado% Grootslang% Iara% Jiaolong% Kappa% Kelpie% Lake monster% Hydra% Loch Ness Monster% Mugwump% Naiad% Nixie% Ogopogo% Ondine% Rainbow serpent% Rusalka% Ryujin% Shellycoat% Warlock% Yacuruna% Alp% Dwarf% Fenghuang% Griffin% Hippogriff% Mountain Giant% Kamaitachi% Mavka% Oread% Patupaiarehe% Rübezahl% Satyr% Tengu% Yeti% Aspidochelone% Bishop-fish% Charybdis% Cai Cai-Vilu% Dragon King% Fish People% Hippocamp% Leviathan% Jormungand% Kraken% Mermaid% Merman% Nereid% Sea monk% Sea monster% Sea serpent% Selkie% Shen% Siren% Tritons% Umibōzu% Water Dragon% Yacuruna% Błudnik% Bunyip% Grootslang% Lernaean Hydra% Honey Island Swamp monster% Mokele-mbembe% Swamp monster% Will-o'-the-wisp% Cherufe% Phoenix% Salamander% Akhlut% Amarok% Hrimthurs% Ijiraq% Jotun% Qiqirn% Saumen Kar% Tizheruk% Wechuge% Wendigo% Yeti% Ymir% Yuki-onna% Banshee% Boggart% Brownie% Domovoi% Dvorovoi% Duende% Jinn% Kobold% Tomte% Vampire% Zashiki-warashi% Cerberus% Ammit% Cyclopes% Demon% Devil% Earth Dragon% Garm% Hekatonkheires% Hellhound% Ifrit% Ox-Head% Horse-Face% Preta%",
            '25% Human | 75% Mythos':"",
            '50% Human | 50% Mythos':"",
            '75% Human | 25% Mythos':"",
            'Mythos + Animals':"",
            '25% Human | 75% Mythos + Animals':"",
            '50% Human | 50% Mythos + Animals':"",
            '75% Human | 25% Mythos + Animals':"",
            'Pokemon':"Bulbasaur%Ivysaur%Venusaur%Charmander%Charmeleon%Charizard%Squirtle%Wartortle%Blastoise%Caterpie%Metapod%Butterfree%Weedle%Kakuna%Beedrill%Pidgey%Pidgeotto%Pidgeot%Rattata%Raticate%Spearow%Fearow%Ekans%Arbok%Pikachu%Raichu%Sandshrew%Sandslash%Nidoran♀%Nidorina%Nidoqueen%Nidoran♂%Nidorino%Nidoking%Clefairy%Clefable%Vulpix%Ninetales%Jigglypuff%Wigglytuff%Zubat%Golbat%Oddish%Gloom%Vileplume%Paras%Parasect%Venonat%Venomoth%Diglett%Dugtrio%Meowth%Persian%Psyduck%Golduck%Mankey%Primeape%Growlithe%Arcanine%Poliwag%Poliwhirl%Poliwrath%Abra%Kadabra%Alakazam%Machop%Machoke%Machamp%Bellsprout%Weepinbell%Victreebel%Tentacool%Tentacruel%Geodude%Graveler%Golem%Ponyta%Rapidash%Slowpoke%Slowbro%Magnemite%Magneton%Farfetch'd%Doduo%Dodrio%Seel%Dewgong%Grimer%Muk%Shellder%Cloyster%Gastly%Haunter%Gengar%Onix%Drowzee%Hypno%Krabby%Kingler%Voltorb%Electrode%Exeggcute%Exeggutor%Cubone%Marowak%Hitmonlee%Hitmonchan%Lickitung%Koffing%Weezing%Rhyhorn%Rhydon%Chansey%Tangela%Kangaskhan%Horsea%Seadra%Goldeen%Seaking%Staryu%Starmie%Mr. Mime%Scyther%Jynx%Electabuzz%Magmar%Pinsir%Tauros%Magikarp%Gyarados%Lapras%Ditto%Eevee%Vaporeon%Jolteon%Flareon%Porygon%Omanyte%Omastar%Kabuto%Kabutops%Aerodactyl%Snorlax%Articuno%Zapdos%Moltres%Dratini%Dragonair%Dragonite%Mewtwo%Mew%Chikorita%Bayleef%Meganium%Cyndaquil%Quilava%Typhlosion%Totodile%Croconaw%Feraligatr%Sentret%Furret%Hoothoot%Noctowl%Ledyba%Ledian%Spinarak%Ariados%Crobat%Chinchou%Lanturn%Pichu%Cleffa%Igglybuff%Togepi%Togetic%Natu%Xatu%Mareep%Flaaffy%Ampharos%Bellossom%Marill%Azumarill%Sudowoodo%Politoed%Hoppip%Skiploom%Jumpluff%Aipom%Sunkern%Sunflora%Yanma%Wooper%Quagsire%Espeon%Umbreon%Murkrow%Slowking%Misdreavus%Unown%Wobbuffet%Girafarig%Pineco%Forretress%Dunsparce%Gligar%Steelix%Snubbull%Granbull%Qwilfish%Scizor%Shuckle%Heracross%Sneasel%Teddiursa%Ursaring%Slugma%Magcargo%Swinub%Piloswine%Corsola%Remoraid%Octillery%Delibird%Mantine%Skarmory%Houndour%Houndoom%Kingdra%Phanpy%Donphan%Porygon2%Stantler%Smeargle%Tyrogue%Hitmontop%Smoochum%Elekid%Magby%Miltank%Blissey%Raikou%Entei%Suicune%Larvitar%Pupitar%Tyranitar%Lugia%Ho-oh%Celebi%Treecko%Grovyle%Sceptile%Torchic%Combusken%Blaziken%Mudkip%Marshtomp%Swampert%Poochyena%Mightyena%Zigzagoon%Linoone%Wurmple%Silcoon%Beautifly%Cascoon%Dustox%Lotad%Lombre%Ludicolo%Seedot%Nuzleaf%Shiftry%Taillow%Swellow%Wingull%Pelipper%Ralts%Kirlia%Gardevoir%Surskit%Masquerain%Shroomish%Breloom%Slakoth%Vigoroth%Slaking%Nincada%Ninjask%Shedinja%Whismur%Loudred%Exploud%Makuhita%Hariyama%Azurill%Nosepass%Skitty%Delcatty%Sableye%Mawile%Aron%Lairon%Aggron%Meditite%Medicham%Electrike%Manectric%Plusle%Minun%Volbeat%Illumise%Roselia%Gulpin%Swalot%Carvanha%Sharpedo%Wailmer%Wailord%Numel%Camerupt%Torkoal%Spoink%Grumpig%Spinda%Trapinch%Vibrava%Flygon%Cacnea%Cacturne%Swablu%Altaria%Zangoose%Seviper%Lunatone%Solrock%Barboach%Whiscash%Corphish%Crawdaunt%Baltoy%Claydol%Lileep%Cradily%Anorith%Armaldo%Feebas%Milotic%Castform%Kecleon%Shuppet%Banette%Duskull%Dusclops%Tropius%Chimecho%Absol%Wynaut%Snorunt%Glalie%Spheal%Sealeo%Walrein%Clamperl%Huntail%Gorebyss%Relicanth%Luvdisc%Bagon%Shelgon%Salamence%Beldum%Metang%Metagross%Regirock%Regice%Registeel%Latias%Latios%Kyogre%Groudon%Rayquaza%Jirachi%Deoxys%Turtwig%Grotle%Torterra%Chimchar%Monferno%Infernape%Piplup%Prinplup%Empoleon%Starly%Staravia%Staraptor%Bidoof%Bibarel%Kricketot%Kricketune%Shinx%Luxio%Luxray%Budew%Roserade%Cranidos%Rampardos%Shieldon%Bastiodon%Burmy%Wormadam%Mothim%Combee%Vespiquen%Pachirisu%Buizel%Floatzel%Cherubi%Cherrim%Shellos%Gastrodon%Ambipom%Drifloon%Drifblim%Buneary%Lopunny%Mismagius%Honchkrow%Glameow%Purugly%Chingling%Stunky%Skuntank%Bronzor%Bronzong%Bonsly%Mime Jr.%Happiny%Chatot%Spiritomb%Gible%Gabite%Garchomp%Munchlax%Riolu%Lucario%Hippopotas%Hippowdon%Skorupi%Drapion%Croagunk%Toxicroak%Carnivine%Finneon%Lumineon%Mantyke%Snover%Abomasnow%Weavile%Magnezone%Lickilicky%Rhyperior%Tangrowth%Electivire%Magmortar%Togekiss%Yanmega%Leafeon%Glaceon%Gliscor%Mamoswine%Porygon-Z%Gallade%Probopass%Dusknoir%Froslass%Rotom%Uxie%Mesprit%Azelf%Dialga%Palkia%Heatran%Regigigas%Giratina%Cresselia%Phione%Manaphy%Darkrai%Shaymin%Arceus%Victini%Snivy%Servine%Serperior%Tepig%Pignite%Emboar%Oshawott%Dewott%Samurott%Patrat%Watchog%Lillipup%Herdier%Stoutland%Purrloin%Liepard%Pansage%Simisage%Pansear%Simisear%Panpour%Simipour%Munna%Musharna%Pidove%Tranquill%Unfezant%Blitzle%Zebstrika%Roggenrola%Boldore%Gigalith%Woobat%Swoobat%Drilbur%Excadrill%Audino%Timburr%Gurdurr%Conkeldurr%Tympole%Palpitoad%Seismitoad%Throh%Sawk%Sewaddle%Swadloon%Leavanny%Venipede%Whirlipede%Scolipede%Cottonee%Whimsicott%Petilil%Lilligant%Basculin%Sandile%Krokorok%Krookodile%Darumaka%Darmanitan%Maractus%Dwebble%Crustle%Scraggy%Scrafty%Sigilyph%Yamask%Cofagrigus%Tirtouga%Carracosta%Archen%Archeops%Trubbish%Garbodor%Zorua%Zoroark%Minccino%Cinccino%Gothita%Gothorita%Gothitelle%Solosis%Duosion%Reuniclus%Ducklett%Swanna%Vanillite%Vanillish%Vanilluxe%Deerling%Sawsbuck%Emolga%Karrablast%Escavalier%Foongus%Amoonguss%Frillish%Jellicent%Alomomola%Joltik%Galvantula%Ferroseed%Ferrothorn%Klink%Klang%Klinklang%Tynamo%Eelektrik%Eelektross%Elgyem%Beheeyem%Litwick%Lampent%Chandelure%Axew%Fraxure%Haxorus%Cubchoo%Beartic%Cryogonal%Shelmet%Accelgor%Stunfisk%Mienfoo%Mienshao%Druddigon%Golett%Golurk%Pawniard%Bisharp%Bouffalant%Rufflet%Braviary%Vullaby%Mandibuzz%Heatmor%Durant%Deino%Zweilous%Hydreigon%Larvesta%Volcarona%Cobalion%Terrakion%Virizion%Tornadus%Thundurus%Reshiram%Zekrom%Landorus%Kyurem%Keldeo%Meloetta%Genesect%Chespin%Quilladin%Chesnaught%Fennekin%Braixen%Delphox%Froakie%Frogadier%Greninja%Bunnelby%Diggersby%Fletchling%Fletchinder%Talonflame%Scatterbug%Spewpa%Vivillon%Litleo%Pyroar%Flabébé%Floette%Florges%Skiddo%Gogoat%Pancham%Pangoro%Furfrou%Espurr%Meowstic%Honedge%Doublade%Aegislash%Spritzee%Aromatisse%Swirlix%Slurpuff%Inkay%Malamar%Binacle%Barbaracle%Skrelp%Dragalge%Clauncher%Clawitzer%Helioptile%Heliolisk%Tyrunt%Tyrantrum%Amaura%Aurorus%Sylveon%Hawlucha%Dedenne%Carbink%Goomy%Sliggoo%Goodra%Klefki%Phantump%Trevenant%Pumpkaboo%Gourgeist%Bergmite%Avalugg%Noibat%Noivern%Xerneas%Yveltal%Zygarde%Diancie%Hoopa%Volcanion%Rowlet%Dartrix%Decidueye%Litten%Torracat%Incineroar%Popplio%Brionne%Primarina%Pikipek%Trumbeak%Toucannon%Yungoos%Gumshoos%Grubbin%Charjabug%Vikavolt%Crabrawler%Crabominable%Oricorio%Cutiefly%Ribombee%Rockruff%Lycanroc%Wishiwashi%Mareanie%Toxapex%Mudbray%Mudsdale%Dewpider%Araquanid%Fomantis%Lurantis%Morelull%Shiinotic%Salandit%Salazzle%Stufful%Bewear%Bounsweet%Steenee%Tsareena%Comfey%Oranguru%Passimian%Wimpod%Golisopod%Sandygast%Palossand%Pyukumuku%Type: Null%Silvally%Minior%Komala%Turtonator%Togedemaru%Mimikyu%Bruxish%Drampa%Dhelmise%Jangmo-o%Hakamo-o%Kommo-o%Tapu Koko%Tapu Lele%Tapu Bulu%Tapu Fini%Cosmog%Cosmoem%Solgaleo%Lunala%Nihilego%Buzzwole%Pheromosa%Xurkitree%Celesteela%Kartana%Guzzlord%Necrozma%Magearna%Marshadow%Poipole%Naganadel%Stakataka%Blacephalon%Zeraora%Meltan%Melmetal%Grookey%Thwackey%Rillaboom%Scorbunny%Raboot%Cinderace%Sobble%Drizzile%Inteleon%Skwovet%Greedent%Rookidee%Corvisquire%Corviknight%Blipbug%Dottler%Orbeetle%Nickit%Thievul%Gossifleur%Eldegoss%Wooloo%Dubwool%Chewtle%Drednaw%Yamper%Boltund%Rolycoly%Carkol%Coalossal%Applin%Flapple%Appletun%Silicobra%Sandaconda%Cramorant%Arrokuda%Barraskewda%Toxel%Toxtricity%Sizzlipede%Centiskorch%Clobbopus%Grapploct%Sinistea%Polteageist%Hatenna%Hattrem%Hatterene%Impidimp%Morgrem%Grimmsnarl%Obstagoon%Perrserker%Cursola%Sirfetch'd%Mr. Rime%Runerigus%Milcery%Alcremie%Falinks%Pincurchin%Snom%Frosmoth%Stonjourner%Eiscue%Indeedee%Morpeko%Cufant%Copperajah%Dracozolt%Arctozolt%Dracovish%Arctovish%Duraludon%Dreepy%Drakloak%Dragapult%Zacian%Zamazenta%Eternatus%Kubfu%Urshifu%Zarude%Regieleki%Regidrago%Glastrier%Spectrier%Calyrex%Wyrdeer%Kleavor%Ursaluna%Basculegion%Sneasler%Overqwil%Enamorus%Sprigatito%Floragato%Meowscarada%Fuecoco%Crocalor%Skeledirge%Quaxly%Quaxwell%Quaquaval%Lechonk%Oinkologne%Tarountula%Spidops%Nymble%Lokix%Pawmi%Pawmo%Pawmot%Tandemaus%Maushold%Fidough%Dachsbun%Smoliv%Dolliv%Arboliva%Squawkabilly%Nacli%Naclstack%Garganacl%Charcadet%Armarouge%Ceruledge%Tadbulb%Bellibolt%Wattrel%Kilowattrel%Maschiff%Mabosstiff%Shroodle%Grafaiai%Bramblin%Brambleghast%Toedscool%Toedscruel%Klawf%Capsakid%Scovillain%Rellor%Rabsca%Flittle%Espathra%Tinkatink%Tinkatuff%Tinkaton%Wiglett%Wugtrio%Bombirdier%Finizen%Palafin%Varoom%Revavroom%Cyclizar%Orthworm%Glimmet%Glimmora%Greavard%Houndstone%Flamigo%Cetoddle%Cetitan%Veluza%Dondozo%Tatsugiri%Annihilape%Clodsire%Farigiraf%Dudunsparce%Kingambit%Great Tusk%Scream Tail%Brute Bonnet%Flutter Mane%Slither Wing%Sandy Shocks%Iron Treads%Iron Bundle%Iron Hands%Iron Jugulis%Iron Moth%Iron Thorns%Frigibax%Arctibax%Baxcalibur%Gimmighoul%Gholdengo%Wo-Chien%Chien-Pao%Ting-Lu%Chi-Yu%Roaring Moon%Iron Valiant%Koraidon%Miraidon%Walking Wake%Iron Leaves%Dipplin%Poltchageist%Sinistcha%Okidogi%Munkidori%Fezandipiti%Ogerpon%Archaludon%Hydrapple%Gouging Fire%Raging Bolt%Iron Boulder%Iron Crown%Terapagos%Pecharunt",
            '25% Human | 75% Pokemon':"",
            '50% Human | 50% Pokemon':"",
            '75% Human | 25% Pokemon':"",
            'Digimon':"Invisimon%Oblivimon%Dimetromon%Ryugumon%Cernumon%MarineBullmon%Elizamon%Nezhamon%Dinomon%Skadimon%PolarBearmon%Erlangmon: Blast Mode%(X Antibody) QueenBeemon%(X Antibody) Vespamon%(X Antibody) ForgeBeemon%HeavyMetaldramon%Loudmon%Punkmon%Takutoumon:Wrath Mode%Erlangmon%Cendrillmon%Chaperomon%Zephagamon%GrandGalemon%Fluffymon%Yolkmon%Callismon%Tlalocmon%ShoeShoemon%Shoemon%Galemon%Pteromon%Takutoumon%(X Antibody) Fenriloogamon: Takemikazuchi%BigUkkomon%Ukkomon%Dijiangmon%Xingtianmon%Lianpumon%Dominimon%ArkhaiAngemon%Luxmon%Fanglongmon: Ruin Mode%Moonmon%Sunmon%Brigadramon%Hi-Commandramon%(X Antibody) Fenriloogamon%(X Antibody) Helloogarmon%(X Antibody) Soloogarmon%Cargodramon%(X Antibody) Loogarmon%(X Antibody) Bowmon%(X Antibody) Fusamon%Quantumon%(X Antibody) Loogamon%Proximamon%Arcturusmon%GreyKnightsmon%Zanmetsumon%Bombermon%Ghilliedhumon%Fumamon%Cthyllamon%Regulusmon%Galacticmon%Destromon%Snatchmon%Vemmon%(X Antibody) Baalmon(X antibody)%Amphimon%Diarbbitmon%Siriusmon%ShineGreymon: Ruin Mode%Chamblemon%Publimon%Oleamon%Huankunmon%Xiangpengmon%Xiquemon%Imperialdramon: Fighter Mode (Black)%(X Antibody) Greymon (Blue)((X Antibody) )%Oboromon%Gyuukimon%ShinMonzaemon%HoverEspimon%Espimon%Jupitermon: Wrath Mode%Plutomon%Ceresmon%Bacchusmon%Junomon: Hysteric Mode%Junomon%Thetismon%Lamortmon%Canoweissmon%Sistermon Ciel (Awake.)%Sistermon Noir (Awake.)%Sistermon Blanc (Awake.)%GulusGammamon%TeslaJellymon%SymbareAngoramon%BlackGatomon Uver.%Weddinmon%Shortmon%BlackRapidmon%BlackGargomon%Omnimon Zwart Defeat%WezenGammamon%KausGammamon%BetelGammamon%Abbadomon Core%Luminamon (Nene Version)%Xros WarsShoutmon X7: Superior Mode%Jellymon%Puyoyomon%Puyomon%Angoramon%Bosamon%Pyonmon%Gammamon%Gurimon%Curimon%Abbadomon%Negamon%PileVolcanomon%Raidenmon%Raijinmon%DoKunemon%ModokiBetamon%Hydramon%Bloomlordmon%Ajatarmon%Guardromon (Gold)%Burgamon%Piddomon%SandYanmamon%Yanmamon%MoriShellmon%BomberNanimon%(X Antibody) HerculesKabuterimon%(X Antibody) Starmon%(X Antibody) Growlmon%(X Antibody) Hagurumon%(X Antibody) Gaiomon: Itto Mode%Brachiomon%Kyukimon%Vermilimon%Assaultmon%Tekkamon%Vulturemon%Tumblemon%Sandmon%Burpmon%BlackKingNumemon%GoldNumemon%Calumon%Gladimon%Xros WarsShoutmon X4K%KoDokugumon%Yoxtu!Yoxtu!mon%Minidekachimon%Atamadekachimon%Trailmon%KingSukamon%Shroudmon%FrosVelgrmon%Frozomon%Hiyarimon%BlackSeraphimon%RareRaremon%Climbmon%Divemon%ClearAgumon%BanchoLillymon%(X Antibody) MetalGreymon (Vaccine)%(X Antibody) IceLeomon%(X Antibody) MetalMamemon%(X Antibody) Thundermon%(X Antibody) Monochromon%(X Antibody) Dobermon%(X Antibody) Gesomon%(X Antibody) Gotsumon%(X Antibody) Crabmon%(X Antibody) Guilmon%Shoutmon EX6%TorikaraBallmon%Burgamon%Potamon%Achillesmon%Shivamon%Kazuchimon%Pistmon%Tempomon%Shootmon%Boutmon%Mitamamon%LovelyAngemon%Bibimon%Dokimon%Namakemon%Runnermon%Exermon%Bulkmon%Komondomon%Pulsemon%Omnimon: Merciful Mode%DoneDevimon%WereGarurumon: Sagittarius Mode%Imperialdramon: Dragon Mode (Black)%Manticoremon%Mimicmon%Baluchimon%DarkMaildramon%MetalGreymon: Alterous Mode%Rebellimon%Machmon%Junkmon%HeavyLeomon%Hopmon%Ketomon%Nidhoggmon%Entmon%Parasaurmon%Toropiamon%Pomumon%Eyesmon: Scatter Mode%Eyesmon%(X Antibody) Betamon%(X Antibody) Gazimon%Argomon%Ghostmon%Regalecusmon%Piranimon%Gusokumon%MarineChimairamon%Tobiumon%Sangomon%Gogmamon%Baboongamon%Sunarizamon%JewelBeemon%Hudiemon%Xros WarsArresterdramon: Superior Mode%(X Antibody) Garurumon%(X Antibody) Greymon%Argomon%Argomon%Argomon%Spadamon%Morphomon%Eosmon%Gabumon (Bond of Friendship)%Agumon (Bond of Bravery)%Eosmon%Eosmon%TonosamaMamemon%Omnimon Zwart%Terriermon Assistant%CrysPaledramon%Metallicdramon%Jazarichmon%Jazardmon%Jazamon%Hexeblaumon%Paledramon%NoblePumpkinmon%(X Antibody) Ogudomon%(X Antibody) Jesmon GX%(X Antibody) Keramon%(X Antibody) OmniShoutmon%(X Antibody) Meramon%(X Antibody) Pegasusmon%(X Antibody) Rapidmon%(X Antibody) Monzaemon%(X Antibody) Gankoomon%(X Antibody) Examon%(X Antibody) Cyberdramon%(X Antibody) RizeGreymon%(X Antibody) Phoenixmon%(X Antibody) Justimon%(X Antibody) Wizardmon%(X Antibody) Seasarmon%(X Antibody) Cherubimon (Good)%(X Antibody) Ophanimon%(X Antibody) Angewomon%(X Antibody) Diaboromon%(X Antibody) Dynasmon%(X Antibody) Leopardmon%(X Antibody) Magnadramon%(X Antibody) Plesiomon%(X Antibody) Goldramon%(X Antibody) Garudamon%(X Antibody) Gatomon%(X Antibody) Togemon%(X Antibody) Tylomon%(X Antibody) Lopmon%(X Antibody) Syakomon%(X Antibody) Terriermon%(X Antibody) Palmon%(X Antibody) Pteramon%(X Antibody) Mamemon%(X Antibody) Ebemon%(X Antibody) Kentaurosmon%(X Antibody) Craniamon%(X Antibody) UlforceVeedramon%(X Antibody) Magnamon%(X Antibody) MegaSeadramon%(X Antibody) Triceramon%(X Antibody) Okuwamon%(X Antibody) Mantaraymon%(X Antibody) Nefertimon%(X Antibody) Seadramon%(X Antibody) Kuwagamon%(X Antibody) Allomon%(X Antibody) Gomamon%(X Antibody) Kokuwamon%(X Antibody) BlackWarGreymon%(X Antibody) LadyDevimon%(X Antibody) MetalGreymon (Virus)%(X Antibody) Ogremon%(X Antibody) Agumon (Black)%Rasenmon%Rasenmon: Fury Mode%Stefilmon%Filmon%(X Antibody) Rosemon%(X Antibody) PrinceMamemon%(X Antibody) SkullMammothmon%(X Antibody) Mammothmon%(X Antibody) Mephistomon%(X Antibody) Myotismon%(X Antibody) Salamon%(X Antibody) Otamamon%Yaamon%Keemon%(X Antibody) Impmon%(X Antibody) DarkTyrannomon%(X Antibody) Numemon%(X Antibody) Lucemon%(X Antibody) Lilithmon%(X Antibody) Leviamon%(X Antibody) Belphemon%(X Antibody) Barbamon%(X Antibody) Creepymon%(X Antibody) DarkKnightmon%(X Antibody) Cherubimon (Black)%(X Antibody) Ophanimon: Falldown Mode%UltimateChaosmon%Pusurimon%Pusumon%Surfimon%Bulucomon%Herissmon%MetalGarurumon (Black)%WereGarurumon (Black)%Garurumon (Black)%Justimon: Blitz Arm%Ginkakumon Promote%IceDevimon%Kuzuhamon Maid Mode%WarGrowlmon (Orange)%Greymon (Blue)%Xros WarsShoutmon (King Version)%(X Antibody) WarGreymon%(X Antibody) MetalGarurumon%(X Antibody) Megidramon%(X Antibody) WereGarurumon%(X Antibody) Lillymon%(X Antibody) Sakuyamon%(X Antibody) Beelzemon%(X Antibody) WarGrowlmon%(X Antibody) Rhinomon%(X Antibody) Renamon%(X Antibody) Tokomon%(X Antibody) BeelStarmon%(X Antibody) Gallantmon%(X Antibody) Cerberusmon%(X Antibody) Tyrannomon%(X Antibody) Dracomon%(X Antibody) Gabumon%(X Antibody) Minervamon%(X Antibody) LordKnightmon%Sistermon Ciel%(X Antibody) MetalTyrannomon%(X Antibody) Leomon%(X Antibody) Agumon%(X Antibody) Jesmon%RagnaLoardmon%Rafflesimon%Ordinemon%Xros WarsRaptorSparrowmon%BanchoGolemon%Cerberusmon: Werewolf Mode%Growlmon (Orange)%ToyAgumon (Black)%Xros WarsShootingStarmon%Justimon: Critical Arm%Crowmon%Dinohyumon%Rapidmon%Xros WarsJaegerDorulumon%Gundramon%Aegiochusmon: Holy%Gabumon (Black)%Pipimon%Raguelmon%BryweLudramon%Volcanicdramon%Lavogaritamon%Maycrackmon: Vicious Mode%Mastemon%Boltboutamon%RaijiLudomon%TiaLudomon%Lavorvomon%BushiAgumon%Ludomon%Kakkinmon%Cotsucomon%Antylamon%Meicoomon%Whamon (Champion)%Gekomon%Vorvomon%Xros WarsAtlurBallistamon%Omnimon Alter-B%BlackMachGaogamon%BlackGaogamon%Falcomon (2006 Anime Version)%Kudamon (2006 Anime Version)%NEO%Xros WarsYakiimon%Xros WarsMonimon%Xros WarsMonitamon%Xros WarsMervamon%Xros WarsMetalGreymon + Cyber Launcher%Xros WarsMetalGreymon (2010 Anime Version)%Xros WarsMailBirdramon%Xros WarsMusouKnightmon%Xros WarsMadLeomon: Armed Mode%Xros WarsMadLeomon%Xros WarsBommon (2010 Anime Version)%Xros WarsBeelzemon (2010 Anime Version)%Xros WarsBlastmon%Xros WarsFootmon%Xros WarsPillomon%Xros WarsPickmon%Xros WarsBallistamon%Xros WarsBakomon%Xros WarsBagramon%Xros WarsHi-VisionMonitamon%Xros WarsBaalmon%Xros WarsNeoMyotismon%Xros WarsDondokomon%Xros WarsDonShoutmon%Xros WarsDorulumon%Xros WarsDorbickmon%Xros WarsTroopmon%Xros WarsDeadlyAxemon%Xros WarsDeckerdramon%Xros WarsDeckerGreymon%Xros WarsTuwarmon%Xros WarsChuuChuumon%Xros WarsChibickmon%Xros WarsChikurimon%Xros WarsDamemon%Xros WarsTactimon%Xros WarsDarknessBagramon%Xros WarsDarkKnightmon%Xros WarsZenimon%Xros WarsSplashmon%Xros WarsSparrowmon%Xros WarsStarmons%Xros WarsSkullKnightmon: Mighty Axe Mode%Xros WarsSkullKnightmon: Cavalier Mode%Xros WarsSkullKnightmon%Xros WarsJokermon%Xros WarsShanitamon%Xros WarsShoutmon + Dorulu Cannon%Xros WarsShoutmon + Star Sword%Xros WarsShoutmon + Jet Sparrow%Xros WarsShoutmon X7%Xros WarsShoutmon X5B%Xros WarsShoutmon X5%Xros WarsShoutmon X4B%Xros WarsShoutmon X4%Xros WarsShoutmon X3%Xros WarsShoutmon X2%Xros WarsShoutmon DX%Xros WarsShoutmon%Xros WarsJetMervamon%Xros WarsZeigGreymon%Xros WarsZamielmon%Xros WarsSoundbirdmon%Xros WarsCyberdramon%Xros WarsKozenimon%Xros WarsGreymon (2010 Anime Version)%Xros WarsGravimon%Xros WarsCutemon%Xros WarsGumdramon%Xros WarsGanemon%Xros WarsGaossmon%Xros WarsOlegmon%Xros WarsOmniShoutmon%Xros WarsEkakimon%Xros WarsIgnitemon%Xros WarsArresterdramon%(Hybrid) Loweemon%(Hybrid) Lanamon%(Hybrid) Rhihimon%(Hybrid) RhinoKabuterimon%(Hybrid) Mercurymon%(Hybrid) MagnaGarurumon%(Hybrid) MetalKabuterimon%(Hybrid) Velgrmon%(Hybrid) Petaldramon%(Hybrid) Beowolfmon%(Hybrid) Flamemon%(Hybrid) Beetlemon%(Hybrid) Korikakumon%(Hybrid) Kazemon%(Hybrid) Kumamon%(Hybrid) Duskmon%(Hybrid) DaiPenmon%(Hybrid) Sephirothmon%(Hybrid) Strabimon%(Hybrid) Zephyrmon%(Hybrid) JetSilphymon%(Hybrid) Grumblemon%(Hybrid) Gigasmon%(Hybrid) KendoGarurumon%(Hybrid) Calmaramon%(Hybrid) EmperorGreymon%(Hybrid) JagerLoweemon%(Hybrid) BurningGreymon%(Hybrid) Lobomon%(Hybrid) Arbormon%(Hybrid) Aldamon%(Hybrid) Agunimon%Rinkmon%Lynxmon%Rhinomon%Lighdramon%Yasyamon%Mothmon%Maildramon%Moosemon%Manbomon%Mantaraymon%Magnamon%Ponchomon%Halsemon%Boarmon%Pegasusmon%Frogmon%Prairiemon%Flamedramon%FlameWizardmon%Bullmon%Flybeemon%Pteramon%Bucchiemon (Green)%Bucchiemon%Pipismon%Rabbitmon%Peacockmon%Baronmon%Honeybeemon%Butterflymon%Harpymon%Nohemon%Nefertimon%Togemogumon%Toucanmon%Depthmon%Tylomon%Digmon%Sepikmon%Sethmon%Swanmon%Stegomon%Shurimon%Shadramon%Seahomon%Sheepmon%Thunderbirdmon%Salamandermon%Submarimon%Sagittarimon%Searchmon%Kongoumon%GoldVeedramon%Goatmon%Kenkimon%Quetzalmon%Kangarumon%Chameleonmon%Kabukimon%Gargoylemon%Orcamon%Opossummon%Elephantmon%Allomon%Archelomon%Aurumon%LordKnightmon%Lotosmon%Rosemon: Burst Mode%Rosemon%Ravemon: Burst Mode%Ravemon%Lucemon: Larva%Lucemon: Satan Mode%Lilithmon%Leviamon%Lampmon%RustTyrannomon%Rasielmon%Jupitermon%Merukimon%MedievalGallantmon%(X Antibody) MetalPiranimon%MetalSeadramon%MetalGarurumon%MetalEtemon%Megidramon%MoonMillenniummon%Murmukusmon%Machinedramon%Millenniummon%MirageGaogamon: Burst Mode%MirageGaogamon%Minervamon%Marsmon%MarineAngemon%MagnaKidmon%Boltmon%Magnadramon%Phoenixmon%Belphemon: Rage Mode%Belphemon: Sleep Mode%Beelzemon: Blast Mode%Beelzemon%BeelStarmon%MaloMyotismon%HerculesKabuterimon%Plesiomon%Breakdramon%PrinceMamemon%BlitzGreymon%BlackSaintGargomon%BlackWarGreymon%PlatinumNumemon%Pukumon%Fujinmon%Fanglongmon%Pharaohmon%Puppetmon%VictoryGreymon%Piedmon%BanchoLeomon%BanchoMamemon%BanchoStingmon%Barbamon%Parasimon%Babamon%Baihumon%HiAndromon%Neptunemon%(X Antibody) Dorugoramon%Leopardmon: Leopard Mode%Leopardmon%Durandamon%Dynasmon%Gallantmon: Crimson Mode%Gallantmon%Devitamamon%Ghoulmon (Black)%Ghoulmon%DeathXmon%Creepymon%(X Antibody) DexDorugoramon%(X Antibody) Dinorexmon%(X Antibody) Dinotigermon%Diaboromon%Dianamon%Azulongmon%Darkdramon%TyrantKabuterimon%Titamon%(X Antibody) TigerVespamon%MegaGargomon%Seraphimon%Slayerdramon%Kentaurosmon%SlashAngemon%Spinomon%Susanomon%SkullMammothmon%Zhuqiaomon%Suijinmon%ZeedMillenniummon%ZeedGarurumon%JumboGamemon%Justimon: Accel Arm%Shakamon%ShineGreymon: Burst Mode%ShineGreymon%Jijimon%Ebonwumon%Jesmon%Zanbamon%Sakuyamon: Maid Mode%Sakuyamon%SaberLeomon%Goldramon%Reapermon%Cherubimon (Black)%Cherubimon (Good)%Eaglemon%Craniamon%GraceNovamon%Gryphonmon%GroundLocomon%GranDracmon%(X Antibody) GrandisKuwagamon%GranKuwagamon%ClavisAngemon%Kuzuhamon%Quartzmon%CresGarurumon%QueenChessmon%KingChessmon%KingEtemon%Cannondramon%(X Antibody) GigaSeadramon%Gankoomon%Gulfmon%Chaosmon: Valdur Arm%Chaosmon%(X Antibody) Chaosdramon%Chaosdramon%ChaosGallantmon%(X Antibody) Gaiomon%Omnimon Alter-S%(X Antibody) Omnimon%Omnimon%Ophanimon: Falldown Mode%Ophanimon%Ornismon%Ogudomon%(X Antibody) Ouryumon%AncientWisemon%AncientMegatheriummon%AncientMermaimon%AncientVolcanomon%AncientBeetlemon%AncientTroymon%AncientSphinxmon%AncientGreymon%AncientGarurumon%AncientKazemon%Eldradimon%Examon%Vulcanusmon%WarGreymon%VenomMyotismon%Venusmon%Varodurumon%Valkyrimon%Vikemon%Ebemon%Aegisdramon%Imperialdramon: Fighter Mode%Imperialdramon: Paladin Mode%Imperialdramon: Dragon Mode%King Drasil_7D6%UlforceVeedramon%(X Antibody) Alphamon: Ouryuken%(X Antibody) Alphamon%(X Antibody) UltimateBrachiomon%Argomon%Apollomon%Apocalymon%Anubismon%Armageddemon%AvengeKidmon%WaruMonzaemon%WaruSeadramon%Wisemon%WereGarurumon%Locomon%LoaderLeomon%LadyDevimon%Luminamon%Lucemon: Chaos Mode%RookChessmon%Lillymon%Rapidmon%Lilamon%RizeGreymon%Crowmon (2006 Anime Version)%Monzaemon%Mephistomon%MetalMamemon%(X Antibody) MetalPhantomon%MetalTyrannomon%MetalGreymon (Vaccine)%MetalGreymon (Virus)%MetallifeKuwagamon%WarGrowlmon%Megadramon%MegaSeadramon%Maycrackmon%Mihiramon%Mistymon%Mammothmon%MarineDevimon%(X Antibody) Mametyramon%Mamemon%Mummymon%MachGaogamon%Matadormon%MasterTyrannomon%Majiramon%Makuramon%Mermaimon%Volcanomon%MagnaAngemon%Whamon%Betsumon%(X Antibody) Vademon%Vademon%Blossomon%Flaremon%BlueMeramon%BlackWarGrowlmon%Feresmon%Phantomon%HippoGryphonmon%Piximon%BigMamemon%BishopChessmon%(X Antibody) Hisyaryumon%Pumpkinmon%Pandamon%IceLeomon%Divermon%Parrotmon%Bulbmon%Bastemon%Pajiramon%Paildramon%NeoDevimon%Datamon%Knightmon%(X Antibody) DoruGreymon%Triceramon%ShogunGekomon%Doumon%Deramon%Duramon%SkullMeramon%Digitamamon%(X Antibody) DexDoruGreymon%Dinobeemon%Cho-Hakkaimon%Caturamon%Chirinmon%Tankdramon%Dragomon%Taomon%DarkSuperStarmon%Sirenmon%SaviorHuckmon%Zudomon%SkullScorpiomon%(X Antibody) SkullBaluchimon%SkullSatamon%SkullGreymon%SuperStarmon%Sinduramon%Silphymon%Cherrymon%Shakkoumon%Jagamon%Shaujinmon%Sandiramon%Sanzomon%Sagomon%Cyberdramon%Gokuumon%Cerberusmon%Kumbhiramon%Crescemon%(X Antibody) Grademon%GrapLeomon%Groundramon%Giromon%CaptainHookmon%(X Antibody) CannonBeemon%CatchMamemon%Kimeramon%Gigadramon%Garudamon%Karatenmon%Garbagemon%Orochimon%Okuwamon%Angewomon%Etemon%ExTyrannomon%AeroVeedramon%Volcdramon%Wingdramon%Vikaralamon%Myotismon%Vajramon%Infermon%Indramon%Meteormon%Andromon%Antylamon (Deva)%Argomon%Arukenimon%(X Antibody) Scorpiomon%Scorpiomon%MegaKabuterimon (Red)%MegaKabuterimon (Blue)%Astamon%Asuramon%Aegiochusmon: Blue%Aegiochusmon: Dark%Aegiochusmon: Green%Aegiochusmon%(X Antibody) Waspmon%Reppamon%RedVegiemon%Lekismon%Leomon%Raremon%Dolphmon%Deputymon%(X Antibody) Raptordramon%Liamon%Youkomon%Unimon%Frigimon%Monochromon%Mojyamon%Meramon%Mekanorimon%Musyamon%Minotarumon%Mikemon%Porcupamon%Peckmon%Vegiemon%BladeKuwagamon%Flarerizamon%Blimpmon%BlackGatomon%BlackGrowlmon%PlatinumSukamon%Flymon%Hookmon%Boogiemon%Fugamon%Veedramon%Fangmon%Firamon%Hyogamon%Petermon%Apemon%Bakemon%BaoHuckmon%Birdramon%Numemon%NiseDrimogemon%Nanimon%KnightChessmon (White)%KnightChessmon (Black)%(X Antibody) Dorugamon%Drimogemon%(X Antibody) TobuCatmon%Doggymon%Togemon%Dokugumon%Dobermon%Tortomon%Turuiemon%Deltamon%Devimon%Devidramon%(X Antibody) DexDorugamon%Gatomon%Tyrannomon%Diatrymon%MudFrigimon%Tankmon%Darcmon%Tuskmon%Targetmon%DarkLizardmon%DarkTyrannomon%Sorcermon%Soulmon%Saberdramon%ZubaEagermon%Snimon%Strikedramon%Stingmon%Starmon%Sukamon%JungleMojyamon%ShimaUnimon%Sistermon Noir%GeoGreymon%Shellmon%Shademon%Sealsdramon%Coelamon%Seadramon%Seasarmon%Sunflowmon%Thundermon%Sangloupmon%Weedmon%Cyclonemon%Gorillamon%Roachmon%Golemon%Kokatorimon%Kogamon%Coredramon (Green)%Coredramon (Blue)%Centarumon%Geremon%Gesomon%Kuwagamon%Clockmon%Greymon%Gururumon%Grizzlymon%Kurisarimon%Growlmon%(X Antibody) Ginryumon%Ginkakumon%Kinkakumon%Kyubimon%Kiwimon%Gawappamon%Garurumon%Gargomon%ShellNumemon%Kabuterimon%Guardromon%Gaogamon%(X Antibody) Omekamon%Octomon%Ogremon%Angemon%Ebidramon%ExVeemon%Airdramon%Woodmon%Wendigomon%Witchmon%Wizardmon%Vilemon%Ikkakumon%Ninjamon%Ankylomon%Aquilamon%Akatorimon%Icemon%Aegiomon%Wormmon%Lopmon%Renamon%Liollmon%Lunamon%Lucemon%(X Antibody) Ryudamon%Lalamon%Labramon%SnowAgumon%Monodramon%Muchomon%Mushroomon%Bokomon%PawnChessmon (White)%PawnChessmon (Black)%Hawkmon%Penmon%Betamon%Bearmon%Salamon%Floramon%Veemon%(X Antibody) FunBeemon%Falcomon%Phascomon%Biyomon%DemiDevimon%Palmon%Huckmon%Patamon%Hagurumon%Tapirmon%Neemon%Fake Agumon Expert%(X Antibody) Dorumon%Dracomon%Dracmon%ToyAgumon%Tentomon%Terriermon%Tinkermon%Tsukaimon%Chuumon%Solarmon%Zubamon%SnowGoblimon%Swimmon%Syakomon%Shamamon%Sistermon Blanc%Psychemon%Coronamon%Commandramon%Gomamon%Goblimon%Kotemon%Gotsumon%Kokuwamon%KoKabuterimon%Monmon%Keramon%Kunemon%Kudamon%Guilmon%Candlemon%Gizamon%Kamemon%Gabumon%Crabmon%Gazimon%Gaomon%Otamamon (Red)%Otamamon%Elecmon (Violet)%Elecmon%EbiBurgamon%Impmon%Aruraumon%Armadillomon%Arcadiamon%Agumon Expert%Agumon (Black)%Agumon (2006 Anime Version)%Agumon%Wanyamon%Motimon%Minomon%Missimon%Poromon%Viximon%Bebydomon%(X Antibody) Puroromon%Frimon%DemiMeramon%Bukamon%Yokomon%Pinamon%Budmon%Pagumon%Nyaromon%(X Antibody) Dorimon%Tokomon%Tsumemon%Tsunomon%Kokomon%Chapmon%DemiVeemon%Tanemon%Xiaomon%Sakuttomon%Koromon%Gummymon%(X Antibody) Kyokyomon%Cupimon%Kyaromon%Gigimon%Kapurimon%Upamon%Relemon%Leafmon%Yuramon%YukimiBotamon%Mokumon%Poyomon%Bommon%Popomon%Botamon%Puwamon%Pururumon%(X Antibody) Pupumon%(X Antibody) Fufumon%Punimon%Puttimon%Petitmon%Pichimon%Pafumon%Pabumon%Paomon%Nyokimon%(X Antibody) Dodomon%Tsubumon%Choromon%Chibomon%Zerimon%Zurumon%Jyarimon%Sakumon%Conomon%Kuramon",
            '25% Human | 75% Digimon':"",
            '50% Human | 50% Digimon':"",
            '75% Human | 25% Digimon':"",
            'Pokemon + Digimon':"",
            '25% Human | 75% Pokemon + Digimon':"",
            '50% Human | 50% Pokemon + Digimon':"",
            '75% Human | 25% Pokemon + Digimon':"",
            'Chaos':""
        },
        age: {
            'All': "1%2%3%4%5%6%7%8%9%10%11%12%13%14%15%16%17%18%19%20%21%22%23%24%25%26%27%28%29%30%31%32%33%34%35%36%37%38%39%40%41%42%43%44%45%46%47%48%49%50%51%52%53%54%55%56%57%58%59%60%61%62%63%64%65%66%67%68%69%70%71%72%73%74%75%76%77%78%79%80%81%82%83%84%85%86%87%88%89%90%91%92%93%94%95%96%97%98%99%100+", // ages 1 to 99
            'Child': "1%2%3%4%5%6%7%8%9%10%11%12%13%14%15%16%17", // ages 1 to 17
            'Adult': "18%19%20%21%22%23%24%25%26%27%28%29%30%31%32%33%34%35%36%37%38%39%40%41%42%43%44%45%46%47%48%49%50%51%52%53%54%55%56%57%58%59%60%61%62%63%64%65%66%67%68%69%70", // ages 18 to 7
            'Elderly':"%71%72%73%74%75%76%77%78%79%80%81%82%83%84%85%86%87%88%89%90%91%92%93%94%95%96%97%98%99%100+",
            'Ancient': "100%200%300%400%500%600%700%800%900%1000%1100%1200%1300%1400%1500%1600%1700%1800%1900%2000%2100%2200%2300%2400%2500%2600%2700%2800%2900%3000%3100%3200%3300%3400%3500%3600%3700%3800%3900%4000%4100%4200%4300%4400%4500%4600%4700%4800%4900%5000%5100%5200%5300%5400%5500%5600%5700%5800%5900%6000%6100%6200%6300%6400%6500%6600%6700%6800%6900%7000%7100%7200%7300%7400%7500%7600%7700%7800%7900%8000%8100%8200%8300%8400%8500%8600%8700%8800%8900%9000%9100%9200%9300%9400%9500%9600%9700%9800%9900%10000+",
        },
        bodyType: {
            'All': "Slim%Athletic%Average%Curvy%Muscular%Stocky%Petite%Lean%Toned%Fit%Slender%Shapely%Voluptuous%Chubby%Overweight%Obese%Hefty%Skinny%Scrawny%Gangly%Lanky%Wiry%Sinewy%Flabby%Pudgy%Plump%Portly%Stout%Rotund%Paunchy%Potbellied%Willowy%Statuesque%Towering%Diminutive%Stubby%Squat%Deformed%Grotesque%Hideous%Unsightly%Repulsive%Revolting%Monstrous%Misshapen%Disfigured%Malformed%Gorgeous%Stunning%Handsome%Beautiful%Attractive%Pleasing%Alluring%Captivating%Charming%Elegant",
            'Slender': "Slim%Lean%Slender%Skinny%Scrawny%Gangly%Lanky%Wiry%Sinewy%Willowy%Lithe%Graceful%Svelte%Sylphlike",
            'Fit': "Athletic%Toned%Fit%Muscular%Sinewy%Strapping%Brawny%Burly%Powerful%Robust%Vigorous%Mighty%Herculean",
            'Average': "Average%Shapely%Stocky%Ordinary%Common%Typical%Regular%Unremarkable%Nondescript%Plain%Homely",
            'Curvy': "Curvy%Voluptuous%Shapely%Buxom%Full-figured%Hourglass%Zaftig%Rubenesque%Lush%Ample%Curvaceous%Bodacious",
            'Overweight': "Chubby%Overweight%Obese%Hefty%Flabby%Pudgy%Plump%Portly%Stout%Rotund%Paunchy%Potbellied%Corpulent%Fleshy%Bloated",
            'Short': "Petite%Diminutive%Stubby%Squat%Pint-sized%Compact%Teeny%Miniature%Elfin%Dainty%Tiny%Wee",
            'Tall': "Towering%Statuesque%Lofty%Gigantic%Colossal%Enormous%Huge%Immense%Mammoth%Gargantuan%Titanic%Mountainous",
            'Ugly': "Deformed%Grotesque%Hideous%Unsightly%Repulsive%Revolting%Monstrous%Misshapen%Disfigured%Malformed%Unpleasant%Homely%Unappealing%Unattractive",
            'Attractive': "Gorgeous%Stunning%Handsome%Beautiful%Attractive%Pleasing%Alluring%Captivating%Charming%Elegant%Exquisite%Magnificent%Dazzling%Radiant",
        },
        personality: {
            'All': "Cheerful%Serious%Energetic%Calm%Average%Shy%Outgoing%Snarky%Kind%Brave%Cautious%Adventurous%Ambitious%Analytical%Charismatic%Confident%Creative%Curious%Dependable%Diplomatic%Disciplined%Empathetic%Enthusiastic%Extroverted%Friendly%Generous%Gentle%Honest%Humble%Humorous%Idealistic%Independent%Introverted%Intuitive%Logical%Loyal%Mysterious%Observant%Optimistic%Passionate%Patient%Perfectionist%Persistent%Pessimistic%Philosophical%Practical%Resourceful%Romantic%Sarcastic%Selfless%Sensible%Sensitive%Skeptical%Sociable%Spontaneous%Stoic%Stubborn%Sympathetic%Thoughtful%Trustworthy%Unpredictable%Wise%Witty%Zealous",
            'Positive': "Cheerful%Energetic%Kind%Brave%Adventurous%Ambitious%Charismatic%Confident%Creative%Curious%Dependable%Empathetic%Enthusiastic%Friendly%Generous%Gentle%Honest%Humble%Humorous%Idealistic%Independent%Intuitive%Loyal%Optimistic%Passionate%Patient%Persistent%Resourceful%Romantic%Selfless%Sensible%Sensitive%Sociable%Spontaneous%Sympathetic%Thoughtful%Trustworthy%Wise%Witty%Zealous",
            'Neutral': "Average%Analytical%Calm%Cautious%Diplomatic%Disciplined%Extroverted%Introverted%Logical%Mysterious%Observant%Philosophical%Practical%Stoic",
            'Negative': "Serious%Shy%Snarky%Cautious%Pessimistic%Perfectionist%Sarcastic%Skeptical%Stubborn%Unpredictable",
            'Extroverted': "Cheerful%Energetic%Outgoing%Adventurous%Charismatic%Confident%Enthusiastic%Extroverted%Friendly%Humorous%Sociable%Spontaneous%Witty",
            'Introverted': "Serious%Calm%Shy%Analytical%Cautious%Independent%Introverted%Mysterious%Observant%Thoughtful",
            'Thinking': "Analytical%Logical%Practical%Skeptical%Resourceful%Sensible%Wise%Philosophical%Perfectionist%Stoic%Disciplined%Persistent",
            'Feeling': "Kind%Empathetic%Gentle%Romantic%Selfless%Sensitive%Sympathetic%Idealistic%Passionate%Sentimental%Compassionate%Nurturing",
            'Judging': "Serious%Ambitious%Disciplined%Dependable%Honest%Loyal%Persistent%Practical%Responsible%Sensible%Trustworthy%Decisive%Organized%Punctual",
            'Perceiving': "Energetic%Adventurous%Creative%Curious%Adaptable%Easygoing%Flexible%Open-minded%Spontaneous%Tolerant%Improvising%Relaxed",
            'Assertive': "Confident%Independent%Ambitious%Decisive%Determined%Dominant%Firm%Strong-willed%Competitive%Bold%Daring%Fearless",
            'Turbulent': "Snarky%Sarcastic%Unpredictable%Chaotic%Impulsive%Moody%Paranoid%Pessimistic%Quarrelsome%Resentful%Temperamental%Volatile",
        },
        bio: {
            'Standard': "Loves exploring new places.%Enjoys reading books and learning new things.%Has a passion for music and the arts.%A dedicated athlete and fitness enthusiast.%An adventurous spirit with a love for travel.%Loyal friend who values honesty and integrity.%Tech-savvy individual with a knack for gadgets.%Creative thinker who enjoys solving problems.%Animal lover who spends time volunteering at shelters.%An aspiring chef who loves experimenting in the kitchen.",
            // Add more categories if needed
        },
    };

    defaultRandomizerOptions.species['25% Human | 75% Animals'] = defaultRandomizerOptions.species.Animals + "%Human*923";
    defaultRandomizerOptions.species['50% Human | 50% Animals'] = defaultRandomizerOptions.species.Animals + "%Human*2770";
    defaultRandomizerOptions.species['75% Human | 25% Animals'] = defaultRandomizerOptions.species.Animals + "%Human*8310";
    defaultRandomizerOptions.species['25% Human | 75% Mythos'] = defaultRandomizerOptions.species.Mythological + "%Human*317";
    defaultRandomizerOptions.species['50% Human | 50% Mythos'] = defaultRandomizerOptions.species.Mythological + "%Human*951";
    defaultRandomizerOptions.species['75% Human | 25% Mythos'] = defaultRandomizerOptions.species.Mythological + "%Human*2853";
    defaultRandomizerOptions.species['Mythos + Animals'] = defaultRandomizerOptions.species.Animals + "," + defaultRandomizerOptions.species.Mythological;
    defaultRandomizerOptions.species['25% Human | 75% Mythos + Animals'] = defaultRandomizerOptions.species['Mythos + Animals'] + "%Human*1240";
    defaultRandomizerOptions.species['50% Human | 50% Mythos + Animals'] = defaultRandomizerOptions.species['Mythos + Animals'] + "%Human*3721";
    defaultRandomizerOptions.species['75% Human | 25% Mythos + Animals'] = defaultRandomizerOptions.species['Mythos + Animals'] + "%Human*11163";
    defaultRandomizerOptions.species['25% Human | 75% Pokemon'] = defaultRandomizerOptions.species.Pokemon + "%Human*512";
    defaultRandomizerOptions.species['50% Human | 50% Pokemon'] = defaultRandomizerOptions.species.Pokemon + "%Human*1024";
    defaultRandomizerOptions.species['75% Human | 25% Pokemon'] = defaultRandomizerOptions.species.Pokemon + "%Human*3072";
    defaultRandomizerOptions.species['25% Human | 75% Digimon'] = defaultRandomizerOptions.species.Digimon + "%Human*614";
    defaultRandomizerOptions.species['50% Human | 50% Digimon'] = defaultRandomizerOptions.species.Digimon + "%Human*1227";
    defaultRandomizerOptions.species['75% Human | 25% Digimon'] = defaultRandomizerOptions.species.Digimon + "%Human*3681";
    defaultRandomizerOptions.species['Pokemon + Digimon'] = defaultRandomizerOptions.species.Pokemon + "," + defaultRandomizerOptions.species.Digimon;
    defaultRandomizerOptions.species['25% Human | 75% Pokemon + Digimon'] = defaultRandomizerOptions.species['Pokemon + Digimon'] + "%Human*1126";
    defaultRandomizerOptions.species['50% Human | 50% Pokemon + Digimon'] = defaultRandomizerOptions.species['Pokemon + Digimon'] + "%Human*2251";
    defaultRandomizerOptions.species['75% Human | 25% Pokemon + Digimon'] = defaultRandomizerOptions.species['Pokemon + Digimon'] + "%Human*6753";
    defaultRandomizerOptions.species.Chaos = defaultRandomizerOptions.species.Realistic + "%" + defaultRandomizerOptions.species.Animals + "%" + defaultRandomizerOptions.species.Mythological + "%" + defaultRandomizerOptions.species.Pokemon + "%" + defaultRandomizerOptions.species.Digimon + "%" + defaultRandomizerOptions.species.Fantasy + "%" + defaultRandomizerOptions.species["Sci-fi"];

    // User's randomizer settings
    const randomizerSettings = {
        emoji: {
            selectedOption: 'Smileys',
            customList: ''
        },
        name: {
            selectedOption: 'Common',
            customList: ''
        },
        sex: {
            selectedOption: 'Standard',
            customList: ''
        },
        species: {
            selectedOption: 'Realistic',
            customList: ''
        },
        age: {
            selectedOption: 'Adult',
            customList: ''
        },
        bodyType: {
            selectedOption: 'All',
            customList: ''
        },
        personality: {
            selectedOption: 'All',
            customList: ''
        },
        bio: {
            selectedOption: 'Standard',
            customList: ''
        },
    };

    // Function to generate a random character
    function generateRandomCharacter() {
        const character = {};

        // Helper to get pronouns based on sex (male, female, other)
        function getPronouns(sex) {
            const lowerSex = sex.toLowerCase();
            if (lowerSex === 'male') {
                return { subject: 'he', object: 'him', possessive: 'his' };
            } else if (lowerSex === 'female') {
                return { subject: 'she', object: 'her', possessive: 'her' };
            } else {
                return { subject: 'they', object: 'them', possessive: 'their' };
            }
        }

        // Helper to remove comments (>> ... <<) - only for string fields
        function removeComments(text) {
            if (typeof text === 'string') {
                return text.replace(/>>.*?<<\s*/g, '');
            }
            return text; // If it's not a string, just return it unchanged
        }

        // Helper to process sub-lists (&!)
        function processSubLists(items) {
            const mainList = [];
            const subLists = [];

            items.forEach((item, index) => {
                if (index === 0) {
                    // The first item is the main list
                    mainList.push(...item.split(/[%\n]+/).map(i => i.trim()).filter(Boolean));
                } else {
                    // The remaining items are sub-lists, split by commas
                    const subListItems = item.split(/[%\n]+/).map(i => i.trim()).filter(Boolean);
                    subLists.push(subListItems);
                }
            });

            return { mainList, subLists };
        }

        // Process weighting for string items with a "*n" suffix
        function weightItems(list) {
            return list.map(item => {
                if (typeof item === 'string') {
                    const match = item.match(/^(.*)\*(\d+)$/);
                    if (match) {
                        return { value: match[1].trim(), weight: parseInt(match[2], 10) };
                    }
                    return { value: item.trim(), weight: 1 };
                }
                return { value: item, weight: 1 }; // For non-string items (e.g., age), no trimming
            });
        }

        // Function to get random item based on weighted random
        function getRandomFromWeightedList(list) {
            const totalWeight = list.reduce((sum, item) => sum + item.weight, 0);
            let random = Math.random() * totalWeight;
            for (const item of list) {
                if (random < item.weight) {
                    return item.value;
                }
                random -= item.weight;
            }
            return ''; // Fallback
        }

       // Function to handle recursive sub-list resolution and replace tokens
       function resolveSubListReferences(text, subLists, character, recursionDepth = 0) {
            const MAX_RECURSION_DEPTH = 10; // Prevent infinite recursion
            if (recursionDepth > MAX_RECURSION_DEPTH) {
                console.warn('Maximum recursion depth reached while resolving sub-lists.');
                return text;
            }

            // Replace sub-list references like &?n with a random item from sub-list n
            let resolvedText = text.replace(/&\?(\d+)/g, (match, listIndex) => {
                const index = parseInt(listIndex, 10);
                if (subLists[index] && subLists[index].length > 0) {
                    const subList = subLists[index];
                    const randomSubItem = getRandomFromWeightedList(weightItems(subList));
                    // Recursively resolve any sub-list references within the chosen sub-list item
                    return resolveSubListReferences(randomSubItem, subLists, character, recursionDepth + 1);
                }
                return ''; // If sub-list doesn't exist or is empty, return empty string
            });

            // After resolving sub-list references, replace tokens like #?a, #?b, etc.
            const pronouns = getPronouns(character.sex || '');
            resolvedText = resolvedText.replace(/#\?a/g, character.name || '')
                .replace(/#\?b/g, pronouns.subject)
                .replace(/#\?c/g, pronouns.object)
                .replace(/#\?d/g, pronouns.possessive);

            return resolvedText;
        }

        // In the `getRandomItem` function, update where `resolveSubListReferences` is called:
        function getRandomItem(field) {
            let items = [];
            if (randomizerSettings[field].customList.trim() !== '') {
                // Use custom list
                items = randomizerSettings[field].customList
                    .split(/[,\n]+/)
                    .map(item => item.trim())
                    .filter(item => item !== '');
            } else {
                // Use default list
                const selectedOption = randomizerSettings[field].selectedOption;
                items = defaultRandomizerOptions[field][selectedOption]
                    .split(/[,\n]+/)
                    .map(item => item.trim())
                    .filter(item => item !== '');
            }

            // Handle cases where items might be undefined or empty
            if (!items || items.length === 0) {
                return '';
            }

            // Remove comments (only applies to string fields)
            items = items.map(removeComments);

            // First, process the entire string before splitting by commas or newlines
            const inputString = items.join(',');

            // Split the input string on "&!" to separate sub-lists from the main text
            const mainTextAndSubLists = inputString.split('&!');

            // The main text is everything before the first "&!"
            const mainListString = mainTextAndSubLists.shift(); // Get the main text
            const subListStrings = mainTextAndSubLists; // Remaining parts are sub-lists

            // Now process the main list and any sub-lists
            const { mainList, subLists } = processSubLists([mainListString, ...subListStrings]);

            // Get the random item from the main list
            let result = getRandomFromWeightedList(weightItems(mainList));

            // If the field is 'bio', handle dynamic text insertion (e.g., pronouns, names)
            if (field === 'bio' && typeof result === 'string') {
                // Resolve sub-list references and replace tokens for bio
                result = resolveSubListReferences(result, subLists, character);
            } else {
                // For non-bio fields, resolve sub-list references if they exist
                result = resolveSubListReferences(result, subLists, character);
            }

            // For age, convert to numbers
            if (field === 'age') {
                result = parseInt(result, 10);
            }
            return result;
        }

        // Generate character fields
        character.emoji = getRandomItem('emoji');
        character.name = getRandomItem('name');
        character.sex = getRandomItem('sex');
        character.species = getRandomItem('species');
        character.age = getRandomItem('age');
        character.bodyType = getRandomItem('bodyType');
        character.personality = getRandomItem('personality');
        character.bio = getRandomItem('bio');

        return character;
    }

    // Function to capitalize first letter
    function capitalizeFirstLetter(string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
    }

    // Function to open Randomizer Settings dialog
    function openRandomizerSettings() {
        const settingsForm = document.createElement('form');
        console.log(settingsForm);
        settingsForm.innerHTML = `
        <div style="display: flex; flex-direction: column; width: 100%; min-width: 500px; margin: 0 auto;">
            <!-- Scrollable content container -->
            <div class="scrollable-content" style="flex: 1; overflow-y: auto; max-height: 300px; padding-right: 10px;">
                <!-- Fields will be inserted here dynamically -->
            </div>
            <!-- Buttons at the bottom -->
            <div class="settings-buttons" style="text-align: center; padding-top: 10px;">
                <button type="submit" style="background-color: var(--button-bg-color); color: var(--text-color); border: none; padding: 8px 16px; border-radius: 5px; margin-right: 10px; cursor: pointer;">Save Settings</button>
                <button type="button" style="background-color: var(--button-bg-color); color: var(--text-color); border: none; padding: 8px 16px; border-radius: 5px; cursor: pointer;" id="cancel-button">Cancel</button>
            </div>
        </div>
    `;

        const fieldsContainer = settingsForm.querySelector('.scrollable-content');
        // For each randomizable field, create settings UI
        const fields = ['emoji', 'name', 'sex', 'species', 'age', 'bodyType', 'personality', 'bio'];
        fields.forEach(field => {
            const fieldDiv = document.createElement('div');
            fieldDiv.style.marginBottom = '10px';

            const label = document.createElement('label');
            label.style.color = 'var(--text-color)';
            label.style.fontSize = '12px';
            label.textContent = `Randomizer for ${capitalizeFirstLetter(field)}:`;

            // Dropdown for default options
            const select = document.createElement('select');
            select.name = field;
            select.style.cssText = 'background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding:5px; width: 100%; box-sizing: border-box;';
            // Populate options
            const options = defaultRandomizerOptions[field];
            for (const optionName in options) {
                const option = document.createElement('option');
                option.value = optionName;
                option.textContent = optionName;
                if (randomizerSettings[field].selectedOption === optionName && !randomizerSettings[field].customList.trim()) {
                    option.selected = true;
                }
                select.appendChild(option);
            }

            // Custom list textarea
            const textarea = document.createElement('textarea');
            textarea.name = field + '_custom';
            textarea.rows = field != 'bio' ? 2 : 4;
            textarea.placeholder = 'Enter custom list, separated by "%" or new lines.';
            textarea.style.cssText = 'background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding:5px; width: 100%; box-sizing: border-box; margin-top: 5px;';
            textarea.value = randomizerSettings[field].customList;

            // If custom list is non-empty, disable the select
            if (randomizerSettings[field].customList.trim() !== '') {
                select.disabled = true;
            }

            // Event listener to disable select if textarea has content
            textarea.addEventListener('input', (e) => {
                if (textarea.value.trim() !== '') {
                    select.disabled = true;
                } else {
                    select.disabled = false;
                }
            });

            fieldDiv.appendChild(label);
            fieldDiv.appendChild(select);
            fieldDiv.appendChild(textarea);
            fieldsContainer.appendChild(fieldDiv);
        });

        const helpLabel = document.createElement('label');
        helpLabel.style.color = 'var(--text-color)';
        helpLabel.style.fontSize = '18px';
        helpLabel.textContent = `Text codes for advanced list creation;`;
        fieldsContainer.appendChild(helpLabel);

        // Create a paragraph element for the help text
        const helpText = document.createElement('p');

        // Apply styling to the paragraph element
        helpText.style.color = 'var(--text-color)';
        helpText.style.fontSize = '12px';

        // Set the content of the help text
        helpText.innerHTML = `
  <em>"%" marks the end of an item.<br>
  "*n" Multiply the odds an item is chosen.<br>
  "&!" Create a new sub list, index is assigned by order.<br>
  "&?n" Get a random item from a sublist.<br>
  "#?a" Get Character name (bio only)<br>
  "#?b" Get character pronoun like "he" (bio only)<br>
  "#?c" Get character pronoun like "him" (bio only)<br>
  "#?d" Get character pronoun like "his" (bio only)<br>
  ">>" Comment start.<br>
  "<<" Comment end.<br></em>
`;

        // Append the paragraph to the container
        fieldsContainer.appendChild(helpText);

        const cancelButton = settingsForm.querySelector('#cancel-button');
        cancelButton.addEventListener('click', () => {
            closeModal(settingsModal);
        });

        const settingsModal = createModal('Randomizer Settings', settingsForm);
        settingsForm.addEventListener('submit', (e) => {
            e.preventDefault();
            // Update randomizerSettings
            fields.forEach(field => {
                const select = settingsForm[field];
                const textarea = settingsForm[field + '_custom'];
                randomizerSettings[field].customList = textarea.value.trim();
                if (randomizerSettings[field].customList !== '') {
                    randomizerSettings[field].selectedOption = '';
                } else {
                    randomizerSettings[field].selectedOption = select.value;
                }
            });
            closeModal(settingsModal);
        });

        settingsForm.parentNode.style.backgroundColor = 'var(--bg-color-full)';
    }

    // Function to edit a character
    function editCharacter(character) {
        const lockState = {
            emoji: false,
            name: false,
            sex: false,
            species: false,
            age: false,
            bodyType: false,
            personality: false,
            bio: false
        };

        const editForm = document.createElement('form');
        editForm.innerHTML = `
<div style="width: 100%; min-width: 500px; margin: 0 auto; position: relative;">
    ${createField('Emoji', 'emoji', character.emoji)}
    ${createAvatarField('Avatar', 'avatar', character.avatar)}
    ${createField('Name', 'name', character.name)}
    ${createSexDropdown('Sex', 'sex', character.sex)}
    ${createField('Species', 'species', character.species)}
    ${createField('Age', 'age', character.age)}
    ${createField('Body Type', 'bodyType', character.bodyType)}
    ${createField('Personality', 'personality', character.personality)}
    ${createTextareaField('Bio', 'bio', character.bio)}
    <label style="color: var(--text-color); font-size: 12px; margin-bottom: 8px; display: block;">Character Type:
        <select name="characterType" style="background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding: 5px; width: 100%; box-sizing: border-box;">
            <option value="0" ${character.characterType === 0 ? 'selected' : ''}>Non-User</option>
            <option value="1" ${character.characterType === 1 ? 'selected' : ''}>User</option>
            <option value="2" ${character.characterType === 2 ? 'selected' : ''}>Collection</option>
        </select>
    </label>
    <button type="submit" style="background-color: var(--button-bg-color); color: var(--text-color); border: none; padding: 5px; border-radius: 5px; width: 100%; text-align: center; margin-top: 10px;">Save</button>
</div>
`;

        // Helper functions to create fields
        function createField(labelText, fieldName, value) {
            return `
    <label style="color: var(--text-color); font-size: 12px; margin-bottom: 8px; display: block;">
        ${labelText}:
        <div style="position: relative;">
            <input type="text" name="${fieldName}" value="${value}" autocomplete="off" style="background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding: 5px; width: calc(100% - 35px); box-sizing: border-box;"/>
            <button type="button" class="lock-button" data-field="${fieldName}" style="position: absolute; right: 0; top: 0; height: 100%; width: 35px; background-color: var(--button-bg-color); border: 1px solid var(--border-color); border-radius: 5px; cursor: pointer; color: var(--text-color);">${lockState[fieldName] ? '🔒' : '🔓'}</button>
        </div>
    </label>
    `;
        }

        function createAvatarField(labelText, fieldName, value) {
            return `
    <label style="color: var(--text-color); font-size: 12px; margin-bottom: 8px; display: block;">
        ${labelText}:
        <div style="position: relative;">
            <input type="text" name="${fieldName}" value="${value}" autocomplete="off" style="background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding: 5px; width: calc(100% - 35px); box-sizing: border-box;" />
            <button type="button" class="open-avatar-button" data-field="${fieldName}" style="position: absolute; right: 0; top: 0; height: 100%; width: 35px; background-color: var(--button-bg-color); border: 1px solid var(--border-color); border-radius: 5px; cursor: pointer; color: var(--text-color);">🔗</button>
        </div>
    </label>
    `;
        }

        function createSexDropdown(labelText, fieldName, value) {
            return `
    <label style="color: var(--text-color); font-size: 12px; margin-bottom: 8px; display: block;">
        ${labelText}:
        <div style="position: relative;">
            <select name="${fieldName}" style="background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding: 5px; width: calc(100% - 35px); box-sizing: border-box;">
                <option value="male" ${value === 'male' ? 'selected' : ''}>Male</option>
                <option value="female" ${value === 'female' ? 'selected' : ''}>Female</option>
                <option value="other" ${value === 'other' ? 'selected' : ''}>Other</option>
            </select>
            <button type="button" class="lock-button" data-field="${fieldName}" style="position: absolute; right: 0; top: 0; height: 100%; width: 35px; background-color: var(--button-bg-color); border: 1px solid var(--border-color); border-radius: 5px; cursor: pointer; color: var(--text-color);">${lockState[fieldName] ? '🔒' : '🔓'}</button>
        </div>
    </label>
    `;
        }

        function createTextareaField(labelText, fieldName, value) {
            return `
    <label style="color: var(--text-color); font-size: 12px; margin-bottom: 8px; display: block;">
        ${labelText}:
        <div style="position: relative;">
            <textarea name="${fieldName}" autocomplete="off" rows="4" style="background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding: 5px; width: calc(100% - 35px); box-sizing: border-box;">${value}</textarea>
            <button type="button" class="lock-button" data-field="${fieldName}" style="position: absolute; right: 0; top: 0; height: 100%; width: 35px; background-color: var(--button-bg-color); border: 1px solid var(--border-color); border-radius: 5px; cursor: pointer; color: var(--text-color);">${lockState[fieldName] ? '🔒' : '🔓'}</button>
        </div>
    </label>
    `;
        }

        // Copy Tooltip button
        const copyButton = document.createElement('button');
        copyButton.textContent = '📋';
        copyButton.title = 'Copy Tooltip';
        copyButton.type = 'button'; // Prevent form submission
        copyButton.style.cssText = `
    position: absolute;
    top: 15px;
    right: 50px;
    background: none;
    border: none;
    font-size: 20px;
    cursor: pointer;
    color: var(--text-color);
    `;
        copyButton.addEventListener('click', () => {
            const tooltipContent = getCharacterTooltipContent(character);
            const textWithNewlines = tooltipContent.replace(/<br\s*\/?>/gi, '\n').replace(/<[^>]*>/g, '');
            navigator.clipboard.writeText(textWithNewlines);
        });
        editForm.appendChild(copyButton);

        // Randomize button
        const randomizeButton = document.createElement('button');
        randomizeButton.textContent = '🎲';
        randomizeButton.title = 'Randomize';
        randomizeButton.type = 'button'; // Prevent form submission
        randomizeButton.style.cssText = `
    position: absolute;
    top: 15px;
    right: 90px;
    background: none;
    border: none;
    font-size: 20px;
    cursor: pointer;
    color: var(--text-color);
    `;
        randomizeButton.addEventListener('click', () => {
            const randomCharacter = generateRandomCharacter();
            const fields = ['emoji', 'name', 'sex', 'species', 'age', 'bodyType', 'personality', 'bio'];
            fields.forEach((field) => {
                if (!lockState[field]) {
                    editForm[field].value = randomCharacter[field];
                }
            });
        });
        editForm.appendChild(randomizeButton);

        // Settings button
        const settingsButton = document.createElement('button');
        settingsButton.textContent = '⚙️';
        settingsButton.title = 'Randomizer Settings';
        settingsButton.type = 'button'; // Prevent form submission
        settingsButton.style.cssText = `
    position: absolute;
    top: 15px;
    right: 130px;
    background: none;
    border: none;
    font-size: 20px;
    cursor: pointer;
    color: var(--text-color);
    `;
        settingsButton.addEventListener('click', () => {
            openRandomizerSettings();
        });
        editForm.appendChild(settingsButton);

        // Append the form to a modal or the desired container
        const modal = createModal('Edit Character', editForm);

        // Lock button functionality
        const lockButtons = editForm.querySelectorAll('.lock-button');
        lockButtons.forEach((button) => {
            const fieldName = button.getAttribute('data-field');
            button.addEventListener('click', () => {
                lockState[fieldName] = !lockState[fieldName];
                // Update button icon based on state
                button.textContent = lockState[fieldName] ? '🔒' : '🔓';
            });
        });

        // Open Avatar button functionality
        const avatarButton = editForm.querySelector('.open-avatar-button');
        avatarButton.addEventListener('click', () => {
            const avatarUrl = editForm.avatar.value;
            if (isValidImageUrl(avatarUrl)) {
                window.open(avatarUrl, '_blank');
            } else {
                alert('Invalid image URL');
            }
        });

        editForm.addEventListener('submit', (e) => {
            e.preventDefault();
            character.emoji = editForm.emoji.value;
            character.avatar = editForm.avatar.value;
            character.name = editForm.name.value;
            character.sex = editForm.sex.value;
            character.species = editForm.species.value;
            character.age = editForm.age.value;
            character.bodyType = editForm.bodyType.value;
            character.personality = editForm.personality.value;
            character.bio = editForm.bio.value;
            character.characterType = parseInt(editForm.characterType.value, 10);
            renderCharacterGroups();
            closeModal(modal);
        });
    }

    // Function to delete a character
    function deleteCharacter(characterId) {
        if (confirm('Are you sure you want to delete this character?')) {
            characterGroups.forEach(group => {
                group.items = deleteCharacterRecursive(group.items, characterId);
            });
            renderCharacterGroups();
        }
    }

    function deleteCharacterRecursive(items, characterId) {
        return items.filter(item => {
            if (item.id === characterId) {
                return false;
            }
            if (item.children && item.children.length > 0) {
                item.children = deleteCharacterRecursive(item.children, characterId);
            }
            return true;
        });
    }

    // Function to export all characters with groups
    function exportCharacters() {
        const data = {
            characterGroups: characterGroups,
            settings: { c_radius, c_labelFontSize } // Save current settings
        };
        const json = JSON.stringify(data, null, 2);
        const blob = new Blob([json], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `all_characters_with_groups.json`;
        link.click();
    }

    // Function to import characters with settings
    function importCharacters() {
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = '.json';
        fileInput.addEventListener('change', async (event) => {
            const file = event.target.files[0];
            const reader = new FileReader();
            reader.onload = (e) => {
                try {
                    const importedData = JSON.parse(e.target.result);
                    if (Array.isArray(importedData)) {
                        // Old format
                        characterGroups = importedData;
                        renderCharacterGroups();
                    } else if (importedData.characterGroups) {
                        characterGroups = importedData.characterGroups;

                        // Load settings
                        if (importedData.settings) {
                            // Assign settings
                            c_radius = importedData.settings.c_radius || c_radius;
                            c_labelFontSize = importedData.settings.c_labelFontSize || c_labelFontSize;
                        }

                        renderCharacterGroups();
                    } else {
                        alert('Invalid format for characters import.');
                    }
                } catch (error) {
                    alert('Failed to import characters: ' + error.message);
                }
            };
            reader.readAsText(file);
        });
        fileInput.click();
    }

    // Function to export a single character
    function exportCharacter(character) {
        const json = JSON.stringify(character, null, 2);
        const blob = new Blob([json], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `${character.name}.json`;
        link.click();
    }

    // Function to move character to a group (uncoupling from parent)
    function moveCharacterToGroup(characterId, targetGroupIndex) {
        let character = null;
        // Remove character from current group or parent
        characterGroups.forEach(group => {
            group.items = removeCharacterRecursive(group.items, characterId, (item) => {
                character = item;
            });
        });
        // Add to target group
        if (character) {
            characterGroups[targetGroupIndex].items.push(character);
            renderCharacterGroups();
        }
    }

    function removeCharacterRecursive(items, characterId, callback) {
        return items.filter(item => {
            if (item.id === characterId) {
                callback(item);
                return false;
            }
            if (item.children && item.children.length > 0) {
                item.children = removeCharacterRecursive(item.children, characterId, callback);
            }
            return true;
        });
    }

    // Function to move character under another character (nesting)
    function moveCharacterToParent(characterId, parentCharacter) {
        let character = null;
        // Remove character from current group or parent
        characterGroups.forEach(group => {
            group.items = removeCharacterRecursive(group.items, characterId, (item) => {
                character = item;
            });
        });
        if (character) {
            parentCharacter.children.push(character);
            renderCharacterGroups();
        }
    }

    // Utility function to generate unique IDs
    function generateId() {
        return '_' + Math.random().toString(36).substr(2, 9);
    }

    // --- Location Sidebar with Groups and Nested Locations ---
    const locationSidebar = document.createElement('div');
    locationSidebar.id = 'location-sheet-sidebar';
    locationSidebar.style.cssText = `
        position: fixed;
        top: 0;
        left: -350px;
        width: 350px;
        height: 100%;
        display: flex;
        flex-direction: column;
        background-color: var(--bg-color);
        border-right: 2px solid var(--border-color);
        box-shadow: 2px 0 5px var(--shadow-color);
        box-sizing: border-box;
        transition: left 0.3s;
        z-index: 9999;
    `;
    document.body.appendChild(locationSidebar);

    const locationToggleButton = document.createElement('button');
    locationToggleButton.textContent = '☰';
    locationToggleButton.style.cssText = `
        position: fixed;
        top: 10px;
        left: 10px;
        padding: 5px 10px;
        border: none;
        background-color: var(--button-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
        transition: left 0.3s;
        z-index: 10000;
    `;
    locationToggleButton.addEventListener('click', () => {
        const isOpen = locationSidebar.style.left === '0px';
        locationSidebar.style.left = isOpen ? '-350px' : '0';
        locationToggleButton.style.left = isOpen ? '10px' : '360px';
    });
    document.body.appendChild(locationToggleButton);

    const locationHeader = document.createElement('div');
    locationHeader.style.cssText = `
        padding: 10px;
        background-color: var(--border-color);
        text-align: center;
        font-weight: bold;
        color: var(--text-color);
    `;
    locationHeader.textContent = 'Locations';
    locationSidebar.appendChild(locationHeader);

    const locationButtonBox = document.createElement('div');
    locationButtonBox.style.cssText = `
        display: flex;
        justify-content: space-between;
        padding: 10px;
        background-color: var(--bg-color);
        flex-shrink: 0;
    `;
    locationSidebar.appendChild(locationButtonBox);

    // New Location Button
    const newLocationButton = document.createElement('button');
    newLocationButton.textContent = 'New';
    newLocationButton.title = 'Create New Location';
    newLocationButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--success-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    newLocationButton.addEventListener('click', () => {
        createNewLocation();
    });
    locationButtonBox.appendChild(newLocationButton);

    // Load Location Button
    const loadLocationButton = document.createElement('button');
    loadLocationButton.textContent = 'Load';
    loadLocationButton.title = 'Load a Location';
    loadLocationButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--info-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    loadLocationButton.addEventListener('click', () => {
        loadLocation();
    });
    locationButtonBox.appendChild(loadLocationButton);

    // Group Location Button
    const groupLocationButton = document.createElement('button');
    groupLocationButton.textContent = 'Group';
    groupLocationButton.title = 'Create New Group';
    groupLocationButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--info-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    groupLocationButton.addEventListener('click', () => {
        createNewLocationGroup();
    });
    locationButtonBox.appendChild(groupLocationButton);

    // Import Location Button
    const importLocationButton = document.createElement('button');
    importLocationButton.textContent = 'Import';
    importLocationButton.title = 'Import Locations';
    importLocationButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--warning-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    importLocationButton.addEventListener('click', () => {
        importLocations();
    });
    locationButtonBox.appendChild(importLocationButton);

    // Export Location Button
    const exportLocationButton = document.createElement('button');
    exportLocationButton.textContent = 'Export';
    exportLocationButton.title = 'Export Locations';
    exportLocationButton.style.cssText = `
        padding: 5px 10px;
        border: none;
        background-color: var(--muted-bg-color);
        color: var(--text-color);
        border-radius: 5px;
        cursor: pointer;
    `;
    exportLocationButton.addEventListener('click', () => {
        exportLocations();
    });
    locationButtonBox.appendChild(exportLocationButton);

    // Add fifth button: "Load" for Location
    function loadLocation() {
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = '.json';
        fileInput.addEventListener('change', async (event) => {
            const file = event.target.files[0];
            const reader = new FileReader();
            reader.onload = (e) => {
                try {
                    const location = JSON.parse(e.target.result);
                    if (location && location.id) {
                        // Add to Ungrouped
                        const ungrouped = locationGroups.find(g => g.name === 'Ungrouped');
                        if (ungrouped) {
                            ungrouped.items.push(location);
                        } else {
                            locationGroups[0].items.push(location);
                        }
                        renderLocationGroups();
                        ensureActiveLocation();
                    } else {
                        alert('Invalid location format.');
                    }
                } catch (error) {
                    alert('Failed to load location: ' + error.message);
                }
            };
            reader.readAsText(file);
        });
        fileInput.click();
    }

    const locationGroupList = document.createElement('div');
    locationGroupList.id = 'location-group-list';
    locationGroupList.style.cssText = `
        flex-grow: 1;
        overflow-y: auto;
        padding: 10px;
    `;
    locationSidebar.appendChild(locationGroupList);

    // Initialize Location Groups with a single default location
    let locationGroups = [
        {
            name: 'Ungrouped',
            items: [
                {
                    id: generateId(),
                    active: true,
                    emoji: '📍',
                    reference: 'Url goes here...',
                    name: 'Default Location',
                    description: 'Description of the default location.',
                    children: [],
                    collapsed: false
                }
            ],
            collapsed: false,

        }
    ];

    // Function to create a new Location
    function createNewLocation() {
        const newLocation = {
            id: generateId(),
            active: false,
            emoji: '📍',
            reference: 'Url Goes here...',
            name: 'New Location',
            description: '',
            children: [],
            collapsed: false
        };
        // Add to Ungrouped
        const ungrouped = locationGroups.find(g => g.name === 'Ungrouped');
        if (ungrouped) {
            ungrouped.items.push(newLocation);
        } else {
            locationGroups[0].items.push(newLocation);
        }
        renderLocationGroups();
        ensureActiveLocation();
    }

    // Function to create a new Location Group
    function createNewLocationGroup() {
        const groupName = prompt('Enter group name:', `Group ${locationGroups.length}`);
        if (groupName && groupName.trim() !== '') {
            locationGroups.push({ name: groupName.trim(), items: [], collapsed: false });
            renderLocationGroups();
        }
    }

    // Function to render Location Groups and Items
    function renderLocationGroups() {
        locationGroupList.innerHTML = '';

        locationGroups.forEach((group, groupIndex) => {
            // Sort items alphabetically by name
            group.items.sort((a, b) => a.name.localeCompare(b.name));

            const groupContainer = document.createElement('div');
            groupContainer.className = 'location-group';
            groupContainer.style.cssText = `
                margin-bottom: 10px;
                border: 1px solid var(--border-color);
                border-radius: 5px;
                background-color: var(--active-char-color);
            `;

            const groupHeader = document.createElement('div');
            groupHeader.style.cssText = `
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 5px 10px;
                background-color: var(--button-bg-color);
                color: var(--text-color);
                cursor: pointer;
                user-select: none;
                position: relative;
            `;
            groupHeader.textContent = group.name;
            groupHeader.addEventListener('click', () => {
                group.collapsed = !group.collapsed;
                renderLocationGroups();
            });

            const groupActions = document.createElement('div');
            groupActions.style.cssText = `
                display: flex;
                align-items: center;
            `;

            // Rename Group Button
            const renameGroupButton = document.createElement('button');
            renameGroupButton.textContent = '✏️';
            renameGroupButton.title = 'Rename Group';
            renameGroupButton.style.cssText = `
                background: none;
                border: none;
                color: var(--text-color);
                cursor: pointer;
                margin-right: 2px;
            `;
            renameGroupButton.addEventListener('click', (e) => {
                e.stopPropagation();
                renameLocationGroup(groupIndex);
            });
            groupActions.appendChild(renameGroupButton);

            // Delete Group Button
            const deleteGroupButton = document.createElement('button');
            deleteGroupButton.textContent = '🗑️';
            deleteGroupButton.title = 'Delete Group';
            deleteGroupButton.style.cssText = `
                background: none;
                border: none;
                color: var(--text-color);
                cursor: pointer;
            `;
            deleteGroupButton.addEventListener('click', (e) => {
                e.stopPropagation();
                deleteLocationGroup(groupIndex);
            });
            groupActions.appendChild(deleteGroupButton);

            groupHeader.appendChild(groupActions);
            groupContainer.appendChild(groupHeader);

            if (!group.collapsed) {
                const itemsContainer = document.createElement('div');
                itemsContainer.style.cssText = `
                    padding: 5px 10px;
                    display: block;
                `;
                if (group.items.length === 0) {
                    const emptyInfo = document.createElement('div');
                    emptyInfo.className = 'location-slot';
                    emptyInfo.style.cssText = `
                        display: flex;
                        align-items: center;
                        padding: 10px;
                        margin-bottom: 5px;
                        border: 1px solid var(--border-color);
                        border-radius: 5px;
                        height: 20px;
                        background-color: var(--bg-color);
                        cursor: default;
                    `;

                    const infoText = document.createElement('span');
                    infoText.textContent = `Group is empty`;
                    infoText.style.cssText = `
                        color: var(--text-color);
                    `;

                    emptyInfo.appendChild(infoText);
                    itemsContainer.appendChild(emptyInfo);
                } else {
                    group.items.forEach((location) => {
                        const locationSlot = createLocationSlot(location, groupIndex);
                        itemsContainer.appendChild(locationSlot);
                    });
                }
                groupContainer.appendChild(itemsContainer);
            } else {
                const collapsedInfo = document.createElement('div');
                collapsedInfo.className = 'location-slot';
                collapsedInfo.style.cssText = `
                    display: flex;
                    align-items: center;
                    padding: 10px;
                    margin-bottom: 10px;
                    border: 1px solid var(--border-color);
                    border-radius: 5px;
                    height: 20px;
                    margin-top: 5px;
                    background-color: var(--bg-color);
                    cursor: default;
                    margin-left: 10px;
                    margin-right: 10px;
                `;
                const infoText = document.createElement('span');
                infoText.textContent = `${group.items.length} items hidden`;

                //lime
                if (findActiveLocation(group.items)) {
                    // All active
                    infoText.style.cssText = `color: rgba(36, 242, 0, 0.75);`;
                } else {
                    // All inactive
                    infoText.style.cssText = `color: var(--text-color-darker);`;
                }

                collapsedInfo.appendChild(infoText);
                groupContainer.appendChild(collapsedInfo);
            }

            // Add dragover and drop events for grouping
            groupContainer.addEventListener('dragover', (e) => {
                e.preventDefault();
                groupContainer.style.border = `2px dashed var(--info-bg-color)`;
            });

            groupContainer.addEventListener('dragleave', (e) => {
                groupContainer.style.border = `1px solid var(--border-color)`;
            });

            groupContainer.addEventListener('drop', (e) => {
                e.preventDefault();
                groupContainer.style.border = `1px solid var(--border-color)`;
                const data = e.dataTransfer.getData('text/plain');
                const { type, id } = JSON.parse(data);
                if (type === 'location') {
                    moveLocationToGroup(id, groupIndex);
                }
            });

            locationGroupList.appendChild(groupContainer);
        });

        // Ensure at least one group exists
        if (locationGroups.length === 0) {
            locationGroups.push({ name: 'Ungrouped', items: [], collapsed: false });
            renderLocationGroups();
        }

        // Ensure at least one location is active
        ensureActiveLocation();
    }

    // Function to generate tooltip content for a location
    function getLocationTooltipContent(location, isRadial = false) {
        if (isRadial && location.emoji === '📁') {
            // If it's a group node in the radial tree, only show the name
            return `<strong>"${location.name}"</strong>`;
        }
        let content = `<strong>"${location.name}"</strong>:<br><em>"${location.description || 'No description available.'}"</em>`;
        return content;
    }

    // Function to create a Location Slot DOM element (recursive)
    function createLocationSlot(location, groupIndex, parent = null, level = 0) {
        const locationSlot = document.createElement('div');
        locationSlot.className = 'location-slot';
        locationSlot.draggable = true;
        locationSlot.dataset.id = location.id;
        locationSlot.style.cssText = `
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 5px;
            margin-bottom: 5px;
            border: 1px solid var(--border-color);
            border-radius: 5px;
            background-color: var(--bg-color);
            cursor: grab;
            margin-left: ${level * 20}px;
        `;

        // Drag events
        locationSlot.addEventListener('dragstart', (e) => {
            e.stopPropagation();
            e.dataTransfer.setData('text/plain', JSON.stringify({ type: 'location', id: location.id }));
            e.currentTarget.style.opacity = '0.5';
        });

        locationSlot.addEventListener('dragend', (e) => {
            e.currentTarget.style.opacity = '1';
        });

        // Click event for collapsing/expanding
        if (location.children && location.children.length > 0) {
            locationSlot.style.cursor = 'pointer';
            locationSlot.addEventListener('click', (e) => {
                e.stopPropagation();
                location.collapsed = !location.collapsed;
                renderLocationGroups();
            });
        }

        // Left Div (Active Toggle, Emoji, Name)
        const leftDiv = document.createElement('div');
        leftDiv.style.cssText = `
            display: flex;
            align-items: center;
            flex-grow: 1;
            overflow: hidden;
        `;

        // Remove Collapse/Expand Button
        // (Not needed as per new requirement)

        const activeButton = document.createElement('button');
        activeButton.textContent = location.active ? '🟢' : '🔴';
        activeButton.title = 'Toggle Active';
        activeButton.style.cssText = `
            padding: 3px;
            border: none;
            background: none;
            cursor: pointer;
            color: var(--text-color);
            margin-right: 5px;
        `;
        activeButton.addEventListener('click', (e) => {
            e.stopPropagation();
            // Since only one active location is allowed, deactivate others
            locationGroups.forEach(group => {
                group.items.forEach(loc => {
                    deactivateLocationRecursive(loc);
                });
            });
            location.active = !location.active;
            renderLocationGroups();
        });
        leftDiv.appendChild(activeButton);

        const emojiSpan = document.createElement('span');
        emojiSpan.textContent = location.emoji;
        emojiSpan.style.marginRight = '5px';
        leftDiv.appendChild(emojiSpan);

        const nameSpan = document.createElement('span');
        nameSpan.textContent = location.name;
        nameSpan.style.cssText = `
            flex-grow: 1;
            min-width: 0;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            color: var(--text-color);
        `;

        // Add tooltip event listeners
        nameSpan.addEventListener('mouseenter', (e) => {
            showTooltip(e, getLocationTooltipContent(location), false, location.reference);
        });
        nameSpan.addEventListener('mouseleave', hideTooltip);
        nameSpan.addEventListener('dragover', hideTooltip);

        leftDiv.appendChild(nameSpan);

        locationSlot.appendChild(leftDiv);

        // Right Div (Edit, Delete, Export)
        const rightDiv = document.createElement('div');
        rightDiv.style.display = 'flex';
        rightDiv.style.alignItems = 'center';

        const editButton = document.createElement('button');
        editButton.textContent = '✏️';
        editButton.title = 'Edit Location';
        editButton.style.cssText = `
            padding: 0px;
            border: none;
            background: none;
            cursor: pointer;
            color: var(--text-color);
            margin-right: 2px;
        `;
        editButton.addEventListener('click', (e) => {
            e.stopPropagation();
            editLocation(location);
        });
        rightDiv.appendChild(editButton);

        const deleteButton = document.createElement('button');
        deleteButton.textContent = '🗑️';
        deleteButton.title = 'Delete Location';
        deleteButton.style.cssText = `
            padding: 0px;
            border: none;
            background: none;
            cursor: pointer;
            color: var(--text-color);
            margin-right: 2px;
        `;
        deleteButton.addEventListener('click', (e) => {
            e.stopPropagation();
            deleteLocation(location.id);
        });
        rightDiv.appendChild(deleteButton);

        const exportButton = document.createElement('button');
        exportButton.textContent = '⬇️';
        exportButton.title = 'Export Location';
        exportButton.style.cssText = `
            padding: 0px;
            border: none;
            background: none;
            cursor: pointer;
            color: var(--text-color);
        `;
        exportButton.addEventListener('click', (e) => {
            e.stopPropagation();
            exportLocation(location);
        });
        rightDiv.appendChild(exportButton);

        locationSlot.appendChild(rightDiv);

        // Dragover and Drop events
        locationSlot.addEventListener('dragover', (e) => {
            e.preventDefault();
            e.stopPropagation();
            locationSlot.style.border = `2px dashed var(--info-bg-color)`;
        });

        locationSlot.addEventListener('dragleave', (e) => {
            locationSlot.style.border = `1px solid var(--border-color)`;
        });

        locationSlot.addEventListener('drop', (e) => {
            e.preventDefault();
            e.stopPropagation();
            locationSlot.style.border = `1px solid var(--border-color)`;
            const data = e.dataTransfer.getData('text/plain');
            const { type, id } = JSON.parse(data);
            if (type === 'location' && id !== location.id) {
                moveLocationToParent(id, location);
            }
        });

        // Prevent click on buttons from triggering slot collapse/expand
        activeButton.addEventListener('click', (e) => e.stopPropagation());
        editButton.addEventListener('click', (e) => e.stopPropagation());
        deleteButton.addEventListener('click', (e) => e.stopPropagation());
        exportButton.addEventListener('click', (e) => e.stopPropagation());

        // Recursive rendering of children
        const container = document.createElement('div');
        container.appendChild(locationSlot);

        if (location.children && location.children.length > 0) {
            if (!location.collapsed) {
                location.children.forEach(child => {
                    const childSlot = createLocationSlot(child, groupIndex, location, level + 1);
                    container.appendChild(childSlot);
                });
            } else {
                const collapsedInfo = document.createElement('div');
                collapsedInfo.className = 'location-slot';
                collapsedInfo.style.cssText = `
                    display: flex;
                    align-items: center;
                    padding: 10px;
                    margin-bottom: 5px;
                    border: 1px solid var(--border-color);
                    border-radius: 5px;
                    background-color: var(--bg-color);
                    height: 20px;
                    cursor: default;
                    margin-left: ${(level + 1) * 20}px;
                `;

                const infoText = document.createElement('span');
                infoText.textContent = `${location.children.length} items hidden`;

                //lime
                if (findActiveLocation(location.children)) {
                    // All active
                    infoText.style.cssText = `color: rgba(36, 242, 0, 0.75);`;
                } else {
                    // All inactive
                    infoText.style.cssText = `color: var(--text-color-darker);`;
                }

                collapsedInfo.appendChild(infoText);
                container.appendChild(collapsedInfo);
            }
        }

        return container;
    }

    function deactivateLocationRecursive(location) {
        location.active = false;
        if (location.children && location.children.length > 0) {
            location.children.forEach(child => {
                deactivateLocationRecursive(child);
            });
        }
    }

    // Function to rename a location group
    function renameLocationGroup(groupIndex) {
        const newName = prompt('Enter new group name:', locationGroups[groupIndex].name);
        if (newName && newName.trim() !== '') {
            locationGroups[groupIndex].name = newName.trim();
            renderLocationGroups();
        }
    }

    // Function to delete a location group
    function deleteLocationGroup(groupIndex) {
        if (locationGroups.length === 1) {
            alert('At least one group must exist.');
            return;
        }
        if (confirm(`Are you sure you want to delete the group "${locationGroups[groupIndex].name}"? All locations in this group will be moved to "Ungrouped".`)) {
            const group = locationGroups.splice(groupIndex, 1)[0];
            const ungrouped = locationGroups.find(g => g.name === 'Ungrouped');
            if (ungrouped) {
                ungrouped.items = ungrouped.items.concat(group.items);
            } else {
                locationGroups.unshift({ name: 'Ungrouped', items: group.items, collapsed: false });
            }
            renderLocationGroups();
        }
    }

    // Default randomizer options for locations
    const defaultRandomizerOptionsAlt = {
        emoji: {
            'Buildings': "🏠%🏡%🏫%🏭%🏢%🏰%🏩",
            'Nature': "🌲%🌳%🌴%🌵%🌾%🌊%🌋",
            // Add more categories if needed
        },
        name: {
            'Common': "Park%Museum%Library%Coffee Shop%Restaurant%Beach%Mountain%Lake%Forest%City",
            'Fantasy': "Dragon’s Lair%Enchanted Forest%Mystic Mountain%Crystal Lake%Forbidden City",
            // Add more categories if needed
        },
        description: {
            'Standard': "A beautiful place to visit.%Known for its stunning views.%A popular spot among locals.%Rich in history and culture.%Famous for its delicious cuisine.%Home to many rare species.%A tranquil escape from the city.%A bustling hub of activity.%A hidden gem waiting to be explored.%An iconic landmark.",
            // Add more categories if needed
        },
    };

    // User's randomizer settings for locations
    const randomizerSettingsAlt = {
        emoji: {
            selectedOption: 'Buildings',
            customList: ''
        },
        name: {
            selectedOption: 'Common',
            customList: ''
        },
        description: {
            selectedOption: 'Standard',
            customList: ''
        },
    };

    // Function to generate a random location
    function generateRandomLocationAlt() {
        const location = {};

        // Helper to remove comments (>> ... <<) - only for string fields
        function removeComments(text) {
            if (typeof text === 'string') {
                return text.replace(/>>.*?<<\s*/g, '');
            }
            return text; // If it's not a string, just return it unchanged
        }

        // Helper to process sub-lists (&!)
        function processSubLists(items) {
            const mainList = [];
            const subLists = [];

            items.forEach((item, index) => {
                if (index === 0) {
                    // The first item is the main list
                    mainList.push(...item.split(/[%\n]+/).map(i => i.trim()).filter(Boolean));
                } else {
                    // The remaining items are sub-lists, split by commas
                    const subListItems = item.split(/[%\n]+/).map(i => i.trim()).filter(Boolean);
                    subLists.push(subListItems);
                }
            });

            return { mainList, subLists };
        }

        // Process weighting for string items with a "*n" suffix
        function weightItems(list) {
            return list.map(item => {
                if (typeof item === 'string') {
                    const match = item.match(/^(.*)\*(\d+)$/);
                    if (match) {
                        return { value: match[1].trim(), weight: parseInt(match[2], 10) };
                    }
                    return { value: item.trim(), weight: 1 };
                }
                return { value: item, weight: 1 }; // For non-string items (e.g., age), no trimming
            });
        }

        // Function to get random item based on weighted random
        function getRandomFromWeightedList(list) {
            const totalWeight = list.reduce((sum, item) => sum + item.weight, 0);
            let random = Math.random() * totalWeight;
            for (const item of list) {
                if (random < item.weight) {
                    return item.value;
                }
                random -= item.weight;
            }
            return ''; // Fallback
        }

        // Function to handle recursive sub-list resolution and replace tokens
        function resolveSubListReferences(text, subLists, location, recursionDepth = 0) {
            const MAX_RECURSION_DEPTH = 10; // Prevent infinite recursion
            if (recursionDepth > MAX_RECURSION_DEPTH) {
                console.warn('Maximum recursion depth reached while resolving sub-lists.');
                return text;
            }

            // Replace sub-list references like &?n with a random item from sub-list n
            let resolvedText = text.replace(/&\?(\d+)/g, (match, listIndex) => {
                const index = parseInt(listIndex, 10);
                if (subLists[index] && subLists[index].length > 0) {
                    const subList = subLists[index];
                    const randomSubItem = getRandomFromWeightedList(weightItems(subList));
                    // Recursively resolve any sub-list references within the chosen sub-list item
                    return resolveSubListReferences(randomSubItem, subLists, location, recursionDepth + 1);
                }
                return ''; // If sub-list doesn't exist, return empty string
            });

            // After resolving sub-list references, replace tokens like #?a, #?b, etc.
            // In this case, we only use #?a for the location name, but you can extend this
            resolvedText = resolvedText.replace(/#\?a/g, location.name || '');

            return resolvedText;
        }

        // Function to get a random item from a list, including handling sub-lists and weighting
        function getRandomItem(field) {
            let items = [];
            if (randomizerSettingsAlt[field].customList.trim() !== '') {
                // Use custom list
                items = randomizerSettingsAlt[field].customList
                    .split(/[,\n]+/)
                    .map(item => item.trim())
                    .filter(item => item !== '');
            } else {
                // Use default list
                const selectedOption = randomizerSettingsAlt[field].selectedOption;
                items = defaultRandomizerOptionsAlt[field][selectedOption]
                    .split(/[,\n]+/)
                    .map(item => item.trim())
                    .filter(item => item !== '');
            }

            // Handle cases where items might be undefined or empty
            if (!items || items.length === 0) {
                return '';
            }

            // Remove comments (only applies to string fields)
            items = items.map(removeComments);

            // First, process the entire string before splitting by commas or newlines
            const inputString = items.join(',');

            // Split the input string on "&!" to separate sub-lists from the main text
            const mainTextAndSubLists = inputString.split('&!');

            // The main text is everything before the first "&!"
            const mainListString = mainTextAndSubLists.shift(); // Get the main text
            const subListStrings = mainTextAndSubLists; // Remaining parts are sub-lists

            // Now process the main list and any sub-lists
            const { mainList, subLists } = processSubLists([mainListString, ...subListStrings]);

            // Get the random item from the main list
            let result = getRandomFromWeightedList(weightItems(mainList));

            // If the field is 'description', handle dynamic text insertion (e.g., location name)
            if (field === 'description' && typeof result === 'string') {
                // Resolve sub-list references and replace tokens for the description
                result = resolveSubListReferences(result, subLists, location);
            } else {
                // For non-description fields, resolve sub-list references if they exist
                result = resolveSubListReferences(result, subLists, location);
            }

            return result;
        }

        // Generate location fields
        location.emoji = getRandomItem('emoji');
        location.name = getRandomItem('name');
        location.description = getRandomItem('description');

        return location;
    }

    // Function to open Randomizer Settings dialog for locations
    function openRandomizerSettingsAlt() {
        const settingsForm = document.createElement('form');
        settingsForm.innerHTML = `
    <div style="display: flex; flex-direction: column; width: 100%; min-width: 500px; margin: 0 auto;">
        <!-- Scrollable content container -->
        <div class="scrollable-content" style="flex: 1; overflow-y: auto; max-height: 300px; padding-right: 10px;">
            <!-- Fields will be inserted here dynamically -->
        </div>
        <!-- Buttons at the bottom -->
        <div class="settings-buttons" style="text-align: center; padding-top: 10px;">
            <button type="submit" style="background-color: var(--button-bg-color); color: var(--text-color); border: none; padding: 8px 16px; border-radius: 5px; margin-right: 10px; cursor: pointer;">Save Settings</button>
            <button type="button" style="background-color: var(--button-bg-color); color: var(--text-color); border: none; padding: 8px 16px; border-radius: 5px; cursor: pointer;" id="cancel-button-alt">Cancel</button>
        </div>
    </div>
    `;

        const fieldsContainer = settingsForm.querySelector('.scrollable-content');

        // For each randomizable field, create settings UI
        const fields = ['emoji', 'name', 'description'];
        fields.forEach(field => {
            const fieldDiv = document.createElement('div');
            fieldDiv.style.marginBottom = '10px';

            const label = document.createElement('label');
            label.style.color = 'var(--text-color)';
            label.style.fontSize = '12px';
            label.textContent = `Randomizer for ${capitalizeFirstLetter(field)}:`;

            // Dropdown for default options
            const select = document.createElement('select');
            select.name = field;
            select.style.cssText = 'background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding:5px; width: 100%; box-sizing: border-box;';
            // Populate options
            const options = defaultRandomizerOptionsAlt[field];
            for (const optionName in options) {
                const option = document.createElement('option');
                option.value = optionName;
                option.textContent = optionName;
                if (randomizerSettingsAlt[field].selectedOption === optionName && !randomizerSettingsAlt[field].customList.trim()) {
                    option.selected = true;
                }
                select.appendChild(option);
            }

            // Custom list textarea
            const textarea = document.createElement('textarea');
            textarea.name = field + '_custom';
            textarea.rows = field != 'description' ? 2 : 4;
            textarea.placeholder = 'Enter custom list, separated by "%" or new lines.';
            textarea.style.cssText = 'background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding:5px; width: 100%; box-sizing: border-box; margin-top: 5px;';
            textarea.value = randomizerSettingsAlt[field].customList;

            // If custom list is non-empty, disable the select
            if (randomizerSettingsAlt[field].customList.trim() !== '') {
                select.disabled = true;
            }

            // Event listener to disable select if textarea has content
            textarea.addEventListener('input', (e) => {
                if (textarea.value.trim() !== '') {
                    select.disabled = true;
                } else {
                    select.disabled = false;
                }
            });

            fieldDiv.appendChild(label);
            fieldDiv.appendChild(select);
            fieldDiv.appendChild(textarea);
            fieldsContainer.appendChild(fieldDiv);
        });

        const helpLabel = document.createElement('label');
        helpLabel.style.color = 'var(--text-color)';
        helpLabel.style.fontSize = '18px';
        helpLabel.textContent = `Text codes for advanced list creation;`;
        fieldsContainer.appendChild(helpLabel);

        // Create a paragraph element for the help text
        const helpText = document.createElement('p');

        // Apply styling to the paragraph element
        helpText.style.color = 'var(--text-color)';
        helpText.style.fontSize = '12px';

        // Set the content of the help text
        helpText.innerHTML = `
  <em>"%" marks the end of an item.<br>
  "*n" Multiply the odds an item is chosen.<br>
  "&!" Create a new sub list, index is assigned by order.<br>
  "&?n" Get a random item from a sublist.<br>
  "#?a" Get Location name (Description only)<br>
  ">>" Comment start.<br>
  "<<" Comment end.<br></em>
`;

        // Append the paragraph to the container
        fieldsContainer.appendChild(helpText);

        const cancelButton = settingsForm.querySelector('#cancel-button-alt');
        cancelButton.addEventListener('click', () => {
            closeModal(settingsModal);
        });

        const settingsModal = createModal('Randomizer Settings', settingsForm);
        settingsForm.addEventListener('submit', (e) => {
            e.preventDefault();
            // Update randomizerSettingsAlt
            fields.forEach(field => {
                const select = settingsForm[field];
                const textarea = settingsForm[field + '_custom'];
                randomizerSettingsAlt[field].customList = textarea.value.trim();
                if (randomizerSettingsAlt[field].customList !== '') {
                    randomizerSettingsAlt[field].selectedOption = '';
                } else {
                    randomizerSettingsAlt[field].selectedOption = select.value;
                }
            });
            closeModal(settingsModal);
        });

        settingsForm.parentNode.style.backgroundColor = 'var(--bg-color-full)';
    }

    // Function to edit a location with randomize feature
    function editLocation(location) {
        const lockState = {
            emoji: false,
            name: false,
            description: false
        };

        const editForm = document.createElement('form');
        editForm.innerHTML = `
    <div style="width: 100%; min-width: 500px; margin: 0 auto; position: relative;">
        ${createFieldAlt('Emoji', 'emoji', location.emoji)}
        ${createReferenceField('Reference', 'reference', location.reference)}
        ${createFieldAlt('Name', 'name', location.name)}
        ${createTextareaFieldAlt('Description', 'description', location.description)}
        <button type="submit" style="background-color: var(--button-bg-color); color: var(--text-color); border: none; padding: 5px; border-radius: 5px; width: 100%; text-align: center; margin-top: 10px;">Save</button>
    </div>
    `;

        // Helper functions to create fields with lock buttons
        function createFieldAlt(labelText, fieldName, value) {
            return `
        <label style="color: var(--text-color); font-size: 12px; margin-bottom: 8px; display: block;">
            ${labelText}:
            <div style="position: relative;">
                <input type="text" name="${fieldName}" value="${value}" autocomplete="off" style="background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding: 5px; width: calc(100% - 35px); box-sizing: border-box;"/>
                <button type="button" class="lock-button-alt" data-field="${fieldName}" style="position: absolute; right: 0; top: 0; height: 100%; width: 35px; background-color: var(--button-bg-color); border: 1px solid var(--border-color); border-radius: 5px; cursor: pointer; color: var(--text-color);">${lockState[fieldName] ? '🔒' : '🔓'}</button>
            </div>
        </label>
        `;
        }

        function createReferenceField(labelText, fieldName, value) {
            return `
        <label style="color: var(--text-color); font-size: 12px; margin-bottom: 8px; display: block;">
            ${labelText}:
            <div style="position: relative;">
                <input type="text" name="${fieldName}" value="${value}" autocomplete="off" style="background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding: 5px; width: calc(100% - 35px); box-sizing: border-box;" />
                <button type="button" class="open-reference-button" data-field="${fieldName}" style="position: absolute; right: 0; top: 0; height: 100%; width: 35px; background-color: var(--button-bg-color); border: 1px solid var(--border-color); border-radius: 5px; cursor: pointer; color: var(--text-color);">🔗</button>
            </div>
        </label>
        `;
        }

        function createTextareaFieldAlt(labelText, fieldName, value) {
            return `
        <label style="color: var(--text-color); font-size: 12px; margin-bottom: 8px; display: block;">
            ${labelText}:
            <div style="position: relative;">
                <textarea name="${fieldName}" autocomplete="off" rows="4" style="background-color: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color); border-radius: 5px; padding: 5px; width: calc(100% - 35px); box-sizing: border-box;">${value}</textarea>
                <button type="button" class="lock-button-alt" data-field="${fieldName}" style="position: absolute; right: 0; top: 0; height: 100%; width: 35px; background-color: var(--button-bg-color); border: 1px solid var(--border-color); border-radius: 5px; cursor: pointer; color: var(--text-color);">${lockState[fieldName] ? '🔒' : '🔓'}</button>
            </div>
        </label>
        `;
        }

        // Copy Tooltip button
        const copyButton = document.createElement('button');
        copyButton.textContent = '📋';
        copyButton.title = 'Copy Tooltip';
        copyButton.type = 'button'; // Prevent form submission
        copyButton.style.cssText = `
    position: absolute;
    top: 15px;
    right: 50px;
    background: none;
    border: none;
    font-size: 20px;
    cursor: pointer;
    color: var(--text-color);
    `;
        copyButton.addEventListener('click', () => {
            const tooltipContent = getLocationTooltipContent(location);
            const textWithNewlines = tooltipContent.replace(/<br\s*\/?>/gi, '\n').replace(/<[^>]*>/g, '');
            navigator.clipboard.writeText(textWithNewlines);
        });
        editForm.appendChild(copyButton);

        // Randomize button
        const randomizeButton = document.createElement('button');
        randomizeButton.textContent = '🎲';
        randomizeButton.title = 'Randomize';
        randomizeButton.type = 'button'; // Prevent form submission
        randomizeButton.style.cssText = `
    position: absolute;
    top: 15px;
    right: 90px;
    background: none;
    border: none;
    font-size: 20px;
    cursor: pointer;
    color: var(--text-color);
    `;
        randomizeButton.addEventListener('click', () => {
            const randomLocation = generateRandomLocationAlt();
            const fields = ['emoji', 'name', 'description'];
            fields.forEach((field) => {
                if (!lockState[field]) {
                    editForm[field].value = randomLocation[field];
                }
            });
        });
        editForm.appendChild(randomizeButton);

        // Settings button
        const settingsButton = document.createElement('button');
        settingsButton.textContent = '⚙️';
        settingsButton.title = 'Randomizer Settings';
        settingsButton.type = 'button'; // Prevent form submission
        settingsButton.style.cssText = `
    position: absolute;
    top: 15px;
    right: 130px;
    background: none;
    border: none;
    font-size: 20px;
    cursor: pointer;
    color: var(--text-color);
    `;
        settingsButton.addEventListener('click', () => {
            openRandomizerSettingsAlt();
        });
        editForm.appendChild(settingsButton);

        const modal = createModal('Edit Location', editForm);

        // Lock button functionality
        const lockButtons = editForm.querySelectorAll('.lock-button-alt');
        lockButtons.forEach((button) => {
            const fieldName = button.getAttribute('data-field');
            button.addEventListener('click', () => {
                lockState[fieldName] = !lockState[fieldName];
                // Update button icon based on state
                button.textContent = lockState[fieldName] ? '🔒' : '🔓';
            });
        });

        // Open Reference button functionality
        const referenceButton = editForm.querySelector('.open-reference-button');
        referenceButton.addEventListener('click', () => {
            const referenceUrl = editForm.reference.value;
            if (isValidImageUrl(referenceUrl)) {
                window.open(referenceUrl, '_blank');
            } else {
                alert('Invalid image URL');
            }
        });

        editForm.addEventListener('submit', (e) => {
            e.preventDefault();
            location.emoji = editForm.emoji.value;
            location.reference = editForm.reference.value;
            location.name = editForm.name.value;
            location.description = editForm.description.value;
            renderLocationGroups();
            ensureActiveLocation();
            closeModal(modal);
        });
    }

    // Function to delete a location
    function deleteLocation(locationId) {
        if (confirm('Are you sure you want to delete this location?')) {
            locationGroups.forEach(group => {
                group.items = deleteLocationRecursive(group.items, locationId);
            });
            renderLocationGroups();
            ensureActiveLocation();
        }
    }

    function deleteLocationRecursive(items, locationId) {
        return items.filter(item => {
            if (item.id === locationId) {
                return false;
            }
            if (item.children && item.children.length > 0) {
                item.children = deleteLocationRecursive(item.children, locationId);
            }
            return true;
        });
    }

    // Function to export all locations with groups
    function exportLocations() {
        const data = {
            locationGroups: locationGroups,
            settings: { l_radius, l_labelFontSize } // Save current settings
        };
        const json = JSON.stringify(data, null, 2);
        const blob = new Blob([json], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `all_locations_with_groups.json`;
        link.click();
    }

    // Function to import locations with groups
    function importLocations() {
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = '.json';
        fileInput.addEventListener('change', async (event) => {
            const file = event.target.files[0];
            const reader = new FileReader();
            reader.onload = (e) => {
            try {
                const importedData = JSON.parse(e.target.result);
                if (Array.isArray(importedData)) {
                    // Old format
                    locationGroups = importedData;
                    renderLocationGroups();
                } else if (importedData.locationGroups) {
                    locationGroups = importedData.locationGroups;

                    // Load settings
                    if (importedData.settings) {
                        // Assign settings
                        l_radius = importedData.settings.l_radius || l_radius;
                        l_labelFontSize = importedData.settings.l_labelFontSize || l_labelFontSize;
                    }

                    renderLocationGroups();
                } else {
                    alert('Invalid format for characters import.');
                }
            } catch (error) {
                alert('Failed to import characters: ' + error.message);
            }
        };
            reader.readAsText(file);
        });
        fileInput.click();
    }

    // Function to export a single location
    function exportLocation(location) {
        const json = JSON.stringify(location, null, 2);
        const blob = new Blob([json], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `${location.name}.json`;
        link.click();
    }

    // Function to move location to a group (uncoupling from parent)
    function moveLocationToGroup(locationId, targetGroupIndex) {
        let location = null;
        // Remove location from current group or parent
        locationGroups.forEach(group => {
            group.items = removeLocationRecursive(group.items, locationId, (item) => {
                location = item;
            });
        });
        // Add to target group
        if (location) {
            locationGroups[targetGroupIndex].items.push(location);
            renderLocationGroups();
            ensureActiveLocation();
        }
    }

    function removeLocationRecursive(items, locationId, callback) {
        return items.filter(item => {
            if (item.id === locationId) {
                callback(item);
                return false;
            }
            if (item.children && item.children.length > 0) {
                item.children = removeLocationRecursive(item.children, locationId, callback);
            }
            return true;
        });
    }

    // Function to move location under another location (nesting)
    function moveLocationToParent(locationId, parentLocation) {
        let location = null;
        // Remove location from current group or parent
        locationGroups.forEach(group => {
            group.items = removeLocationRecursive(group.items, locationId, (item) => {
                location = item;
            });
        });
        if (location) {
            if(parentLocation.children == undefined){
               parentLocation.children = [];
            }
            parentLocation.children.push(location);
            renderLocationGroups();
            ensureActiveLocation();
        }
    }

    // Function to create a modal
    function createModal(title, content) {
        const modalOverlay = document.createElement('div');
        modalOverlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 10002;
        `;

        const modalBox = document.createElement('div');
        modalBox.style.cssText = `
            background-color: var(--bg-color);
            padding: 20px;
            border: 1px solid var(--border-color);
            border-radius: 5px;
            width: fit-content;
            min-width: 500px;
            max-width: 90%;
            box-shadow: 0 0 10px var(--shadow-color);
            position: relative;
        `;

        const modalTitle = document.createElement('h2');
        modalTitle.textContent = title;
        modalTitle.style.cssText = `
            margin-top: 0;
            color: var(--text-color);
        `;
        modalBox.appendChild(modalTitle);

        const closeButton = document.createElement('button');
        closeButton.textContent = '✖️';
        closeButton.style.cssText = `
            position: absolute;
            top: 15px;
            right: 20px;
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            color: var(--text-color);
        `;
        closeButton.addEventListener('click', () => {
            closeModal(modalOverlay);
        });
        modalBox.appendChild(closeButton);

        modalBox.appendChild(content);
        modalOverlay.appendChild(modalBox);
        document.body.appendChild(modalOverlay);

        return modalOverlay;
    }

    // Function to close a modal
    function closeModal(modal) {
        if (modal && modal.parentNode) {
            modal.parentNode.removeChild(modal);
        }
    }

    // Function to ensure at least one location is active
    function ensureActiveLocation() {
        const activeLocations = [];
        locationGroups.forEach(group => {
            group.items.forEach(loc => {
                collectActiveLocations(loc, activeLocations);
            });
        });
        if (activeLocations.length === 0 && locationGroups.flatMap(g => g.items).length > 0) {
            locationGroups[0].items[0].active = true;
        }
    }

    function collectActiveLocations(location, activeLocations) {
        if (location.active) {
            activeLocations.push(location);
        }
        if (location.children && location.children.length > 0) {
            location.children.forEach(child => {
                collectActiveLocations(child, activeLocations);
            });
        }
    }

    // Initial render of Character and Location Groups
    renderCharacterGroups();
    renderLocationGroups();

    // --- Plot Field ---
    const plotDiv = document.createElement('div');
    plotDiv.style.cssText = `
        display: flex;
        justify-content: space-between;
        padding: 10px;
        background-color: var(--bg-color);
        border-top: 1px solid var(--border-color);
        flex-shrink: 0;
    `;
    const plotInput = document.createElement('input');
    plotInput.type = 'text';
    plotInput.placeholder = 'Plot';
    plotInput.style.cssText = `
        width: 100%;
        padding: 5px;
        border: 1px solid var(--border-color);
        border-radius: 5px;
        background-color: var(--bg-color);
        color: var(--text-color);
        box-sizing: border-box;
    `;
    plotDiv.appendChild(plotInput);
    characterSidebar.appendChild(plotDiv);

    // --- Location Context Inputs ---
    const globalInputs = document.createElement('div');
    globalInputs.style.cssText = `
        display: flex;
        justify-content: space-between;
        padding: 10px;
        background-color: var(--bg-color);
        border-top: 1px solid var(--border-color);
        flex-shrink: 0;
    `;
    locationSidebar.appendChild(globalInputs);

    const timeInput = document.createElement('input');
    timeInput.type = 'text';
    timeInput.placeholder = 'Time';
    timeInput.style.cssText = `
        width: calc(50% - 5px);
        padding: 5px;
        border: 1px solid var(--border-color);
        border-radius: 5px;
        background-color: var(--bg-color);
        color: var(--text-color);
    `;
    globalInputs.appendChild(timeInput);

    const weatherInput = document.createElement('input');
    weatherInput.type = 'text';
    weatherInput.placeholder = 'Weather';
    weatherInput.style.cssText = `
        width: calc(50% - 5px);
        padding: 5px;
        border: 1px solid var(--border-color);
        border-radius: 5px;
        background-color: var(--bg-color);
        color: var(--text-color);
    `;
    globalInputs.appendChild(weatherInput);

    // Initial render of transparency and theme settings
    transparencySlider.value = defaultTransparency;
    themeDropdown.value = defaultTheme;

    // Load D3.js library
    await new Promise((resolve, reject) => {
        const d3Script = document.createElement('script');
        d3Script.src = 'https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.4/d3.min.js';
        d3Script.onload = resolve;
        d3Script.onerror = reject;
        document.head.appendChild(d3Script);
    });

    // --- Modifications Start Here ---

    // Variables to keep track of open windows
    let radialTreeOpen = false;
    let searchPanelOpen = { character: false, location: false };

    // Helper function to find an item by ID
    function findItemById(groups, id) {
        let result = null;
        for (let group of groups) {
            if (group.id === id) {
                return group;
            }
            if (group.items) {
                result = findItemInItems(group.items, id);
                if (result) {
                    return result;
                }
            }
        }
        return null;
    }

    function findItemInItems(items, id) {
        for (let item of items) {
            if (item.id === id) {
                return item;
            } else if (item.children && item.children.length > 0) {
                let found = findItemInItems(item.children, id);
                if (found) return found;
            }
        }
        return null;
    }

    function findGroupIndexByName(groups, name) {
        for (let i = 0; i < groups.length; i++) {
            if (groups[i].name === name) {
                return i;
            }
        }
        return null;
    }

    // Helper function to remove an item by ID
    function removeItemById(groups, id) {
        for (let group of groups) {
            if (group.items) {
                group.items = removeItemFromItems(group.items, id);
            }
        }
    }

    function removeItemFromItems(items, id) {
        return items.filter(item => {
            if (item.id === id) {
                return false;
            } else if (item.children && item.children.length > 0) {
                item.children = removeItemFromItems(item.children, id);
            }
            return true;
        });
    }

    // Helper function to check for circular references
    function isAncestor(itemId, possibleAncestorId, type) {
        let targetItem = null;
        if (type === 'character') {
            targetItem = findItemById(characterGroups, itemId);
        } else {
            targetItem = findItemById(locationGroups, itemId);
        }

        if (!targetItem) return false;

        function searchChildren(item) {
            if (item.id === possibleAncestorId) {
                return true;
            }
            if (item.children && item.children.length > 0) {
                for (let child of item.children) {
                    if (searchChildren(child)) {
                        return true;
                    }
                }
            }
            if (item.items && item.items.length > 0) {
                for (let child of item.items) {
                    if (searchChildren(child)) {
                        return true;
                    }
                }
            }
            return false;
        }

        return searchChildren(targetItem);
    }

    // Function to create a radial tree visualization
    function createRadialTree(data, type) {
        // Variables to store settings and use them globally
        c_radius = type === 'character' ? (window.c_radius || 300) : 300;
        c_labelFontSize = type === 'character' ? (window.c_labelFontSize || 12) : 12;
        c_nodeSize = type === 'character' ? (window.c_nodeSize || 24) : 24;
        l_radius = type === 'location' ? (window.l_radius || 300) : 300;
        l_labelFontSize = type === 'location' ? (window.l_labelFontSize || 12) : 12;
        l_nodeSize = type === 'location' ? (window.l_nodeSize || 24) : 24;

        ItemTransferTarget = null;

        // Close any existing radial tree window
        if (document.getElementById('radial-tree-window')) {
            document.body.removeChild(document.getElementById('radial-tree-window'));
        }

        // Create the movable window container
        const windowContainer = document.createElement('div');
        windowContainer.id = 'radial-tree-window';
        windowContainer.style.cssText = `
        position: fixed;
        top: 100px;
        left: 100px;
        width: 600px;
        height: 600px;
        background-color: var(--bg-color);
        border: 1px solid var(--border-color);
        box-shadow: 0 0 10px var(--shadow-color);
        border-radius: 5px;
        z-index: 10002;
        display: flex;
        flex-direction: column;
    `;

        // Add a header with the title and buttons
        const header = document.createElement('div');
        header.style.cssText = `
        display: flex;
        align-items: center;
        padding: 5px;
        background-color: var(--button-bg-color);
        color: var(--text-color);
        cursor: move;
    `;

        const title = document.createElement('span');
        title.textContent = `${type === 'character' ? 'Character' : 'Location'} Radial Tree`;
        title.style.flexGrow = '1';
        header.appendChild(title);

        const buttonContainer = document.createElement('div');
        buttonContainer.style.display = 'flex';
        buttonContainer.style.alignItems = 'center';

        // New Refresh Button
        const NItemButton = document.createElement('button');
        NItemButton.textContent = '📝';
        NItemButton.title = 'New Item';
        NItemButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        margin-right: 5px;
    `;
        buttonContainer.appendChild(NItemButton);

        NItemButton.addEventListener('click', () => {
            if(type === 'character'){createNewCharacter();}else{createNewLocation();}
            ItemTransferTarget = null;
            refreshTree(svgContainer, data, type);
        });

        // New Refresh Button
        const NGroupButton = document.createElement('button');
        NGroupButton.textContent = '🗄️';
        NGroupButton.title = 'New Group';
        NGroupButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        margin-right: 5px;
    `;
        buttonContainer.appendChild(NGroupButton);

        NGroupButton.addEventListener('click', () => {
            if(type === 'character'){createNewCharacterGroup();}else{createNewLocationGroup();}
            ItemTransferTarget = null;
            refreshTree(svgContainer, data, type);
        });

        // New Refresh Button
        const refreshButton = document.createElement('button');
        refreshButton.textContent = '🔄';
        refreshButton.title = 'Refresh Tree';
        refreshButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        margin-right: 5px;
    `;
        buttonContainer.appendChild(refreshButton);

        // Settings Button
        const settingsButton = document.createElement('button');
        settingsButton.textContent = '⚙️';
        settingsButton.title = 'Settings';
        settingsButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        margin-right: 5px;
    `;
        buttonContainer.appendChild(settingsButton);

        // Close Button
        const closeButton = document.createElement('button');
        closeButton.textContent = '✖️';
        closeButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
    `;
        closeButton.addEventListener('click', () => {
            document.body.removeChild(windowContainer);
            radialTreeOpen = false;
            ItemTransferTarget = null;
        });
        buttonContainer.appendChild(closeButton);

        header.appendChild(buttonContainer);
        windowContainer.appendChild(header);

        // Create SVG container
        const svgContainer = document.createElement('div');
        svgContainer.style.cssText = `
        flex-grow: 1;
        width: 100%;
        background-color: var(--bg-color);
        overflow: hidden;
        position: relative;
    `;
        windowContainer.appendChild(svgContainer);

        // Append to body
        document.body.appendChild(windowContainer);
        radialTreeOpen = true;

        // Make window draggable
        makeElementDraggable(windowContainer, header);

        // Create settings panel
        const settingsPanel = document.createElement('div');
        settingsPanel.style.cssText = `
        position: absolute;
        top: 50px;
        right: 10px;
        width: 200px;
        background-color: var(--bg-color);
        border: 1px solid var(--border-color);
        box-shadow: 0 0 10px var(--shadow-color);
        border-radius: 5px;
        padding: 10px;
        z-index: 10003;
        display: none;
    `;
        settingsPanel.innerHTML = `
        <label style="color: var(--text-color);">Node Distance: <input type="range" min="100" max="1000" value="${type === 'character' ? c_radius : l_radius}" id="nodeDistanceSlider" style="width: 100%;"></label>
        <label style="color: var(--text-color);">Label Size: <input type="range" min="8" max="24" value="${type === 'character' ? c_labelFontSize : l_labelFontSize}" id="labelSizeSlider" style="width: 100%;"></label>
        <label style="color: var(--text-color);">Node Size: <input type="range" min="8" max="48" value="${type === 'character' ? c_nodeSize : l_nodeSize}" id="nodeSizeSlider" style="width: 100%;"></label>
        <button id="applySettingsButton" style="margin-top: 10px; width: 100%;">Apply</button>
    `;
        windowContainer.appendChild(settingsPanel);

        settingsButton.addEventListener('click', () => {
            settingsPanel.style.display = settingsPanel.style.display === 'none' ? 'block' : 'none';
            ItemTransferTarget = null;
            refreshTree(svgContainer, data, type);
        });

        const nodeDistanceSlider = settingsPanel.querySelector('#nodeDistanceSlider');
        const labelSizeSlider = settingsPanel.querySelector('#labelSizeSlider');
        const nodeSizeSlider = settingsPanel.querySelector('#nodeSizeSlider');
        const applySettingsButton = settingsPanel.querySelector('#applySettingsButton');

        applySettingsButton.addEventListener('click', () => {
            if (type === 'character') {
                window.c_radius = parseInt(nodeDistanceSlider.value, 10);
                window.c_labelFontSize = parseInt(labelSizeSlider.value, 10);
                window.c_nodeSize = parseInt(nodeSizeSlider.value, 10);
            } else {
                window.l_radius = parseInt(nodeDistanceSlider.value, 10);
                window.l_labelFontSize = parseInt(labelSizeSlider.value, 10);
                window.l_nodeSize = parseInt(nodeSizeSlider.value, 10);
            }

            settingsPanel.style.display = 'none';

            // Regenerate the tree with new settings
            generateRadialTreeVisualization(svgContainer, data, type, type === 'character' ? window.c_radius : window.l_radius, type === 'character' ? window.c_labelFontSize : window.l_labelFontSize, type === 'character' ? window.c_nodeSize : window.l_nodeSize);
        });

        // Add event listener to refresh button
        refreshButton.addEventListener('click', () => {
            ItemTransferTarget = null;
            refreshTree(svgContainer, data, type);
        });

        // Initial rendering of the tree
        generateRadialTreeVisualization(svgContainer, data, type, type === 'character' ? c_radius : l_radius, type === 'character' ? c_labelFontSize : l_labelFontSize, type === 'character' ? c_nodeSize : l_nodeSize);
    }

    function refreshTree(container, data, type) {
        // Clear the existing SVG container (to remove the old tree)
        container.innerHTML = '';

        // Re-use the same data, or if necessary, fetch new data here
        const structuredData = structureData(type === 'character' ? characterGroups : locationGroups);

        // Store the current zoom, pan, and rotation before refresh
        const currentTransform = window.currentTransform || { x: container.clientWidth / 2, y: container.clientHeight / 2, k: 1 };
        const currentRotation = window.currentRotation || 0;

        // Regenerate the tree visualization with the existing settings
        const radius = type === 'character' ? window.c_radius : window.l_radius;
        const labelFontSize = type === 'character' ? window.c_labelFontSize : window.l_labelFontSize;
        const nodeSize = type === 'character' ? window.c_nodeSize : window.l_nodeSize;

        // Regenerate the tree and apply the stored transformation
        generateRadialTreeVisualization(container, structuredData, type, radius, labelFontSize, nodeSize, currentTransform, currentRotation);
    }

    function generateRadialTreeVisualization(container, data, type, radius = 300, labelFontSize = 12, nodeSize = 24, initialTransform = null, initialRotation = 0) {
        // Clear the container
        container.innerHTML = '';

        // Set dimensions
        const width = container.clientWidth;
        const height = container.clientHeight;

        // Current zoom, pan, and rotation state
        let currentRotation = initialRotation;
        let currentTransform = initialTransform || { x: width / 2, y: height / 2, k: 1 };

        // Create a D3 zoom behavior
        const zoomBehavior = d3.zoom()
        .scaleExtent([0.5, 5])
        .on('zoom', zoomed);

        // Create SVG element with zoom and pan functionality
        const svg = d3.select(container)
        .append('svg')
        .attr('width', width)
        .attr('height', height)
        .call(zoomBehavior) // Apply the zoom behavior
        .append('g')
        .attr('transform', `translate(${currentTransform.x},${currentTransform.y}) scale(${currentTransform.k}) rotate(${currentRotation})`);

        // Apply the initial zoom, pan, and rotation
        d3.select(container).select('svg').call(zoomBehavior.transform, d3.zoomIdentity.translate(currentTransform.x, currentTransform.y).scale(currentTransform.k));

        function zoomed(event) {
            // Update the current pan and zoom values
            currentTransform = event.transform;
            // Apply the combined transformation (zoom, pan, and rotation)
            svg.attr('transform', `translate(${currentTransform.x},${currentTransform.y}) scale(${currentTransform.k}) rotate(${currentRotation})`);

            // Store the transformation globally so we can retain it after refresh
            window.currentTransform = currentTransform;
        }

        // Convert data to D3 hierarchy
        const root = d3.hierarchy({ name: type === 'character' ? 'Characters' : 'Locations', children: data })
        .sum(d => d.children ? 0 : 1);

        // Create the radial tree layout
        const tree = d3.tree()
        .size([2 * Math.PI, radius])
        .separation((a, b) => (a.parent == b.parent ? 1 : 2) / a.depth);

        tree(root);

        // Create links
        const link = svg.append('g')
        .selectAll('.link')
        .data(root.links())
        .join('path')
        .attr('class', 'link')
        .attr('d', d3.linkRadial()
              .angle(d => d.x)
              .radius(d => d.y))
        .attr('stroke', 'var(--muted-bg-color)')
        .attr('fill', 'none');

        // Create nodes
        const node = svg.append('g')
        .selectAll('.node')
        .data(root.descendants())
        .join('g')
        .attr('class', 'node')
        .attr('transform', d => `
            rotate(${d.x * 180 / Math.PI - 90})
            translate(${d.y},0)
        `);

        // Use emoji as node symbols
        node.append('text')
            .attr('dy', '0.31em')
            .attr('font-size', `${nodeSize}px`) // Use nodeSize for font size
            .attr('text-anchor', 'middle')
            .attr('transform', d => `rotate(0)`) // No flipping of text
            .text(d => d.data.emoji || '⭕') // Use emoji or a default symbol
            .style('font-size', `${nodeSize}px`)
            .style('fill', 'var(--text-color)')
            .on('mouseover', (event, d) => {
            const content = type === 'character' ? getCharacterTooltipContent(d.data, true) : getLocationTooltipContent(d.data, true);
            showTooltip_radial(event, content);
        })
            .on('mousemove', (event) => {
            moveTooltip_radial(event);
        })
            .on('mouseout', hideTooltip_radial)
            .on('contextmenu', (event, d) => {
            event.preventDefault();
            navigateToItem(d.data.id, type); // Navigate to the item in the sidebar
        });

        // Labels (without emoji)
        node.append('text')
            .attr('dy', '0.31em')
            .attr('x', +nodeSize / 2 + 5)
            .attr('text-anchor', 'center') // Always center the text
            .attr('transform', d => `rotate(0)`) // No flipping of text
            .text(d => d.data.name) // Do not include emoji in label
            .style('font-size', `${labelFontSize}px`)
            .style('fill', d => (ItemTransferTarget && d.data.id === ItemTransferTarget.id) ? 'var(--warning-bg-color)' : 'var(--text-color)')
            .on('mouseover', (event, d) => {
            const content = type === 'character' ? getCharacterTooltipContent(d.data, true) : getLocationTooltipContent(d.data, true);
            showTooltip_radial(event, content);
        })
            .on('mousemove', (event) => {
            moveTooltip_radial(event);
        })
            .on('mouseout', hideTooltip_radial)
            .on('contextmenu', (event, d) => {
            event.preventDefault();

            if (ItemTransferTarget == null) {
                // Check if it's an item (not a group)
                if (d.data.description != undefined) { // items undefined means it's not a group
                    CreateContextMenu(
                        'var(--button-bg-color)',
                        'var(--text-color)',
                        ['Locate', 'Edit', 'Move', 'Delete'],
                        [
                            // Locate
                            function() { navigateToItem(d.data.id, type); },
                            // Edit
                            function() {
                                const itemId = d.data.id;
                                if (type === 'character') {
                                    const character = findItemById(characterGroups, itemId);
                                    if (character) {
                                        editCharacter(character);
                                        renderCharacterGroups();
                                        refreshTree(container, data, type);
                                    }
                                } else {
                                    const location = findItemById(locationGroups, itemId);
                                    if (location) {
                                        editLocation(location);
                                        renderLocationGroups();
                                        refreshTree(container, data, type);
                                    }
                                }
                            },
                            // Move
                            function() {
                                ItemTransferTarget = d.data;
                                refreshTree(container, data, type);
                            },
                            // Delete
                            function() {
                                const itemId = d.data.id;
                                if (type === 'character') {
                                    deleteCharacter(itemId);
                                    renderCharacterGroups();
                                    refreshTree(container, data, type);
                                } else {
                                    deleteLocation(itemId);
                                    renderLocationGroups();
                                    refreshTree(container, data, type);
                                }
                            }
                        ]
                    );
                } else {
                    // It's a group
                    CreateContextMenu(
                        'var(--button-bg-color)',
                        'var(--text-color)',
                        ['Edit', 'Delete'],
                        [
                            // Edit Group
                            function() {
                                const groupName = d.data.name;
                                if (type === 'character') {
                                    const groupIndex = findGroupIndexByName(characterGroups, groupName);
                                    if (groupIndex !== null) {
                                        renameGroup(groupIndex);
                                        renderCharacterGroups();
                                        refreshTree(container, data, type);
                                    }
                                } else {
                                    const groupIndex = findGroupIndexByName(locationGroups, groupName);
                                    if (groupIndex !== null) {
                                        renameLocationGroup(groupIndex);
                                        renderLocationGroups();
                                        refreshTree(container, data, type);
                                    }
                                }
                            },
                            // Delete Group
                            function() {
                                const groupName = d.data.name;
                                if (type === 'character') {
                                    const groupIndex = findGroupIndexByName(characterGroups, groupName);
                                    if (groupIndex !== null) {
                                        deleteGroup(groupIndex);
                                        renderCharacterGroups();
                                        refreshTree(container, data, type);
                                    }
                                } else {
                                    const groupIndex = findGroupIndexByName(locationGroups, groupName);
                                    if (groupIndex !== null) {
                                        deleteLocationGroup(groupIndex);
                                        renderLocationGroups();
                                        refreshTree(container, data, type);
                                    }
                                }
                            }
                        ]
                    );
                }
            } else {
                // Moving an item
                if (ItemTransferTarget.id === d.data.id) {
                    // Stop moving
                    CreateContextMenu(
                        'var(--button-bg-color)',
                        'var(--text-color)',
                        ['Stop'],
                        [
                            function() {
                                ItemTransferTarget = null;
                                refreshTree(container, data, type);
                            }
                        ]
                    );
                } else {
                    // Place the item
                    CreateContextMenu(
                        'var(--button-bg-color)',
                        'var(--text-color)',
                        ['Place'],
                        [
                            function() {
                                // Check for circular reference
                                if (isAncestor(ItemTransferTarget.id, d.data.id, type)) {
                                    alert('Cannot move an item into its descendant.');
                                    return;
                                }

                                if (d.data.description != undefined) {
                                    if (type === 'character') {
                                        moveCharacterToParent(ItemTransferTarget.id, findItemById(characterGroups, d.data.id));
                                    } else {
                                        moveLocationToParent(ItemTransferTarget.id, findItemById(locationGroups, d.data.id));
                                    }
                                } else {
                                    // New parent is a group
                                    const groupName = d.data.name;
                                    if (type === 'character') {
                                        const groupIndex = findGroupIndexByName(locationGroups, groupName);
                                        moveCharacterToGroup(ItemTransferTarget.id, groupIndex);
                                    } else {
                                        const groupIndex = findGroupIndexByName(locationGroups, groupName);
                                        moveLocationToGroup(ItemTransferTarget.id, groupIndex);
                                    }
                                }

                                // Clear transfer target
                                ItemTransferTarget = null;

                                // Refresh
                                if (type === 'character') {
                                    renderCharacterGroups();
                                } else {
                                    renderLocationGroups();
                                }

                                refreshTree(container, data, type);
                            }
                        ]
                    );
                }
            }
            showMenu(event);
        });

        // --- Rotation Knob UI ---
        const knobContainer = document.createElement('div');
        knobContainer.style.cssText = `
        position: absolute;
        bottom: 10px;
        right: 10px;
        width: 100px;
        height: 100px;
        z-index: 10003;
        background-color: var(--bg-color);
        border: 1px solid var(--border-color);
        border-radius: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
    `;

        const knob = document.createElement('div');
        knob.style.cssText = `
        width: 60px;
        height: 60px;
        background-color: var(--button-bg-color);
        border-radius: 50%;
        position: relative;
        transform: rotate(${currentRotation}deg); /* Apply initial rotation */
    `;

        // Add a small indicator inside the knob to show the starting point
        const knobIndicator = document.createElement('div');
        knobIndicator.style.cssText = `
        position: absolute;
        top: 5px;
        left: 50%;
        transform: translateX(-50%);
        width: 10px;
        height: 10px;
        background-color: var(--text-color);
        border-radius: 50%;
    `;
        knob.appendChild(knobIndicator);

        knobContainer.appendChild(knob);
        container.appendChild(knobContainer);

        let isDragging = false;
        let previousAngle = 0;

        // Utility function to get the angle of the mouse relative to the center of the knob
        function getAngleFromEvent(event, element) {
            const rect = element.getBoundingClientRect();
            const centerX = rect.left + rect.width / 2;
            const centerY = rect.top + rect.height / 2;
            const deltaX = event.clientX - centerX;
            const deltaY = event.clientY - centerY;
            const angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);
            return angle;
        }

        // Function to start dragging the knob
        knob.addEventListener('mousedown', (event) => {
            isDragging = true;
            previousAngle = getAngleFromEvent(event, knob);
            event.preventDefault();
        });

        // Function to handle dragging
        document.addEventListener('mousemove', (event) => {
            if (isDragging) {
                const currentAngle = getAngleFromEvent(event, knob);
                const deltaAngle = currentAngle - previousAngle;

                // Update the current rotation
                currentRotation = (currentRotation + deltaAngle) % 360;
                if (currentRotation < 0) currentRotation += 360; // Ensure positive rotation

                // Apply the combined transformation (rotation, zoom, and pan)
                svg.attr('transform', `translate(${currentTransform.x},${currentTransform.y}) scale(${currentTransform.k}) rotate(${currentRotation})`);

                // Rotate the knob visually
                knob.style.transform = `rotate(${currentRotation}deg)`;

                // Store the updated rotation globally so we can retain it after refresh
                window.currentRotation = currentRotation;

                // Update previous angle for the next move
                previousAngle = currentAngle;
            }
        });

        // Stop dragging when mouse is released
        document.addEventListener('mouseup', () => {
            isDragging = false;
        });

        // Resize listener
        window.addEventListener('resize', () => {
            svg.attr('width', container.clientWidth).attr('height', container.clientHeight);
        });
    }

    function navigateToItem(id, type) {
        if (type === 'character') {
            // Expand groups and scroll to the character
            characterGroups.forEach(group => {
                expandItemAndFind(group, id, type);
            });
            renderCharacterGroups();

            const itemElement = document.querySelector(`#character-group-list [data-id="${id}"]`);
            if (itemElement) {
                // Ensure the character menu stays open
                if (characterSidebar.style.right === '-350px') {
                    characterToggleButton.click(); // Open the sidebar if it's closed
                }
                itemElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }
        } else {
            // Expand groups and scroll to the location
            locationGroups.forEach(group => {
                expandItemAndFind(group, id, type);
            });
            renderLocationGroups();
            const itemElement = document.querySelector(`#location-group-list [data-id="${id}"]`);
            if (itemElement) {
                // Ensure the location menu stays open
                if (locationSidebar.style.left === '-350px') {
                    locationToggleButton.click(); // Open the sidebar if it's closed
                }
                itemElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }
        }
    }

    // Function to expand groups and find item (recursive)
    function expandItemAndFind(item, id, type) {
        if (item.id === id) {
            return true;
        }

        let found = false;

        if (item.items && item.items.length > 0) {
            for (let i = 0; i < item.items.length; i++) {
                if (expandItemAndFind(item.items[i], id, type)) {
                    item.collapsed = false; // Expand parent
                    found = true;
                }
            }
        }

        if (item.children && item.children.length > 0) {
            for (let i = 0; i < item.children.length; i++) {
                if (expandItemAndFind(item.children[i], id, type)) {
                    item.collapsed = false; // Expand parent
                    found = true;
                }
            }
        }

        return found;
    }

    // Function to create structured data for D3.js
    function structureData(groups) {
        return groups.map(group => ({
            name: group.name,
            emoji: '📁', // Assign folder emoji to groups
            id: group.id || generateId(),
            children: group.items.map(item => mapItem(item))
        }));
    }

    function mapItem(item) {
        return {
            id: item.id,
            name: item.name,
            emoji: item.emoji || '', // Use item's emoji, empty string if none
            description: item.description || item.bio || '',
            children: item.children ? item.children.map(child => mapItem(child)) : []
        };
    }

    // Tooltips for Radial Tree
    let radialTooltipElement = null;

    function showTooltip_radial(event, content) {
        hideTooltip_radial(); // Remove existing tooltip if any

        // Create new tooltip element
        radialTooltipElement = document.createElement('div');
        radialTooltipElement.style.cssText = `
        position: absolute;
        z-index: 100003;
        background-color: var(--bg-tool);
        color: var(--text-color);
        border: 1px solid var(--border-color);
        padding: 5px;
        border-radius: 5px;
        font-size: 12px;
        max-width: 600px;
        white-space: pre-wrap;
        box-shadow: 0 0 10px var(--shadow-color);
        pointer-events: none;
    `;
        radialTooltipElement.innerHTML = content;

        radialTooltipElement.style.left = `${event.pageX + 10}px`;
        radialTooltipElement.style.top = `${event.pageY + 10}px`;

        document.body.appendChild(radialTooltipElement);
    }

    function moveTooltip_radial(event) {
        if (radialTooltipElement) {
            radialTooltipElement.style.left = `${event.pageX + 10}px`;
            radialTooltipElement.style.top = `${event.pageY + 10}px`;
        }
    }

    function hideTooltip_radial() {
        if (radialTooltipElement && radialTooltipElement.parentNode) {
            radialTooltipElement.parentNode.removeChild(radialTooltipElement);
            radialTooltipElement = null; // Set to null after removing
        }
    }
    // Adding buttons to headers

    // Character Header Modifications
    characterHeader.innerHTML = '';

    const characterHeaderContainer = document.createElement('div');
    characterHeaderContainer.style.cssText = `
        display: flex;
        align-items: center;
        justify-content: center;
    `;

    // Search Button for Characters (Left Side)
    const characterSearchButton = document.createElement('button');
    characterSearchButton.textContent = '🔍';
    characterSearchButton.title = 'Open Search Panel';
    characterSearchButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        font-size: 18px;
        margin-right: 10px;
    `;
    characterHeaderContainer.appendChild(characterSearchButton);

    characterSearchButton.addEventListener('click', () => {
        toggleSearchPanel('character');
    });

    // Character Title
    const characterTitle = document.createElement('span');
    characterTitle.textContent = 'Characters';
    characterTitle.style.cssText = `
        color: var(--text-color);
        flex-grow: 1;
        text-align: center;
    `;
    characterHeaderContainer.appendChild(characterTitle);

    // Radial Tree Button for Characters (Right Side)
    const characterRadialButton = document.createElement('button');
    characterRadialButton.textContent = '🌐';
    characterRadialButton.title = 'Open Radial Tree';
    characterRadialButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        font-size: 18px;
        margin-left: 10px;
    `;
    characterHeaderContainer.appendChild(characterRadialButton);

    characterHeader.appendChild(characterHeaderContainer);

    // Location Header Modifications
    locationHeader.innerHTML = '';

    const locationHeaderContainer = document.createElement('div');
    locationHeaderContainer.style.cssText = `
        display: flex;
        align-items: center;
        justify-content: center;
    `;

    // Radial Tree Button for Locations (Left Side)
    const locationRadialButton = document.createElement('button');
    locationRadialButton.textContent = '🌐';
    locationRadialButton.title = 'Open Radial Tree';
    locationRadialButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        font-size: 18px;
        margin-right: 10px;
    `;
    locationHeaderContainer.appendChild(locationRadialButton);

    // Location Title
    const locationTitle = document.createElement('span');
    locationTitle.textContent = 'Locations';
    locationTitle.style.cssText = `
        color: var(--text-color);
        flex-grow: 1;
        text-align: center;
    `;
    locationHeaderContainer.appendChild(locationTitle);

    // Search Button for Locations (Right Side)
    const locationSearchButton = document.createElement('button');
    locationSearchButton.textContent = '🔍';
    locationSearchButton.title = 'Open Search Panel';
    locationSearchButton.style.cssText = `
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        font-size: 18px;
        margin-left: 10px;
    `;
    locationHeaderContainer.appendChild(locationSearchButton);

    locationHeader.appendChild(locationHeaderContainer);

    // Function to open search panel (Integrated into Sidebar)
    function toggleSearchPanel(type) {
        if (type === 'character') {
            if (searchPanelOpen.character) {
                // Close search panel
                characterSearchContainer.style.display = 'none';
                searchPanelOpen.character = false;
            } else {
                // Open search panel
                characterSearchContainer.style.display = 'block';
                searchPanelOpen.character = true;
                characterSearchInput.focus();
            }
        } else {
            if (searchPanelOpen.location) {
                // Close search panel
                locationSearchContainer.style.display = 'none';
                searchPanelOpen.location = false;
            } else {
                // Open search panel
                locationSearchContainer.style.display = 'block';
                searchPanelOpen.location = true;
                locationSearchInput.focus();
            }
        }
    }

    // Character Search Panel
    const characterSearchContainer = document.createElement('div');
    characterSearchContainer.style.cssText = `
    position: relative;
    display: none;
    padding: 10px;
    background-color: var(--bg-color);
`;
    const characterSearchInput = document.createElement('input');
    characterSearchInput.type = 'text';
    characterSearchInput.placeholder = 'Search...';
    characterSearchInput.style.cssText = `
    width: 100%;
    margin-bottom: 0px;
    padding: 5px;
    border: 1px solid var(--border-color);
    border-radius: 5px;
    background-color: var(--bg-color);
    color: var(--text-color);
`;

    // Adjust the results container to match the search input width
    const characterResultsContainer = document.createElement('div');
    characterResultsContainer.style.cssText = `
    position: absolute;
    top: calc(100% + 5px); /* Position below the search input */
    left: 0;
    width: 100%;
    max-height: 200px;
    overflow-y: auto;
    background-color: var(--bg-color);
    border: 1px solid var(--border-color);
    box-shadow: 0 0 10px var(--shadow-color);
    z-index: 1000;
`;
    characterSearchContainer.appendChild(characterSearchInput);
    characterSearchContainer.appendChild(characterResultsContainer);
    characterSidebar.insertBefore(characterSearchContainer, characterGroupList);

    characterSearchInput.addEventListener('input', () => {
        const query = characterSearchInput.value.trim().toLowerCase();
        characterResultsContainer.innerHTML = '';
        if (query.length > 0) {
            const results = searchItems(query, 'character');
            if (results.length > 0) {
                results.forEach(result => {
                    const resultItem = document.createElement('div');
                    resultItem.style.cssText = `
                    padding: 5px;
                    border-bottom: 1px solid var(--border-color);
                    cursor: pointer;
                    color: var(--text-color);
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                `;
                    resultItem.addEventListener('click', () => {
                        navigateToItem(result.id, 'character');
                        characterSearchInput.value = '';
                        characterResultsContainer.innerHTML = '';
                    });
                    resultItem.innerHTML = formatSearchResult(result);
                    characterResultsContainer.appendChild(resultItem);
                });
            } else {
                characterResultsContainer.textContent = 'No results found.';
            }
        }
    });

    // Location Search Panel
    const locationSearchContainer = document.createElement('div');
    locationSearchContainer.style.cssText = `
    position: relative;
    display: none;
    padding: 10px;
    background-color: var(--bg-color);
`;
    const locationSearchInput = document.createElement('input');
    locationSearchInput.type = 'text';
    locationSearchInput.placeholder = 'Search...';
    locationSearchInput.style.cssText = `
    width: 100%;
    margin-bottom: 0px;
    padding: 5px;
    border: 1px solid var(--border-color);
    border-radius: 5px;
    background-color: var(--bg-color);
    color: var(--text-color);
`;

    // Adjust the results container to match the search input width
    const locationResultsContainer = document.createElement('div');
    locationResultsContainer.style.cssText = `
    position: absolute;
    top: calc(100% + 5px); /* Position below the search input */
    left: 0;
    width: 100%;
    max-height: 200px;
    overflow-y: auto;
    background-color: var(--bg-color);
    border: 1px solid var(--border-color);
    box-shadow: 0 0 10px var(--shadow-color);
    z-index: 1000;
`;
    locationSearchContainer.appendChild(locationSearchInput);
    locationSearchContainer.appendChild(locationResultsContainer);
    locationSidebar.insertBefore(locationSearchContainer, locationGroupList);

    locationSearchInput.addEventListener('input', () => {
        const query = locationSearchInput.value.trim().toLowerCase();
        locationResultsContainer.innerHTML = '';
        if (query.length > 0) {
            const results = searchItems(query, 'location');
            if (results.length > 0) {
                results.forEach(result => {
                    const resultItem = document.createElement('div');
                    resultItem.style.cssText = `
                    padding: 5px;
                    border-bottom: 1px solid var(--border-color);
                    cursor: pointer;
                    color: var(--text-color);
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                `;
                    resultItem.addEventListener('click', () => {
                        navigateToItem(result.id, 'location');
                        locationSearchInput.value = '';
                        locationResultsContainer.innerHTML = '';
                    });
                    resultItem.innerHTML = formatSearchResult(result);
                    locationResultsContainer.appendChild(resultItem);
                });
            } else {
                locationResultsContainer.textContent = 'No results found.';
            }
        }
    });

    locationSearchButton.addEventListener('click', () => {
        toggleSearchPanel('location');
    });

    // Radial Tree Button Event Listeners
    characterRadialButton.addEventListener('click', () => {
        if (radialTreeOpen) {
            document.getElementById('radial-tree-window').remove();
            radialTreeOpen = false;
        }
        const data = structureData(characterGroups);
        createRadialTree(data, 'character');
    });

    locationRadialButton.addEventListener('click', () => {
        if (radialTreeOpen) {
            document.getElementById('radial-tree-window').remove();
            radialTreeOpen = false;
        }
        const data = structureData(locationGroups);
        createRadialTree(data, 'location');
    });

    // Function to search items
    function searchItems(query, type) {
        const results = [];
        const groups = type === 'character' ? characterGroups : locationGroups;
        groups.forEach(group => {
            searchGroup(group, query, results, []);
        });
        return results;
    }

    function searchGroup(group, query, results, path) {
        const newPath = [...path, group.name];
        group.items.forEach(item => {
            searchItem(item, query, results, newPath);
        });
    }

    function searchItem(item, query, results, path) {
        const newPath = [...path, item.name];
        if (item.name.toLowerCase().includes(query)) {
            results.push({ id: item.id, path: newPath });
        }
        if (item.children && item.children.length > 0) {
            item.children.forEach(child => {
                searchItem(child, query, results, newPath);
            });
        }
    }

    function formatSearchResult(result) {
        let html = '';
        const maxCharacters = 42; // Adjust as needed
        let displayPath = result.path.join(' > ');

        if (displayPath.length > maxCharacters) {
            displayPath = '...' + displayPath.slice(-maxCharacters);
        }

        const pathSegments = displayPath.split(' > ');

        for (let i = 0; i < pathSegments.length - 1; i++) {
            html += `<span style="font-size: 12px; color: var(--text-color-darker); white-space: nowrap;">${pathSegments[i]} > </span>`;
        }
        html += `<strong style="white-space: nowrap;">${pathSegments[pathSegments.length - 1]}</strong>`;

        return `<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${html}</div>`;
    }

    function GetImage(url, callback) {
        // Validate the URL (basic image URL validation)
        if (!isValidImageUrl(url)) {
            console.error("Invalid image URL:", url);
            if (typeof callback === "function") {
                callback(null);
            }
            return;
        }

        // Fetch the image
        GM_xmlhttpRequest({
            method: "GET",
            url: url,
            responseType: "arraybuffer", // Get the raw binary data
            onload: function(response) {
                if (response.status === 200) {
                    // Convert the binary data to a Base64 string
                    const base64Data = arrayBufferToBase64(response.response);

                    // Determine the MIME type from the URL or default to image/jpeg
                    const mimeType = getMimeTypeFromUrl(url) || "image/jpeg";
                    const dataUri = `data:${mimeType};base64,${base64Data}`;

                    // Call the callback with the Base64 data URI
                    if (typeof callback === "function") {
                        callback(dataUri);
                    }
                } else {
                    console.error(`Failed to fetch image. HTTP Status: ${response.status}`);
                    if (typeof callback === "function") {
                        callback(null);
                    }
                }
            },
            onerror: function(error) {
                console.error("Error fetching the image:", error);
                if (typeof callback === "function") {
                    callback(null);
                }
            }
        });
    }

    function isValidImageUrl(url) {
        return /^(https?:\/\/.*\.(?:png|jpg|jpeg|gif|webp|bmp|svg))$/i.test(url);
    }

    function arrayBufferToBase64(buffer) {
        let binary = '';
        const bytes = new Uint8Array(buffer);
        const len = bytes.byteLength;
        for (let i = 0; i < len; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return btoa(binary);
    }

    function getMimeTypeFromUrl(url) {
        const extension = url.split('.').pop().toLowerCase();
        switch (extension) {
            case 'png': return 'image/png';
            case 'jpg': case 'jpeg': return 'image/jpeg';
            case 'gif': return 'image/gif';
            case 'webp': return 'image/webp';
            case 'bmp': return 'image/bmp';
            case 'svg': return 'image/svg+xml';
            default: return null;
        }
    }
})();