привет! вот код gui для управления настройками телеграм бота. исправь эту ошибку
Traceback (most recent call last):
  File "c:\Users\misha\OneDrive\Рабочий стол\meowbot\meow\meowalka! v0.2\config_gui.py", line 659, in <module>
    main()
  File "c:\Users\misha\OneDrive\Рабочий стол\meowbot\meow\meowalka! v0.2\config_gui.py", line 655, in main
    gui = ConfigGUI(root)
  File "c:\Users\misha\OneDrive\Рабочий стол\meowbot\meow\meowalka! v0.2\config_gui.py", line 223, in __init__
    self.create_credentials_tab()
  File "c:\Users\misha\OneDrive\Рабочий стол\meowbot\meow\meowalka! v0.2\config_gui.py", line 274, in create_credentials_tab
    telegram_entry = ttk.Entry(frame, textvariable=self.telegram_token_var, width=50, undo=True)
  File "C:\Users\misha\AppData\Local\Programs\Python\Python310\lib\tkinter\ttk.py", line 664, in __init__
    Widget.__init__(self, master, widget or "ttk::entry", kw)
  File "C:\Users\misha\AppData\Local\Programs\Python\Python310\lib\tkinter\ttk.py", line 552, in __init__
    tkinter.Widget.__init__(self, master, widgetname, kw=kw)
  File "C:\Users\misha\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 2601, in __init__
    self.tk.call(
_tkinter.TclError: unknown option "-undo"
сам код:
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import json
import os

CONFIG_FILE = 'config.json'

def load_config():
    # Определяем директорию текущего скрипта
    script_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(script_dir, CONFIG_FILE)
    
    if not os.path.exists(config_path):
        # Создание стандартного конфигурационного файла, если он не существует
        default_config = {
            "telegram_token": "",
            "api_key": "",
            "authorized_user_ids": [],
            "models": {},
            "system_instruction": "ты - хороший ассистент, готовый ответить на любой вопрос."
        }
        with open(config_path, 'w', encoding='utf-8') as f:
            json.dump(default_config, f, indent=4, ensure_ascii=False)
    with open(config_path, 'r', encoding='utf-8') as f:
        return json.load(f)

def save_config(config):
    # Определяем директорию текущего скрипта
    script_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(script_dir, CONFIG_FILE)
    
    with open(config_path, 'w', encoding='utf-8') as f:
        json.dump(config, f, indent=4, ensure_ascii=False)

class AddEditModelDialog:
    def __init__(self, parent, title, name="", model_id="", model_type="text"):
        self.parent = parent
        self.top = tk.Toplevel(parent)
        self.top.title(title)
        self.top.transient(parent)
        self.top.grab_set()
        self.top.resizable(False, False)
        
        # Центрирование диалогового окна
        self.top.update_idletasks()
        width = 400
        height = 200
        x = parent.winfo_x() + (parent.winfo_width() // 2) - (width // 2)
        y = parent.winfo_y() + (parent.winfo_height() // 2) - (height // 2)
        self.top.geometry(f"{width}x{height}+{x}+{y}")
        
        # Основной фрейм
        main_frame = ttk.Frame(self.top)
        main_frame.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
        
        # Название модели
        ttk.Label(main_frame, text="Название модели:").grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
        self.name_var = tk.StringVar(value=name)
        self.name_entry = ttk.Entry(main_frame, textvariable=self.name_var, width=50)
        self.name_entry.grid(column=1, row=0, padx=5, pady=5, sticky=tk.W)
        
        # Кнопка "Вставить" для названия модели
        paste_btn_name = ttk.Button(main_frame, text="Вставить", command=lambda: self.paste_text(self.name_entry))
        paste_btn_name.grid(column=2, row=0, padx=5, pady=5)
        
        # ID модели
        ttk.Label(main_frame, text="ID модели:").grid(column=0, row=1, sticky=tk.W, padx=5, pady=5)
        self.id_var = tk.StringVar(value=model_id)
        self.id_entry = ttk.Entry(main_frame, textvariable=self.id_var, width=50)
        self.id_entry.grid(column=1, row=1, padx=5, pady=5, sticky=tk.W)
        
        # Кнопка "Вставить" для ID модели
        paste_btn_id = ttk.Button(main_frame, text="Вставить", command=lambda: self.paste_text(self.id_entry))
        paste_btn_id.grid(column=2, row=1, padx=5, pady=5)
        
        # Тип модели
        ttk.Label(main_frame, text="Тип модели:").grid(column=0, row=2, sticky=tk.W, padx=5, pady=5)
        self.type_var = tk.StringVar(value=model_type)
        self.type_combo = ttk.Combobox(main_frame, textvariable=self.type_var, values=["text", "image", "multimodal"], state="readonly")
        self.type_combo.grid(column=1, row=2, padx=5, pady=5, sticky=tk.W)
        self.type_combo.set(model_type)
        
        # Кнопка "Вставить" для типов моделей (опционально)
        # Если необходимо вставлять типы моделей, можно добавить кнопку здесь
        
        # Кнопки "OK" и "Отмена"
        btn_frame = ttk.Frame(main_frame)
        btn_frame.grid(column=0, row=3, columnspan=3, pady=10)
        
        ok_btn = ttk.Button(btn_frame, text="OK", command=self.on_ok)
        ok_btn.pack(side=tk.RIGHT, padx=5)
        
        cancel_btn = ttk.Button(btn_frame, text="Отмена", command=self.on_cancel)
        cancel_btn.pack(side=tk.RIGHT, padx=5)
        
        # Добавление контекстного меню для вставки
        self.add_paste_context_menu(self.name_entry)
        self.add_paste_context_menu(self.id_entry)
    
    def add_paste_context_menu(self, widget):
        menu = tk.Menu(widget, tearoff=0)
        menu.add_command(label="Вставить", command=lambda: self.paste_text(widget))
        
        def show_context_menu(event):
            try:
                menu.tk_popup(event.x_root, event.y_root)
            finally:
                menu.grab_release()
        
        widget.bind("<Button-3>", show_context_menu)  # Для Windows и Linux
        widget.bind("<Button-2>", show_context_menu)  # Для macOS
    
    def paste_text(self, widget):
        try:
            clipboard = self.top.clipboard_get()
            widget.insert(tk.INSERT, clipboard)
        except tk.TclError:
            pass  # Нет данных в буфере обмена
    
    def on_ok(self):
        name = self.name_var.get().strip()
        model_id = self.id_var.get().strip()
        model_type = self.type_var.get().strip()
        if not name or not model_id or not model_type:
            messagebox.showerror("Ошибка", "Все поля обязательны для заполнения.", parent=self.top)
            return
        self.result = (name, model_id, model_type)
        self.top.destroy()
    
    def on_cancel(self):
        self.top.destroy()

class AddEditUserDialog:
    def __init__(self, parent, title):
        self.top = tk.Toplevel(parent)
        self.top.title(title)
        self.top.transient(parent)
        self.top.grab_set()
        self.top.resizable(False, False)
        
        # Центрирование диалогового окна
        self.top.update_idletasks()
        width = 300
        height = 120
        x = parent.winfo_x() + (parent.winfo_width() // 2) - (width // 2)
        y = parent.winfo_y() + (parent.winfo_height() // 2) - (height // 2)
        self.top.geometry(f"{width}x{height}+{x}+{y}")
        
        # Основной фрейм
        main_frame = ttk.Frame(self.top)
        main_frame.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
        
        # ID пользователя
        ttk.Label(main_frame, text="ID пользователя:").grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
        self.user_id_var = tk.StringVar()
        self.user_entry = ttk.Entry(main_frame, textvariable=self.user_id_var, width=40)
        self.user_entry.grid(column=1, row=0, padx=5, pady=5, sticky=tk.W)
        
        # Кнопка "Вставить"
        paste_btn_user = ttk.Button(main_frame, text="Вставить", command=lambda: self.paste_text(self.user_entry))
        paste_btn_user.grid(column=2, row=0, padx=5, pady=5)
        
        # Кнопки "OK" и "Отмена"
        btn_frame = ttk.Frame(main_frame)
        btn_frame.grid(column=0, row=1, columnspan=3, pady=10)
        
        ok_btn = ttk.Button(btn_frame, text="OK", command=self.on_ok)
        ok_btn.pack(side=tk.RIGHT, padx=5)
        
        cancel_btn = ttk.Button(btn_frame, text="Отмена", command=self.on_cancel)
        cancel_btn.pack(side=tk.RIGHT, padx=5)
        
        # Добавление контекстного меню для вставки
        self.add_paste_context_menu(self.user_entry)
    
    def add_paste_context_menu(self, widget):
        menu = tk.Menu(widget, tearoff=0)
        menu.add_command(label="Вставить", command=lambda: self.paste_text(widget))
        
        def show_context_menu(event):
            try:
                menu.tk_popup(event.x_root, event.y_root)
            finally:
                menu.grab_release()
        
        widget.bind("<Button-3>", show_context_menu)  # Для Windows и Linux
        widget.bind("<Button-2>", show_context_menu)  # Для macOS
    
    def paste_text(self, widget):
        try:
            clipboard = self.top.clipboard_get()
            widget.insert(tk.INSERT, clipboard)
        except tk.TclError:
            pass  # Нет данных в буфере обмена
    
    def on_ok(self):
        user_id = self.user_id_var.get().strip()
        if not user_id:
            messagebox.showerror("Ошибка", "ID пользователя обязательно для заполнения.", parent=self.top)
            return
        try:
            user_id = int(user_id)
        except ValueError:
            messagebox.showerror("Ошибка", "ID пользователя должен быть числом.", parent=self.top)
            return
        self.result = user_id
        self.top.destroy()
    
    def on_cancel(self):
        self.top.destroy()

class ConfigGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("Настройки Telegram бота")
        self.config = load_config()

        tab_control = ttk.Notebook(root)

        # Вкладка для токенов и ключей
        self.credentials_tab = ttk.Frame(tab_control)
        tab_control.add(self.credentials_tab, text='Токены и ключи')
        self.create_credentials_tab()

        # Вкладка для авторизованных пользователей
        self.users_tab = ttk.Frame(tab_control)
        tab_control.add(self.users_tab, text='Авторизованные пользователи')
        self.create_users_tab()

        # Вкладка для моделей
        self.models_tab = ttk.Frame(tab_control)
        tab_control.add(self.models_tab, text='Модели')
        self.create_models_tab()

        # Вкладка для инструкций
        self.instruction_tab = ttk.Frame(tab_control)
        tab_control.add(self.instruction_tab, text='Инструкция')
        self.create_instruction_tab()

        tab_control.pack(expand=1, fill='both')

        # Кнопки сохранения и выхода
        btn_frame = ttk.Frame(root)
        btn_frame.pack(side=tk.BOTTOM, padx=10, pady=10)

        save_button = ttk.Button(btn_frame, text="Сохранить", command=self.save_and_exit)
        save_button.pack(side=tk.RIGHT, padx=5)

        exit_button = ttk.Button(btn_frame, text="Выйти", command=root.quit)
        exit_button.pack(side=tk.RIGHT, padx=5)

        # Центрирование окна после создания всех виджетов
        self.center_window()

    def center_window(self):
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        if width <= 1 and height <=1:
            # Если окно ещё не отрисовано, временно установим размеры
            self.root.geometry("800x600")
            width = 800
            height = 600
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f"{width}x{height}+{x}+{y}")

    def create_credentials_tab(self):
        frame = self.credentials_tab

        # Telegram Token
        ttk.Label(frame, text="Токен бота:").grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
        self.telegram_token_var = tk.StringVar(value=self.config.get('telegram_token', ''))
        telegram_entry = ttk.Entry(frame, textvariable=self.telegram_token_var, width=50, undo=True)
        telegram_entry.grid(column=1, row=0, padx=5, pady=5, sticky=tk.W)
        paste_btn_telegram = ttk.Button(frame, text="Вставить", command=lambda: self.paste_text(telegram_entry))
        paste_btn_telegram.grid(column=2, row=0, padx=5, pady=5)
        
        # Добавление контекстного меню для вставки
        self.add_paste_context_menu(telegram_entry)

        # API Key
        ttk.Label(frame, text="API ключ:").grid(column=0, row=1, sticky=tk.W, padx=5, pady=5)
        self.api_key_var = tk.StringVar(value=self.config.get('api_key', ''))
        api_entry = ttk.Entry(frame, textvariable=self.api_key_var, width=50, undo=True)
        api_entry.grid(column=1, row=1, padx=5, pady=5, sticky=tk.W)
        paste_btn_api = ttk.Button(frame, text="Вставить", command=lambda: self.paste_text(api_entry))
        paste_btn_api.grid(column=2, row=1, padx=5, pady=5)
        
        # Добавление контекстного меню для вставки
        self.add_paste_context_menu(api_entry)

    def create_users_tab(self):
        frame = self.users_tab

        # Список авторизованных пользователей
        ttk.Label(frame, text="ID телеграм пользователей, которым можно пользоваться ботом:").pack(anchor=tk.W, padx=5, pady=5)

        self.user_listbox = tk.Listbox(frame, height=15, width=50)
        self.user_listbox.pack(padx=5, pady=5)

        for user_id in self.config.get('authorized_user_ids', []):
            self.user_listbox.insert(tk.END, user_id)

        # Кнопки добавления и удаления пользователей
        btn_frame = ttk.Frame(frame)
        btn_frame.pack(pady=5)

        add_btn = ttk.Button(btn_frame, text="Добавить ID", command=self.add_user)
        add_btn.pack(side=tk.LEFT, padx=5)

        remove_btn = ttk.Button(btn_frame, text="Удалить выбранный ID", command=self.remove_user)
        remove_btn.pack(side=tk.LEFT, padx=5)

        # Реализация drag-and-drop для user_listbox
        self.user_listbox.bind('<ButtonPress-1>', self.on_user_start_drag)
        self.user_listbox.bind('<ButtonRelease-1>', self.on_user_drop)
        self.user_listbox.bind('<B1-Motion>', self.on_user_drag_motion)

        self.user_drag_data = {"index": None, "item": None}

    def on_user_start_drag(self, event):
        widget = event.widget
        try:
            index = widget.nearest(event.y)
            if index >= widget.size():
                self.user_drag_data["item"] = None
                self.user_drag_data["index"] = None
                return
            self.user_drag_data["item"] = widget.get(index)
            self.user_drag_data["index"] = index
        except Exception as e:
            self.user_drag_data["item"] = None
            self.user_drag_data["index"] = None

    def on_user_drag_motion(self, event):
        widget = event.widget
        try:
            y = event.y
            new_index = widget.nearest(y)
            if new_index < 0:
                new_index = 0
            elif new_index >= widget.size():
                new_index = widget.size() - 1

            old_index = self.user_drag_data["index"]
            if self.user_drag_data["item"] and new_index != old_index:
                # Удаляем и вставляем в новое место
                widget.delete(old_index)
                widget.insert(new_index, self.user_drag_data["item"])
                # Обновляем порядок в config
                try:
                    user_id = int(self.user_drag_data["item"])
                    self.config['authorized_user_ids'].remove(user_id)
                    self.config['authorized_user_ids'].insert(new_index, user_id)
                except ValueError:
                    pass
                self.user_drag_data["index"] = new_index
        except Exception:
            pass

    def on_user_drop(self, event):
        self.user_drag_data = {"index": None, "item": None}

    def add_user(self):
        dialog = AddEditUserDialog(self.root, "Добавить пользователя")
        self.root.wait_window(dialog.top)
        if dialog.result:
            user_id = dialog.result
            if user_id not in self.config['authorized_user_ids']:
                self.config['authorized_user_ids'].append(user_id)
                self.user_listbox.insert(tk.END, user_id)
            else:
                messagebox.showinfo("Информация", "Этот ID уже добавлен.", parent=self.root)

    def remove_user(self):
        selected = self.user_listbox.curselection()
        if selected:
            user_id = self.user_listbox.get(selected[0])
            confirm = messagebox.askyesno("Подтверждение", f"Вы точно хотите удалить пользователя с ID {user_id}?", parent=self.root)
            if confirm:
                try:
                    self.config['authorized_user_ids'].remove(int(user_id))
                    self.user_listbox.delete(selected[0])
                except ValueError:
                    messagebox.showerror("Ошибка", "Неверный формат ID пользователя.", parent=self.root)
        else:
            messagebox.showwarning("Предупреждение", "Выберите пользователя для удаления.", parent=self.root)

    def create_models_tab(self):
        frame = self.models_tab

        # Список моделей
        ttk.Label(frame, text="Доступные модели:").pack(anchor=tk.W, padx=5, pady=5)

        self.models_listbox = tk.Listbox(frame, height=15, width=50)
        self.models_listbox.pack(padx=5, pady=5)

        for name, model_info in self.config.get('models', {}).items():
            self.models_listbox.insert(tk.END, f"{name}: {model_info['id']} ({model_info['type']})")

        # Кнопки добавления, редактирования и удаления моделей
        btn_frame = ttk.Frame(frame)
        btn_frame.pack(pady=5)

        add_btn = ttk.Button(btn_frame, text="Добавить модель", command=self.add_model)
        add_btn.pack(side=tk.LEFT, padx=5)

        edit_btn = ttk.Button(btn_frame, text="Изменить модель", command=self.edit_model)
        edit_btn.pack(side=tk.LEFT, padx=5)

        remove_btn = ttk.Button(btn_frame, text="Удалить выбранную модель", command=self.remove_model)
        remove_btn.pack(side=tk.LEFT, padx=5)

        # Реализация drag-and-drop для models_listbox
        self.models_listbox.bind('<ButtonPress-1>', self.on_model_start_drag)
        self.models_listbox.bind('<ButtonRelease-1>', self.on_model_drop)
        self.models_listbox.bind('<B1-Motion>', self.on_model_drag_motion)

        self.model_drag_data = {"index": None, "item": None}

    def on_model_start_drag(self, event):
        widget = event.widget
        try:
            index = widget.nearest(event.y)
            if index >= widget.size():
                self.model_drag_data["item"] = None
                self.model_drag_data["index"] = None
                return
            self.model_drag_data["item"] = widget.get(index)
            self.model_drag_data["index"] = index
        except Exception as e:
            self.model_drag_data["item"] = None
            self.model_drag_data["index"] = None

    def on_model_drag_motion(self, event):
        widget = event.widget
        try:
            y = event.y
            new_index = widget.nearest(y)
            if new_index < 0:
                new_index = 0
            elif new_index >= widget.size():
                new_index = widget.size() - 1

            old_index = self.model_drag_data["index"]
            if self.model_drag_data["item"] and new_index != old_index:
                # Удаляем и вставляем в новое место
                widget.delete(old_index)
                widget.insert(new_index, self.model_drag_data["item"])
                # Обновляем порядок в config['models']
                try:
                    name, rest = self.model_drag_data["item"].split(": ", 1)
                    model_id, model_type = rest.rsplit(" (", 1)
                    model_type = model_type.rstrip(")")
                    # Удаляем старую запись
                    if name in self.config['models']:
                        del self.config['models'][name]
                    # Вставляем новую запись на новое место
                    models = list(self.config['models'].items())
                    models.insert(new_index, (name, {"id": model_id, "type": model_type}))
                    self.config['models'] = {k: v for k, v in models}
                except ValueError:
                    pass
                self.model_drag_data["index"] = new_index
        except Exception:
            pass

    def on_model_drop(self, event):
        self.model_drag_data = {"index": None, "item": None}

    def add_model(self):
        dialog = AddEditModelDialog(self.root, "Добавить модель")
        self.root.wait_window(dialog.top)
        if dialog.result:
            name, model_id, model_type = dialog.result
            if name in self.config['models']:
                messagebox.showerror("Ошибка", "Модель с таким именем уже существует.", parent=self.root)
                return
            self.config['models'][name] = {"id": model_id, "type": model_type}
            self.models_listbox.insert(tk.END, f"{name}: {model_id} ({model_type})")

    def edit_model(self):
        selected = self.models_listbox.curselection()
        if not selected:
            messagebox.showwarning("Предупреждение", "Выберите модель для изменения.", parent=self.root)
            return
        model_entry = self.models_listbox.get(selected[0])
        try:
            name, rest = model_entry.split(": ", 1)
            model_id, model_type = rest.rsplit(" (", 1)
            model_type = model_type.rstrip(")")
        except ValueError:
            messagebox.showerror("Ошибка", "Неверный формат выбранной модели.", parent=self.root)
            return

        dialog = AddEditModelDialog(self.root, "Изменить модель", name, model_id, model_type)
        self.root.wait_window(dialog.top)
        if dialog.result:
            new_name, new_model_id, new_model_type = dialog.result
            if new_name != name and new_name in self.config['models']:
                messagebox.showerror("Ошибка", "Модель с таким именем уже существует.", parent=self.root)
                return
            # Обновление конфигурации
            del self.config['models'][name]
            self.config['models'][new_name] = {"id": new_model_id, "type": new_model_type}
            # Обновление списка
            self.models_listbox.delete(selected[0])
            self.models_listbox.insert(selected[0], f"{new_name}: {new_model_id} ({new_model_type})")

    def remove_model(self):
        selected = self.models_listbox.curselection()
        if selected:
            model_entry = self.models_listbox.get(selected[0])
            try:
                name, rest = model_entry.split(": ", 1)
            except ValueError:
                messagebox.showerror("Ошибка", "Неверный формат выбранной модели.", parent=self.root)
                return
            confirm = messagebox.askyesno("Подтверждение", f"Вы точно хотите удалить модель '{name}'?", parent=self.root)
            if confirm:
                del self.config['models'][name]
                self.models_listbox.delete(selected[0])
        else:
            messagebox.showwarning("Предупреждение", "Выберите модель для удаления.", parent=self.root)

    def create_instruction_tab(self):
        frame = self.instruction_tab

        ttk.Label(frame, text="Системная инструкция:").pack(anchor=tk.W, padx=5, pady=5)
        self.instruction_text = tk.Text(frame, height=20, width=70, undo=True)
        self.instruction_text.pack(padx=10, pady=5)
        self.instruction_text.insert(tk.END, self.config.get('system_instruction', 'ты ведёшь себя как котик'))

        # Кнопка "Вставить"
        paste_btn_instruction = ttk.Button(frame, text="Вставить", command=lambda: self.paste_text(self.instruction_text))
        paste_btn_instruction.pack(padx=10, pady=(0,5), anchor=tk.E)

        # Добавление контекстного меню для вставки
        self.add_paste_context_menu(self.instruction_text)

    def add_paste_context_menu(self, widget):
        menu = tk.Menu(widget, tearoff=0)
        menu.add_command(label="Вставить", command=lambda: self.paste_text(widget))
        
        def show_context_menu(event):
            try:
                menu.tk_popup(event.x_root, event.y_root)
            finally:
                menu.grab_release()
        
        widget.bind("<Button-3>", show_context_menu)  # Для Windows и Linux
        widget.bind("<Button-2>", show_context_menu)  # Для macOS

    def paste_text(self, widget):
        try:
            clipboard = self.root.clipboard_get()
            widget.insert(tk.INSERT, clipboard)
        except tk.TclError:
            pass  # Нет данных в буфере обмена

    def save_and_exit(self):
        # Сохранение токенов и ключей
        self.config['telegram_token'] = self.telegram_token_var.get().strip()
        self.config['api_key'] = self.api_key_var.get().strip()

        # Сохранение инструкций
        self.config['system_instruction'] = self.instruction_text.get("1.0", tk.END).strip()

        save_config(self.config)
        messagebox.showinfo("Успех", "Настройки сохранены. Перезапустите бота для применения изменений.", parent=self.root)
        self.root.quit()

class AddEditUserDialog:
    def __init__(self, parent, title):
        self.top = tk.Toplevel(parent)
        self.top.title(title)
        self.top.transient(parent)
        self.top.grab_set()
        self.top.resizable(False, False)
        
        # Центрирование диалогового окна
        self.top.update_idletasks()
        width = 300
        height = 120
        x = parent.winfo_x() + (parent.winfo_width() // 2) - (width // 2)
        y = parent.winfo_y() + (parent.winfo_height() // 2) - (height // 2)
        self.top.geometry(f"{width}x{height}+{x}+{y}")
        
        # Основной фрейм
        main_frame = ttk.Frame(self.top)
        main_frame.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
        
        # ID пользователя
        ttk.Label(main_frame, text="ID пользователя:").grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
        self.user_id_var = tk.StringVar()
        self.user_entry = ttk.Entry(main_frame, textvariable=self.user_id_var, width=40, undo=True)
        self.user_entry.grid(column=1, row=0, padx=5, pady=5, sticky=tk.W)
        
        # Кнопка "Вставить"
        paste_btn_user = ttk.Button(main_frame, text="Вставить", command=lambda: self.paste_text(self.user_entry))
        paste_btn_user.grid(column=2, row=0, padx=5, pady=5)
        
        # Кнопки "OK" и "Отмена"
        btn_frame = ttk.Frame(main_frame)
        btn_frame.grid(column=0, row=1, columnspan=3, pady=10)
        
        ok_btn = ttk.Button(btn_frame, text="OK", command=self.on_ok)
        ok_btn.pack(side=tk.RIGHT, padx=5)
        
        cancel_btn = ttk.Button(btn_frame, text="Отмена", command=self.on_cancel)
        cancel_btn.pack(side=tk.RIGHT, padx=5)
        
        # Добавление контекстного меню для вставки
        self.add_paste_context_menu(self.user_entry)
    
    def add_paste_context_menu(self, widget):
        menu = tk.Menu(widget, tearoff=0)
        menu.add_command(label="Вставить", command=lambda: self.paste_text(widget))
        
        def show_context_menu(event):
            try:
                menu.tk_popup(event.x_root, event.y_root)
            finally:
                menu.grab_release()
        
        widget.bind("<Button-3>", show_context_menu)  # Для Windows и Linux
        widget.bind("<Button-2>", show_context_menu)  # Для macOS
    
    def paste_text(self, widget):
        try:
            clipboard = self.top.clipboard_get()
            widget.insert(tk.INSERT, clipboard)
        except tk.TclError:
            pass  # Нет данных в буфере обмена
    
    def on_ok(self):
        user_id = self.user_id_var.get().strip()
        if not user_id:
            messagebox.showerror("Ошибка", "ID пользователя обязательно для заполнения.", parent=self.top)
            return
        try:
            user_id = int(user_id)
        except ValueError:
            messagebox.showerror("Ошибка", "ID пользователя должен быть числом.", parent=self.top)
            return
        self.result = user_id
        self.top.destroy()
    
    def on_cancel(self):
        self.top.destroy()

def main():
    root = tk.Tk()
    gui = ConfigGUI(root)
    root.mainloop()

if __name__ == '__main__':
    main()