Smart Notes Pro

Умные заметки с настраиваемыми генераторами

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

ستحتاج إلى تثبيت إضافة مثل Stylus لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتتمكن من تثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

(لدي بالفعل مثبت أنماط للمستخدم، دعني أقم بتثبيته!)

// ==UserScript==
// @name         Smart Notes Pro
// @namespace    http://tampermonkey.net/
// @version      3.4
// @description  Умные заметки с настраиваемыми генераторами
// @author       Вы
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_addStyle
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Загрузка сохраненных данных
    let savedData = GM_getValue('smart_notes_data');
    let userRN = GM_getValue('user_rn');
    let userANTemplate = GM_getValue('user_an_template');

    // Если это первый запуск или нет данных - запрашиваем у пользователя
    if (!userRN || !userANTemplate || !savedData) {
        setupFirstRun();
        return; // Прерываем выполнение, setupFirstRun сам перезагрузит скрипт
    }

    // Инициализация сохраненных значений
    if (!savedData) {
        savedData = {
            an: generateANFromTemplate(userANTemplate),
            email: generateRandomEmail(16),
            password: generateRandomPassword(8),
            phone: generateUSAPhoneNumber()
        };
        GM_setValue('smart_notes_data', savedData);
    }

    // Получаем сохраненные пользовательские заметки
    const USER_NOTES = GM_getValue('user_smart_notes', 'Ваши заметки здесь...\nСохраняются автоматически.');

    // Функция для первого запуска - запрос RN и шаблона AN
    function setupFirstRun() {
        // Создаем стили для модального окна
        GM_addStyle(`
            #setup-modal {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0, 0, 0, 0.8);
                z-index: 1000000;
                display: flex;
                justify-content: center;
                align-items: center;
                font-family: 'SF Pro Text', -apple-system, sans-serif;
            }

            .setup-container {
                background: white;
                padding: 30px;
                border-radius: 12px;
                width: 400px;
                max-width: 90%;
                box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
            }

            .setup-title {
                font-size: 20px;
                font-weight: 600;
                color: #1976D2;
                margin-bottom: 20px;
                text-align: center;
            }

            .setup-input-group {
                margin-bottom: 20px;
            }

            .setup-label {
                display: block;
                font-size: 14px;
                font-weight: 500;
                margin-bottom: 8px;
                color: #333;
            }

            .setup-input {
                width: 100%;
                padding: 10px 12px;
                border: 2px solid #e0e0e0;
                border-radius: 6px;
                font-size: 14px;
                font-family: 'SF Mono', Monaco, monospace;
                box-sizing: border-box;
            }

            .setup-input:focus {
                outline: none;
                border-color: #2196F3;
                box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);
            }

            .setup-info {
                font-size: 12px;
                color: #666;
                margin-top: 5px;
            }

            .setup-example {
                background: #f5f5f5;
                padding: 8px 12px;
                border-radius: 4px;
                font-family: 'SF Mono', Monaco, monospace;
                font-size: 13px;
                margin: 5px 0;
                border: 1px solid #e0e0e0;
            }

            .setup-button {
                width: 100%;
                padding: 12px;
                background: linear-gradient(to right, #4CAF50, #45a049);
                color: white;
                border: none;
                border-radius: 6px;
                font-size: 14px;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s;
                margin-top: 10px;
            }

            .setup-button:hover {
                background: linear-gradient(to right, #45a049, #388E3C);
                transform: translateY(-1px);
            }
        `);

        // Создаем модальное окно
        const modal = document.createElement('div');
        modal.id = 'setup-modal';
        modal.innerHTML = `
            <div class="setup-container">
                <div class="setup-title">🚀 Настройка Smart Notes</div>

                <div class="setup-input-group">
                    <label class="setup-label">Введите RN (9 цифр):</label>
                    <input type="text" id="rn-input" class="setup-input" placeholder="253177049" maxlength="9">
                    <div class="setup-info">RN не изменяется, это фиксированный номер</div>
                    <div class="setup-example">Пример: 253177049</div>
                </div>

                <div class="setup-input-group">
                    <label class="setup-label">Введите шаблон для AN:</label>
                    <input type="text" id="an-input" class="setup-input" placeholder="448XXXXX" maxlength="8">
                    <div class="setup-info">Первые цифры - фиксированные, X - случайные цифры</div>
                    <div class="setup-example">Пример: 448XXXXX (8 цифр: 448 + 5 случайных)</div>
                    <div class="setup-example">Пример: 44XXXXXX (8 цифр: 44 + 6 случайных)</div>
                </div>

                <button id="save-setup" class="setup-button">💾 Сохранить и продолжить</button>
            </div>
        `;

        document.body.appendChild(modal);

        // Фокус на первом поле
        setTimeout(() => {
            document.getElementById('rn-input').focus();
        }, 100);

        // Обработчик сохранения
        document.getElementById('save-setup').addEventListener('click', function() {
            const rnInput = document.getElementById('rn-input').value.trim();
            const anInput = document.getElementById('an-input').value.trim();

            // Проверка RN
            if (!/^\d{9}$/.test(rnInput)) {
                alert('❌ RN должен содержать ровно 9 цифр!');
                document.getElementById('rn-input').focus();
                return;
            }

            // Проверка шаблона AN
            if (!/^\d{1,7}X{1,7}$/.test(anInput) || anInput.length !== 8) {
                alert('❌ Шаблон AN должен содержать 8 символов: цифры и буквы X\nПример: 448XXXXX');
                document.getElementById('an-input').focus();
                return;
            }

            // Сохраняем данные
            GM_setValue('user_rn', rnInput);
            GM_setValue('user_an_template', anInput);

            // Создаем начальные данные
            const initialData = {
                an: generateANFromTemplate(anInput),
                email: generateRandomEmail(16),
                password: generateRandomPassword(8),
                phone: generateUSAPhoneNumber()
            };
            GM_setValue('smart_notes_data', initialData);

            // Удаляем модальное окно
            modal.remove();

            // Перезагружаем страницу для применения настроек
            showNotification('✅ Настройки сохранены! Перезагружаем...');
            setTimeout(() => {
                location.reload();
            }, 1000);
        });

        // Поддержка Enter для сохранения
        modal.addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                document.getElementById('save-setup').click();
            }
        });
    }

    // Генерация AN по шаблону
    function generateANFromTemplate(template) {
        let result = '';
        for (let char of template) {
            if (char === 'X') {
                result += Math.floor(Math.random() * 10);
            } else {
                result += char;
            }
        }
        return result;
    }

    // Функция для генерации случайных цифр
    function generateRandomDigits(length) {
        let result = '';
        for (let i = 0; i < length; i++) {
            result += Math.floor(Math.random() * 10);
        }
        return result;
    }

    // Функция для генерации случайных букв
    function generateRandomLetters(length, uppercase = false) {
        let result = '';
        const chars = 'abcdefghijklmnopqrstuvwxyz';
        for (let i = 0; i < length; i++) {
            let char = chars.charAt(Math.floor(Math.random() * chars.length));
            result += uppercase ? char.toUpperCase() : char;
        }
        return result;
    }

    // Генерация случайной почты
    function generateRandomEmail(length = 16) {
        const prefix = generateRandomLetters(length - 10) + generateRandomDigits(3);
        return prefix.toLowerCase() + '@yahoo.com';
    }

    // Генерация случайного пароля
    function generateRandomPassword(length = 8) {
        const lowercase = 'abcdefghijklmnopqrstuvwxyz';
        const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        const digits = '0123456789';
        const specials = '!@#$%^&*';

        // Гарантируем хотя бы одну цифру, одну заглавную букву и один спецсимвол
        let password = '';
        password += uppercase.charAt(Math.floor(Math.random() * uppercase.length)); // Заглавная буква
        password += digits.charAt(Math.floor(Math.random() * digits.length)); // Цифра
        password += specials.charAt(Math.floor(Math.random() * specials.length)); // Спецсимвол

        // Заполняем оставшиеся символы
        const allChars = lowercase + uppercase + digits + specials;
        for (let i = password.length; i < length; i++) {
            password += allChars.charAt(Math.floor(Math.random() * allChars.length));
        }

        // Перемешиваем символы
        return password.split('').sort(() => Math.random() - 0.5).join('');
    }

    // Генерация USA номера телефона (10 цифр без форматирования)
    function generateUSAPhoneNumber() {
        return generateRandomDigits(10);
    }

    // Функция копирования в буфер обмена
    function copyToClipboard(text) {
        navigator.clipboard.writeText(text).then(() => {
            showNotification('✅ Скопировано: ' + (text.length > 20 ? text.substring(0, 20) + '...' : text));
        }).catch(err => {
            // Fallback для старых браузеров
            const textArea = document.createElement('textarea');
            textArea.value = text;
            document.body.appendChild(textArea);
            textArea.select();
            document.execCommand('copy');
            document.body.removeChild(textArea);
            showNotification('✅ Скопировано');
        });
    }

    // Функция обновления генератора
    function refreshGenerator(type) {
        let newValue;

        switch(type) {
            case 'an':
                newValue = generateANFromTemplate(userANTemplate);
                savedData.an = newValue;
                break;
            case 'email':
                newValue = generateRandomEmail(16);
                savedData.email = newValue;
                break;
            case 'password':
                newValue = generateRandomPassword(8);
                savedData.password = newValue;
                break;
            case 'phone':
                newValue = generateUSAPhoneNumber();
                savedData.phone = newValue;
                break;
        }

        // Обновляем отображение
        const valueElement = document.querySelector(`.generator-value.${type}`);
        const row = valueElement.closest('.generator-row');
        const copyBtn = row.querySelector('.gen-copy');

        valueElement.textContent = newValue;
        valueElement.onclick = () => copyToClipboard(newValue);
        copyBtn.onclick = () => copyToClipboard(newValue);

        // Сохраняем
        GM_setValue('smart_notes_data', savedData);

        showNotification(`🔄 Обновлен ${type}: ${newValue}`);
    }

    // Стили для основного окна
    GM_addStyle(`
        #smart-notes-btn {
            position: fixed;
            top: 20px;
            right: 20px;
            width: 60px;
            height: 60px;
            background: linear-gradient(135deg, #2196F3, #1976D2);
            color: white;
            border: none;
            border-radius: 50%;
            cursor: pointer;
            z-index: 999999;
            font-size: 24px;
            box-shadow: 0 4px 12px rgba(33, 150, 243, 0.4);
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0;
        }

        #smart-notes-btn:hover {
            transform: scale(1.1);
            box-shadow: 0 6px 15px rgba(33, 150, 243, 0.6);
        }

        #smart-notes-window {
            position: fixed;
            top: 100px;
            right: 20px;
            width: 380px;
            background: white;
            border: 2px solid #2196F3;
            border-radius: 12px;
            box-shadow: 0 8px 25px rgba(33, 150, 243, 0.3);
            z-index: 999998;
            font-family: 'SF Pro Text', -apple-system, sans-serif;
            display: none;
            overflow: hidden;
        }

        #notes-header {
            background: linear-gradient(135deg, #2196F3, #1976D2);
            color: white;
            padding: 16px 20px;
            border-radius: 10px 10px 0 0;
            cursor: move;
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-weight: 600;
            font-size: 16px;
            border-bottom: 1px solid rgba(255, 255, 255, 0.2);
        }

        #notes-content {
            padding: 20px;
            max-height: 500px;
            overflow-y: auto;
            background: #f8fafc;
        }

        .generators-section {
            margin-bottom: 20px;
        }

        .section-title {
            font-size: 14px;
            font-weight: 600;
            color: #1976D2;
            margin: 20px 0 10px 0;
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .section-title:first-child {
            margin-top: 0;
        }

        .generator-row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 12px;
            margin: 8px 0;
            border-radius: 8px;
            background: white;
            border: 1px solid #e0e0e0;
        }

        .generator-label {
            font-weight: 600;
            font-size: 13px;
            min-width: 80px;
        }

        .generator-value {
            font-family: 'SF Mono', Monaco, monospace;
            font-size: 13px;
            flex: 1;
            margin: 0 10px;
            padding: 6px 10px;
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.2s;
            word-break: break-all;
            user-select: all;
            border: 1px solid transparent;
        }

        .generator-value:hover {
            transform: scale(1.02);
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }

        .generator-value.rn {
            background: linear-gradient(135deg, #fff9c4, #fff176);
            color: #5d4037;
            border-color: #ffd54f;
        }

        .generator-value.an {
            background: linear-gradient(135deg, #e1bee7, #ce93d8);
            color: #4a148c;
            border-color: #ba68c8;
        }

        .generator-value.email {
            background: linear-gradient(135deg, #b3e5fc, #81d4fa);
            color: #01579b;
            border-color: #4fc3f7;
        }

        .generator-value.password {
            background: linear-gradient(135deg, #c8e6c9, #a5d6a7);
            color: #1b5e20;
            border-color: #81c784;
        }

        .generator-value.phone {
            background: linear-gradient(135deg, #ffccbc, #ffab91);
            color: #bf360c;
            border-color: #ff8a65;
        }

        .generator-buttons {
            display: flex;
            gap: 5px;
            min-width: 70px;
        }

        .gen-btn {
            padding: 6px 10px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 11px;
            font-weight: 500;
            transition: all 0.2s;
            display: flex;
            align-items: center;
            justify-content: center;
            min-width: 32px;
        }

        .gen-refresh {
            background: #4CAF50;
            color: white;
        }

        .gen-refresh:hover {
            background: #388E3C;
            transform: scale(1.1);
        }

        .gen-copy {
            background: #2196F3;
            color: white;
        }

        .gen-copy:hover {
            background: #1976D2;
            transform: scale(1.1);
        }

        .user-notes-section {
            margin-top: 20px;
        }

        #user-notes-textarea {
            width: 100%;
            min-height: 100px;
            padding: 12px;
            border: 1px solid #bbdefb;
            border-radius: 8px;
            background: white;
            font-family: 'SF Pro Text', -apple-system, sans-serif;
            font-size: 13px;
            line-height: 1.4;
            resize: vertical;
            color: #333;
            box-sizing: border-box;
            margin-bottom: 12px;
        }

        #user-notes-textarea:focus {
            outline: none;
            border-color: #2196F3;
            box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.2);
        }

        .notes-controls {
            display: flex;
            gap: 8px;
            padding: 15px 20px;
            background: #f1f8ff;
            border-top: 1px solid #e3f2fd;
        }

        .notes-btn {
            padding: 10px 12px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            flex: 1;
            font-weight: 500;
            font-size: 12px;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 5px;
        }

        .notes-refresh-all {
            background: linear-gradient(to right, #FF9800, #F57C00);
            color: white;
        }

        .notes-refresh-all:hover {
            background: linear-gradient(to right, #F57C00, #E65100);
            transform: translateY(-1px);
        }

        .notes-save {
            background: linear-gradient(to right, #4CAF50, #45a049);
            color: white;
        }

        .notes-save:hover {
            background: linear-gradient(to right, #45a049, #388E3C);
            transform: translateY(-1px);
        }

        .notes-close {
            background: linear-gradient(to right, #9E9E9E, #757575);
            color: white;
        }

        .notes-close:hover {
            background: linear-gradient(to right, #757575, #616161);
            transform: translateY(-1px);
        }

        .notes-info {
            font-size: 11px;
            color: #666;
            text-align: center;
            margin-top: 8px;
            padding-top: 8px;
            border-top: 1px dashed #ddd;
        }

        .template-info {
            font-size: 11px;
            color: #666;
            margin-top: 5px;
            font-style: italic;
        }
    `);

    // Создаем кнопку
    function createButton() {
        const button = document.createElement('button');
        button.id = 'smart-notes-btn';
        button.innerHTML = '📝';
        button.title = 'Smart Notes - Генераторы данных';

        button.addEventListener('click', toggleNotesWindow);
        document.body.appendChild(button);
    }

    // Создаем окно заметок
    function createNotesWindow() {
        const windowElement = document.createElement('div');
        windowElement.id = 'smart-notes-window';

        windowElement.innerHTML = `
            <div id="notes-header">
                <span>🚀 Smart Notes</span>
                <span id="notes-minimize" style="cursor:pointer; font-size:20px;">−</span>
            </div>
            <div id="notes-content">
                <div class="section-title">
                    <span>🎯 Генераторы данных</span>
                </div>
                <div class="generators-section">
                    <!-- RN (введен пользователем) -->
                    <div class="generator-row" id="rn-row">
                        <div class="generator-label">RN:</div>
                        <div class="generator-value rn">${userRN}</div>
                        <div class="generator-buttons">
                            <button class="gen-btn gen-copy" title="Копировать">📋</button>
                        </div>
                    </div>
                    <div class="template-info">Шаблон AN: ${userANTemplate}</div>

                    <!-- AN (генерируется по шаблону) -->
                    <div class="generator-row" id="an-row">
                        <div class="generator-label">AN:</div>
                        <div class="generator-value an">${savedData.an}</div>
                        <div class="generator-buttons">
                            <button class="gen-btn gen-refresh" title="Обновить">🔄</button>
                            <button class="gen-btn gen-copy" title="Копировать">📋</button>
                        </div>
                    </div>

                    <!-- Email -->
                    <div class="generator-row" id="email-row">
                        <div class="generator-label">Email:</div>
                        <div class="generator-value email">${savedData.email}</div>
                        <div class="generator-buttons">
                            <button class="gen-btn gen-refresh" title="Обновить">🔄</button>
                            <button class="gen-btn gen-copy" title="Копировать">📋</button>
                        </div>
                    </div>

                    <!-- Password -->
                    <div class="generator-row" id="password-row">
                        <div class="generator-label">Password:</div>
                        <div class="generator-value password">${savedData.password}</div>
                        <div class="generator-buttons">
                            <button class="gen-btn gen-refresh" title="Обновить">🔄</button>
                            <button class="gen-btn gen-copy" title="Копировать">📋</button>
                        </div>
                    </div>

                    <!-- USA Phone -->
                    <div class="generator-row" id="phone-row">
                        <div class="generator-label">USA Phone:</div>
                        <div class="generator-value phone">${savedData.phone}</div>
                        <div class="generator-buttons">
                            <button class="gen-btn gen-refresh" title="Обновить">🔄</button>
                            <button class="gen-btn gen-copy" title="Копировать">📋</button>
                        </div>
                    </div>
                </div>

                <div class="section-title">
                    <span>📝 Мои заметки</span>
                </div>
                <div class="user-notes-section">
                    <textarea id="user-notes-textarea" placeholder="Введите ваши заметки здесь...">${USER_NOTES}</textarea>
                    <div class="notes-info">
                        Сохраняются автоматически при закрытии
                    </div>
                </div>
            </div>
            <div class="notes-controls">
                <button id="refresh-all-btn" class="notes-btn notes-refresh-all" title="Обновить все генераторы">
                    🔄 Все
                </button>
                <button id="save-btn" class="notes-btn notes-save" title="Сохранить заметки">
                    💾 Сохранить
                </button>
                <button id="close-btn" class="notes-btn notes-close" title="Закрыть окно">
                    ✕ Закрыть
                </button>
            </div>
        `;

        document.body.appendChild(windowElement);
        makeDraggable(windowElement);
        setupNotesListeners();
        setupGeneratorListeners();
    }

    // Настройка слушателей для генераторов
    function setupGeneratorListeners() {
        // RN - копирование
        const rnRow = document.getElementById('rn-row');
        const rnCopyBtn = rnRow.querySelector('.gen-copy');
        const rnValueElement = rnRow.querySelector('.generator-value');

        rnValueElement.addEventListener('click', () => copyToClipboard(userRN));
        rnCopyBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            copyToClipboard(userRN);
        });

        // AN
        setupGeneratorRow('an');

        // Email
        setupGeneratorRow('email');

        // Password
        setupGeneratorRow('password');

        // Phone
        setupGeneratorRow('phone');
    }

    // Настройка строки генератора
    function setupGeneratorRow(type) {
        const row = document.getElementById(`${type}-row`);
        const valueElement = row.querySelector('.generator-value');
        const refreshBtn = row.querySelector('.gen-refresh');
        const copyBtn = row.querySelector('.gen-copy');

        // Клик по значению - копирование
        valueElement.addEventListener('click', () => copyToClipboard(savedData[type]));

        // Кнопка обновления
        refreshBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            refreshGenerator(type);
        });

        // Кнопка копирования
        copyBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            copyToClipboard(savedData[type]);
        });
    }

    // Переключение окна
    function toggleNotesWindow() {
        const windowElement = document.getElementById('smart-notes-window');
        const button = document.getElementById('smart-notes-btn');

        if (windowElement.style.display === 'block') {
            windowElement.style.display = 'none';
            button.innerHTML = '📝';
            button.style.background = 'linear-gradient(135deg, #2196F3, #1976D2)';
            saveUserNotes(); // Автосохранение при закрытии
        } else {
            windowElement.style.display = 'block';
            button.innerHTML = '📘';
            button.style.background = 'linear-gradient(135deg, #4CAF50, #45a049)';
        }
    }

    // Настройка обработчиков
    function setupNotesListeners() {
        // Обновить все генераторы
        document.getElementById('refresh-all-btn').addEventListener('click', refreshAllGenerators);

        // Сохранить заметки
        document.getElementById('save-btn').addEventListener('click', saveUserNotes);

        // Закрыть окно
        document.getElementById('close-btn').addEventListener('click', toggleNotesWindow);

        // Сворачивание
        document.getElementById('notes-minimize').addEventListener('click', function(e) {
            e.stopPropagation();
            const content = document.getElementById('notes-content');
            const controls = document.querySelector('.notes-controls');
            const isHidden = content.style.display === 'none';

            content.style.display = isHidden ? 'block' : 'none';
            controls.style.display = isHidden ? 'flex' : 'none';
            this.innerHTML = isHidden ? '−' : '+';
        });
    }

    // Обновить все генераторы
    function refreshAllGenerators() {
        savedData = {
            an: generateANFromTemplate(userANTemplate),
            email: generateRandomEmail(16),
            password: generateRandomPassword(8),
            phone: generateUSAPhoneNumber()
        };

        // Обновляем отображение и слушатели
        const types = ['an', 'email', 'password', 'phone'];
        types.forEach(type => {
            const row = document.getElementById(`${type}-row`);
            const valueElement = row.querySelector('.generator-value');

            valueElement.textContent = savedData[type];

            // Обновляем слушатели
            valueElement.onclick = () => copyToClipboard(savedData[type]);

            const copyBtn = row.querySelector('.gen-copy');
            copyBtn.onclick = (e) => {
                e.stopPropagation();
                copyToClipboard(savedData[type]);
            };
        });

        // Сохраняем
        GM_setValue('smart_notes_data', savedData);

        showNotification('🔄 Все генераторы обновлены!');
    }

    // Сохранить пользовательские заметки
    function saveUserNotes() {
        const textarea = document.getElementById('user-notes-textarea');
        const text = textarea.value;

        GM_setValue('user_smart_notes', text);
        showNotification('💾 Заметки сохранены');
    }

    // Перетаскивание окна
    function makeDraggable(element) {
        const header = document.getElementById('notes-header');
        let isDragging = false;
        let currentX, currentY, initialX, initialY;

        header.addEventListener('mousedown', startDrag);

        function startDrag(e) {
            if (e.target.id === 'notes-minimize') return;

            initialX = e.clientX - element.offsetLeft;
            initialY = e.clientY - element.offsetTop;
            isDragging = true;

            document.addEventListener('mousemove', drag);
            document.addEventListener('mouseup', stopDrag);
            header.style.opacity = '0.9';
        }

        function drag(e) {
            if (isDragging) {
                e.preventDefault();
                currentX = e.clientX - initialX;
                currentY = e.clientY - initialY;

                // Ограничение перемещения
                currentX = Math.max(10, Math.min(currentX, window.innerWidth - element.offsetWidth - 10));
                currentY = Math.max(10, Math.min(currentY, window.innerHeight - element.offsetHeight - 10));

                element.style.left = currentX + 'px';
                element.style.top = currentY + 'px';
                element.style.right = 'auto';
            }
        }

        function stopDrag() {
            isDragging = false;
            document.removeEventListener('mousemove', drag);
            document.removeEventListener('mouseup', stopDrag);
            header.style.opacity = '1';
        }
    }

    // Уведомления
    function showNotification(message) {
        const notification = document.createElement('div');
        notification.textContent = message;

        notification.style.cssText = `
            position: fixed;
            top: 90px;
            right: 20px;
            background: #333;
            color: white;
            padding: 10px 15px;
            border-radius: 6px;
            z-index: 999997;
            font-family: system-ui, -apple-system, sans-serif;
            font-size: 13px;
            box-shadow: 0 3px 10px rgba(0,0,0,0.2);
            animation: slideIn 0.3s ease;
            max-width: 300px;
        `;

        document.body.appendChild(notification);

        setTimeout(() => {
            notification.style.animation = 'slideOut 0.3s ease';
            setTimeout(() => notification.remove(), 300);
        }, 2000);

        // Стили анимации
        if (!document.querySelector('#notes-notification-styles')) {
            const style = document.createElement('style');
            style.id = 'notes-notification-styles';
            style.textContent = `
                @keyframes slideIn {
                    from { transform: translateX(100%); opacity: 0; }
                    to { transform: translateX(0); opacity: 1; }
                }
                @keyframes slideOut {
                    from { transform: translateX(0); opacity: 1; }
                    to { transform: translateX(100%); opacity: 0; }
                }
            `;
            document.head.appendChild(style);
        }
    }

    // Инициализация
    setTimeout(() => {
        createButton();
        createNotesWindow();

        showNotification('🚀 Smart Notes загружен. Нажмите кнопку 📝');
    }, 1000);
})();