Chicken Executor

Its just a executor.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Chicken Executor
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Its just a executor.
// @author       You
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_getClipboard
// @grant        GM_xmlhttpRequest
// @license None
// ==/UserScript==

(function () {
  "use strict";

  // Global variables
  let isMinimized = false;
  let currentTab = "home";
  let scriptTabs = [{ id: "tab1", name: "Script 1", content: "" }];
  let activeScriptTab = "tab1";
  let isDragging = false;
  let dragOffset = { x: 0, y: 0 };

  // Initialize storage
  if (!GM_getValue("scripts", null)) {
    GM_setValue("scripts", JSON.stringify([]));
  }
  if (!GM_getValue("settings", null)) {
    GM_setValue(
      "settings",
      JSON.stringify({
        theme: "dark",
        editProtection: false,
        antiScam: true,
        openaiKey: "YOUR_OPENAI_API_KEY_HERE",
        defaultSaveLocation: "local",
        autoUpdate: true,
      }),
    );
  }

  // CSS Styles
  const styles = `
        .chicken-executor {
            position: fixed;
            top: 50px;
            right: 50px;
            width: 600px;
            height: 500px;
            background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%);
            border-radius: 12px;
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
            z-index: 999999;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: #ffffff;
            overflow: hidden;
            transition: all 0.3s ease;
        }

        .chicken-header {
            background: linear-gradient(90deg, #4f46e5 0%, #7c3aed 100%);
            height: 40px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 0 15px;
            border-radius: 12px 12px 0 0;
        }

        .chicken-title {
            font-weight: 600;
            font-size: 14px;
            color: white;
        }

        .chicken-controls {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .chicken-btn {
            width: 20px;
            height: 20px;
            border-radius: 4px;
            border: none;
            cursor: pointer;
            font-size: 12px;
            font-weight: bold;
            display: flex;            /* makes button a flex container */
           justify-content: center;  /* centers horizontally */
           align-items: center;      /* centers vertically */
           padding: 0;               /* remove default padding */
           transition: all 0.2s ease;
           line-height: normal;      /* reset line-height */
       }


        .minimize-btn { background: #fbbf24; color: #92400e; }
        .maximize-btn { background: #10b981; color: #065f46; }
        .close-btn { background: #ef4444; color: #991b1b; }

        .chicken-btn:hover {
            transform: scale(1.1);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
        }

        .chicken-body {
            display: flex;
            height: calc(100% - 40px);
        }

        .chicken-sidebar {
            width: 150px;
            background: rgba(0, 0, 0, 0.2);
            padding: 15px 0;
            border-right: 1px solid rgba(255, 255, 255, 0.1);
        }

        .sidebar-item {
            padding: 12px 20px;
            cursor: pointer;
            transition: all 0.2s ease;
            font-size: 13px;
            border-left: 3px solid transparent;
        }

        .sidebar-item:hover {
            background: rgba(255, 255, 255, 0.1);
            border-left-color: #4f46e5;
        }

        .sidebar-item.active {
            background: rgba(79, 70, 229, 0.3);
            border-left-color: #4f46e5;
        }

        .chicken-content {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
        }

        .content-section {
            display: none;
        }

        .content-section.active {
            display: block;
        }

        .script-input {
            width: 100%;
            height: 200px;
            background: rgba(0, 0, 0, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 8px;
            padding: 15px;
            color: white;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            resize: vertical;
            outline: none;
        }

        .script-input::placeholder {
            color: rgba(255, 255, 255, 0.5);
        }

        .script-tabs {
            display: flex;
            gap: 5px;
            margin-bottom: 10px;
            flex-wrap: wrap;
        }

        .script-tab {
            background: rgba(0, 0, 0, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 6px;
            padding: 6px 12px;
            font-size: 11px;
            cursor: pointer;
            transition: all 0.2s ease;
            position: relative;
        }

        .script-tab.active {
            background: rgba(79, 70, 229, 0.5);
            border-color: #4f46e5;
        }

        .script-tab:hover {
            background: rgba(255, 255, 255, 0.1);
        }

        .add-tab-btn {
            background: rgba(16, 185, 129, 0.3);
            border: 1px solid #10b981;
            border-radius: 6px;
            padding: 6px 12px;
            font-size: 11px;
            color: #10b981;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .add-tab-btn:hover {
            background: rgba(16, 185, 129, 0.5);
        }

        .executor-buttons {
            display: flex;
            gap: 10px;
            margin-top: 15px;
            flex-wrap: wrap;
        }

        .exec-btn {
            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
            border: none;
            border-radius: 6px;
            padding: 10px 20px;
            color: white;
            font-size: 12px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .exec-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(79, 70, 229, 0.4);
        }

        .exec-btn.secondary {
            background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%);
        }

        .exec-btn.success {
            background: linear-gradient(135deg, #10b981 0%, #059669 100%);
        }

        .search-input {
            width: 100%;
            background: rgba(0, 0, 0, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 8px;
            padding: 12px;
            color: black;
            font-size: 13px;
            margin-bottom: 15px;
            outline: none;
        }

        .script-cards {
            display: grid;
            gap: 15px;
            max-height: 300px;
            overflow-y: auto;
        }

        .script-card {
            background: rgba(0, 0, 0, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 8px;
            padding: 15px;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .script-card:hover {
            background: rgba(255, 255, 255, 0.1);
            transform: translateY(-2px);
        }

        .card-title {
            font-weight: 600;
            margin-bottom: 5px;
            color: #4f46e5;
        }

        .card-description {
            font-size: 12px;
            color: rgba(255, 255, 255, 0.7);
        }

        .cloud-results {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 15px;
            max-height: 350px;
            overflow-y: auto;
        }

        .cloud-item {
            background: rgba(0, 0, 0, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 8px;
            padding: 15px;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .cloud-item:hover {
            background: rgba(255, 255, 255, 0.1);
            transform: translateY(-2px);
        }

        .settings-group {
            margin-bottom: 20px;
        }

        .settings-label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            font-size: 13px;
        }

        .settings-input, .settings-select {
            width: 100%;
            background: rgba(0, 0, 0, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 6px;
            padding: 10px;
            color: white;
            font-size: 12px;
            outline: none;
        }

        .settings-checkbox {
            margin-right: 8px;
        }

        .notification {
            position: fixed;
            top: 20px;
            right: 20px;
            background: linear-gradient(135deg, #10b981 0%, #059669 100%);
            color: white;
            padding: 12px 20px;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
            z-index: 1000000;
            font-size: 13px;
            font-weight: 600;
            opacity: 0;
            transform: translateX(100%);
            transition: all 0.3s ease;
        }

        .notification.show {
            opacity: 1;
            transform: translateX(0);
        }

        .minimized-icon {
            position: fixed;
            width: 50px;
            height: 50px;
            background: url('https://i.imgur.com/WL8OlOU.png') center/cover;
            border: 3px solid #4f46e5;
            border-radius: 12px;
            cursor: pointer;
            z-index: 999999;
            transition: all 0.2s ease;
            box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
        }

        .minimized-icon:hover {
            transform: scale(1.05);
            box-shadow: 0 12px 35px rgba(79, 70, 229, 0.4);
        }

        .donation-content {
            text-align: center;
            padding: 40px 20px;
        }

        .donation-title {
            font-size: 24px;
            font-weight: 700;
            margin-bottom: 15px;
            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }

        .donation-text {
            margin-bottom: 25px;
            color: rgba(255, 255, 255, 0.8);
            line-height: 1.6;
        }

        .paypal-btn {
            background: linear-gradient(135deg, #0070ba 0%, #003087 100%);
            border: none;
            border-radius: 8px;
            padding: 15px 30px;
            color: white;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s ease;
            text-decoration: none;
            display: inline-block;
        }

        .paypal-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 20px rgba(0, 112, 186, 0.4);
        }

        /* Scrollbar Styling */
        ::-webkit-scrollbar {
            width: 8px;
        }

        ::-webkit-scrollbar-track {
            background: rgba(0, 0, 0, 0.2);
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb {
            background: rgba(79, 70, 229, 0.6);
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb:hover {
            background: rgba(79, 70, 229, 0.8);
        }
    `;

  // Create and inject styles
  const styleSheet = document.createElement("style");
  styleSheet.textContent = styles;
  document.head.appendChild(styleSheet);

  // Notification system
  function showNotification(message, type = "success") {
    const notification = document.createElement("div");
    notification.className = "notification";
    notification.textContent = message;

    if (type === "error") {
      notification.style.background =
        "linear-gradient(135deg, #ef4444 0%, #dc2626 100%)";
    }

    document.body.appendChild(notification);

    setTimeout(() => notification.classList.add("show"), 100);
    setTimeout(() => {
      notification.classList.remove("show");
      setTimeout(() => notification.remove(), 300);
    }, 3000);
  }

  // Create main executor panel
  function createExecutorPanel() {
    const panel = document.createElement("div");
    panel.className = "chicken-executor";
    panel.innerHTML = `
            <div class="chicken-header">
                <div class="chicken-title">Chicken Executor</div>
                <div class="chicken-controls">
                    <button class="chicken-btn minimize-btn" title="Minimize">−</button>
                    <button class="chicken-btn maximize-btn" title="Maximize">□</button>
                    <button class="chicken-btn close-btn" title="Close">×</button>
                </div>
            </div>
            <div class="chicken-body">
                <div class="chicken-sidebar">
                    <div class="sidebar-item active" data-tab="home">🏠 Home</div>
                    <div class="sidebar-item" data-tab="main">⚡ Main</div>
                    <div class="sidebar-item" data-tab="cloud">☁ Cloud</div>
                    <div class="sidebar-item" data-tab="settings">⚙ Settings</div>
                    <div class="sidebar-item" data-tab="files">📁 Files</div>
                    <div class="sidebar-item" data-tab="donation">💝 Donation</div>
                </div>
                <div class="chicken-content">
                    ${createHomeContent()}
                    ${createMainContent()}
                    ${createCloudContent()}
                    ${createSettingsContent()}
                    ${createFilesContent()}
                    ${createDonationContent()}
                </div>
            </div>
        `;

    document.body.appendChild(panel);
    return panel;
  }

  // Create content sections
  function createHomeContent() {
    return `
            <div class="content-section active" id="home-content">
                <h2>Script Store</h2>
                <input type="text" class="search-input" placeholder="Search saved scripts..." id="script-search">
                <div class="script-cards" id="saved-scripts"></div>
            </div>
        `;
  }

  function createMainContent() {
    return `
            <div class="content-section" id="main-content">
                <h2>Live JS Executor</h2>
                <div class="script-tabs" id="script-tabs"></div>
                <textarea class="script-input" placeholder="Enter Script Here..." id="script-editor"></textarea>
                <div class="executor-buttons">
                    <button class="exec-btn" id="execute-btn">Execute</button>
                    <button class="exec-btn secondary" id="execute-clipboard-btn">Execute Clipboard</button>
                    <button class="exec-btn success" id="save-script-btn">Save Script</button>
                </div>
            </div>
        `;
  }

  function createCloudContent() {
    return `
            <div class="content-section" id="cloud-content">
                <h2>GreasyFork Scripts</h2>
                <input type="text" class="search-input" placeholder="Search GreasyFork..." id="greasyfork-search">
                <div class="cloud-results" id="cloud-results"></div>
            </div>
        `;
  }

  function createSettingsContent() {
    const settings = JSON.parse(GM_getValue("settings"));
    return `
            <div class="content-section" id="settings-content">
                <h2>Settings</h2>
                <div class="settings-group">
                    <label class="settings-label">Theme</label>
                    <select class="settings-select" id="theme-select">
                        <option value="dark" ${settings.theme === "dark" ? "selected" : ""}>Dark</option>
                        <option value="light" ${settings.theme === "light" ? "selected" : ""}>Light</option>
                    </select>
                </div>
                <div class="settings-group">
                    <label class="settings-label">
                        <input type="checkbox" class="settings-checkbox" id="edit-protection" ${settings.editProtection ? "checked" : ""}>
                        Protection
                    </label>
                </div>
                <div class="settings-group">
                    <label class="settings-label">
                        <input type="checkbox" class="settings-checkbox" id="anti-scam" ${settings.antiScam ? "checked" : ""}>
                        Anti-Scam Protection
                    </label>
                </div>
                <div class="settings-group">
                    <label class="settings-label">OpenAI API Key</label>
                    <input type="password" class="settings-input" id="openai-key" value="${settings.openaiKey}" placeholder="YOUR_OPENAI_API_KEY_HERE">
                </div>
                <div class="settings-group">
                    <label class="settings-label">Default Save Location</label>
                    <select class="settings-select" id="save-location">
                        <option value="local" ${settings.defaultSaveLocation === "local" ? "selected" : ""}>Local Storage</option>
                        <option value="cloud" ${settings.defaultSaveLocation === "cloud" ? "selected" : ""}>Cloud Sync</option>
                    </select>
                </div>
                <div class="settings-group">
                    <label class="settings-label">
                        <input type="checkbox" class="settings-checkbox" id="auto-update" ${settings.autoUpdate ? "checked" : ""}>
                        Auto Update Scripts
                    </label>
                </div>
            </div>
        `;
  }

  function createFilesContent() {
    return `
            <div class="content-section" id="files-content">
                <h2>File Explorer</h2>
                <div class="script-cards" id="file-explorer"></div>
            </div>
        `;
  }

  function createDonationContent() {
    return `
            <div class="content-section" id="donation-content">
                <div class="donation-content">
                    <h2 class="donation-title">Support Development</h2>
                    <p class="donation-text">
                        If you enjoy using Chicken Executor and would like to support its development,
                        consider making a donation. Your support helps keep this project alive and enables
                        new features and improvements.
                    </p>
                    <a href="https://www.paypal.com/ncp/payment/W2GMQQULX79U2" target="_blank" class="paypal-btn">
                        💳 Donate via PayPal
                    </a>
                </div>
            </div>
        `;
  }

  // Create minimized icon
  function createMinimizedIcon() {
    const icon = document.createElement("div");
    icon.className = "minimized-icon";
    icon.title = "Chicken Executor";
    icon.style.top = "50px";
    icon.style.right = "50px";

    // Make icon draggable
    let isDragging = false;
    let dragOffset = { x: 0, y: 0 };

    icon.addEventListener("mousedown", (e) => {
      if (e.button === 0) {
        // Left click only
        isDragging = true;
        const rect = icon.getBoundingClientRect();
        dragOffset.x = e.clientX - rect.left;
        dragOffset.y = e.clientY - rect.top;

        // Prevent text selection during drag
        e.preventDefault();
      }
    });

    document.addEventListener("mousemove", (e) => {
      if (isDragging) {
        const x = e.clientX - dragOffset.x;
        const y = e.clientY - dragOffset.y;

        // Keep icon within viewport bounds
        const maxX = window.innerWidth - 150;
        const maxY = window.innerHeight - 150;

        icon.style.left = Math.max(0, Math.min(x, maxX)) + "px";
        icon.style.top = Math.max(0, Math.min(y, maxY)) + "px";
        icon.style.right = "auto";
      }
    });

    document.addEventListener("mouseup", (e) => {
      if (isDragging) {
        isDragging = false;

        // Check if this was a click (minimal movement)
        const rect = icon.getBoundingClientRect();
        const clickX = e.clientX - rect.left;
        const clickY = e.clientY - rect.top;

        if (
          Math.abs(clickX - dragOffset.x) < 5 &&
          Math.abs(clickY - dragOffset.y) < 5
        ) {
          // This was a click, restore the panel
          restorePanel();
        }
      }
    });

    document.body.appendChild(icon);
    return icon;
  }

  // Panel management functions
  function minimizePanel() {
    const panel = document.querySelector(".chicken-executor");
    if (panel) {
      panel.style.display = "none";
      isMinimized = true;
      createMinimizedIcon();
    }
  }

  function restorePanel() {
    const panel = document.querySelector(".chicken-executor");
    const icon = document.querySelector(".minimized-icon");

    if (panel && icon) {
      panel.style.display = "block";
      icon.remove();
      isMinimized = false;
    }
  }

  function closePanel() {
    const panel = document.querySelector(".chicken-executor");
    const icon = document.querySelector(".minimized-icon");

    if (panel) panel.remove();
    if (icon) icon.remove();
  }

  // Tab management
  function switchTab(tabName) {
    // Update sidebar
    document.querySelectorAll(".sidebar-item").forEach((item) => {
      item.classList.remove("active");
    });
    document.querySelector(`[data-tab="${tabName}"]`).classList.add("active");

    // Update content
    document.querySelectorAll(".content-section").forEach((section) => {
      section.classList.remove("active");
    });
    document.getElementById(`${tabName}-content`).classList.add("active");

    currentTab = tabName;

    // Load content based on tab
    if (tabName === "home") {
      loadSavedScripts();
    } else if (tabName === "main") {
      updateScriptTabs();
    } else if (tabName === "files") {
      loadFileExplorer();
    }
  }

  // Script tab management
  function updateScriptTabs() {
    const tabsContainer = document.getElementById("script-tabs");
    tabsContainer.innerHTML = "";

    scriptTabs.forEach((tab) => {
      const tabElement = document.createElement("div");
      tabElement.className = `script-tab ${tab.id === activeScriptTab ? "active" : ""}`;
      tabElement.textContent = tab.name;
      tabElement.onclick = () => switchScriptTab(tab.id);
      tabElement.ondblclick = () => renameScriptTab(tab.id);
      tabsContainer.appendChild(tabElement);
    });

    const addButton = document.createElement("div");
    addButton.className = "add-tab-btn";
    addButton.textContent = "+";
    addButton.onclick = addScriptTab;
    tabsContainer.appendChild(addButton);

    // Update editor content
    const activeTab = scriptTabs.find((tab) => tab.id === activeScriptTab);
    if (activeTab) {
      document.getElementById("script-editor").value = activeTab.content;
    }
  }

  function switchScriptTab(tabId) {
    // Save current content
    const currentTab = scriptTabs.find((tab) => tab.id === activeScriptTab);
    if (currentTab) {
      currentTab.content = document.getElementById("script-editor").value;
    }

    activeScriptTab = tabId;
    updateScriptTabs();
  }

  function addScriptTab() {
    const newId = "tab" + (scriptTabs.length + 1);
    const newTab = {
      id: newId,
      name: `Script ${scriptTabs.length + 1}`,
      content: "",
    };
    scriptTabs.push(newTab);
    activeScriptTab = newId;
    updateScriptTabs();
    showNotification("New tab created");
  }

  function renameScriptTab(tabId) {
    const tab = scriptTabs.find((t) => t.id === tabId);
    if (tab) {
      const newName = prompt("Enter new tab name:", tab.name);
      if (newName && newName.trim()) {
        tab.name = newName.trim();
        updateScriptTabs();
        showNotification("Tab renamed");
      }
    }
  }

  // Script execution
  function executeScript(code) {
    try {
      // Basic anti-scam check
      const settings = JSON.parse(GM_getValue("settings"));
      if (settings.antiScam) {
        const suspiciousPatterns = [
          /document\.cookie/i,
          /localStorage\./i,
          /sessionStorage\./i,
          /\.send\(/i,
          /fetch\(/i,
          /XMLHttpRequest/i,
        ];

        if (suspiciousPatterns.some((pattern) => pattern.test(code))) {
          if (
            !confirm(
              "This script contains potentially suspicious code. Are you sure you want to execute it?",
            )
          ) {
            return;
          }
        }
      }

      // Execute the code
      eval(code);
      showNotification("Script executed successfully");
    } catch (error) {
      showNotification(`Execution error: ${error.message}`, "error");
      console.error("Script execution error:", error);
    }
  }

  // Save script
  function saveScript() {
    const code = document.getElementById("script-editor").value;
    if (!code.trim()) {
      showNotification("No script to save", "error");
      return;
    }

    const name = prompt("Enter script name:");
    if (!name || !name.trim()) return;

    const scripts = JSON.parse(GM_getValue("scripts"));
    const newScript = {
      id: Date.now().toString(),
      name: name.trim(),
      code: code,
      created: new Date().toISOString(),
    };

    scripts.push(newScript);
    GM_setValue("scripts", JSON.stringify(scripts));
    showNotification("Script saved successfully");

    if (currentTab === "home") {
      loadSavedScripts();
    }
  }

  // Load saved scripts
  function loadSavedScripts() {
    const scripts = JSON.parse(GM_getValue("scripts"));
    const container = document.getElementById("saved-scripts");
    container.innerHTML = "";

    scripts.forEach((script) => {
      const card = document.createElement("div");
      card.className = "script-card";

      // Card inner HTML with delete button
      card.innerHTML = `
            <div class="card-title">${script.name}</div>
            <div class="card-description">Created: ${new Date(script.created).toLocaleDateString()}</div>
            <button class="exec-btn secondary delete-btn" style="margin-top: 10px; padding: 5px 10px; font-size: 11px;">Delete</button>
        `;

      // Load script on card click (except delete button)
      card.addEventListener("click", (e) => {
        if (e.target.classList.contains("delete-btn")) return; // ignore clicks on delete button
        switchTab("main");
        const activeTab = scriptTabs.find((tab) => tab.id === activeScriptTab);
        if (activeTab) {
          activeTab.content = script.code;
          document.getElementById("script-editor").value = script.code;
        }
        showNotification("Script loaded");
      });

      // Delete button functionality
      const deleteBtn = card.querySelector(".delete-btn");
      deleteBtn.addEventListener("click", (e) => {
        e.stopPropagation(); // prevent triggering card click
        if (confirm(`Are you sure you want to delete "${script.name}"?`)) {
          const updatedScripts = scripts.filter((s) => s.id !== script.id);
          GM_setValue("scripts", JSON.stringify(updatedScripts));
          showNotification("Script deleted");
          loadSavedScripts(); // refresh list
        }
      });

      container.appendChild(card);
    });

    if (scripts.length === 0) {
      container.innerHTML =
        '<div style="text-align: center; color: rgba(255,255,255,0.5); padding: 40px;">No saved scripts</div>';
    }
  }

  // --- GreasyFork search ---
  async function searchGreasyFork(query) {
    if (!query.trim()) return;
    const resultsContainer = document.getElementById("cloud-results");
    resultsContainer.innerHTML =
      '<div style="text-align:center; padding:20px;">Searching...</div>';

    const searchUrl = `https://greasyfork.org/en/scripts?q=${encodeURIComponent(query)}`;

    try {
      const res = await fetch(searchUrl);
      const html = await res.text();
      const parser = new DOMParser();
      const doc = parser.parseFromString(html, "text/html");
      const scriptElements = doc.querySelectorAll("li[data-script-id]");

      resultsContainer.innerHTML = "";
      if (!scriptElements.length) {
        resultsContainer.innerHTML =
          '<div style="text-align:center; padding:20px; color: rgba(255,255,255,0.5);">No scripts found</div>';
        return;
      }

      scriptElements.forEach((el) => {
        const id = el.dataset.scriptId;
        const name = el.dataset.scriptName || "Unnamed Script";
        const desc =
          el.querySelector(".script-description")?.innerText ||
          "No description";
        const author =
          el.querySelector(".script-list-author a")?.innerText || "Unknown";
        const installs =
          el
            .querySelector("dd.script-list-total-installs span")
            ?.innerText.trim() || "0";

        const href = `https://greasyfork.org/en/scripts/${id}-${name.toLowerCase().replace(/\s+/g, "-")}/code`;

        const item = document.createElement("div");
        item.className = "cloud-item";
        item.style.cssText = `
                padding: 12px;
                margin: 5px 0;
                border-radius: 8px;
                background: rgba(255,255,255,0.05);
            `;

        item.innerHTML = `
                <div style="font-weight:bold; margin-bottom:5px;">${name}</div>
                <div style="font-size:12px; color: rgba(255,255,255,0.8); margin-bottom:5px;">${desc}</div>
                <div style="font-size:11px; color: rgba(255,255,255,0.6); margin-bottom:8px;">By ${author} • ${installs} installs</div>
                <div style="display:flex; gap:10px;">
                    <button class="exec-btn" data-href="${href}">Install</button>
                    <button class="exec-btn secondary" data-id="${id}" data-name="${name}">View Code</button>
                </div>
            `;

        // Install: inject code, create tab, save, switch sidebar to main
        item.querySelector("button.exec-btn").onclick = async (e) => {
          const href = e.target.dataset.href;
          const code = await fetchGreasyForkCode(href);
          const editor = document.getElementById("script-editor");
          editor.value = code;

          addScriptTab(name);

          const saveBtn = document.getElementById("save-script-btn");
          if (saveBtn) saveBtn.click();

          // Switch sidebar to main tab
          document
            .querySelectorAll(".sidebar-item")
            .forEach((s) => s.classList.remove("active"));
          const mainSidebar = document.querySelector(
            '.sidebar-item[data-tab="main"]',
          );
          if (mainSidebar) mainSidebar.classList.add("active");
          showTab("main-content");

          editor.scrollIntoView({ behavior: "smooth" });
        };

        // View Code: inject into main editor, switch sidebar to main
        item.querySelector("button.secondary").onclick = async (e) => {
          const id = e.target.dataset.id;
          const name = e.target.dataset.name;
          const code = await fetchGreasyForkCode(
            `https://greasyfork.org/en/scripts/${id}-${name.toLowerCase().replace(/\s+/g, "-")}/code`,
          );
          const editor = document.getElementById("script-editor");
          editor.value = code;

          // Switch sidebar to main tab
          document
            .querySelectorAll(".sidebar-item")
            .forEach((s) => s.classList.remove("active"));
          const mainSidebar = document.querySelector(
            '.sidebar-item[data-tab="main"]',
          );
          if (mainSidebar) mainSidebar.classList.add("active");
          showTab("main-content");

          editor.scrollIntoView({ behavior: "smooth" });
        };

        resultsContainer.appendChild(item);
      });
    } catch (err) {
      console.error(err);
      resultsContainer.innerHTML =
        '<div style="text-align:center; padding:20px; color:red;"> results</div>';
    }
  }

  // --- Utility: fetch code ---
  async function fetchGreasyForkCode(href) {
    try {
      const res = await fetch(href);
      const html = await res.text();
      const parser = new DOMParser();
      const doc = parser.parseFromString(html, "text/html");
      return (
        doc.querySelector(".code-container pre")?.innerText ||
        "// Code not available"
      );
    } catch (err) {
      console.error(err);
      return "// Error fetching code";
    }
  }

  // --- Utility: add script tab ---
  function addScriptTab(scriptName) {
    const tabsContainer = document.getElementById("script-tabs");
    if (!tabsContainer) return;

    tabsContainer
      .querySelectorAll(".script-tab")
      .forEach((t) => t.classList.remove("active"));

    const tab = document.createElement("div");
    tab.className = "script-tab active";
    tab.textContent = scriptName;
    tab.onclick = () =>
      document
        .getElementById("script-editor")
        .scrollIntoView({ behavior: "smooth" });
    tabsContainer.insertBefore(
      tab,
      tabsContainer.querySelector(".add-tab-btn"),
    );
  }

  // --- Utility: switch content ---
  function showTab(tabId) {
    document.querySelectorAll(".content-section").forEach((sec) => {
      sec.classList.toggle("active", sec.id === tabId);
    });
  }

  // --- Attach search input ---
  document
    .getElementById("greasyfork-search")
    ?.addEventListener("keydown", (e) => {
      if (e.key === "Enter") searchGreasyFork(e.target.value);
    });

  // Load file explorer
  function loadFileExplorer() {
    const container = document.getElementById("file-explorer");
    const scripts = JSON.parse(GM_getValue("scripts"));

    container.innerHTML = "";

    // Show GM storage files
    const gmFiles = [
      {
        name: "scripts.json",
        type: "GM Storage",
        size: JSON.stringify(scripts).length + " bytes",
      },
      {
        name: "settings.json",
        type: "GM Storage",
        size: JSON.stringify(GM_getValue("settings")).length + " bytes",
      },
    ];

    [
      ...gmFiles,
      ...scripts.map((s) => ({
        name: s.name,
        type: "Saved Script",
        size: s.code.length + " chars",
      })),
    ].forEach((file) => {
      const card = document.createElement("div");
      card.className = "script-card";
      card.innerHTML = `
                <div class="card-title">📄 ${file.name}</div>
                <div class="card-description">${file.type} • ${file.size}</div>
            `;
      container.appendChild(card);
    });
  }

  // Save settings
  function saveSettings() {
    const settings = {
      theme: document.getElementById("theme-select").value,
      editProtection: document.getElementById("edit-protection").checked,
      antiScam: document.getElementById("anti-scam").checked,
      openaiKey: document.getElementById("openai-key").value,
      defaultSaveLocation: document.getElementById("save-location").value,
      autoUpdate: document.getElementById("auto-update").checked,
    };

    GM_setValue("settings", JSON.stringify(settings));
    showNotification("Settings saved");
  }

  // Initialize the executor
  function init() {
    const panel = createExecutorPanel();

    // Header button events
    panel.querySelector(".minimize-btn").onclick = minimizePanel;
    panel.querySelector(".maximize-btn").onclick = () => {
      // Toggle maximize/restore
      if (panel.style.width === "100vw") {
        panel.style.width = "600px";
        panel.style.height = "500px";
        panel.style.top = "50px";
        panel.style.left = "auto";
        panel.style.right = "50px";
        showNotification("Panel restored");
      } else {
        panel.style.width = "100vw";
        panel.style.height = "100vh";
        panel.style.top = "0";
        panel.style.left = "0";
        panel.style.right = "auto";
        showNotification("Panel maximized");
      }
    };
    panel.querySelector(".close-btn").onclick = closePanel;

    // Sidebar navigation
    panel.querySelectorAll(".sidebar-item").forEach((item) => {
      item.onclick = () => switchTab(item.dataset.tab);
    });

    // Main tab functionality
    panel.querySelector("#execute-btn").onclick = () => {
      const code = document.getElementById("script-editor").value;
      if (code.trim()) {
        executeScript(code);
      } else {
        showNotification("No script to execute", "error");
      }
    };

    panel.querySelector("#execute-clipboard-btn").onclick = async () => {
      try {
        const clipboardText = await GM_getClipboard();
        if (clipboardText && clipboardText.trim()) {
          executeScript(clipboardText);
        } else {
          showNotification("Clipboard is empty", "error");
        }
      } catch (error) {
        showNotification("Failed to read clipboard", "error");
      }
    };

    panel.querySelector("#save-script-btn").onclick = saveScript;

    // Script editor auto-save
    panel.querySelector("#script-editor").oninput = (e) => {
      const activeTab = scriptTabs.find((tab) => tab.id === activeScriptTab);
      if (activeTab) {
        activeTab.content = e.target.value;
      }
    };

    // Home tab search
    panel.querySelector("#script-search").oninput = (e) => {
      const query = e.target.value.toLowerCase();
      const cards = panel.querySelectorAll("#saved-scripts .script-card");
      cards.forEach((card) => {
        const title = card
          .querySelector(".card-title")
          .textContent.toLowerCase();
        card.style.display = title.includes(query) ? "block" : "none";
      });
    };

    // Cloud search
    panel.querySelector("#greasyfork-search").onkeypress = (e) => {
      if (e.key === "Enter") {
        searchGreasyFork(e.target.value);
      }
    };

    // Settings auto-save
    const settingsInputs = panel.querySelectorAll(
      "#settings-content input, #settings-content select",
    );
    settingsInputs.forEach((input) => {
      input.onchange = saveSettings;
    });

    // Initialize content
    loadSavedScripts();
    updateScriptTabs();

    // Make panel draggable by header
    let isDragging = false;
    let dragOffset = { x: 0, y: 0 };

    panel.querySelector(".chicken-header").onmousedown = (e) => {
      if (e.target.classList.contains("chicken-btn")) return;

      isDragging = true;
      const rect = panel.getBoundingClientRect();
      dragOffset.x = e.clientX - rect.left;
      dragOffset.y = e.clientY - rect.top;
      e.preventDefault();
    };

    document.onmousemove = (e) => {
      if (isDragging && !isMinimized) {
        const x = e.clientX - dragOffset.x;
        const y = e.clientY - dragOffset.y;

        panel.style.left =
          Math.max(0, Math.min(x, window.innerWidth - panel.offsetWidth)) +
          "px";
        panel.style.top =
          Math.max(0, Math.min(y, window.innerHeight - panel.offsetHeight)) +
          "px";
        panel.style.right = "auto";
      }
    };

    document.onmouseup = () => {
      isDragging = false;
    };

    // Keyboard shortcuts
    document.onkeydown = (e) => {
      if (e.ctrlKey && e.shiftKey && e.key === "E") {
        e.preventDefault();
        if (isMinimized) {
          restorePanel();
        } else {
          minimizePanel();
        }
      }
    };

    showNotification("Chicken Executor loaded! Press Ctrl+Shift+E to toggle.");
  }

  // Wait for page load
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", init);
  } else {
    init();
  }
})();