```lua
local imgui = require("imgui") -- Import необходимых модулей
local encoding = require("encoding")
encoding.default = "CP1251"
local u8 = encoding.UTF8
local json = require("dkjson") -- Убедитесь, что dkjson.lua доступен
local CHAT_COMMAND = "notepad" -- Константы
local SAVE_FILE = "notes.json" -- Файл для сохранения текущих заметок
local windowVisible = imgui.ImBool(false) -- Переменные состояния
local inputTitle = imgui.ImBuffer(256)
local inputTags = imgui.ImBuffer(256) -- Для ввода тегов
local inputText = imgui.ImBuffer(1024)
local searchQuery = imgui.ImBuffer(256)
local notes = {}
local showImportPopup = imgui.ImBool(false) -- Для всплывающих окон импорта/экспорта
local importPath = imgui.ImBuffer(256) -- для пользовательского пути импорта
local showExportPopup = imgui.ImBool(false)
local exportPath = imgui.ImBuffer(256) -- для пользовательского пути экспорта
local showDeletePopup = imgui.ImBool(false) -- Для подтверждения удаления заметки
local deleteNoteIndex = 0
local function fileExists(filepath) -- Вспомогательные функции -- Проверка существования файла
    local file = io.open(filepath, "r")
    if file then
        file:close()
        return true
    else
        return false
    end
end

local function loadNotes() -- Загрузка заметок из файла
    if fileExists(SAVE_FILE) then
        local file, err = io.open(SAVE_FILE, "r")
        if file then
            local content = file:read("*a")
            file:close()
            local decoded, _, decode_err = json.decode(content, 1, nil)
            if decoded and type(decoded) == "table" then
                notes = decoded
            else
                showNotification("Ошибка разбора файла заметок: " .. (decode_err or "Неизвестная ошибка"), 0xFF0000)
            end
        else
            showNotification("Не удалось открыть файл заметок: " .. (err or "Неизвестная ошибка"), 0xFF0000)
        end
    end
end

local function saveNotes() -- Сохранение заметок в файл
    local file, err = io.open(SAVE_FILE, "w")
    if file then
        local encoded = json.encode(notes, {
            indent = true
        })

        file:write(encoded)
        file:close()
    else
        showNotification("Не удалось сохранить заметки: " .. (err or "Неизвестная ошибка"), 0xFF0000) -- Обработка ошибки открытия файла
    end
end

local function importNotes(filepath) -- Импорт заметок из файла
    if fileExists(filepath) then
        local file, err = io.open(filepath, "r")
        if file then
            local content = file:read("*a")
            file:close()
            local decoded, _, decode_err = json.decode(content, 1, nil)
            if decoded and type(decoded) == "table" then
                notes = decoded
                saveNotes()
                showNotification("Заметки успешно импортированы из " .. filepath, 0x00FF00)
            else
                showNotification("Ошибка разбора файла импорта: " .. (decode_err or "Неизвестная ошибка"), 0xFF0000)
            end
        else
            showNotification("Не удалось открыть файл импорта: " .. filepath, 0xFF0000)
        end
    else
        showNotification("Файл импорта не найден: " .. filepath, 0xFF0000)
    end
end

local function exportNotes(filepath) -- Экспорт заметок в файл
    local file, err = io.open(filepath, "w")
    if file then
        local encoded = json.encode(notes, {
            indent = true
        })

        file:write(encoded)
        file:close()
        showNotification("Заметки успешно экспортированы в " .. filepath, 0x00FF00)
    else
        showNotification("Не удалось создать файл экспорта: " .. (err or filepath), 0xFF0000)
    end
end

local function importNotesWithPrompt() -- Функции для вызова всплывающих окон импорта и экспорта
    showImportPopup.v = true
end

local function exportNotesWithPrompt()
    showExportPopup.v = true
end

local function confirmImport() -- Функции подтверждения импорта и экспорта
    if showImportPopup.v then imgui.OpenPopup("Импорт заметок") end
    if imgui.BeginPopupModal("Импорт заметок", showImportPopup, imgui.WindowFlags.AlwaysAutoResize) then
        imgui.Text(u8("Введите путь к файлу импорта:"))
        imgui.InputText(u8("Путь к файлу"), importPath, imgui.ImVec2(300, 0))
        imgui.Separator()
        if imgui.Button(u8("Импортировать"), imgui.ImVec2(120, 0)) then
            local path = importPath.v
            if path ~= "" then
                importNotes(path)
                showImportPopup.v = false
                importPath.v = ""
            else
                showNotification("Путь к файлу импорта не может быть пустым.", 0xFFA500)
            end
        end

        imgui.SameLine()
        if imgui.Button(u8("Отмена"), imgui.ImVec2(120, 0)) then
            showImportPopup.v = false
            importPath.v = ""
        end

        imgui.EndPopup()
    end
end

local function confirmExport()
    if showExportPopup.v then imgui.OpenPopup("Экспорт заметок") end
    if imgui.BeginPopupModal("Экспорт заметок", showExportPopup, imgui.WindowFlags.AlwaysAutoResize) then
        imgui.Text(u8("Введите путь к файлу экспорта:"))
        imgui.InputText(u8("Путь к файлу"), exportPath, imgui.ImVec2(300, 0))
        imgui.Separator()
        if imgui.Button(u8("Экспортировать"), imgui.ImVec2(120, 0)) then
            local path = exportPath.v
            if path ~= "" then
                exportNotes(path)
                showExportPopup.v = false
                exportPath.v = ""
            else
                showNotification("Путь к файлу экспорта не может быть пустым.", 0xFFA500)
            end
        end

        imgui.SameLine()
        if imgui.Button(u8("Отмена"), imgui.ImVec2(120, 0)) then
            showExportPopup.v = false
            exportPath.v = ""
        end

        imgui.EndPopup()
    end
end

local function confirmDelete() -- Функция подтверждения удаления заметки
    if showDeletePopup.v then imgui.OpenPopup("Подтверждение удаления") end
    if imgui.BeginPopupModal("Подтверждение удаления", showDeletePopup, imgui.WindowFlags.AlwaysAutoResize) then
        imgui.Text(u8("Вы уверены, что хотите удалить эту заметку?"))
        imgui.Separator()
        if imgui.Button(u8("Да"), imgui.ImVec2(120, 0)) then
            table.remove(notes, deleteNoteIndex)
            saveNotes()
            showDeletePopup.v = false
            showNotification("Заметка удалена.", 0xFFA500)
        end

        imgui.SameLine()
        if imgui.Button(u8("Нет"), imgui.ImVec2(120, 0)) then showDeletePopup.v = false end
        imgui.EndPopup()
    end
end

local function showAllPopups() -- Функция отображения всех всплывающих окон
    confirmImport()
    confirmExport()
    confirmDelete()
end

local function showNotification(message, color) -- Функция уведомлений
    sampAddChatMessage(u8("[Notepad] ") .. message, color or 0x00FF00) -- Всплывающие уведомления (можно заменить на предпочитаемый метод уведомлений)
end

local function toggleWindow() -- Основные функции управления
    windowVisible.v = not windowVisible.v
end

local function initialize()
    sampRegisterChatCommand(CHAT_COMMAND, toggleWindow)
    while not isSampAvailable() do
        wait(200)
    end

    loadNotes()
    imgui.Process = false
end

local function addNote()
    local title = inputTitle.v:match("^%s*(.-)%s*$")
    local tags = inputTags.v:match("^%s*(.-)%s*$") -- Извлечение тегов
    local content = inputText.v:match("^%s*(.-)%s*$")
    if title ~= "" and content ~= "" then
        table.insert(notes, {
            title = title,
            tags = tags, -- Добавление тегов в структуру заметки
            content = content,
            createdAt = os.date("%Y-%m-%d %H:%M:%S")
        })

        inputTitle.v = ""
        inputTags.v = ""
        inputText.v = ""
        saveNotes()
        showNotification("Заметка добавлена.")
    else
        showNotification("Пожалуйста, заполните все поля.", 0xFFA500)
    end
end

local function editNote(index)
    local note = notes[index]
    if note then
        inputTitle.v = note.title
        inputTags.v = note.tags -- Восстановление тегов при редактировании
        inputText.v = note.content
        table.remove(notes, index)
        saveNotes()
        showNotification("Заметку можно отредактировать и сохранить заново.")
    end
end

local function deleteNoteFunction(index)
    if notes[index] then
        deleteNoteIndex = index
        showDeletePopup.v = true
    end
end

local function clearAllNotes()
    notes = {} -- Можно добавить подтверждение здесь, если необходимо
    saveNotes()
    showNotification("Все заметки очищены.", 0xFFA500)
end

local function requestDeleteNote(index) -- Функция для запроса удаления заметки
    deleteNoteFunction(index)
end

local function drawNotes() -- Функция рисования заметок
    imgui.Text(u8("Заметки:"))
    imgui.Separator()
    if #notes == 0 then
        imgui.Text(u8("Нет заметок для отображения."))
    else
        if imgui.BeginChild("NotesList", imgui.ImVec2(0, 200), true) then
            for i = #notes, 1, -1 do -- Итерация в обратном порядке для безопасного удаления
                local note = notes[i]
                local isMatch = searchQuery.v == "" or note.title:lower():find(searchQuery.v:lower()) or (note.tags and note.tags:lower():find(searchQuery.v:lower())) or note.content:lower():find(searchQuery.v:lower())
                if isMatch then
                    if imgui.TreeNode(u8(note.title .. "##" .. i)) then
                        if note.tags and note.tags ~= "" then
                            imgui.Text(u8("Теги: ") .. note.tags)
                        else
                            imgui.Text(u8("Теги: Отсутствуют"))
                        end

                        imgui.TextWrapped(note.content)
                        imgui.Text(u8("Создано: ") .. note.createdAt)
                        if imgui.Button(u8("Редактировать##" .. i)) then editNote(i) end
                        imgui.SameLine()
                        if imgui.Button(u8("Удалить##" .. i)) then requestDeleteNote(i) end
                        imgui.TreePop()
                    end
                end
            end

            imgui.EndChild()
        end
    end
end

local function drawFrame() -- Функция рисования основного окна
    if not windowVisible.v then return end
    local resX, resY = getScreenResolution()
    imgui.SetNextWindowPos(imgui.ImVec2(resX / 2 - 300, resY / 2 - 300), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowSize(imgui.ImVec2(600, 700), imgui.Cond.FirstUseEver)
    imgui.Begin(u8("Блокнот для Даня Модеров"), windowVisible, imgui.WindowFlags.MenuBar + imgui.WindowFlags.NoResize)
    if imgui.BeginMenuBar() then -- Панель меню
        if imgui.BeginMenu(u8("Действия")) then
            if imgui.MenuItem(u8("Очистить все заметки")) then clearAllNotes() end
            if imgui.MenuItem(u8("Импортировать заметки")) then importNotesWithPrompt() end
            if imgui.MenuItem(u8("Экспортировать заметки")) then exportNotesWithPrompt() end
            imgui.EndMenu()
        end

        imgui.EndMenuBar()
    end

    if imgui.CollapsingHeader(u8("Добавить Заметку"), imgui.TreeNodeFlags.DefaultOpen) then -- Раздел добавления заметки
        imgui.InputText(u8("Название заметки"), inputTitle, imgui.ImVec2(-1, 0))
        imgui.InputText(u8("Теги (через запятую)"), inputTags, imgui.ImVec2(-1, 0)) -- Добавление ввода тегов
        imgui.InputTextMultiline(u8("Текст заметки"), inputText, imgui.ImVec2(-1, 150))
        if imgui.Button(u8("Добавить заметку")) then addNote() end
    end

    imgui.Separator()
    if imgui.CollapsingHeader(u8("Просмотр Заметок"), imgui.TreeNodeFlags.DefaultOpen) then -- Раздел просмотра заметок
        imgui.InputText(u8("Поиск"), searchQuery, imgui.ImVec2(-1, 0))
        drawNotes()
    end

    showAllPopups() -- Обработка всех всплывающих окон
    imgui.End()
end

local function modifySearch() -- Функция модификации поиска
end

function main() -- В данном случае поиск уже включает теги, но можно расширить функциональность -- Например, добавить фильтрацию по дате или определенным тегам -- Для упрощения оставим базовый поиск
    initialize()
    while true do
        wait(0)
        imgui.Process = windowVisible.v
    end
end

function imgui.OnDrawFrame()
    drawFrame()
end

local function apply_custom_style() -- Применение пользовательского стиля
    local style = imgui.GetStyle()
    local colors = style.Colors
    local clr = imgui.Col
    local ImVec4 = imgui.ImVec4
    style.WindowRounding = 5.0 -- Стилизация окна
    style.WindowTitleAlign = imgui.ImVec2(0.5, 0.5)
    style.ChildWindowRounding = 5.0
    style.FrameRounding = 5.0 -- Стилизация фреймов
    style.ItemSpacing = imgui.ImVec2(10.0, 10.0)
    style.ScrollbarSize = 15.0
    style.ScrollbarRounding = 5.0
    style.GrabMinSize = 10.0
    style.GrabRounding = 5.0
    colors[clr.WindowBg] = ImVec4(0.1, 0.1, 0.1, 1.0) -- Цветовая схема
    colors[clr.TitleBg] = ImVec4(0.2, 0.2, 0.2, 1.0)
    colors[clr.TitleBgActive] = ImVec4(0.3, 0.3, 0.3, 1.0)
    colors[clr.TitleBgCollapsed] = ImVec4(0.15, 0.15, 0.15, 1.0)
    colors[clr.Button] = ImVec4(0.2, 0.2, 0.2, 1.0)
    colors[clr.ButtonHovered] = ImVec4(0.3, 0.3, 0.3, 1.0)
    colors[clr.ButtonActive] = ImVec4(0.4, 0.4, 0.4, 1.0)
    colors[clr.FrameBg] = ImVec4(0.2, 0.2, 0.2, 1.0)
    colors[clr.FrameBgHovered] = ImVec4(0.3, 0.3, 0.3, 1.0)
    colors[clr.FrameBgActive] = ImVec4(0.4, 0.4, 0.4, 1.0)
    colors[clr.CheckMark] = ImVec4(0.0, 0.5, 0.0, 1.0)
    colors[clr.Header] = ImVec4(0.2, 0.2, 0.2, 1.0)
    colors[clr.HeaderHovered] = ImVec4(0.3, 0.3, 0.3, 1.0)
    colors[clr.HeaderActive] = ImVec4(0.4, 0.4, 0.4, 1.0)
    colors[clr.ResizeGrip] = ImVec4(0.2, 0.2, 0.2, 1.0)
    colors[clr.ResizeGripHovered] = ImVec4(0.3, 0.3, 0.3, 1.0)
    colors[clr.ResizeGripActive] = ImVec4(0.4, 0.4, 0.4, 1.0)
    colors[clr.ScrollbarBg] = ImVec4(0.1, 0.1, 0.1, 1.0)
    colors[clr.ScrollbarGrab] = ImVec4(0.2, 0.2, 0.2, 1.0)
    colors[clr.ScrollbarGrabHovered] = ImVec4(0.3, 0.3, 0.3, 1.0)
    colors[clr.ScrollbarGrabActive] = ImVec4(0.4, 0.4, 0.4, 1.0)
end

apply_custom_style()
```
Fix errors:
[{
	"resource": "/C:/Users/Admin/Downloads/cleaned originalSA by kichiro/moonloader/notepad.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Unused variable: err",
	"startLineNumber": 64,
	"startColumn": 21,
	"endLineNumber": 64,
	"endColumn": 24
},{
	"resource": "/C:/Users/Admin/Downloads/cleaned originalSA by kichiro/moonloader/notepad.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Variable 'showNotification' shadows existing binding, defined at line 40, column 17",
	"startLineNumber": 185,
	"startColumn": 16,
	"endLineNumber": 185,
	"endColumn": 32
},{
	"resource": "/C:/Users/Admin/Downloads/cleaned originalSA by kichiro/moonloader/notepad.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Double if statement. Please combine the condition of this if statement with that of the outer if statement using `and`.",
	"startLineNumber": 265,
	"startColumn": 21,
	"endLineNumber": 278,
	"endColumn": 24
},{
	"resource": "/C:/Users/Admin/Downloads/cleaned originalSA by kichiro/moonloader/notepad.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Are you Egyptian? What's with these fucking scope pyramids!?",
	"startLineNumber": 267,
	"startColumn": 29,
	"endLineNumber": 267,
	"endColumn": 66
},{
	"resource": "/C:/Users/Admin/Downloads/cleaned originalSA by kichiro/moonloader/notepad.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Are you Egyptian? What's with these fucking scope pyramids!?",
	"startLineNumber": 269,
	"startColumn": 29,
	"endLineNumber": 269,
	"endColumn": 64
},{
	"resource": "/C:/Users/Admin/Downloads/cleaned originalSA by kichiro/moonloader/notepad.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Are you Egyptian? What's with these fucking scope pyramids!?",
	"startLineNumber": 274,
	"startColumn": 74,
	"endLineNumber": 274,
	"endColumn": 85
},{
	"resource": "/C:/Users/Admin/Downloads/cleaned originalSA by kichiro/moonloader/notepad.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Are you Egyptian? What's with these fucking scope pyramids!?",
	"startLineNumber": 276,
	"startColumn": 68,
	"endLineNumber": 276,
	"endColumn": 88
},{
	"resource": "/C:/Users/Admin/Downloads/cleaned originalSA by kichiro/moonloader/notepad.lua",
	"owner": "glua",
	"severity": 4,
	"message": "Unused variable: modifySearch",
	"startLineNumber": 321,
	"startColumn": 16,
	"endLineNumber": 321,
	"endColumn": 28
}]
Also fix the error: g.CurrentWindowStack.Size == 1