WhatsApp Sticker Creator with Custom Maker Enhanced

在WhatsApp Web中创建自定义贴纸。

当前为 2025-02-24 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         WhatsApp Sticker Creator with Custom Maker Enhanced
// @version      1.1
// @description  Create custom stickers in WhatsApp Web.
// @description:af  Skep persoonlike stickertjies in WhatsApp Web.
// @description:ar  إنشاء ملصقات مخصصة في WhatsApp Web.
// @description:az  WhatsApp Web-də fərdi stikerlər yaradın.
// @description:bg  Създаване на персонализирани стикери в WhatsApp Web.
// @description:bn  WhatsApp Web-এ কাস্টম স্টিকার তৈরি করুন।
// @description:bs  Kreirajte prilagođene naljepnice u WhatsApp Webu.
// @description:ca  Crea gomets personalitzats a WhatsApp Web.
// @description:cs  Vytvářejte vlastní nálepky ve WhatsApp Webu.
// @description:cy  Creu stickeriaid addasedig yn WhatsApp Web.
// @description:da  Opret brugerdefinerede stickers i WhatsApp Web.
// @description:de  Erstellen Sie benutzerdefinierte Aufkleber in WhatsApp Web.
// @description:el  Δημιουργήστε προσαρμοσμένα αυτοκόλλητα στο WhatsApp Web.
// @description:en  Create custom stickers in WhatsApp Web.
// @description:eo  Kreu proprajn glumarkojn en WhatsApp Web.
// @description:es  Crear stickers personalizados en WhatsApp Web.
// @description:et  Looge WhatsApp Web-is kohandatud kleepsud.
// @description:eu  Sortu pertsonalizatutako itsaskiak WhatsApp Web-en.
// @description:fa  ایجاد برچسب‌های سفارشی در WhatsApp Web.
// @description:fi  Luo mukautettuja tarranauhoja WhatsApp Webiin.
// @description:fr  Créer des autocollants personnalisés dans WhatsApp Web.
// @description:gl  Crea adhesivos personalizados en WhatsApp Web.
// @description:gu  WhatsApp Web માં કસ્ટમ સ્ટિકર્સ બનાવો.
// @description:he  צור מדבקות מותאמות אישית ב-WhatsApp Web.
// @description:hi  WhatsApp Web में कस्टम स्टिकर बनाएं।
// @description:hr  Stvorite prilagođene naljepnice u WhatsApp Webu.
// @description:hu  Hozzon létre egyéni matricákat a WhatsApp Webben.
// @description:id  Buat stiker kustom di WhatsApp Web.
// @description:it  Crea sticker personalizzati su WhatsApp Web.
// @description:ja  WhatsApp Webでカスタムステッカーを作成します。
// @description:ka  შექმენით მორგებული სტიკერები WhatsApp Web-ში.
// @description:kk  WhatsApp Web-де тұтынушыға сәйкес таңбалар жасаңыз.
// @description:km  បង្កើតស្លាកតាមតម្រូវការនៅលើ WhatsApp Web។
// @description:kn  WhatsApp Web ನಲ್ಲಿ ಅನುಗುಣವಾದ ಸ್ಟಿಕರ್‌ಗಳನ್ನು ರಚಿಸಿ.
// @description:ko  WhatsApp 웹에서 사용자 정의 스티커를 만듭니다.
// @description:ku  Di WhatsApp Web de stikerên xwerû biafirîne.
// @description:ky  WhatsApp Web'de кардардын көңүлүнө ылайыктуу стикерлерди түзгүлө.
// @description:lt  Sukurkite pasirinktinius lipdukus „WhatsApp Web“.
// @description:lv  Izveidojiet pielāgotas uzlīmes WhatsApp tīmeklī.
// @description:mk  Креирајте прилагодени стикери во WhatsApp Web.
// @description:ml  WhatsApp വെബിൽ ആവശ്യമനുസരിച്ച് സ്റ്റിക്കർ സൃഷ്ടിക്കുക.
// @description:mn  WhatsApp Web дээр өөрийн хүссэн шошго үүсгэх.
// @description:mr  WhatsApp Web मध्ये कस्टम स्टिकर तयार करा.
// @description:ms  Cipta pelekat tersuai di WhatsApp Web.
// @description:my  WhatsApp Web တွင်စိတ်ကြိုက်သတ်မှတ်ထားသော နှိပ်ပုံများဖန်တီးပါ။
// @description:nb  Lag egne klistremerker i WhatsApp Web.
// @description:ne  WhatsApp वेबमा अनुकूलित स्टिकरहरू सिर्जना गर्नुहोस्।
// @description:nl  Maak aangepaste stickers in WhatsApp Web.
// @description:nn  Lag tilpassa klistremerke i WhatsApp Web.
// @description:no  Lag egne klistremerker i WhatsApp Web.
// @description:pa  WhatsApp ਵੈਬ ਵਿੱਚ ਕਸਟਮ ਸਟਿੱਕਰ ਬਣਾਓ।
// @description:pl  Twórz niestandardowe naklejki w WhatsApp Web.
// @description:pt  Criar adesivos personalizados no WhatsApp Web.
// @description:ro  Creați autocolante personalizate în WhatsApp Web.
// @description:ru  Создавайте собственные стикеры в WhatsApp Web.
// @description:si  WhatsApp Web හි විශේෂිත සටිකර සාදන්න.
// @description:sk  Vytvorte vlastné nálepky v službe WhatsApp Web.
// @description:sl  Ustvarite prilagojene nalepke v WhatsApp Spletu.
// @description:sq  Krijoni ngjitës të personalizuar në WhatsApp Web.
// @description:sr  Направите прилагодљиве налепнице у ВхатсАпп Вебу.
// @description:sv  Skapa anpassade klistermärken i WhatsApp Web.
// @description:sw  Tengeneza lebo maalum katika WhatsApp Web.
// @description:ta  WhatsApp வலைதளத்தில் தனிப்பயனாக அட்டைகள் உருவாக்கவும்.
// @description:te  WhatsApp వెబ్‌లో అనుకూలిత స్టికర్లు సృష్టించండి.
// @description:th สร้างสติกเกอร์แบบกำหนดเองใน WhatsApp Web
// @description:tr  WhatsApp Web'de özel etiketler oluşturun.
// @description:uk  Створюйте власні наклейки в WhatsApp Web.
// @description:ur  WhatsApp ویب میں کسٹم اسٹکر بنائیں۔
// @description:uz  WhatsApp Web-da maxsus stikerlar yarating.
// @description:vi  Tạo nhãn dán tùy chỉnh trong WhatsApp Web.
// @description:zh  在WhatsApp Web中创建自定义贴纸。
// @description:zh-CN 在WhatsApp Web中创建自定义贴纸。
// @description:zh-TW 在WhatsApp Web中建立自訂貼紙。
// @author       DeveloperMDCM
// @match        https://web.whatsapp.com/
// @icon         https://static-00.iconduck.com/assets.00/whatsapp-icon-1020x1024-iykox85t.png
// @grant        GM_addStyle
// @run-at       document-end
// @compatible chrome
// @compatible firefox
// @compatible opera
// @compatible safari
// @compatible edge
// @license MIT
// @namespace https://github.com/DeveloperMDCM/
// @homepage     https://github.com/DeveloperMDCM/
// ==/UserScript==

(function () {
    'use strict';
    console.log('Script en ejecución by: DeveloperMDCM');
    const HEADER_STYLE = 'color: #F00; font-size: 24px; font-family: sans-serif;';
    const MESSAGE_STYLE = 'color: #00aaff; font-size: 16px; font-family: sans-serif;';
    const CODE_STYLE = 'font-size: 14px; font-family: monospace;';
  
    console.log(
      '%cStiker Maker for Whatsapp Web\n' +
        '%cRun %c(v1.0)\n' +
        'By: DeveloperMDCM.',
      HEADER_STYLE,
      CODE_STYLE,
      MESSAGE_STYLE
    );
  
    // Variables globales para rotación y hover
    let isRotating = false;
    let initialRotateAngle = 0;
    let initialElementRotation = 0;
    let hoveredElement = null;
    let currentMousePos = { x: 0, y: 0 };
    const colorsText = ["#000000", "#ff0000", "#00ff00", "#0000ff", "#ffff00", "#00ffff", "#ff00ff", "#ffffff", "#ff000000"];

    GM_addStyle(`
        /* Panel principal */
        #stickerPanel {
            position: fixed;
            top: 0;
            right: 0;
            width: 580px;
            height: auto;
            max-height: 90vh;
            overflow-y: auto;
            background-color: #111b21;
            border: 1px solid #202c33;
            padding: 10px;
            z-index: 10000;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        }
        /* Pestañas */
        .tabsContainer {
            display: flex;
            justify-content: space-around;
            margin-bottom: 10px;
        }
        .tabsContainer button {
            flex: 1;
            padding: 8px;
            border: none;
            cursor: pointer;
            background-color: #005c4b;
            color: #fff;
            font-weight: bold;
        }
        .tabsContainer button:first-child { margin-right: 5px; }
        .tabsContainer button:last-child { margin-left: 5px; }
        /* Sección Clásica */
        .dropZone {
            border: 2px dashed #ccc;
            padding: 20px;
            text-align: center;
            margin-bottom: 10px;
            cursor: pointer;
            background-color: #111b21;
        }
        input[type="file"] { display: none; }
        #createSticker, #createCustomSticker {
            width: 100%;
            padding: 8px;
            margin-top: 5px;
            background-color: #005c4b;
            border: none;
            color: #fff;
            font-weight: bold;
            border-radius: 3px;
        }
        #status, #customStatus {
            font-size: 12px;
            color: #555;
            text-align: center;
            margin-top: 5px;
        }
        #previewCanvas { display: none; }
        /* Sección Personalizada */
        #customSection { display: none; }
        /* Toolbar y menús emergentes */
        #customToolbar {
            display: flex;
            flex-wrap: wrap;
            gap: 5px;
            margin-bottom: 5px;
            align-items: center;
        }
        #customToolbar button {
            padding: 5px 8px;
            cursor: pointer;
            border: none;
            background-color: #005c4b;
            color: #fff;
            border-radius: 3px;
        }
        #customToolbar select { padding: 4px; }
        /* Panel de opciones del lápiz y de formas */
        #pencilOptionsPanel, #shapeOptionsPanel {
            display: none;
            margin: 5px 0;
            padding: 5px;
            border: 1px solid #ddd;
            background-color: #005c4b;
            font-size: 12px;
            border-radius: 3px;
        }
        /* Botones de color y tamaño */
        .colorButton, .sizeButton {
            width: 15px;
            height: 15px;
            border-radius: 50%;
            border: 2px solid #ccc;
            display: inline-block;
            margin: 2px;
            cursor: pointer;
        }
        .sizeButton[data-size="2"] { width: 8px; height: 8px; }
        .sizeButton[data-size="4"] { width: 12px; height: 12px; }
        .sizeButton[data-size="6"] { width: 16px; height: 16px; }
        .sizeButton[data-size="8"] { width: 20px; height: 20px; }
        #pencilColorContainer, #pencilSizeContainer { display: inline-block; vertical-align: middle; }
        /* Panel para formas */
        #shapeOptionsPanel button {
            margin-right: 5px;
            padding: 3px 6px;
            border: none;      
            color: #fff;
            border-radius: 3px;
            cursor: pointer;
        }
        /* Área de canvas con fondo ajedrezado */
        .canvasContainer {
            border: 2px dashed #ccc;
            width: 100%;
            height: 60vh;
            max-height: 60vh;
            margin: auto;
            position: relative;
        }
        #customCanvas {
            width: 100%;
            height: 100%;
            background-size: 20px 20px;
            background-image:
              linear-gradient(45deg, #ccc 25%, transparent 25%),
              linear-gradient(-45deg, #ccc 25%, transparent 25%),
              linear-gradient(45deg, transparent 75%, #ccc 75%),
              linear-gradient(-45deg, #fff 75%, #ccc 75%);
            background-size: 20px 20px;
            background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
            display: block;
        }
        /* Botón flotante */
        #openStickerPanel {
            position: fixed;
            bottom: 20px;
            right: 20px;
            padding: 10px 15px;
            background-color: #005c4b;
            color: #fff;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            z-index: 10000;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
        }
        /* Panel de edición de texto */
        #textEditorPanel {
            margin-top: 10px;
            padding: 5px;
         
            display: none;
            border-radius: 3px;
        }
        #textEditorPanel label { margin: 3px 5px; }
        /* Panel de emojis */
        #emojiContainer {
            position: fixed;
            top: 0;
            right: 600px;
            width: auto;
            height: 400px;
            background-color: #111b21;
            border: 1px solid #ddd;
            box-shadow: 0 4px 12px rgba(0,0,0,0.2);
            z-index: 10000;
            display: none;
            flex-direction: column;
            border-radius: 3px;
        }
        #emojiCategoryContainer {
            display: flex;
            justify-content: space-around;
            padding: 5px;
        }
        #emojiCategoryContainer button {
            background-color: #005c4b;
            color: #fff;
            border: none;
            padding: 5px;
            cursor: pointer;
            flex: 1;
            margin: 0 2px;
            border-radius: 3px;
        }
        #emojiContent {
            overflow-y: auto;
            height: 350px;
            padding: 10px 0 30px 10px;
            display: grid;
            background-color: black;
            grid-template-columns: repeat(6, 1fr);
            gap: 5px;
        }
        #textFontSelect {
        width: auto;
            appearance: auto;
        }
         #textFontSelect:not(:invalid) {
        color: #fff;
        }
        .textEditorContent {
          display: flex;
          flex-direction: column;
          gap: 6px;
        }
    `);

    // =========================
    // Espera a que la página se cargue
    // =========================
    window.addEventListener("load", () => { setTimeout(initStickerTool, 3000); });


    const emojis = {
        faces_emotion: [
            { "emoji": "😀" }, { "emoji": "😁" }, { "emoji": "😂" }, { "emoji": "🤣" },
            { "emoji": "😃" }, { "emoji": "😄" }, { "emoji": "😅" }, { "emoji": "😆" },
            { "emoji": "😉" }, { "emoji": "😊" }, { "emoji": "😋" }, { "emoji": "😎" },
            { "emoji": "😍" }, { "emoji": "😘" }, { "emoji": "🥰" }, { "emoji": "😗" },
            { "emoji": "😙" }, { "emoji": "🥲" }, { "emoji": "😚" }, { "emoji": "☺️" },
            { "emoji": "🙂" }, { "emoji": "🤗" }, { "emoji": "🤩" }, { "emoji": "🤔" },
            { "emoji": "🫡" }, { "emoji": "🤨" }, { "emoji": "😐" }, { "emoji": "😑" },
            { "emoji": "😶" }, { "emoji": "🫥" }, { "emoji": "😶‍🌫️" }, { "emoji": "🙄" },
            { "emoji": "😏" }, { "emoji": "😣" }, { "emoji": "😥" }, { "emoji": "😮" },
            { "emoji": "🤐" }, { "emoji": "😯" }, { "emoji": "😪" }, { "emoji": "😫" },
            { "emoji": "🥱" }, { "emoji": "😴" }, { "emoji": "😌" }, { "emoji": "😛" },
            { "emoji": "😜" }, { "emoji": "😝" }, { "emoji": "🤤" }, { "emoji": "😒" },
            { "emoji": "😓" }, { "emoji": "😔" }, { "emoji": "😕" }, { "emoji": "🫤" },
            { "emoji": "🙃" }, { "emoji": "🫠" }, { "emoji": "🤑" }, { "emoji": "😲" },
            { "emoji": "☹️" }, { "emoji": "🙁" }, { "emoji": "😖" }, { "emoji": "😞" },
            { "emoji": "😟" }, { "emoji": "😤" }, { "emoji": "😢" }, { "emoji": "😭" },
            { "emoji": "😦" }, { "emoji": "😧" }, { "emoji": "😨" }, { "emoji": "😩" },
            { "emoji": "🤯" }, { "emoji": "😬" }, { "emoji": "😮‍💨" }, { "emoji": "😰" },
            { "emoji": "😱" }, { "emoji": "🥵" }, { "emoji": "🥶" }, { "emoji": "😳" },
            { "emoji": "🤪" }, { "emoji": "😵" }, { "emoji": "😵‍💫" }, { "emoji": "🥴" },
            { "emoji": "😠" }, { "emoji": "😡" }, { "emoji": "🤬" }, { "emoji": "😷" },
            { "emoji": "🤒" }, { "emoji": "🤕" }, { "emoji": "🤢" }, { "emoji": "🤮" },
            { "emoji": "🤧" }, { "emoji": "😇" }, { "emoji": "🥳" }, { "emoji": "🥸" },
            { "emoji": "🥺" }, { "emoji": "🥹" }, { "emoji": "🤠" }, { "emoji": "🤡" },
            { "emoji": "🤥" }, { "emoji": "🫨" }, { "emoji": "🤫" }, { "emoji": "🤭" },
            { "emoji": "🫢" }, { "emoji": "🫣" }, { "emoji": "🧐" }, { "emoji": "🤓" },
            { "emoji": "😈" }, { "emoji": "👿" }, { "emoji": "👹" }, { "emoji": "👺" },
            { "emoji": "💀" }, { "emoji": "☠️" }, { "emoji": "👻" }, { "emoji": "👽" },
            { "emoji": "👾" }, { "emoji": "💩" }, { "emoji": "🤖" }
        ],
        animals: [
            { "emoji": "😺" }, { "emoji": "😸" }, { "emoji": "😹" }, { "emoji": "😻" },
            { "emoji": "😼" }, { "emoji": "😽" }, { "emoji": "🙀" }, { "emoji": "😿" },
            { "emoji": "😾" }, { "emoji": "🙈" }, { "emoji": "🙉" }, { "emoji": "🙊" },
            { "emoji": "🐵" }, { "emoji": "🐶" }, { "emoji": "🐺" }, { "emoji": "🐱" },
            { "emoji": "🦁" }, { "emoji": "🐯" }, { "emoji": "🦒" }, { "emoji": "🦊" },
            { "emoji": "🦝" }, { "emoji": "🐮" }, { "emoji": "🐷" }, { "emoji": "🐗" },
            { "emoji": "🐭" }, { "emoji": "🐹" }, { "emoji": "🐰" }, { "emoji": "🐻" },
            { "emoji": "🐨" }, { "emoji": "🐼" }, { "emoji": "🐸" }, { "emoji": "🦓" },
            { "emoji": "🐴" }, { "emoji": "🫎" }, { "emoji": "🫏" }, { "emoji": "🦄" },
            { "emoji": "🐔" }, { "emoji": "🐲" }, { "emoji": "🐽" }, { "emoji": "🐾" },
            { "emoji": "🐒" }, { "emoji": "🦍" }, { "emoji": "🦧" }, { "emoji": "🦮" },
            { "emoji": "🐩" }, { "emoji": "🐕" }, { "emoji": "🐈" }, { "emoji": "🐅" },
            { "emoji": "🐆" }, { "emoji": "🦌" }, { "emoji": "🦬" }, { "emoji": "🦏" },
            { "emoji": "🐘" }, { "emoji": "🐁" }, { "emoji": "🐀" }, { "emoji": "🦔" },
            { "emoji": "🐇" }, { "emoji": "🦎" }, { "emoji": "🐊" }, { "emoji": "🐢" },
            { "emoji": "🐍" }, { "emoji": "🐉" }, { "emoji": "🦕" }, { "emoji": "🦖" },
            { "emoji": "🐬" }, { "emoji": "🐳" }, { "emoji": "🐋" }, { "emoji": "🐟" },
            { "emoji": "🐠" }, { "emoji": "🐡" }, { "emoji": "🦀" }, { "emoji": "🐚" }
        ]
    };

    function initStickerTool() {
        if (document.getElementById("stickerPanel")) return;

        // Crear panel principal
        const panel = document.createElement("div");
        panel.id = "stickerPanel";
        panel.style.display = "none";
        // Pestañas
        const tabsContainer = document.createElement("div");
        tabsContainer.className = "tabsContainer";
        const btnClassic = document.createElement("button");
        btnClassic.textContent = "Classic Sticker";
        const btnCustom = document.createElement("button");
        btnCustom.textContent = "Custom Sticker";
        tabsContainer.appendChild(btnClassic);
        tabsContainer.appendChild(btnCustom);
        panel.appendChild(tabsContainer);

        // Sección Clásica
        const classicSection = document.createElement("div");
        classicSection.id = "classicSection";
        classicSection.innerHTML = `
            <div id="dropZone" class="dropZone">Drag or click to select image</div>
            <input type="file" id="fileInput" accept="image/*" />
            <button id="createSticker" disabled>Create Sticker</button>
            <p id="status"></p>
            <canvas id="previewCanvas"></canvas>
        `;
        panel.appendChild(classicSection);

        // Sección Personalizada
        const customSection = document.createElement("div");
        customSection.id = "customSection";
        customSection.innerHTML = `

            <!-- Toolbar con íconos -->
            <div id="customToolbar">
             <button id="addCustomImage"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-photo-plus"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 8h.01" /><path d="M12.5 21h-6.5a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v6.5" /><path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l4 4" /><path d="M14 14l1 -1c.67 -.644 1.45 -.824 2.182 -.54" /><path d="M16 19h6" /><path d="M19 16v6" /></svg></button>
                <button id="openEmojiPanel"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-mood-smile"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /><path d="M9 10l.01 0" /><path d="M15 10l.01 0" /><path d="M9.5 15a3.5 3.5 0 0 0 5 0" /></svg></button>
                <input type="file" id="customFileInput" accept="image/*" />
                <button id="toggleDrawing"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-pencil"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" /><path d="M13.5 6.5l4 4" /></svg></button>
                <button id="toggleShapes"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-square"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" /></svg></button>
                <button id="bringForward"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-layers-selected"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M8 10.5l6.492 -6.492" /><path d="M13.496 16l6.504 -6.504z" /><path d="M8.586 15.414l10.827 -10.827" /><path d="M8 6a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z" /><path d="M16 16v2a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2v-8a2 2 0 0 1 2 -2h2" /></svg></button>
                <button id="sendBackward"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-layers-selected-bottom"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 14.5l4 -4" /><path d="M9.496 20l4.004 -4z" /><path d="M4.586 19.414l3.914 -3.914" /><path d="M8 6a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z" /><path d="M16 16v2a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2v-8a2 2 0 0 1 2 -2h2" /></svg></button>
                <button id="deleteElement"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-trash"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 7l16 0" /><path d="M10 11l0 6" /><path d="M14 11l0 6" /><path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12" /><path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3" /></svg></button>
                <button id="clearCanvas"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-restore"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3.06 13a9 9 0 1 0 .49 -4.087" /><path d="M3 4.001v5h5" /><path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /></svg></button>
                <button id="toggleMultiSelect"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-select-all"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M8 8m0 1a1 1 0 0 1 1 -1h6a1 1 0 0 1 1 1v6a1 1 0 0 1 -1 1h-6a1 1 0 0 1 -1 -1z" /><path d="M12 20v.01" /><path d="M16 20v.01" /><path d="M8 20v.01" /><path d="M4 20v.01" /><path d="M4 16v.01" /><path d="M4 12v.01" /><path d="M4 8v.01" /><path d="M4 4v.01" /><path d="M8 4v.01" /><path d="M12 4v.01" /><path d="M16 4v.01" /><path d="M20 4v.01" /><path d="M20 8v.01" /><path d="M20 12v.01" /><path d="M20 16v.01" /><path d="M20 20v.01" /></svg></btton>
                <button id="addText"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-letter-t"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M6 4l12 0" /><path d="M12 4l0 16" /></svg></button>
                <button id="downloadImage"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-photo-down"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 8h.01" /><path d="M12.5 21h-6.5a3 3 0 0 1 -3 -3v-12a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v6.5" /><path d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l4 4" /><path d="M14 14l1 -1c.653 -.629 1.413 -.815 2.13 -.559" /><path d="M19 16v6" /><path d="M22 19l-3 3l-3 -3" /></svg></button>
                <button id="undo"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-arrow-back-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 14l-4 -4l4 -4" /><path d="M5 10h11a4 4 0 1 1 0 8h-1" /></svg></button>
                <button id="redo"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-arrow-forward-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M15 14l4 -4l-4 -4" /><path d="M19 10h-11a4 4 0 1 0 0 8h1" /></svg></button>
            </div>
            <!-- Panel emergente para opciones del lápiz -->
            <div id="pencilOptionsPanel">
                <div>Pincel - Colores:</div>
                <div id="pencilColorContainer"></div>
                <div>Pincel - Grosor:</div>
                <div id="pencilSizeContainer"></div>
            </div>
            <!-- Panel emergente para opciones de formas -->
            <div id="shapeOptionsPanel">
                <button id="shapeSquare"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-square"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" /></svg></button>
                <button id="shapeCircle"><svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-circle"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /></svg></button>
            </div>
            <div class="canvasContainer">
                <canvas id="customCanvas" width="512" height="512"></canvas>
            </div>
            <button id="createCustomSticker">Create Custom Sticker</button>
            <p id="customStatus"></p>
            <!-- Panel de edición de texto -->
            <div id="textEditorPanel">
              <div class="textEditorContent">
                <label>Text: <input type="text" id="textContentInput"></label>
               <div>
                <label>Color: <span id="textColorButtons"></span></label>
                <label>Bg: <span id="textBgButtons"></span></label>
               </div>
                <div>
                <label>Font:
                    <select id="textFontSelect">
                        <option value="" disabled selected>Select font</option>
                        <option value="Arial">Arial</option>
                        <option value="Courier New">Courier New</option>
                        <option value="Times New Roman">Times New Roman</option>
                        <option value="Verdana">Verdana</option>
                        <option value="Georgia">Georgia</option>
                    </select>
                </label>
                  <label>Size: <input type="range" id="textFontSizeInput" min="10" max="100" value="30"></label>
                </div>
              </dib>
              
            </div>
        `;
        panel.appendChild(customSection);

        document.body.appendChild(panel);

        // Botón flotante para abrir/cerrar el panel
        addFloatingButton(panel);

        // Configurar secciones
        setupClassicSection();
        setupCustomSection();

        // Cambio de pestañas
        btnClassic.addEventListener("click", () => {
            document.getElementById("classicSection").style.display = "block";
            document.getElementById("customSection").style.display = "none";
        });
        btnCustom.addEventListener("click", () => {
            document.getElementById("classicSection").style.display = "none";
            document.getElementById("customSection").style.display = "block";
        });
    }



    // Botón flotante
    function addFloatingButton(panel) {
        const btn = document.createElement("button");
        btn.id = "openStickerPanel";
        btn.textContent = "Sticker";
        btn.innerHTML = `<svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="2"  stroke-linecap="round"  stroke-linejoin="round"  class="icon icon-tabler icons-tabler-outline icon-tabler-sticker-2"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M6 4h12a2 2 0 0 1 2 2v7h-5a2 2 0 0 0 -2 2v5h-7a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2z" /><path d="M20 13v.172a2 2 0 0 1 -.586 1.414l-4.828 4.828a2 2 0 0 1 -1.414 .586h-.172" /></svg>`
        document.body.appendChild(btn);
        btn.addEventListener("click", () => {
            panel.style.display = panel.style.display === "none" ? "block" : "none";
            const emojiContainer = document.getElementById("emojiContainer");

            if (emojiContainer.style.display === "flex") {
                emojiContainer.style.display = "none";
            }
            else {
                emojiContainer.style.display = "none";
            }

        });
    }

    // =========================
    // MODO CLÁSICO
    // =========================
    function setupClassicSection() {
        const dropZone = document.getElementById("dropZone");
        const fileInput = document.getElementById("fileInput");
        const createStickerButton = document.getElementById("createSticker");
        const statusText = document.getElementById("status");
        const previewCanvas = document.getElementById("previewCanvas");
        let selectedImageCanvas = null;
        let createClicked = false;

        dropZone.addEventListener("click", () => fileInput.click());
        dropZone.addEventListener("dragover", (e) => { e.preventDefault(); dropZone.style.borderColor = "#000"; });
        dropZone.addEventListener("dragleave", (e) => { e.preventDefault(); dropZone.style.borderColor = "#ccc"; });
        dropZone.addEventListener("drop", (e) => {
            e.preventDefault();
            dropZone.style.borderColor = "#ccc";
            if (e.dataTransfer.files && e.dataTransfer.files[0]) { handleFile(e.dataTransfer.files[0]); }
        });
        fileInput.addEventListener("change", () => { if (fileInput.files && fileInput.files[0]) { handleFile(fileInput.files[0]); } });

        function handleFile(file) {

            const reader = new FileReader();
            reader.onload = function (event) {
                const img = new Image();
                img.onload = function () {
                    previewCanvas.width = previewCanvas.parentElement.clientWidth;
                    previewCanvas.height = previewCanvas.parentElement.clientHeight;
                    const ctx = previewCanvas.getContext("2d");
                    ctx.clearRect(0, 0, previewCanvas.width, previewCanvas.height);
                    const ratio = Math.min(previewCanvas.width / img.width, previewCanvas.height / img.height);
                    const newWidth = img.width * ratio;
                    const newHeight = img.height * ratio;
                    const dx = (previewCanvas.width - newWidth) / 2;
                    const dy = (previewCanvas.height - newHeight) / 2;
                    ctx.drawImage(img, dx, dy, newWidth, newHeight);
                    selectedImageCanvas = previewCanvas;
                    createStickerButton.disabled = false;
                    statusText.textContent = "Image uploaded successfully";
                    createClicked = false;
                };
                img.src = event.target.result;
            };
            reader.readAsDataURL(file);
        }

        createStickerButton.addEventListener("click", () => {
            if (!selectedImageCanvas || createClicked) return;
            createClicked = true;
            createStickerButton.disabled = true;
            statusText.textContent = "Generating sticker...";
            selectedImageCanvas.toBlob(function (blob) {
                if (!blob) { statusText.textContent = "Error al convertir la imagen."; return; }
                const stickerFile = new File([blob], "sticker.webp", { type: "image/webp" });
                simulateWhatsAppFileUpload(stickerFile, statusText);
            }, "image/webp");
        });
    }

    // =========================
    // MODO PERSONALIZADO (STICKER MAKER)
    // =========================
    function setupCustomSection() {
        const customCanvas = document.getElementById("customCanvas");
        const ctx = customCanvas.getContext("2d");
        customCanvas.width = customCanvas.offsetWidth;
        customCanvas.height = customCanvas.offsetHeight;
        const addCustomImageButton = document.getElementById("addCustomImage");
        const customFileInput = document.getElementById("customFileInput");
        const createCustomStickerButton = document.getElementById("createCustomSticker");
        const customStatus = document.getElementById("customStatus");
        const toggleDrawingButton = document.getElementById("toggleDrawing");
        const toggleShapesButton = document.getElementById("toggleShapes");
        const bringForwardButton = document.getElementById("bringForward");
        const sendBackwardButton = document.getElementById("sendBackward");
        const deleteElementButton = document.getElementById("deleteElement");
        const clearCanvasButton = document.getElementById("clearCanvas");
        const toggleMultiSelectButton = document.getElementById("toggleMultiSelect");
        const addTextButton = document.getElementById("addText");
        const fontSelect = document.getElementById("fontSelect");
        const downloadButton = document.getElementById("downloadImage");
        const undoButton = document.getElementById("undo");
        const redoButton = document.getElementById("redo");

        // Paneles emergentes
        const pencilOptionsPanel = document.getElementById("pencilOptionsPanel");
        const pencilColorContainer = document.getElementById("pencilColorContainer");
        const pencilSizeContainer = document.getElementById("pencilSizeContainer");
        const shapeOptionsPanel = document.getElementById("shapeOptionsPanel");
        const shapeSquareButton = document.getElementById("shapeSquare");
        const shapeCircleButton = document.getElementById("shapeCircle");

        // Panel de edición de texto
        const textEditorPanel = document.getElementById("textEditorPanel");
        const textContentInput = document.getElementById("textContentInput");
        const textColorButtons = document.getElementById("textColorButtons");
        const textBgButtons = document.getElementById("textBgButtons");
        const textFontSelect = document.getElementById("textFontSelect");
        const textFontSizeInput = document.getElementById("textFontSizeInput");

        // Variables internas para el lápiz
        let drawingColor = "#000000";
        const brushSizeInput = { value: 2 };

        // Variables para elementos en el canvas
        let customElements = [];
        let selectedElement = null;
        let isDrawingMode = false;
        let drawingInProgress = false;
        let currentDrawing = null;
        let customCreateClicked = false;
        let offsetX = 0, offsetY = 0;
        let isDragging = false;
        let isResizing = false, resizeStartX = 0, resizeStartY = 0;
        let originalFontSize = 0;
        let originalWidth = 0, originalHeight = 0;

        // Variables para multi-select
        let isMultiSelectMode = false;
        let multiSelectedElements = [];
        let multiSelectRect = null;
        let isGroupDragging = false;
        let groupDragStart = null;

        // Variables para undo/redo
        let history = [];
        let historyIndex = -1;

        function resizeCanvas() {
            const container = customCanvas.parentElement;
            customCanvas.width = container.clientWidth;
            customCanvas.height = container.clientHeight;
            drawCustomCanvas();
        }
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);

        function cloneCustomElements(elements) {
            return elements.map(el => {
                let newEl = Object.assign({}, el);
                if (el.points) newEl.points = el.points.map(p => ({ x: p.x, y: p.y }));
                if (el.type === "image" && el.img && el.img.src) {
                    const newImg = new Image();
                    newImg.src = el.img.src;
                    newEl.img = newImg;
                }
                return newEl;
            });
        }
        function saveHistory() {
            history = history.slice(0, historyIndex + 1);
            history.push(cloneCustomElements(customElements));
            historyIndex++;
        }

        // Helper: tamaño por defecto para imágenes
        function getDefaultImageSize(img) {
            let width = img.width, height = img.height;
            if (width > 300) {
                const ratio = 300 / width;
                width = img.width * ratio;
                height = img.height * ratio;
            }
            return { width, height };
        }

        // Función para detectar si un punto está en un elemento (considerando rotación)
        function isPointInElement(el, x, y) {
            if (el.rotation && el.rotation !== 0) {
                const cx = el.x + el.width / 2;
                const cy = el.y + el.height / 2;
                // Convertir (x,y) al sistema de coordenadas del elemento
                const dx = x - cx;
                const dy = y - cy;
                const angle = -el.rotation;
                const rx = dx * Math.cos(angle) - dy * Math.sin(angle);
                const ry = dx * Math.sin(angle) + dy * Math.cos(angle);
                return rx >= -el.width / 2 && rx <= el.width / 2 && ry >= -el.height / 2 && ry <= el.height / 2;
            } else {
                return x >= el.x && x <= el.x + el.width && y >= el.y && y <= el.y + el.height;
            }
        }

        // Variable para almacenar la posición actual del mouse
        let currentMousePos = { x: 0, y: 0 };

        // Función para dibujar un elemento (aplica rotación si tiene)
        function drawElement(el) {
            if (el.rotation && el.rotation !== 0) {
                const cx = el.x + el.width / 2, cy = el.y + el.height / 2;
                ctx.save();
                ctx.translate(cx, cy);
                ctx.rotate(el.rotation);
                if (el.type === "image") {
                    ctx.drawImage(el.img, -el.width / 2, -el.height / 2, el.width, el.height);
                } else if (el.type === "emoji") {
                    ctx.font = el.fontSize + "px sans-serif";
                    ctx.textBaseline = "top";
                    ctx.fillText(el.emoji, -el.width / 2, -el.height / 2);
                } else if (el.type === "drawing") {
                    ctx.beginPath();
                    el.points.forEach((p, index) => { index === 0 ? ctx.moveTo(p.x - cx, p.y - cy) : ctx.lineTo(p.x - cx, p.y - cy); });
                    ctx.strokeStyle = el.color; ctx.lineWidth = el.brushSize;
                    ctx.lineJoin = "round"; ctx.lineCap = "round"; ctx.stroke();
                } else if (el.type === "text") {
                    ctx.font = el.fontSize + "px " + el.fontFamily;
                    ctx.textBaseline = "top";
                    if (el.bgColor) {
                        const metrics = ctx.measureText(el.text);
                        const padding = 2;
                        ctx.fillStyle = el.bgColor;
                        ctx.fillRect(-el.width / 2 - padding, -el.height / 2 - padding, metrics.width + 2 * padding, el.fontSize + 2 * padding);
                    }
                    ctx.fillStyle = el.color;
                    ctx.fillText(el.text, -el.width / 2, -el.height / 2);
                } else if (el.type === "shape") {
                    ctx.strokeStyle = el.color; ctx.lineWidth = 2;
                    if (el.shape === "square") {
                        ctx.strokeRect(-el.width / 2, -el.height / 2, el.width, el.height);
                    } else if (el.shape === "circle") {
                        ctx.beginPath();
                        ctx.arc(0, 0, el.width / 2, 0, Math.PI * 2);
                        ctx.stroke();
                    }
                }
                ctx.restore();
            } else {
                if (el.type === "image") {
                    ctx.drawImage(el.img, el.x, el.y, el.width, el.height);
                } else if (el.type === "emoji") {
                    ctx.font = el.fontSize + "px sans-serif";
                    ctx.textBaseline = "top";
                    ctx.fillText(el.emoji, el.x, el.y);
                    const metrics = ctx.measureText(el.emoji);
                    el.width = metrics.width; el.height = el.fontSize;
                } else if (el.type === "drawing") {
                    ctx.beginPath();
                    el.points.forEach((p, index) => { index === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y); });
                    ctx.strokeStyle = el.color; ctx.lineWidth = el.brushSize;
                    ctx.lineJoin = "round"; ctx.lineCap = "round"; ctx.stroke();
                } else if (el.type === "text") {
                    ctx.font = el.fontSize + "px " + el.fontFamily;
                    ctx.textBaseline = "top";
                    if (el.bgColor) {
                        const metrics = ctx.measureText(el.text);
                        const padding = 2;
                        ctx.fillStyle = el.bgColor;
                        ctx.fillRect(el.x - padding, el.y - padding, metrics.width + 2 * padding, el.fontSize + 2 * padding);
                    }
                    ctx.fillStyle = el.color;
                    ctx.fillText(el.text, el.x, el.y);
                    const metrics = ctx.measureText(el.text);
                    el.width = metrics.width; el.height = el.fontSize;
                } else if (el.type === "shape") {
                    ctx.strokeStyle = el.color; ctx.lineWidth = 2;
                    if (el.shape === "square") ctx.strokeRect(el.x, el.y, el.width, el.height);
                    else if (el.shape === "circle") {
                        ctx.beginPath();
                        ctx.arc(el.x + el.width / 2, el.y + el.height / 2, el.width / 2, 0, Math.PI * 2);
                        ctx.stroke();
                    }
                }
            }
        }
        // Función para dibujar el canvas completo, incluyendo handles y resaltado por hover/selección
        function drawCustomCanvas(forceRedraw = false) {
            const rect = customCanvas.getBoundingClientRect();

            // Verificar si hay cambio de tamaño
            if (customCanvas.width !== rect.width || customCanvas.height !== rect.height || forceRedraw) {
                customCanvas.width = rect.width;
                customCanvas.height = rect.height;
            }

            ctx.clearRect(0, 0, customCanvas.width, customCanvas.height);
            customElements.forEach(el => { drawElement(el); });

            // Si hay un elemento hover (y no está seleccionado) se dibuja su borde en verde
            if (hoveredElement && hoveredElement !== selectedElement) {
                ctx.save();
                ctx.strokeStyle = "green";
                ctx.lineWidth = 2;
                if (hoveredElement.rotation && hoveredElement.rotation !== 0) {
                    const cx = hoveredElement.x + hoveredElement.width / 2;
                    const cy = hoveredElement.y + hoveredElement.height / 2;
                    ctx.translate(cx, cy);
                    ctx.rotate(hoveredElement.rotation);
                    ctx.strokeRect(-hoveredElement.width / 2, -hoveredElement.height / 2, hoveredElement.width, hoveredElement.height);
                } else {
                    ctx.strokeRect(hoveredElement.x, hoveredElement.y, hoveredElement.width, hoveredElement.height);
                }
                ctx.restore();
            }

            // Si hay un elemento seleccionado, dibujar borde verde, fondo semitransparente e indicadores
            if (selectedElement) {
                ctx.save();
                if (selectedElement.rotation && selectedElement.rotation !== 0) {
                    const cx = selectedElement.x + selectedElement.width / 2;
                    const cy = selectedElement.y + selectedElement.height / 2;
                    ctx.translate(cx, cy);
                    ctx.rotate(selectedElement.rotation);

                    // Fondo verde semitransparente y borde
                    ctx.fillStyle = "rgba(0,255,0,0.2)";
                    ctx.fillRect(-selectedElement.width / 2, -selectedElement.height / 2, selectedElement.width, selectedElement.height);
                    ctx.strokeStyle = "green";
                    ctx.lineWidth = 2;
                    ctx.strokeRect(-selectedElement.width / 2, -selectedElement.height / 2, selectedElement.width, selectedElement.height);

                    // Indicador de rotación (círculo verde con flecha)
                    ctx.beginPath();
                    ctx.arc(0, -selectedElement.height / 2 - 20, 8, 0, Math.PI * 2);
                    ctx.fillStyle = "green";
                    ctx.fill();
                    ctx.strokeStyle = "white";
                    ctx.lineWidth = 2;
                    // Dibujar flecha circular
                    ctx.beginPath();
                    ctx.arc(0, -selectedElement.height / 2 - 20, 12, -Math.PI / 2, Math.PI / 2, false);
                    ctx.stroke();
                    // Punta de la flecha
                    ctx.beginPath();
                    ctx.moveTo(4, -selectedElement.height / 2 - 20);
                    ctx.lineTo(8, -selectedElement.height / 2 - 24);
                    ctx.lineTo(12, -selectedElement.height / 2 - 20);
                    ctx.stroke();

                    // Indicador de redimensión (cuadrado verde)
                    ctx.fillStyle = "green";
                    ctx.fillRect(selectedElement.width / 2 - 8, selectedElement.height / 2 - 8, 16, 16);
                    ctx.strokeStyle = "white";
                    ctx.strokeRect(selectedElement.width / 2 - 8, selectedElement.height / 2 - 8, 16, 16);

                } else {
                    // Fondo verde semitransparente y borde
                    ctx.fillStyle = "rgba(0,255,0,0.2)";
                    ctx.fillRect(selectedElement.x, selectedElement.y, selectedElement.width, selectedElement.height);
                    ctx.strokeStyle = "green";
                    ctx.lineWidth = 2;
                    ctx.strokeRect(selectedElement.x, selectedElement.y, selectedElement.width, selectedElement.height);

                    // Indicador de rotación
                    ctx.beginPath();
                    ctx.arc(selectedElement.x + selectedElement.width / 2, selectedElement.y - 20, 8, 0, Math.PI * 2);
                    ctx.fillStyle = "green";
                    ctx.fill();
                    ctx.strokeStyle = "white";
                    ctx.lineWidth = 2;
                    // Dibujar flecha circular
                    ctx.beginPath();
                    ctx.arc(selectedElement.x + selectedElement.width / 2, selectedElement.y - 20, 12, -Math.PI / 2, Math.PI / 2, false);
                    ctx.stroke();
                    // Punta de la flecha
                    ctx.beginPath();
                    ctx.moveTo(selectedElement.x + selectedElement.width / 2 + 4, selectedElement.y - 20);
                    ctx.lineTo(selectedElement.x + selectedElement.width / 2 + 8, selectedElement.y - 24);
                    ctx.lineTo(selectedElement.x + selectedElement.width / 2 + 12, selectedElement.y - 20);
                    ctx.stroke();

                    // Indicador de redimensión
                    ctx.fillStyle = "green";
                    ctx.fillRect(selectedElement.x + selectedElement.width - 8, selectedElement.y + selectedElement.height - 8, 16, 16);
                    ctx.strokeStyle = "white";
                    ctx.strokeRect(selectedElement.x + selectedElement.width - 8, selectedElement.y + selectedElement.height - 8, 16, 16);
                }
                ctx.restore();
            }

            // Dibujar bordes azul dashed para multi-selección
            multiSelectedElements.forEach(el => {
                ctx.save();
                ctx.strokeStyle = "blue";
                ctx.lineWidth = 1;
                ctx.setLineDash([5, 5]);
                ctx.strokeRect(el.x, el.y, el.width, el.height);
                ctx.restore();
            });

            // Dibujar rectángulo de selección múltiple si está activo
            if (multiSelectRect) {
                ctx.save();
                ctx.strokeStyle = "blue";
                ctx.lineWidth = 1;
                ctx.setLineDash([5, 5]);
                const rx = Math.min(multiSelectRect.startX, multiSelectRect.currentX);
                const ry = Math.min(multiSelectRect.startY, multiSelectRect.currentY);
                const rw = Math.abs(multiSelectRect.currentX - multiSelectRect.startX);
                const rh = Math.abs(multiSelectRect.currentY - multiSelectRect.startY);
                ctx.strokeRect(rx, ry, rw, rh);
                ctx.restore();
            }
        }


        // Actualizar variable hoveredElement según la posición del mouse
        customCanvas.addEventListener("mousemove", (e) => {
            const rect = customCanvas.getBoundingClientRect();
            currentMousePos = { x: e.clientX - rect.left, y: e.clientY - rect.top };
            // Si no se está arrastrando, redimensionando, rotando o dibujando, detectar hover
            if (!isDragging && !isResizing && !isRotating && !drawingInProgress) {
                hoveredElement = null;
                for (let i = customElements.length - 1; i >= 0; i--) {
                    const el = customElements[i];
                    if (isPointInElement(el, currentMousePos.x, currentMousePos.y)) {
                        hoveredElement = el;
                        break;
                    }
                }
                drawCustomCanvas();
            }
        });

        // =============================
        // Eventos del canvas
        // =============================
        customCanvas.addEventListener("mousedown", (e) => {
            const rect = customCanvas.getBoundingClientRect();
            const x = e.clientX - rect.left, y = e.clientY - rect.top;
            // Si hay un elemento seleccionado, comprobar handle de rotación
            if (selectedElement) {
                const cx = selectedElement.x + selectedElement.width / 2;
                const cy = selectedElement.y + selectedElement.height / 2;
                const rot = selectedElement.rotation || 0;
                const handleOffset = { x: 0, y: -(selectedElement.height / 2 + 20) };
                const rx = cx + handleOffset.x * Math.cos(rot) - handleOffset.y * Math.sin(rot);
                const ry = cy + handleOffset.x * Math.sin(rot) + handleOffset.y * Math.cos(rot);
                if (distance({ x, y }, { x: rx, y: ry }) < 15) {
                    isRotating = true;
                    initialRotateAngle = Math.atan2(y - cy, x - cx);
                    initialElementRotation = selectedElement.rotation || 0;
                    return;
                }
                // Comprobar handle de resize
                const vectorBR = { x: selectedElement.width / 2, y: selectedElement.height / 2 };
                const brx = cx + vectorBR.x * Math.cos(rot) - vectorBR.y * Math.sin(rot);
                const bry = cy + vectorBR.x * Math.sin(rot) + vectorBR.y * Math.cos(rot);
                if (distance({ x, y }, { x: brx, y: bry }) < 15) {
                    isResizing = true;
                    resizeStartX = x; resizeStartY = y;
                    if (selectedElement.type === "text" || selectedElement.type === "emoji") {
                        originalWidth = selectedElement.width;
                        originalFontSize = selectedElement.fontSize;
                    } else {
                        originalWidth = selectedElement.width;
                        originalHeight = selectedElement.height;
                    }
                    return;
                }
            }
            if (isDrawingMode) {
                drawingInProgress = true;
                currentDrawing = { type: "drawing", points: [{ x, y }], color: drawingColor, brushSize: brushSizeInput.value, rotation: 0 };
                selectedElement = null;
            } else if (isMultiSelectMode) {
                let inSelected = multiSelectedElements.some(el => x >= el.x && x <= el.x + el.width && y >= el.y && y <= el.y + el.height);
                if (inSelected && multiSelectedElements.length > 0) {
                    isGroupDragging = true;
                    groupDragStart = { startX: x, startY: y, positions: multiSelectedElements.map(el => ({ x: el.x, y: el.y })) };
                } else {
                    multiSelectRect = { startX: x, startY: y, currentX: x, currentY: y };
                    multiSelectedElements = [];
                }
                selectedElement = null;
            } else {
                let found = false;
                for (let i = customElements.length - 1; i >= 0; i--) {
                    const el = customElements[i];
                    if (el.type === "drawing") {
                        const xs = el.points.map(p => p.x), ys = el.points.map(p => p.y);
                        const minX = Math.min(...xs), maxX = Math.max(...xs);
                        const minY = Math.min(...ys), maxY = Math.max(...ys);
                        if (x >= minX && x <= maxX && y >= minY && y <= maxY) { selectedElement = el; offsetX = x - minX; offsetY = y - minY; found = true; break; }
                    } else {
                        if (isPointInElement(el, x, y)) {
                            selectedElement = el;
                            if (x >= el.x + el.width - 15 && x <= el.x + el.width + 15 && y >= el.y + el.height - 15 && y <= el.y + el.height + 15) {
                                isResizing = true;
                                resizeStartX = x; resizeStartY = y;
                                if (el.type === "text" || el.type === "emoji") {
                                    originalWidth = el.width; originalFontSize = el.fontSize;
                                } else {
                                    originalWidth = el.width; originalHeight = el.height;
                                }
                            } else {
                                isDragging = true;
                                offsetX = x - el.x; offsetY = y - el.y;
                            }
                            found = true; break;
                        }
                    }
                }
                if (!found) { selectedElement = null; }
                drawCustomCanvas();
                updateTextEditorPanel();
            }
        });

        customCanvas.addEventListener("mousemove", (e) => {
            const rect = customCanvas.getBoundingClientRect();
            const x = e.clientX - rect.left, y = e.clientY - rect.top;
            currentMousePos = { x, y };
            // Si se está en modo rotación
            if (isRotating && selectedElement) {
                const cx = selectedElement.x + selectedElement.width / 2;
                const cy = selectedElement.y + selectedElement.height / 2;
                const currentAngle = Math.atan2(y - cy, x - cx);
                selectedElement.rotation = initialElementRotation + (currentAngle - initialRotateAngle);
                drawCustomCanvas();
                return;
            }
            if (isDrawingMode && drawingInProgress && currentDrawing) {
                currentDrawing.points.push({ x, y });
                drawCustomCanvas();
                ctx.strokeStyle = currentDrawing.color;
                ctx.lineWidth = currentDrawing.brushSize;
                ctx.lineJoin = "round"; ctx.lineCap = "round";
                ctx.beginPath();
                currentDrawing.points.forEach((point, index) => { index === 0 ? ctx.moveTo(point.x, point.y) : ctx.lineTo(point.x, point.y); });
                ctx.stroke();
            } else if (isMultiSelectMode) {
                if (isGroupDragging && groupDragStart) {
                    const deltaX = x - groupDragStart.startX, deltaY = y - groupDragStart.startY;
                    multiSelectedElements.forEach((el, idx) => {
                        const initPos = groupDragStart.positions[idx];
                        el.x = initPos.x + deltaX; el.y = initPos.y + deltaY;
                    });
                    drawCustomCanvas();
                } else if (multiSelectRect) {
                    multiSelectRect.currentX = x; multiSelectRect.currentY = y;
                    drawCustomCanvas();
                } else if (isDragging && selectedElement && !isDrawingMode && !isResizing && !isRotating) {
                    selectedElement.x = x - offsetX; selectedElement.y = y - offsetY;
                    drawCustomCanvas();
                }
            } else {
                if (isResizing && selectedElement) {
                    let newWidth = originalWidth + (x - resizeStartX);
                    if (newWidth < 20) newWidth = 20;
                    if (selectedElement.type === "text" || selectedElement.type === "emoji") {
                        let scale = newWidth / originalWidth;
                        selectedElement.fontSize = originalFontSize * scale;
                        selectedElement.width = newWidth;
                        selectedElement.height = originalFontSize * scale;
                    } else {
                        let newHeight = originalHeight + (y - resizeStartY);
                        if (newHeight < 20) newHeight = 20;
                        selectedElement.width = newWidth; selectedElement.height = newHeight;
                    }
                    drawCustomCanvas();
                } else if (isDragging && selectedElement && !isDrawingMode && !isResizing && !isRotating) {
                    selectedElement.x = x - offsetX; selectedElement.y = y - offsetY;
                    drawCustomCanvas();
                }
            }
            // Actualizar cursor sobre handles (para rotación y resize)
            if (!isDragging && !isResizing && !isRotating && selectedElement) {
                const cx = selectedElement.x + selectedElement.width / 2;
                const cy = selectedElement.y + selectedElement.height / 2;
                const rot = selectedElement.rotation || 0;
                const handleOffset = { x: 0, y: -(selectedElement.height / 2 + 20) };
                const rx = cx + handleOffset.x * Math.cos(rot) - handleOffset.y * Math.sin(rot);
                const ry = cy + handleOffset.x * Math.sin(rot) + handleOffset.y * Math.cos(rot);
                const vectorBR = { x: selectedElement.width / 2, y: selectedElement.height / 2 };
                const brx = cx + vectorBR.x * Math.cos(rot) - vectorBR.y * Math.sin(rot);
                const bry = cy + vectorBR.x * Math.sin(rot) + vectorBR.y * Math.cos(rot);
                if (distance({ x, y }, { x: rx, y: ry }) < 15) customCanvas.style.cursor = "grab";
                else if (distance({ x, y }, { x: brx, y: bry }) < 15) customCanvas.style.cursor = "nwse-resize";
                else customCanvas.style.cursor = "default";
            }
        });

        customCanvas.addEventListener("mouseup", () => {
            if (isDrawingMode && drawingInProgress && currentDrawing) {
                customElements.push(currentDrawing);
                saveHistory();
                currentDrawing = null; drawingInProgress = false;
            }
            if (isMultiSelectMode) {
                if (isGroupDragging) { isGroupDragging = false; groupDragStart = null; saveHistory(); }
                else if (multiSelectRect) {
                    const rx = Math.min(multiSelectRect.startX, multiSelectRect.currentX);
                    const ry = Math.min(multiSelectRect.startY, multiSelectRect.currentY);
                    const rw = Math.abs(multiSelectRect.currentX - multiSelectRect.startX);
                    const rh = Math.abs(multiSelectRect.currentY - multiSelectRect.startY);
                    multiSelectedElements = customElements.filter(el => (el.x >= rx && el.y >= ry && (el.x + el.width) <= (rx + rw) && (el.y + el.height) <= (ry + rh)));
                    multiSelectRect = null; drawCustomCanvas();
                }
            } else { if (isDragging || isResizing || isRotating) saveHistory(); }
            isResizing = false; isDragging = false; isRotating = false;
            drawCustomCanvas();
        });
        customCanvas.addEventListener("mouseleave", () => {
            if (isDrawingMode && drawingInProgress && currentDrawing) {
                customElements.push(currentDrawing); saveHistory();
                currentDrawing = null; drawingInProgress = false;
            }
            isResizing = false; isDragging = false; isGroupDragging = false; multiSelectRect = null; isRotating = false;
            drawCustomCanvas();
        });

        // =============================
        // Agregar imagen personalizada
        // =============================
        addCustomImageButton.addEventListener("click", () => customFileInput.click());
        customFileInput.addEventListener("change", () => {
            if (customFileInput.files && customFileInput.files[0]) {
                const file = customFileInput.files[0];
                const reader = new FileReader();
                reader.onload = function (event) {
                    const img = new Image();
                    img.onload = function () {
                        const size = getDefaultImageSize(img);
                        if (file.type === "image/gif") {
                            const element = { type: "image", isGif: true, originalBlob: file, img: new Image(), x: 50, y: 50, width: size.width, height: size.height, rotation: 0 };
                            element.img.src = URL.createObjectURL(file);
                            customElements.push(element);
                        } else {
                            const element = { type: "image", img: img, x: 50, y: 50, width: size.width, height: size.height, rotation: 0 };
                            customElements.push(element);
                        }
                        saveHistory(); drawCustomCanvas();
                    };
                    img.src = event.target.result;
                };
                reader.readAsDataURL(file);
            }
        });

        // =============================
        // Panel de emojis
        // =============================
        let currentCategory = 'faces_emotion';
        const emojiContainer = document.createElement("div");
        emojiContainer.id = "emojiContainer";
        const emojiCategoryContainer = document.createElement("div");
        emojiCategoryContainer.id = "emojiCategoryContainer";
        const btnEmotions = document.createElement("button");
        btnEmotions.textContent = "Emociones";
        const btnAnimals = document.createElement("button");
        btnAnimals.textContent = "Animales";
        btnEmotions.addEventListener("click", () => { currentCategory = 'faces_emotion'; loadEmojis(currentCategory); });
        btnAnimals.addEventListener("click", () => { currentCategory = 'animals'; loadEmojis(currentCategory); });
        emojiCategoryContainer.appendChild(btnEmotions);
        emojiCategoryContainer.appendChild(btnAnimals);
        const emojiContent = document.createElement("div");
        emojiContent.id = "emojiContent";
        emojiContainer.appendChild(emojiCategoryContainer);
        emojiContainer.appendChild(emojiContent);
        document.body.appendChild(emojiContainer);
        const emojiToggleButton = document.getElementById("openEmojiPanel");
        emojiToggleButton.addEventListener("click", () => {
            if (emojiContainer.style.display === "none" || emojiContainer.style.display === "") { emojiContainer.style.display = "flex"; loadEmojis(currentCategory); }
            else { emojiContainer.style.display = "none"; }
        });
        function loadEmojis(category) {
            emojiContent.innerHTML = "";
            const data = emojis[category];
            data.forEach(emojiData => {
                const btn = document.createElement("button");
                btn.textContent = emojiData.emoji;
                btn.style.fontSize = "24px"; btn.style.padding = "5px";
                btn.classList.add("addEmoji");
                btn.style.border = "1px solid #ccc"; btn.style.borderRadius = "5px";
                btn.style.cursor = "pointer"; btn.style.backgroundColor = "#f9f9f9";
                btn.addEventListener("click", () => {
                    const element = { type: "emoji", emoji: emojiData.emoji, x: 50, y: 50, fontSize: 70, width: 0, height: 0, rotation: 0 };
                    customElements.push(element); saveHistory(); drawCustomCanvas();
                });
                emojiContent.appendChild(btn);
            });
        }
        loadEmojis(currentCategory);

        // =============================
        // Configurar menú emergente del lápiz
        // =============================
        pencilColorContainer.innerHTML = "";
        const pencilColors = colorsText;
        pencilColors.forEach(color => {
            const btn = document.createElement("div");
            btn.className = "colorButton";
            btn.style.backgroundColor = color;
            btn.addEventListener("click", () => {
                drawingColor = color;
                Array.from(pencilColorContainer.children).forEach(b => b.style.borderColor = "#ccc");
                btn.style.borderColor = "#000";
            });
            pencilColorContainer.appendChild(btn);
        });
        pencilSizeContainer.innerHTML = "";
        const pencilSizes = [2, 4, 6, 8];
        pencilSizes.forEach(size => {
            const btn = document.createElement("div");
            btn.className = "sizeButton";
            btn.setAttribute("data-size", size);
            btn.style.backgroundColor = "#777";
            btn.addEventListener("click", () => {
                brushSizeInput.value = size;
                if (selectedElement && selectedElement.type === "drawing") {
                    selectedElement.brushSize = size; drawCustomCanvas();
                }
                Array.from(pencilSizeContainer.children).forEach(b => b.style.borderColor = "#ccc");
                btn.style.borderColor = "#000";
            });
            pencilSizeContainer.appendChild(btn);
        });
        // Toggle lápiz: ahora alterna entre activar y desactivar el modo dibujo
        toggleDrawingButton.addEventListener("click", () => {
            if (isDrawingMode) {
                isDrawingMode = false;
                pencilOptionsPanel.style.display = "none";
                toggleDrawingButton.style.backgroundColor = "#005c4b";
            } else {
                isDrawingMode = true;
                pencilOptionsPanel.style.display = "block";
                toggleDrawingButton.style.backgroundColor = "#ddd";
                // Si se activa el lápiz, desactivar modo formas
                shapeOptionsPanel.style.display = "none";
                selectedElement = null;
            }
        });

        // =============================
        // Configurar menú emergente para formas
        // =============================
        toggleShapesButton.addEventListener("click", () => {
            pencilOptionsPanel.style.display = "none";
            shapeOptionsPanel.style.display = (shapeOptionsPanel.style.display === "none" || shapeOptionsPanel.style.display === "") ? "block" : "none";
            toggleShapesButton.style.backgroundColor = shapeOptionsPanel.style.display === "block" ? "#ddd" : "#005c4b";
        });
        shapeSquareButton.addEventListener("click", () => {
            const element = { type: "shape", shape: "square", x: 50, y: 50, width: 100, height: 100, color: "#000000", rotation: 0 };
            customElements.push(element); saveHistory(); drawCustomCanvas();
        });
        shapeCircleButton.addEventListener("click", () => {
            const element = { type: "shape", shape: "circle", x: 50, y: 50, width: 100, height: 100, color: "#000000", rotation: 0 };
            customElements.push(element); saveHistory(); drawCustomCanvas();
        });

        // =============================
        // Configurar botón multi-select
        // =============================
        toggleMultiSelectButton.addEventListener("click", () => {
            isMultiSelectMode = !isMultiSelectMode;
            toggleMultiSelectButton.style.backgroundColor = isMultiSelectMode ? "#ddd" : "#005c4b";
            if (!isMultiSelectMode) { multiSelectedElements = []; drawCustomCanvas(); }
        });

        // =============================
        // Configurar edición de texto (botones de color)
        // =============================
        const textColors = colorsText;
        function populateColorButtons(container, callback) {
            container.innerHTML = "";
            textColors.forEach(color => {
                const btn = document.createElement("div");
                btn.className = "colorButton";
                btn.style.backgroundColor = color;
                btn.addEventListener("click", () => { callback(color); });
                container.appendChild(btn);
            });
        }
        populateColorButtons(textColorButtons, (color) => { if (selectedElement && selectedElement.type === "text") { selectedElement.color = color; drawCustomCanvas(); } });
        populateColorButtons(textBgButtons, (color) => { if (selectedElement && selectedElement.type === "text") { selectedElement.bgColor = color; drawCustomCanvas(); } });
        addTextButton.addEventListener("click", () => {
            const text = prompt("Enter the text:");
            if (text) {
                const element = { type: "text", text: text, x: 50, y: 50, fontSize: 30, width: 0, height: 0, color: "#000000", bgColor: "", rotation: 0 };
                customElements.push(element); saveHistory(); drawCustomCanvas();
            }
        });

        // =============================
        // Resto de controles: bringForward, sendBackward, etc.
        // =============================
        bringForwardButton.addEventListener("click", () => {
            if (selectedElement) {
                const idx = customElements.indexOf(selectedElement);
                if (idx !== -1 && idx < customElements.length - 1) { customElements.splice(idx, 1); customElements.push(selectedElement); saveHistory(); drawCustomCanvas(); }
            }
        });
        sendBackwardButton.addEventListener("click", () => {
            if (selectedElement) {
                const idx = customElements.indexOf(selectedElement);
                if (idx > 0) { customElements.splice(idx, 1); customElements.unshift(selectedElement); saveHistory(); drawCustomCanvas(); }
            }
        });
        deleteElementButton.addEventListener("click", () => {
            if (selectedElement) {
                const idx = customElements.indexOf(selectedElement);
                if (idx !== -1) { customElements.splice(idx, 1); selectedElement = null; saveHistory(); drawCustomCanvas(); }
            }
        });
        clearCanvasButton.addEventListener("click", () => { customElements = []; selectedElement = null; saveHistory(); drawCustomCanvas(); });
        downloadButton.addEventListener("click", () => {
            const dataURL = customCanvas.toDataURL("image/png");
            const a = document.createElement("a");
            a.href = dataURL; a.download = "sticker.png"; a.click();
        });
        undoButton.addEventListener("click", () => {
            if (historyIndex > 0) { historyIndex--; customElements = cloneCustomElements(history[historyIndex]); drawCustomCanvas(); }
        });
        redoButton.addEventListener("click", () => {
            if (historyIndex < history.length - 1) { historyIndex++; customElements = cloneCustomElements(history[historyIndex]); drawCustomCanvas(); }
        });

        // =============================
        // Panel de edición de texto: actualización en tiempo real
        // =============================
        function updateTextEditorPanel() {
            if (selectedElement && selectedElement.type === "text") {
                textEditorPanel.style.display = "block";
                textContentInput.value = selectedElement.text;
                textFontSelect.value = selectedElement.fontFamily || "";
                textFontSizeInput.value = selectedElement.fontSize;
            } else { textEditorPanel.style.display = "none"; }
        }
        textContentInput.addEventListener("input", () => { if (selectedElement && selectedElement.type === "text") { selectedElement.text = textContentInput.value; drawCustomCanvas(); } });
        textFontSelect.addEventListener("change", () => { if (selectedElement && selectedElement.type === "text") { selectedElement.fontFamily = textFontSelect.value; drawCustomCanvas(); } });
        textFontSizeInput.addEventListener("input", () => { if (selectedElement && selectedElement.type === "text") { selectedElement.fontSize = parseInt(textFontSizeInput.value); drawCustomCanvas(); } });

        // =============================
        // Animación: Si hay algún GIF, redibujar continuamente
        // =============================
        function animateCanvas() {
            if (customElements.some(el => el.type === "image" && el.isGif)) { drawCustomCanvas(); }
            requestAnimationFrame(animateCanvas);
        }
        animateCanvas();

        // =============================
        // Crear sticker personalizado
        // =============================
        createCustomStickerButton.addEventListener("click", () => {

            if (customCreateClicked) return;
            customCreateClicked = true;
            createCustomStickerButton.disabled = true;
            customStatus.textContent = "Generating custom sticker...";
            selectedElement = null;
            hoveredElement = null;
            multiSelectedElements = [];
            drawCustomCanvas();
            const gifElements = customElements.filter(el => el.type === "image" && el.isGif);
            if (gifElements.length === 1 && customElements.length === 1) {
                simulateWhatsAppFileUpload(gifElements[0].originalBlob, customStatus);
                customElements = []; selectedElement = null; drawCustomCanvas();
                createCustomStickerButton.disabled = false; customCreateClicked = false;
            } else {
                customCanvas.toBlob(function (blob) {
                    if (!blob) { customStatus.textContent = "Error generating sticker."; return; }
                    const stickerFile = new File([blob], "sticker_personalizado.webp", { type: "image/webp" });
                    simulateWhatsAppFileUpload(stickerFile, customStatus);
                    customElements = []; selectedElement = null; drawCustomCanvas();
                    createCustomStickerButton.disabled = false; customCreateClicked = false;
                }, "image/webp");
            }
        });
    }

    // =============================
    // Simulación de subida a WhatsApp
    // =============================
    function simulateWhatsAppFileUpload(file, statusElement) {
        openAttachmentMenu();
        setTimeout(() => {
            const waFileInput = document.querySelector("input[type='file'][accept*='image']");
            if (!waFileInput) { statusElement.textContent = "WhatsApp file input not found"; return; }
            const dt = new DataTransfer();
            dt.items.add(file);
            waFileInput.files = dt.files;
            const event = new Event("change", { bubbles: true });
            waFileInput.dispatchEvent(event);
            statusElement.textContent = "Sticker loaded. Sending...";
            setTimeout(() => {
                const sendButton = document.querySelector("span[data-icon='send']");
                if (sendButton) { sendButton.click(); statusElement.textContent = "Sticker send"; }
                else { statusElement.textContent = "Submit button not found"; }
            }, 1000);
        }, 500);
    }

    // =============================
    // Abrir menú de adjuntos de WhatsApp
    // =============================
    function openAttachmentMenu() {
        const attachmentButton = document.querySelector("div[title='Adjuntar']") || document.querySelector("span[data-icon='clip']");
        if (attachmentButton) { attachmentButton.click(); }
    }

    // Función auxiliar: distancia entre dos puntos
    function distance(p1, p2) {
        return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
    }
})();