Diep.io Custom Points Upgrader - Optimized

NEW! custom upgrade builds update! Your upgrade builds will save now! This is still in beta!

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         Diep.io Custom Points Upgrader - Optimized
// @namespace    http://tampermonkey.net/
// @version      10.08
// @homepage     https://greasyfork.org/scripts/416440
// @description  NEW! custom upgrade builds update! Your upgrade builds will save now! This is still in beta!
// @author       -{Abyss⌬}-ora
// @match        https://diep.io/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    "use strict";

    // ========== CONSTANTS ==========
    const MAX_POINTS = 33;
    const MAX_ATTRIBUTE_LEVEL = 7;

    const STORAGE_KEYS = {
        USERNAME: "quickSpawnUsername",
        SAVED_NAMES: "savedNames",
        SAVED_BUTTONS: "savedButtons",
        REMOVED_DEFAULTS: "removedDefaults",
        BACKUP_DATA: "backupData",
        SCRIPT_VERSION: "scriptVersion",
        MENU_POSITION: "menuPosition"
    };

    const ATTRIBUTES = [
        { name: "Health Regen", color: "rgb(232, 188, 157)", maxLevel: 10 },
        { name: "Max Health", color: "rgb(230, 128, 234)", maxLevel: 10 },
        { name: "Body Damage", color: "rgb(165, 128, 234)", maxLevel: 10 },
        { name: "Bullet Speed", color: "rgb(128, 162, 234)", maxLevel: 7 },
        { name: "Bullet Penetration", color: "rgb(234, 215, 128)", maxLevel: 7 },
        { name: "Bullet Damage", color: "rgb(234, 128, 128)", maxLevel: 7 },
        { name: "Reload", color: "rgb(164, 234, 128)", maxLevel: 7 },
        { name: "Movement Speed", color: "rgb(128, 234, 230)", maxLevel: 10 }
    ];

    const BACKGROUND_IMAGE = "url('https://media.tenor.com/images/f3f5354b7c304bc61882dbb1183885e7/tenor.gif')";

    // ========== HELPER FUNCTIONS ==========
    const getStorage = (key) => localStorage.getItem(key);
    const setStorage = (key, value) => localStorage.setItem(key, value);
    const getStorageJSON = (key) => JSON.parse(getStorage(key) || "null") || [];
    const setStorageJSON = (key, value) => setStorage(key, JSON.stringify(value));

    const createElement = (tag, className, attributes = {}) => {
        const el = document.createElement(tag);
        if (className) el.className = className;
        Object.entries(attributes).forEach(([key, value]) => {
            if (key === 'style') {
                Object.assign(el.style, value);
            } else {
                el[key] = value;
            }
        });
        return el;
    };

    const applyStyles = (element, styles) => Object.assign(element.style, styles);

    const toggleVisibility = (element) => {
        if (element) {
            element.style.display = element.style.display === "none" ? "block" : "none";
        }
    };

    function getScriptVersion() {
        const metadataBlock = `
// ==UserScript==
// @version      10.08
// ==/UserScript==`;
        const versionMatch = metadataBlock.match(/@version\s+([\d.]+)/);
        return versionMatch ? versionMatch[1] : null;
    }

    function saveDataBeforeUpdate() {
        const dataToSave = Object.fromEntries(
            Object.entries(STORAGE_KEYS)
            .filter(([key]) => key !== 'BACKUP_DATA' && key !== 'SCRIPT_VERSION')
            .map(([_, value]) => [value, getStorage(value)])
        );
        setStorageJSON(STORAGE_KEYS.BACKUP_DATA, dataToSave);
    }

    function retrieveDataAfterUpdate() {
        const backupData = getStorageJSON(STORAGE_KEYS.BACKUP_DATA);
        if (backupData && Object.keys(backupData).length) {
            Object.entries(backupData).forEach(([key, value]) => {
                if (value) setStorage(key, value);
            });
        }
    }

    function checkAndUpdateVersion() {
        const currentVersion = getScriptVersion();
        const savedVersion = getStorage(STORAGE_KEYS.SCRIPT_VERSION);

        if (!savedVersion || savedVersion < currentVersion) {
            retrieveDataAfterUpdate();
            setStorage(STORAGE_KEYS.SCRIPT_VERSION, currentVersion);
        }
    }

    function spawnWithBuild(cmd) {
        const spawnName = userInput.value.trim();
        window.input.execute(`game_spawn ${spawnName}`);
        window.input.execute(`game_stats_build ${cmd}`);
        toggleVisibility(document.getElementById("myhover"));
    }

    function dragElement(elmnt) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        const header = document.getElementById(elmnt.id + "Header");
        (header || 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;
        }
    }

    function adjustFontSize(element) {
        let fontSize = 16;
        element.style.fontSize = fontSize + "px";
        while (element.scrollWidth > element.clientWidth && fontSize > 6) {
            element.style.fontSize = --fontSize + "px";
        }
    }

    // ========== ATTRIBUTE EDITOR CREATION ==========
    function createAttributeEditor(popupId = "", initialCode = "", onUpdate) {
        const container = createElement("div");
        let code = initialCode;
        let totalPoints = MAX_POINTS;

        const pointsCounter = createElement("div", null, {
            id: `pointsCounter${popupId ? '-' + popupId : ''}`,
            textContent: `Points: ${MAX_POINTS}`,
            style: {
                display: "inline-block",
                padding: "2px 6px",
                backgroundColor: "rgba(0, 0, 0, 0.5)",
                borderRadius: "5px",
                marginBottom: "5px"
            }
        });

        const codeString = createElement("input", null, {
            id: `codeString${popupId ? '-' + popupId : ''}`,
            type: "text",
            value: code,
            style: {
                display: "block",
                width: "80%",
                margin: "0 auto 10px auto",
                textAlign: "center",
                fontSize: "18px"
            }
        });

        function updateAttributes() {
            totalPoints = MAX_POINTS;
            let isSmasherBuild = false;

            ATTRIBUTES.forEach((attribute, index) => {
                const attributeRow = document.getElementById(`attributeRow-${popupId}-${index}`);
                if (!attributeRow) return;

                const maxLevel = attribute.maxLevel || MAX_ATTRIBUTE_LEVEL;
                const attributeCount = Math.min(
                    (code.match(new RegExp(index + 1, "g")) || []).length,
                    maxLevel
                );

                // Check if this is a smasher attribute with more than 7 points
                if (maxLevel > MAX_ATTRIBUTE_LEVEL && attributeCount > MAX_ATTRIBUTE_LEVEL) {
                    isSmasherBuild = true;
                }

                // Update minus button color based on whether row has points
                const minusButton = attributeRow.children[0];
                if (attributeCount > 0) {
                    minusButton.style.backgroundColor = attribute.color;
                } else {
                    minusButton.style.backgroundColor = "gray";
                }

                // Handle base 7 squares
                for (let i = 0; i < MAX_ATTRIBUTE_LEVEL; i++) {
                    const square = attributeRow.children[i + 1];
                    if (i < Math.min(attributeCount, MAX_ATTRIBUTE_LEVEL)) {
                        square.style.backgroundColor = attribute.color;
                        square.style.border = "1px solid black";
                        totalPoints--;
                    } else {
                        square.style.backgroundColor = "gray";
                        square.style.border = "0";
                    }
                }

                // Handle bonus squares (8th, 9th, 10th) for attributes with maxLevel > 7
                if (maxLevel > MAX_ATTRIBUTE_LEVEL) {
                    const bonusSquaresNeeded = Math.max(0, attributeCount - MAX_ATTRIBUTE_LEVEL);
                    const existingBonusSquares = attributeRow.querySelectorAll('.bonus-square').length;

                    // Add bonus squares if needed
                    for (let i = existingBonusSquares; i < bonusSquaresNeeded; i++) {
                        const bonusSquare = createElement("div", "bonus-square", {
                            style: {
                                border: "1px solid black",
                                backgroundColor: attribute.color,
                                width: "30px",
                                height: "30px",
                                display: "inline-block",
                                position: "relative",
                                padding: "0 5px",
                                animation: "bounceIn 0.3s ease-out"
                            }
                        });
                        attributeRow.insertBefore(bonusSquare, attributeRow.lastChild);
                        totalPoints--;
                    }

                    // Remove bonus squares if needed
                    const allBonusSquares = Array.from(attributeRow.querySelectorAll('.bonus-square'));
                    for (let i = bonusSquaresNeeded; i < allBonusSquares.length; i++) {
                        allBonusSquares[i].remove();
                    }
                }
            });

            // Update points display
            if (isSmasherBuild || totalPoints < 0 || totalPoints > MAX_POINTS) {
                pointsCounter.textContent = `Points: modified for Smashers`;
            } else {
                pointsCounter.textContent = `Points: ${totalPoints}`;
            }

            if (onUpdate) onUpdate(code, totalPoints);
        }

        function createAttributeRow(attribute, index) {
            const attributeRow = createElement("div", "attribute", {
                id: `attributeRow-${popupId}-${index}`,
                style: { position: "relative" }
            });

            const minusButton = createElement("button", null, {
                textContent: "-",
                style: {
                    padding: "0 5px",
                    border: "1px solid black",
                    borderRadius: "50px 0 0 50px",
                    width: "32px",
                    height: "32px",
                    color: "black",
                    fontWeight: "bold",
                    backgroundColor: "gray"
                }
            });

            minusButton.onclick = () => {
                const coloredSquares = Array.from(attributeRow.children).filter(
                    child => child !== plusButton && child !== minusButton && child.style.backgroundColor === attribute.color
                );
                if (coloredSquares.length > 0) {
                    const square = coloredSquares[coloredSquares.length - 1];
                    square.style.backgroundColor = "gray";
                    square.style.border = "0";
                    code = code.slice(0, -1);
                    codeString.value = code;
                    updateAttributes();
                }
            };

            attributeRow.appendChild(minusButton);

            for (let i = 0; i < MAX_ATTRIBUTE_LEVEL; i++) {
                const colorDiv = createElement("div", null, {
                    style: {
                        border: "0",
                        backgroundColor: "gray",
                        width: "30px",
                        height: "30px",
                        display: "inline-block",
                        position: "relative",
                        padding: "0 5px"
                    }
                });

                if (i === 3) {
                    const textSpan = createElement("span", null, {
                        textContent: attribute.name,
                        style: {
                            position: "absolute",
                            top: "50%",
                            left: "50%",
                            transform: "translate(-50%, -50%)",
                            color: "white",
                            pointerEvents: "none",
                            whiteSpace: "nowrap",
                            zIndex: "1",
                            textShadow: "1px 1px #000, 2px 2px #555, -1px -1px #000, -2px -2px #555"
                        }
                    });
                    colorDiv.appendChild(textSpan);
                }

                attributeRow.appendChild(colorDiv);
            }

            const plusButton = createElement("button", null, {
                textContent: "+",
                style: {
                    padding: "0 5px",
                    border: "1px solid black",
                    borderRadius: "0 50px 50px 0",
                    width: "32px",
                    height: "32px",
                    color: "black",
                    fontWeight: "bold",
                    backgroundColor: attribute.color
                }
            });

            plusButton.onclick = () => {
                const maxLevel = attribute.maxLevel || MAX_ATTRIBUTE_LEVEL;
                const currentCount = (code.match(new RegExp(index + 1, "g")) || []).length;

                if (currentCount < maxLevel) {
                    code += (index + 1);
                    codeString.value = code;
                    updateAttributes();
                }
            };

            attributeRow.appendChild(plusButton);
            return attributeRow;
        }

        codeString.addEventListener("input", (event) => {
            code = event.target.value;
            updateAttributes();
        });

        container.appendChild(pointsCounter);
        container.appendChild(codeString);
        ATTRIBUTES.forEach((attribute, index) => {
            container.appendChild(createAttributeRow(attribute, index));
        });

        // Call updateAttributes after a short delay to ensure DOM is ready
        setTimeout(() => updateAttributes(), 0);

        return {
            container,
            getCode: () => code,
            pointsCounter,
            codeString
        };
    }

    // ========== POPUP CREATION ==========
    function createPopup(title, popupId = `popup-${Date.now()}`) {
        const popup = createElement("div", "popup", {
            id: popupId,
            innerHTML: `<div class="popup-header" id="${popupId}Header">${title}</div>`
        });

        const closeButton = createElement("button", "close-btn", {
            textContent: "X",
            onclick: () => document.body.removeChild(popup)
        });

        popup.appendChild(closeButton);
        document.body.appendChild(popup);
        dragElement(popup);

        return popup;
    }

    function createEditPopup(buttonContainer, buttonData) {
        const popupId = `editPopup-${Date.now()}`;
        const popup = createPopup("Drag me", popupId);

        const buildNameInput = createElement("input", null, {
            type: "text",
            placeholder: "Build Name",
            value: buttonData.name,
            style: {
                display: "block",
                width: "80%",
                margin: "0 auto 10px auto"
            }
        });

        popup.appendChild(buildNameInput);

        const { container, getCode } = createAttributeEditor(popupId, buttonData.cmd);
        popup.appendChild(container);

        // Trigger update after container is in DOM
        setTimeout(() => {
            const event = new Event('input', { bubbles: true });
            popup.querySelector(`#codeString-${popupId}`).dispatchEvent(event);
        }, 10);

        const saveChangesButton = createElement("button", null, {
            textContent: "Save Changes",
            style: {
                display: "block",
                margin: "10px auto",
                width: "80%",
                fontSize: "14px",
                padding: "8px",
                backgroundColor: "white",
                border: "2px solid black",
                borderRadius: "5px",
                cursor: "pointer"
            },
            onclick: () => {
                const buildName = buildNameInput.value.trim();
                if (!buildName) {
                    alert("Please enter a build name.");
                    return;
                }

                buttonData.name = buildName;
                buttonData.cmd = getCode();

                buttonContainer.querySelector(".button").textContent = buildName;

                const savedButtons = getStorageJSON(STORAGE_KEYS.SAVED_BUTTONS);
                const updatedButtons = savedButtons.map(b => 
                                                        b.cmd === buttonData.cmd && b.name !== buildName ? b : 
                                                        b.name === buttonData.name || b.cmd === buttonData.cmd ? buttonData : b
                                                       );
                setStorageJSON(STORAGE_KEYS.SAVED_BUTTONS, updatedButtons);

                document.body.removeChild(popup);
            }
        });

        const deleteButton = createElement("button", null, {
            textContent: "Delete Build",
            style: {
                display: "block",
                margin: "10px auto",
                width: "80%",
                fontSize: "14px",
                padding: "8px",
                backgroundColor: "white",
                border: "2px solid black",
                borderRadius: "5px",
                cursor: "pointer"
            },
            onclick: () => {
                const confirmPopup = createPopup("Drag Me", `confirmDelete-${popupId}`);

                const message = createElement("div", null, {
                    textContent: "Are you sure you want to delete this build?",
                    style: {
                        textAlign: "center",
                        marginBottom: "20px"
                    }
                });

                const btnContainer = createElement("div", null, {
                    style: {
                        display: "flex",
                        justifyContent: "space-between"
                    }
                });

                const noBtn = createElement("button", "button", {
                    textContent: "NO",
                    onclick: () => document.body.removeChild(confirmPopup)
                });

                const yesBtn = createElement("button", "button", {
                    textContent: "YES",
                    onclick: () => {
                        buttonContainer.remove();
                        const savedButtons = getStorageJSON(STORAGE_KEYS.SAVED_BUTTONS);
                        setStorageJSON(STORAGE_KEYS.SAVED_BUTTONS, 
                                       savedButtons.filter(b => b.name !== buttonData.name)
                                      );
                        document.body.removeChild(confirmPopup);
                        document.body.removeChild(popup);
                    }
                });

                btnContainer.appendChild(noBtn);
                btnContainer.appendChild(yesBtn);
                confirmPopup.appendChild(message);
                confirmPopup.appendChild(btnContainer);
            }
        });

        popup.appendChild(saveChangesButton);
        popup.appendChild(deleteButton);
    }

    // ========== INITIALIZATION ==========
    saveDataBeforeUpdate();
    checkAndUpdateVersion();

    // ========== STYLES ==========
    const style = createElement("style", null, {
        textContent: `
        #myhover a {
            z-index: 999;
            position: absolute;
            top: 300px;
            transition: 0.3s;
            width: 250px;
            padding: 45px 15px 15px 15px; /* extra top space for drag bar */
            background-image: ${BACKGROUND_IMAGE};
            background-color: #555;
            text-decoration: none;
            font-size: 10px;
            font-family: 'Monoton', cursive;
            text-shadow: 1px 1px #000, 2px 2px #555;
            color: white;
            border: double thick white;
            border-radius: 20px;
            /* cursor removed to allow normal pointer except drag header */
        }
                /* Drag header inside main menu */
                #myhover a .main-drag-header {
                    position: absolute;
                    top: 5px;
                    left: 5px;
                    right: 45px;
                    height: 30px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    background-color: rgba(5,5,5,0.85);
                    color: #fff;
                    font-size: 12px;
                    font-family: 'Monoton', cursive;
                    text-shadow: 1px 1px #000, 2px 2px #555;
                    border: 1px solid white;
                    border-radius: 12px;
                    cursor: grab;
                    user-select: none;
                }
                #myhover a .main-drag-header:active { cursor: grabbing; }
        /* Right side (default) */
        #myhover a.snap-right { right: -260px; left: auto; }
        #myhover a.snap-right:hover { right: 0; }
        /* Left side */
        #myhover a.snap-left { left: -260px; right: auto; }
        #myhover a.snap-left:hover { left: 0; }
        /* During drag: disable hover and let JS control position */
        .dragging,
        .dragging * {
            transform: none !important;
            transition: none !important;
        }
        .dragging:hover {
            transform: none !important;
            transition: none !important;
        }
        /* Magnet snap animation - ease in (slow start) then ease out (slow end) with bounce */
        #myhover a.magnet-snap { 
            transition: left 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), 
                        right 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), 
                        top 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
        }
        .button {
            display: block;
            margin: 5px auto;
            width: 90%;
            text-align: center;
            font-size: 18px;
            font-family: 'Jersey 10', sans-serif;
            color: black;
            background-color: white;
            border-radius: 5px;
            transition: 0.4s;
            cursor: pointer;
        }
        .button:hover { transform: translateX(-10px); }
        #userInput {
            margin: 5px auto;
            width: 90%;
            padding: 8px;
            font-family: 'Monoton', cursive;
            text-align: center;
        }
        #specialButton {
            display: block;
            margin: 5px auto;
            width: 90%;
            text-align: center;
            font-size: 18px;
            font-family: 'Jersey 10', sans-serif;
            color: white;
            background-color: black;
            border-radius: 5px;
            border-color: white;
            transition: 0.4s;
            cursor: pointer;
            opacity: 0.8;
        }
        #specialButton:hover {
            color: black;
            background-color: darkgray;
            transform: translateX(-10px);
        }
        .popup {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 300px;
            background-image: ${BACKGROUND_IMAGE};
            background-color: white;
            border: double thick white;
            border-radius: 10px;
            padding: 20px;
            padding-top: 50px;
            z-index: 1000;
            text-shadow: 1px 1px #000, 2px 2px #555;
        }
        .attribute {
            display: flex;
            align-items: center;
            margin-bottom: 10px;
        }
        .close-btn {
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
            top: 1px;
            right: 0px;
            width: 40px;
            height: 35px;
            color: white;
            cursor: pointer;
            font-size: 18px;
            transition: background-color 0.3s;
            text-shadow: 1px 1px #000, 2px 2px #555;
            border-radius: 10px;
            background-color: rgba(0, 0, 0, 0.8);
            z-index: 10;
        }
        .close-btn:hover { background-color: red; }
        #topRightButton {
            position: absolute;
            top: 5px;
            right: 5px;
            width: 30px;
            height: 30px;
            padding: 0;
            background-color: rgba(5,5,5,0.85);
            color: white;
            border: 1px solid white;
            border-radius: 12px;
            cursor: pointer;
            font-size: 16px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Monoton', cursive;
            text-shadow: 1px 1px #000, 2px 2px #555;
            transition: background-color 0.3s;
            z-index: 1001;
        }
        #topRightButton:hover { background-color: rgba(255,0,0,0.85); }
        #buildButtonsContainer {
            max-height: 400px;
            overflow-y: scroll;
            margin-left: 5px;
            -ms-overflow-style: none;
            scrollbar-width: none;
        }
        ::-webkit-scrollbar { width: 10px; }
        ::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 10px;
        }
        ::-webkit-scrollbar-thumb {
            background: #888;
            border-radius: 10px;
        }
        ::-webkit-scrollbar-thumb:hover { background: #555; }
        .popup-header {
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
            top: 1px;
            left: 0px;
            right: 35px;
            height: 30px;
            cursor: grabbing;
            z-index: 10;
            background-color: rgba(5, 5, 5, 0.8);
            color: #fff;
            font-size: 10px;
            font-family: 'Monoton', cursive;
            text-shadow: 1px 1px #000, 2px 2px #555;
            border-radius: 10px;
            margin-bottom: 10px;
        }
        .edit-button {
            background-color: gray;
            border: none;
            color: white;
            font-size: 18px;
            cursor: pointer;
            width: 30px;
            height: 30px;
            margin-right: 5px;
            transition: background-color 0.3s;
        }
        .edit-button:hover { background-color: lightgray; }
        @keyframes bounceIn {
            0% { transform: scale(0); opacity: 0; }
            50% { transform: scale(1.2); }
            100% { transform: scale(1); opacity: 1; }
        }
    `});
    document.head.appendChild(style);

    // ========== MENU CREATION ==========
    const hoverMenu = createElement("div", "hover", { id: "myhover" });
    const modMenu = createElement("a", null, { id: "modtab" });
    // Start snapped to right by default
    modMenu.classList.add('snap-right');

    const dragHeader = createElement('div','main-drag-header',{textContent:'Drag Menu'});
    const menuHeader = createElement("h1");
    const versionText = createElement("small");
    const smallerVersionText = createElement("small", null, {
        textContent: `Version: ${getScriptVersion()}`
    });
    versionText.appendChild(smallerVersionText);
    menuHeader.appendChild(versionText);
    menuHeader.appendChild(document.createElement("br"));
    menuHeader.appendChild(document.createTextNode("-{Abyss⌬}-ora's Mod Menu beta"));
    modMenu.appendChild(dragHeader);
    modMenu.appendChild(menuHeader);

    // Enable drag & snap behavior for main menu anchor
    (function enableDragAndSnap(el, handle){
        let dragging = false;
        let offsetX = 0;
        let offsetY = 0;

        // Load saved position
        function loadPosition() {
            const saved = getStorageJSON(STORAGE_KEYS.MENU_POSITION);
            if (saved && saved.snapSide) {
                el.classList.remove('snap-right', 'snap-left');
                el.classList.add(saved.snapSide);
                if (saved.top !== undefined) {
                    el.style.top = saved.top + 'px';
                }
            }
        }

        // Save position
        function savePosition(snapSide, top) {
            setStorageJSON(STORAGE_KEYS.MENU_POSITION, { snapSide, top });
        }

        // Keep menu on screen when window resizes
        function keepOnScreen() {
            if (dragging) return;

            const saved = getStorageJSON(STORAGE_KEYS.MENU_POSITION);
            const rect = el.getBoundingClientRect();
            const viewportHeight = window.innerHeight;
            const menuHeight = rect.height;

            // Always try to use saved position if it exists
            let targetTop = saved && saved.top !== undefined ? saved.top : rect.top;

            // Check if saved position would fit on screen
            let newTop = targetTop;

            // If menu doesn't fit on screen at all, show top part
            if (menuHeight > viewportHeight) {
                newTop = 0;
            } else {
                // Clamp to viewport bounds
                if (targetTop + menuHeight > viewportHeight) {
                    newTop = viewportHeight - menuHeight;
                }
                if (targetTop < 0) {
                    newTop = 0;
                }
            }

            // Apply position with bounce animation if changed
            if (newTop !== rect.top) {
                el.classList.add('magnet-snap');
                el.style.top = newTop + 'px';
                setTimeout(() => { el.classList.remove('magnet-snap'); }, 600);
            }
            // Note: We don't save here - only save when user manually moves it
        }

        function onMouseDown(e){
            if(e.button !== 0) return;

            dragging = true;

            // Freeze all transforms so visuals match reality
            el.classList.add("dragging");

            // Get actual pixel position on screen ignoring transforms
            const rect = el.getBoundingClientRect();

            // Calculate offset from mouse to element
            offsetX = e.clientX - rect.left;
            offsetY = e.clientY - rect.top;

            // Remove snap classes
            el.classList.remove('snap-right', 'snap-left');

            // Switch to absolute positioning locked to the screen location
            el.style.position = "absolute";
            el.style.left = rect.left + "px";
            el.style.top = rect.top + "px";
            el.style.right = "auto";

            e.preventDefault();
        }

        function onMouseMove(e){
            if (!dragging) return;

            // Move EXACTLY with the mouse but constrain to viewport
            const newLeft = e.clientX - offsetX;
            const newTop = e.clientY - offsetY;

            // Get element dimensions
            const rect = el.getBoundingClientRect();
            const maxLeft = window.innerWidth - rect.width;
            const maxTop = window.innerHeight - rect.height;

            // Constrain position within viewport bounds
            el.style.left = Math.max(0, Math.min(newLeft, maxLeft)) + "px";
            el.style.top = Math.max(0, Math.min(newTop, maxTop)) + "px";
        }

        function onMouseUp(){
            if (!dragging) return;

            dragging = false;
            el.classList.remove("dragging");

            // Determine snap side based on center position
            const rect = el.getBoundingClientRect();
            const centerX = rect.left + rect.width / 2;
            const mid = window.innerWidth / 2;

            let snapRight = centerX > mid;
            let snapSide = snapRight ? 'snap-right' : 'snap-left';

            // Apply magnet snap animation
            el.classList.add('magnet-snap');
            if(snapRight){
                el.classList.add('snap-right');
                el.style.left = 'auto';
                el.style.right = '';
            } else {
                el.classList.add('snap-left');
                el.style.right = 'auto';
                el.style.left = '';
            }

            // Save position
            savePosition(snapSide, rect.top);

            setTimeout(() => { el.classList.remove('magnet-snap'); }, 600);
        }

        handle.addEventListener('mousedown', onMouseDown);
        document.addEventListener('mousemove', onMouseMove);
        document.addEventListener('mouseup', onMouseUp);
        window.addEventListener('resize', keepOnScreen);

        // Load saved position on init
        loadPosition();
        // Check position after a brief delay to ensure DOM is ready
        setTimeout(keepOnScreen, 100);
    })(modMenu, dragHeader);

    // ========== USERNAME INPUT ==========
    const inputContainer = createElement("div", null, {
        style: {
            position: "relative",
            width: "90%",
            margin: "5px auto"
        }
    });

    const heartIcon = createElement("span", null, {
        textContent: "♥",
        style: {
            position: "absolute",
            left: "10px",
            top: "50%",
            transform: "translateY(-50%)",
            cursor: "pointer",
            fontSize: "18px",
            color: "black"
        }
    });

    const userInput = createElement("input", null, {
        id: "userInput",
        type: "text",
        placeholder: "Enter Username",
        value: getStorage(STORAGE_KEYS.USERNAME) || "",
        style: {
            width: "100%",
            padding: "8px 30px",
            border: "2px solid black",
            borderRadius: "5px",
            boxSizing: "border-box",
            fontFamily: "'Monoton', cursive",
            textAlign: "center"
        }
    });

    const dropdownArrow = createElement("span", null, {
        textContent: "▼",
        style: {
            position: "absolute",
            right: "10px",
            top: "50%",
            transform: "translateY(-50%)",
            cursor: "pointer",
            fontSize: "14px",
            color: "black"
        }
    });

    const dropdown = createElement("div", null, {
        id: "dropdownMenu",
        style: {
            position: "absolute",
            width: "100%",
            top: "100%",
            left: "0",
            backgroundImage: BACKGROUND_IMAGE,
            border: "4px double white",
            borderTop: "none",
            display: "none",
            zIndex: "100",
            maxHeight: "150px",
            overflowY: "auto"
        }
    });

    function updateDropdown(names) {
        dropdown.innerHTML = "";
        names.forEach(name => {
            const optionContainer = createElement("div", null, {
                style: {
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "space-between",
                    padding: "8px",
                    cursor: "pointer",
                    fontFamily: "'Monoton', cursive",
                    textAlign: "center",
                    fontSize: "18px",
                    backgroundImage: BACKGROUND_IMAGE,
                    transition: "background 0.3s"
                }
            });

            const option = createElement("div", null, {
                textContent: name,
                style: { flexGrow: "1", textAlign: "left" }
            });

            option.addEventListener("mouseover", () => {
                optionContainer.style.backgroundColor = "rgba(169, 169, 169, 0.8)";
            });

            option.addEventListener("mouseout", () => {
                optionContainer.style.backgroundColor = "transparent";
            });

            option.addEventListener("click", () => {
                userInput.value = name;
                dropdown.style.display = "none";
                setStorage(STORAGE_KEYS.USERNAME, name);
                updateHeartIcon();
            });

            optionContainer.appendChild(option);
            dropdown.appendChild(optionContainer);
        });
    }

    function updateHeartIcon() {
        const name = userInput.value.trim();
        const savedNames = getStorageJSON(STORAGE_KEYS.SAVED_NAMES);
        heartIcon.style.color = savedNames.includes(name) ? "red" : "black";
    }

    dropdownArrow.addEventListener("click", () => toggleVisibility(dropdown));

    document.addEventListener("click", (event) => {
        if (!inputContainer.contains(event.target)) {
            dropdown.style.display = "none";
        }
    });

    userInput.addEventListener("input", (event) => {
        setStorage(STORAGE_KEYS.USERNAME, event.target.value);
        updateHeartIcon();
    });

    heartIcon.addEventListener("click", () => {
        const name = userInput.value.trim();
        if (!name) return;

        const savedNames = getStorageJSON(STORAGE_KEYS.SAVED_NAMES);
        const nameIndex = savedNames.indexOf(name);

        if (nameIndex === -1) {
            savedNames.push(name);
            heartIcon.style.color = "red";
        } else {
            savedNames.splice(nameIndex, 1);
            heartIcon.style.color = "black";
        }

        setStorageJSON(STORAGE_KEYS.SAVED_NAMES, savedNames);
        updateDropdown(savedNames);
    });

    inputContainer.appendChild(heartIcon);
    inputContainer.appendChild(userInput);
    inputContainer.appendChild(dropdownArrow);
    inputContainer.appendChild(dropdown);
    modMenu.appendChild(inputContainer);

    const savedNames = getStorageJSON(STORAGE_KEYS.SAVED_NAMES);
    updateDropdown(savedNames);
    updateHeartIcon();

    // ========== BUILD BUTTONS CONTAINER ==========
    const buildButtonsContainer = createElement("div", null, { id: "buildButtonsContainer" });
    modMenu.appendChild(buildButtonsContainer);

    function createButton(buttonData) {
        const buttonContainer = createElement("div", null, {
            style: {
                display: "flex",
                alignItems: "center",
                justifyContent: "center"
            }
        });

        const editButton = createElement("button", "edit-button", {
            textContent: "🖉",
            onclick: () => createEditPopup(buttonContainer, buttonData)
        });

        const button = createElement("button", "button", {
            textContent: buttonData.name,
            style: { backgroundColor: buttonData.color },
            onclick: () => spawnWithBuild(buttonData.cmd)
        });

        buttonContainer.appendChild(editButton);
        buttonContainer.appendChild(button);
        buildButtonsContainer.appendChild(buttonContainer);
    }

    // Load saved buttons
    const savedButtons = getStorageJSON(STORAGE_KEYS.SAVED_BUTTONS);
    savedButtons.forEach(createButton);

    // ========== ADD BUILD BUTTON ==========
    const specialButton = createElement("button", null, {
        id: "specialButton",
        textContent: "[+]",
        onclick: () => {
            const popupId = "createBuildPopup";
            const popup = createPopup("Drag me", popupId);

            const buildNameInput = createElement("input", null, {
                type: "text",
                placeholder: "Build Name",
                style: {
                    display: "block",
                    width: "80%",
                    margin: "0 auto 10px auto"
                }
            });

            popup.appendChild(buildNameInput);

            const { container, getCode } = createAttributeEditor(popupId);
            popup.appendChild(container);

            const createBuildButton = createElement("button", null, {
                textContent: "Create Build",
                style: {
                    display: "block",
                    margin: "20px auto 0 auto",
                    width: "80%",
                    fontSize: "18px",
                    padding: "10px",
                    backgroundColor: "white",
                    border: "2px solid black",
                    borderRadius: "5px",
                    cursor: "pointer"
                },
                onclick: () => {
                    const buildName = buildNameInput.value.trim();
                    if (!buildName) {
                        alert("Please enter a build name.");
                        return;
                    }

                    const newButtonData = {
                        name: buildName,
                        color: "#C0C0C0",
                        cmd: getCode()
                    };

                    const savedButtons = getStorageJSON(STORAGE_KEYS.SAVED_BUTTONS);
                    savedButtons.push(newButtonData);
                    setStorageJSON(STORAGE_KEYS.SAVED_BUTTONS, savedButtons);

                    createButton(newButtonData);
                    document.body.removeChild(popup);
                }
            });

            popup.appendChild(createBuildButton);
        }
    });

    modMenu.appendChild(specialButton);

    // ========== RESET BUTTON ==========
    const topRightButton = createElement("button", null, {
        id: "topRightButton",
        textContent: "↻",
        onclick: () => {
            const resetPopup = createPopup("Reset Confirmation");

            const confirmationMessage = createElement("div", null, {
                textContent: "Do you really want to reset to default builds?",
                style: {
                    textAlign: "center",
                    marginBottom: "20px"
                }
            });

            const buttonsContainer = createElement("div", null, {
                style: {
                    display: "flex",
                    justifyContent: "space-between"
                }
            });

            const noButton = createElement("button", "button", {
                textContent: "NO",
                onclick: () => document.body.removeChild(resetPopup)
            });

            const yesButton = createElement("button", "button", {
                textContent: "YES",
                onclick: () => {
                    localStorage.removeItem(STORAGE_KEYS.SAVED_BUTTONS);
                    localStorage.removeItem(STORAGE_KEYS.REMOVED_DEFAULTS);
                    location.reload();
                }
            });

            buttonsContainer.appendChild(noButton);
            buttonsContainer.appendChild(yesButton);
            resetPopup.appendChild(confirmationMessage);
            resetPopup.appendChild(buttonsContainer);
        }
    });

    modMenu.appendChild(topRightButton);
    hoverMenu.appendChild(modMenu);
    document.body.appendChild(hoverMenu);

    // ========== KEYBOARD SHORTCUT ==========
    document.addEventListener("keydown", (event) => {
        if ((event.key === "r" || event.key === "R") && 
            !["INPUT", "TEXTAREA"].includes(event.target.tagName)) {
            toggleVisibility(document.getElementById("myhover"));
        }
    });
})();