[
  {
    "path": ".gitattributes",
    "content": "*.pth filter=lfs diff=lfs merge=lfs -text\n*.exe filter=lfs diff=lfs merge=lfs -text\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]\npatreon: # Replace with a single Patreon username\nopen_collective: # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\nlfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry\npolar: # Replace with a single Polar username\nbuy_me_a_coffee: # Replace with a single Buy Me a Coffee username\nthanks_dev: # Replace with a single thanks.dev username\ncustom: ['https://afdian.com/a/WindHdie']\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\n/dist\n\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n\n#Electron-builder output\n/dist_electron\n*.pyc\nsky-music-server/.idea/\nsky-music-server/node_modules/\nsky-music-web/node_modules/\nsky-music-web/.idea/\nsky-music-server/build/\nsky-music-web/web2/\nsky-music-web/dist_electron/\nsky-music-web/backend_dist\nsky-music-web/out\ndraw-follow-window/build\ndraw-follow-window/dist\nweb2/\n**/__pycache__/**\nresources/\n*.spec\nffmpeg.exe\ntemplate-resources/systemMusic/**\n"
  },
  {
    "path": ".version",
    "content": "{\n    \"version\": \"2.6.5\",\n    \"title\": \"更新啦~新年快乐🔔\",\n    \"content\": \"🍉新版本v2.6.6\\\\n🍊更新群-1007672060\\\\n💡版本更新协助\\\\n🥝 更新日志\\\\n\\\\t⭐️ 演奏、转谱界面，已转换歌曲进行细分分类\\\\n\\\\t⭐️ 转谱添加人声分离功能\\\\n\\\\t🔧 修复同步歌单的时候带来的问题 \\\\n\\\\t (如果有需要 群里也有单独解密的软件进行下载)\",\n    \"downloadUrl\": \"https://github.com/windhide/SkyMusicPlay-for-Windows/releases/download/v2.6.6/v2.6.6_x64_windows.exe\",\n    \"positiveText\": \"新年快乐🎇\",\n    \"negativeText\": \"朕知道了，退下吧。🥲\"\n}"
  },
  {
    "path": "README.md",
    "content": "﻿# SkyMusicPlay-for-Windows\r\n\r\n<p align=\"center\">\r\n  <a href=\"https://github.com/windhide/SkyMusicPlay-for-Windows\"><img src=\"https://files.superbed.cc/store/images/7e/7a/67bfcd95d0e0a243d4067e7a.png\" width=\"256\" height=\"256\" alt=\"SkyMusicPlay-for-Windows\"></a>\r\n<h1 align = \"center\">星星弹琴软件</h1>\r\n<div align = \"center\">\r\n        <a href=\"https://www.kdocs.cn/l/cpTkEdhxIRob\" target=\"_blank\">教程文档</a> &nbsp; · &nbsp;\r\n        <a href=\"https://github.com/windhide/SkyMusicPlay-for-Windows/releases\">点我下载</a>\r\n</div>\r\n\r\n## 丨安装提醒\r\n>\r\n> **安装请`关闭杀毒软件`进行**\r\n>\r\n> 支持PC端，也支持模拟器端\r\n>\r\n> 🚧目前还在施工中，功能快速迭代中...🚧\r\n>\r\n>\r\n> ✨如果需要相关创意功能欢迎在issues中提出✨\r\n>\r\n</details>\r\n\r\n\r\n## 丨项目开发环境\r\n\r\n- **Python**：3.11\r\n- **Node**：16.20.2\r\n\r\n## 丨技术栈\r\n\r\n- **Electron**\r\n- **TypeScript**\r\n- **Vite**\r\n- **Naive-UI**\r\n- **Python**\r\n- **YOLO**\r\n- **WebSocket**\r\n\r\n## 丨其他\r\n-  项目引用或代码引用请注明原作者出处，禁止商业用途\r\n-  [Creative Commons Attribution-NonCommercial (CC BY-NC) 许可协议](https://creativecommons.org/licenses/by-nc/4.0/deed.zh-hans)\r\n\r\n\r\n## 丨联系方式\r\n- 如有任何问题或建议，欢迎通过以下方式与我联系：\r\n- [Email](mailto:WindHide520@gmail.com)\r\n- [GitHub](https://github.com/windhide)\r\n\r\n## 致谢\r\n- [pianotrans](https://github.com/azuwis/pianotrans) 音乐转钢琴谱\r\n- [basic-pitch](https://github.com/spotify/) 音乐转MIDI\r\n\r\n"
  },
  {
    "path": "buildProject.ps1",
    "content": "# =========================\n# 自动管理员提权\n# =========================\n$principal = New-Object Security.Principal.WindowsPrincipal(\n    [Security.Principal.WindowsIdentity]::GetCurrent()\n)\n\nif (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {\n    Write-Host \"This script requires administrator privileges.\"\n    Write-Host \"Attempting to restart with administrator rights...\"\n\n    Start-Process powershell `\n        -Verb RunAs `\n        -ArgumentList \"-NoExit -ExecutionPolicy Bypass -File `\"$PSCommandPath`\"\"\n\n    exit\n}\n\n# =========================\n# 脚本所在目录\n# =========================\n$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition\nSet-Location $ScriptDir\n\nWrite-Host \"Current script directory: $ScriptDir\"\n\n# =========================\n# 删除旧构建目录\n# =========================\n$pathsToRemove = @(\n    \"$ScriptDir\\sky-music-web\\dist\",\n    \"$ScriptDir\\sky-music-server\\build\",\n    \"$ScriptDir\\sky-music-web\\backend_dist\"\n)\n\nforeach ($path in $pathsToRemove) {\n    if (Test-Path $path) {\n        Write-Host \"Removing: $path\"\n        Remove-Item -Recurse -Force -Path $path\n    }\n}\n\n# =========================\n# 构建 Python 服务器\n# =========================\nWrite-Host \"`n=== Building Python Server ===\"\n\nSet-Location \"$ScriptDir\\sky-music-server\"\n\n& \".\\.venv\\Scripts\\python.exe\" -m PyInstaller `\n    -i icon.ico `\n    sky_music_server.py `\n    --distpath \"$ScriptDir\\sky-music-web\\backend_dist\" `\n    --version-file \"$ScriptDir\\sky-music-server\\version.txt\" `\n    --hidden-import main `\n    --collect-all sklearn `\n    --collect-all basic_pitch `\n    --collect-all plyer `\n\t--collect-all torch `\n\t--collect-all torchvision `\n\t--hidden-import=torch `\n\t--hidden-import demucs `\n\t--collect-all demucs `\n\t--hidden-import=torchvision `\n    --uac-admin\n\nif ($LASTEXITCODE -ne 0) {\n    Write-Error \"PyInstaller build failed.\"\n    exit 1\n}\n\n# =========================\n# 复制 ffmpeg.exe\n# =========================\nWrite-Host \"`nCopying ffmpeg.exe\"\n\n$ffmpegSrc = \"$ScriptDir\\ffmpeg.exe\"\n$ffmpegDst = \"$ScriptDir\\sky-music-web\\backend_dist\\sky_music_server\\ffmpeg.exe\"\n\nif (Test-Path $ffmpegSrc) {\n    Copy-Item $ffmpegSrc $ffmpegDst -Force\n} else {\n    Write-Warning \"ffmpeg.exe not found: $ffmpegSrc\"\n}\n\n# =========================\n# 构建 Electron 应用\n# =========================\nWrite-Host \"`n=== Building Electron App ===\"\n\nSet-Location \"$ScriptDir\\sky-music-web\"\n\n& npm run build:win\n\nif ($LASTEXITCODE -ne 0) {\n    Write-Error \"Electron build failed.\"\n    exit 1\n}\n\n# =========================\n# 完成提示\n# =========================\nWrite-Host \"`nAll tasks completed successfully!\"\nPause\n"
  },
  {
    "path": "draw-follow-window/README.md",
    "content": "```shell\n  pyinstaller --onefile --noconsole --clean --strip --name draw_server draw_server.py\n\n```\n\n```shell\n  draw_server.exe --width 1024 --height 768 --x 200 --y 300\n```\n\n"
  },
  {
    "path": "draw-follow-window/draw_server.py",
    "content": "import tkinter as tk\nimport socket\nimport threading\nimport sys\nimport argparse\nimport os\n\n# 针对 Windows 系统设置 DPI Awareness（适用于 Windows 8.1 及以上）\nif os.name == \"nt\":\n    try:\n        from ctypes import windll\n\n        windll.shcore.SetProcessDpiAwareness(1)\n    except Exception as e:\n        print(\"无法设置 DPI Awareness，可能影响窗口几何尺寸的准确性。\")\n\n\n# 绘制和删除方框的 API\ndef draw_box_api(canvas, width, height, position_x, position_y, box_id=None):\n    # 在 Canvas 上绘制一个指定大小和位置的方框\n    if box_id is not None:\n        # 重用已有的方框对象\n        canvas.coords(box_id,\n            position_x, position_y,\n            position_x + width, position_y + height)\n        return box_id\n    else:\n        # 创建新的方框对象\n        return canvas.create_rectangle(\n            position_x, position_y,\n            position_x + width, position_y + height,\n            outline=\"#00ffff\", width=3\n        )\n\n\ndef delete_box_api(canvas, box_id, box_pool=None):\n    # 从 Canvas 上删除指定 ID 的方框\n    if box_pool is not None and len(box_pool) < 100:\n        # 将方框对象添加到对象池中\n        canvas.itemconfig(box_id, state='hidden')\n        box_pool.append(box_id)\n    else:\n        # 对象池已满或未使用对象池，直接删除\n        canvas.delete(box_id)\n\n# 主窗口类\nclass TransparentBoxWindow:\n    def __init__(self, root, width, height, position_x, position_y):\n        self.root = root\n        self.port = 12345  # 固定端口\n\n        # 设置 Canvas\n        self.canvas = tk.Canvas(root, width=width, height=height, bg=\"white\", highlightthickness=0)\n        self.canvas.pack()\n\n        # 绘制红色边框\n        # self.draw_red_border(width, height)\n\n        # 存储用户自定义 ID 与 Tkinter 方框 ID 的映射\n        self.boxes = {}\n        # 对象池 - 存储可重用的方框对象\n        self.box_pool = []\n        self.max_pool_size = 100  # 对象池最大容量\n\n        # 启动 Socket 服务器\n        threading.Thread(target=self.start_server, daemon=True).start()\n\n    def draw_red_border(self, width, height, border_thickness=10):\n        \"\"\"在 Canvas 上绘制一个红色的边框\"\"\"\n        self.canvas.create_rectangle(\n            border_thickness // 2, border_thickness // 2,\n            width - border_thickness // 2, height - border_thickness // 2,\n            outline=\"red\", width=border_thickness, tags=\"red_border\"\n        )\n\n    def start_server(self):\n        # 创建 Socket 服务器\n        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        server.bind((\"localhost\", self.port))\n        server.listen(5)\n        print(f\"服务器已启动，监听端口：{self.port}，等待连接...\")\n\n        while True:\n            client, addr = server.accept()\n            print(f\"收到连接来自 {addr}\")\n            threading.Thread(target=self.handle_client, args=(client,), daemon=True).start()\n\n    def handle_client(self, client):\n        try:\n            buffer = \"\"\n            command_batch = []\n            while True:\n                data = client.recv(1024).decode(\"utf-8\")\n                if not data:\n                    break\n                buffer += data\n                # 按换行符分割命令\n                commands = buffer.split(\"\\n\")\n                # 收集完整命令到批处理列表\n                for command in commands[:-1]:\n                    print(f\"收到命令: {command}\")\n                    command_batch.append(command)\n                    # 当积累了足够的命令或遇到特殊命令时执行批处理\n                    if len(command_batch) >= 30 or any(cmd.startswith((\"resize\", \"exit\", \"update\")) for cmd in command_batch):\n                        self.process_command_batch(command_batch)\n                        command_batch = []\n                # 将最后一个不完整的命令保留到下一次处理\n                buffer = commands[-1]\n            # 处理剩余的命令\n            if command_batch:\n                self.process_command_batch(command_batch)\n        except ConnectionResetError:\n            print(\"客户端断开连接\")\n        finally:\n            client.close()\n\n    def process_command_batch(self, commands):\n        # 创建命令分类字典\n        command_groups = {\n            \"draw\": [],\n            \"delete\": [],\n            \"update\": None,\n            \"resize\": None,\n            \"exit\": False\n        }\n        \n        # 对命令进行分类\n        for command in commands:\n            parts = command.split()\n            cmd_type = parts[0]\n            \n            if cmd_type == \"draw\":\n                command_groups[\"draw\"].append({\n                    \"id\": parts[1],\n                    \"width\": int(parts[2]),\n                    \"height\": int(parts[3]),\n                    \"x\": int(parts[4]),\n                    \"y\": int(parts[5])\n                })\n            elif cmd_type == \"delete\":\n                command_groups[\"delete\"].append(parts[1])\n            elif cmd_type == \"update\":\n                # 将update命令作为触发批处理的信号\n                command_groups[\"update\"] = True\n            elif cmd_type == \"resize\":\n                command_groups[\"resize\"] = {\n                    \"width\": int(parts[1]),\n                    \"height\": int(parts[2]),\n                    \"x\": int(parts[3]),\n                    \"y\": int(parts[4])\n                }\n            elif cmd_type == \"exit\":\n                command_groups[\"exit\"] = True\n        \n        # 批量处理删除命令\n        for box_id in command_groups[\"delete\"]:\n            if box_id in self.boxes:\n                tkinter_id = self.boxes[box_id]\n                delete_box_api(self.canvas, tkinter_id, self.box_pool)\n                del self.boxes[box_id]\n        \n        # 批量处理绘制命令\n        for box in command_groups[\"draw\"]:\n            if box[\"id\"] not in self.boxes:\n                # 尝试从对象池中获取方框对象\n                reused_box_id = None\n                if self.box_pool:\n                    reused_box_id = self.box_pool.pop()\n                    self.canvas.itemconfig(reused_box_id, state='normal')\n                \n                tkinter_id = draw_box_api(\n                    self.canvas,\n                    box[\"width\"],\n                    box[\"height\"],\n                    box[\"x\"],\n                    box[\"y\"],\n                    reused_box_id\n                )\n                self.boxes[box[\"id\"]] = tkinter_id\n        \n        # 处理调整窗口大小命令\n        if command_groups[\"resize\"]:\n            resize = command_groups[\"resize\"]\n            self.change_window_geometry(\n                resize[\"width\"],\n                resize[\"height\"],\n                resize[\"x\"],\n                resize[\"y\"]\n            )\n        \n        # 处理退出命令\n        if command_groups[\"exit\"]:\n            print(\"接收到退出指令，正在退出程序...\")\n            self.exit_program()\n        \n        # 更新Canvas\n        self.root.update_idletasks()\n\n    def change_window_geometry(self, width, height, position_x, position_y):\n        print(f\"更改窗口尺寸和位置为：{width}x{height}, 坐标: ({position_x}, {position_y})\")\n\n        # 隐藏所有方框而不是删除它们\n        for tkinter_id in self.boxes.values():\n            self.canvas.itemconfig(tkinter_id, state='hidden')\n            if len(self.box_pool) < self.max_pool_size:\n                self.box_pool.append(tkinter_id)\n        self.boxes.clear()\n\n        # 修改窗口和Canvas大小\n        self.root.geometry(f\"{width}x{height}+{position_x}+{position_y}\")\n        self.canvas.config(width=width, height=height)\n\n        # 一次性更新UI\n        self.root.update_idletasks()\n\n        # 输出调整后的实际窗口大小\n        actual_width = self.root.winfo_width()\n        actual_height = self.root.winfo_height()\n        print(f\"调整后实际窗口尺寸: {actual_width}x{actual_height}\")\n\n        # 输出调整后的实际窗口大小\n        actual_width = self.root.winfo_width()\n        actual_height = self.root.winfo_height()\n        print(f\"调整后实际窗口尺寸: {actual_width}x{actual_height}\")\n\n    def exit_program(self):\n        self.root.destroy()\n        sys.exit(0)\n\n\nif __name__ == \"__main__\":\n    # 解析命令行参数\n    parser = argparse.ArgumentParser(description=\"Transparent Box GUI\")\n    parser.add_argument(\"--width\", type=int, default=800, help=\"Window width\")  # 窗口宽度\n    parser.add_argument(\"--height\", type=int, default=600, help=\"Window height\")  # 窗口高度\n    parser.add_argument(\"--x\", type=int, default=100, help=\"Window position X\")  # 窗口 X 坐标\n    parser.add_argument(\"--y\", type=int, default=100, help=\"Window position Y\")  # 窗口 Y 坐标\n    args = parser.parse_args()\n\n    width = args.width\n    height = args.height\n    x = args.x\n    y = args.y\n\n    root = tk.Tk()\n    # 尽管已在 Windows 下尝试设置 DPI Awareness，仍保持 scaling 为 1.0\n    root.tk.call('tk', 'scaling', 1.0)\n    # 先设置 geometry，再调用 update_idletasks 确保尺寸生效\n    root.geometry(f\"{width}x{height}+{x}+{y}\")\n    root.update_idletasks()\n\n    root.overrideredirect(True)\n    root.attributes(\"-transparentcolor\", \"white\")\n    root.attributes(\"-topmost\", True)\n\n    app = TransparentBoxWindow(root, width, height, x, y)\n    root.mainloop()\n"
  },
  {
    "path": "draw-follow-window/draw_socket_demo.py",
    "content": "import socket\nimport time\n\nclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nclient.connect((\"localhost\", 12345))  # 连接到服务器\n\n\ndef send_command(command):\n    try:\n        client.sendall(command.encode(\"utf-8\"))  # 发送命令\n        print(f\"发送命令: {command}\")\n    except ConnectionRefusedError:\n        print(\"无法连接到服务器，请确保服务端已启动。\")\n\n\n# 示例指令序列\nsend_command(\"draw box1 100 50 200 200\\n\")  # 绘制第一个方框\ntime.sleep(1)  # 等待 1 秒\nsend_command(\"draw box2 150 100 300 300\\n\")  # 绘制第二个方框\ntime.sleep(1)  # 等待 1 秒\n\n# 调整窗口尺寸和位置，同时清空所有已绘制的方框\nsend_command(\"resize 2560 1080 50 10\\n\")  # 更改窗口为 1000x800 大小，位置 (50, 50)\n# time.sleep(2)  # 等待 2 秒\n\nsend_command(\"draw box2 150 100 1000 1000\\n\")  # 绘制第二个方框\ntime.sleep(1)  # 等待 1 秒\n# 再次绘制新的方框\nsend_command(\"draw box3 120 80 400 100\\n\")  # 绘制第三个方框\ntime.sleep(1)  # 等待 1 秒\nsend_command(\"draw box4 200 150 500 400\\n\")  # 绘制第四个方框\ntime.sleep(2)  # 等待 2 秒\n\n# 删除某些方框\nsend_command(\"delete box3\\n\")  # 删除第三个方框\ntime.sleep(2)  # 等待 2 秒\nsend_command(\"delete box4\\n\")  # 删除第四个方框\ntime.sleep(2)  # 等待 2 秒\n\nsend_command(\"update\\n\")  # 删除第四个方框\ntime.sleep(2)  # 等待 2 秒\n# 添加退出指令\nsend_command(\"exit \\n\")  # 发送退出指令到服务器\nprint(\"发送退出指令，客户端结束运行。\")\n"
  },
  {
    "path": "sky-music-server/README.md",
    "content": "打包指令\n```shell\n# 有命令调试打包\npyinstaller --uac-admin sky_music_server.py -i icon.ico --upx-dir D:\\Desktop\\upx-4.2.2-win64\\ --distpath D:\\Desktop\\SkyMusicPlay-for-Windows\\sky-music-web\\dist\\win-unpacked\\backend_dist --hidden-import=main --collect-all=sklearn --collect-all=basic_pitch\n# 无命令调试打包\npyinstaller --uac-admin -w sky_music_server.py -i icon.ico --upx-dir D:\\Desktop\\upx-4.2.2-win64\\ --distpath D:\\Desktop\\SkyMusicPlay-for-Windows\\sky-music-web\\dist\\win-unpacked\\backend_dist --hidden-import=main --collect-all=sklearn --collect-all=basic_pitch\n```\n> ffmpeg.exe 放在和 sky_windows_music.exe平级"
  },
  {
    "path": "sky-music-server/music_compare_repeat.py",
    "content": "import difflib\nimport hashlib\nimport os\nimport shutil\nfrom collections import defaultdict\n\n\ndef get_file_hash(file_path, block_size=65536):\n    \"\"\"计算文件的 SHA-256 哈希值\"\"\"\n    hasher = hashlib.sha256()\n    with open(file_path, 'rb') as f:\n        while chunk := f.read(block_size):\n            hasher.update(chunk)\n    return hasher.hexdigest()\n\n\ndef get_file_similarity(file1, file2):\n    \"\"\"计算两个文件的内容相似度\"\"\"\n    with open(file1, 'r', errors='ignore') as f1, open(file2, 'r', errors='ignore') as f2:\n        text1 = f1.readlines()\n        text2 = f2.readlines()\n    return difflib.SequenceMatcher(None, text1, text2).ratio()\n\n\ndef find_similar_files(input_folder, threshold=0.8):\n    \"\"\"查找相似文件并标记需要删除的文件\"\"\"\n    files = [os.path.join(input_folder, f) for f in os.listdir(input_folder) if\n             os.path.isfile(os.path.join(input_folder, f))]\n\n    # 用哈希分组\n    hash_groups = defaultdict(list)\n\n    for file in files:\n        file_hash = get_file_hash(file)\n        hash_groups[file_hash].append(file)\n\n    to_delete = set()\n    checked_pairs = set()\n\n    for group in hash_groups.values():\n        # 如果 MD5 相同的文件超过 1 个，则这些都属于重复文件\n        if len(group) > 1:\n            # 保留最大（或最老）的一个，其余删除\n            group_sorted = sorted(group, key=lambda f: os.path.getsize(f), reverse=True)\n            keep = group_sorted[0]\n            duplicates = group_sorted[1:]\n            to_delete.update(duplicates)\n            continue\n\n        # 其它情况下才继续相似度比对（不同 hash）\n        for i, file1 in enumerate(group):\n            for file2 in group[i + 1:]:\n                if (file1, file2) in checked_pairs:\n                    continue\n                checked_pairs.add((file1, file2))\n\n                similarity = get_file_similarity(file1, file2)\n\n                if similarity >= threshold:\n                    smaller_file = min(file1, file2, key=lambda f: os.path.getsize(f))\n                    to_delete.add(smaller_file)\n\n    return to_delete\n\n\ndef process_files(input_folder, output_folder, threshold=0.8):\n    \"\"\"处理文件夹，删除重复文件并移动剩余文件\"\"\"\n    if not os.path.exists(output_folder):\n        os.makedirs(output_folder)\n\n    to_delete = find_similar_files(input_folder, threshold)\n\n    # 删除重复文件\n    deleted_files = list(to_delete)\n    for file in to_delete:\n        os.remove(file)\n\n    # 移动剩余文件\n    for file in os.listdir(input_folder):\n        full_path = os.path.join(input_folder, file)\n        if os.path.isfile(full_path):\n            shutil.move(full_path, os.path.join(output_folder, file))\n\n    print(f\"删除了 {len(deleted_files)} 个文件：\")\n    for file in deleted_files:\n        print(file)\n\n\nif __name__ == \"__main__\":\n    input_folder = r\"D:\\Desktop\\处理好的\"  # 输入文件夹路径\n    output_folder = r\"D:\\Desktop\\二次处理的\"  # 处理后正常输出路径\n    process_files(input_folder, output_folder)\n"
  },
  {
    "path": "sky-music-server/music_file_process.py",
    "content": "import json\nimport os\nimport re\nimport shutil  # 用于移动文件\nfrom concurrent.futures import ThreadPoolExecutor\n\nimport chardet  # 用于检测文件编码\n\n\ndef sanitize_filename(name):\n    \"\"\"清理文件名中的非法字符\"\"\"\n    return re.sub(r'[<>:\"/\\\\\\\\|?*]', '_', name)\n\n\ndef process_file(file_path, normal_output_folder, encrypted_folder, keyword=\"1Key\"):\n    try:\n        # 自动检测文件编码\n        with open(file_path, 'rb') as file:\n            raw_data = file.read()\n            detected = chardet.detect(raw_data)\n            encoding = detected.get('encoding', 'utf-8') or 'utf-8'  # 避免 None\n\n        # 用检测到的编码读取文件\n        with open(file_path, 'r', encoding=encoding) as file:\n            content = file.read()\n\n        # 解析 JSON\n        try:\n            json_data = json.loads(content)\n        except json.JSONDecodeError as e:\n            print(f\"❌ 解析 JSON 失败: {file_path}, 错误: {e}\")\n            return\n\n        # 确保 JSON 是列表并且不为空\n        if not isinstance(json_data, list) or len(json_data) == 0:\n            print(f\"❌ 无效的 JSON 结构: {file_path}\")\n            return\n\n        # **检查是否包含关键词 \"1Key\"**\n        if keyword in content:\n            first_name = json_data[0].get('name', '未命名文件')\n            sanitized_name = sanitize_filename(first_name)\n            new_file_name = f\"{sanitized_name}.txt\"\n            new_file_path = os.path.join(normal_output_folder, new_file_name)\n\n            # 避免文件名冲突\n            counter = 1\n            while os.path.exists(new_file_path):\n                new_file_name = f\"{sanitized_name}_{counter}.txt\"\n                new_file_path = os.path.join(normal_output_folder, new_file_name)\n                counter += 1\n\n            # **将内容转换为 UTF-8 并保存**\n            with open(new_file_path, 'w', encoding='utf-8') as new_file:\n                new_file.write(content)\n\n            print(f\"✅ 文件 {os.path.basename(file_path)} 已重命名并保存到 {normal_output_folder}\")\n            return\n\n        # **检查是否包含 isEncrypted: true**\n        for item in json_data:\n            if isinstance(item, dict) and item.get(\"isEncrypted\") is True:\n                # **直接移动文件到加密文件夹**\n                shutil.move(file_path, os.path.join(encrypted_folder, os.path.basename(file_path)))\n                print(f\"✅ 文件 {os.path.basename(file_path)} 已移动到 {encrypted_folder}\")\n                return\n\n        # **如果既不是加密文件，也不包含关键词 \"1Key\"，则跳过**\n        print(f\"⚠️ 文件 {os.path.basename(file_path)} 不包含 'isEncrypted': true 或 '{keyword}'，跳过处理\")\n\n    except (KeyError, IOError, UnicodeDecodeError) as e:\n        print(f\"❌ 处理文件 {os.path.basename(file_path)} 时出错: {e}\")\n\n\ndef process_files(input_folder, normal_output_folder, encrypted_folder, keyword=\"1Key\"):\n    # **确保目标文件夹存在**\n    os.makedirs(normal_output_folder, exist_ok=True)\n    os.makedirs(encrypted_folder, exist_ok=True)\n\n    # **使用线程池并行处理文件**\n    with ThreadPoolExecutor() as executor:\n        for root, _, files in os.walk(input_folder):\n            for file_name in files:\n                file_path = os.path.join(root, file_name)\n                executor.submit(process_file, file_path, normal_output_folder, encrypted_folder, keyword)\n\n    print(\"✅ 所有文件处理完成。\")\n\n\nif __name__ == '__main__':\n    # **文件夹路径**\n    input_folder = r\"D:\\SoftWareStorage\\Tencent Download\\额外的谱子_倒卖死妈_一辈子都是垃圾\"  # 输入文件夹路径\n    normal_output_folder = r\"D:\\Desktop\\处理好的\"  # 处理后正常输出路径\n    encrypted_folder = r\"D:\\Desktop\\加密的\"  # 加密文件存放路径\n\n    process_files(input_folder, normal_output_folder, encrypted_folder)\n"
  },
  {
    "path": "sky-music-server/music_translate.py",
    "content": "import os\n\nfrom basic_pitch import ICASSP_2022_MODEL_PATH\nfrom basic_pitch.inference import predict_and_save\n\nif __name__ == '__main__':\n    # 定义输入文件和输出路径\n    desktop_path = os.path.join(os.path.expanduser(\"~\"), \"Desktop\")  # 获取桌面路径\n    output_midi_path = \"D:\\\\Desktop\"\n    try:\n        predict_and_save(\n            [\n                r\"D:\\Desktop\\孙燕姿 - 第一天.mp3\"\n            ],\n            output_midi_path,\n            True,\n            False,\n            False,\n            False,\n            ICASSP_2022_MODEL_PATH\n        )\n    except Exception as e:\n        print(f\"处理失败：{e}\")\n"
  },
  {
    "path": "sky-music-server/requirements.txt",
    "content": "plyer==2.1.0\npynput==1.7.7\ncharset-normalizer==3.4.1\nchardet==5.2.0\nultralytics==8.3.61\nopencv-python==4.10.0.84\nnumpy==1.23.5\nPyAutoGUI==0.9.54\nscikit-learn==1.5.1\npsutil==6.1.1\nkeyboard==0.13.5\nJinja2==3.1.6\nplatformdirs==4.3.6\nrequests==2.32.3\nuvicorn==0.34.0\nfastapi==0.115.6\ntorch==2.5.1\nmatplotlib==3.10.0\ntorchlibrosa==0.1.0\nlibrosa==0.10.2.post1\naudioread==3.0.1\nmido==1.3.3\npretty_midi\npywin32\npython-multipart\npyinstaller\nwebsocket_server\nbasic_pitch\ncoremltools\nscikit-learn==1.5.1\nprotobuf==4.25.6\nopenai==1.85.0\ndemucs==4.0.1"
  },
  {
    "path": "sky-music-server/sky_music_apis.py",
    "content": "import json\nimport os\nimport time\nimport webbrowser\n\nimport psutil\nimport requests\nfrom fastapi import FastAPI, UploadFile\nfrom fastapi.middleware.cors import CORSMiddleware\n\nfrom windhide.musicToSheet.aigc_handler_sheet import general_ai\nfrom windhide.playRobot import amd_robot, intel_robot\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils.auto_util import auto_click_fire, shutdown\nfrom windhide.utils.config_util import set_config, get_config, favorite_music, convert_sheet, drop_file\nfrom windhide.utils.hwnd_utils import get_running_apps, get_running_apps_by_struct\nfrom windhide.utils.ocr_follow_util import set_next_sheet, get_key_position, test_key_model_position, \\\n    open_follow\nfrom windhide.utils.ocr_heart_utils import get_friend_model_position\nfrom windhide.utils.path_util import getTypeMusicList, getResourcesPath, process_sheet_rename_time\nfrom windhide.utils.play_util import start, pause, resume, stop\nfrom windhide.utils.sheet_decrypt_util import decrypt_sheet\n\n# 避开与光遇相同核心运行\nprocess = psutil.Process(os.getpid())\nall_cores = list(range(psutil.cpu_count()))\ncores_to_use = [core for core in all_cores if core != 0]\nprocess.cpu_affinity(cores_to_use)\n\napp = FastAPI()\napp.add_middleware(\n    CORSMiddleware,\n    allow_origins=[\"*\"],  # 允许的源，可根据需求设置特定地址或使用 [\"*\"] 允许所有\n    allow_credentials=True,  # 允许携带认证信息（如 Cookies）\n    allow_methods=[\"*\"],  # 允许的 HTTP 方法（如 GET、POST）\n    allow_headers=[\"*\"],  # 允许的 HTTP 请求头\n)\n\nasync def get_list(listName: str, searchStr: str):\n    return getTypeMusicList(listName, searchStr)\n\ndef play_operate(request: dict):\n    match request[\"operate\"]:\n        case 'start':\n            start(request)\n        case 'pause':\n            pause()\n        case 'resume':\n            resume()\n        case 'stop':\n            stop()\n\ndef get_progress():\n    return {\n        \"overall_progress\": f\"{GlobalVariable.overall_progress:.1f}\",\n        \"now_progress\": f\"{GlobalVariable.now_progress:.1f}\",\n        \"now_translate_text\": GlobalVariable.now_translate_text,\n        \"now_play_music\": GlobalVariable.now_play_music,\n        \"now_total_time\": GlobalVariable.now_total_time,\n        \"now_current_time\": GlobalVariable.now_current_time\n    }\n\nasync def create_upload_files(file: UploadFile):\n    path = os.path.join(getResourcesPath(\"translateOriginalMusic\"), f'{file.filename}')\n    with open(path, 'wb') as f:\n        for chunk in iter(lambda: file.file.read(1024), b''):\n            f.write(chunk)\n    return \"ok\"\n\nasync def create_upload_files_user(file: UploadFile):\n    # 读取文件内容\n    file_content = await file.read()\n    import chardet\n    detected = chardet.detect(file_content)\n    encoding = detected.get('encoding', 'utf-8')\n    text_content = file_content.decode(encoding)\n    data = json.loads(text_content)\n\n    is_encrypted = data[0].get(\"isEncrypted\", False)\n    if  is_encrypted:\n        print(\"解密触发\")\n        data = decrypt_sheet(data)\n\n    # 提取 songNotes 并计算时间戳\n    song_notes = data[0].get(\"songNotes\", [])\n    if not song_notes:\n        raise ValueError(\"No songNotes found in the file\")\n\n    sum_time = int(song_notes[-1][\"time\"]) + int(song_notes[-1].get(\"duration\", 0))\n\n    # 生成新的文件名\n    name, ext = os.path.splitext(file.filename)\n    new_filename = f\"{name}-#{sum_time}{ext}\"\n    path = os.path.join(getResourcesPath(\"myImport\"), new_filename)\n\n    # 保存文件\n    with open(path, 'wb') as f:\n        f.write(json.dumps(data).encode())\n    return \"ok\"\n\ndef translate(request: dict):\n    from windhide.musicToSheet.process_audio import process_directory_with_progress\n    match request[\"operate\"]:\n        case 'translate':\n            process_directory_with_progress(request[\"value\"])\n    process_sheet_rename_time(isImportOrTranslate=True)\n    return \"ok\"\n\ndef config_operate(request: dict):\n    match request[\"operate\"]:\n        case 'set':\n            set_config(request)\n        case 'get':\n            return get_config(request)\n        case 'favorite_music':\n            favorite_music(request)\n        case 'convert_sheet':\n            return convert_sheet(request)\n        case 'drop_file':\n            drop_file(request)\n        case 'get_key_position':\n            return get_key_position(float(request[\"conf\"]))\n        case 'cpu_type':\n            return True if GlobalVariable.cpu_type == \"AMD\" else False\n        case 'hwnd_get':\n            return  get_running_apps()\n        case 'hwnd_get_now':\n            if GlobalVariable.window[\"hWnd\"] is None:\n                return \"Nothing\"\n            else:\n                return GlobalVariable.hwnd_title\n        case 'hwnd_set':\n            if request[\"value\"] == 'reset':\n                GlobalVariable.is_custom_hwnd = False\n            else:\n                return get_running_apps_by_struct(request[\"value\"])\n    return \"ok\"\n\ndef follow(request: dict):\n    match request[\"operate\"]:\n        case 'setSheet':\n            set_next_sheet(request)\n        case 'openFollow':\n            open_follow()\n\ndef check():\n    return 'True'\n\ndef open_browser(url: str):\n    webbrowser.open(url)\n    return 'ok'\n\ndef open_files(request: dict):\n    match request[\"operate\"]:\n        case 'images':\n            appdata_path = os.getenv('APPDATA')\n            os.startfile(os.path.join(appdata_path, 'ThatGameCompany', 'com.netease.sky', 'images'))\n        case 'files':\n            os.startfile(os.path.join(getResourcesPath(None), request[\"type\"]))\n\ndef get_update():\n   response = requests.get('https://gitee.com/WindHide/SkyMusicPlay-for-Windows/raw/main/.version')\n   if response.status_code == 200:\n       return json.loads(response.text)\n   return \"404\"\n\n#  下面放识别相关的调用\ndef auto(request: dict):\n    match request[\"operate\"]:\n        case 'click_fire':\n            auto_click_fire()\n        case 'shutdown':\n            shutdown()\n\ndef get_path(request: dict):\n    return getResourcesPath(request[\"type\"])\n\ndef test(request: dict):\n    match request[\"operate\"]:\n        case 'image':\n            return get_friend_model_position(float(request[\"conf\"]), isTest=True)\n        case 'key':\n            test_key_model_position(float(request[\"conf\"]))\n            return None\n        case 'press':\n            match GlobalVariable.cpu_type:\n                case 'Intel':\n                    intel_robot.key_down(request[\"key\"])\n                    time.sleep(0.01)\n                    intel_robot.key_up(request[\"key\"])\n                    return None\n                case 'AMD':\n                    amd_robot.key_down(request[\"key\"])\n                    time.sleep(0.01)\n                    amd_robot.key_up(request[\"key\"])\n                    return None\n            return None\n    return None\n\n\ndef aigc(request: dict):\n    print(f\"okay now is running aigc {request['ai']}\")\n    # if request[\"ai\"] == \"Gemini\":\n    #     return gemini_ai(model=request[\"model\"],filename=request[\"filename\"],type_=request[\"type\"])\n    # else:\n    return general_ai(model=request[\"model\"],filename=request[\"filename\"],type_=request[\"type\"], platform=request[\"ai\"])\n\ndef register_routes(app: FastAPI):\n    app.get(\"/\")(get_list)\n    app.get(\"/check\")(check)\n    app.get(\"/update\")(get_update)\n    app.get(\"/getProgress\")(get_progress)\n    app.get(\"/openBrowser\")(open_browser)\n    app.get(\"/syncSheetName\")(process_sheet_rename_time)\n    app.post(\"/play_operate\")(play_operate)\n    app.post(\"/userMusicUpload\")(create_upload_files_user)\n    app.post(\"/config_operate\")(config_operate)\n    app.post(\"/fileUpload\")(create_upload_files)\n    app.post(\"/openFiles\")(open_files)\n    app.post(\"/translate\")(translate)\n    app.post(\"/follow\")(follow)\n    app.post(\"/auto\")(auto)\n    app.post(\"/aigc\")(aigc)\n    app.post(\"/path\")(get_path)\n    app.post(\"/test\")(test)\n"
  },
  {
    "path": "sky-music-server/sky_music_server.py",
    "content": "import logging\nimport os\nimport queue\nfrom contextlib import asynccontextmanager\n\nimport sys\nimport threading\nimport psutil\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\nfrom sky_music_apis import register_routes\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.thread.frame_alive_thread import monitor_process\nfrom windhide.thread.hwnd_check_thread import start_thread as hwnd_check_thread\nfrom windhide.thread.queue_thread import music_start_tasks\nfrom windhide.thread.shortcut_thread import startThread as shortcut_thread\nos.environ[\"TORCHAUDIO_USE_TORCHCODEC\"] = \"0\"\n# 设置 CPU 亲和性，避开与光遇相同核心运行\nprocess = psutil.Process(os.getpid())\nall_cores = list(range(psutil.cpu_count()))\n# 避开光遇核心（假设是 0）和系统核心（可选避开 1）\navailable_cores = [core for core in all_cores if core not in [0, 1]]\n# 选择前两个空闲核心\ncores_to_use = available_cores[:2]\nprocess.cpu_affinity(cores_to_use)\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    # 检查是否为生产模式\n    if \"--prod\" in sys.argv:\n        GlobalVariable.isProd = True\n    else:\n        GlobalVariable.isProd = False\n        print(\"当前为开发模式\")\n\n    # 启动快捷键监听线程\n    shortcut_websocket_thread = threading.Thread(target=shortcut_thread, daemon=True)\n    shortcut_websocket_thread.start()\n\n    # 启动目标进程监控线程（仅在生产模式下）\n    if GlobalVariable.isProd:\n        target_process = \"Sky_Music.exe\"\n        process_monitor_thread = threading.Thread(target=monitor_process, args=(target_process,), daemon=True)\n        process_monitor_thread.start()\n\n    # 启动窗口监听线程\n    hwnd_thread = threading.Thread(target=hwnd_check_thread, daemon=True)\n    hwnd_thread.start()\n\n    # 初始化播放任务队列\n    GlobalVariable.task_queue = queue.Queue()\n    task_thread = threading.Thread(target=music_start_tasks, daemon=True)\n    task_thread.start()\n    yield  # 👈 此处之后 FastAPI 正式启动\n    # 关闭时的清理逻辑（可选）\n    print(\"应用正在关闭...\")\napp = FastAPI(lifespan=lifespan)\napp.add_middleware(\n    CORSMiddleware,\n    allow_origins=[\"*\"],\n    allow_credentials=True,\n    allow_methods=[\"*\"],\n    allow_headers=[\"*\"],\n)\nregister_routes(app)\n\nif __name__ == '__main__':\n    try:\n        uvicorn.run(app, host=\"localhost\", port=9899, log_config=None)\n        logging.info(\"服务启动完成\")\n    except Exception as e:\n        logging.error(e)"
  },
  {
    "path": "sky-music-server/version.txt",
    "content": "# version.txt\nVSVersionInfo(\n  ffi=FixedFileInfo(\n    filevers=(1, 0, 0, 0),\n    prodvers=(1, 0, 0, 0),\n    mask=0x3f,\n    flags=0x0,\n    OS=0x40004,\n    fileType=0x1,\n    subtype=0x0,\n    date=(0, 0)\n  ),\n  kids=[\n    StringFileInfo([\n      StringTable(\n        '040904B0',\n        [\n          StringStruct('CompanyName', 'WindHide'),\n          StringStruct('FileDescription', '小星弹琴软件'),\n          StringStruct('FileVersion', '1.0.0.0'),\n          StringStruct('InternalName', 'sky-music-server'),\n          StringStruct('LegalCopyright', '© 2025 WindHide'),\n          StringStruct('OriginalFilename', 'sky-music-server.exe'),\n          StringStruct('ProductName', '小星弹琴软件'),\n          StringStruct('ProductVersion', '1.0.0.0')\n        ]\n      )\n    ]),\n    VarFileInfo([VarStruct('Translation', [1033, 1200])])\n  ]\n)\n"
  },
  {
    "path": "sky-music-server/windhide/auto/auto_thread.py",
    "content": "import threading\nfrom os import path\n\nimport time\n\nimport plyer\nfrom pynput.keyboard import Controller, Key\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils.ocr_heart_utils import get_friend_model_position\nfrom windhide.utils.ocr_normal_utils import resetGameFrame\nfrom windhide.utils.path_util import getResourcesPath\n\nif GlobalVariable.cpu_type == 'Intel':\n    from windhide.playRobot.intel_robot import mouse_move_to, key_press\nelse:\n    from windhide.playRobot.amd_robot import mouse_move_to, key_press\n\nkeyboard = Controller()\nclass HeartFireThread(threading.Thread):\n    def __init__(self):\n        super().__init__()\n        self._running = False  # 控制线程运行的标志位\n        self._lock = threading.Lock()  # 保证线程安全\n\n    def run(self):\n        \"\"\"线程启动后执行的主逻辑\"\"\"\n        self._running = True\n        resetGameFrame()\n        # mouse_wheel_scroll(\"down\")\n        # time.sleep(2)\n        # key_press(\"g\")\n        time.sleep(2)\n        # 先判断是不是第一页\n        while self._running:\n            friend_button = get_friend_model_position(GlobalVariable.sheld)[\"button\"]\n            if len(friend_button) >= 2:\n                break\n            else:\n                key_press(\"z\")\n            self.check_running()\n            time.sleep(3)\n        key_press(\"c\")\n        time.sleep(2)\n        # 来到第一页\n        while True:\n            if not self._running:\n                break\n            results = get_friend_model_position(GlobalVariable.sheld)\n            button = results[\"button\"]\n            friend = results[\"friend\"]\n            if len(friend) != 0:\n                for position in friend:\n                    if not self._running:\n                        break\n                    time.sleep(1)\n                    mouse_move_to(position[0], position[1])\n                    key_press(\"space\")\n                    time.sleep(0.1)\n                    key_press(\"space\")\n                    time.sleep(1.5)\n                    key_press(\"f\")\n                    time.sleep(1)\n                    key_press(\"ESC\")\n                # 下一页\n                time.sleep(1.5)\n                key_press(\"c\")\n                time.sleep(3)\n            else:\n                # 如果没有，显示别是不是到第一页去了，否则直接下一页\n                if len(button) < 2:\n                    key_press(\"c\")\n                    time.sleep(3)\n                else:\n                    plyer.notification.notify(\n                        app_name='小星弹琴软件',\n                        app_icon=path.join(getResourcesPath(\"systemTools\"), \"icon.ico\"),\n                        title='🔥🔥🔥🔥🔥🔥🔥🔥',\n                        message='点火结束🔥🔥🔥🔥🔥',\n                        timeout=1\n                    )\n                    return \"点火结束\"\n\n    def stop(self):\n        \"\"\"安全停止线程\"\"\"\n        with self._lock:\n            self._running = False\n        GlobalVariable.auto_thread = None\n\n    def check_running(self):\n        \"\"\"检查线程是否正在运行，若未运行则安全退出\"\"\"\n        with self._lock:\n            if not self._running:\n                raise StopIteration(\"线程已停止\")\n\n\ndef press_left():\n    keyboard.press(Key.left)\n    time.sleep(0.1)\n    keyboard.release(Key.left)\n"
  },
  {
    "path": "sky-music-server/windhide/musicToSheet/aigc_handler_sheet.py",
    "content": "import json\nimport os\nimport re\n\n# from google import genai\nfrom openai import OpenAI\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils.path_util import getResourcesPath\nfrom windhide.utils.play_util import detect_encoding\n\n\n# def gemini_ai(model,filename, type_):\n#     client = genai.Client(api_key=GlobalVariable.ai_token[\"Gemini\"])\n#     song_data = loadSheetFile(type_,filename)\n#     contents = GlobalVariable.duration_prompt if model == 'duration' else GlobalVariable.translate_prompt\n#     contents = contents.replace(\"{input}\",json.dumps(song_data[\"songNotes\"]))\n#     print(contents)\n#     response = client.models.generate_content(\n#         model=\"gemini-2.5-flash-preview-05-20\", contents=contents\n#     )\n#     return match_to_sheet(response.text, filename+\"Gemini\", song_data[\"bpm\"], model)\n\n# noinspection PyTypeChecker\ndef general_ai(model, filename, type_, platform):\n    try:\n        client = OpenAI(\n            api_key=GlobalVariable.general_ai[platform][\"key\"],\n            base_url=GlobalVariable.general_ai[platform][\"url\"]\n        )\n\n        # 加载原始乐谱\n        song_data = loadSheetFile(type_, filename)\n        target_length = len(song_data[\"songNotes\"])\n\n        # 准备初始提示词\n        contents = GlobalVariable.duration_prompt if model == 'duration' else GlobalVariable.translate_prompt\n        # 初始化消息上下文\n        messages = [\n            {\"role\": \"system\", \"content\": contents},\n            {\"role\": \"user\", \"content\": json.dumps(song_data[\"songNotes\"])},\n        ]\n\n        # 初始化状态变量\n        full_objects = []\n        max_retry = 20\n        retry_count = 0\n        total_segments = None\n        current_segment = 1\n\n        print(\"🎼 开始生成 JSON 音符数据...\")\n\n        while retry_count < max_retry:\n            # 向模型发起请求\n            response = client.chat.completions.create(\n                model=GlobalVariable.general_ai[platform][\"model\"],\n                messages=messages,\n                stream=True,\n            )\n\n            # 逐步拼接响应内容\n            partial = \"\"\n            for chunk in response:\n                if chunk.choices:\n                    delta = chunk.choices[0].delta\n                    if hasattr(delta, \"content\") and delta.content:\n                        partial += delta.content\n                        print(delta.content, end=\"\", flush=True)\n\n            # 提取段落信息\n            seg_cur, seg_tot = parse_segment_info(partial)\n            if seg_cur and seg_tot:\n                current_segment = seg_cur\n                total_segments = seg_tot\n                allow_extra_retry = 5\n                max_retry = total_segments + allow_extra_retry\n                retry_count = current_segment\n                print(f\"\\n🔍 当前第 {current_segment} 段 / 共 {total_segments} 段\")\n\n            # 提取 JSON 对象\n            new_objs = re.findall(r'\\{[^{}]*?\"time\"\\s*:\\s*\\d+[^{}]*?\\}', partial)\n            full_objects.extend(new_objs)\n            print(f\"\\n📦 已收集 JSON 元素数：{len(full_objects)} / 目标 {target_length}\")\n\n            # ✅ 判断是否完成（段数或数量）\n            if (total_segments and current_segment >= total_segments) or len(full_objects) >= target_length:\n                json_text = f\"[{','.join(full_objects)}]\"\n                saveSheetFile(json_text, filename + platform, song_data[\"bpm\"], model)\n                print(\"✅ JSON 输出已完成，已保存\")\n                return \"ok\"\n\n            # 🚫 若未完成，续问 —— 精简上下文避免 token 超限\n            retry_count += 1\n            print(f\"⚠️ 第 {current_segment} 段未完成，开始第 {retry_count} 次续问...\")\n\n            messages = [\n                {\"role\": \"system\", \"content\": contents},\n                {\"role\": \"user\", \"content\": json.dumps(song_data[\"songNotes\"])},\n                {\"role\": \"assistant\", \"content\": partial},\n                {\"role\": \"user\", \"content\": \"请继续上次未完成的 JSON 输出。\"}\n            ]\n\n        print(\"❌ 达到最大重试次数，输出失败\")\n        return \"output incomplete\"\n\n    except Exception as e:\n        print(\"❗ 异常：\", e)\n        return \"Nothing to do\"\n\ndef parse_segment_info(text):\n    \"\"\"\n    解析格式如“第 N 段（共预计 M 段）”，返回 (N, M)\n    \"\"\"\n    pattern = r'第\\s*(\\d+)\\s*段（共预计\\s*(\\d+)\\s*段）'\n    match = re.search(pattern, text)\n    if match:\n        current_segment = int(match.group(1))\n        total_segments = int(match.group(2))\n        return current_segment, total_segments\n    return None, None\n\ndef match_to_sheet(text, filename, bpm, model):\n    start_idx = text.find('[')\n    end_idx = text.rfind(']')\n\n    if start_idx == -1 or end_idx == -1 or end_idx <= start_idx:\n        return \"error\"\n\n    json_str = text[start_idx:end_idx + 1]\n\n    try:\n        parsed = json.loads(json_str)\n        if isinstance(parsed, list) and len(parsed) >= 20:\n            print(\"✅ 成功解析 JSON 数组，长度：\", len(parsed))\n            saveSheetFile(json.dumps(parsed), filename, bpm, model)\n            return \"ok\"\n        else:\n            return \"error\"\n    except json.JSONDecodeError as e:\n        print(\"⚠️ JSON 解码失败:\", e)\n        return \"error\"\n\n\ndef loadSheetFile(type, fileName):\n    # 优化了文件路径构建\n    file_path = os.path.join(getResourcesPath(type), fileName + \".txt\")\n    with open(file_path, 'r', encoding=detect_encoding(file_path)) as file:\n        data = json.load(file)\n    song_notes = data[0].get(\"songNotes\", [])\n    bpm = data[0].get(\"bpm\", [])\n    if not song_notes:\n        return []\n    return {\n        \"songNotes\": song_notes,\n        \"bpm\": bpm\n    }\n\ndef saveSheetFile(song_notes, fileName, bpm, model):\n    if isinstance(song_notes, str):\n        song_notes = json.loads(song_notes)\n    output_file_name = fileName + \"_AIGC_Handler_\"+ (\"延音\" if model == \"duration\" else \"间隔优化\")\n    output = [{\n        \"name\": output_file_name,\n        \"author\": \"skyMusic-WindHide\",\n        \"transcribedBy\": \"WindHide's Software\",\n        \"bpm\": bpm,\n        \"bitsPerPage\": 15,\n        \"pitchLevel\": 0,\n        \"isComposed\": True,\n        \"songNotes\": song_notes,\n        \"isEncrypted\": False,\n    }]\n    file_output_path =os.path.join(getResourcesPath(\"myTranslate\"), f\"{output_file_name}.txt\")\n    with open(file_output_path, 'w') as f:\n        json.dump(output, f, indent=4, ensure_ascii=False)\n\n"
  },
  {
    "path": "sky-music-server/windhide/musicToSheet/music2html.py",
    "content": "import os\n\nfrom jinja2 import Template\nfrom platformdirs import user_desktop_dir\n\nhtml_template = \"\"\"\n<!DOCTYPE html>\n<html lang=\"en_US\">\n\t<head>\n\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n\t\t<title>{{ sheet_name }}</title>\n\t\t<style type=\"text/css\">\n@media (prefers-reduced-motion: reduce){html { scroll-behavior: auto; }}\nhtml { scroll-behavior: smooth; }\n#navigation { border: none; }\n#transcript { margin: 0 0; }\nbody{font-family: \"Noto Sans\", \"Noto Sans CJK JP\", \"Noto Sans CJK KR\", \"Noto Sans CJK SC\", \"Noto Sans CJK TC\", \"Avenir\", \"Arial\", \"sans-serif\";font-size: 12pt;}\nh1{font-size: 1.3em;font-weight: bold;}\n.header{font-size: 0.8em;line-height: 50%;}\n.line{display: flex;flex-direction: row;flex-wrap: wrap;}\n.lyrics{margin-left: 0.5rem;margin-bottom: 0.35rem;border: 0px black solid;width: 8.11em;font-size: 0.8em;text-align: center;}\nhr{border: none;margin-left: 0;padding: 0;margin-right: 1.8em;width: 100vw;}\nhr.sep { border-top: thin solid lightgray; width: 93vw; }\nhr.solid { border-top: thin solid black; }\nhr.double { border-top: medium double black; }\nhr.dashed { border-top: thin dashed black; }\n.instr.silent, .instr.broken{border-width: 0;background-color: transparent;}\n.repeat, .num{font-size: 0.8em;align-self: flex-end;margin: 2px;}\n.num{color: grey;padding-left: 2em;}\n.broken{color: red;font-weight: bold;}\n@media (prefers-color-scheme: dark){body { background-color: #282828; }.instr.harp { border-color: white; }p, body, td, text.headers { color: white; }}\n.instr{margin-left: 0.5rem;margin-bottom: 0.35rem;border-radius: 5px;border: 1px black solid;display: grid;width: fit-content;}\n.instr.harp {grid-template-columns: repeat(5, 1.3em); grid-template-rows: repeat(3, 1.4em);}\n.instr.drum {grid-template-columns: repeat(4, 1.3em); grid-template-rows: repeat(2, 1.4em);}\n.r1, .r2, .r3, [class^=\"q\"]{border-radius: 4px;margin: 2px;width: 1em;height: 1em;justify-self: center;align-self: center;}\nd1, d2, d3, silence { background-position: 50%; }\n.r1 { background-color: limegreen; }\n.r2 { background-color: deepskyblue; }\n.r3 { background-color: deeppink; }\ncrc { background-image: url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 91 91'%3E%3Ccircle fill='transparent' stroke='white' stroke-width='5px' cx='45.4' cy='45.4' r='25.5'%3E%3C/circle%3E%3C/svg%3E\"); }\ndmn { background-image: url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 123.40601 123.40601'%0A%3E%3Cg transform='translate(-52.444184,-69.21989)'%0A%3E%3Crect style='fill:none;stroke:white ;stroke-width:5px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;' width='64.633926' height='64.633926' x='140.97375' y='-20.454748' transform='rotate(45)' /%3E%3C/g%3E%3C/svg%3E\"); }\ncrdm { background-image: url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 123.40601 123.40601'%0A%3E%3Cg transform='translate(-52.444184,-69.21989)' %3E%3Crect style='fill:none;stroke:white;stroke-width:5px;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1' width='64.633926' height='64.633926' x='140.97375' y='-20.454748' transform='rotate(45)' /%3E%3Ccircle style='fill:none;stroke:white;stroke-width:5px;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1' cx='114.12409' cy='130.82843' r='31.938707' /%3E%3C/g%3E%3C/svg%3E\"); }\nd1 { background-image: url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 123.40601 123.40601'%3E%3Ccircle stroke='none' fill='rgb(194,240,194)' cx='61.5' cy='61.5' r='14'%3E%3C/circle%3E%3C/svg%3E\"); }\nd2 { background-image: url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 123.40601 123.40601'%3E%3Ccircle stroke='none' fill='rgb(179,236,255)' cx='61.5' cy='61.5' r='14'%3E%3C/circle%3E%3C/svg%3E\"); }\nd3 { background-image: url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 123.40601 123.40601'%3E%3Ccircle stroke='none' fill='rgb(255,185,223)' cx='61.5' cy='61.5' r='14'%3E%3C/circle%3E%3C/svg%3E\"); }\ndn { background-image: url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 123.40601 123.40601'%3E%3Ccircle stroke='none' fill='rgb(167,167,167)' cx='61.5' cy='61.5' r='14'%3E%3C/circle%3E%3C/svg%3E\"); }\nsilence { background-image: url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 123.40601 123.40601'%3E%3Ccircle stroke='none' fill='rgb(167,167,167)' cx='61.5' cy='61.5' r='28'%3E%3C/circle%3E%3C/svg%3E\"); }\n</style></head>\n<body>\n<h1>{{ sheet_name }}</h1>\n<p class=\"header\"><b>文件由：WindHide's Sky Music弹琴软件创建</b> <a href=\"https://github.com/windhide/SkyMusicPlay-for-Windows\" style=\"color: pink;\">https://github.com/windhide/SkyMusicPlay-for-Windows</a></p>\n<p class=\"header\"><b></b></p>\n</div>\n<div id=\"transcript\">\n    {% for line in content %}\n    <hr class=\"sep\">\n    <div class=\"line\" id=\"{{ line.id }}\">\n        {% for instr in line.instruments %}\n        <div class=\"instr harp\" id=\"{{ instr.id }}\">\n            {% for note in instr.notes %}\n            <{{ note.type }} class=\"{{ note.class }}\"></{{ note.type }}>\n            {% endfor %}\n        </div>\n        {% endfor %}\n    </div>\n    {% endfor %}\n</div>\n</body></html>\n\"\"\"\n\n\ndef generatorSheetHtml(sheet_name, convert_sheet):\n    context = []\n    instr_index = 0\n    line_index = 0\n    line_data = {\"id\": f\"line-{line_index}\", \"instruments\": []}\n\n    max_instruments_per_line = 13\n    switch_limit = {13: 11, 11: 13}  # 交替限制\n\n    # 映射按键到音符类型\n    note_mapping = {\n        \"y\": (\"crdm\", \"r1\"),\n        \"u\": (\"dmn\", \"r1\"),\n        \"i\": (\"crc\", \"r1\"),\n        \"o\": (\"dmn\", \"r1\"),\n        \"p\": (\"crc\", \"r1\"),\n\n        \"h\": (\"crc\", \"r2\"),\n        \"j\": (\"dmn\", \"r2\"),\n        \"k\": (\"crdm\", \"r2\"),\n        \"l\": (\"dmn\", \"r2\"),\n        \";\": (\"crc\", \"r2\"),\n\n        \"n\": (\"crc\", \"r3\"),\n        \"m\": (\"dmn\", \"r3\"),\n        \",\": (\"crc\", \"r3\"),\n        \".\": (\"dmn\", \"r3\"),\n        \"/\": (\"crdm\", \"r3\"),\n    }\n\n    for index, key in enumerate(convert_sheet):\n        notes = []\n        for char in \"yuiophjkl;nm,./\":\n            if char in key:\n                note_type, note_class = note_mapping[char]\n            else:\n                note_type, note_class = \"d1\", \"\"  # 默认值\n\n            notes.append({\"type\": note_type, \"class\": note_class})\n\n        instrument = {\"id\": f\"instr-{instr_index}\", \"notes\": notes}\n        line_data[\"instruments\"].append(instrument)\n        instr_index += 1\n\n        # 判断是否换行\n        if instr_index == max_instruments_per_line:\n            context.append(line_data)\n            line_index += 1\n            line_data = {\"id\": f\"line-{line_index}\", \"instruments\": []}\n            instr_index = 0\n            max_instruments_per_line = switch_limit[max_instruments_per_line]\n\n    # 处理最后一行\n    if line_data[\"instruments\"]:\n        context.append(line_data)\n\n    # 渲染模板\n    template = Template(html_template)\n    final_html = template.render(sheet_name=sheet_name, content=context)\n\n    desktop_path = os.path.join(user_desktop_dir(), f\"{sheet_name}.html\")\n    with open(desktop_path, \"w\", encoding=\"utf-8\") as file:\n        file.write(final_html)\n\n    return \"ok\"\n"
  },
  {
    "path": "sky-music-server/windhide/musicToSheet/process_audio.py",
    "content": "import json\nimport os\n\nimport pretty_midi\n\nfrom windhide.musicToSheet.transfer_MID import inference\nfrom windhide.musicToSheet.vocals_split import split_vocals\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils.path_util import getResourcesPath\n\n# 15个音符与键盘按键的映射\nnote_to_key = {\"_C_c¹\":{36:'1Key0',38:'1Key1',40:'1Key2',41:'1Key3',43:'1Key4',45:'1Key5',47:'1Key6',48:'1Key7',50:'1Key8',52:'1Key9',53:'1Key10',55:'1Key11',57:'1Key12',59:'1Key13',60:'1Key14'},\"c_c²\":{48:'1Key0',50:'1Key1',52:'1Key2',53:'1Key3',55:'1Key4',57:'1Key5',59:'1Key6',60:'1Key7',62:'1Key8',64:'1Key9',65:'1Key10',67:'1Key11',69:'1Key12',71:'1Key13',72:'1Key14'},'c¹_c³':{60:'1Key0',62:'1Key1',64:'1Key2',65:'1Key3',67:'1Key4',69:'1Key5',71:'1Key6',72:'1Key7',74:'1Key8',76:'1Key9',77:'1Key10',79:'1Key11',81:'1Key12',83:'1Key13',84:'1Key14'},\"c²_c⁴\":{72:'1Key0',74:'1Key1',76:'1Key2',77:'1Key3',79:'1Key4',81:'1Key5',83:'1Key6',84:'1Key7',86:'1Key8',88:'1Key9',89:'1Key10',91:'1Key11',93:'1Key12',95:'1Key13',96:'1Key14'},\"c³_c⁵\":{84:'1Key0',86:'1Key1',88:'1Key2',89:'1Key3',91:'1Key4',93:'1Key5',95:'1Key6',96:'1Key7',98:'1Key8',100:'1Key9',101:'1Key10',103:'1Key11',105:'1Key12',107:'1Key13',108:'1Key14'},\"_C_c²\":{36:'1Key-7',38:'1Key-6',40:'1Key-5',41:'1Key-4',43:'1Key-3',45:'1Key-2',47:'1Key-1',48:'1Key0',50:'1Key1',52:'1Key2',53:'1Key3',55:'1Key4',57:'1Key5',59:'1Key6',60:'1Key7',62:'1Key8',64:'1Key9',65:'1Key10',67:'1Key11',69:'1Key12',71:'1Key13',72:'1Key14'},\"c_c³\":{48:'1Key-7',50:'1Key-6',52:'1Key-5',53:'1Key-4',55:'1Key-3',57:'1Key-2',59:'1Key-1',60:'1Key0',62:'1Key1',64:'1Key2',65:'1Key3',67:'1Key4',69:'1Key5',71:'1Key6',72:'1Key7',74:'1Key8',76:'1Key9',77:'1Key10',79:'1Key11',81:'1Key12',83:'1Key13',84:'1Key14'},\"c¹_c⁴\":{60:'1Key-7',62:'1Key-6',64:'1Key-5',65:'1Key-4',67:'1Key-3',69:'1Key-2',71:'1Key-1',72:'1Key0',74:'1Key1',76:'1Key2',77:'1Key3',79:'1Key4',81:'1Key5',83:'1Key6',84:'1Key7',86:'1Key8',88:'1Key9',89:'1Key10',91:'1Key11',93:'1Key12',95:'1Key13',96:'1Key14'},\"c²_c⁵\":{72:'1Key-7',74:'1Key-6',76:'1Key-5',77:'1Key-4',79:'1Key-3',81:'1Key-2',83:'1Key-1',84:'1Key0',86:'1Key1',88:'1Key2',89:'1Key3',91:'1Key4',93:'1Key5',95:'1Key6',96:'1Key7',98:'1Key8',100:'1Key9',101:'1Key10',103:'1Key11',105:'1Key12',107:'1Key13',108:'1Key14'},\"_C_c³\":{36:'1Key-14',38:'1Key-13',40:'1Key-12',41:'1Key-11',43:'1Key-10',45:'1Key-9',47:'1Key-8',48:'1Key-7',50:'1Key-6',52:'1Key-5',53:'1Key-4',55:'1Key-3',57:'1Key-2',59:'1Key-1',60:'1Key0',62:'1Key1',64:'1Key2',65:'1Key3',67:'1Key4',69:'1Key5',71:'1Key6',72:'1Key7',74:'1Key8',76:'1Key9',77:'1Key10',79:'1Key11',81:'1Key12',83:'1Key13',84:'1Key14'},\"c_c⁴\":{48:'1Key-14',50:'1Key-13',52:'1Key-12',53:'1Key-11',55:'1Key-10',57:'1Key-9',59:'1Key-8',60:'1Key-7',62:'1Key-6',64:'1Key-5',65:'1Key-4',67:'1Key-3',69:'1Key-2',71:'1Key-1',72:'1Key0',74:'1Key1',76:'1Key2',77:'1Key3',79:'1Key4',81:'1Key5',83:'1Key6',84:'1Key7',86:'1Key8',88:'1Key9',89:'1Key10',91:'1Key11',93:'1Key12',95:'1Key13',96:'1Key14'},\"c¹_c⁵\":{60:'1Key-14',62:'1Key-13',64:'1Key-12',65:'1Key-11',67:'1Key-10',69:'1Key-9',71:'1Key-8',72:'1Key-7',74:'1Key-6',76:'1Key-5',77:'1Key-4',79:'1Key-3',81:'1Key-2',83:'1Key-1',84:'1Key0',86:'1Key1',88:'1Key2',89:'1Key3',91:'1Key4',93:'1Key5',95:'1Key6',96:'1Key7',98:'1Key8',100:'1Key9',101:'1Key10',103:'1Key11',105:'1Key12',107:'1Key13',108:'1Key14'},\"_C_c⁴\":{36:'1Key-14',38:'1Key-13',40:'1Key-12',41:'1Key-11',43:'1Key-10',45:'1Key-9',47:'1Key-8',48:'1Key-7',50:'1Key-6',52:'1Key-5',53:'1Key-4',55:'1Key-3',57:'1Key-2',59:'1Key-1',60:'1Key0',62:'1Key1',64:'1Key2',65:'1Key3',67:'1Key4',69:'1Key5',71:'1Key6',72:'1Key7',74:'1Key8',76:'1Key9',77:'1Key10',79:'1Key11',81:'1Key12',83:'1Key13',84:'1Key14',86:'1Key15',88:'1Key16',89:'1Key17',91:'1Key18',93:'1Key19',95:'1Key20',96:'1Key21',},\"c_c⁵\":{48:'1Key-14',50:'1Key-13',52:'1Key-12',53:'1Key-11',55:'1Key-10',57:'1Key-9',59:'1Key-8',60:'1Key-7',62:'1Key-6',64:'1Key-5',65:'1Key-4',67:'1Key-3',69:'1Key-2',71:'1Key-1',72:'1Key0',74:'1Key1',76:'1Key2',77:'1Key3',79:'1Key4',81:'1Key5',83:'1Key6',84:'1Key7',86:'1Key8',88:'1Key9',89:'1Key10',91:'1Key11',93:'1Key12',95:'1Key13',96:'1Key14',98:'1Key15',100:'1Key16',101:'1Key17',103:'1Key18',105:'1Key19',107:'1Key20',108:'1Key21',},\"_C_c⁵\":{36:'1Key-14',38:'1Key-13',40:'1Key-12',41:'1Key-11',43:'1Key-10',45:'1Key-9',47:'1Key-8',48:'1Key-7',50:'1Key-6',52:'1Key-5',53:'1Key-4',55:'1Key-3',57:'1Key-2',59:'1Key-1',60:\"1Key0\",62:\"1Key1\",64:\"1Key2\",65:\"1Key3\",67:\"1Key4\",69:\"1Key5\",71:\"1Key6\",72:\"1Key7\",74:\"1Key8\",76:\"1Key9\",77:\"1Key10\",79:\"1Key11\",81:\"1Key12\",83:\"1Key13\",84:\"1Key14\",86:\"1Key15\",88:\"1Key16\",89:\"1Key17\",91:\"1Key18\",93:\"1Key19\",95:\"1Key20\",96:\"1Key21\",98:\"1Key22\",100:\"1Key23\",101:\"1Key24\",103:\"1Key25\",105:\"1Key26\",107:\"1Key27\",108:\"1Key28\"},\"_C_b\":{36:'1Key0',38:'1Key1',40:'1Key2',41:'1Key3',43:'1Key4',45:'1Key5',47:'1Key6',48:'1Key7',50:'1Key8',52:'1Key9',53:'1Key10',55:'1Key11',57:'1Key12',59:'1Key13'},\"c_b¹\":{48:'1Key0',50:'1Key1',52:'1Key2',53:'1Key3',55:'1Key4',57:'1Key5',59:'1Key6',60:'1Key7',62:'1Key8',64:'1Key9',65:'1Key10',67:'1Key11',69:'1Key12',71:'1Key13'},'c¹_b²':{60:'1Key0',62:'1Key1',64:'1Key2',65:'1Key3',67:'1Key4',69:'1Key5',71:'1Key6',72:'1Key7',74:'1Key8',76:'1Key9',77:'1Key10',79:'1Key11',81:'1Key12',83:'1Key13'},\"c²_b³\":{72:'1Key0',74:'1Key1',76:'1Key2',77:'1Key3',79:'1Key4',81:'1Key5',83:'1Key6',84:'1Key7',86:'1Key8',88:'1Key9',89:'1Key10',91:'1Key11',93:'1Key12',95:'1Key13'},\"c³_b⁴\":{84:'1Key0',86:'1Key1',88:'1Key2',89:'1Key3',91:'1Key4',93:'1Key5',95:'1Key6',96:'1Key7',98:'1Key8',100:'1Key9',101:'1Key10',103:'1Key11',105:'1Key12',107:'1Key13'},\"_C_b¹\":{36:'1Key-7',38:'1Key-6',40:'1Key-5',41:'1Key-4',43:'1Key-3',45:'1Key-2',47:'1Key-1',48:'1Key0',50:'1Key1',52:'1Key2',53:'1Key3',55:'1Key4',57:'1Key5',59:'1Key6',60:'1Key7',62:'1Key8',64:'1Key9',65:'1Key10',67:'1Key11',69:'1Key12',71:'1Key13'},\"c_b²\":{48:'1Key-7',50:'1Key-6',52:'1Key-5',53:'1Key-4',55:'1Key-3',57:'1Key-2',59:'1Key-1',60:'1Key0',62:'1Key1',64:'1Key2',65:'1Key3',67:'1Key4',69:'1Key5',71:'1Key6',72:'1Key7',74:'1Key8',76:'1Key9',77:'1Key10',79:'1Key11',81:'1Key12',83:'1Key13'},\"c¹_b³\":{60:'1Key-7',62:'1Key-6',64:'1Key-5',65:'1Key-4',67:'1Key-3',69:'1Key-2',71:'1Key-1',72:'1Key0',74:'1Key1',76:'1Key2',77:'1Key3',79:'1Key4',81:'1Key5',83:'1Key6',84:'1Key7',86:'1Key8',88:'1Key9',89:'1Key10',91:'1Key11',93:'1Key12',95:'1Key13'},\"c²_b⁴\":{72:'1Key-7',74:'1Key-6',76:'1Key-5',77:'1Key-4',79:'1Key-3',81:'1Key-2',83:'1Key-1',84:'1Key0',86:'1Key1',88:'1Key2',89:'1Key3',91:'1Key4',93:'1Key5',95:'1Key6',96:'1Key7',98:'1Key8',100:'1Key9',101:'1Key10',103:'1Key11',105:'1Key12',107:'1Key13'},\"_C_b²\":{36:'1Key-14',38:'1Key-13',40:'1Key-12',41:'1Key-11',43:'1Key-10',45:'1Key-9',47:'1Key-8',48:'1Key-7',50:'1Key-6',52:'1Key-5',53:'1Key-4',55:'1Key-3',57:'1Key-2',59:'1Key-1',60:'1Key0',62:'1Key1',64:'1Key2',65:'1Key3',67:'1Key4',69:'1Key5',71:'1Key6',72:'1Key7',74:'1Key8',76:'1Key9',77:'1Key10',79:'1Key11',81:'1Key12',83:'1Key13'},\"c_b³\":{48:'1Key-14',50:'1Key-13',52:'1Key-12',53:'1Key-11',55:'1Key-10',57:'1Key-9',59:'1Key-8',60:'1Key-7',62:'1Key-6',64:'1Key-5',65:'1Key-4',67:'1Key-3',69:'1Key-2',71:'1Key-1',72:'1Key0',74:'1Key1',76:'1Key2',77:'1Key3',79:'1Key4',81:'1Key5',83:'1Key6',84:'1Key7',86:'1Key8',88:'1Key9',89:'1Key10',91:'1Key11',93:'1Key12',95:'1Key13'},\"c¹_b⁴\":{60:'1Key-14',62:'1Key-13',64:'1Key-12',65:'1Key-11',67:'1Key-10',69:'1Key-9',71:'1Key-8',72:'1Key-7',74:'1Key-6',76:'1Key-5',77:'1Key-4',79:'1Key-3',81:'1Key-2',83:'1Key-1',84:'1Key0',86:'1Key1',88:'1Key2',89:'1Key3',91:'1Key4',93:'1Key5',95:'1Key6',96:'1Key7',98:'1Key8',100:'1Key9',101:'1Key10',103:'1Key11',105:'1Key12',107:'1Key13'},\"_C_b³\":{36:'1Key-14',38:'1Key-13',40:'1Key-12',41:'1Key-11',43:'1Key-10',45:'1Key-9',47:'1Key-8',48:'1Key-7',50:'1Key-6',52:'1Key-5',53:'1Key-4',55:'1Key-3',57:'1Key-2',59:'1Key-1',60:'1Key0',62:'1Key1',64:'1Key2',65:'1Key3',67:'1Key4',69:'1Key5',71:'1Key6',72:'1Key7',74:'1Key8',76:'1Key9',77:'1Key10',79:'1Key11',81:'1Key12',83:'1Key13',84:'1Key14',86:'1Key15',88:'1Key16',89:'1Key17',91:'1Key18',93:'1Key19',95:'1Key20'},\"c_b⁴\":{48:'1Key-14',50:'1Key-13',52:'1Key-12',53:'1Key-11',55:'1Key-10',57:'1Key-9',59:'1Key-8',60:'1Key-7',62:'1Key-6',64:'1Key-5',65:'1Key-4',67:'1Key-3',69:'1Key-2',71:'1Key-1',72:'1Key0',74:'1Key1',76:'1Key2',77:'1Key3',79:'1Key4',81:'1Key5',83:'1Key6',84:'1Key7',86:'1Key8',88:'1Key9',89:'1Key10',91:'1Key11',93:'1Key12',95:'1Key13',96:'1Key14',98:'1Key15',100:'1Key16',101:'1Key17',103:'1Key18',105:'1Key19',107:'1Key20'},\"_C_b⁴\":{36:'1Key-14',38:'1Key-13',40:'1Key-12',41:'1Key-11',43:'1Key-10',45:'1Key-9',47:'1Key-8',48:'1Key-7',50:'1Key-6',52:'1Key-5',53:'1Key-4',55:'1Key-3',57:'1Key-2',59:'1Key-1',60:\"1Key0\",62:\"1Key1\",64:\"1Key2\",65:\"1Key3\",67:\"1Key4\",69:\"1Key5\",71:\"1Key6\",72:\"1Key7\",74:\"1Key8\",76:\"1Key9\",77:\"1Key10\",79:\"1Key11\",81:\"1Key12\",83:\"1Key13\",84:\"1Key14\",86:\"1Key15\",88:\"1Key16\",89:\"1Key17\",91:\"1Key18\",93:\"1Key19\",95:\"1Key20\",96:\"1Key21\",98:\"1Key22\",100:\"1Key23\",101:\"1Key24\",103:\"1Key25\",105:\"1Key26\",107:\"1Key27\"}}\nextra_note_to_key = {\"_C_c¹\":{37:['1Key0','1Key1'],39:['1Key1','1Key2'],42:['1Key3','1Key4'],44:['1Key4','1Key5'],46:['1Key5','1Key6'],49:['1Key6','1Key7'],51:['1Key8','1Key9'],54:['1Key10','1Key11'],56:['1Key11','1Key12'],58:['1Key12','1Key13'],},\"c_c²\":{49:['1Key0','1Key1'],51:['1Key1','1Key2'],54:['1Key3','1Key4'],56:['1Key4','1Key5'],58:['1Key5','1Key6'],61:['1Key6','1Key7'],63:['1Key8','1Key9'],66:['1Key10','1Key11'],68:['1Key11','1Key12'],70:['1Key12','1Key13'],},'c¹_c³':{61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],},\"c²_c⁴\":{73:['1Key0','1Key1'],75:['1Key1','1Key2'],78:['1Key3','1Key4'],80:['1Key4','1Key5'],82:['1Key5','1Key6'],85:['1Key6','1Key7'],87:['1Key8','1Key9'],90:['1Key10','1Key11'],92:['1Key11','1Key12'],94:['1Key12','1Key13'],},\"c³_c⁵\":{85:['1Key0','1Key1'],87:['1Key1','1Key2'],90:['1Key3','1Key4'],92:['1Key4','1Key5'],94:['1Key5','1Key6'],97:['1Key6','1Key7'],99:['1Key8','1Key9'],102:['1Key10','1Key11'],104:['1Key11','1Key12'],106:['1Key12','1Key13'],},\"_C_c²\":{37:['1Key-7','1Key-6'],39:['1Key-6','1Key-5'],42:['1Key-4','1Key-3'],44:['1Key-3','1Key-2'],46:['1Key-2','1Key-1'],49:['1Key0','1Key1'],51:['1Key1','1Key2'],54:['1Key3','1Key4'],56:['1Key4','1Key5'],58:['1Key5','1Key6'],61:['1Key6','1Key7'],63:['1Key8','1Key9'],66:['1Key10','1Key11'],68:['1Key11','1Key12'],70:['1Key12','1Key13'],},\"c_c³\":{49:['1Key-7','1Key-6'],51:['1Key-6','1Key-5'],54:['1Key-4','1Key-3'],56:['1Key-3','1Key-2'],58:['1Key-2','1Key-1'],61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],},\"c¹_c⁴\":{61:['1Key-7','1Key-6'],63:['1Key-6','1Key-5'],66:['1Key-4','1Key-3'],68:['1Key-3','1Key-2'],70:['1Key-2','1Key-1'],73:['1Key0','1Key1'],75:['1Key1','1Key2'],78:['1Key3','1Key4'],80:['1Key4','1Key5'],82:['1Key5','1Key6'],85:['1Key6','1Key7'],87:['1Key8','1Key9'],90:['1Key10','1Key11'],92:['1Key11','1Key12'],94:['1Key12','1Key13'],},\"c²_c⁵\":{73:['1Key-7','1Key-6'],75:['1Key-6','1Key-5'],78:['1Key-4','1Key-3'],80:['1Key-3','1Key-2'],82:['1Key-2','1Key-1'],85:['1Key0','1Key1'],87:['1Key1','1Key2'],90:['1Key3','1Key4'],92:['1Key4','1Key5'],94:['1Key5','1Key6'],97:['1Key6','1Key7'],99:['1Key8','1Key9'],102:['1Key10','1Key11'],104:['1Key11','1Key12'],106:['1Key12','1Key13'],},\"_C_c³\":{37:['1Key-14','1Key-13'],39:['1Key-13','1Key-12'],42:['1Key-11','1Key-10'],44:['1Key-10','1Key-9'],46:['1Key-9','1Key-8'],49:['1Key-7','1Key-6'],51:['1Key-6','1Key-5'],54:['1Key-4','1Key-3'],56:['1Key-3','1Key-2'],58:['1Key-2','1Key-1'],61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],},\"c_c⁴\":{49:['1Key-14','1Key-13'],51:['1Key-13','1Key-12'],54:['1Key-11','1Key-10'],56:['1Key-10','1Key-9'],58:['1Key-9','1Key-8'],61:['1Key-7','1Key-6'],63:['1Key-6','1Key-5'],66:['1Key-4','1Key-3'],68:['1Key-3','1Key-2'],70:['1Key-2','1Key-1'],73:['1Key0','1Key1'],75:['1Key1','1Key2'],78:['1Key3','1Key4'],80:['1Key4','1Key5'],82:['1Key5','1Key6'],85:['1Key6','1Key7'],87:['1Key8','1Key9'],90:['1Key10','1Key11'],92:['1Key11','1Key12'],94:['1Key12','1Key13'],},\"c¹_c⁵\":{61:['1Key-14','1Key-13'],63:['1Key-13','1Key-12'],66:['1Key-11','1Key-10'],68:['1Key-10','1Key-9'],70:['1Key-9','1Key-8'],73:['1Key-7','1Key-6'],75:['1Key-6','1Key-5'],78:['1Key-4','1Key-3'],80:['1Key-3','1Key-2'],82:['1Key-2','1Key-1'],85:['1Key0','1Key1'],87:['1Key1','1Key2'],90:['1Key3','1Key4'],92:['1Key4','1Key5'],94:['1Key5','1Key6'],97:['1Key6','1Key7'],99:['1Key8','1Key9'],102:['1Key10','1Key11'],104:['1Key11','1Key12'],106:['1Key12','1Key13'],},\"_C_c⁴\":{37:['1Key-14','1Key-13'],39:['1Key-13','1Key-12'],42:['1Key-11','1Key-10'],44:['1Key-10','1Key-9'],46:['1Key-9','1Key-8'],49:['1Key-7','1Key-6'],51:['1Key-6','1Key-5'],54:['1Key-4','1Key-3'],56:['1Key-3','1Key-2'],58:['1Key-2','1Key-1'],61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],85:['1Key14','1Key15'],87:['1Key15','1Key16'],90:['1Key17','1Key18'],92:['1Key18','1Key19'],94:['1Key19','1Key20'],},\"c_c⁵\":{49:['1Key-14','1Key-13'],51:['1Key-13','1Key-12'],54:['1Key-11','1Key-10'],56:['1Key-10','1Key-9'],58:['1Key-9','1Key-8'],61:['1Key-7','1Key-6'],63:['1Key-6','1Key-5'],66:['1Key-4','1Key-3'],68:['1Key-3','1Key-2'],70:['1Key-2','1Key-1'],73:['1Key0','1Key1'],75:['1Key1','1Key2'],78:['1Key3','1Key4'],80:['1Key4','1Key5'],82:['1Key5','1Key6'],85:['1Key6','1Key7'],87:['1Key8','1Key9'],90:['1Key10','1Key11'],92:['1Key11','1Key12'],94:['1Key12','1Key13'],97:['1Key14','1Key15'],99:['1Key15','1Key16'],102:['1Key17','1Key18'],104:['1Key18','1Key19'],106:['1Key19','1Key20'],},\"_C_c⁵\":{37:['1Key-14','1Key-13'],39:['1Key-13','1Key-12'],42:['1Key-11','1Key-10'],44:['1Key-10','1Key-9'],46:['1Key-9','1Key-8'],49:['1Key-7','1Key-6'],51:['1Key-6','1Key-5'],54:['1Key-4','1Key-3'],56:['1Key-3','1Key-2'],58:['1Key-2','1Key-1'],61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],85:['1Key14','1Key15'],87:['1Key15','1Key16'],90:['1Key17','1Key18'],92:['1Key18','1Key19'],94:['1Key19','1Key20'],97:['1Key21','1Key22'],99:['1Key22','1Key23'],102:['1Key24','1Key25'],104:['1Key25','1Key26'],106:['1Key26','1Key27'],},\"_C_b\":{37:['1Key0','1Key1'],39:['1Key1','1Key2'],42:['1Key3','1Key4'],44:['1Key4','1Key5'],46:['1Key5','1Key6'],49:['1Key6','1Key7'],51:['1Key8','1Key9'],54:['1Key10','1Key11'],56:['1Key11','1Key12'],58:['1Key12','1Key13'],},\"c_b¹\":{49:['1Key0','1Key1'],51:['1Key1','1Key2'],54:['1Key3','1Key4'],56:['1Key4','1Key5'],58:['1Key5','1Key6'],61:['1Key6','1Key7'],63:['1Key8','1Key9'],66:['1Key10','1Key11'],68:['1Key11','1Key12'],70:['1Key12','1Key13'],},'c¹_b²':{61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],},\"c²_b³\":{73:['1Key0','1Key1'],75:['1Key1','1Key2'],78:['1Key3','1Key4'],80:['1Key4','1Key5'],82:['1Key5','1Key6'],85:['1Key6','1Key7'],87:['1Key8','1Key9'],90:['1Key10','1Key11'],92:['1Key11','1Key12'],94:['1Key12','1Key13'],},\"c³_b⁴\":{85:['1Key0','1Key1'],87:['1Key1','1Key2'],90:['1Key3','1Key4'],92:['1Key4','1Key5'],94:['1Key5','1Key6'],97:['1Key6','1Key7'],99:['1Key8','1Key9'],102:['1Key10','1Key11'],104:['1Key11','1Key12'],106:['1Key12','1Key13'],},\"_C_b¹\":{37:['1Key-7','1Key-6'],39:['1Key-6','1Key-5'],42:['1Key-4','1Key-3'],44:['1Key-3','1Key-2'],46:['1Key-2','1Key-1'],49:['1Key0','1Key1'],51:['1Key1','1Key2'],54:['1Key3','1Key4'],56:['1Key4','1Key5'],58:['1Key5','1Key6'],61:['1Key6','1Key7'],63:['1Key8','1Key9'],66:['1Key10','1Key11'],68:['1Key11','1Key12'],70:['1Key12','1Key13'],},\"c_b²\":{49:['1Key-7','1Key-6'],51:['1Key-6','1Key-5'],54:['1Key-4','1Key-3'],56:['1Key-3','1Key-2'],58:['1Key-2','1Key-1'],61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],},\"c¹_b³\":{61:['1Key-7','1Key-6'],63:['1Key-6','1Key-5'],66:['1Key-4','1Key-3'],68:['1Key-3','1Key-2'],70:['1Key-2','1Key-1'],73:['1Key0','1Key1'],75:['1Key1','1Key2'],78:['1Key3','1Key4'],80:['1Key4','1Key5'],82:['1Key5','1Key6'],85:['1Key6','1Key7'],87:['1Key8','1Key9'],90:['1Key10','1Key11'],92:['1Key11','1Key12'],94:['1Key12','1Key13'],},\"c²_b⁴\":{73:['1Key-7','1Key-6'],75:['1Key-6','1Key-5'],78:['1Key-4','1Key-3'],80:['1Key-3','1Key-2'],82:['1Key-2','1Key-1'],85:['1Key0','1Key1'],87:['1Key1','1Key2'],90:['1Key3','1Key4'],92:['1Key4','1Key5'],94:['1Key5','1Key6'],97:['1Key6','1Key7'],99:['1Key8','1Key9'],102:['1Key10','1Key11'],104:['1Key11','1Key12'],106:['1Key12','1Key13'],},\"_C_b²\":{37:['1Key-14','1Key-13'],39:['1Key-13','1Key-12'],42:['1Key-11','1Key-10'],44:['1Key-10','1Key-9'],46:['1Key-9','1Key-8'],49:['1Key-7','1Key-6'],51:['1Key-6','1Key-5'],54:['1Key-4','1Key-3'],56:['1Key-3','1Key-2'],58:['1Key-2','1Key-1'],61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],},\"c_b³\":{49:['1Key-14','1Key-13'],51:['1Key-13','1Key-12'],54:['1Key-11','1Key-10'],56:['1Key-10','1Key-9'],58:['1Key-9','1Key-8'],61:['1Key-7','1Key-6'],63:['1Key-6','1Key-5'],66:['1Key-4','1Key-3'],68:['1Key-3','1Key-2'],70:['1Key-2','1Key-1'],73:['1Key0','1Key1'],75:['1Key1','1Key2'],78:['1Key3','1Key4'],80:['1Key4','1Key5'],82:['1Key5','1Key6'],85:['1Key6','1Key7'],87:['1Key8','1Key9'],90:['1Key10','1Key11'],92:['1Key11','1Key12'],94:['1Key12','1Key13'],},\"c¹_b⁴\":{61:['1Key-14','1Key-13'],63:['1Key-13','1Key-12'],66:['1Key-11','1Key-10'],68:['1Key-10','1Key-9'],70:['1Key-9','1Key-8'],73:['1Key-7','1Key-6'],75:['1Key-6','1Key-5'],78:['1Key-4','1Key-3'],80:['1Key-3','1Key-2'],82:['1Key-2','1Key-1'],85:['1Key0','1Key1'],87:['1Key1','1Key2'],90:['1Key3','1Key4'],92:['1Key4','1Key5'],94:['1Key5','1Key6'],97:['1Key6','1Key7'],99:['1Key8','1Key9'],102:['1Key10','1Key11'],104:['1Key11','1Key12'],106:['1Key12','1Key13'],},\"_C_b³\":{37:['1Key-14','1Key-13'],39:['1Key-13','1Key-12'],42:['1Key-11','1Key-10'],44:['1Key-10','1Key-9'],46:['1Key-9','1Key-8'],49:['1Key-7','1Key-6'],51:['1Key-6','1Key-5'],54:['1Key-4','1Key-3'],56:['1Key-3','1Key-2'],58:['1Key-2','1Key-1'],61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],85:['1Key14','1Key15'],87:['1Key15','1Key16'],90:['1Key17','1Key18'],92:['1Key18','1Key19'],94:['1Key19','1Key20'],},\"c_b⁴\":{49:['1Key-14','1Key-13'],51:['1Key-13','1Key-12'],54:['1Key-11','1Key-10'],56:['1Key-10','1Key-9'],58:['1Key-9','1Key-8'],61:['1Key-7','1Key-6'],63:['1Key-6','1Key-5'],66:['1Key-4','1Key-3'],68:['1Key-3','1Key-2'],70:['1Key-2','1Key-1'],73:['1Key0','1Key1'],75:['1Key1','1Key2'],78:['1Key3','1Key4'],80:['1Key4','1Key5'],82:['1Key5','1Key6'],85:['1Key6','1Key7'],87:['1Key8','1Key9'],90:['1Key10','1Key11'],92:['1Key11','1Key12'],94:['1Key12','1Key13'],97:['1Key14','1Key15'],99:['1Key15','1Key16'],102:['1Key17','1Key18'],104:['1Key18','1Key19'],106:['1Key19','1Key20'],},\"_C_b⁴\":{37:['1Key-14','1Key-13'],39:['1Key-13','1Key-12'],42:['1Key-11','1Key-10'],44:['1Key-10','1Key-9'],46:['1Key-9','1Key-8'],49:['1Key-7','1Key-6'],51:['1Key-6','1Key-5'],54:['1Key-4','1Key-3'],56:['1Key-3','1Key-2'],58:['1Key-2','1Key-1'],61:['1Key0','1Key1'],63:['1Key1','1Key2'],66:['1Key3','1Key4'],68:['1Key4','1Key5'],70:['1Key5','1Key6'],73:['1Key6','1Key7'],75:['1Key8','1Key9'],78:['1Key10','1Key11'],80:['1Key11','1Key12'],82:['1Key12','1Key13'],85:['1Key14','1Key15'],87:['1Key15','1Key16'],90:['1Key17','1Key18'],92:['1Key18','1Key19'],94:['1Key19','1Key20'],97:['1Key21','1Key22'],99:['1Key22','1Key23'],102:['1Key24','1Key25'],104:['1Key25','1Key26'],106:['1Key26','1Key27'],}}\n# 特殊音符的映射规则\nspecial_note_mapping = {'_C_c¹':{62:57,64:59,65:60,},'c_c²':{74:69,76:71,77:72,},'c¹_c³':{86:81,88:83,89:84,},'c²_c⁴':{98:93,100:95,101:96,},'c³_c⁵':{110:105,112:107,113:108,},\"_C_c²\":{74:69,76:71,77:72,},\"c_c³\":{86:81,88:83,89:84,},\"c¹_c⁴\":{98:93,100:95,101:96,},\"c²_c⁵\":{110:105,112:107,113:108,},\"_C_c³\":{86:81,88:83,89:84,},\"c_c⁴\":{98:93,100:95,101:96,},\"c¹_c⁵\":{110:105,112:107,113:108,},\"_C_c⁴\":{98:93,100:95,101:96,},\"c_c⁵\":{110:105,112:107,113:108,},\"_C_c⁵\":{110:105,112:107,113:108,},\"_C_b\":{62:57,64:59,},\"c_b¹\":{74:69,76:71,},\"c¹_b²\":{86:81,88:83,},\"c²_b³\":{98:93,100:95,},\"c³_b⁴\":{110:105,112:107,},\"_C_b¹\":{74:69,76:71,},\"c_b²\":{86:81,88:83,},\"c¹_b³\":{98:93,100:95,},\"c²_b⁴\":{110:105,112:107,},\"_C_b²\":{86:81,88:83,},\"c_b³\":{98:93,100:95,},\"c¹_b⁴\":{110:105,112:107,},\"_C_b³\":{98:93,100:95,},\"c_b⁴\":{110:105,112:107,},\"_C_b⁴\":{110:105,112:107,}}\n\n# 根据 BPM 动态调整时间合并阈值\ndef get_dynamic_time_merge_threshold(bpm):\n    return max(GlobalVariable.merge_min, min(GlobalVariable.merge_max, int(60000 / bpm / 4)))  # 限制阈值在 范围区间\n\n# 15 个音符与键盘按键的映射\ndef get_bpm_from_midi(midi_file_path):\n    midi = pretty_midi.PrettyMIDI(midi_file_path)\n    tempos = midi.get_tempo_changes()\n    return tempos[1][0] if len(tempos[1]) > 0 else 120\n\n\ndef merge_keys(keys):\n    key_count = len(keys)\n    return [f\"{key_count}Key{key.replace('1Key', '')}\" for key in keys]\n\n\ndef process_midi_to_txt(input_path, output_path, version):\n    midi = pretty_midi.PrettyMIDI(input_path)\n    bpm = get_bpm_from_midi(input_path)\n    time_merge_threshold = get_dynamic_time_merge_threshold(bpm)\n    notes = []\n\n    for instrument in midi.instruments:\n        if not instrument.is_drum:\n            for note in instrument.notes:\n                pitch, time, velocity= note.pitch, int(note.start * 1000), note.velocity\n                if velocity < GlobalVariable.velocity_filter:\n                    continue\n                if pitch in note_to_key[version]:\n                    notes.append({'time': time, 'key': note_to_key[version][pitch]})\n                elif GlobalVariable.semitone_switch is True and pitch in extra_note_to_key[version]:\n                    for extra_key in extra_note_to_key[version][pitch]:\n                        notes.append({'time': time, 'key': extra_key})\n                elif GlobalVariable.detail_switch is True and pitch in special_note_mapping[version]:\n                    notes.append({'time': time, 'key': note_to_key[version][special_note_mapping[version][pitch]]})\n\n    notes.sort(key=lambda x: x['time'])\n    merged_notes, last_time, temp_keys = [], None, []\n\n    for note in notes:\n        if last_time is None or note['time'] - last_time <= time_merge_threshold:\n            temp_keys.append(note['key'])\n        else:\n            merged_notes.extend({'time': last_time, 'key': k} for k in merge_keys(temp_keys))\n            temp_keys = [note['key']]\n        last_time = note['time']\n\n    merged_notes.extend({'time': last_time, 'key': k} for k in merge_keys(temp_keys))\n    output = [{\n        \"name\": os.path.basename(input_path).replace(\"_basic_pitch.mid\",\"_Range\") + version,\n        \"author\": \"skyMusic-WindHide\",\n        \"transcribedBy\": \"WindHide's Software\",\n        \"bpm\": bpm,\n        \"bitsPerPage\": 15,\n        \"pitchLevel\": 0,\n        \"isComposed\": True,\n        \"songNotes\": merged_notes,\n        \"isEncrypted\": False,\n    }]\n\n    with open(output_path, 'w') as f:\n        json.dump(output, f, indent=4)\n\n    return 100\n\n\ndef process_directory_with_progress(typeStr, output_dir=getResourcesPath(\"myTranslate\")):\n    GlobalVariable.overall_progress = 0\n    os.makedirs(output_dir, exist_ok=True)\n    files_to_process = [f for f in os.listdir(getResourcesPath(\"translateOriginalMusic\"))\n                        if f.endswith(('.mp3', '.ogg', '.wav', '.flac', '.mid', '.m4a'))]\n\n    total_files = len(files_to_process)\n    tranMap = []\n    if GlobalVariable.is_singular:\n        mapping = {\n            \"2\": [\"_C_c¹\", \"c_c²\", \"c¹_c³\", \"c²_c⁴\", \"c³_c⁵\"],\n            \"3\": [\"_C_c²\", \"c_c³\", \"c¹_c⁴\", \"c²_c⁵\"],\n            \"4\": [\"_C_c³\", \"c_c⁴\", \"c¹_c⁵\"],\n            \"5\": [\"_C_c⁴\", \"c_c⁵\"],\n            \"6\": [\"_C_c⁵\"]\n        }\n    else:\n        mapping = {\n            \"2\": [\"_C_b\",  \"c_b¹\", \"c¹_b²\", \"c²_b³\", \"c³_b⁴\"],\n            \"3\": [\"_C_b¹\", \"c_b²\", \"c¹_b³\", \"c²_b⁴\"],\n            \"4\": [\"_C_b²\", \"c_b³\", \"c¹_b⁴\"],\n            \"5\": [\"_C_b³\", \"c_b⁴\"],\n            \"6\": [\"_C_b⁴\"]\n        }\n\n    for key in mapping:\n        if key in typeStr:\n            tranMap.extend(mapping[key])\n\n    if not total_files:\n        print(\"没有找到需要处理的文件\")\n        return\n\n    if GlobalVariable.split_switch:\n        for idx, file in enumerate(files_to_process):\n            if \"_ok\" in file or \"_vocals.flac\" in file or \"_beat.flac\" in file:\n                continue\n            musicFilePath = os.path.join(getResourcesPath(\"translateOriginalMusic\"), file)\n            split_vocals(musicFilePath)  # 处理人声分离\n        files_to_process = [f for f in os.listdir(getResourcesPath(\"translateOriginalMusic\"))\n                            if f.endswith(('.mp3', '.ogg', '.wav', '.flac', '.mid', '.m4a'))]\n\n    for idx, file in enumerate(files_to_process):\n        if \"_ok\" in file:\n            continue\n\n        GlobalVariable.now_translate_text = [f\"{idx + 1}/{total_files}\", file]\n        fileNameNoEnd = file.rsplit('.', 1)[0]\n        midFilePath = os.path.join(getResourcesPath(\"translateMID\"), f\"{fileNameNoEnd}_basic_pitch\")\n        musicFilePath = os.path.join(getResourcesPath(\"translateOriginalMusic\"), file)\n\n        if not file.endswith(\".mid\"):\n            inference(input_path=musicFilePath)\n        else:\n            midFilePath = os.path.join(getResourcesPath(\"translateOriginalMusic\"), f\"{fileNameNoEnd}\")\n\n        for version in tranMap:\n            process_midi_to_txt(midFilePath + \".mid\", os.path.join(output_dir, f\"{fileNameNoEnd}_Range_{version}.txt\"),\n                                version)\n\n        new_file_path = os.path.join(getResourcesPath(\"translateOriginalMusic\"),\n                                     f\"{fileNameNoEnd}_ok.{file.split('.')[-1]}\")\n        os.rename(os.path.join(getResourcesPath(\"translateOriginalMusic\"), file), new_file_path)\n        print(f\"已将文件 {file} 重命名为 {new_file_path}\")\n        GlobalVariable.overall_progress = ((idx + 1) / total_files) * 100\n\n    GlobalVariable.overall_progress = 100\n"
  },
  {
    "path": "sky-music-server/windhide/musicToSheet/transfer_MID.py",
    "content": "from windhide.utils.path_util import getResourcesPath\n\n\ndef inference(input_path):\n    from basic_pitch import ICASSP_2022_MODEL_PATH\n    from basic_pitch.inference import predict_and_save\n    output_midi_path = getResourcesPath(\"translateMID\")\n    try:\n        predict_and_save([  input_path ],\n            output_midi_path,\n            True,\n            False,\n            False,\n            False,\n            ICASSP_2022_MODEL_PATH\n        )\n    except Exception as e:\n        print(e)\n"
  },
  {
    "path": "sky-music-server/windhide/musicToSheet/vocals_split.py",
    "content": "import os\nimport shutil\n\nimport demucs.separate\n\nfrom windhide.utils.path_util import getResourcesPath\n\ndef split_vocals(musicFilePath):\n    ffmpeg_dir = os.path.join(getResourcesPath(\"systemTools\"), \"ffmpeg\")\n\n    if not os.path.exists(os.path.join(ffmpeg_dir, \"ffmpeg.exe\")):\n        raise RuntimeError(\"FFmpeg 未找到，请确认路径正确\")\n    # 注入 PATH\n    os.environ[\"PATH\"] = ffmpeg_dir + os.pathsep + os.environ.get(\"PATH\", \"\")\n\n    os.environ['TORCH_HOME'] = os.path.join(getResourcesPath(\"systemTools\"), \"modelData\")\n    demucs.separate.main([\n        \"--flac\",\n        \"--two-stems\",\n        \"vocals\",\n        \"-o\", getResourcesPath(\"splitMusic\"),\n        \"-n\", \"mdx_extra\",\n        musicFilePath\n    ])\n    # 转换完成后\n    # 文件移动到translateOriginalMusic\n    filename = musicFilePath.split(\"\\\\\")[-1].split(\".\")[0]\n    os.path.join(getResourcesPath(\"splitMusic\"), \"mdx_extra\", filename)\n    no_vocals_path = os.path.join(getResourcesPath(\"splitMusic\"), \"mdx_extra\", filename, \"no_vocals.flac\")\n    vocals_path = os.path.join(getResourcesPath(\"splitMusic\"), \"mdx_extra\", filename, \"vocals.flac\")\n    # 移动文件\n    targetFolder = getResourcesPath(\"translateOriginalMusic\")\n    shutil.move(no_vocals_path, f\"{targetFolder}/{filename + '_beat.flac'}\")\n    shutil.move(vocals_path, f\"{targetFolder}/{filename + '_vocals.flac'}\")\n    shutil.rmtree(os.path.join(getResourcesPath(\"splitMusic\"), \"mdx_extra\", filename))  # 删除子文件夹\n"
  },
  {
    "path": "sky-music-server/windhide/playRobot/amd_robot.py",
    "content": "import ctypes\nimport threading\nimport time\nfrom ctypes import windll\n\nimport keyboard\nimport pyautogui\nimport win32con\nimport win32gui\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.thread.amd_play_thread import ControlledThread\nfrom windhide.utils.path_util import convert_notes_to_delayed_format, convert_json_to_play\n\nPostMessageW = windll.user32.PostMessageW # ok 消息队列\nSendMessageW = windll.user32.SendMessageW # ok 立即处理\nMapVirtualKeyW = windll.user32.MapVirtualKeyW\nVkKeyScanW = windll.user32.VkKeyScanW\nuser32 = ctypes.windll.user32\n\nWM_KEYDOWN = 0x100\nWM_KEYUP = 0x101\npyautogui.FAILSAFE = False\n\ndef send_single_key_to_window_task(key, duration):\n    \"\"\"发送单个按键，减少延迟\"\"\"\n    key_down(key)\n    time.sleep(duration/1000 + GlobalVariable.duration)\n    key_up(key)\n\ndef send_multiple_key_to_window_task(keys, duration):\n    \"\"\"发送组合按键，减少延迟\"\"\"\n    for key in keys:\n        key_down(key)\n    time.sleep(duration/1000 + GlobalVariable.duration)\n    for key in keys:\n        key_up(key)\n\n\n#  这里是跟弹独立出来的\ndef send_multiple_key_press(keys):\n    for key in keys:\n        keyboard.press(key)\n\n\ndef send_multiple_key_release(keys):\n    for key in keys:\n        keyboard.release(key)\n\n\n# 现在给模拟器和跟弹在用了\ndef send_single_key_to_window_follow(key, duration):\n    \"\"\"发送单个按键，减少延迟\"\"\"\n    keyboard.press(key)\n    time.sleep(duration/1000 + GlobalVariable.duration)\n    keyboard.release(key)\n\n # 现在给模拟器和跟弹在用了\ndef send_multiple_key_to_window_follow(keys, duration):\n    \"\"\"发送组合按键，减少延迟\"\"\"\n    for key in keys:\n        keyboard.press(key)\n    time.sleep(duration/1000 + GlobalVariable.duration)\n    for key in keys:\n        keyboard.release(key)\n\ndef execute_in_thread(target, *args, **kwargs):\n    \"\"\"通用线程执行器，采用线程池管理\"\"\"\n    thread = threading.Thread(target=target, args=args, kwargs=kwargs)\n    thread.daemon = True  # 将线程设置为守护线程，程序退出时自动结束线程\n    thread.start()\n    return thread\n\ndef send_single_key_to_window(key, duration):\n    \"\"\"发送单个按键（新线程中执行）\"\"\"\n    if GlobalVariable.compatibility_mode:\n        execute_in_thread(send_single_key_to_window_follow, key,duration)\n    else:\n        execute_in_thread(send_single_key_to_window_task, key,duration)\n\ndef send_multiple_key_to_window(keys, duration):\n    \"\"\"发送组合按键（新线程中执行）\"\"\"\n    if GlobalVariable.compatibility_mode:\n        execute_in_thread(send_multiple_key_to_window_follow, keys,duration)\n    else:\n        execute_in_thread(send_multiple_key_to_window_task, keys,duration)\n\ndef playMusic(fileName, type):\n    \"\"\"优化音乐播放逻辑，只加载乐谱数据一次\"\"\"\n    convert_notes_to_delayed_format(fileName, type)\n    if GlobalVariable.thread is not None:\n        stop()\n    GlobalVariable.thread = ControlledThread()\n    GlobalVariable.thread.start()\n\ndef playMusic_edit(text):\n    \"\"\"优化音乐播放逻辑，只加载乐谱数据一次\"\"\"\n    convert_json_to_play(text)\n    if GlobalVariable.thread is not None:\n        stop()\n    GlobalVariable.thread = ControlledThread()\n    GlobalVariable.thread.start()\n\ndef resume():\n    \"\"\"恢复播放\"\"\"\n    if GlobalVariable.thread:\n        GlobalVariable.thread.resume()\n\ndef pause():\n    \"\"\"暂停播放\"\"\"\n    if GlobalVariable.thread:\n        GlobalVariable.thread.pause()\n\ndef stop():\n    \"\"\"停止播放\"\"\"\n    if GlobalVariable.thread:\n        GlobalVariable.thread.stop()\n        GlobalVariable.set_progress = 0\n        GlobalVariable.thread = None\n\n\n#  点击，按下\n\ndef mouse_move_to(x: int, y: int):\n    # 获取窗口的屏幕位置\n    window_rect = win32gui.GetWindowRect(GlobalVariable.window[\"hWnd\"])  # 返回 (left, top, right, bottom)\n    window_x, window_y = window_rect[0], window_rect[1]\n    client_x = window_x + x\n    client_y = window_y + y\n    win32gui.SendMessage(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    pyautogui.moveTo(client_x, client_y, duration=0)\n\n#  核心\ndef key_press(key: str):\n    key = key.lower()\n    if key in special_keys:\n        vk_code, scan_code = special_keys[key]\n    else:\n        # 普通按键的处理\n        vk_code = VkKeyScanW(ctypes.c_wchar(key))\n        scan_code = keyboard.key_to_scan_codes(key)[0] if key != '/' else keyboard.key_to_scan_codes(key)[1]\n    lparam = (scan_code << 16) | 1\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        PostMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYDOWN, vk_code, lparam)\n        time.sleep(0.01)\n        PostMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYUP, vk_code, lparam)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        SendMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYDOWN, vk_code, lparam)\n        time.sleep(0.01)\n        SendMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYUP, vk_code, lparam)\n\ndef key_down(key: str):\n    set_us_keyboard_layout()\n    key = key.lower()\n    if key in special_keys:\n        vk_code, scan_code = special_keys[key]\n    else:\n        # 普通按键的处理\n        vk_code = VkKeyScanW(ctypes.c_wchar(key))\n        scan_code = keyboard.key_to_scan_codes(key)[0] if key != '/' else keyboard.key_to_scan_codes(key)[1]\n    lparam = (scan_code << 16) | 1\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        PostMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYDOWN, vk_code, lparam)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        SendMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYDOWN, vk_code, lparam)\n\ndef key_up(key: str):\n    set_us_keyboard_layout()\n    key = key.lower()\n    if key in special_keys:\n        vk_code, scan_code = special_keys[key]\n    else:\n        # 普通按键的处理\n        vk_code = VkKeyScanW(ctypes.c_wchar(key))\n        scan_code = keyboard.key_to_scan_codes(key)[0] if key != '/' else keyboard.key_to_scan_codes(key)[1]\n    lparam = (scan_code << 16) | 0XC0000001\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        PostMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYUP, vk_code, lparam)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        SendMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYUP, vk_code, lparam)\n\ndef mouse_wheel_scroll(operator):\n    match operator:\n        case 'up':\n            delta =  3000\n        case 'down':\n            delta = -3000\n    window_rect = win32gui.GetWindowRect(GlobalVariable.window[\"hWnd\"])  # 返回 (left, top, right, bottom)\n    # 窗口中心\n    window_x, window_y = window_rect[0] + window_rect[0] / 2, window_rect[1] + window_rect[1] / 2\n    # 激活窗口\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    pyautogui.moveTo(window_x, window_y)\n    pyautogui.scroll(delta)\n\n\ndef set_us_keyboard_layout():\n    # LoadKeyboardLayoutW 函数的定义\n    user32.LoadKeyboardLayoutW.argtypes = [ctypes.c_wchar_p, ctypes.c_uint]\n    user32.LoadKeyboardLayoutW.restype = ctypes.c_void_p\n    user32.LoadKeyboardLayoutW(\"00000409\", 1)  # 0409 是美国键盘布局标识符，1 表示激活\n\nspecial_keys = {\n    'space': (0x20, 0x39),  # 空格键\n    'tab': (0x09, 0x0F),    # Tab 键\n    'esc': (0x1B, 0x01),    # Escape 键\n    'shift': (0x10, 0x2A),  # 左 Shift 键\n    'right': (0x27, 0x4D),  # 方向键右\n    'left': (0x25, 0x4B),   # 方向键左\n    'up': (0x26, 0x48),     # 方向键上\n    'down': (0x28, 0x50)    # 方向键下\n}\n"
  },
  {
    "path": "sky-music-server/windhide/playRobot/intel_robot.py",
    "content": "import ctypes\nimport time\n\nimport keyboard\nimport pyautogui\nimport win32con\nimport win32gui\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.thread.intel_play_thread import ControlledThread\nfrom windhide.utils.path_util import convert_notes_to_delayed_format, convert_json_to_play\n\nPostMessageW = ctypes.windll.user32.PostMessageW  # 消息队列\nSendMessageW = ctypes.windll.user32.SendMessageW  # 立即处理\nMapVirtualKeyW = ctypes.windll.user32.MapVirtualKeyW\nVkKeyScanW = ctypes.windll.user32.VkKeyScanW\nuser32 = ctypes.windll.user32\n\nWM_KEYDOWN = 0x100\nWM_KEYUP = 0x101\npyautogui.FAILSAFE = False\n\ndef send_single_key_to_window_task(key, duration):\n    \"\"\"发送单个按键，减少延迟\"\"\"\n    key_down(key)\n    time.sleep(duration/1000 + GlobalVariable.duration)\n    key_up(key)\n\ndef send_multiple_key_to_window_task(keys, duration):\n    \"\"\"发送组合按键，减少延迟\"\"\"\n    for key in keys:\n        key_down(key)\n    time.sleep(duration/1000 + GlobalVariable.duration)\n    for key in keys:\n        key_up(key)\n\ndef send_single_key_to_window(key, duration):\n    \"\"\"发送单个按键（单线程）\"\"\"\n    if GlobalVariable.compatibility_mode:\n        send_single_key_to_window_follow(key, duration)\n    else:\n        send_single_key_to_window_task(key, duration)\n\ndef send_multiple_key_to_window(keys, duration):\n    \"\"\"发送组合按键（单线程）\"\"\"\n    if GlobalVariable.compatibility_mode:\n        send_multiple_key_to_window_follow(keys, duration)\n    else:\n        send_multiple_key_to_window_task(keys, duration)\n\ndef send_single_key_to_window_follow(key, duration):\n    \"\"\"发送单个按键，减少延迟（单线程）\"\"\"\n    keyboard.press(key)\n    time.sleep(duration/1000 + GlobalVariable.duration)\n    keyboard.release(key)\n\ndef send_multiple_key_to_window_follow(keys, duration):\n    \"\"\"发送组合按键，减少延迟（单线程）\"\"\"\n    for key in keys:\n        keyboard.press(key)\n    time.sleep(duration/1000 + GlobalVariable.duration)\n    for key in keys:\n        keyboard.release(key)\n\ndef playMusic(fileName, type):\n    \"\"\"优化音乐播放逻辑，只加载乐谱数据一次\"\"\"\n    convert_notes_to_delayed_format(fileName, type)\n    if GlobalVariable.thread is not None:\n        stop()\n    GlobalVariable.thread = ControlledThread()\n    GlobalVariable.thread.start()\n\ndef playMusic_edit(text):\n    \"\"\"优化音乐播放逻辑，只加载乐谱数据一次\"\"\"\n    convert_json_to_play(text)\n    if GlobalVariable.thread is not None:\n        stop()\n    GlobalVariable.thread = ControlledThread()\n    GlobalVariable.thread.start()\n\ndef resume():\n    \"\"\"恢复播放\"\"\"\n    if GlobalVariable.thread:\n        GlobalVariable.thread.resume()\n\ndef pause():\n    \"\"\"暂停播放\"\"\"\n    if GlobalVariable.thread:\n        GlobalVariable.thread.pause()\n\ndef stop():\n    \"\"\"停止播放\"\"\"\n    if GlobalVariable.thread:\n        GlobalVariable.thread.stop()\n        GlobalVariable.set_progress = 0\n        GlobalVariable.thread = None\n\n# 点击，按下\ndef mouse_move_to(x: int, y: int):\n    # 获取窗口的屏幕位置\n    window_rect = win32gui.GetWindowRect(GlobalVariable.window[\"hWnd\"])  # 返回 (left, top, right, bottom)\n    window_x, window_y = window_rect[0], window_rect[1]\n    client_x = window_x + x\n    client_y = window_y + y\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    pyautogui.moveTo(client_x, client_y, duration=0)\n\n# 核心\ndef key_press(key: str):\n    key = key.lower()\n    if key in special_keys:\n        vk_code, scan_code = special_keys[key]\n    else:\n        # 普通按键的处理\n        vk_code = VkKeyScanW(ctypes.c_wchar(key))\n        scan_code = keyboard.key_to_scan_codes(key)[0] if key != '/' else keyboard.key_to_scan_codes(key)[1]\n    lparam = (scan_code << 16) | 1\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        PostMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYDOWN, vk_code, lparam)\n        time.sleep(0.01)\n        PostMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYUP, vk_code, lparam)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        SendMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYDOWN, vk_code, lparam)\n        time.sleep(0.01)\n        SendMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYUP, vk_code, lparam)\n\ndef key_down(key: str):\n    set_us_keyboard_layout()\n    key = key.lower()\n    if key in special_keys:\n        vk_code, scan_code = special_keys[key]\n    else:\n        # 普通按键的处理\n        vk_code = VkKeyScanW(ctypes.c_wchar(key))\n        scan_code = keyboard.key_to_scan_codes(key)[0] if key != '/' else keyboard.key_to_scan_codes(key)[1]\n    lparam = (scan_code << 16) | 1\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        PostMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYDOWN, vk_code, lparam)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        SendMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYDOWN, vk_code, lparam)\n\ndef key_up(key: str):\n    key = key.lower()\n    if key in special_keys:\n        vk_code, scan_code = special_keys[key]\n    else:\n        # 普通按键的处理\n        vk_code = VkKeyScanW(ctypes.c_wchar(key))\n        scan_code = keyboard.key_to_scan_codes(key)[0] if key != '/' else keyboard.key_to_scan_codes(key)[1]\n    lparam = (scan_code << 16) | 0XC0000001\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        PostMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYUP, vk_code, lparam)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n        SendMessageW(GlobalVariable.window[\"hWnd\"], WM_KEYUP, vk_code, lparam)\n\ndef mouse_wheel_scroll(operator):\n    match operator:\n        case 'up':\n            delta =  3000\n        case 'down':\n            delta = -3000\n    window_rect = win32gui.GetWindowRect(GlobalVariable.window[\"hWnd\"])  # 返回 (left, top, right, bottom)\n    # 窗口中心\n    window_x, window_y = window_rect[0] + window_rect[0] / 2, window_rect[1] + window_rect[1] / 2\n    # 激活窗口\n    if GlobalVariable.is_post_w:\n        PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    else:\n        SendMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    pyautogui.moveTo(window_x, window_y)\n    pyautogui.scroll(delta)\n\ndef set_us_keyboard_layout():\n    # LoadKeyboardLayoutW 函数的定义\n    user32.LoadKeyboardLayoutW.argtypes = [ctypes.c_wchar_p, ctypes.c_uint]\n    user32.LoadKeyboardLayoutW.restype = ctypes.c_void_p\n    user32.LoadKeyboardLayoutW(\"00000409\", 1)  # 0409 是美国键盘布局标识符，1 表示激活\n\nspecial_keys = {\n    'space': (0x20, 0x39),  # 空格键\n    'tab': (0x09, 0x0F),    # Tab 键\n    'esc': (0x1B, 0x01),    # Escape 键\n    'shift': (0x10, 0x2A),  # 左 Shift 键\n    'right': (0x27, 0x4D),  # 方向键右\n    'left': (0x25, 0x4B),   # 方向键左\n    'up': (0x26, 0x48),     # 方向键上\n    'down': (0x28, 0x50)    # 方向键下\n}\n"
  },
  {
    "path": "sky-music-server/windhide/static/global_variable.py",
    "content": "class GlobalVariable:\n    # 运行环境配置\n    isProd = False\n    cpu_type = None\n    compatibility_mode = False  # 是否虚拟机\n    is_post_w = False  # 是否插队模式\n\n    duration_prompt = \"\"\"你现在是一个音乐数据生成器，不是聊天助手。\n\n🎼 输入是一首歌曲的音符数据，格式为一个 JSON 数组，每个元素如下：\n{\"time\":0,\"key\":\"1Key10\",\"duration\":400}\n\n解释：\n- `time` 表示时间，单位为毫秒。\n- `key` 表示音符键名，格式为 `{轨道号}Key{音高编号}`。\n- `轨道号` 是数字，如 `1` 或 `2`，表示旋律或和声的分轨。\n- `duration` 表示这个音要持续的时长（单位毫秒，最少 300 毫秒）。\n- `音高编号` 必须从下表中选择：\n\n| 编号 | keyN   | 对应音高        |\n|------|--------|-----------------|\n|  0   | Key0   | C4 (MIDI 60)    |\n|  1   | Key1   | D4 (62)         |\n|  2   | Key2   | E4 (64)         |\n|  3   | Key3   | F4 (65)         |\n|  4   | Key4   | G4 (67)         |\n|  5   | Key5   | A4 (69)         |\n|  6   | Key6   | B4 (71)         |\n|  7   | Key7   | C5 (72)         |\n|  8   | Key8   | D5 (74)         |\n|  9   | Key9   | E5 (76)         |\n| 10   | Key10  | F5 (77)         |\n| 11   | Key11  | G5 (79)         |\n| 12   | Key12  | A5 (81)         |\n| 13   | Key13  | B5 (83)         |\n| 14   | Key14  | C6 (84)         |\n\n🧠 你的任务：\n- 对原始旋律进行改编，使旋律更自然流畅。\n- 添加或修改 `duration` 字段。\n- **允许自由发挥，增加音符数量不得少于原始音符总数，鼓励适度创新和变化。**\n- 避免长时间重复相同旋律，保证整体音乐连贯性。\n- 生成的 `time` 应合理反映节奏，避免毫秒级零散断裂，建议保持符合歌曲节拍风格。\n- 轨道号代表不同声部，1号轨道为主旋律，2号轨道为和声伴奏，可适当调整和声层次。\n- 同一时间点最多同时按下3个不同音符，保持和声自然。\n- 每次输出最多 40 个完整 JSON 元素，不允许跨元素截断。\n- 每个元素结构严格为：`{\"time\":x,\"key\":\"xKeyx\",\"duration\":x},`\n- 所有 `key` 必须严格来自上方表格（含轨道前缀，如 `\"1Key4\"`）。\n- 如果多个音符同时按下，使用相同的 `time` 和不同的 `key`。\n- 允许对不合理音节进行改造，使其更符合音乐逻辑。\n\n🧩 输出格式要求：\n- 每次输出仅包含中间段 JSON 元素，不输出 `[` 或 `]`。\n- 每次输出第一行必须注明：`第 N 段（共预计 M 段）`\n- 输出不得包含除 JSON 结构外的任何注释、说明或总结语。\n- 不得说“已完成”、“以下是输出”、“JSON 完整”等总结语。\n\n🪛 响应规范：\n- 保证每个 JSON 对象都闭合（不能残缺或中断）。\n- 禁止输出非 `{\"time\":,\"key\":}` 格式的字段。\n- 当我回复“继续”，你只输出**上一次后的 JSON 段落**，禁止重复。\n- 你不能停止任务，除非我显式让你“停止”。\n\n🎵 准备开始时，我会提供原始 JSON 数据，你必须根据以上规范对其改编并分段输出。\n\n示例输出片段：\n第 1 段（共预计 10 段）\n{\"time\":0,\"key\":\"1Key10\",\"duration\":400},{\"time\":250,\"key\":\"1Key12\",\"duration\":120},{\"time\":250,\"key\":\"2Key4\",\"duration\":200},{\"time\":500,\"key\":\"1Key14\",\"duration\":300},\n{\"time\":750,\"key\":\"1Key13\",\"duration\":312},{\"time\":1000,\"key\":\"1Key11\",\"duration\":313},{\"time\":1250,\"key\":\"1Key9\",\"duration\":421},{\"time\":1250,\"key\":\"2Key7\",\"duration\":436},\n{\"time\":1500,\"key\":\"1Key10\",\"duration\":332},{\"time\":1750,\"key\":\"1Key12\",\"duration\":315}\"\"\"\n\n\n\n    translate_prompt = \"\"\"你现在是一个音乐数据生成器，不是聊天助手。\n\n🎼 输入是一首歌曲的音符数据，格式为一个 JSON 数组，每个元素如下：\n{\"time\":0,\"key\":\"1Key10\"}\n\n解释：\n- `time` 表示时间，单位为毫秒。\n- `key` 表示音符键名，格式为 `{轨道号}Key{音高编号}`。\n- `轨道号` 是数字，如 `1` 或 `2`，表示旋律或和声的分轨。\n- `音高编号` 必须从下表中选择：\n\n| 编号 | keyN   | 对应音高        |\n|------|--------|-----------------|\n|  0   | Key0   | C4 (MIDI 60)    |\n|  1   | Key1   | D4 (62)         |\n|  2   | Key2   | E4 (64)         |\n|  3   | Key3   | F4 (65)         |\n|  4   | Key4   | G4 (67)         |\n|  5   | Key5   | A4 (69)         |\n|  6   | Key6   | B4 (71)         |\n|  7   | Key7   | C5 (72)         |\n|  8   | Key8   | D5 (74)         |\n|  9   | Key9   | E5 (76)         |\n| 10   | Key10  | F5 (77)         |\n| 11   | Key11  | G5 (79)         |\n| 12   | Key12  | A5 (81)         |\n| 13   | Key13  | B5 (83)         |\n| 14   | Key14  | C6 (84)         |\n\n🧠 你的任务：\n- 对原始旋律进行改编，使旋律更自然流畅。\n- **允许自由发挥，增加音符数量不得少于原始音符总数，鼓励适度创新和变化。**\n- 避免长时间重复相同旋律，保证整体音乐连贯性。\n- 生成的 `time` 应合理反映节奏，避免毫秒级零散断裂，建议保持符合歌曲节拍风格。\n- 轨道号代表不同声部，1号轨道为主旋律，2号轨道为和声伴奏，可适当调整和声层次。\n- 同一时间点最多同时按下3个不同音符，保持和声自然。\n- 每次输出最多 40 个完整 JSON 元素，不允许跨元素截断。\n- 每个元素结构严格为：`{\"time\":1234,\"key\":\"xKeyN\"},`\n- 所有 `key` 必须严格来自上方表格（含轨道前缀，如 `\"1Key4\"`）。\n- 如果多个音符同时按下，使用相同的 `time` 和不同的 `key`。\n- 允许对不合理音节进行改造，使其更符合音乐逻辑。\n\n🧩 输出格式要求：\n- 每次输出仅包含中间段 JSON 元素，不输出 `[` 或 `]`。\n- 每次输出第一行必须注明：`第 N 段（共预计 M 段）`\n- 输出不得包含除 JSON 结构外的任何注释、说明或总结语。\n- 不得说“已完成”、“以下是输出”、“JSON 完整”等总结语。\n\n🪛 响应规范：\n- 保证每个 JSON 对象都闭合（不能残缺或中断）。\n- 禁止输出非 `{\"time\":,\"key\":}` 格式的字段。\n- 当我回复“继续”，你只输出**上一次后的 JSON 段落**，禁止重复。\n- 你不能停止任务，除非我显式让你“停止”。\n\n🎵 准备开始时，我会提供原始 JSON 数据，你必须根据以上规范对其改编并分段输出。\n\n示例输出片段：\n第 1 段（共预计 10 段）\n{\"time\":0,\"key\":\"1Key10\"},{\"time\":250,\"key\":\"1Key12\"},{\"time\":250,\"key\":\"2Key4\"},{\"time\":500,\"key\":\"1Key14\"},\n{\"time\":750,\"key\":\"1Key13\"},{\"time\":1000,\"key\":\"1Key11\"},{\"time\":1250,\"key\":\"1Key9\"},{\"time\":1250,\"key\":\"2Key7\"},\n{\"time\":1500,\"key\":\"1Key10\"},{\"time\":1750,\"key\":\"1Key12\"}\"\"\"\n\n    general_ai = {\n        # \"Kimi\":{\n        #     \"key\": \"sk-sfpR8uS6S0puwi3d758viFNLrPmXTwDyhoecDEEIorX49bbr\",\n        #     \"url\": \"https://api.moonshot.cn/v1\",\n        #     \"model\": \"moonshot-v1-128k\",\n        # } ,\n        # \"Qwen\":{\n        #     \"key\": \"sk-99dae6996fb24d62a85a4e5b68c5619e\",\n        #     \"url\": \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n        #     \"model\": \"qwen-turbo-latest\",\n        # }\n    }\n\n    # 窗口相关\n    is_custom_hwnd = False\n    hwnd_title = \"Sky.exe\"\n    hwnd_select_struct = {}\n    window = {\n        \"hWnd\": None,\n        \"width\": 0,\n        \"height\": 0,\n        \"position_x\": 0,\n        \"position_y\": 0,\n        \"is_change\": False,\n        \"key_position\": None,\n        \"wait\": False\n    }\n\n    # 快捷键相关\n    shortcutStruct = {\n        \"follow_key\":{\n            \"tap_key\": \"yuiophjkl;nm,./\",\n            \"string\": \"-=q\",\n            \"repeat\": \"-\",\n            \"repeat_next\": '=',\n            \"resize\": \"q\",\n            \"exit\": \"esc\"\n        },\n        \"music_key\":{\n            \"string\": \"f2f5f6f7f8updownleftrightpage_uppage_down\",\n            \"next\": \"f2\",\n            \"start\": \"f5\",\n            \"resume\": \"f6\",\n            \"pause\": \"f7\",\n            \"stop\": \"f8\",\n            \"add_duration\": \"up\",\n            \"reduce_duration\": \"down\",\n            \"add_delay\": \"right\",\n            \"reduce_delay\": \"left\",\n            \"add_speed\": \"page_up\",\n            \"reduce_speed\": \"page_down\",\n        }\n    }\n    # 线程相关\n    thread = None\n    auto_thread = None\n    task_queue = None\n\n    # 乐谱相关\n    music_sheet = []  # 乐谱\n\n    # 进度条相关\n    now_progress = 0  # 进度条\n    set_progress = -0.01  # 进度条\n    now_play_music = \"没有正在播放的歌曲哦\"\n    now_total_time = \"\"\n    now_current_time = \"\"\n\n    # 音乐转换进度条\n    overall_progress = 0  # 总体进度\n    now_translate_text = []\n    merge_min = 20\n    merge_max = 30\n    velocity_filter = 10\n    is_singular = True\n    semitone_switch = True # 半音转换开关\n    detail_switch = True # 超3音转换开关\n    split_switch = False # 人声分离开关\n\n    # 演奏相关\n    play_speed = 1  # 倍速\n    delay_interval = 0  # 0\n    duration = 0  # 20毫秒\n\n    # 跟弹相关\n    follow_music = \"\"\n    follow_sheet = []\n    nowClientKey = \"\"\n    nowRobotKey = \"\"\n    follow_client = None\n    isNowAutoPlaying = False\n    follow_thread = None  # 跟弹按键处理相关线程\n    exit_flag = False\n    draw_process = None\n    window_offset_x = 0\n    window_offset_y = 0\n    follow_process = None\n    sheld = 0.7\n    # 乐谱映射\n    keyMap = {\n        'Key-14': '', 'Key-13': '', 'Key-12': '', 'Key-11': '', 'Key-10': '', 'Key-9': '', 'Key-8': '',\n        'Key-7': '', 'Key-6': '', 'Key-5': '', 'Key-4': '', 'Key-3': '', 'Key-2': '', 'Key-1': '',\n        'Key0': 'y', 'Key1': 'u', 'Key2': 'i', 'Key3': 'o', 'Key4': 'p', 'Key5': 'h', 'Key6': 'j',\n        'Key7': 'k', 'Key8': 'l', 'Key9': ';', 'Key10': 'n', 'Key11': 'm', 'Key12': ',', 'Key13': '.',\n        'Key14': '/', 'Key15': '', 'Key16': '', 'Key17': '', 'Key18': '', 'Key19': '', 'Key20': '',\n        'Key21': '', 'Key22': '', 'Key23': '', 'Key24': '', 'Key25': '', 'Key26': '', 'Key27': '',\n        'Key28': ''\n    }\n"
  },
  {
    "path": "sky-music-server/windhide/thread/amd_play_thread.py",
    "content": "import math\nimport threading\nimport time\n\nfrom windhide.playRobot import amd_robot\nfrom windhide.static.global_variable import GlobalVariable\n\n\nclass ControlledThread:\n    def __init__(self):\n        self._pause_event = threading.Event()\n        self._pause_event.set()  # 初始状态允许运行\n        self._thread = None\n        self._running = False\n\n    def _run(self):\n        if not GlobalVariable.music_sheet:\n            self.stop()\n            return\n\n        local_music_sheet = GlobalVariable.music_sheet[:]\n        total_length = 1 if len(local_music_sheet) == 1 else len(local_music_sheet) - 1\n        index = 0\n\n        # 在播放开始时计算总时长（单位为毫秒）\n        total_time = sum(sheet[\"delay\"] for sheet in local_music_sheet)\n        GlobalVariable.now_total_time = self.format_time(total_time)\n        current_time = 0  # 当前时间（单位为毫秒）\n\n        while self._running and index < len(local_music_sheet):\n            self._pause_event.wait()  # 等待恢复运行\n\n            if GlobalVariable.set_progress != -0.01:\n                index = math.floor(total_length * GlobalVariable.set_progress)\n                GlobalVariable.set_progress = -0.01\n                current_time = total_time * (index / total_length)  # 调整当前时间\n                continue\n\n            sheet = local_music_sheet[index]\n            keys = sheet[\"key\"]\n            delay = sheet[\"delay\"] / GlobalVariable.play_speed\n            if total_length == 0:\n                GlobalVariable.now_progress = 100\n            else:\n                GlobalVariable.now_progress = (index / total_length) * 100\n            if keys:\n                (amd_robot.send_single_key_to_window if len(keys) == 1\n                 else amd_robot.send_multiple_key_to_window)(keys, sheet[\"duration\"] if \"duration\" in sheet else 0)\n\n            time.sleep(delay / 1000 + GlobalVariable.delay_interval)\n            # 格式化当前时间/总时间\n            # formatted_time = self.format_time(current_time) + \" / \" + self.format_time(total_time)\n            # print(f\"播放时间：{formatted_time}\", end=\"\\r\")\n            GlobalVariable.now_current_time = self.format_time(current_time)\n            current_time += delay  # 更新当前时间\n            index += 1\n\n    def format_time(self, milliseconds):\n        \"\"\"\n        将毫秒数格式化为时分秒格式（HH:MM:SS 或 MM:SS）\n        \"\"\"\n        seconds = milliseconds / 1000\n        hours, remainder = divmod(seconds, 3600)\n        minutes, seconds = divmod(remainder, 60)\n\n        if hours > 0:\n            return f\"{int(hours):02}:{int(minutes):02}:{int(seconds):02}\"\n        else:\n            return f\"{int(minutes):02}:{int(seconds):02}\"\n\n    def start(self):\n        if self._running:\n            return\n        self._running = True\n        if self._thread and self._thread.is_alive():\n            self._thread.join()\n        self._thread = threading.Thread(target=self._run, daemon=True)\n        self._thread.start()\n\n    def pause(self):\n        self._pause_event.clear()\n\n    def resume(self):\n        self._pause_event.set()\n\n    def stop(self):\n        self._running = False\n        self.resume()  # 避免暂停状态导致的死锁\n        if self._thread and self._thread.is_alive():\n            self._thread.join()\n        self._thread = None\n"
  },
  {
    "path": "sky-music-server/windhide/thread/follow_process_thread.py",
    "content": "import os\nimport subprocess\n\nimport psutil\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils.ocr_normal_utils import get_game_position\nfrom windhide.utils.path_util import getResourcesPath\n\nGlobalVariable.draw_process = None  # 进程对象\n\n\ndef run_follow_process():\n    try:\n        x1, y1, x2, y2 = get_game_position()\n        width, height = x2 - x1, y2 - y1\n\n        GlobalVariable.draw_process = subprocess.Popen(\n            [\n                os.path.join(getResourcesPath(\"systemTools\"), \"drawTool\", \"draw_server.exe\"),\n                f\"--width={width}\",\n                f\"--height={height}\",\n                f\"--x={x1}\",\n                f\"--y={y1}\",\n            ],\n            creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,  # 独立进程组，便于管理\n        )\n    except (FileNotFoundError, subprocess.SubprocessError):\n        pass  # 直接忽略异常，避免冗余输出\n\ndef stop_follow_process():\n    \"\"\"彻底终止 draw_server.exe 及其所有子进程\"\"\"\n    process = GlobalVariable.draw_process\n    if process and process.poll() is None:\n        try:\n            parent = psutil.Process(process.pid)\n            children = parent.children(recursive=True)\n\n            for child in children:\n                child.terminate()\n\n            _, still_alive = psutil.wait_procs(children, timeout=5)\n            for child in still_alive:\n                child.kill()\n\n            parent.terminate()\n            parent.wait(5)\n\n            GlobalVariable.draw_process = None  # 清理进程记录\n        except psutil.NoSuchProcess:\n            pass\n        except Exception:\n            pass\n"
  },
  {
    "path": "sky-music-server/windhide/thread/follow_thread.py",
    "content": "import time\nfrom os import path\n\nimport plyer\nfrom pynput import keyboard\n\nfrom windhide.playRobot.amd_robot import send_multiple_key_press, send_multiple_key_release\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils import hook_util\nfrom windhide.utils.command_util import resize_and_reload_key, clear_window_key, add_window_key, \\\n    quit_window, update_key\nfrom windhide.utils.path_util import getResourcesPath\n\nhook_util.sout_null()\n\nGlobalVariable.exit_flag = False  # 添加全局退出标志\noriginalKeys = \"None\"\npressedKeys = set()\n\ndef get_key_string(key):\n    if hasattr(key, \"char\") and key.char is not None:  # 处理普通字符按键\n        return key.char\n    elif hasattr(key, \"name\"):  # 处理特殊按键\n        return key.name\n    else:\n        return str(key)  # 兜底方案，转换为字符串\n\ndef on_press(key):\n    global pressedKeys, originalKeys\n    if GlobalVariable.exit_flag:\n        return False  # 终止监听\n    if GlobalVariable.follow_music != \"\":\n        try:\n            key = get_key_string(key)\n            if key in GlobalVariable.shortcutStruct[\"follow_key\"][\"string\"] or key in GlobalVariable.shortcutStruct[\"follow_key\"][\"tap_key\"]:\n                if GlobalVariable.isNowAutoPlaying:\n                    if key not in GlobalVariable.shortcutStruct[\"follow_key\"][\"repeat\"]:\n                        GlobalVariable.nowRobotKey += key\n                    if len(GlobalVariable.nowRobotKey) == len(GlobalVariable.nowClientKey):\n                        GlobalVariable.isNowAutoPlaying = False\n                        GlobalVariable.nowRobotKey = ''\n                else:\n                    if key in GlobalVariable.shortcutStruct[\"follow_key\"][\"repeat\"]:\n                        GlobalVariable.isNowAutoPlaying = True\n                        send_multiple_key_press(GlobalVariable.nowClientKey)\n                    if key in GlobalVariable.shortcutStruct[\"follow_key\"][\"repeat_next\"]:\n                        send_multiple_key_press(GlobalVariable.nowClientKey)\n        except Exception as e:\n            print(f\"发生错误: {e.__doc__} , 开始重新加载\")\n\n    # 处理 Esc 退出监听\n    if key == GlobalVariable.shortcutStruct[\"follow_key\"][\"exit\"] or  key == \"alt_l\":\n        print(\"检测到 Esc 键，退出监听...\")\n        GlobalVariable.exit_flag = True  # 设置全局标志\n        try:\n            quit_window()\n        except Exception as e:\n            return False\n        return False  # 停止监听\n\n\ndef key_release(key):\n    global pressedKeys, originalKeys\n    if GlobalVariable.exit_flag:\n        return False  # 终止监听\n    if GlobalVariable.follow_music != \"\":\n        try:\n            key = get_key_string(key)\n            if key in GlobalVariable.shortcutStruct[\"follow_key\"][\"string\"] or key in GlobalVariable.shortcutStruct[\"follow_key\"][\"tap_key\"]:\n                if GlobalVariable.isNowAutoPlaying:\n                    if key not in GlobalVariable.shortcutStruct[\"follow_key\"][\"repeat\"]:\n                        GlobalVariable.nowRobotKey += key\n                    if len(GlobalVariable.nowRobotKey) == len(GlobalVariable.nowClientKey):\n                        GlobalVariable.isNowAutoPlaying = False\n                        GlobalVariable.nowRobotKey = ''\n                else:\n                    if key in GlobalVariable.shortcutStruct[\"follow_key\"][\"repeat\"]:\n                        GlobalVariable.isNowAutoPlaying = True\n                        send_multiple_key_release(GlobalVariable.nowClientKey)\n                    if key in GlobalVariable.shortcutStruct[\"follow_key\"][\"repeat_next\"]:\n                        send_multiple_key_release(GlobalVariable.nowClientKey)\n                    if key in GlobalVariable.shortcutStruct[\"follow_key\"][\"resize\"]:\n                        resize_and_reload_key()\n                    else:\n                        if key in originalKeys:\n                            pressedKeys.add(key)\n                        if len(pressedKeys) == len(originalKeys):\n                            pressedKeys.clear()\n                            maybe_next_key = get_next_sheet_demo(\"ok\")\n                            if not maybe_next_key:\n                                return\n                            else:\n                                originalKeys = set(maybe_next_key)\n        except Exception as e:\n            print(f\"发生错误: {e.__doc__} , 开始重新加载\")\n\n    # 处理 Esc 退出监听\n    if key == GlobalVariable.shortcutStruct[\"follow_key\"][\"exit\"] or  key == \"alt_l\":\n        print(\"检测到 Esc 键，退出监听...\")\n        GlobalVariable.exit_flag = True  # 设置全局标志\n        try:\n            quit_window()\n        except Exception as e:\n            return False\n        return False  # 停止监听\n\ndef get_next_sheet_demo(operator):\n    if len(GlobalVariable.follow_sheet) == 0:\n        return \"\"\n    try:\n        if operator != \"load\":\n            global originalKeys\n            clear_window_key(originalKeys)\n\n        if operator == \"ok\" or operator == \"load\":\n            sheet = GlobalVariable.follow_sheet[0]\n            GlobalVariable.nowClientKey = sheet\n            GlobalVariable.follow_sheet = GlobalVariable.follow_sheet[1:]\n            if len(GlobalVariable.follow_sheet) == 0:\n                GlobalVariable.exit_flag = True  # 设置全局标志\n                quit_window()\n                plyer.notification.notify(\n                    app_name='小星弹琴软件',\n                    app_icon=path.join(getResourcesPath(\"systemTools\"), \"icon.ico\"),\n                    title='已经结束啦',\n                    message='这首歌已经弹完了哦',\n                    timeout=1\n                )\n                send_multiple_key_press(\"z\")\n                send_multiple_key_release(\"z\")\n                return False\n            for key in sheet:\n                add_window_key(key)\n            update_key()\n            return sheet\n        else:\n            GlobalVariable.nowClientKey = GlobalVariable.follow_sheet[0]\n            return GlobalVariable.follow_sheet[0]\n    except IndexError:\n        print(\"空数组\")\n        return \"\"\n\n\ndef startThread():\n    global originalKeys, pressedKeys\n    time.sleep(2)\n    originalKeys = set(get_next_sheet_demo(\"load\"))\n    pressedKeys = set()\n    GlobalVariable.exit_flag = False  # 确保每次启动时标志位重置\n    with keyboard.Listener(on_press=on_press, on_release=key_release) as listener:\n        listener.join()\n"
  },
  {
    "path": "sky-music-server/windhide/thread/frame_alive_thread.py",
    "content": "import os\nimport time\n\nimport psutil\n\n\ndef is_process_running(process_name):\n    \"\"\"检查目标进程是否运行\"\"\"\n    return any(proc.info[\"name\"] == process_name for proc in psutil.process_iter([\"name\"]))\n\n\ndef monitor_process(process_name):\n    \"\"\"监听目标进程的状态，如果退出则结束主程序\"\"\"\n    print(f\"🔍 监听进程: {process_name}\")\n    while True:\n        if not is_process_running(process_name):\n            print(f\"⚠️ {process_name} 已退出，关闭主程序。\")\n            os._exit(0)  # 强制退出主进程\n        time.sleep(1)  # 每秒检查一次\n"
  },
  {
    "path": "sky-music-server/windhide/thread/hwnd_check_thread.py",
    "content": "import os\nimport time\nimport traceback\n\nimport psutil\nimport pywintypes\nimport win32gui\nimport win32process\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils import hook_util\nfrom windhide.utils.ocr_follow_util import get_key_position\n\nhook_util.sout_null()\n\ndef safe_enum_windows(callback):\n    \"\"\"封装 EnumWindows 调用，捕获特定异常，防止异常中断调用链\"\"\"\n    try:\n        win32gui.EnumWindows(callback, None)\n    except pywintypes.error as e:\n        error_code = e.args[0]  # 获取错误码\n        error_message = e.args[1]  # 获取错误消息\n        error_details = e.args[2]  # 获取错误详细信息\n        if error_code == 2:  # 系统找不到指定文件，忽略\n            print(f\"[DEBUG] EnumWindows 错误码 2：{error_message}，详细信息：{error_details}\")\n        else:\n            # 打印错误码、消息和详细信息，同时也捕获堆栈跟踪\n            print(f\"[DEBUG] EnumWindows 异常:\")\n            print(f\"  错误码: {error_code}\")\n            print(f\"  错误消息: {error_message}\")\n            print(f\"  错误详细信息: {error_details}\")\n            print(\"[DEBUG] 错误堆栈跟踪:\")\n            traceback.print_exc()  # 打印堆栈跟踪\n\n\ndef get_exe_name_from_hwnd(hwnd):\n    # 获取窗口的 PID\n    _, pid = win32process.GetWindowThreadProcessId(hwnd)\n    try:\n        # 使用 psutil 获取进程的 exe 路径\n        process = psutil.Process(pid)\n        exe_path = process.exe()  # 获取 exe 路径\n        exe_name = os.path.basename(exe_path)  # 只获取文件名\n        return exe_name\n    except (psutil.NoSuchProcess, psutil.AccessDenied):\n        return None\n\n\ndef find_window_by_class(class_name):\n    \"\"\"根据窗口类名查找窗口句柄\"\"\"\n    hwnd = win32gui.FindWindow(class_name, None)\n    return hwnd\n\ndef update_window_handle():\n    \"\"\"查找窗口句柄，并更新全局变量\"\"\"\n    if GlobalVariable.is_custom_hwnd is False:\n        class_name = \"TgcMainWindow\"\n        hwnd = find_window_by_class(class_name)\n        if hwnd:\n            left, top, right, bottom = win32gui.GetWindowRect(hwnd)\n            width, height = right - left, bottom - top\n            window = GlobalVariable.window\n            window[\"hWnd\"], window[\"width\"], window[\"height\"] = hwnd, width, height\n            window[\"position_x\"], window[\"position_y\"] = left, top\n\n            # 仅在窗口信息发生变化时设置 is_change\n            if any([\n                window[\"width\"] != width,\n                window[\"height\"] != height,\n                window[\"position_x\"] != left,\n                window[\"position_y\"] != top,\n            ]):\n                window[\"is_change\"] = True\n            GlobalVariable.hwnd_title = get_exe_name_from_hwnd(hwnd)\n            get_key_position(0.88)\n        else:\n            GlobalVariable.window[\"hWnd\"] = None\n    else:\n        GlobalVariable.hwnd_title = get_exe_name_from_hwnd(GlobalVariable.window[\"hWnd\"])\n\ndef start_thread():\n    \"\"\"后台线程循环更新窗口句柄\"\"\"\n    while True:\n        update_window_handle()\n        time.sleep(2)"
  },
  {
    "path": "sky-music-server/windhide/thread/intel_play_thread.py",
    "content": "import math\nimport threading\nimport time\n\nfrom windhide.playRobot import intel_robot\nfrom windhide.static.global_variable import GlobalVariable\n\n\nclass ControlledThread:\n    def __init__(self):\n        self._pause_event = threading.Event()\n        self._pause_event.set()  # 初始状态为运行\n        self._thread = None\n        self._running = False\n\n    def _run(self):\n        if not GlobalVariable.music_sheet:\n            self.stop()\n            return\n\n        local_music_sheet = GlobalVariable.music_sheet[:]\n        total_length = 1 if len(local_music_sheet) == 1 else len(local_music_sheet) - 1\n        index = 0\n\n        # 在播放开始时计算总时长（单位为毫秒）\n        total_time = sum(sheet[\"delay\"] for sheet in local_music_sheet)\n        GlobalVariable.now_total_time = self.format_time(total_time)\n        current_time = 0  # 当前时间（单位为毫秒）\n\n        while self._running and index < len(local_music_sheet):\n            self._pause_event.wait()  # 等待恢复\n\n            if GlobalVariable.set_progress != -0.01:\n                index = math.floor(total_length * GlobalVariable.set_progress)\n                GlobalVariable.set_progress = -0.01\n                current_time = total_time * (index / total_length)  # 调整当前时间\n                continue\n\n            sheet = local_music_sheet[index]\n            keys = sheet[\"key\"]\n            delay = sheet[\"delay\"] / GlobalVariable.play_speed\n            if total_length == 0:\n                GlobalVariable.now_progress = 100\n            else:\n                GlobalVariable.now_progress = (index / total_length) * 100\n            if keys:\n                (intel_robot.send_single_key_to_window if len(keys) == 1\n                 else intel_robot.send_multiple_key_to_window)(keys, sheet[\"duration\"] if \"duration\" in sheet else 0)\n\n            time.sleep(delay / 1000 + GlobalVariable.delay_interval)\n            # 格式化当前时间/总时间\n            # formatted_time = self.format_time(current_time) + \" / \" + self.format_time(total_time)\n            # print(f\"播放时间：{formatted_time}\", end=\"\\r\")\n            GlobalVariable.now_current_time = self.format_time(current_time)\n            current_time += delay  # 更新当前时间\n            index += 1\n\n    def format_time(self, milliseconds):\n        \"\"\"\n        将毫秒数格式化为时分秒格式（HH:MM:SS 或 MM:SS）\n        \"\"\"\n        seconds = milliseconds / 1000\n        hours, remainder = divmod(seconds, 3600)\n        minutes, seconds = divmod(remainder, 60)\n\n        if hours > 0:\n            return f\"{int(hours):02}:{int(minutes):02}:{int(seconds):02}\"\n        else:\n            return f\"{int(minutes):02}:{int(seconds):02}\"\n\n    def start(self):\n        if self._running:\n            return\n        self._running = True\n        if self._thread and self._thread.is_alive():\n            self._thread.join()\n        self._thread = threading.Thread(target=self._run, daemon=True)\n        self._thread.start()\n\n    def pause(self):\n        self._pause_event.clear()\n\n    def resume(self):\n        self._pause_event.set()\n\n    def stop(self):\n        self._running = False\n        self.resume()  # 防止死锁\n        if self._thread and self._thread.is_alive():\n            self._thread.join()\n        self._thread = None"
  },
  {
    "path": "sky-music-server/windhide/thread/queue_thread.py",
    "content": "import queue\nimport re\nfrom os import path\n\nimport plyer\n\nfrom windhide.playRobot import intel_robot, amd_robot\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils.path_util import getResourcesPath\n\n\ndef music_start_tasks():\n    while True:\n        try:\n            request = GlobalVariable.task_queue.get(block=True, timeout=0.5)  # 最多等待1秒\n        except queue.Empty:\n            continue\n        try:\n            if GlobalVariable.window[\"hWnd\"] is None and GlobalVariable.compatibility_mode is False:\n                plyer.notification.notify(\n                    app_name='小星弹琴软件',\n                    app_icon=path.join(getResourcesPath(\"systemTools\"),\"icon.ico\"),\n                    title='🔥🔥🔥🔥🔥',\n                    message='未检测到游戏窗口，请打开游戏或者去句柄页面进行指定！本次播放操作释放',\n                    timeout=1\n                )\n                GlobalVariable.now_progress = 100\n                GlobalVariable.task_queue.task_done()\n                continue\n            GlobalVariable.now_play_music = (\"\" if 'sheet' in request else  re.sub(r\"-#(\\d+)(?=\\.\\w+)?\", \"\", request[\"fileName\"].replace(\".txt\", \"\")))\n            match GlobalVariable.cpu_type:\n                case \"Intel\":\n                    intel_robot.playMusic_edit(request[\"sheet\"]) if 'sheet' in request else intel_robot.playMusic(request[\"fileName\"], request[\"type\"])\n                case \"AMD\":\n                    amd_robot.playMusic_edit(request[\"sheet\"]) if 'sheet' in request else amd_robot.playMusic(request[\"fileName\"], request[\"type\"])\n        except Exception as e:\n            print(f\"Error in processing task: {str(e)}\")\n        GlobalVariable.task_queue.task_done()  # 标记任务完成"
  },
  {
    "path": "sky-music-server/windhide/thread/shortcut_thread.py",
    "content": "import urllib\n\nfrom pynput import keyboard\nfrom websocket_server import WebsocketServer\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils import hook_util\n\nhook_util.sout_null()\n\nserver = WebsocketServer(\"127.0.0.1\", 11452)\n\n\ndef get_key_string(key):\n    if hasattr(key, \"char\") and key.char is not None:  # 处理普通字符按键\n        return key.char\n    elif hasattr(key, \"name\"):  # 处理特殊按键\n        return key.name\n    else:\n        return str(key)  # 兜底方案，转换为字符串\n\n\n# 键盘按键事件处理\ndef on_press(key):\n    key = get_key_string(key)\n    if key in GlobalVariable.shortcutStruct[\"music_key\"][\"string\"]:\n        try:\n            server.send_message_to_all(urllib.parse.quote(key))\n        except Exception as e:\n            print(f\"发送消息时发生错误: {e}\")\n# 客户端事件处理\ndef on_client_connect(client, server):\n    print(f\"客户端 {client['id']} 已连接\")\n\ndef on_client_disconnect(client, server):\n    print(f\"客户端 {client['id']} 已断开连接\")\n\n# 启动 WebSocket 服务\ndef startThread():\n    try:\n        server.set_fn_new_client(on_client_connect)\n        server.set_fn_client_left(on_client_disconnect)\n        listener = keyboard.Listener(on_press=on_press)\n        listener.start()\n        print(\"WebSocket 服务正在启动，监听 127.0.0.1:11452...\")\n        server.run_forever()\n    except Exception as e:\n        print(f\"WebSocket 服务器启动失败: {e}\")\n"
  },
  {
    "path": "sky-music-server/windhide/utils/auto_util.py",
    "content": "\nfrom windhide.auto.auto_thread import HeartFireThread\nfrom windhide.static.global_variable import GlobalVariable\n\n\ndef auto_click_fire():\n    if GlobalVariable.auto_thread is not None:\n        GlobalVariable.auto_thread.stop()\n    GlobalVariable.auto_thread = HeartFireThread()\n    GlobalVariable.auto_thread.daemon = True\n    GlobalVariable.auto_thread.start()\n\ndef shutdown():\n    GlobalVariable.auto_thread.stop()"
  },
  {
    "path": "sky-music-server/windhide/utils/command_util.py",
    "content": "import socket\nimport threading\nimport time\nfrom os import path\nfrom time import sleep\n\nimport plyer\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.thread.follow_process_thread import run_follow_process, stop_follow_process\nfrom windhide.utils.ocr_normal_utils import get_game_position\nfrom windhide.utils.path_util import getResourcesPath\n\n# 全局变量，存储客户端连接对象\nGlobalVariable.follow_client = None\n\n\n\ndef start_process():\n    # 创建并启动线程，传递参数\n    thread = threading.Thread(target=run_follow_process)\n    thread.daemon = True  # 设置为守护线程，主线程退出时自动退出\n    thread.start()\n\ndef add_window_key(key):\n    try:\n        width = GlobalVariable.window['key_position'][key]['width']\n        height = GlobalVariable.window['key_position'][key]['height']\n        position_x = GlobalVariable.window['key_position'][key]['position_x'] - GlobalVariable.window_offset_x\n        position_y = GlobalVariable.window['key_position'][key]['position_y'] - GlobalVariable.window_offset_y\n        send_command(f\"draw {key} {width} {height} {position_x} {position_y} \\n\")  # 绘制\n    except KeyError as e:\n        print(\"按键识别不完全，重新调用 => \", e, e.__doc__)\n        GlobalVariable.window[\"is_change\"] = True\n        time.sleep(2)\n        resize_and_reload_key()\n\ndef del_window_key(key):\n    send_command(f\"delete {key} \\n\")  # 绘制\n\ndef clear_window_key(keys):\n    for key in keys:\n        send_command(f\"delete {key} \\n\")\n\ndef update_key():\n    send_command(f\"update \\n\")\n\ndef resize_and_reload_key():\n    if GlobalVariable.window[\"wait\"] is not True:\n        GlobalVariable.window[\"is_change\"] = True\n        GlobalVariable.window[\"wait\"] = True\n    plyer.notification.notify(\n        app_name='小星弹琴软件',\n        app_icon=path.join(getResourcesPath(\"systemTools\"), \"icon.ico\"),\n        title='已经在很努力的检测了',\n        message='如果长时间未检测完成请换个位置打开琴键',\n        timeout=0.3\n    )\n    while True:\n        sleep(1)\n        if len(GlobalVariable.window['key_position']) == 15 and GlobalVariable.window[\"wait\"] == False:\n            GlobalVariable.window[\"wait\"] = False\n            position = get_game_position()\n            position_x, position_y = position[0], position[1]\n            width, height = position[2] - position[0], position[3] - position[1]\n            # 检查窗口大小是否发生变化\n            if width != GlobalVariable.window.get('width', 0) or height != GlobalVariable.window.get('height', 0):\n                GlobalVariable.window['width'] = width\n                GlobalVariable.window['height'] = height\n                # 重新计算按键位置\n                from windhide.utils.ocr_follow_util import get_key_position\n                get_key_position(None)  # 重新获取按键位置\n            send_command(f\"resize {width} {height} {position_x} {position_y} \\n\")\n            clear_window_key(GlobalVariable.nowClientKey)\n            # 重新获取新的15个按键\n            if len(GlobalVariable.follow_sheet) > 0:\n                GlobalVariable.nowClientKey = GlobalVariable.follow_sheet[0]\n                for key in GlobalVariable.nowClientKey:\n                    add_window_key(key)\n                update_key()\n            break\n    plyer.notification.notify(\n        app_name='小星弹琴软件',\n        app_icon=path.join(getResourcesPath(\"systemTools\"), \"icon.ico\"),\n        title='检测完毕',\n        message='OK',\n        timeout=1\n    )\n\ndef quit_window():\n    send_command(f\"exit\\n\")\n    GlobalVariable.follow_client.shutdown(socket.SHUT_RDWR)  # 关闭套接字的读写\n    GlobalVariable.follow_client.close()\n    GlobalVariable.follow_client = None\n    stop_follow_process()\n\ndef wait_for_server(host, port, max_retries=30, delay=2):\n    \"\"\"等待服务器启动并可连接\"\"\"\n    retries = 0\n    while retries < max_retries:\n        try:\n            with socket.create_connection((host, port), timeout=1) as sock:\n                return True  # 服务器已启动\n        except (ConnectionRefusedError, OSError):\n            retries += 1\n            time.sleep(delay)\n    return False  # 超时\n\ndef send_command(command):\n    try:\n        if GlobalVariable.follow_client is None:\n            if not wait_for_server(\"localhost\", 12345):\n                print(\"无法连接到 draw_server.exe，超时退出。\")\n                return\n            GlobalVariable.follow_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            GlobalVariable.follow_client.connect((\"localhost\", 12345))  # 连接到服务器\n        GlobalVariable.follow_client.send(command.encode(\"utf-8\"))\n        print(f\"发送命令: {command}\")\n    except WindowsError as e:\n        GlobalVariable.exit_flag = True\n        print(\"send Command错误\", e.__doc__)\n    except Exception as e:\n        print(\"send Command错误\", e.__doc__)\n        GlobalVariable.exit_flag = True\n        # GlobalVariable.follow_client.shutdown(socket.SHUT_RDWR)  # 关闭套接字的读写\n        # GlobalVariable.follow_client.close()\n        # GlobalVariable.follow_client = None\n"
  },
  {
    "path": "sky-music-server/windhide/utils/config_util.py",
    "content": "import os\nimport shutil\n\nfrom windhide.musicToSheet.music2html import generatorSheetHtml\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils.path_util import getResourcesPath, convert_notes_to_delayed_format\n\n\ndef set_config(request: dict):\n    match request[\"name\"]:\n        case 'delay_interval':\n            GlobalVariable.delay_interval = float(request[\"value\"])\n        case 'duration':\n            GlobalVariable.duration = float(request[\"value\"])\n        case 'set_progress':\n            GlobalVariable.set_progress = float(request[\"value\"])\n        case 'play_speed':\n            GlobalVariable.play_speed = float(request[\"value\"])\n        case 'compatibility_mode':\n            GlobalVariable.compatibility_mode = request[\"value\"]\n        case 'is_post_w':\n            GlobalVariable.is_post_w = request[\"value\"]\n        case 'cpu_type':\n            GlobalVariable.cpu_type = \"AMD\" if request[\"value\"] else \"Intel\"\n        case 'shortcutStruct':\n            GlobalVariable.shortcutStruct = request[\"value\"]\n        case 'keyMap':\n            GlobalVariable.keyMap = request[\"value\"]\n        case 'merge_min':\n            GlobalVariable.merge_min = int(request[\"value\"])\n        case 'merge_max':\n            GlobalVariable.merge_max = int(request[\"value\"])\n        case 'velocity_filter':\n            GlobalVariable.velocity_filter = int(request[\"value\"])\n        case 'is_singular':\n            GlobalVariable.is_singular = request[\"value\"]\n        case 'semitone_switch':\n            GlobalVariable.semitone_switch = request[\"value\"]\n        case 'detail_switch':\n            GlobalVariable.detail_switch = request[\"value\"]\n        case 'split_switch':\n            GlobalVariable.split_switch = request[\"value\"]\n        case 'ai_token':\n            GlobalVariable.ai_token[request[\"value\"][\"type\"]] = request[\"value\"][\"token\"]\n        case 'translate_prompt':\n            GlobalVariable.translate_prompt = request[\"value\"]\n        case 'duration_prompt':\n            GlobalVariable.duration_prompt = request[\"value\"]\n        case 'sheld':\n            GlobalVariable.sheld = float(request[\"value\"])\n\ndef get_config(request: dict):\n    configValue = eval(\"GlobalVariable.\" + request[\"name\"])\n    return configValue\n\ndef favorite_music(request: dict):\n    src = os.path.join(getResourcesPath(request['type']), request['fileName'] + \".txt\")\n    dst = os.path.join(getResourcesPath('myFavorite'), request['fileName'] + \".txt\")\n    shutil.copy(src, dst, follow_symlinks=False)\n\n\ndef convert_sheet(request: dict):\n    convert_notes_to_delayed_format(request[\"fileName\"], request[\"type\"])\n    generatorSheetHtml(request[\"fileName\"], list(map(lambda item: item['key'], GlobalVariable.music_sheet)))\n    GlobalVariable.music_sheet = []\n    return \"ok\"\n\n\ndef drop_file(request: dict):\n    file_name = request[\"fileName\"]\n    if file_name is None:\n        return '不ok'\n    if request.get('suffix', None) is None:\n        drop_path = os.path.join(getResourcesPath(request['type']), file_name + '.txt')\n    else:\n        drop_path = os.path.join(getResourcesPath(request['type']), file_name + request['suffix'])\n    os.remove(drop_path)\n    return 'ok'"
  },
  {
    "path": "sky-music-server/windhide/utils/hook_util.py",
    "content": "import builtins\nimport platform\n\nfrom windhide.static.global_variable import GlobalVariable\n\n\n# 重定向 print 到空函数\n\ndef sout_null():\n    if GlobalVariable.isProd:\n        builtins.print = lambda *args, **kwargs: None\n    cpu_check()\n    return None\n\ndef cpu_check():\n    cpu_info = platform.processor()\n    if \"Intel\" in cpu_info:\n        GlobalVariable.cpu_type = 'Intel'\n    elif \"AMD\" in cpu_info:\n        GlobalVariable.cpu_type = 'AMD'"
  },
  {
    "path": "sky-music-server/windhide/utils/hwnd_utils.py",
    "content": "import os\n\nimport psutil\nimport win32gui\nimport win32process\n\nfrom windhide.static.global_variable import GlobalVariable\n\n\ndef get_running_apps():\n    apps = []\n    # 获取当前系统运行的所有进程\n    for proc in psutil.process_iter(['pid', 'name']):\n        try:\n            pid = proc.info['pid']\n            name = proc.info['name']\n            exe_path = proc.exe()\n            if 'System' in name or 'svchost' in name:\n                continue\n            def enum_windows(hwnd, lParam):\n                if win32gui.IsWindowVisible(hwnd):\n                    window_title = win32gui.GetWindowText(hwnd)\n                    if window_title:\n                        _, window_pid = win32process.GetWindowThreadProcessId(hwnd)\n                        if window_pid == pid:\n                            apps.append({\n                                'title': window_title,\n                                'exe_name': os.path.basename(exe_path),\n                                'pid': pid,\n                                'hwnd': hwnd\n                            })\n            win32gui.EnumWindows(enum_windows, None)\n        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):\n            pass\n    return apps\n\ndef get_running_apps_by_struct(check_struct):\n    if any(item == check_struct for item in get_running_apps()) is True:\n        GlobalVariable.hwnd_select_struct = check_struct\n        GlobalVariable.window[\"hWnd\"] = check_struct[\"hwnd\"]\n        GlobalVariable.is_custom_hwnd = True\n    else:\n        GlobalVariable.is_custom_hwnd = False\n"
  },
  {
    "path": "sky-music-server/windhide/utils/ocr_follow_util.py",
    "content": "import logging\nimport os\nimport threading\n\nimport keyboard\nimport time\n\n\nfrom ultralytics import YOLO\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.thread.follow_thread import startThread as follow_thread_demo\nfrom windhide.utils.command_util import start_process\nfrom windhide.utils.ocr_normal_utils import get_window_screenshot\nfrom windhide.utils.path_util import getResourcesPath, convert_notes_to_delayed_format\nif GlobalVariable.cpu_type == 'Intel':\n    from windhide.playRobot.intel_robot import mouse_move_to, key_press\nelse:\n    from windhide.playRobot.amd_robot import mouse_move_to, key_press\n\nglobal_button_model = None\n\nlogging.getLogger(\"ultralytics\").setLevel(logging.WARNING)\n\ndef set_next_sheet(request: dict):\n    try:\n        print(f\"Setting follow sheet for file: {request['fileName']}\")\n        convert_notes_to_delayed_format(request[\"fileName\"], request[\"type\"])\n        GlobalVariable.follow_sheet = list(map(lambda item: item['key'], GlobalVariable.music_sheet))\n        GlobalVariable.music_sheet = []\n        GlobalVariable.follow_music = request[\"fileName\"]\n    except Exception as e:\n        print(f\"Error in /followSheet: {str(e)}\")\n\n\ndef get_next_sheet(request: dict):\n    if len(GlobalVariable.follow_sheet) == 0:\n        return \"\"\n    try:\n        if request[\"type\"] == \"ok\":\n            sheet = GlobalVariable.follow_sheet[0]\n            GlobalVariable.nowClientKey = sheet\n            GlobalVariable.follow_sheet = GlobalVariable.follow_sheet[1:]\n            return sheet\n        else:\n            GlobalVariable.nowClientKey = GlobalVariable.follow_sheet[0]\n            return GlobalVariable.follow_sheet[0]\n    except IndexError:\n        print(\"空数组\")\n        return \"\"\n\ndef load_key_model():\n    \"\"\"加载模型并保存在全局变量中\"\"\"\n    global global_button_model\n    if global_button_model is None:\n        button_model_path = os.path.join(getResourcesPath(\"systemTools\"), \"modelData\", \"check_key_model.pt\")\n        global_button_model = YOLO(button_model_path)  # 加载模型并保存在 global_friend_model 中\n        print(\"模型加载完成\")\n    return global_button_model\n\n\ndef get_key_position(conf, threshold=10):\n    if GlobalVariable.window[\"key_position\"] is not None:\n        if len(GlobalVariable.window[\"key_position\"]) == 15 and not GlobalVariable.window[\"is_change\"]:\n            return GlobalVariable.window[\"key_position\"]\n    print(\"开始检测按键布局\")\n    GlobalVariable.window[\"key_position\"] = None\n    image = None\n    try:\n        bgr_image = get_window_screenshot()\n        height, width = bgr_image.shape[:2]\n        crop_width = int(width * 0.15)  # 右边10%的宽度\n        crop_height = int(height * 0.1)  # 底部 10% 的高度\n        image = bgr_image[: -crop_height, : -crop_width]\n    except Exception as e:\n        print(e)\n\n    model = load_key_model()\n    results = model(image, conf=conf)  # 替换为你的图片路径\n    boxes = results[0].boxes  # 检测到的所有框\n    xyxy = boxes.xyxy.cpu().numpy()  # 获取每个框的绝对坐标 (x1, y1, x2, y2)\n    all_boxes = []\n    for box in xyxy:\n        x1, y1, x2, y2 = box\n        width = int(x2 - x1)\n        height = int(y2 - y1)\n        all_boxes.append({\n            \"left\": int(x1),\n            \"top\": int(y1),\n            \"right\": int(x2),\n            \"bottom\": int(y2),\n            \"width\": width,\n            \"height\": height,\n            \"position_x\": int(x1),  # 添加 position_x\n            \"position_y\": int(y1)  # 添加 position_y\n        })\n    result_dict = {}\n    for box in all_boxes:\n        y_key = box[\"top\"]  # 使用上边距作为分组依据\n        added = False\n        for key in result_dict:\n            if abs(key - y_key) <= threshold:\n                result_dict[key].append(box)\n                added = True\n                break\n        if not added:\n            result_dict[y_key] = [box]\n    sorted_result = {}\n    sorted_keys = sorted(result_dict)\n    for key in sorted_keys:\n        group = result_dict[key]\n        sorted_group = sorted(group, key=lambda b: b[\"position_x\"])\n        sorted_result[key] = [{\n            \"width\": box[\"width\"],\n            \"height\": box[\"height\"],\n            \"position_x\": box[\"position_x\"],\n            \"position_y\": box[\"position_y\"]\n        } for box in sorted_group]\n    key_mapping = {\n        0: [\"y\", \"u\", \"i\", \"o\", \"p\"],  # 第一组\n        1: [\"h\", \"j\", \"k\", \"l\", \";\"],  # 第二组\n        2: [\"n\", \"m\", \",\", \".\", \"/\"]  # 第三组\n    }\n    final_result = {}\n    for idx, (group_key, group_boxes) in enumerate(zip(sorted_keys, sorted_result.values())):\n        if idx == 3:\n            break\n        # 避免越界\n        keys = key_mapping[idx]  # 获取当前分组的键名列表\n        for key_name, box in zip(keys, group_boxes):\n            final_result[key_name] = box  # 使用键名作为最终结果的 key\n    GlobalVariable.window[\"key_position\"] = final_result\n    if len(final_result) == 15:\n        GlobalVariable.window[\"is_change\"] = False\n        GlobalVariable.window[\"wait\"] = False\n\n    print(\"final_result\",final_result)\n    print(\"final_result len =>\",len(final_result))\n    return final_result\n\ndef test_key_model_position(conf):\n    image = None\n    time.sleep(1)\n    try:\n        bgr_image = get_window_screenshot()\n        height, width = bgr_image.shape[:2]\n        crop_width = int(width * 0.15)  # 右边10%的宽度\n        crop_height = int(height * 0.1)  # 底部 10% 的高度\n        image = bgr_image[: -crop_height, : -crop_width]\n    except Exception as e:\n        print(e)\n    model = load_key_model()\n    results = model(image, conf=conf)  # 替换为你的图片路径\n    results[0].show()\n\ndef open_follow():\n    if GlobalVariable.exit_flag == False:\n        keyboard.press('left alt')\n        time.sleep(0.05)\n        keyboard.press('left alt')\n        time.sleep(1.3)\n    start_process()\n    GlobalVariable.follow_thread = threading.Thread(target=follow_thread_demo)\n    GlobalVariable.follow_thread.daemon = True  # 设置为守护线程，主线程退出时自动退出\n    GlobalVariable.follow_thread.start()\n"
  },
  {
    "path": "sky-music-server/windhide/utils/ocr_heart_utils.py",
    "content": "import os\n\nimport cv2\nimport numpy as np\nimport pyautogui\nimport win32con\nimport win32gui\nfrom sklearn.cluster import DBSCAN\nfrom ultralytics import YOLO\n\nfrom windhide.static.global_variable import GlobalVariable\nfrom windhide.utils.path_util import getResourcesPath\n\nif GlobalVariable.cpu_type == 'AMD':\n    from windhide.playRobot.amd_robot import PostMessageW\nelse:\n    from windhide.playRobot.intel_robot import PostMessageW\n\n# 全局变量，保存模型\nglobal_friend_model = None\n\ndef load_model():\n    \"\"\"加载模型并保存在全局变量中\"\"\"\n    global global_friend_model\n    if global_friend_model is None:\n        model_path = os.path.join(getResourcesPath(\"systemTools\"), \"modelData\", \"friend_model.pt\")\n        global_friend_model = YOLO(model_path)  # 加载模型并保存在 global_friend_model 中\n    print(\"模型加载完成\")\n    return global_friend_model\n\ndef merge_boxes(boxes, confs, max_distance=50):\n    \"\"\"\n    合并距离相近的识别框，合并后的框为置信度高的框。\n\n    :param boxes: 识别框的坐标 [x1, y1, x2, y2] (形状为 [num_boxes, 4])\n    :param confs: 每个框的置信度 (形状为 [num_boxes, ])\n    :param max_distance: 合并框时的最大距离，单位为像素\n    :return: 合并后的框的坐标和置信度\n    \"\"\"\n    # 使用 DBSCAN 聚类算法来找出距离相近的框\n    clustering = DBSCAN(eps=max_distance, min_samples=1, metric='euclidean').fit(boxes[:, :2])  # 只考虑框的中心点进行聚类\n\n    # 聚类标签\n    labels = clustering.labels_\n\n    # 合并结果\n    merged_boxes = []\n    merged_confs = []\n\n    for label in np.unique(labels):\n        # 获取同一类框的索引\n        indices = np.where(labels == label)[0]\n\n        # 获取该组框的坐标和置信度\n        group_boxes = boxes[indices]\n        group_confs = confs[indices]\n\n        # 选择置信度最高的框作为合并后的框\n        max_conf_index = np.argmax(group_confs)\n        # best_box = group_boxes[max_conf_index]\n\n        # 计算合并后的框，使用最小外接矩形\n        x1 = np.min(group_boxes[:, 0])\n        y1 = np.min(group_boxes[:, 1])\n        x2 = np.max(group_boxes[:, 2])\n        y2 = np.max(group_boxes[:, 3])\n\n        # 将合并后的框添加到结果列表\n        merged_boxes.append([x1, y1, x2, y2])\n        merged_confs.append(group_confs[max_conf_index])  # 置信度为该类中的最大置信度\n\n    return np.array(merged_boxes), np.array(merged_confs)\n\n\ndef get_friend_model_position(conf, isTest=False, max_distance=50):\n    # 加载已经训练好的模型\n    image = get_window_screenshot_friend()\n    model = load_model()\n    results = model(image, conf=conf)  # 替换为你的图片路径\n    boxes = results[0].boxes  # 这是检测到的所有框\n    xyxy = boxes.xyxy.cpu().numpy()  # 获取每个框的绝对坐标 (x1, y1, x2, y2)\n    classes = boxes.cls.cpu().numpy()  # 获取每个框对应的分类号\n    confs = boxes.conf.cpu().numpy()  # 获取每个框的置信度\n    class_names = [\"button\", \"friend\"]  # 获取所有类别的名称\n    merged_boxes, merged_confs = merge_boxes(xyxy, confs, max_distance)\n\n    # 获取截图的偏移量\n    screenshot_offset_x = 150\n    screenshot_offset_y = 110\n\n    # 创建结果字典，专门存储合并框的中心点坐标\n    result_dict = {\n        \"button\": [],\n        \"friend\": [],\n    }\n\n    # 填充结果字典：仅保存修正后的中心点坐标\n    for i, box in enumerate(merged_boxes):\n        class_id = int(classes[i])  # 获取当前合并框的类别ID\n        label = class_names[class_id]  # 获取类别名称\n        x1, y1, x2, y2 = box\n\n        # 修正坐标：加上截图的偏移量\n        x1 += screenshot_offset_x\n        y1 += screenshot_offset_y\n        x2 += screenshot_offset_x\n        y2 += screenshot_offset_y\n\n        # 计算修正后的中心点坐标\n        center_x = (x1 + x2) / 2\n        center_y = (y1 + y2) / 2\n\n        result_dict[label].append((center_x, center_y))\n\n    # 如果需要可视化\n    image_with_boxes = image.copy()\n    for i, box in enumerate(merged_boxes):\n        x1, y1, x2, y2 = box\n\n        # 同样修正坐标\n        x1 += screenshot_offset_x\n        y1 += screenshot_offset_y\n        x2 += screenshot_offset_x\n        y2 += screenshot_offset_y\n\n        cv2.rectangle(image_with_boxes, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)\n        cv2.putText(image_with_boxes, f\"{merged_confs[i]:.2f}\", (int(x1), int(y1) - 10),\n                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)\n\n    if isTest:\n        results[0].show()\n\n    return result_dict\n\ndef get_window_screenshot_friend():\n    png_path = os.path.join(getResourcesPath(\"systemTools\"), 'modelData', 'demoScheenshot', 'demo.png')\n    saturation_scale = 2.4  # >1增加饱和度，<1降低饱和度\n    PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    client_rect = win32gui.GetClientRect(GlobalVariable.window[\"hWnd\"])\n    # 将客户区矩形转换为屏幕坐标\n    client_x1, client_y1 = win32gui.ClientToScreen(GlobalVariable.window[\"hWnd\"], (client_rect[0], client_rect[1]))\n    client_x2, client_y2 = win32gui.ClientToScreen(GlobalVariable.window[\"hWnd\"], (client_rect[2], client_rect[3]))\n    # 截取窗口客户区范围内的图像\n    screenshot = pyautogui.screenshot(\n        region=(client_x1 + 150, client_y1 + 80, client_x2 - client_x1 - 240, client_y2 - client_y1 - 150))\n    _, s_channel, _ = cv2.split(cv2.cvtColor(np.array(screenshot), cv2.COLOR_BGR2HSV))\n    d = np.clip(s_channel * saturation_scale, 0, 220).astype(np.uint8)\n    cv2.imwrite(png_path, d)\n    image = cv2.imread(png_path)\n    return image\n"
  },
  {
    "path": "sky-music-server/windhide/utils/ocr_normal_utils.py",
    "content": "import ctypes\n\nimport cv2\nimport numpy as np\nimport pyautogui\nimport win32con\nimport win32gui\n\nfrom windhide.static.global_variable import GlobalVariable\n\n\ndef resetGameFrame():\n    win32gui.ShowWindow(GlobalVariable.window[\"hWnd\"], win32con.SW_RESTORE)  # 先恢复窗口，以防最小化\n    rect = win32gui.GetWindowRect(GlobalVariable.window[\"hWnd\"])\n    x, y = rect[0], rect[1]  # 保持窗口的左上角位置不变\n    win32gui.MoveWindow(GlobalVariable.window[\"hWnd\"], x, y, 1280, 720, True)\n\ndef get_window_screenshot():\n    \"\"\"获取指定窗口的截图\"\"\"\n    # 获取窗口位置和大小\n    # PostMessageW(GlobalVariable.window[\"hWnd\"], win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)\n    rect = win32gui.GetWindowRect(GlobalVariable.window[\"hWnd\"])\n    x1, y1, x2, y2 = rect\n    # 截取窗口范围内的图像\n    screenshot = pyautogui.screenshot(region=(x1, y1, x2 - x1, y2 - y1))\n    return cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)\n\ndef get_system_dpi():\n    hdc = ctypes.windll.user32.GetDC(0)  # 获取屏幕设备上下文\n    dpi = ctypes.windll.gdi32.GetDeviceCaps(hdc, 88)  # LOGPIXELSX = 88\n    ctypes.windll.user32.ReleaseDC(0, hdc)  # 释放设备上下文\n    return dpi\n\ndef get_game_position():\n    hwnd = GlobalVariable.window[\"hWnd\"]\n    # 获取窗口物理坐标\n    rect = win32gui.GetWindowRect(hwnd)\n    client_rect = win32gui.GetClientRect(hwnd)\n    # 获取窗口 DPI 缩放比例\n    border_x = (rect[2] - rect[0] - client_rect[2]) // 2\n    border_y = (rect[3] - rect[1] - client_rect[3] - border_x)\n    GlobalVariable.window_offset_x = border_x\n    GlobalVariable.window_offset_y = border_y\n    # 转换物理坐标为逻辑坐标，去掉边框和标题栏\n    x1 = int((rect[0] + border_x))\n    y1 = int((rect[1] + border_y))\n    x2 = int((rect[2] - border_x))\n    y2 = int((rect[3] - border_y))\n    return x1, y1, x2, y2"
  },
  {
    "path": "sky-music-server/windhide/utils/path_util.py",
    "content": "import json\nimport os\nimport re\n\nimport chardet\nimport plyer\n\nfrom windhide.static.global_variable import GlobalVariable\n\n\ndef matchKey(key):\n    match = re.search(r'(Key-?\\d+)', key)\n    return match.group(1)\n\ndef convert_notes_to_delayed_format(fileName, type):\n    # 优化了文件路径构建\n    file_path = os.path.join(getResourcesPath(type), fileName + \".txt\")\n    with open(file_path, 'r', encoding=detect_encoding(file_path)) as file:\n        data = json.load(file)\n    song_notes = data[0].get(\"songNotes\", [])\n    if not song_notes:\n        return []\n\n    result = []\n    combined_keys = \"\"  # 按键累积\n    combined_time = None  # 当前时间\n\n    for i, note in enumerate(song_notes):\n        current_time = note[\"time\"]\n        key = note[\"key\"]\n        # 处理新时间点\n        if current_time != combined_time:\n            if combined_keys:\n                next_time = song_notes[i][\"time\"] if i < len(song_notes) else current_time\n                delay = next_time - combined_time\n                result.append({\"key\": combined_keys, \"delay\": delay, \"duration\": note[\"duration\"] if \"duration\" in note else 0})\n\n\n            combined_time = current_time\n            combined_keys = GlobalVariable.keyMap.get(matchKey(key), '')  # 获取按键，默认空字符串\n        else:\n            combined_keys += GlobalVariable.keyMap.get(matchKey(key), '')  # 如果时间相同，合并按键\n    # 处理最后的累积按键\n    if combined_keys:\n        result.append({\"key\": combined_keys, \"delay\": 0, 'duration':song_notes[len(song_notes) - 1]['duration'] if \"duration\" in note else 0})  # 最后条目的延迟为0\n    GlobalVariable.music_sheet = result\n\n\ndef convert_json_to_play(song_notes):\n    result = []\n    combined_keys = \"\"  # 按键累积\n    combined_time = None  # 当前时间\n    for i, note in enumerate(song_notes):\n        current_time = note[\"time\"]\n        key = note[\"key\"]\n        # 处理新时间点\n        if current_time != combined_time:\n            if combined_keys:\n                next_time = song_notes[i][\"time\"] if i < len(song_notes) else current_time\n                delay = next_time - combined_time\n                result.append({\"key\": combined_keys, \"delay\": delay, \"duration\": note[\"duration\"]})\n            combined_time = current_time\n            combined_keys = GlobalVariable.keyMap.get(matchKey(key), '')  # 获取按键，默认空字符串\n        else:\n            combined_keys += GlobalVariable.keyMap.get(matchKey(key), '')  # 如果时间相同，合并按键\n    if combined_keys:\n        result.append({\"key\": combined_keys, \"delay\": 0, \"duration\": song_notes[len(song_notes) - 1]['duration']})  # 最后条目的延迟为0\n    GlobalVariable.music_sheet = result\n\n\ndef getResourcesPath(file):\n    nowPath = os.path.dirname(os.path.abspath(__file__))\n    resources_path = os.path.dirname(os.path.dirname(nowPath))\n    target_subpath = os.path.join(\"backend_dist\", \"sky_music_server\")\n    resources_path = os.path.abspath(\n        os.path.join(resources_path, \"..\", \"..\", \"..\")) if target_subpath in resources_path else os.path.abspath(\n        os.path.join(resources_path, \"..\"))\n    if file is None:\n        return os.path.join(resources_path, 'resources')\n    else:\n        return os.path.join(resources_path, 'resources', file)\n\n\ndef getTypeMusicList(type, searchStr=None):\n    # 获取资源目录路径\n    resources_dir = os.path.join(getResourcesPath(None), type)\n    # 获取目录下所有文件名\n    file_names = [\n        file for file in os.listdir(resources_dir)\n        if os.path.isfile(os.path.join(resources_dir, file))\n           and file != \".keep\"\n           and not re.search(r\"-#\\d+(?=\\.\\w+)?$\", file)  # 排除匹配 -#数字 的文件\n    ]\n    # 如果 searchStr 不为空，过滤包含 searchStr 的文件名，忽略大小写\n    if searchStr and searchStr.strip():\n        file_names = [file for file in file_names if searchStr.lower() in file.lower()]\n\n    # 构建返回的音乐列表，包含文件名和总时长\n    music_list = []\n    for file in file_names:\n        music_list.append({\n            \"name\": re.sub(r\"-#(\\d+)(?=\\.\\w+)?\", \"\", file.replace(\".txt\", \"\")),\n            \"total_duration\": format_time(int(re.search(r\"-#(\\d+)(?=\\.\\w+)?\", file).group(1) if re.search(r\"-#(\\d+)(?=\\.\\w+)?\", file) else \"0\")),\n            \"truthName\": f\"{file.replace('.txt', '')}\"\n        })\n\n    return music_list\n\ndef process_sheet_rename_time(isImportOrTranslate = False):\n    plyer.notification.notify(\n        app_name='小星弹琴软件',\n        app_icon=os.path.join(getResourcesPath(\"systemTools\"), \"icon.ico\"),\n        title='开始同步乐谱时长操作',\n        message='时间可能会比较长，耐心等待，执行过程中可能会影响正常演奏。',\n        timeout=1\n    )\n    if isImportOrTranslate:\n        resource_dirs = [\n            os.path.join(getResourcesPath(None), \"myImport\"),\n            os.path.join(getResourcesPath(None), \"myTranslate\"),\n        ]\n    else:\n        resource_dirs = [\n            os.path.join(getResourcesPath(None), \"systemMusic\"),\n            os.path.join(getResourcesPath(None), \"myTranslate\"),\n            os.path.join(getResourcesPath(None), \"myImport\"),\n            os.path.join(getResourcesPath(None), \"myFavorite\")\n        ]\n    all_file_paths = []\n    for resources_dir in resource_dirs:\n        if not os.path.exists(resources_dir):\n            continue\n        file_paths = [\n            os.path.abspath(os.path.join(resources_dir, file))\n            for file in os.listdir(resources_dir)\n            if os.path.isfile(os.path.join(resources_dir, file)) and file != \".keep\"\n        ]\n        all_file_paths.extend(file_paths)\n\n    for file_path in all_file_paths:\n        if re.search(r\"-#(\\d+)(?=\\.\\w+)?\", file_path):\n            continue\n        try:\n            with open(file_path, 'r', encoding=detect_encoding(file_path)) as file:\n                data = json.load(file)\n            song_notes = data[0].get(\"songNotes\", [])\n            if not song_notes:\n                continue\n            sumTime = int(song_notes[-1][\"time\"]) + int(song_notes[-1].get(\"duration\", 0))\n            directory, filename = os.path.split(file_path)\n            name, ext = os.path.splitext(filename)\n            new_filename = f\"{name}-#{sumTime}{ext}\"\n            new_file_path = os.path.join(directory, new_filename)\n            # 重命名文件\n            os.rename(file_path, new_file_path)\n        except Exception as e:\n            continue\n    plyer.notification.notify(\n        app_name='小星弹琴软件',\n        app_icon=os.path.join(getResourcesPath(\"systemTools\"), \"icon.ico\"),\n        title='开始同步乐谱时长操作',\n        message='操作完成',\n        timeout=1\n    )\n    return \"ok\"\n\ndef format_time(milliseconds):\n    \"\"\"\n    将毫秒数格式化为时分秒格式（HH:MM:SS 或 MM:SS）\n    \"\"\"\n    seconds = milliseconds / 1000\n    hours, remainder = divmod(seconds, 3600)\n    minutes, seconds = divmod(remainder, 60)\n\n    if hours > 0:\n        return f\"{int(hours):02}:{int(minutes):02}:{int(seconds):02}\"\n    else:\n        return f\"{int(minutes):02}:{int(seconds):02}\"\n\ndef detect_encoding(file_path):\n    with open(file_path, 'rb') as file:\n        raw_data = file.read(32000)  # 读取文件的前32KB进行编码检测\n        return chardet.detect(raw_data)['encoding']  # 直接返回编码"
  },
  {
    "path": "sky-music-server/windhide/utils/play_util.py",
    "content": "import chardet\n\nfrom windhide.playRobot import intel_robot, amd_robot\nfrom windhide.static.global_variable import GlobalVariable\n\n\ndef detect_encoding(file_path):\n    with open(file_path, 'rb') as file:\n        raw_data = file.read(32000)  # 读取文件的前32KB进行编码检测\n        return chardet.detect(raw_data)['encoding']  # 直接返回编码\n\ndef start(request: dict):\n    GlobalVariable.task_queue.put(request)  # 将请求放入队列\n\ndef pause():\n    try:\n        print(\"Pausing music\")\n        match GlobalVariable.cpu_type:\n            case \"Intel\":\n                intel_robot.pause()\n            case \"AMD\":\n                amd_robot.pause()\n    except Exception as e:\n        print(f\"Error in /pause: {str(e)}\")\n\n\ndef stop():\n    try:\n        print(\"Stopping music\")\n        GlobalVariable.now_play_music = \"没有正在播放的歌曲哦\"\n        match GlobalVariable.cpu_type:\n            case \"Intel\":\n                intel_robot.stop()\n            case \"AMD\":\n                amd_robot.stop()\n    except Exception as e:\n        print(f\"Error in /stop: {str(e)}\")\n\n\ndef resume():\n    try:\n        print(\"Resuming music\")\n        match GlobalVariable.cpu_type:\n            case \"Intel\":\n                intel_robot.resume()\n            case \"AMD\":\n                amd_robot.resume()\n    except Exception as e:\n        print(f\"Error in /resume: {str(e)}\")\n"
  },
  {
    "path": "sky-music-server/windhide/utils/sheet_decrypt_util.py",
    "content": "import json\n\n\ndef decrypt_sheet(data):\n    # 加密密钥和签名（来自 CEN.cs）\n    KEY = \"TB,R&Q}-ULFXF7={nU7v?fy#Khr9Mhuu\"\n    SIGNATURE = \"ztB_kaFeQe/wa8Kq{r_jz!r=P])hQL(f\"\n    sheet_data = data[0]\n    # 获取加密的 songNotes\n    encrypted_notes = sheet_data.get('songNotes', [])\n\n    if not encrypted_notes:\n        print(\"错误：songNotes 为空\")\n        return\n\n    print(f\"找到 {len(encrypted_notes)} 个加密字符\")\n    print(\"开始解密...\")\n\n    # 解密算法（基于 CEN.ToString）\n    decrypted_chars = []\n    for i, short_val in enumerate(encrypted_notes):\n        # decrypted = (short - key[i % keyLength] + 100)\n        key_char = KEY[i % len(KEY)]\n        decrypted_char = chr(short_val - ord(key_char) + 100)\n        decrypted_chars.append(decrypted_char)\n\n    # 组合解密后的字符串\n    decrypted_str = ''.join(decrypted_chars)\n\n    # 移除尾部签名\n    decrypted_str = decrypted_str.replace(SIGNATURE, '')\n\n    print(f\"解密后字符串长度: {len(decrypted_str)}\")\n\n    data[0]['songNotes'] = json.loads(decrypted_str)\n\n    return data\n"
  },
  {
    "path": "sky-music-web/.editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true"
  },
  {
    "path": "sky-music-web/.eslintignore",
    "content": "node_modules\ndist\nout\n.gitignore\n"
  },
  {
    "path": "sky-music-web/.eslintrc.cjs",
    "content": "/* eslint-env node */\nrequire('@rushstack/eslint-patch/modern-module-resolution')\n\nmodule.exports = {\n  extends: [\n    'eslint:recommended',\n    'plugin:vue/vue3-recommended',\n    '@electron-toolkit',\n    '@electron-toolkit/eslint-config-ts/eslint-recommended',\n    '@vue/eslint-config-typescript/recommended',\n    '@vue/eslint-config-prettier'\n  ],\n  rules: {\n    'vue/require-default-prop': 'off',\n    'vue/multi-word-component-names': 'off',\n    '@typescript-eslint/no-explicit-any': 'off',\n    '@typescript-eslint/no-unused-vars': 'off',\n    'no-debugger': 'off',\n  }\n}\n"
  },
  {
    "path": "sky-music-web/.gitignore",
    "content": "node_modules\ndist\nout\n*.txt\n.DS_Store\n*.log*\n"
  },
  {
    "path": "sky-music-web/.npmrc",
    "content": "electron_mirror=https://npmmirror.com/mirrors/electron/\nelectron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/\n"
  },
  {
    "path": "sky-music-web/.prettierignore",
    "content": "out\ndist\npnpm-lock.yaml\nLICENSE.md\ntsconfig.json\ntsconfig.*.json\n"
  },
  {
    "path": "sky-music-web/.prettierrc.yaml",
    "content": "singleQuote: true\nsemi: false\nprintWidth: 100\ntrailingComma: none\n"
  },
  {
    "path": "sky-music-web/README.md",
    "content": "# electron-app\n\nAn Electron application with Vue and TypeScript\n\n## Recommended IDE Setup\n\n- [VSCode](https://code.visualstudio.com/) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin)\n\n## Project Setup\n\n### Install\n\n```bash\n$ yarn\n```\n\n### Development\n\n```bash\n$ yarn dev\n```\n\n### Build\n\n```bash\n# For windows\n$ yarn build:win\n\n# For macOS\n$ yarn build:mac\n\n# For Linux\n$ yarn build:linux\n```\n"
  },
  {
    "path": "sky-music-web/build/entitlements.mac.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>com.apple.security.cs.allow-jit</key>\n    <true/>\n    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>\n    <true/>\n    <key>com.apple.security.cs.allow-dyld-environment-variables</key>\n    <true/>\n  </dict>\n</plist>\n"
  },
  {
    "path": "sky-music-web/dev-app-update.yml",
    "content": "provider: generic\nurl: https://example.com/auto-updates\nupdaterCacheDirName: electron-app-updater\n"
  },
  {
    "path": "sky-music-web/electron-builder.yml",
    "content": "appId: 星星弹琴\nproductName: Sky_Music\ndirectories:\n  buildResources: build\nfiles:\n  - '!**/.vscode/*'\n  - '!src/*'\n  - '!electron.vite.config.{js,ts,mjs,cjs}'\n  - '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'\n  - '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'\n  - '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}'\n  - '!**/backend_dist/**'\n  - '!**/template-resources/**'\n  - '!**/ffmpeg.exe'\n  - '!*.keep'\nwin:\n  executableName: Sky_Music\n  icon: build/icon.ico\n  requestedExecutionLevel: requireAdministrator\nnsis:\n  artifactName: 小星弹琴软件v${version}_x64_windows.${ext}\n  shortcutName: \"小星弹琴软件\"\n  uninstallDisplayName: '卸载 Uninstaller'\n  perMachine: true\n  installerIcon: build/icon.ico\n  uninstallerIcon: build/icon.ico\n  installerHeaderIcon: build/icon.ico\n  oneClick: false  # 允许自定义安装目录和其他设置\n  allowToChangeInstallationDirectory: true  # 允许用户选择安装目录\n  createDesktopShortcut: true  # 允许创建桌面快捷方式\n  createStartMenuShortcut: true  # 允许创建开始菜单快捷方式\n  deleteAppDataOnUninstall: true # 卸载时删除软件缓存数据\nextraFiles:\n  - from: \".\\\\backend_dist\"\n    to: \".\\\\backend_dist\"\n  - from: \"..\\\\template-resources\"\n    to: \".\\\\resources\"\nnpmRebuild: false\npublish:\n  provider: generic\n  url: https://example.com/auto-updates\nelectronDownload:\n  mirror: https://npmmirror.com/mirrors/electron/\n"
  },
  {
    "path": "sky-music-web/electron.vite.config.ts",
    "content": "import { resolve } from 'path'\nimport { defineConfig, externalizeDepsPlugin } from 'electron-vite'\nimport vue from '@vitejs/plugin-vue'\n\nexport default defineConfig({\n  main: {\n    plugins: [externalizeDepsPlugin()]\n  },\n  preload: {\n    plugins: [externalizeDepsPlugin()]\n  },\n  renderer: {\n    resolve: {\n      alias: {\n        '@renderer': resolve('src/renderer/src')\n      }\n    },\n    plugins: [vue()]\n  }\n})\n"
  },
  {
    "path": "sky-music-web/package.json",
    "content": "{\n  \"name\": \"sky-music-web\",\n  \"version\": \"v2.6.6\",\n  \"description\": \"WindHide\",\n  \"main\": \"./out/main/index.js\",\n  \"author\": \"WindHide\",\n  \"homepage\": \"https://github.com/windhide\",\n  \"scripts\": {\n    \"format\": \"prettier --write .\",\n    \"lint\": \"eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix\",\n    \"typecheck:node\": \"tsc --noEmit -p tsconfig.node.json --composite false\",\n    \"typecheck:web\": \"vue-tsc --noEmit -p tsconfig.web.json --composite false\",\n    \"typecheck\": \"npm run typecheck:node && npm run typecheck:web\",\n    \"start\": \"electron-vite preview\",\n    \"dev\": \"electron-vite dev\",\n    \"build\": \"npm run typecheck && electron-vite build\",\n    \"build:win\": \"npm run build && electron-builder --win\"\n  },\n  \"dependencies\": {\n    \"@electron-toolkit/preload\": \"^3.0.0\",\n    \"@electron-toolkit/utils\": \"^3.0.0\",\n    \"@vicons/fluent\": \"^0.13.0\",\n    \"@vicons/ionicons5\": \"^0.12.0\",\n    \"electron-store\": \"^8.0.0\",\n    \"electron-updater\": \"^6.1.7\",\n    \"hotkeys-js\": \"^3.13.9\",\n    \"html2canvas\": \"^1.4.1\",\n    \"iconv-lite\": \"^0.6.3\",\n    \"lodash-es\": \"^4.17.21\",\n    \"naive-ui\": \"^2.41.0\",\n    \"node-cmd\": \"^5.0.0\",\n    \"p-limit\": \"^4.0.0\",\n    \"vfonts\": \"^0.0.3\",\n    \"vue-i18n\": \"^11.1.3\",\n    \"vue-router\": \"^4.0.3\",\n    \"vuex\": \"^4.0.0\"\n  },\n  \"devDependencies\": {\n    \"@electron-toolkit/eslint-config\": \"^1.0.2\",\n    \"@electron-toolkit/eslint-config-ts\": \"^2.0.0\",\n    \"@electron-toolkit/tsconfig\": \"^1.0.1\",\n    \"@rushstack/eslint-patch\": \"^1.10.3\",\n    \"@types/node\": \"^20.14.8\",\n    \"@vitejs/plugin-vue\": \"^5.0.5\",\n    \"@vue/eslint-config-prettier\": \"^9.0.0\",\n    \"@vue/eslint-config-typescript\": \"^13.0.0\",\n    \"electron\": \"^31.0.2\",\n    \"electron-builder\": \"^24.13.3\",\n    \"electron-vite\": \"^2.3.0\",\n    \"eslint\": \"^8.57.0\",\n    \"eslint-plugin-vue\": \"^9.26.0\",\n    \"prettier\": \"^3.3.2\",\n    \"typescript\": \"^5.5.2\",\n    \"vite\": \"^5.3.1\",\n    \"vue\": \"^3.4.30\",\n    \"vue-tsc\": \"^2.0.22\"\n  }\n}\n"
  },
  {
    "path": "sky-music-web/src/main/index.ts",
    "content": "import { app, shell, BrowserWindow, ipcMain, screen, Notification, powerSaveBlocker } from 'electron'\nimport { join } from 'path'\nimport { electronApp, is } from '@electron-toolkit/utils'\nimport icon from '../../build/icon.png?asset'\nimport { spawn, execSync } from 'child_process'\nimport Store from 'electron-store';\nStore.initRenderer()\nconst path = require('path')\nconst fs = require('fs');\nconst iconv = require('iconv-lite'); // 用于支持多种编码格式\nconst elStore = new Store()\nconst MAX_CONCURRENT_COPIES = 20; // 限制最大并行任务数\nlet limit;\n(async () => {\n  const { default: pLimit } = await import('p-limit');\n  limit = pLimit(MAX_CONCURRENT_COPIES);\n})();\nlet mainWindow: BrowserWindow | null = null;\n\napp.commandLine.appendSwitch('no-sandbox');\n// 启动电源保护\npowerSaveBlocker.start('prevent-display-sleep');\npowerSaveBlocker.start('prevent-app-suspension');\napp.commandLine.appendSwitch('enable-gpu-rasterization');  // 强制 GPU 光栅化\napp.commandLine.appendSwitch('ignore-gpu-blacklist');  // 忽略 Electron GPU 黑名单\napp.commandLine.appendSwitch('force-color-profile', 'srgb');  // 统一颜色配置\napp.commandLine.appendSwitch('disable-background-timer-throttling'); // 关闭后台定时器节流\n// 允许 GPU 但在必要时自动回退到软件渲染\napp.commandLine.appendSwitch('disable-software-rasterizer');\nconst syncFolders = [\"myImport\", \"myTranslate\", \"myFavorite\"]\nfunction createWindow(): void {\n  // Create the browser window.\n  mainWindow = new BrowserWindow({\n    width: 800,\n    height: 774,\n    resizable: false,\n    autoHideMenuBar: true,\n    frame: false,\n    transparent: true,\n    alwaysOnTop: false,\n    icon,\n    webPreferences: {\n      preload: join(__dirname, '../preload/index.js'),\n      sandbox: false,\n      nodeIntegration: false,\n      contextIsolation: true\n    }\n  })\n  mainWindow.on('ready-to-show', () => {\n    mainWindow?.show()\n  })\n\n  mainWindow.webContents.setWindowOpenHandler((details) => {\n    shell.openExternal(details.url)\n    return { action: 'deny' }\n  })\n\n  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {\n    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])\n  } else {\n    // Menu.setApplicationMenu(null)\n    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))\n  }\n\n  // 窗口拖动逻辑\n  let isMousePressed = false\n  let offsetX = 0\n  let offsetY = 0\n  let nowHeight = 774\n  let nowWidth = 800\n\n  ipcMain.on('mousedown', (_event, { }) => {\n    console.log(_event)\n    const cursorPoint = screen.getCursorScreenPoint()\n    let bounds:any = null\n    bounds = mainWindow?.getBounds()\n    if (bounds) {\n      isMousePressed = true\n      offsetX = cursorPoint.x - bounds.x // 精确鼠标偏移量\n      offsetY = cursorPoint.y - bounds.y\n    }\n  })\n\n  ipcMain.on('mousemove', (event) => {\n    console.log(event)\n   if (isMousePressed && mainWindow) {\n     const cursorPoint = screen.getCursorScreenPoint()\n     // 实时更新窗口位置\n     mainWindow.setBounds({\n       x: cursorPoint.x - offsetX,\n       y: cursorPoint.y - offsetY,\n       width: nowWidth,\n       height: nowHeight\n     })\n   }\n  })\n\n  ipcMain.on('mouseup', () => {\n    isMousePressed = false\n  })\n\n  ipcMain.on('window-min', (event) => {\n    console.log(event)\n    mainWindow?.minimize()\n  })\n\n  ipcMain.on('window-close', (event) => {\n    console.log(event)\n    ipcMain.removeAllListeners('mousedown')\n    ipcMain.removeAllListeners('mousemove')\n    ipcMain.removeAllListeners('mouseup')\n    mainWindow?.close()\n    app.quit()\n  })\n\n  ipcMain.on('set-always-on-top', (event) => {\n    console.log(event)\n    mainWindow?.setAlwaysOnTop(!mainWindow?.isAlwaysOnTop())\n  })\n\n  ipcMain.on('send_system_notification', (_event, title:string, body: string) => {\n    const notification = new Notification({title,body});\n    notification.show();  // 显示通知\n    setTimeout(()=>{\n      notification.close()\n    },1500)\n  })\n\n\n  ipcMain.on('window_size', (_event, height:number, width: number) => {\n    console.log(_event)\n    let bounds:any = null\n    bounds = mainWindow?.getBounds()\n\n    nowHeight = height === 0 ? 774 : height\n    nowWidth = width === 0 ? 800 : width\n    mainWindow?.setBounds({\n      x: bounds.x,\n      y: bounds.y,\n      width:nowWidth,\n      height:nowHeight\n    })\n  })\n\n  ipcMain.handle('read-file', async (_event, filePath:string, needData: boolean) => {\n    try {\n      let fileContent = await fs.promises.readFile(filePath, 'utf8');\n      const encodingList = ['utf8', 'utf16le', 'gbk']; // 支持的编码\n      for (const encoding of encodingList) {\n        try {\n          const buffer = await fs.promises.readFile(filePath);\n          fileContent = iconv.decode(buffer, encoding);\n          // 测试解析（假设文件是 JSON 格式）\n          JSON.parse(fileContent); // 尝试解析\n          break; // 成功解析则退出循环\n        } catch (err) {\n          // 如果解析失败，继续尝试下一个编码\n          fileContent = undefined;\n        }\n      }\n      if (needData){\n        return JSON.parse(fileContent)\n      }\n      return fileContent.includes(\"songNotes\")\n    } catch (err) {\n      console.error('Error loading JSON:', err);\n      return false;\n    }\n  });\n\n  ipcMain.handle('getVersion', (_event) => {\n    return app.getVersion()\n  });\n\n  // console.log('当前缓存存储位置',app.getPath('userData'))\n  ipcMain.on('setElStore', (_event, key, value) => {\n    elStore.set(key, value)\n  })\n\n  ipcMain.on('getElStore', (event, key) => {\n    const result = elStore.get(key)\n    event.returnValue = result\n  })\n\n  ipcMain.on('sync_sheet_2_el', async (_event,) =>{\n    let cachePath = elStore.path.replaceAll(\"\\\\config.json\", \"\");\n      for (const folder of syncFolders) {\n        fetch(\"http://127.0.0.1:9899/path\", {\n            method: 'POST', \n            headers: {\n              'Content-Type': 'application/json',\n            },\n            body: JSON.stringify({\n              \"type\": folder\n            }), \n          }).then(response => response.json())\n          .then(data =>{\n            copyFolderIncremental(data, path.join(cachePath, folder));\n          })\n          .catch(error => console.error(error))\n      }\n  })\n\n  ipcMain.on('sync_el_2_sheet', async (_event,) =>{\n    let cachePath = elStore.path.replaceAll(\"\\\\config.json\", \"\");\n    for (const folder of syncFolders) {\n      fetch(\"http://127.0.0.1:9899/path\", {\n        method: 'POST', \n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          \"type\": folder\n        }), \n      }).then(response => response.json()).then(data =>{ \n        copyFolderIncremental(path.join(cachePath, folder), data);\n      }).catch(error => console.error(error))\n    }\n  })\n\n  async function copyFolderIncremental(source, target) {\n    try {\n        target = path.resolve(target);\n        source = path.resolve(source);\n        console.log(\"target=>\", target);\n        console.log(\"source=>\", source);\n        // 检查源文件夹是否存在\n        let sourceExists = true;\n        try {\n            await fs.promises.access(source, fs.constants.F_OK);\n        } catch (err) {\n            sourceExists = false;\n            await fs.promises.mkdir(source, { recursive: true });\n        }\n        // 检查目标文件夹是否存在\n        let targetExists = true;\n        try {\n            await fs.promises.access(target, fs.constants.F_OK);\n        } catch (err) {\n            targetExists = false;\n        }\n        // 如果源文件夹不存在且目标文件夹存在，删除目标文件夹\n        if (!sourceExists && targetExists) {\n            await fs.promises.rm(target, { recursive: true, force: true });\n        }\n        // 确保目标文件夹存在\n        await fs.promises.mkdir(target, { recursive: true });\n        // 获取源文件夹中的文件列表\n        const sourceFiles = await fs.promises.readdir(source);\n        const sourceFilesSet = new Set(sourceFiles);\n        // 如果目标文件夹存在，检查需要删除的文件\n        if (targetExists) {\n            const targetFiles = await fs.promises.readdir(target);\n            const deletePromises = targetFiles\n                .filter(file => !sourceFilesSet.has(file))\n                .map(file => {\n                    const targetPath = path.join(target, file);\n                    return fs.promises.rm(targetPath, { recursive: true, force: true });\n                });\n            await Promise.all(deletePromises);\n        }\n        // 复制或更新文件\n        const copyTasks = sourceFiles.map(file => limit(async () => {\n            try {\n                const sourcePath = path.join(source, file);\n                const targetPath = path.join(target, file);\n                const sourceStats = await fs.promises.stat(sourcePath);\n\n                if (sourceStats.isFile()) {\n                    let shouldCopy = true;\n                    try {\n                        const targetStats = await fs.promises.stat(targetPath);\n                        shouldCopy = targetStats.mtimeMs < sourceStats.mtimeMs;\n                    } catch (err) {\n                        // 目标文件不存在，需要复制\n                    }\n                    if (shouldCopy) {\n                        await fs.promises.copyFile(sourcePath, targetPath);\n                    }\n                } else if (sourceStats.isDirectory()) {\n                    await copyFolderIncremental(sourcePath, targetPath);\n                }\n            } catch (err) {\n                console.error(`Error processing file ${file}:`, err);\n            }\n        }));\n        await Promise.all(copyTasks);\n    } catch (err) {\n        console.error(\"Error copying folder:\", err);\n        console.log(\"Continuing with other operations...\");\n    }\n  }\n\n\n}\n\napp.on('window-all-closed', () => {\n  app.quit();\n})\n\nfunction launchBackend() {\n  const args = ['--prod']\n  const exeName = 'sky_music_server.exe'\n  let runPath = __dirname.replace(\"resources\\\\app.asar\\\\out\\\\main\",\"\")\n  const exePath = path.join(runPath, 'backend_dist/sky_music_server/sky_music_server.exe')\n\n  if (!fs.existsSync(exePath)) {\n    console.error('[server] server File not found:', exePath)\n    return\n  }\n\n  if (isBackendRunning(exeName)) {\n    console.log('[server] is running, do Nothiong')\n    return\n  }\n\n  console.log('[server] starting:', exePath)\n\n  const subprocess = spawn(exePath, args, {\n    detached: true,\n    stdio: 'ignore',\n    windowsHide: true\n  })\n\n  subprocess.unref() // 让它在主进程退出后仍能运行\n}\n\nfunction isBackendRunning(processName: string): boolean {\n  try {\n    const stdout = execSync('tasklist', { encoding: 'utf-8' })\n    return stdout.toLowerCase().includes(processName.toLowerCase())\n  } catch (err) {\n    console.error('[check server] faild:', err)\n    return false\n  }\n}\n\n\napp.whenReady().then(() => {\n  electronApp.setAppUserModelId('com.windhide')\n  createWindow()\n  launchBackend()\n})\n\n"
  },
  {
    "path": "sky-music-web/src/preload/index.d.ts",
    "content": "import { ElectronAPI } from '@electron-toolkit/preload'\n\ndeclare global {\n  interface Window {\n    api: {\n      setAlwaysOnTop: () => void;\n      close: () => void;\n      mini: () => void;\n      async readFile: (filePath:string, needData: boolean) => any;\n      system_notification: (title,body) => void;\n      getVersion: () => any;\n      window_size: (height:number, width: number) => void;\n      syncElToSheetFiles\n      sync_el_2_sheet:() => void;\n      sync_sheet_2_el:() =>  void;\n    };\n    electron:{\n      onMouseDown: (x, y) => void;\n      onMouseMove: (x, y) => void;\n      onMouseUp: ()=> void;\n  }\n  }\n}\n"
  },
  {
    "path": "sky-music-web/src/preload/index.ts",
    "content": "import { contextBridge, ipcRenderer } from 'electron'\nimport { electronAPI } from '@electron-toolkit/preload'\n// Custom APIs for renderer\nconst api = {}\n// @ts-ignore (define in dts)\nconst elStore = {}\n\n// Use `contextBridge` APIs to expose Electron APIs to\n// renderer only if context isolation is enabled, otherwise\n// just add to the DOM global.\nif (process.contextIsolated) {\n  try {\n    contextBridge.exposeInMainWorld('api', {\n      setAlwaysOnTop: () => {\n        ipcRenderer.send('set-always-on-top');\n      },\n      close: () => {\n        ipcRenderer.send('window-close');\n      },\n      mini: () => {\n        ipcRenderer.send('window-min');\n      },\n      readFile: async (filePath: string, needData: boolean) => {\n        return await ipcRenderer.invoke('read-file', filePath, needData);\n      },\n      getVersion: () => {\n        return ipcRenderer.invoke('getVersion');\n      },\n      system_notification: async (title,body) => {\n        ipcRenderer.send('send_system_notification', title, body);\n      },\n      window_size: (height:number, width: number) => {\n        ipcRenderer.send('window_size', height, width);\n      },\n      sync_el_2_sheet:() => {\n        ipcRenderer.send('sync_el_2_sheet');\n      },\n      sync_sheet_2_el:() => {\n        ipcRenderer.send('sync_sheet_2_el');\n      }\n    });// 用于向主进程发送拖动事件\n    contextBridge.exposeInMainWorld('electron', {\n      onMouseDown: (x, y) => ipcRenderer.send('mousedown', { x, y }),\n      onMouseMove: (x, y) => ipcRenderer.send('mousemove', { x, y }),\n      onMouseUp: () => ipcRenderer.send('mouseup')\n    })\n    // 用于数据持久化\n    contextBridge.exposeInMainWorld('elStore', {\n      setElStore:(key, value)=>{\n        ipcRenderer.send('setElStore', key, value);\n      },\n      getElStore:(key)=>{\n        return ipcRenderer.sendSync('getElStore', key);\n      }\n    })\n  } catch (error) {\n    console.error(error)\n  }\n} else {\n  // @ts-ignore (define in dts)\n  window.electron = electronAPI\n  // @ts-ignore (define in dts)\n  window.api = api\n  // @ts-ignore (define in dts)\n  window.elStore = elStore\n}\n"
  },
  {
    "path": "sky-music-web/src/renderer/index.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Sky_Music</title>\n  <style>\n    html, body {\n      margin: 0;\n      padding: 0;\n      width: 100%;\n      height: 100%;\n      background: rgba(255, 255, 255, 0); /* 半透明背景 */\n      border-radius: 25px; /* 圆角设置 */\n      overflow: hidden;\n      border: .5px solid #eeeeee30;\n      box-sizing: border-box;\n    }\n  </style>\n  </head>\n\n  <body>\n    <div id=\"app\"></div>\n    <script type=\"module\" src=\"/src/main.ts\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/App.vue",
    "content": "<template>\n  <n-config-provider :theme=\"darkTheme\" :style=\"{ opacity : transparency_number}\" >\n    <n-flex id=\"drag-area\" justify=\"end\" style=\"position: fixed; z-index: 200; right: 18px\" :style=\"{ width: collapsed ? '90%' : '80%'}\">\n      <n-button text type=\"warning\" size=\"large\" style=\"margin-top: 12px; font-size: 20px;\" @click=\"syncSheetName\">\n        <n-icon size=\"25px\">\n          <ArrowSync16Filled />\n        </n-icon>\n      </n-button>\n      <n-popselect v-model:value=\"nowLang\" :options=\"options\" trigger=\"click\" @update:value=\"changeLang\" scrollable>\n          <n-button text size=\"large\" color=\"#A3F6EC\" style=\"margin-top: 12px; font-size: 20px;\" :round=\"false\"> \n            <n-icon size=\"25px\">\n              <Language />\n            </n-icon> \n          </n-button>\n      </n-popselect>\n      <n-popover style=\"border-radius: 17px; --n-color: rgba(47,47,55,1)\" trigger=\"click\">\n        <template #trigger>\n          <n-button text size=\"large\" color=\"#A3F6EC\" style=\"margin-top: 12px; font-size: 20px;\" :round=\"false\"> \n            <n-icon size=\"25px\">\n              <ColorPaletteOutline />\n            </n-icon> \n          </n-button>\n        </template>\n        <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\">{{ t('main.transparency') }}</n-gradient-text>\n        <n-slider v-model:value=\"transparency_number\" :step=\"0.01\" :max=\"1\" :min=\"0\" style=\"width: 200px;\"/>\n        <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\">{{ t('main.color') }}</n-gradient-text>\n        <n-color-picker :show-alpha=\"false\" v-model:value=\"colorPick\"/>\n      </n-popover>\n      <n-popover style=\"border-radius: 17px; --n-color: rgba(47,47,55,1)\" trigger=\"click\">\n        <template #trigger>\n          <n-button text size=\"large\" color=\"#D0BDF4\" style=\"margin-top: 12px; font-size: 20px;\" :round=\"false\"> \n            <n-icon size=\"25px\">\n              <Settings48Regular />\n            </n-icon> \n          </n-button>\n        </template>\n        <n-switch size=\"small\" v-model:value=\"is_compatibility_mode\" @update:value=\"CompatibilityModeChange\" :rail-style=\"railStyle\" :round=\"false\"> \n            <template #checked>\n              <p style=\"color: rgba(94, 104, 81, 0.75);\">{{ t('main.compatible') }}</p>\n            </template>\n            <template #unchecked>\n              <p style=\"color: rgba(94, 104, 81, 0.75);\">{{ t('main.backend') }}</p>\n            </template>\n          </n-switch> \n          <br>\n          <n-switch size=\"small\" v-model:value=\"isPostW\" @update:value=\"PostWChange\" :rail-style=\"railStyle\" v-show=\"is_compatibility_mode != true\" :round=\"false\"> \n              <template #checked>\n                <p style=\"color: rgba(94, 104, 81, 0.75);\">{{ t('main.queue') }}</p>\n              </template>\n              <template #unchecked>\n                <p style=\"color: rgba(94, 104, 81, 0.75);\">{{ t('main.cut') }}</p>\n              </template>\n          </n-switch>\n          <br>\n          <n-switch size=\"small\" v-model:value=\"isRunnable\" @update:value=\"RunnableChange\" :rail-style=\"railStyle\" v-show=\"is_compatibility_mode != true\" :round=\"false\"> \n              <template #checked>\n                <p style=\"color: rgba(94, 104, 81, 0.75);\">{{ t('main.multi_core') }}</p>\n              </template>\n              <template #unchecked>\n                <p style=\"color: rgba(94, 104, 81, 0.75);\">{{ t('main.single_core') }}</p>\n              </template>\n          </n-switch>\n      </n-popover>\n      <n-button text :dashed=\"fixDashed\" size=\"large\" color=\"#F2C9C4\" style=\"margin-top: 12px; font-size: 20px;\" @click=\"fixHandle\">\n        <n-icon size=\"25px\">\n          <Pin48Regular v-if=\"fixDashed\" />\n          <Pin48Filled v-else />\n        </n-icon>\n      </n-button>\n      <n-button text type=\"warning\" size=\"large\" style=\"margin-top: 12px; font-size: 20px;\" @click=\"openFileHandle\">\n        <n-icon size=\"25px\">\n          <ImageOutline />\n        </n-icon>\n      </n-button>\n      <n-button text type=\"info\" size=\"large\" style=\"margin-top: 12px; font-size: 25px;\" @click=\"miniHandle\">\n          <n-icon>\n            <RemoveSharp />\n          </n-icon>\n      </n-button>\n      <n-button text type=\"error\" size=\"large\" style=\"margin-top: 12px; font-size: 25px;\" @click=\"closeHandle\">\n          <n-icon>\n            <Close />\n          </n-icon>\n      </n-button>\n    </n-flex>\n    <n-spin :show=\"show\" :size=\"90\" stroke=\"#F2E8C4\">\n      <n-message-provider>\n        <n-dialog-provider>\n          <n-space vertical>\n            <n-layout>\n              <n-layout has-sider>\n                <n-layout-sider  v-show=\"route.fullPath.indexOf('keyboard') == -1\" bordered show-trigger \n                  collapse-mode=\"width\" :collapsed-width=\"64\" :width=\"150\" :native-scrollbar=\"false\" @update:collapsed=\"collapsedHandle\"\n                  :style=\"{\n                    height: '100vh',\n                    backgroundColor: colorPick+ ' !important'\n                  }\"\n                  >\n                  <n-menu :collapsed-width=\"64\" :collapsed-icon-size=\"23\" :options=\"menuOptions\"\n                    @update:value=\"clickMenu\" />\n                </n-layout-sider>\n                  <n-layout \n                  :style=\"{\n                    padding: '30px 20px 0px 20px',\n                    backgroundColor: colorPick+' !important'\n                  }\"\n                  >\n                  <router-view />\n                </n-layout>\n              </n-layout>\n            </n-layout>\n          </n-space>\n        </n-dialog-provider>\n      </n-message-provider>\n      <template #description> <div style=\"color: #F2E8C4;\">{{ t('main.loading') }}</div> </template>\n    </n-spin>\n  </n-config-provider>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { Component, CSSProperties } from 'vue'\nimport { h, onMounted, ref, nextTick, computed } from 'vue'\nimport { NIcon, darkTheme, NMessageProvider } from 'naive-ui'\nimport { getData, sendData } from '@renderer/utils/fetchUtils'\nimport {\n  CubeSharp,\n  Home,\n  MusicalNotes,\n  GameController,\n  Close,\n  RemoveSharp,\n  Flask,\n  ImageOutline,\n  Settings,\n  PlanetSharp,\n  ColorPaletteOutline,\n  PulseSharp,\n  Language,\n  LogoGoogle\n} from '@vicons/ionicons5'\nimport {\n  Pin48Regular,\n  Pin48Filled,\n  Settings48Regular,\n  Compose24Filled,\n  ArrowSync16Filled\n} from '@vicons/fluent'\nimport router from '@renderer/router'\nimport { useRoute } from 'vue-router'\nimport { useI18n } from \"vue-i18n\";\nconst { t, locale } = useI18n();\nconst route = useRoute()\nconst collapsed = ref(false)\nconst is_compatibility_mode = ref(false)\nconst isPostW = ref(true)\nconst isRunnable = ref(true)\nconst transparency_number = ref(1.00)\nconst colorPick = ref(\"#101014\")\nconst nowLang = ref('zh_cn')\nconst options = [\n  {\n    label: \"简体中文\",\n    value: \"zh_cn\"\n  },\n  {\n    label: \"文言文\",\n    value: \"zh_classical\"\n  },\n  {\n    label: \"繁體中文\",\n    value: \"zh_tw\"\n  },\n  {\n    label: \"English\",\n    value: \"en\"\n  },\n  {\n    label: \"日本語\",\n    value: \"jp\"\n  },\n  {\n    label: \"한국어\",\n    value: \"ko\"\n  }\n];\n\nfunction fixHandle() {\n  if (fixDashed.value) {\n    window.api.setAlwaysOnTop();\n    fixDashed.value = false\n  } else {\n    window.api.setAlwaysOnTop();\n    fixDashed.value = true\n  }\n}\n\nfunction railStyle({ focused, checked }){\n  const style: CSSProperties = {}\n  if (checked) {\n    style.background = '#F2C9C4'\n    if (focused) {\n      style.boxShadow = '0 0 0 2px #F2C9C440'\n    }\n  }\n  else {\n    style.background = '#F2E8C4'\n    if (focused) {\n      style.boxShadow = '0 0 0 2px #F2E8C440'\n    }\n  }\n  return style\n}\n\nfunction openFileHandle() {\n  sendData('openFiles',{\n      \"operate\":\"images\"\n  })\n}\n\nfunction syncSheetName() {\n  getData('syncSheetName').then(_res=>{\n    window.api.sync_sheet_2_el()\n  })\n  \n}\n\nfunction miniHandle() {\n  window.api.mini()\n}\nfunction closeHandle() {\n  window.api.close()\n}\n\nfunction renderIcon(icon: Component) {\n  return () => h(NIcon, null, { default: () => h(icon) });\n}\n\nconst collapsedHandle = (isCoolapsed: boolean) => {\n  console.log(isCoolapsed)\n  collapsed.value = isCoolapsed\n}\n\nlet show = ref(true)\nlet fixDashed = ref(true)\nconst menuOptions = computed(() => [\n  {\n    label: t('main.menu.home'),\n    key: \"home\",\n    icon: renderIcon(Home),\n  },\n  {\n    label: t('main.menu.music'),\n    key: \"music\",\n    icon: renderIcon(MusicalNotes),\n  },\n  {\n    label: t('main.menu.tutorial'),\n    key: \"tutorial\",\n    icon: renderIcon(GameController),\n  },\n  {\n    label: t('main.menu.kube'),\n    key: \"kube\",\n    icon: renderIcon(CubeSharp),\n  },\n  {\n    label: t('main.menu.shortcut'),\n    key: \"shortcut\",\n    icon: renderIcon(PlanetSharp),\n  },\n  {\n    label: t('main.menu.musicEdit'),\n    key: \"musicEdit\",\n    icon: renderIcon(Compose24Filled),\n  },\n  {\n    key: \"kube\",\n    type: \"divider\"\n  },\n  {\n    label: t(\"main.menu.aisetting\"),\n    key: \"aiSetting\",\n    icon: renderIcon(LogoGoogle)\n  },\n  {\n    label: t('main.menu.setting'),\n    key: \"setting\",\n    icon: renderIcon(Settings),\n  },\n  {\n    label: t('main.menu.hwndHandle'),\n    key: \"hwndHandle\",\n    icon: renderIcon(PulseSharp),\n  },\n  {\n    label: t('main.menu.magicTools'),\n    key: \"magicTools\",\n    icon: renderIcon(Flask),\n  },\n]);\n\nconst clickMenu = (key: string) => {\n  router.push({ name: key });\n};\n\nlet checkInterval = setInterval(() => {\n  getData(\"check\").then(res => {\n    if (res === undefined) return\n    show.value = !res\n    clearInterval(checkInterval)\n    LoadData()\n    window.api.sync_el_2_sheet()\n    router.push({ name: 'home', query: { show: 1 } });\n  });\n}, 500)\n\nfunction CompatibilityModeChange(value: boolean){\n  sendData(\"config_operate\",{\n    operate:\"set\",\n    name:\"compatibility_mode\",\n    value\n  })\n}\n\nfunction PostWChange(value: boolean){\n  sendData(\"config_operate\",{\n    operate:\"set\",\n    name:\"is_post_w\",\n    value\n  })\n}\n\nfunction RunnableChange(value: boolean){\n  sendData(\"config_operate\",{\n    operate: \"set\",\n    name: \"cpu_type\",\n    value\n  })\n}\n\nfunction changeLang(value: string) {\n  // 更新locale值并保存到localStorage\n  locale.value = value\n  localStorage.setItem('sky-music-language', value)\n  show.value = true\n  nextTick(async () => {\n    const newMenuOptions = [\n      {\n        label: t('main.menu.home'),\n        key: \"home\",\n        icon: renderIcon(Home),\n      },\n      {\n        label: t('main.menu.music'),\n        key: \"music\",\n        icon: renderIcon(MusicalNotes),\n      },\n      {\n        label: t('main.menu.tutorial'),\n        key: \"tutorial\",\n        icon: renderIcon(GameController),\n      },\n      {\n        label: t('main.menu.kube'),\n        key: \"kube\",\n        icon: renderIcon(CubeSharp),\n      },\n      {\n        label: t('main.menu.shortcut'),\n        key: \"shortcut\",\n        icon: renderIcon(PlanetSharp),\n      },\n      {\n        label: t('main.menu.musicEdit'),\n        key: \"musicEdit\",\n        icon: renderIcon(Compose24Filled),\n      },\n      {\n        key: \"kube\",\n        type: \"divider\"\n      },\n      {\n        label: t(\"main.menu.aisetting\"),\n        key: \"aiSetting\",\n        icon: renderIcon(LogoGoogle)\n      },\n      {\n        label: t('main.menu.setting'),\n        key: \"setting\",\n        icon: renderIcon(Settings),\n      },\n      {\n        label: t('main.menu.hwndHandle'),\n        key: \"hwndHandle\",\n        icon: renderIcon(PulseSharp),\n      },\n      {\n        label: t('main.menu.magicTools'),\n        key: \"magicTools\",\n        icon: renderIcon(Flask),\n      }\n    ]\n    Object.assign(menuOptions, newMenuOptions)\n    const currentRoute = route.name\n    // 跳转到设置页再跳回原页面，切换过程中显示Loading\n    let target = currentRoute\n    await router.push({ name: 'setting' })\n    await nextTick()\n    await router.push({ name: target })\n    show.value = false\n  })\n}\n\nfunction LoadData(){\n  sendData(\"config_operate\",{\n    operate: \"cpu_type\" \n  }).then(res=>{\n    isRunnable.value = res\n  })\n}\n\nonMounted(() => {\n  // 从localStorage获取保存的语言设置，初始化当前语言\n  const savedLanguage = localStorage.getItem('sky-music-language')\n  if (savedLanguage) {\n    nowLang.value = savedLanguage\n    locale.value = savedLanguage\n  }\n\n  const dragArea = document.getElementById('drag-area')\n  if (dragArea) {\n    let startX, startY\n\n    dragArea.addEventListener('mousedown', (event) => {\n      startX = event.clientX\n      startY = event.clientY\n\n      window.electron.onMouseDown(startX, startY)\n      const onMouseMove = (moveEvent) => {\n        const deltaX = moveEvent.clientX - startX\n        const deltaY = moveEvent.clientY - startY\n        window.electron.onMouseMove(deltaX, deltaY)\n      }\n      const onMouseUp = () => {\n        document.removeEventListener('mousemove', onMouseMove)\n        document.removeEventListener('mouseup', onMouseUp)\n        window.electron.onMouseUp()\n      }\n\n      document.addEventListener('mousemove', onMouseMove)\n      document.addEventListener('mouseup', onMouseUp)\n    })\n  } else {\n    console.error('drag-area element not found')\n  }\n})\n</script>\n\n<style scoped>\n:deep(.n-menu--vertical){\n  --n-border-radius: 21px !important;\n  --n-item-text-color-active: rgb(242,232,196) !important;\n  --n-item-icon-color-active: rgb(242,232,196) !important;\n  --n-item-text-color-active-hover: rgb(242,232,196) !important;\n  --n-item-icon-color: rgba(221,242,196, 0.82) !important;\n  --n-item-icon-color-hover:  rgb(242,201,196) !important;\n  --n-item-icon-color-active: rgb(242,232,196) !important;\n  --n-item-icon-color-active-hover: rgb(242,232,196) !important;\n  --n-item-icon-color-child-active: rgb(242,232,196) !important;\n  --n-item-icon-color-child-active-hover: rgb(242,232,196) !important;\n  --n-item-icon-color-collapsed: rgba(255, 255, 255, 0.9);\n  --n-item-color-active: rgba(242,232,196,0.15) !important;\n  --n-item-color-active-hover: rgba(242,232,196,0.3) !important;\n  --n-item-icon-color-collapsed: rgba(221,242,196, 0.82) !important;\n}\n:deep(.n-menu-item-content){\n  --n-item-text-color: rgba(221,242,196, 0.82) !important;\n  --n-item-text-color-hover: rgb(242,201,196) !important;\n  color: rgba(94, 104, 81, 0.82);\n}\n:deep(.n-slider-rail__fill){\n  --n-fill-color-hover: #A3F6EC !important;\n  background-color: #A3F6EC !important;\n}\n</style>\n\n<style>\n.n-card {\n  background-color: rgba(242, 201, 196, 0) !important;\n}\n.n-menu-divider {\n  margin-bottom: 275px;\n  background-color: rgba(242, 201, 196, 0);\n}\n.n-drawer-mask,.n-drawer{\n  border-radius: 26px !important;\n}\n</style>"
  },
  {
    "path": "sky-music-web/src/renderer/src/component/svg/cr.vue",
    "content": "<template><svg version=\"0.0\" width=\"63.876953\" height=\"63.876953\" id=\"svg3639\" xmlns=\"http://www.w3.org/2000/svg\"\n><path d=\"M 31.939164,9.4384766 A 22.500162,22.500162 0 0 0 9.4384767,31.939165 22.500162,22.500162 0 0 0 31.939164,54.438477 22.500162,22.500162 0 0 0 54.438476,31.939165 22.500162,22.500162 0 0 0 31.939164,9.4384766 Z m 0,2.5303484 A 19.969496,19.969496 0 0 1 51.908129,31.939165 19.969496,19.969496 0 0 1 31.939164,51.90813 19.969496,19.969496 0 0 1 11.968824,31.939165 19.969496,19.969496 0 0 1 31.939164,11.968825 Z\" id=\"path3629\" style=\"stroke-width:0.983987\"/><defs id=\"defs3633\"/></svg></template><script setup lang=\"ts\" />"
  },
  {
    "path": "sky-music-web/src/renderer/src/component/svg/dm.vue",
    "content": "<template><svg version=\"0.0\" width=\"63.876953\" height=\"63.876953\" id=\"svg3639\" xmlns=\"http://www.w3.org/2000/svg\"\n><path d=\"M 30.878793,1.0626133 1.0626133,30.878793 a 1.4999541,1.4999541 89.999124 0 0 3.24e-5,2.121288 L 30.87876,62.814372 a 1.5000459,1.5000459 179.99912 0 0 2.121353,-3.2e-5 L 62.81434,33.000113 a 1.5000459,1.5000459 90.000876 0 0 3.2e-5,-2.121353 L 33.000081,1.0626457 a 1.4999541,1.4999541 8.7588976e-4 0 0 -2.121288,-3.24e-5 z m 2.121284,3.400427 26.413908,26.4157167 a 1.5000513,1.5000513 90.00098 0 1 -3.6e-5,2.121356 L 33.000113,59.413949 a 1.5000513,1.5000513 179.99902 0 1 -2.121356,3.6e-5 L 4.4630403,33.000077 A 1.4999487,1.4999487 89.99902 0 1 4.463004,30.878793 L 30.878793,4.463004 a 1.4999487,1.4999487 9.804247e-4 0 1 2.121284,3.63e-5 z\"/></svg></template><script setup lang=\"ts\" />"
  },
  {
    "path": "sky-music-web/src/renderer/src/component/svg/dmcr.vue",
    "content": "<template><svg version=\"0.0\" width=\"63.876953\" height=\"63.876953\" id=\"svg3639\" xmlns=\"http://www.w3.org/2000/svg\"\n><path d=\"M 31.939164,9.4384766 A 22.500162,22.500162 0 0 0 9.4384767,31.939165 22.500162,22.500162 0 0 0 31.939164,54.438477 22.500162,22.500162 0 0 0 54.438476,31.939165 22.500162,22.500162 0 0 0 31.939164,9.4384766 Z m 0,2.5303484 A 19.969496,19.969496 0 0 1 51.908129,31.939165 19.969496,19.969496 0 0 1 31.939164,51.90813 19.969496,19.969496 0 0 1 11.968824,31.939165 19.969496,19.969496 0 0 1 31.939164,11.968825 Z\" id=\"path3629\" style=\"stroke-width:0.983987\"/><defs id=\"defs3633\"/><path id=\"path3635\" d=\"M 30.878793,1.0626133 1.0626133,30.878793 a 1.4999541,1.4999541 89.999124 0 0 3.24e-5,2.121288 L 30.87876,62.814372 a 1.5000459,1.5000459 179.99912 0 0 2.121353,-3.2e-5 L 62.81434,33.000113 a 1.5000459,1.5000459 90.000876 0 0 3.2e-5,-2.121353 L 33.000081,1.0626457 a 1.4999541,1.4999541 8.7588976e-4 0 0 -2.121288,-3.24e-5 z m 2.121284,3.400427 26.413908,26.4157167 a 1.5000513,1.5000513 90.00098 0 1 -3.6e-5,2.121356 L 33.000113,59.413949 a 1.5000513,1.5000513 179.99902 0 1 -2.121356,3.6e-5 L 4.4630403,33.000077 A 1.4999487,1.4999487 89.99902 0 1 4.463004,30.878793 L 30.878793,4.463004 a 1.4999487,1.4999487 9.804247e-4 0 1 2.121284,3.63e-5 z\"/></svg></template><script setup lang=\"ts\" />"
  },
  {
    "path": "sky-music-web/src/renderer/src/env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n\ndeclare module '*.vue' {\n  import type { DefineComponent } from 'vue'\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types\n  const component: DefineComponent<{}, {}, any>\n  export default component\n}\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/i18n/index.ts",
    "content": "import { createI18n } from 'vue-i18n'\nimport zh_cn from './locales/zh-cn.json'\nimport zh_classical from './locales/zh-classical.json'\nimport zh_tw from './locales/zh-tw.json'\nimport en from './locales/en.json'\nimport jp from './locales/jp.json'\nimport ko from './locales/ko.json'\n\n// 从localStorage获取保存的语言设置，如果没有则使用默认值'zh_cn'\nconst savedLanguage = localStorage.getItem('sky-music-language') || 'zh_cn'\n\nconst i18n = createI18n({\n  legacy: false,\n  locale: savedLanguage,\n  fallbackLocale: 'zh_cn',\n  messages: {\n    zh_cn,\n    zh_classical,\n    zh_tw,\n    en,\n    jp,\n    ko\n  }\n})\n\nexport default i18n"
  },
  {
    "path": "sky-music-web/src/renderer/src/i18n/locales/en.json",
    "content": "{\n  \"columns\": {\n    \"name\": \"Song title\",\n    \"operation\": \"operate\",\n    \"total_duration\": \"Duration\"\n  },\n  \"home\": {\n    \"head_text\": \"If you think it's easy to use, you can enjoy a cup of coffee☕\",\n    \"patterns0\": \"completely free\",\n    \"patterns1\": \"Being cheated\",\n    \"patterns2\": \"Coffee☕\",\n    \"qq\": \"Q group\",\n    \"qq_sb\": \"channel\",\n    \"text\": \"Welcome to use. This software is completely free\",\n    \"tutorial\": \"tutorial\",\n    \"update\": \"It's the latest version\",\n    \"update_error\": \"Update detection error\",\n    \"update_info\": \"Can't detect the new version of the software, try to repair the network\"\n  },\n  \"hwnd_handle\": {\n    \"columns\": {\n      \"exe_name\": \"Process name\",\n      \"hwnd\": \"Handle\",\n      \"operation\": \"Select\",\n      \"pid\": \"PID\",\n      \"title\": \"Software title\"\n    },\n    \"head_text\": \"Here is the target sent by the background. No games except light encounters have been tested and will not be repaired.\",\n    \"head_text2\": \"Because of this function, other games have been blocked, don’t look for me. \\nDepend on the game's anti-cheating mechanism\",\n    \"now_hwnd\": \"Now handle >\",\n    \"patterns0\": \"Change the destination sent in the background\",\n    \"patterns1\": \"Light encounter\",\n    \"patterns2\": \"Not tested\",\n    \"patterns3\": \"Won't\",\n    \"patterns4\": \"Don't look for me\",\n    \"patterns5\": \"lead to\",\n    \"patterns6\": \"title\",\n    \"patterns7\": \"Anti-cheating mechanism\",\n    \"refresh\": \"Refresh the list\",\n    \"reset\": \"Reset\",\n    \"reset_sky\": \"Reset to light encounter window\"\n  },\n  \"kube\": {\n    \"Streng_filter\": \"Force filtering (less than milliseconds)\",\n    \"all_t\": \"Full sound conversion only\",\n    \"chose_music\": \"Select\",\n    \"dual\": \"Even keys\",\n    \"dynamic_merge\": \"Dynamic merge threshold range division\",\n    \"get_fail\": \"Failed to get {value}\",\n    \"half_t\": \"Convert semitone\",\n    \"odd\": \"Singular keys\",\n    \"other_key\": \"Super 3 tone change\",\n    \"range_key\": \"Range conversion only\",\n    \"scale\": {\n      \"scale2\": \"Sky range_2 sets\",\n      \"scale3\": \"3 sets\",\n      \"scale4\": \"4 sets\",\n      \"scale5\": \"5 sets\",\n      \"scale6\": \"6 sets\"\n    },\n    \"star_transfer\": \"conversion\",\n    \"title\": \"Convert songs\",\n    \"transfer_fail\": \"Conversion failed\",\n    \"transfer_progress\": \"Conversion progress\",\n    \"transfer_success\": \"Conversion successfully\"\n  },\n  \"magic_tools\": {\n    \"buttons\": {\n      \"abaaba\": \"Scream\",\n      \"autoFire\": \"Automatic ignition\",\n      \"check\": \"examine\",\n      \"developer\": \"Developer customization\",\n      \"heart_fire\": \"Heart fire\",\n      \"key\": \"button\",\n      \"shutdown\": \"Terminate thread\"\n    },\n    \"fileButtons\": {\n      \"myFavorite\": \"love\",\n      \"myImport\": \"Imported\",\n      \"myTranslate\": \"Converted\",\n      \"systemMusic\": \"System music\",\n      \"translateMID\": \"MIDI\"\n    },\n    \"head_text\": \"Here is the beta function, please use it with caution, no memory modification is involved.\",\n    \"head_text2\": \"This function is for learning and communication only and is strictly prohibited for commercial purposes. Please delete it within 24 hours\",\n    \"head_text3\": \"🚫Simulator players are prohibited from using all the following functions🚫\",\n    \"messeage\": {\n      \"start\": \"Now start automatically clicking on Heart Fire\",\n      \"stop\": \"termination! \\n! \\n! \\n! \\n!\"\n    },\n    \"patterns0\": \"Use with caution 🌶\",\n    \"patterns1\": \"No memory modification involved 🌶\",\n    \"patterns2\": \"This function is for learning and communication only and is strictly prohibited for commercial purposes. Please delete it within 24 hours\",\n    \"patterns3\": \"🚫Simulator players are prohibited from using all the following functions🚫\"\n  },\n  \"main\": {\n    \"backend\": \"Background mode\",\n    \"color\": \"Background color\",\n    \"compatible\": \"Compatibility mode\",\n    \"cut\": \"Cut-in mode\",\n    \"loading\": \"🍉Application is loading, please wait~\",\n    \"menu\": {\n      \"home\": \"introduce\",\n      \"hwndHandle\": \"Handle\",\n      \"kube\": \"TranSheet\",\n      \"magicTools\": \"Developer\",\n      \"music\": \"Music\",\n      \"musicEdit\": \"Edit\",\n      \"setting\": \"Music Set\",\n      \"shortcut\": \"Shortcut\",\n      \"tutorial\": \"Follow\",\n      \"aisetting\": \"AI setting\"\n    },\n    \"multi_core\": \"Multi-core mode\",\n    \"queue\": \"Queue mode\",\n    \"single_core\": \"Single-core mode\",\n    \"transparency\": \"transparency\"\n  },\n  \"messeage\": {\n    \"choose_plz\": \"Choose a song and play it with the handsome guy\",\n    \"progress_fail\": \"Failed to obtain progress\",\n    \"remove_fail\": \"Deletion failed\",\n    \"remove_success\": \"Removal successfully\",\n    \"double_click\": \"Double-click the song to play!\",\n    \"msg1\": \"Only allow start\",\n    \"msg10\": \"The maximum sustain sound is 2\",\n    \"msg11\": \"Sustain 0.01\",\n    \"msg12\": \"The lowest sustain sound is 0\",\n    \"msg13\": \"Sustain -0.01\",\n    \"msg14\": \"The maximum interval is 2\",\n    \"msg15\": \"Interval 0.01\",\n    \"msg16\": \"The minimum interval is 0\",\n    \"msg17\": \"Interval-0.01\",\n    \"msg18\": \"The maximum speed is 5\",\n    \"msg19\": \"Speed ​​0.1\",\n    \"msg2\": \"Choose a song and play it. Beautiful\",\n    \"msg20\": \"The lowest speed is 0.1\",\n    \"msg21\": \"Speed ​​-0.1\",\n    \"msg3\": \"start\",\n    \"msg4\": \"continue\",\n    \"msg5\": \"Only allow for continued\",\n    \"msg6\": \"pause\",\n    \"msg7\": \"Pause is allowed only when it is playing\",\n    \"msg8\": \"stop\",\n    \"msg9\": \"Next\",\n    \"no_import\": \"Import failed\",\n    \"no_music\": \"There are no songs playing\",\n    \"no_now\": \"Nothing, kid, really nothing 😭, try another category\",\n    \"ok_import\": \"Complete the import\",\n    \"order_ok\": \"The song on the list is finished\",\n    \"sheet\": \"Score👉\",\n    \"unknow_music\": \"Unknown songs\"\n  },\n  \"music_edit\": {\n    \"dialog\": {\n      \"content\": \"Are you sure you want to clear all scores in the current work area? \\nUnsaved changes will be lost.\",\n      \"content2\": \"Are you sure you want to leave the score editing page? \\nUnsaved changes will be lost.\",\n      \"negativeText\": \"If I don't clear, I'll save it first\",\n      \"negativeText2\": \"I'll save it first if I don't leave\",\n      \"positiveText\": \"Just clear it, clear it\",\n      \"positiveText2\": \"Just leave\",\n      \"title\": \"A warm tip from the developer ⭐\"\n    },\n    \"sheet\": {\n      \"error\": {\n        \"data\": \"Error in spectral data format\",\n        \"sheet_data\": \"Spectral Note Data Format Error\"\n      },\n      \"load_fail\": \"Spectrum loading failed\",\n      \"load_success\": \"The score loaded successfully\"\n    },\n    \"tips\": {\n      \"afer_add_column\": \"Insert a new column after the current highlighted column\",\n      \"clear_sheet\": \"Clear the score of the current workspace\",\n      \"copy_now_to_end\": \"Copy a copy to the end of the current highlighted column\",\n      \"copy_now_to_head\": \"Copy a copy to the beginning of the current highlighted column\",\n      \"copy_now_to_next\": \"Copy a copy of the current highlighted column to the next column\",\n      \"copy_now_to_pre\": \"Copy a copy of the current highlighted column to the previous column\",\n      \"delete_now_column\": \"Delete the current highlighted column\",\n      \"next_column\": \"Next column\",\n      \"pause\": \"pause\",\n      \"play\": \"Play\",\n      \"play_now_column\": \"The highlighted column is in the game and press\",\n      \"pre_column\": \"Previous column\",\n      \"save_sheet\": \"Save the spectrum\",\n      \"select_in_music\": \"Select songs from the song list\",\n      \"tip1\": \"The long press interval needs to be less than the column and wait for the delay, and it has been automatically adjusted (currently)\",\n      \"tip2\": \"Copy to the beginning\",\n      \"tip3\": \"Copyed to previous column\",\n      \"tip4\": \"Copyed to the next column\",\n      \"tip5\": \"Copyed to the last column\",\n      \"tip6\": \"The long press interval needs to be less than the waiting interval, and the waiting delay after the column has been automatically increased (currently)\",\n      \"tip7\": \"The waiting delay after column cannot be less than 10, and has been automatically adjusted (new globally)\",\n      \"tip8\": \"The waiting delay after long pressing is less than the column, 10ms, has been automatically adjusted (new globally)\",\n      \"upend\": \"Put it upside down\",\n      \"upload_sheet\": \"Upload score edit\"\n    },\n    \"title\": {\n      \"add_new_after_column\": \"Waiting delay after added column\",\n      \"add_new_count_column\": \"Number of new columns\",\n      \"add_new_druation_column\": \"New long press interval\",\n      \"change_send_key_in_game\": \"Send keys to the game via column\",\n      \"columnAfterDuration\": \"Waiting delay after column\",\n      \"columnDownDuration\": \"long press column\",\n      \"func_area_tip\": \"Ribbon prompts\",\n      \"global_after\": \"Delay after glo column\",\n      \"global_down\": \"Long press area\",\n      \"set\": \"set up\",\n      \"sheet_area_color\": \"Alternating colors in the spectrum area\",\n      \"sheet_name\": \"Song name\",\n      \"sheet_name_placeholder\": \"Song Name/File Name\"\n    },\n    \"total_column\": \"Total column count: {length}\",\n    \"total_time\": \"Total length of music score: {length}\"\n  },\n  \"setting\": {\n    \"clearAll\": \"Shortcut keys have been reset\",\n    \"clearNow\": \"This key has been cleared\",\n    \"head_text\": \"The piano map takes effect for this operation. Restarting the software requires reset. If you do not adapt, please adapt as soon as possible.\",\n    \"key_map\": \"Key Mapping\",\n    \"ok\": \"Set\",\n    \"patterns0\": \"This run\",\n    \"patterns1\": \"again\",\n    \"patterns2\": \"Restart\",\n    \"patterns3\": \"Adapt to it as soon as possible\",\n    \"repeat\": \"There are duplicate shortcut key values, please check the configuration.\",\n    \"reset_map\": \"Reset piano shooting\"\n  },\n  \"shortcutKeys\": {\n    \"button_title\": {\n      \"add_delay\": \"interval\",\n      \"add_duration\": \"+ Suspension\",\n      \"add_speed\": \"+ speed\",\n      \"exit\": \"quit\",\n      \"next\": \"Next\",\n      \"pause\": \"pause\",\n      \"reduce_delay\": \"- Interval\",\n      \"reduce_duration\": \"- Suspension\",\n      \"reduce_speed\": \"- speed\",\n      \"repeat\": \"repeat\",\n      \"repeat_next\": \"Repeat & step\",\n      \"resize\": \"Reload keys\",\n      \"resume\": \"continue\",\n      \"start\": \"Play\",\n      \"stop\": \"stop\"\n    },\n    \"divider1\": \"Music shortcut keys\",\n    \"divider2\": \"Follow the shortcut key\",\n    \"head_text\": \"The shortcut keys are effective for this operation. Restarting the software requires reset. If you do not adapt, please adapt as soon as possible.\",\n    \"patterns0\": \"This run\",\n    \"patterns1\": \"again\",\n    \"patterns2\": \"Restart\",\n    \"patterns3\": \"Adapt to it as soon as possible\",\n    \"title\": \"Reset shortcut key\"\n  },\n  \"tab\": {\n    \"love_success\": \"Successfully collected\",\n    \"myFavorite\": \"love\",\n    \"myImport\": \"Import\",\n    \"myTranslate\": \"Converted\",\n    \"remove_success\": \"Removal successfully\",\n    \"search\": \"search\",\n    \"systemMusic\": \"systemMusic\",\n    \"translateOriginalMusic\": \"Unconverted songs\",\n    \"clear\": \"Clear\",\n    \"title\": \"Playlist\"\n  },\n  \"tutorial\": {\n    \"chose_music\": \"Please select a song first\",\n    \"error\": \"The conversion failed, please try again\",\n    \"error_console\": \"Conversion failed\",\n    \"follow\": \"Start following the bullet\",\n    \"no_music\": \"No songs\",\n    \"now\": \"Current: {music}\",\n    \"save\": \"Save visual scores to desktop\",\n    \"save_desktop\": \"Saved on desktop\"\n  },\n  \"controller\": {\n    \"no_music\": \"No songs\"\n  },\n  \"music\": {\n    \"chose\": \"Play:\",\n    \"placeholder1\": \"interval\",\n    \"placeholder2\": \"Sustaining sound\",\n    \"play\": \"choose:\",\n    \"space\": {\n      \"chose0\": \"System comes with\",\n      \"chose1\": \"random\",\n      \"chose2\": \"Customize\",\n      \"mult_speed\": \"Double the speed\",\n      \"title\": \"Interval delay\",\n      \"title1\": \"Sustain Settings\"\n    }\n  },\n  \"rule\": {\n    \"cycle\": \"cycle\",\n    \"order\": \"order\",\n    \"random\": \"random\"\n  }\n}\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/i18n/locales/jp.json",
    "content": "{\n  \"main\": {\n    \"loading\": \"🍉アプリケーションをロード中、少々お待ちください~\",\n    \"compatible\": \"互換モード\",\n    \"backend\": \"バックエンドモード\",\n    \"queue\": \"キュー・モード\",\n    \"cut\": \"割り込みモード\",\n    \"multi_core\": \"マルチコアモード\",\n    \"single_core\": \"シングルコアモード\",\n    \"transparency\": \"透明度\",\n    \"color\": \"背景色\",\n    \"menu\": {\n      \"home\": \"紹介\",\n      \"music\": \"演奏\",\n      \"tutorial\": \"練習\",\n      \"kube\": \"譜面作成\",\n      \"shortcut\": \"ショートカット\",\n      \"musicEdit\": \"楽譜編集\",\n      \"setting\": \"設定\",\n      \"hwndHandle\": \"ハンドル\",\n      \"magicTools\": \"開発者\"\n    }\n  },\n  \"shortcutKeys\": {\n    \"title\": \"ショートカットキーをリセット\",\n    \"divider1\": \"音楽ショートカット\",\n    \"divider2\": \"練習ショートカット\",\n    \"head_text\": \"ショートカットは今回の実行中のみ有効です。ソフトを再起動する場合は再設定が必要です。\",\n    \"button_title\": {\n      \"start\": \"再生\",\n      \"resume\": \"続き\",\n      \"pause\": \"一時停止\",\n      \"stop\": \"停止\",\n      \"add_duration\": \"+ サステイン\",\n      \"reduce_duration\": \"- サステイン\",\n      \"add_delay\": \"+ 間隔\",\n      \"reduce_delay\": \"- 間隔\",\n      \"add_speed\": \"+ 速度\",\n      \"reduce_speed\": \"- 速度\",\n      \"next\": \"次曲\",\n      \"repeat\": \"リピート\",\n      \"repeat_next\": \"リピートしてスキップ\",\n      \"exit\": \"終了\",\n      \"resize\": \"キー再読み込み\"\n    },\n    \"patterns0\": \"今回の実行\",\n    \"patterns1\": \"再設定\",\n    \"patterns2\": \"再起動\",\n    \"patterns3\": \"早めに慣れてください\"\n  },\n  \"tab\": {\n    \"systemMusic\": \"システム音楽\",\n    \"myImport\": \"インポート音楽\",\n    \"myFavorite\": \"お気に入り\",\n    \"myTranslate\": \"変換済み音楽\",\n    \"translateOriginalMusic\": \"未変換音楽\",\n    \"search\": \"検索\",\n    \"love_success\": \"お気に入りに追加しました\",\n    \"remove_success\": \"削除しました\",\n    \"title\": \"プレイリスト\",\n    \"clear\": \"クリア\"\n  },\n  \"music_edit\": {\n    \"total_column\": \"総列数：{length}\",\n    \"total_time\": \"楽譜総時間：{length}\",\n    \"tips\": {\n      \"pause\": \"一時停止\",\n      \"play\": \"再生\",\n      \"upend\": \"逆再生\",\n      \"pre_column\": \"前の列\",\n      \"next_column\": \"次の列\",\n      \"afer_add_column\": \"現在のハイライト列の後に新しい列を挿入\",\n      \"delete_now_column\": \"現在のハイライト列を削除\",\n      \"play_now_column\": \"現在のハイライト列をゲームで押す\",\n      \"copy_now_to_head\": \"現在のハイライト列を先頭にコピー\",\n      \"copy_now_to_pre\": \"現在のハイライト列を前の列にコピー\",\n      \"copy_now_to_next\": \"現在のハイライト列を次の列にコピー\",\n      \"copy_now_to_end\": \"現在のハイライト列を最後にコピー\",\n      \"select_in_music\": \"プレイリストから選択\",\n      \"save_sheet\": \"楽譜を保存\",\n      \"clear_sheet\": \"現在の作業領域の楽譜をクリア\",\n      \"upload_sheet\": \"楽譜をアップロードして編集\",\n      \"tip1\": \"長押し間隔は列後の待機遅延より短くする必要があります（現在）\",\n      \"tip2\": \"先頭にコピーしました\",\n      \"tip3\": \"前の列にコピーしました\",\n      \"tip4\": \"次の列にコピーしました\",\n      \"tip5\": \"最後にコピーしました\",\n      \"tip6\": \"長押し間隔は待機間隔より短くする必要があります（現在）\",\n      \"tip7\": \"列後の待機遅延は10以上にする必要があります（グローバル追加）\",\n      \"tip8\": \"長押し間隔は列後の待機遅延より10ms短くする必要があります（グローバル追加）\"\n    },\n    \"title\": {\n      \"change_send_key_in_game\": \"列を過ぎたらゲームにキーを送信\",\n      \"func_area_tip\": \"機能エリアのヒント\",\n      \"sheet_area_color\": \"楽譜エリアの交互色\",\n      \"columnDownDuration\": \"列長押し間隔\",\n      \"columnAfterDuration\": \"列後待機遅延\",\n      \"sheet_name\": \"曲名\",\n      \"sheet_name_placeholder\": \"曲名/ファイル名\",\n      \"add_new_count_column\": \"新しい列の数\",\n      \"add_new_druation_column\": \"新しい長押し間隔\",\n      \"add_new_after_column\": \"新しい列後待機遅延\",\n      \"global_down\": \"グローバル長押し間隔\",\n      \"set\": \"設定\",\n      \"global_after\": \"グローバル列後遅延\"\n    },\n    \"dialog\": {\n      \"title\": \"開発者からの暖かいヒント⭐\",\n      \"content\": \"現在の作業領域のすべての楽譜をクリアしますか？保存されていない変更は失われます。\",\n      \"content2\": \"楽譜編集ページを離れますか？保存されていない変更は失われます。\",\n      \"positiveText\": \"クリアする\",\n      \"negativeText\": \"保存してからクリア\",\n      \"positiveText2\": \"離れる\",\n      \"negativeText2\": \"保存してから離れる\"\n    },\n    \"sheet\": {\n      \"error\": {\n        \"sheet_data\": \"楽譜データ形式エラー\",\n        \"data\": \"楽譜データ形式エラー\"\n      },\n      \"load_success\": \"楽譜の読み込みに成功\",\n      \"load_fail\": \"楽譜の読み込みに失敗\"\n    }\n  },\n  \"columns\": {\n    \"name\": \"曲名\",\n    \"operation\": \"操作\",\n    \"total_duration\": \"時間\"\n  },\n  \"messeage\": {\n    \"remove_success\": \"削除しました\",\n    \"remove_fail\": \"削除失敗\",\n    \"progress_fail\": \"進捗取得失敗\",\n    \"choose_plz\": \"曲を選んでから練習してください\",\n    \"double_click\": \"曲をダブルクリックで再生！\",\n    \"unknow_music\": \"不明な曲\",\n    \"order_ok\": \"プレイリストの曲が終了しました\",\n    \"no_music\": \"再生中の曲はありません\",\n    \"sheet\": \"楽譜👉\",\n    \"no_import\": \"インポート失敗\",\n    \"ok_import\": \"インポート完了\",\n    \"no_now\": \"ありません、他のカテゴリを試してください\",\n    \"msg1\": \"停止状態でのみ開始可能\",\n    \"msg2\": \"曲を選んでから再生してください\",\n    \"msg3\": \"開始\",\n    \"msg4\": \"続き\",\n    \"msg5\": \"一時停止状態でのみ続き可能\",\n    \"msg6\": \"一時停止\",\n    \"msg7\": \"再生中のみ一時停止可能\",\n    \"msg8\": \"停止\",\n    \"msg9\": \"次曲\",\n    \"msg10\": \"サステイン最大2\",\n    \"msg11\": \"サステイン+0.01\",\n    \"msg12\": \"サステイン最小0\",\n    \"msg13\": \"サステイン-0.01\",\n    \"msg14\": \"間隔最大2\",\n    \"msg15\": \"間隔+0.01\",\n    \"msg16\": \"間隔最小0\",\n    \"msg17\": \"間隔-0.01\",\n    \"msg18\": \"速度最大5\",\n    \"msg19\": \"速度+0.1\",\n    \"msg20\": \"速度最小0.1\",\n    \"msg21\": \"速度-0.1\"\n  },\n  \"tutorial\": {\n    \"error_console\": \"変換失敗\",\n    \"error\": \"変換失敗、再試行してください\",\n    \"save_desktop\": \"デスクトップに保存しました\",\n    \"now\": \"現在: {music} \",\n    \"save\": \"可視化楽譜をデスクトップに保存\",\n    \"chose_music\": \"まず曲を選択してください\",\n    \"no_music\": \"曲がありません\",\n    \"follow\": \"練習開始\"\n  },\n  \"setting\": {\n    \"key_map\": \"キーマッピング\",\n    \"reset_map\": \"キーマッピングをリセット\",\n    \"head_text\": \"キーマッピングは今回の実行中のみ有効です。ソフトを再起動する場合は再設定が必要です。\",\n    \"repeat\": \"重複するショートカット値があります。設定を確認してください。\",\n    \"ok\": \"設定済み\",\n    \"clearNow\": \"このキーをクリア\",\n    \"clearAll\": \"ショートカットをリセット\",\n    \"patterns0\": \"今回の実行\",\n    \"patterns1\": \"再設定\",\n    \"patterns2\": \"再起動\",\n    \"patterns3\": \"早めに慣れてください\"\n  },\n  \"home\": {\n    \"head_text\": \"気に入ったらコーヒー一杯☕をお願いします\",\n    \"text\": \"このソフトウェアへようこそ。このソフトウェアは完全無料です。もし購入した場合は騙されています\",\n    \"update\": \"現在最新バージョンです\",\n    \"update_error\": \"更新チェックエラー\",\n    \"update_info\": \"ソフトウェアの新バージョンを検出できません。ネットワークを修復してみてください\",\n    \"tutorial\": \"チュートリアル\",\n    \"qq\": \"QQグループ\",\n    \"qq_sb\": \"チャンネル\",\n    \"patterns0\": \"完全無料\",\n    \"patterns1\": \"騙されています\",\n    \"patterns2\": \"コーヒー☕\"\n  },\n  \"kube\": {\n    \"title\": \"楽曲変換\",\n    \"chose_music\": \"音楽を選択\",\n    \"star_transfer\": \"変換開始\",\n    \"transfer_success\": \"変換成功\",\n    \"transfer_fail\": \"変換失敗\",\n    \"get_fail\": \"{value} の取得に失敗しました\",\n    \"odd\": \"奇数キー\",\n    \"dual\": \"偶数キー\",\n    \"half_t\": \"半音変換を含む\",\n    \"all_t\": \"全音のみ変換\",\n    \"range_key\": \"範囲のみ変換\",\n    \"other_key\": \"3音以上の転調\",\n    \"Streng_filter\": \"強度フィルター（ミリ秒未満）\",\n    \"dynamic_merge\": \"動的マージしきい値範囲（BPM計算に依存）\",\n    \"scale\": {\n      \"scale2\": \"Sky範囲_2オクターブ\",\n      \"scale3\": \"3オクターブ\",\n      \"scale4\": \"4オクターブ\",\n      \"scale5\": \"5オクターブ\",\n      \"scale6\": \"6オクターブ\"\n    },\n    \"transfer_progress\": \"変換進捗\"\n  },\n  \"magic_tools\": {\n    \"head_text\": \"ここはベータ機能です。慎重にご利用ください🌶、メモリ改変は含みません🌶。\",\n    \"head_text2\": \"この機能は学習・交流のみを目的としています。商用利用は禁止、24時間以内に削除してください\",\n    \"head_text3\": \"🚫エミュレータープレイヤーは以下の機能を使用禁止🚫\",\n    \"buttons\": {\n      \"check\": \"チェック\",\n      \"abaaba\": \"強く叫ぶ\",\n      \"heart_fire\": \"心火\",\n      \"key\": \"キー\",\n      \"autoFire\": \"自動点火\",\n      \"developer\": \"開発者カスタム\",\n      \"shutdown\": \"スレッド終了\"\n    },\n    \"fileButtons\": {\n      \"systemMusic\": \"システム音楽\",\n      \"myImport\": \"インポート音楽\",\n      \"myTranslate\": \"変換済み音楽\",\n      \"myFavorite\": \"お気に入り音楽\",\n      \"translateMID\": \"変換MIDI\"\n    },\n    \"messeage\": {\n      \"start\": \"今から心火を自動クリックします\",\n      \"stop\": \"終了！！！！！\"\n    },\n    \"patterns0\": \"慎重にご利用ください🌶\",\n    \"patterns1\": \"メモリ改変は含みません🌶\",\n    \"patterns2\": \"この機能は学習・交流のみを目的としています。商用利用は禁止、24時間以内に削除してください\",\n    \"patterns3\": \"🚫エミュレータープレイヤーは以下の機能を使用禁止🚫\"\n  },\n  \"hwnd_handle\": {\n    \"head_text\": \"ここはバックグラウンド送信先を変更する場所です。Sky以外のゲームは未検証、修正は行いません\",\n    \"head_text2\": \"この機能で他ゲームがBANされても責任は負いません。ゲームのアンチチート次第です\",\n    \"refresh\": \"リストを更新\",\n    \"reset_sky\": \"Skyウィンドウにリセット\",\n    \"now_hwnd\": \"現在のハンドル >\",\n    \"columns\": {\n      \"title\": \"ソフトタイトル\",\n      \"exe_name\": \"プロセス名\",\n      \"pid\": \"PID\",\n      \"hwnd\": \"ハンドル\",\n      \"operation\": \"選択\"\n    },\n    \"reset\": \"リセット\",\n    \"patterns0\": \"バックグラウンド送信先を変更\",\n    \"patterns1\": \"Sky\",\n    \"patterns2\": \"未検証\",\n    \"patterns3\": \"修正しません\",\n    \"patterns4\": \"責任は負いません\",\n    \"patterns5\": \"BANされる\",\n    \"patterns6\": \"アンチチート\",\n    \"patterns7\": \"不正行為防止メカニズム\"\n  },\n  \"music\": {\n    \"play\": \"選 択: \",\n    \"chose\": \"再 生: \",\n    \"space\": {\n      \"title\": \"間隔遅延\",\n      \"chose0\": \"システム標準\",\n      \"chose1\": \"ランダム\",\n      \"chose2\": \"カスタム\",\n      \"title1\": \"サステイン設定\",\n      \"mult_speed\": \"倍速\"\n    },\n    \"placeholder1\": \"間隔\",\n    \"placeholder2\": \"サステイン\"\n  },\n  \"controller\": {\n    \"no_music\": \"曲がありません\"\n  },\n  \"rule\": {\n    \"order\": \"順番\",\n    \"random\": \"ランダム\",\n    \"cycle\": \"ループ\"\n  }\n}\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/i18n/locales/ko.json",
    "content": "{\n  \"columns\": {\n    \"name\": \"노래 제목\",\n    \"operation\": \"작동하다\",\n    \"total_duration\": \"지속\"\n  },\n  \"home\": {\n    \"head_text\": \"사용하기 쉽다고 생각되면 커피 한 잔을 즐길 수 있습니다.\",\n    \"patterns0\": \"완전히 무료\",\n    \"patterns1\": \"속임수\",\n    \"patterns2\": \"커피 ☕\",\n    \"qq\": \"Q 그룹을 추가하십시오\",\n    \"qq_sb\": \"채널을 추가하십시오\",\n    \"text\": \"이 소프트웨어 사용에 오신 것을 환영합니다. 이 소프트웨어는 완전히 무료입니다. 이 소프트웨어를 구입하면 속임수를 썼습니다.\",\n    \"tutorial\": \"튜토리얼을 참조하십시오\",\n    \"update\": \"최신 버전입니다\",\n    \"update_error\": \"감지 오류 업데이트\",\n    \"update_info\": \"새 버전의 소프트웨어를 감지 할 수없고 네트워크를 수리하십시오.\"\n  },\n  \"hwnd_handle\": {\n    \"columns\": {\n      \"exe_name\": \"프로세스 이름\",\n      \"hwnd\": \"핸들\",\n      \"operation\": \"선택하다\",\n      \"pid\": \"PID\",\n      \"title\": \"소프트웨어 제목\"\n    },\n    \"head_text\": \"다음은 배경에서 보낸 대상입니다. 가벼운 만남을 제외한 게임은 테스트되지 않았으며 수리되지 않습니다.\",\n    \"head_text2\": \"이 기능으로 인해 다른 게임이 차단되었으며 나를 찾지 마십시오. 게임의 체쇄 방지 메커니즘에 따라 다릅니다\",\n    \"now_hwnd\": \"이제 처리>\",\n    \"patterns0\": \"백그라운드에서 보낸 목적지를 변경하십시오\",\n    \"patterns1\": \"가벼운 만남\",\n    \"patterns2\": \"테스트되지 않았습니다\",\n    \"patterns3\": \"습관\",\n    \"patterns4\": \"나를 찾지 마세요\",\n    \"patterns5\": \"이어\",\n    \"patterns6\": \"제목\",\n    \"patterns7\": \"방지 메커니즘\",\n    \"refresh\": \"목록을 새로 고치십시오\",\n    \"reset\": \"다시 놓기\",\n    \"reset_sky\": \"라이트 만남 창으로 재설정하십시오\"\n  },\n  \"kube\": {\n    \"Streng_filter\": \"강제 필터링 (밀리 초 미만)\",\n    \"all_t\": \"완전한 사운드 변환 만\",\n    \"chose_music\": \"파일 선택\",\n    \"dual\": \"열쇠조차도\",\n    \"dynamic_merge\": \"동적 병합 임계 값 범위 부서 (BMP 계산에 대한 동적 의존성)\",\n    \"get_fail\": \"{value}를 얻지 못했습니다.\",\n    \"half_t\": \"Semitone을 변환합니다\",\n    \"odd\": \"단일 키\",\n    \"other_key\": \"슈퍼 3 톤 변경\",\n    \"range_key\": \"범위 변환 만\",\n    \"scale\": {\n      \"scale2\": \"빛이 발생합니다 range_2 스케일 세트\",\n      \"scale3\": \"3 개의 스케일 세트\",\n      \"scale4\": \"4 개의 스케일 세트\",\n      \"scale5\": \"5 세트의 저울\",\n      \"scale6\": \"6 개의 스케일 세트\"\n    },\n    \"star_transfer\": \"변환 시작\",\n    \"title\": \"노래를 변환합니다\",\n    \"transfer_fail\": \"변환이 실패했습니다\",\n    \"transfer_progress\": \"전환 진행\",\n    \"transfer_success\": \"성공적으로 변환\"\n  },\n  \"magic_tools\": {\n    \"buttons\": {\n      \"abaaba\": \"외치다\",\n      \"autoFire\": \"자동 점화\",\n      \"check\": \"조사하다\",\n      \"developer\": \"개발자 사용자 정의\",\n      \"heart_fire\": \"심장 불\",\n      \"key\": \"단추\",\n      \"shutdown\": \"스레드 종료\"\n    },\n    \"fileButtons\": {\n      \"myFavorite\": \"음악 모음\",\n      \"myImport\": \"수입 된 음악\",\n      \"myTranslate\": \"개조 된 음악\",\n      \"systemMusic\": \"시스템 음악\",\n      \"translateMID\": \"스펙트럼의 미디\"\n    },\n    \"head_text\": \"여기 베타 함수는 다음과 같습니다.주의해서 사용하십시오. 메모리 수정은 관련이 없습니다.\",\n    \"head_text2\": \"이 기능은 학습과 의사 소통을위한 것이며 상업적 목적으로 엄격하게 금지됩니다. 24 시간 이내에 삭제하십시오\",\n    \"head_text3\": \"simulator 플레이어는 다음 모든 기능을 사용하지 않습니다.\",\n    \"messeage\": {\n      \"start\": \"이제 Heart Fire를 자동으로 클릭하십시오\",\n      \"stop\": \"종료! ! ! ! !\"\n    },\n    \"patterns0\": \"주의해서 사용하십시오\",\n    \"patterns1\": \"메모리 수정과 관련이 없습니다\",\n    \"patterns2\": \"이 기능은 학습과 의사 소통을위한 것이며 상업적 목적으로 엄격하게 금지됩니다. 24 시간 이내에 삭제하십시오\",\n    \"patterns3\": \"simulator 플레이어는 다음 모든 기능을 사용하지 않습니다.\"\n  },\n  \"main\": {\n    \"backend\": \"배경 모드\",\n    \"color\": \"배경색\",\n    \"compatible\": \"호환성 모드\",\n    \"cut\": \"컷 인 모드\",\n    \"loading\": \"Application이로드 중입니다. 기다려주세요 ~\",\n    \"menu\": {\n      \"home\": \"소개하다\",\n      \"hwndHandle\": \"핸들\",\n      \"kube\": \"비틀기\",\n      \"magicTools\": \"개발자\",\n      \"music\": \"성능\",\n      \"musicEdit\": \"편집\",\n      \"setting\": \"설정\",\n      \"shortcut\": \"단축키\",\n      \"tutorial\": \"추종탄\"\n    },\n    \"multi_core\": \"멀티 코어 모드\",\n    \"queue\": \"대기열 모드\",\n    \"single_core\": \"단일 코어 모드\",\n    \"transparency\": \"투명도\"\n  },\n  \"messeage\": {\n    \"choose_plz\": \"노래를 선택하고 잘 생긴 남자와 함께 연주하십시오.\",\n    \"progress_fail\": \"진전을 얻지 못했습니다\",\n    \"remove_fail\": \"삭제가 실패했습니다\",\n    \"remove_success\": \"성공적으로 제거\",\n    \"double_click\": \"노래를 두 번 클릭하십시오!\",\n    \"msg1\": \"시작 만 허용합니다\",\n    \"msg10\": \"최대 지속 사운드는 2입니다\",\n    \"msg11\": \"0.01을 유지하십시오\",\n    \"msg12\": \"가장 낮은 지속 사운드는 0입니다\",\n    \"msg13\": \"지속 -0.01\",\n    \"msg14\": \"최대 간격은 2입니다\",\n    \"msg15\": \"간격 0.01\",\n    \"msg16\": \"최소 간격은 0입니다\",\n    \"msg17\": \"간격 -0.01\",\n    \"msg18\": \"최대 속도는 5입니다\",\n    \"msg19\": \"속도 0.1\",\n    \"msg2\": \"노래를 선택하고 재생하십시오. 아름다운\",\n    \"msg20\": \"가장 낮은 속도는 0.1입니다\",\n    \"msg21\": \"속도 -0.1\",\n    \"msg3\": \"시작\",\n    \"msg4\": \"계속하다\",\n    \"msg5\": \"계속할 수 있습니다\",\n    \"msg6\": \"정지시키다\",\n    \"msg7\": \"일시 중지는 재생 중일 때만 허용됩니다\",\n    \"msg8\": \"멈추다\",\n    \"msg9\": \"다음\",\n    \"no_import\": \"가져 오기 실패\",\n    \"no_music\": \"노래가 재생되지 않습니다\",\n    \"no_now\": \"아무것도, 아이, 정말 아무것도,, 다른 범주를 시도하십시오\",\n    \"ok_import\": \"수입을 완료하십시오\",\n    \"order_ok\": \"목록의 노래가 완성되었습니다\",\n    \"sheet\": \"스코어 👉\",\n    \"unknow_music\": \"알 수없는 노래\"\n  },\n  \"music_edit\": {\n    \"dialog\": {\n      \"content\": \"현재 작업 영역의 모든 점수를 지우고 싶습니까? 구축되지 않은 변경 사항이 손실됩니다.\",\n      \"content2\": \"점수 편집 페이지를 남겨두고 싶습니까? 구축되지 않은 변경 사항이 손실됩니다.\",\n      \"negativeText\": \"내가 명확하지 않으면 먼저 저장하겠습니다\",\n      \"negativeText2\": \"떠나지 않으면 먼저 저장하겠습니다\",\n      \"positiveText\": \"그냥 지우십시오\",\n      \"positiveText2\": \"그냥 떠나십시오\",\n      \"title\": \"개발자의 따뜻한 팁 ⭐\"\n    },\n    \"sheet\": {\n      \"error\": {\n        \"data\": \"스펙트럼 데이터 형식의 오류\",\n        \"sheet_data\": \"스펙트럼 참고 데이터 형식 오류\"\n      },\n      \"load_fail\": \"스펙트럼 로딩이 실패했습니다\",\n      \"load_success\": \"점수가 성공적으로로드되었습니다\"\n    },\n    \"tips\": {\n      \"afer_add_column\": \"현재 강조 표시된 열에 새 열을 삽입하십시오\",\n      \"clear_sheet\": \"현재 작업 공간의 점수를 지우십시오\",\n      \"copy_now_to_end\": \"현재 강조 표시된 열의 끝에 사본을 복사하십시오.\",\n      \"copy_now_to_head\": \"현재 강조 표시된 열의 시작 부분에 사본을 복사합니다.\",\n      \"copy_now_to_next\": \"현재 강조 표시된 열의 사본을 다음 열에 복사합니다.\",\n      \"copy_now_to_pre\": \"현재 강조 표시된 열의 사본을 이전 열에 복사합니다.\",\n      \"delete_now_column\": \"현재 강조 표시된 열을 삭제하십시오\",\n      \"next_column\": \"다음 열\",\n      \"pause\": \"정지시키다\",\n      \"play\": \"놀다\",\n      \"play_now_column\": \"강조 표시된 열은 게임에 있습니다\",\n      \"pre_column\": \"이전 열\",\n      \"save_sheet\": \"스펙트럼을 저장하십시오\",\n      \"select_in_music\": \"노래 목록에서 노래를 선택하십시오\",\n      \"tip1\": \"긴 프레스 간격은 열보다 작고 지연을 기다려야하며 자동으로 조정되었습니다 (현재)\",\n      \"tip2\": \"처음에 복사하십시오\",\n      \"tip3\": \"이전 열로 복사되었습니다\",\n      \"tip4\": \"다음 열에 복사되었습니다\",\n      \"tip5\": \"마지막 열에 복사되었습니다\",\n      \"tip6\": \"긴 프레스 간격은 대기 간격보다 작아야하며 열이 자동으로 증가한 후 대기 지연 (현재)\",\n      \"tip7\": \"열 후 대기 지연은 10 미만일 수 없으며 자동으로 조정되었습니다 (새로운 글로벌)\",\n      \"tip8\": \"긴 압박 후 대기 지연은 10ms 컬럼보다 작습니다.\",\n      \"upend\": \"거꾸로 두십시오\",\n      \"upload_sheet\": \"업로드 점수 편집\"\n    },\n    \"title\": {\n      \"add_new_after_column\": \"추가 열 후 대기 지연\",\n      \"add_new_count_column\": \"새 열의 수\",\n      \"add_new_druation_column\": \"새로운 긴 프레스 간격\",\n      \"change_send_key_in_game\": \"열을 통해 키를 게임에 보내십시오\",\n      \"columnAfterDuration\": \"열 후 대기 지연\",\n      \"columnDownDuration\": \"길이가\",\n      \"func_area_tip\": \"리본 프롬프트\",\n      \"global_after\": \"글로벌 칼럼 후 지연\",\n      \"global_down\": \"전체 지역을 길게 누릅니다\",\n      \"set\": \"설정\",\n      \"sheet_area_color\": \"스펙트럼 영역의 교대 색상\",\n      \"sheet_name\": \"노래 이름\",\n      \"sheet_name_placeholder\": \"노래 이름/파일 이름\"\n    },\n    \"total_column\": \"총 열 수 : {길이}\",\n    \"total_time\": \"음악 점수의 총 길이 : {길이}\"\n  },\n  \"setting\": {\n    \"clearAll\": \"바로 가기 키를 재설정하십시오\",\n    \"clearNow\": \"이 키가 지워졌습니다\",\n    \"head_text\": \"피아노지도는이 작업에 적용됩니다. 소프트웨어를 다시 시작하려면 재설정이 필요합니다. 적응하지 않으면 가능한 빨리 적응하십시오.\",\n    \"key_map\": \"키 매핑\",\n    \"ok\": \"세트\",\n    \"patterns0\": \"이 실행\",\n    \"patterns1\": \"다시\",\n    \"patterns2\": \"다시 시작하십시오\",\n    \"patterns3\": \"가능한 빨리 적응하십시오\",\n    \"repeat\": \"중복 단축키 키 값이 있습니다. 구성을 확인하십시오.\",\n    \"reset_map\": \"피아노 촬영을 재설정하십시오\"\n  },\n  \"shortcutKeys\": {\n    \"button_title\": {\n      \"add_delay\": \"간격\",\n      \"add_duration\": \"사운드 유지\",\n      \"add_speed\": \"속도의 두 배\",\n      \"exit\": \"그만두다\",\n      \"next\": \"다음\",\n      \"pause\": \"정지시키다\",\n      \"reduce_delay\": \"- 간격\",\n      \"reduce_duration\": \"- 보류\",\n      \"reduce_speed\": \"- 이중 속도\",\n      \"repeat\": \"반복하다\",\n      \"repeat_next\": \"단계별로 반복하고\",\n      \"resize\": \"키를 다시로드하십시오\",\n      \"resume\": \"계속하다\",\n      \"start\": \"놀다\",\n      \"stop\": \"멈추다\"\n    },\n    \"divider1\": \"음악 바로 가기 키\",\n    \"divider2\": \"바로 가기 키를 따르십시오\",\n    \"head_text\": \"바로 가기 키는이 작업에 효과적입니다. 소프트웨어를 다시 시작하려면 재설정이 필요합니다. 적응하지 않으면 가능한 빨리 적응하십시오.\",\n    \"patterns0\": \"이 실행\",\n    \"patterns1\": \"다시\",\n    \"patterns2\": \"다시 시작하십시오\",\n    \"patterns3\": \"가능한 빨리 적응하십시오\",\n    \"title\": \"바로 가기 키를 재설정합니다\"\n  },\n  \"tab\": {\n    \"love_success\": \"성공적으로 수집되었습니다\",\n    \"myFavorite\": \"모으다\",\n    \"myImport\": \"노래 가져 오기\",\n    \"myTranslate\": \"변환 된 노래\",\n    \"remove_success\": \"성공적으로 제거\",\n    \"search\": \"찾다\",\n    \"systemMusic\": \"시스템 노래\",\n    \"translateOriginalMusic\": \"비 변환되지 않은 노래\",\n    \"clear\": \"분명한\",\n    \"title\": \"재생 목록\"\n  },\n  \"tutorial\": {\n    \"chose_music\": \"먼저 노래를 선택하십시오\",\n    \"error\": \"변환이 실패했습니다. 다시 시도하십시오\",\n    \"error_console\": \"변환이 실패했습니다\",\n    \"follow\": \"총알을 따라 가기 시작하십시오\",\n    \"no_music\": \"노래가 없습니다\",\n    \"now\": \"현재 : {music}\",\n    \"save\": \"비주얼 점수를 데스크탑에 저장하십시오\",\n    \"save_desktop\": \"데스크탑에 저장\"\n  },\n  \"controller\": {\n    \"no_music\": \"노래가 없습니다\"\n  },\n  \"music\": {\n    \"chose\": \"놀다:\",\n    \"placeholder1\": \"간격\",\n    \"placeholder2\": \"사운드 유지\",\n    \"play\": \"선택하다:\",\n    \"space\": {\n      \"chose0\": \"시스템과 함께 제공됩니다\",\n      \"chose1\": \"무작위의\",\n      \"chose2\": \"사용자 정의하십시오\",\n      \"mult_speed\": \"속도의 두 배\",\n      \"title\": \"간격 지연\",\n      \"title1\": \"설정 설정을 유지하십시오\"\n    }\n  },\n  \"rule\": {\n    \"cycle\": \"주기\",\n    \"order\": \"주문하다\",\n    \"random\": \"무작위의\"\n  }\n}\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/i18n/locales/zh-classical.json",
    "content": "{\n  \"main\": {\n    \"loading\": \"🍉应用载入中，少待片刻~\",\n    \"compatible\": \"兼容之制\",\n    \"backend\": \"後臺之制\",\n    \"queue\": \"列隊之制\",\n    \"cut\": \"插隊之制\",\n    \"multi_core\": \"多核之制\",\n    \"single_core\": \"單核之制\",\n    \"transparency\": \"透明度\",\n    \"color\": \"底色\",\n    \"menu\": {\n      \"home\": \"序\",\n      \"music\": \"奏樂\",\n      \"tutorial\": \"習彈\",\n      \"kube\": \"譜析\",\n      \"shortcut\": \"捷鍵\",\n      \"musicEdit\": \"譜編\",\n      \"setting\": \"設置\",\n      \"hwndHandle\": \"柄\",\n      \"magicTools\": \"開發者\"\n    }\n  },\n  \"shortcutKeys\": {\n    \"title\": \"重設捷鍵\",\n    \"divider1\": \"樂捷鍵\",\n    \"divider2\": \"習彈捷鍵\",\n    \"head_text\": \"捷鍵僅本次運行有效，重啟需復設，若不適，請速適之。\",\n    \"button_title\": {\n      \"start\": \"奏\",\n      \"resume\": \"續\",\n      \"pause\": \"止\",\n      \"stop\": \"罷\",\n      \"add_duration\": \"+ 延音\",\n      \"reduce_duration\": \"- 延音\",\n      \"add_delay\": \"+ 間隔\",\n      \"reduce_delay\": \"- 間隔\",\n      \"add_speed\": \"+ 倍速\",\n      \"reduce_speed\": \"- 倍速\",\n      \"next\": \"次曲\",\n      \"repeat\": \"復奏\",\n      \"repeat_next\": \"復並過\",\n      \"exit\": \"退\",\n      \"resize\": \"重載鍵\"\n    },\n    \"patterns0\": \"本次運行\",\n    \"patterns1\": \"復設\",\n    \"patterns2\": \"重啟\",\n    \"patterns3\": \"速適之\"\n  },\n  \"tab\": {\n    \"systemMusic\": \"自帶樂\",\n    \"myImport\": \"導入樂\",\n    \"myFavorite\": \"所好\",\n    \"myTranslate\": \"已轉樂\",\n    \"translateOriginalMusic\": \"未轉樂\",\n    \"search\": \"尋\",\n    \"love_success\": \"所好成\",\n    \"remove_success\": \"去除成\",\n    \"title\": \"曲單\",\n    \"clear\": \"盡清\"\n  },\n  \"music_edit\": {\n    \"total_column\": \"總列：{length}\",\n    \"total_time\": \"譜總時：{length}\",\n    \"tips\": {\n      \"pause\": \"止\",\n      \"play\": \"奏\",\n      \"upend\": \"倒奏\",\n      \"pre_column\": \"上列\",\n      \"next_column\": \"下列\",\n      \"afer_add_column\": \"於高亮列後增新列\",\n      \"delete_now_column\": \"去高亮列\",\n      \"play_now_column\": \"高亮列按於戲中\",\n      \"copy_now_to_head\": \"高亮列複首\",\n      \"copy_now_to_pre\": \"高亮列複上列\",\n      \"copy_now_to_next\": \"高亮列複下列\",\n      \"copy_now_to_end\": \"高亮列複末\",\n      \"select_in_music\": \"自曲單選曲\",\n      \"save_sheet\": \"存譜\",\n      \"clear_sheet\": \"清作業區譜\",\n      \"upload_sheet\": \"上傳譜編\",\n      \"tip1\": \"長按間隔須小於列後延，已自調(當下)\",\n      \"tip2\": \"已複首\",\n      \"tip3\": \"已複上列\",\n      \"tip4\": \"已複下列\",\n      \"tip5\": \"已複末列\",\n      \"tip6\": \"長按間隔須小於待延，已自增列後延(當下)\",\n      \"tip7\": \"列後延不得小於十，已自調(全局新)\",\n      \"tip8\": \"長按間隔須小於列後延十毫秒，已自調(全局新)\"\n    },\n    \"title\": {\n      \"change_send_key_in_game\": \"過列發鍵於戲\",\n      \"func_area_tip\": \"功能區示\",\n      \"sheet_area_color\": \"譜區間色\",\n      \"columnDownDuration\": \"列長按間\",\n      \"columnAfterDuration\": \"列後延\",\n      \"sheet_name\": \"曲名\",\n      \"sheet_name_placeholder\": \"曲名/檔名\",\n      \"add_new_count_column\": \"增新列數\",\n      \"add_new_druation_column\": \"新長按間\",\n      \"add_new_after_column\": \"新列後延\",\n      \"global_down\": \"全局長按間\",\n      \"set\": \"設\",\n      \"global_after\": \"全局列後延\"\n    },\n    \"dialog\": {\n      \"title\": \"開發者溫言⭐\",\n      \"content\": \"確清作業區諸譜乎？未存者將失。\",\n      \"content2\": \"確離譜編頁乎？未存者將失。\",\n      \"positiveText\": \"清之可也\",\n      \"negativeText\": \"且存不清\",\n      \"positiveText2\": \"去之可也\",\n      \"negativeText2\": \"且存不去\"\n    },\n    \"sheet\": {\n      \"error\": {\n        \"sheet_data\": \"譜音數據謬\",\n        \"data\": \"譜數據謬\"\n      },\n      \"load_success\": \"譜載成\",\n      \"load_fail\": \"譜載敗\"\n    }\n  },\n  \"columns\": {\n    \"name\": \"曲名\",\n    \"operation\": \"操作\",\n    \"total_duration\": \"時長\"\n  },\n  \"messeage\": {\n    \"remove_success\": \"去除成\",\n    \"remove_fail\": \"去除敗\",\n    \"progress_fail\": \"取進度敗\",\n    \"choose_plz\": \"選曲習彈之\",\n    \"double_click\": \"雙擊奏曲！\",\n    \"unknow_music\": \"曲未詳\",\n    \"order_ok\": \"曲盡於列矣\",\n    \"no_music\": \"無曲正奏也\",\n    \"sheet\": \"譜👉\",\n    \"no_import\": \"導入敗\",\n    \"ok_import\": \"導入成\",\n    \"no_now\": \"無也，誠無也，換類再試之\",\n    \"msg1\": \"止時乃可始\",\n    \"msg2\": \"選曲乃可奏\",\n    \"msg3\": \"始\",\n    \"msg4\": \"續\",\n    \"msg5\": \"止時乃可續\",\n    \"msg6\": \"止\",\n    \"msg7\": \"奏時乃可止\",\n    \"msg8\": \"罷\",\n    \"msg9\": \"次曲\",\n    \"msg10\": \"延音至二為極\",\n    \"msg11\": \"延音+0.01\",\n    \"msg12\": \"延音至零為下\",\n    \"msg13\": \"延音-0.01\",\n    \"msg14\": \"間隔至二為極\",\n    \"msg15\": \"間隔+0.01\",\n    \"msg16\": \"間隔至零為下\",\n    \"msg17\": \"間隔-0.01\",\n    \"msg18\": \"速至五為極\",\n    \"msg19\": \"速+0.1\",\n    \"msg20\": \"速至0.1為下\",\n    \"msg21\": \"速-0.1\"\n  },\n  \"tutorial\": {\n    \"error_console\": \"轉換敗\",\n    \"error\": \"轉換敗，請再試\",\n    \"save_desktop\": \"已存於桌\",\n    \"now\": \"今: {music} \",\n    \"save\": \"存可視譜於桌\",\n    \"chose_music\": \"先選曲\",\n    \"no_music\": \"無曲\",\n    \"follow\": \"始習彈\"\n  },\n  \"setting\": {\n    \"key_map\": \"琴鍵映射\",\n    \"reset_map\": \"重設彈琴映射\",\n    \"head_text\": \"彈琴映射僅本次運行有效，重啟需復設，若不適，請速適之。\",\n    \"repeat\": \"捷鍵值有復，請檢之。\",\n    \"ok\": \"已設\",\n    \"clearNow\": \"已清此鍵\",\n    \"clearAll\": \"已復捷鍵\",\n    \"patterns0\": \"本次運行\",\n    \"patterns1\": \"復設\",\n    \"patterns2\": \"重啟\",\n    \"patterns3\": \"速適之\"\n  },\n  \"home\": {\n    \"head_text\": \"若覺好用，賞我一杯咖啡☕\",\n    \"text\": \"歡迎用此軟，軟全免，若購之，則受騙矣\",\n    \"update\": \"已是新矣\",\n    \"update_error\": \"檢新敗\",\n    \"update_info\": \"新未可檢，試修網絡\",\n    \"tutorial\": \"觀教程\",\n    \"qq\": \"加Q群\",\n    \"qq_sb\": \"加頻道\",\n    \"patterns0\": \"全免\",\n    \"patterns1\": \"受騙了\",\n    \"patterns2\": \"咖啡☕\"\n  },\n  \"kube\": {\n    \"title\": \"轉曲\",\n    \"chose_music\": \"選樂\",\n    \"star_transfer\": \"始轉\",\n    \"transfer_success\": \"轉成\",\n    \"transfer_fail\": \"轉敗\",\n    \"get_fail\": \"取{value}敗\",\n    \"odd\": \"單鍵\",\n    \"dual\": \"雙鍵\",\n    \"half_t\": \"含半音轉\",\n    \"all_t\": \"全音轉\",\n    \"range_key\": \"僅範圍轉\",\n    \"other_key\": \"超三音變\",\n    \"Streng_filter\": \"力度濾(毫秒下)\",\n    \"dynamic_merge\": \"動合閾值分(依bmp計)\",\n    \"scale\": {\n      \"scale2\": \"光遇二階\",\n      \"scale3\": \"三階\",\n      \"scale4\": \"四階\",\n      \"scale5\": \"五階\",\n      \"scale6\": \"六階\"\n    },\n    \"transfer_progress\": \"轉進度\"\n  },\n  \"magic_tools\": {\n    \"head_text\": \"此測試功能，慎用🌶，不涉內存🌶。\",\n    \"head_text2\": \"僅供學習，禁商用，廿四時內刪\",\n    \"head_text3\": \"🚫模擬器者禁用下列諸功能🚫\",\n    \"buttons\": {\n      \"check\": \"檢\",\n      \"abaaba\": \"大叫\",\n      \"heart_fire\": \"心火\",\n      \"key\": \"鍵\",\n      \"autoFire\": \"自點火\",\n      \"developer\": \"開發自定\",\n      \"shutdown\": \"終線\"\n    },\n    \"fileButtons\": {\n      \"systemMusic\": \"系樂\",\n      \"myImport\": \"導樂\",\n      \"myTranslate\": \"轉樂\",\n      \"myFavorite\": \"所好樂\",\n      \"translateMID\": \"轉譜MIDI\"\n    },\n    \"messeage\": {\n      \"start\": \"今自點心火\",\n      \"stop\": \"終止！！！！！\"\n    },\n    \"patterns0\": \"慎用🌶\",\n    \"patterns1\": \"不涉內存🌶\",\n    \"patterns2\": \"僅供學習，禁商用，廿四時內刪\",\n    \"patterns3\": \"🚫模擬器者禁用下列諸功能🚫\"\n  },\n  \"hwnd_handle\": {\n    \"head_text\": \"此更改後臺發送目標，光遇外諸戲未測，不修\",\n    \"head_text2\": \"因是致他戲封號，勿問我。視戲反作弊制而定\",\n    \"refresh\": \"新列\",\n    \"reset_sky\": \"復光遇窗\",\n    \"now_hwnd\": \"今柄 >\",\n    \"columns\": {\n      \"title\": \"軟標\",\n      \"exe_name\": \"程名\",\n      \"pid\": \"PID\",\n      \"hwnd\": \"柄\",\n      \"operation\": \"定\"\n    },\n    \"reset\": \"復\",\n    \"patterns0\": \"更改後臺發送目標\",\n    \"patterns1\": \"光遇\",\n    \"patterns2\": \"未測\",\n    \"patterns3\": \"不修\",\n    \"patterns4\": \"勿問我\",\n    \"patterns5\": \"致\",\n    \"patterns6\": \"封號\",\n    \"patterns7\": \"反作弊制\"\n  },\n  \"music\": {\n    \"play\": \"選: \",\n    \"chose\": \"奏: \",\n    \"space\": {\n      \"title\": \"間隔延\",\n      \"chose0\": \"系自帶\",\n      \"chose1\": \"隨機\",\n      \"chose2\": \"自定\",\n      \"title1\": \"延音設\",\n      \"mult_speed\": \"倍速\"\n    },\n    \"placeholder1\": \"間隔\",\n    \"placeholder2\": \"延音\"\n  },\n  \"controller\": {\n    \"no_music\": \"無曲\"\n  },\n  \"rule\": {\n    \"order\": \"順\",\n    \"random\": \"隨\",\n    \"cycle\": \"循\"\n  }\n}"
  },
  {
    "path": "sky-music-web/src/renderer/src/i18n/locales/zh-cn.json",
    "content": "{\n  \"main\": {\n    \"loading\": \"🍉应用加载中，请稍等~\",\n    \"compatible\": \"兼容模式\",\n    \"backend\": \"后台模式\",\n    \"queue\": \"队列模式\",\n    \"cut\": \"插队模式\",\n    \"multi_core\": \"多核模式\",\n    \"single_core\": \"单核模式\",\n    \"transparency\": \"透明度\",\n    \"color\": \"背景颜色\",\n    \"menu\": {\n      \"home\": \"介绍\",\n      \"music\": \"演奏\",\n      \"tutorial\": \"跟弹\",\n      \"kube\": \"扒谱\",\n      \"shortcut\": \"快捷键\",\n      \"musicEdit\": \"乐谱编辑\",\n      \"setting\": \"设置\",\n      \"hwndHandle\": \"句柄\",\n      \"magicTools\": \"开发者\",\n      \"aisetting\": \"AI设置\"\n    }\n  },\n  \"shortcutKeys\": {\n    \"title\": \"重 置 快 捷 键\",\n    \"divider1\": \"音乐快捷键\",\n    \"divider2\": \"跟弹快捷键\",\n    \"head_text\": \"快捷键为本次运行生效，重启软件需要重新设置，如不适应请尽快适应\",\n    \"button_title\": {\n      \"start\": \"播放\",\n      \"resume\": \"继续\",\n      \"pause\": \"暂停\",\n      \"stop\": \"停止\",\n      \"add_duration\": \"+ 延音\",\n      \"reduce_duration\": \"- 延音\",\n      \"add_delay\": \"+ 间隔\",\n      \"reduce_delay\": \"- 间隔\",\n      \"add_speed\": \"+ 倍速\",\n      \"reduce_speed\": \"- 倍速\",\n      \"next\": \"下一首\",\n      \"repeat\": \"重复\",\n      \"repeat_next\": \"重复并步过\",\n      \"exit\": \"退出\",\n      \"resize\": \"重载按键\"\n    },\n    \"patterns0\": \"本次运行\",\n    \"patterns1\": \"重新\",\n    \"patterns2\": \"重启\",\n    \"patterns3\": \"尽快适应\"\n  },\n  \"tab\": {\n    \"systemMusic\": \"自带歌曲\",\n    \"myImport\": \"导入歌曲\",\n    \"myFavorite\": \"收藏\",\n    \"myTranslate\": \"已转换歌曲\",\n    \"translateOriginalMusic\": \"未转换歌曲\",\n    \"search\": \"搜索\",\n    \"love_success\": \"收藏成功\",\n    \"remove_success\": \"移除成功\",\n    \"title\": \"播放列表\",\n    \"clear\": \"清空\"\n  },\n  \"music_edit\": {\n    \"total_column\": \"总列数：{length}\",\n    \"total_time\": \"乐谱总时长：{length}\",\n    \"tips\": {\n      \"pause\": \"暂停\",\n      \"play\": \"播放\",\n      \"upend\": \"倒放\",\n      \"pre_column\": \"上一列\",\n      \"next_column\": \"下一列\",\n      \"afer_add_column\": \"在当前高亮列后插入新列\",\n      \"delete_now_column\": \"删除当前高亮列\",\n      \"play_now_column\": \"当前高亮列到游戏里面按下\",\n      \"copy_now_to_head\": \"当前高亮列复制一份到开头\",\n      \"copy_now_to_pre\": \"当前高亮列复制一份到上一列\",\n      \"copy_now_to_next\": \"当前高亮列复制一份到下一列\",\n      \"copy_now_to_end\": \"当前高亮列复制一份到末尾\",\n      \"select_in_music\": \"从歌单里面选歌\",\n      \"save_sheet\": \"保存谱子\",\n      \"clear_sheet\": \"清空当前工作区的谱子\",\n      \"upload_sheet\": \"上传谱子编辑\",\n      \"tip1\": \"长按间隔需要小于列后等待延迟，已自动调整(当下)\",\n      \"tip2\": \"已复制到开头\",\n      \"tip3\": \"已复制到上一列\",\n      \"tip4\": \"已复制到下一列\",\n      \"tip5\": \"已复制到最后一列\",\n      \"tip6\": \"长按间隔需要小于等待间隔，已自动增加列后等待延迟(当下)\",\n      \"tip7\": \"列后等待延迟不能小于 10，已自动调整(全局新增)\",\n      \"tip8\": \"长按间隔需要小于列后等待延迟 10ms，已自动调整(全局新增)\"\n    },\n    \"title\": {\n      \"change_send_key_in_game\": \"过列发送按键到游戏\",\n      \"func_area_tip\": \"功能区提示\",\n      \"sheet_area_color\": \"谱区交替色\",\n      \"columnDownDuration\": \"当列长按间隔\",\n      \"columnAfterDuration\": \"列后等待延迟\",\n      \"sheet_name\": \"歌曲名字\",\n      \"sheet_name_placeholder\": \"歌曲名字/文件名字\",\n      \"add_new_count_column\": \"新增列数量\",\n      \"add_new_druation_column\": \"新增的长按间隔\",\n      \"add_new_after_column\": \"新增的列后等待延迟\",\n      \"global_down\": \"全局长按间隔\",\n      \"set\": \"设置\",\n      \"global_after\": \"全局列后延迟\"\n    },\n    \"dialog\": {\n      \"title\": \"一个来自开发者的温馨小提示⭐\",\n      \"content\": \"确定要清空当前工作区域的所有谱子吗？未保存的更改将丢失。\",\n      \"content2\": \"确定要离开乐谱编辑页面吗？未保存的更改将丢失。\",\n      \"positiveText\": \"就清空就清空\",\n      \"negativeText\": \"不清空了我先保存吧\",\n      \"positiveText2\": \"就走就走\",\n      \"negativeText2\": \"不走了我先保存吧\"\n    },\n    \"sheet\": {\n      \"error\": {\n        \"sheet_data\": \"谱子音符数据格式错误\",\n        \"data\": \"谱子数据格式错误\"\n      },\n      \"load_success\": \"谱子加载成功\",\n      \"load_fail\": \"谱子加载失败\"\n    }\n  },\n  \"columns\": {\n    \"name\": \"歌名\",\n    \"operation\": \"操作\",\n    \"total_duration\": \"时长\"\n  },\n  \"messeage\": {\n    \"remove_success\": \"移除成功\",\n    \"remove_fail\": \"删除失败\",\n    \"progress_fail\": \"获取进度失败\",\n    \"choose_plz\": \"选个歌再跟弹吧靓仔\",\n    \"double_click\": \"双击歌曲播放！\",\n    \"unknow_music\": \"未知歌曲\",\n    \"order_ok\": \"列表的歌放完咯\",\n    \"no_music\": \"没有正在播放的歌曲哦\",\n    \"sheet\": \"谱子👉\",\n    \"no_import\": \"导入失败\",\n    \"ok_import\": \"完成导入\",\n    \"no_now\": \"没得啊孩子，真的没得😭，切别的分类再试试吧\",\n    \"msg1\": \"仅停止状态下允许开始\",\n    \"msg2\": \"选个歌再播放吧靓仔\",\n    \"msg3\": \"开始\",\n    \"msg4\": \"继续\",\n    \"msg5\": \"仅暂停状态下允许继续\",\n    \"msg6\": \"暂停\",\n    \"msg7\": \"仅正在播放时允许暂停\",\n    \"msg8\": \"停止\",\n    \"msg9\": \"下一首\",\n    \"msg10\": \"延音最高为2\",\n    \"msg11\": \"延音+0.01\",\n    \"msg12\": \"延音最低为0\",\n    \"msg13\": \"延音-0.01\",\n    \"msg14\": \"间隔最高为2\",\n    \"msg15\": \"间隔+0.01\",\n    \"msg16\": \"间隔最低为0\",\n    \"msg17\": \"间隔-0.01\",\n    \"msg18\": \"速度最高为5\",\n    \"msg19\": \"速度+0.1\",\n    \"msg20\": \"速度最低为0.1\",\n    \"msg21\": \"速度-0.1\"\n  },\n  \"tutorial\": {\n    \"error_console\": \"转换失败\",\n    \"error\": \"转换失败，请重试\",\n    \"save_desktop\": \"已保存在桌面\",\n    \"now\": \"当前: {music} \",\n    \"save\": \"保存可视化乐谱到桌面\",\n    \"chose_music\": \"请先选择一首歌曲\",\n    \"no_music\": \"没有歌曲\",\n    \"follow\": \"开始跟弹\"\n  },\n  \"setting\": {\n    \"key_map\": \"琴键映射\",\n    \"reset_map\": \"重 置 弹 琴 映 射\",\n    \"head_text\": \"弹琴映射为本次运行生效，重启软件需要重新设置，如不适应请尽快适应\",\n    \"repeat\": \"存在重复的快捷键值，请检查配置。\",\n    \"ok\": \"已设置\",\n    \"clearNow\": \"已清除本键\",\n    \"clearAll\": \"已重置快捷键\",\n    \"patterns0\": \"本次运行\",\n    \"patterns1\": \"重新\",\n    \"patterns2\": \"重启\",\n    \"patterns3\": \"尽快适应\"\n  },\n  \"home\": {\n    \"head_text\": \"如果您觉得好用可以赏我一杯咖啡☕\",\n    \"text\": \"欢迎使用本软件，本软件完全免费，如果您是买的本软件就是被骗了\",\n    \"update\": \"当前已经是最新版了\",\n    \"update_error\": \"更新检测错误\",\n    \"update_info\": \"无法检测软件新版本，尝试下修复网络呢\",\n    \"tutorial\": \"看教程\",\n    \"qq\": \"加Q群\",\n    \"qq_sb\": \"加频道\",\n    \"patterns0\": \"完全免费\",\n    \"patterns1\": \"被骗了\",\n    \"patterns2\": \"咖啡☕\"\n  },\n  \"kube\": {\n    \"title\": \"转换歌曲\",\n    \"chose_music\": \"选择音乐\",\n    \"star_transfer\": \"开始转换\",\n    \"transfer_success\": \"转换成功\",\n    \"transfer_fail\": \"转换失败\",\n    \"get_fail\": \"获取 {value} 失败\",\n    \"odd\": \"单数键\",\n    \"dual\": \"双数键\",\n    \"half_t\": \"含半音转换\",\n    \"all_t\": \"仅全音转换\",\n    \"range_key\": \"仅范围转换\",\n    \"other_key\": \"超3音变调\",\n    \"Streng_filter\": \"力度过滤(低于毫秒)\",\n    \"dynamic_merge\": \"动态合并阈值范围划分（动态取决于bmp计算）\",\n    \"scale\": {\n      \"scale2\": \"光遇范围_2组音阶\",\n      \"scale3\": \"3组音阶\",\n      \"scale4\": \"4组音阶\",\n      \"scale5\": \"5组音阶\",\n      \"scale6\": \"6组音阶\"\n    },\n    \"transfer_progress\": \"转换进度\"\n  },\n  \"magic_tools\": {\n    \"head_text\": \"此处是测试版功能请谨慎使用🌶，不涉及内存修改🌶。\",\n    \"head_text2\": \"此处功能仅供学习交流，严禁用于商业用途，请于24小时内删除\",\n    \"head_text3\": \"🚫模拟器玩家禁止使用下面的所有功能🚫\",\n    \"buttons\": {\n      \"check\": \"检查\",\n      \"abaaba\": \"狠狠的叫\",\n      \"heart_fire\": \"心火\",\n      \"key\": \"按键\",\n      \"autoFire\": \"自动点火\",\n      \"developer\": \"开发者自定义\",\n      \"shutdown\": \"终止线程\"\n    },\n    \"fileButtons\": {\n      \"systemMusic\": \"系统的音乐\",\n      \"myImport\": \"导入的音乐\",\n      \"myTranslate\": \"转换的音乐\",\n      \"myFavorite\": \"收藏的音乐\",\n      \"translateMID\": \"转谱的MIDI\"\n    },\n    \"messeage\": {\n      \"start\": \"现在开始自动点击心火\",\n      \"stop\": \"终止！！！！！\"\n    },\n    \"patterns0\": \"谨慎使用🌶\",\n    \"patterns1\": \"不涉及内存修改🌶\",\n    \"patterns2\": \"此处功能仅供学习交流，严禁用于商业用途，请于24小时内删除\",\n    \"patterns3\": \"🚫模拟器玩家禁止使用下面的所有功能🚫\"\n  },\n  \"hwnd_handle\": {\n    \"head_text\": \"此处为更改后台发送的目标，除了光遇以外的游戏均未测试，不会进行修复\",\n    \"head_text2\": \"因为此功能导致其他游戏被封号，不要找我。取决于游戏的反作弊机制\",\n    \"refresh\": \"刷新列表\",\n    \"reset_sky\": \"重置为光遇窗口\",\n    \"now_hwnd\": \"现在的句柄 >\",\n    \"columns\": {\n      \"title\": \"软件标题\",\n      \"exe_name\": \"进程名字\",\n      \"pid\": \"PID\",\n      \"hwnd\": \"句柄\",\n      \"operation\": \"选定\"\n    },\n    \"reset\": \"重置\",\n    \"patterns0\": \"更改后台发送的目标\",\n    \"patterns1\": \"光遇\",\n    \"patterns2\": \"未测试\",\n    \"patterns3\": \"不会\",\n    \"patterns4\": \"不要找我\",\n    \"patterns5\": \"导致\",\n    \"patterns6\": \"封号\",\n    \"patterns7\": \"反作弊机制\"\n  },\n  \"music\": {\n    \"play\": \"选 择: \",\n    \"chose\": \"播 放: \",\n    \"space\": {\n      \"title\": \"间隔延迟\",\n      \"chose0\": \"系统自带\",\n      \"chose1\": \"随机\",\n      \"chose2\": \"自定义\",\n      \"title1\": \"延音设置\",\n      \"mult_speed\": \"倍速\"\n    },\n    \"placeholder1\": \"间隔\",\n    \"placeholder2\": \"延音\"\n  },\n  \"controller\": {\n    \"no_music\": \"没有歌曲\"\n  },\n  \"rule\": {\n    \"order\": \"顺序\",\n    \"random\": \"随机\",\n    \"cycle\": \"循环\"\n  },\n  \"ai_setting\": {\n    \"head_text\": \"此处功能测试中\",\n    \"patterns1\": \"此处功能测试中\",\n    \"buttons\": {\n      \"set_token\": \"保存\"\n    }\n  }\n}\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/i18n/locales/zh-tw.json",
    "content": "{\n  \"columns\": {\n    \"name\": \"歌名\",\n    \"operation\": \"操作\",\n    \"total_duration\": \"時長\"\n  },\n  \"home\": {\n    \"head_text\": \"如果您覺得好用可以賞我一杯咖啡☕\",\n    \"patterns0\": \"完全免費\",\n    \"patterns1\": \"被騙了\",\n    \"patterns2\": \"咖啡☕\",\n    \"qq\": \"加Q群\",\n    \"qq_sb\": \"加頻道\",\n    \"text\": \"歡迎使用本軟件，本軟件完全免費，如果您是買的本軟件就是被騙了\",\n    \"tutorial\": \"看教程\",\n    \"update\": \"當前已經是最新版了\",\n    \"update_error\": \"更新檢測錯誤\",\n    \"update_info\": \"無法檢測軟件新版本，嘗試下修復網絡呢\"\n  },\n  \"hwnd_handle\": {\n    \"columns\": {\n      \"exe_name\": \"進程名字\",\n      \"hwnd\": \"句柄\",\n      \"operation\": \"選定\",\n      \"pid\": \"PID\",\n      \"title\": \"軟件標題\"\n    },\n    \"head_text\": \"此處為更改後台發送的目標，除了光遇以外的遊戲均未測試，不會進行修復\",\n    \"head_text2\": \"因為此功能導致其他遊戲被封號，不要找我。\\n取決於遊戲的反作弊機制\",\n    \"now_hwnd\": \"現在的句柄 >\",\n    \"patterns0\": \"更改後台發送的目標\",\n    \"patterns1\": \"光遇\",\n    \"patterns2\": \"未測試\",\n    \"patterns3\": \"不會\",\n    \"patterns4\": \"不要找我\",\n    \"patterns5\": \"導致\",\n    \"patterns6\": \"封號\",\n    \"patterns7\": \"反作弊機制\",\n    \"refresh\": \"刷新列表\",\n    \"reset\": \"重置\",\n    \"reset_sky\": \"重置為光遇窗口\"\n  },\n  \"kube\": {\n    \"Streng_filter\": \"力度過濾(低於毫秒)\",\n    \"all_t\": \"僅全音轉換\",\n    \"chose_music\": \"選擇音樂\",\n    \"dual\": \"雙數鍵\",\n    \"dynamic_merge\": \"動態合併閾值範圍劃分（動態取決於bmp計算）\",\n    \"get_fail\": \"獲取 {value} 失敗\",\n    \"half_t\": \"含半音轉換\",\n    \"odd\": \"單數鍵\",\n    \"other_key\": \"超3音變調\",\n    \"range_key\": \"僅範圍轉換\",\n    \"scale\": {\n      \"scale2\": \"光遇範圍_2組音階\",\n      \"scale3\": \"3組音階\",\n      \"scale4\": \"4組音階\",\n      \"scale5\": \"5組音階\",\n      \"scale6\": \"6組音階\"\n    },\n    \"star_transfer\": \"開始轉換\",\n    \"title\": \"轉換歌曲\",\n    \"transfer_fail\": \"轉換失敗\",\n    \"transfer_progress\": \"轉換進度\",\n    \"transfer_success\": \"轉換成功\"\n  },\n  \"magic_tools\": {\n    \"buttons\": {\n      \"abaaba\": \"狠狠的叫\",\n      \"autoFire\": \"自動點火\",\n      \"check\": \"檢查\",\n      \"developer\": \"開發者自定義\",\n      \"heart_fire\": \"心火\",\n      \"key\": \"按鍵\",\n      \"shutdown\": \"終止線程\"\n    },\n    \"fileButtons\": {\n      \"myFavorite\": \"收藏的音樂\",\n      \"myImport\": \"導入的音樂\",\n      \"myTranslate\": \"轉換的音樂\",\n      \"systemMusic\": \"系統的音樂\",\n      \"translateMID\": \"轉譜的MIDI\"\n    },\n    \"head_text\": \"此處是測試版功能請謹慎使用🌶，不涉及內存修改🌶。\",\n    \"head_text2\": \"此處功能僅供學習交流，嚴禁用於商業用途，請於24小時內刪除\",\n    \"head_text3\": \"🚫模擬器玩家禁止使用下面的所有功能🚫\",\n    \"messeage\": {\n      \"start\": \"現在開始自動點擊心火\",\n      \"stop\": \"終止！ \\n！ \\n！ \\n！ \\n！\"\n    },\n    \"patterns0\": \"謹慎使用🌶\",\n    \"patterns1\": \"不涉及內存修改🌶\",\n    \"patterns2\": \"此處功能僅供學習交流，嚴禁用於商業用途，請於24小時內刪除\",\n    \"patterns3\": \"🚫模擬器玩家禁止使用下面的所有功能🚫\"\n  },\n  \"main\": {\n    \"backend\": \"後台模式\",\n    \"color\": \"背景顏色\",\n    \"compatible\": \"兼容模式\",\n    \"cut\": \"插隊模式\",\n    \"loading\": \"🍉應用加載中，請稍等~\",\n    \"menu\": {\n      \"home\": \"介紹\",\n      \"hwndHandle\": \"句柄\",\n      \"kube\": \"扒譜\",\n      \"magicTools\": \"開發者\",\n      \"music\": \"演奏\",\n      \"musicEdit\": \"樂譜編輯\",\n      \"setting\": \"設定\",\n      \"shortcut\": \"快速鍵\",\n      \"tutorial\": \"跟彈\"\n    },\n    \"multi_core\": \"多核模式\",\n    \"queue\": \"隊列模式\",\n    \"single_core\": \"單核模式\",\n    \"transparency\": \"透明度\"\n  },\n  \"messeage\": {\n    \"choose_plz\": \"選個歌再跟彈吧靚仔\",\n    \"progress_fail\": \"獲取進度失敗\",\n    \"remove_fail\": \"刪除失敗\",\n    \"remove_success\": \"移除成功\",\n    \"double_click\": \"雙擊歌曲播放！\",\n    \"msg1\": \"僅停止狀態下允許開始\",\n    \"msg10\": \"延音最高為2\",\n    \"msg11\": \"延音 0.01\",\n    \"msg12\": \"延音最低為0\",\n    \"msg13\": \"延音-0.01\",\n    \"msg14\": \"間隔最高為2\",\n    \"msg15\": \"間隔 0.01\",\n    \"msg16\": \"間隔最低為0\",\n    \"msg17\": \"間隔-0.01\",\n    \"msg18\": \"速度最高為5\",\n    \"msg19\": \"速度 0.1\",\n    \"msg2\": \"選個歌再播放吧靚仔\",\n    \"msg20\": \"速度最低為0.1\",\n    \"msg21\": \"速度-0.1\",\n    \"msg3\": \"開始\",\n    \"msg4\": \"繼續\",\n    \"msg5\": \"僅暫停狀態下允許繼續\",\n    \"msg6\": \"暫停\",\n    \"msg7\": \"僅正在播放時允許暫停\",\n    \"msg8\": \"停止\",\n    \"msg9\": \"下一首\",\n    \"no_import\": \"導入失敗\",\n    \"no_music\": \"沒有正在播放的歌曲哦\",\n    \"no_now\": \"沒得啊孩子，真的沒得😭，切別的分類再試試吧\",\n    \"ok_import\": \"完成導入\",\n    \"order_ok\": \"列表的歌放完咯\",\n    \"sheet\": \"譜子👉\",\n    \"unknow_music\": \"未知歌曲\"\n  },\n  \"music_edit\": {\n    \"dialog\": {\n      \"content\": \"確定要清空當前工作區域的所有譜子嗎？\\n未保存的更改將丟失。\",\n      \"content2\": \"確定要離開樂譜編輯頁面嗎？\\n未保存的更改將丟失。\",\n      \"negativeText\": \"不清空了我先保存吧\",\n      \"negativeText2\": \"不走了我先保存吧\",\n      \"positiveText\": \"就清空就清空\",\n      \"positiveText2\": \"就走就走\",\n      \"title\": \"一個來自開發者的溫馨小提示⭐\"\n    },\n    \"sheet\": {\n      \"error\": {\n        \"data\": \"譜子數據格式錯誤\",\n        \"sheet_data\": \"譜子音符數據格式錯誤\"\n      },\n      \"load_fail\": \"譜子加載失敗\",\n      \"load_success\": \"譜子加載成功\"\n    },\n    \"tips\": {\n      \"afer_add_column\": \"在當前高亮列後插入新列\",\n      \"clear_sheet\": \"清空當前工作區的譜子\",\n      \"copy_now_to_end\": \"當前高亮列複製一份到末尾\",\n      \"copy_now_to_head\": \"當前高亮列複製一份到開頭\",\n      \"copy_now_to_next\": \"當前高亮列複製一份到下一列\",\n      \"copy_now_to_pre\": \"當前高亮列複製一份到上一列\",\n      \"delete_now_column\": \"刪除當前高亮列\",\n      \"next_column\": \"下一列\",\n      \"pause\": \"暫停\",\n      \"play\": \"播放\",\n      \"play_now_column\": \"當前高亮列到遊戲裡面按下\",\n      \"pre_column\": \"上一列\",\n      \"save_sheet\": \"保存譜子\",\n      \"select_in_music\": \"從歌單裡面選歌\",\n      \"tip1\": \"長按間隔需要小於列後等待延遲，已自動調整(當下)\",\n      \"tip2\": \"已復製到開頭\",\n      \"tip3\": \"已復製到上一列\",\n      \"tip4\": \"已復製到下一列\",\n      \"tip5\": \"已復製到最後一列\",\n      \"tip6\": \"長按間隔需要小於等待間隔，已自動增加列後等待延遲(當下)\",\n      \"tip7\": \"列後等待延遲不能小於 10，已自動調整(全局新增)\",\n      \"tip8\": \"長按間隔需要小於列後等待延遲 10ms，已自動調整(全局新增)\",\n      \"upend\": \"倒放\",\n      \"upload_sheet\": \"上傳譜子編輯\"\n    },\n    \"title\": {\n      \"add_new_after_column\": \"新增的列後等待延遲\",\n      \"add_new_count_column\": \"新增列數量\",\n      \"add_new_druation_column\": \"新增的長按間隔\",\n      \"change_send_key_in_game\": \"過列發送按鍵到遊戲\",\n      \"columnAfterDuration\": \"列後等待延遲\",\n      \"columnDownDuration\": \"當列長按間隔\",\n      \"func_area_tip\": \"功能區提示\",\n      \"global_after\": \"全局列後延遲\",\n      \"global_down\": \"全局長按間隔\",\n      \"set\": \"設定\",\n      \"sheet_area_color\": \"譜區交替色\",\n      \"sheet_name\": \"歌曲名字\",\n      \"sheet_name_placeholder\": \"歌曲名字/文件名字\"\n    },\n    \"total_column\": \"總列數：{length}\",\n    \"total_time\": \"樂譜總時長：{length}\"\n  },\n  \"setting\": {\n    \"clearAll\": \"已重置快捷鍵\",\n    \"clearNow\": \"已清除本鍵\",\n    \"head_text\": \"彈琴映射為本次運行生效，重啟軟件需要重新設置，如不適應請盡快適應\",\n    \"key_map\": \"琴鍵映射\",\n    \"ok\": \"已設置\",\n    \"patterns0\": \"本次運行\",\n    \"patterns1\": \"重新\",\n    \"patterns2\": \"重啟\",\n    \"patterns3\": \"盡快適應\",\n    \"repeat\": \"存在重複的快捷鍵值，請檢查配置。\",\n    \"reset_map\": \"重 置 彈 琴 映 射\"\n  },\n  \"shortcutKeys\": {\n    \"button_title\": {\n      \"add_delay\": \"間隔\",\n      \"add_duration\": \"延音\",\n      \"add_speed\": \"倍速\",\n      \"exit\": \"退出\",\n      \"next\": \"下一首\",\n      \"pause\": \"暫停\",\n      \"reduce_delay\": \"- 間隔\",\n      \"reduce_duration\": \"- 延音\",\n      \"reduce_speed\": \"- 倍速\",\n      \"repeat\": \"重複\",\n      \"repeat_next\": \"重複併步過\",\n      \"resize\": \"重載按鍵\",\n      \"resume\": \"繼續\",\n      \"start\": \"播放\",\n      \"stop\": \"停止\"\n    },\n    \"divider1\": \"音樂快捷鍵\",\n    \"divider2\": \"跟彈快捷鍵\",\n    \"head_text\": \"快捷鍵為本次運行生效，重啟軟件需要重新設置，如不適應請盡快適應\",\n    \"patterns0\": \"本次運行\",\n    \"patterns1\": \"重新\",\n    \"patterns2\": \"重啟\",\n    \"patterns3\": \"盡快適應\",\n    \"title\": \"重 置 快 捷 鍵\"\n  },\n  \"tab\": {\n    \"love_success\": \"收藏成功\",\n    \"myFavorite\": \"收藏\",\n    \"myImport\": \"導入歌曲\",\n    \"myTranslate\": \"已轉換歌曲\",\n    \"remove_success\": \"移除成功\",\n    \"search\": \"搜尋\",\n    \"systemMusic\": \"自帶歌曲\",\n    \"translateOriginalMusic\": \"未轉換歌曲\",\n    \"clear\": \"清空\",\n    \"title\": \"播放列表\"\n  },\n  \"tutorial\": {\n    \"chose_music\": \"請先選擇一首歌曲\",\n    \"error\": \"轉換失敗，請重試\",\n    \"error_console\": \"轉換失敗\",\n    \"follow\": \"開始跟彈\",\n    \"no_music\": \"沒有歌曲\",\n    \"now\": \"當前: {music}\",\n    \"save\": \"保存可視化樂譜到桌面\",\n    \"save_desktop\": \"已保存在桌面\"\n  },\n  \"controller\": {\n    \"no_music\": \"沒有歌曲\"\n  },\n  \"music\": {\n    \"chose\": \"播 放:\",\n    \"placeholder1\": \"間隔\",\n    \"placeholder2\": \"延音\",\n    \"play\": \"選 擇:\",\n    \"space\": {\n      \"chose0\": \"系統自帶\",\n      \"chose1\": \"隨機\",\n      \"chose2\": \"自定義\",\n      \"mult_speed\": \"倍速\",\n      \"title\": \"間隔延遲\",\n      \"title1\": \"延音設置\"\n    }\n  },\n  \"rule\": {\n    \"cycle\": \"循環\",\n    \"order\": \"順序\",\n    \"random\": \"隨機\"\n  }\n}\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/main.ts",
    "content": "import { createApp } from 'vue'\nimport App from './App.vue'\nimport router from './router'\nimport store from './store'\nimport naive from 'naive-ui'\nimport i18n from './i18n'\n\nconst app = createApp(App)\napp.use(store)\napp.use(router)\napp.use(naive)\napp.use(i18n)\napp.mount('#app')\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/router/index.ts",
    "content": "import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'\n\nconst routes: Array<RouteRecordRaw> = [\n  {\n    path: '/',\n    name: 'home_loader',\n    component: () => import('../views/home_loader.vue')\n  },\n  {\n    path: '/home',\n    name: 'home',\n    component: () => import('../views/home.vue')\n  },\n  {\n    path: '/music',\n    name: 'music',\n    component: () => import('../views/music.vue')\n  },\n  {\n    path: '/kube',\n    name: 'kube',\n    component: () => import('../views/kube.vue')\n  },\n  {\n    path: '/tutorial',\n    name: 'tutorial',\n    component: () => import('../views/tutorial.vue')\n  },\n  {\n    path: '/magicTools',\n    name: 'magicTools',\n    component: () => import('../views/magicTools.vue')\n  },\n  {\n    path: '/shortcut',\n    name: 'shortcut',\n    component: () => import('../views/shortcutKeys.vue')\n  },\n  {\n    path: '/setting',\n    name: 'setting',\n    component: () => import('../views/setting.vue')\n  },\n  {\n    path: '/hwndHandle',\n    name: 'hwndHandle',\n    component: () => import('../views/hwndHandle.vue')\n  },\n  {\n    path: '/musicEdit',\n    name: 'musicEdit',\n    component: () => import('../views/music_edit.vue')\n  },\n  {\n    path: \"/aiSetting\",\n    name: \"aiSetting\",\n    component: () => import('../views/ai_setting.vue')\n  }\n]\n\nconst router = createRouter({\n  history: createWebHistory(import.meta.env.BASE_URL),\n  routes\n})\n\nexport default router\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/store/index.ts",
    "content": "import { createStore } from 'vuex'\n\nexport default createStore({\n  state: {\n    playList:[],\n  },\n  getters: {\n    getPlayList(state) {\n      return state.playList;\n    },\n    getNextPlayMusic(state){\n      const needReturn = state.playList[0]\n      state.playList.splice(0, 1)\n      return needReturn\n    }\n  },\n  mutations: {\n    setPlayList(state, datas) {\n      state.playList = datas;\n    },\n    addPlayList(state:any, data) {\n      let addFlag = true\n      state.playList.forEach(element => {\n        if(element.truthName === data.truthName){\n          addFlag = false;\n          return;\n        }\n      });\n      if(addFlag)\n      state.playList.push({'name': data.name ,'truthName':data.truthName, 'type': data.type})\n    },\n    removePlayList(state:any, index:number){\n      console.log(\"删除下标\",index)\n      state.playList.splice(index, 1)\n    },\n    clearPlayList(state:any){\n      state.playList = []\n    }\n  },\n  actions: {\n  },\n  modules: {}\n})\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/utils/configStore.ts",
    "content": "import { sendData } from \"@renderer/utils/fetchUtils\";\nexport enum CONFIG_TYPE {\n  DELAY_STATUS = 'DELAY_STATUS', //间隔延迟状态\n  DELAY_SPEED = 'DELAY_SPEED', //延迟设置\n  DELAY_RANDOM_START = 'DELAY_RANDOM_START',\n  DELAY_RANDOM_END = 'DELAY_RANDOM_END',\n\n  DURATION_STATUS = 'URATION_STATUS', //延音设置状态\n  DURATION_SPEED = 'DURATION_SPEED', //延音设置\n  DURATION_RANDOM_START = 'DURATION_RANDOM_START',\n  DURATION_RANDOM_END = 'DURATION_RANDOM_END',\n\n  PLAY_SPEED = 'PLAY_SPEED', //播放速度\n\n  SHORTCUT_KEY = 'SHORTCUT_KEY' //快捷键配置\n}\nexport enum CONFIG_STATUS_TYPE {\n  SYSTEM = 'system',\n  RANDOM = 'random',\n  CUSTOM = 'custom',\n}\n\n\nconst configStore = {\n  setItem: (key, value) => {\n    // @ts-ignore (define in dts)\n    window.elStore.setElStore(key, value)\n  },\n\n  getItem: (key) => {\n    // @ts-ignore (define in dts)\n    const value = window.elStore.getElStore(key)\n    return value\n  }\n}\n\nexport default configStore\n\n// 进入程序后，设置缓存快捷键配置\nexport const setConfigShortcutKey = ()=>{\n  if(!configStore.getItem(CONFIG_TYPE.SHORTCUT_KEY)) {\n    return\n  }\n  const shortcutKeyValues = configStore.getItem(CONFIG_TYPE.SHORTCUT_KEY);\n  const follow = shortcutKeyValues.follow_key;\n  const music = shortcutKeyValues.music_key;\n  const followString = (follow.repeat + follow.repeat_next + follow.resize);\n  const musicString = (music.next + music.pause + music.resume + music.start + music.stop + music.add_duration + music.reduce_duration + music.add_delay + music.reduce_delay + music.add_speed + music.reduce_speed);\n  const followKey = {\n    tap_key: \"yuiophjkl;nm,./\",\n    repeat: follow.repeat.toLowerCase(),\n    repeat_next: follow.repeat_next.toLowerCase(),\n    resize: follow.resize.toLowerCase(),\n    exit: follow.exit.toLowerCase(),\n    // 使用计算后的字符串\n    string: followString.toLowerCase()\n  };\n  const musicKey = {\n    next: music.next.toLowerCase(),\n    pause: music.pause.toLowerCase(),\n    resume: music.resume.toLowerCase(),\n    start: music.start.toLowerCase(),\n    stop: music.stop.toLowerCase(),\n    string: musicString.toLowerCase(),\n    add_duration: music.add_duration.toLowerCase(),\n    reduce_duration: music.reduce_duration.toLowerCase(),\n    add_delay: music.add_delay.toLowerCase(),\n    reduce_delay: music.reduce_delay.toLowerCase(),\n    add_speed: music.add_speed.toLowerCase(),\n    reduce_speed: music.reduce_speed.toLowerCase(),\n  };\n  sendData(\"config_operate\", {\n    \"operate\": \"set\",\n    \"name\": \"shortcutStruct\",\n    \"value\": {\n      \"follow_key\": followKey,\n      \"music_key\": musicKey\n    }\n  })\n}\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/utils/fetchUtils.ts",
    "content": "let baseUrl = \"http://127.0.0.1:9899/\"\n\nexport function getList(listName,searchStr){\n  return fetch(baseUrl+\"?listName=\"+listName+\"&searchStr=\"+searchStr)\n  .then(response => response.json())\n  .then(data =>{return data})\n  .catch(error => console.error(error));\n}\n\nexport function getData(url){\n  return fetch(baseUrl+url)\n  .then(response => response.json())\n  .then(data =>{return data})\n  .catch(error => console.error(error));\n}\n\nexport function sendData(url, data) {\n  console.log(\"data\",data)\n  return fetch(baseUrl + url, {\n    method: 'POST', \n    headers: {\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify(data), \n  })\n  .then(response => response.json())\n  .then(data =>{return data})\n  .catch(error => console.error(error));}\n\n  export function setConfig(name,value){\n    return fetch(baseUrl + \"config_operate\", {\n      method: 'POST', \n      headers: {\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify({\n        \"name\":name,\n        \"value\":value,\n        \"operate\":'set'\n      }), \n    })\n    .then(response => response.json())\n    .then(data =>{return data})\n    .catch(error => console.error(error));\n  }\n\n  export function getWWWData(url){\n    return fetch(url)\n    .then(response => response.text())\n    .then(data =>{return data})\n    .catch(error => console.error(error));\n  }"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/ai_setting.vue",
    "content": "<template>\n  <div class=\"father\">\n    <n-divider style=\"\">\n      <n-gradient-text\n          :gradient=\"{\n            from: 'rgb(242,201,196)',\n            to: 'rgb(221,242,196)',\n          }\"\n          id=\"WindHide\"\n        >\n        AIGC Settings\n      </n-gradient-text>\n    </n-divider>\n    <div class=\"father\">\n      <!-- <n-radio-group v-model:value=\"aigcValue\" name=\"radiogroup\">\n        <n-space>\n          <n-radio v-for=\"option in options\" :key=\"option.value\" :value=\"option.value\">\n            <span style=\"color:#F2C9C4\">{{ option.label }}</span>\n          </n-radio>\n        </n-space>\n      </n-radio-group> -->\n    <n-highlight style=\"margin-bottom: 5px; color: #DDF2C4;\" :text=\"headText\" :patterns=\"patterns\" :highlight-style=\"{\n      padding: '0 6px',\n      margin: '0 6px',\n      borderRadius: themeVars.borderRadius,\n      display: 'inline-block',\n      color: 'black',\n      background: '#F2C9C4',\n      transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n    }\" />\n    <div style=\"flex-basis: 100%;\" />\n      <div style=\"flex-basis: 100%; margin-bottom: 20px;\" />\n      <n-input-group style=\"width:450px\">\n        <n-input type=\"text\" size=\"large\" v-model:value=\"token\"/>\n        <n-button type=\"primary\" size=\"large\" @click=\"setData()\" ghost style=\"height:42px\">\n          {{ t('ai_setting.buttons.set_token') }}\n        </n-button>\n      </n-input-group>\n      <n-button type=\"primary\" color=\"#f58f98\" style=\"height:42px; margin-left: 41px;\" ghost @click=\"musicActive = true\">\n          :3\n      </n-button>\n    </div>\n    <n-tabs\n      class=\"card-tabs\"\n      default-value=\"signin\"\n      size=\"large\"\n      animated\n      pane-wrapper-style=\"margin: 0 -4px\"\n      pane-style=\"padding-left: 4px; padding-right: 4px; box-sizing: border-box;\"\n    >\n      <n-tab-pane name=\"signup\" tab=\"转谱提示词\">\n         <n-input\n            v-model:value=\"translate_prompt\"\n            type=\"textarea\"\n            placeholder=\"自动调整尺寸\"\n            :autosize=\"{\n              minRows: 15,\n              maxRows: 21\n            }\"\n            />\n      </n-tab-pane>\n      <n-tab-pane name=\"signin\" tab=\"延音提示词\">\n         <n-input\n            v-model:value=\"duration_prompt\"\n            type=\"textarea\"\n            placeholder=\"自动调整尺寸\"\n            :autosize=\"{\n              minRows: 15,\n              maxRows: 21\n            }\"\n            />\n      </n-tab-pane>\n    </n-tabs>\n  </div>\n  <n-drawer v-model:show=\"musicActive\" :width=\"1000\" placement=\"left\" :trap-focus=\"false\" :block-scroll=\"false\">\n    <n-drawer-content>\n      <n-card style=\"margin-left: -16px; width: 965px;\" :bordered=\"false\">\n        <n-tabs type=\"bar\" animated size=\"small\" @update:value=\"handleUpdateValue\" @before-leave=\"handleBeforeLeave\"\n          :value=\"tabsNumber\">\n          <n-tab-pane name=\"systemMusic\" :tab=\"t('tab.systemMusic')\">\n            <n-data-table :columns=\"tableColumns\" :data=\"music.systemMusic\" :bordered=\"false\" :min-row-height=\"48\"\n              ref=\"systemMusic\" :max-height=\"600\" :virtual-scroll=\"music.systemMusic?.length > 7\"\n              :row-class-name=\"rowClassName\" style=\"\n              --n-td-color: rgba(57, 57, 62, 0);\n              --n-th-color-hover: rgba(57, 57, 62, 0);\n              --n-th-color: rgba(57, 57, 62, 0);\n              --n-td-color-hover: rgba(0, 0, 0, 0.2);\n            \" />\n          </n-tab-pane>\n          <n-tab-pane name=\"myImport\" :tab=\"t('tab.myImport')\" ref=\"myImport\">\n            <n-data-table :columns=\"tableColumns\" :data=\"music.myImport\" :bordered=\"false\" :min-row-height=\"48\"\n              ref=\"myImport\" :max-height=\"600\" :virtual-scroll=\"music.myImport?.length > 7\"\n              :row-class-name=\"rowClassName\" style=\"\n              --n-td-color: rgba(57, 57, 62, 0);\n              --n-th-color-hover: rgba(57, 57, 62, 0);\n              --n-th-color: rgba(57, 57, 62, 0);\n              --n-td-color-hover: rgba(0, 0, 0, 0.2);\n            \" />\n          </n-tab-pane>\n          <n-tab-pane name=\"myTranslate\" :tab=\"t('tab.myTranslate')\" ref=\"myTranslate\">\n            <n-data-table :columns=\"tableColumns\" :data=\"music.myTranslate\" :bordered=\"false\" :min-row-height=\"48\"\n              ref=\"myTranslate\" :max-height=\"600\" :virtual-scroll=\"music.myTranslate?.length > 7\"\n              :row-class-name=\"rowClassName\" style=\"\n              --n-td-color: rgba(57, 57, 62, 0);\n              --n-th-color-hover: rgba(57, 57, 62, 0);\n              --n-th-color: rgba(57, 57, 62, 0);\n              --n-td-color-hover: rgba(0, 0, 0, 0.2);\n            \" />\n          </n-tab-pane>\n          <n-tab-pane name=\"myFavorite\" :tab=\"t('tab.myFavorite')\" ref=\"myFavorite\">\n            <n-data-table :columns=\"tableColumns\" :data=\"music.myFavorite\" :bordered=\"false\" :min-row-height=\"48\"\n              ref=\"myFavorite\" :max-height=\"600\" :virtual-scroll=\"music.myFavorite?.length > 7\"\n              :row-class-name=\"rowClassName\" style=\"\n              --n-td-color: rgba(57, 57, 62, 0);\n              --n-th-color-hover: rgba(57, 57, 62, 0);\n              --n-th-color: rgba(57, 57, 62, 0);\n              --n-td-color-hover: rgba(0, 0, 0, 0.2);\n            \" />\n          </n-tab-pane>\n          <template #suffix>\n            <n-input v-model:value=\"searchText\" round :placeholder=\"t('tab.search')\" style=\"top:-3px;width: 25vh; margin-left: 5px\">\n              <template #suffix>\n                <n-icon :component=\"Search\" />\n              </template>\n            </n-input>\n          </template>\n        </n-tabs>\n      </n-card>\n    </n-drawer-content>\n  </n-drawer>\n</template>\n\n<script setup lang=\"ts\">\nimport { getList, sendData } from \"@renderer/utils/fetchUtils\";\nimport { h, onMounted, onUnmounted, reactive, ref, watch } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { MessageReactive, NButton, useMessage, useThemeVars } from 'naive-ui'\nimport { RowData } from \"naive-ui/es/data-table/src/interface\";\nimport { Search } from '@vicons/ionicons5'\nimport { debounce } from \"lodash-es\";\nconst themeVars = useThemeVars();\nconst { t } = useI18n();\nconst message = useMessage()\nlet messageReactive: MessageReactive | null = null\nconst token = ref(\"\")\nconst translate_prompt = ref(\"\")\nconst duration_prompt = ref(\"\")\nconst musicActive = ref(false);\nconst tabsNumber = ref(\"systemMusic\")\nconst searchText = ref('');\nlet aigcValue = ref(\"DeepSeek\")\nconst QCount = ref(300)\nconst headText = \"音乐时间过长，需要等待的时间也就越长。频繁失败代表api没钱了，aigc出来的效果未必很好，请不要抱有太大期望，api没钱了可以去DeepSeek官网申请自行在下方保存\"\nconst patterns = [\"没钱了\",\"等待\",\"越长\",\"效果未必很好\", \"期望\", \"没钱了\", \"DeepSeek\", \"申请\", \"保存\"]\nconst options = [\n  {\n    label: \"DeepSeek（AI也会犯错效果不会那么好）\",\n    value: 'DeepSeek'\n  },\n  // {\n  //   label: \"Kimi\",\n  //   value: 'Kimi'\n  // },\n  // {\n  //   label: \"Qwen\",\n  //   value: 'Qwen'\n  // }\n]\nlet nowType = 'systemMusic'\n// 音乐数据管理\nconst music: any = reactive({\n  systemMusic: [],\n  myImport: [],\n  myTranslate: [],\n  myFavorite: [],\n  musicList: []\n});\nconst fetchListData = debounce(() => {\n  getListData('myFavorite');\n  getListData('systemMusic');\n  getListData('myImport');\n  getListData('myTranslate');\n}, 200);\nwatch(searchText, fetchListData)\nfunction handleBeforeLeave(name: string) {\n  nowType = name\n  return true\n}\nfunction rowClassName(row: RowData) {\n  if (row?.position) {\n    return 'table_position'\n  }\n  return 'td_css'\n}\nfunction setData(){\n  sendData(\"config_operate\", {\n    \"operate\": \"set\",\n    \"name\": \"ai_token\",\n    \"value\": {\n      \"type\": aigcValue.value,\n      \"token\":token.value\n    }\n  })\n  sendData(\"config_operate\", {\n    \"operate\": \"set\",\n    \"name\": \"translate_prompt\",\n    \"value\": translate_prompt.value\n  })\n  sendData(\"config_operate\", {\n    \"operate\": \"set\",\n    \"name\": \"duration_prompt\",\n    \"value\": duration_prompt.value\n  })\n  message.success(\"done\")\n  getData()\n}\n\nfunction getData(){\n  sendData(\"config_operate\",{\n    \"operate\":\"get\",\n    \"name\": `general_ai`\n  }).then(res=>{\n    token.value = res[aigcValue.value][\"key\"]\n  })\n  sendData(\"config_operate\",{\n    \"operate\":\"get\",\n    \"name\": \"translate_prompt\"\n  }).then(res=>{\n    translate_prompt.value = res\n  })\n  sendData(\"config_operate\",{\n    \"operate\":\"get\",\n    \"name\": \"duration_prompt\"\n  }).then(res=>{\n    duration_prompt.value = res\n  })\n}\nwatch(translate_prompt, () => {\n  sendData(\"config_operate\", {\n    \"operate\": \"set\",\n    \"name\": \"translate_prompt\",\n    \"value\": translate_prompt.value\n  })\n})\nwatch(duration_prompt, () => {\n  sendData(\"config_operate\", {\n    \"operate\": \"set\",\n    \"name\": \"duration_prompt\",\n    \"value\": duration_prompt.value\n  })\n})\n\nconst tableColumns = [\n  {\n    title: t('columns.name'),\n    key: 'name',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: { tooltip: true }\n  },\n  {\n    title: t('columns.total_duration'),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n  {\n    title: t('columns.operation'),\n    key: 'operation',\n    align: \"center\",\n    width: 150,\n    className: 'th_css',\n    render(row) {\n      return [\n        h(NButton, {\n        ghost: true,\n        onClick: () => {\n          messageReactive = message.loading(`正在调用${aigcValue.value}进行优化曲谱`, {\n            duration: 0\n          })\n          sendData(\"aigc\", {\n             \"ai\": aigcValue.value,\n             \"model\": \"duration\",\n             \"filename\": row.truthName,\n             \"type\": nowType \n            }).then(_res => {\n              if (_res == \"ok\"){\n                messageReactive!.destroy()\n                messageReactive = null\n                message.success('保存到了已转换歌曲下了~', {\n                  duration: 5000\n                })\n              }else{\n                messageReactive!.destroy()\n                messageReactive = null\n                message.error('一定是那里出问题了，可能吧？', {\n                  duration: 5000\n                })\n              }\n            }).catch(_=>{\n                message.error('一定是哪里出问题了，可能吧？', {\n                  duration: 5000\n                })\n            })\n        }\n      }, {\n        default: () => '🎻'\n      }),\n      h(NButton, {\n        size: 'medium',\n        ghost: true,\n        onClick: () => {\n          messageReactive = message.loading(`正在调用${aigcValue.value}进行优化曲谱`, {\n            duration: 0\n          })\n          sendData(\"aigc\", {\n              \"ai\": aigcValue.value,\n              \"model\": \"optimization\",\n              \"filename\": row.truthName,\n              \"type\": nowType \n            }).then(_res => {\n              if (_res == \"ok\"){\n                messageReactive!.destroy()\n                messageReactive = null\n                message.success('保存到了已转换歌曲下了~', {\n                  duration: 5000\n                })\n              }else{\n                messageReactive!.destroy()\n                messageReactive = null\n                message.error('一定是哪里出问题了，可能吧？', {\n                  duration: 5000\n                })\n              }\n            }).catch(_=>{\n                message.error('一定是哪里出问题了，可能吧？', {\n                  duration: 5000\n                })\n            })\n        },\n        style: {\n          marginLeft: '10px',       // 设置边框圆角\n        }\n      }, {\n        default: () => '🎹'\n      })\n      ]\n    }\n  }\n];\n\nfunction timeToSeconds(timeString) {\n    var splitTime = timeString.split(':');\n\n    // 如果是 HH:MM:SS 格式\n    if (splitTime.length === 3) {\n        var hours = parseInt(splitTime[0], 10);\n        var minutes = parseInt(splitTime[1], 10);\n        var seconds = parseInt(splitTime[2], 10);\n        return hours * 3600 + minutes * 60 + seconds;\n    }\n\n    // 如果是 MM:SS 格式\n    if (splitTime.length === 2) {\n        var minutes = parseInt(splitTime[0], 10);\n        var seconds = parseInt(splitTime[1], 10);\n        return minutes * 60 + seconds;\n    }\n\n    return 0; // 如果格式不正确，返回0\n}\n\nfunction handleUpdateValue(value: string) {\n  tabsNumber.value = value\n  getListData(value)\n}\n\nasync function getListData(value) {\n  await getList(value, searchText.value).then((_res) => {\n    eval('music.' + value + '=_res')\n  })\n}\n\nwatch(aigcValue, getData)\n\nonMounted(()=>{\n  getData()\n  window.api.window_size(774, 1500);\n  getListData('systemMusic');\n})\nonUnmounted(()=>{\n  window.api.window_size(0, 0);\n})\n</script>\n\n<style scoped>\n@import url(https://fonts.googleapis.com/css?family=Pacifico);\n\n.father{\n  display: flex;\n  align-items: center; /* 垂直居中 */\n  justify-content: center; /* 水平居中 */\n  flex-wrap: wrap; /* 允许换行 */\n}\n#WindHide {\n  font-size: 30px;\n  font-weight: bolder;\n  font-family: \"pacifico\";\n}\n\n:deep(.n-input){\n  --n-border-hover: 1px solid rgb(242,232,196)!important;\n  --n-border-focus: 1px solid rgb(242,232,196)!important;\n  --n-caret-color: rgb(242,232,196)!important;\n  --n-color-focus: rgba(242,232,196,0.1)!important;\n}\n:deep(.n-tabs-bar){\n  --n-bar-color: rgb(242,232,196)!important;\n}\n:deep(.n-tabs){\n    --n-tab-text-color-active: rgb(242,232,196)!important;\n    --n-tab-text-color-hover: rgb(242,232,196)!important;\n    --n-tab-text-color: rgb(221,242,196)!important;\n}\n.n-input{\n  background-color: rgba(24, 24, 28, 0) !important;\n  border: 1pt solid rgba(242,232,196,0.5);\n}\n\n.midi-canvas {\n  width: 100%;\n  height: 100%;\n  display: block;\n  background: transparent;\n}\n\n:deep(.n-input) {\n  --n-border-hover: 1px solid rgb(242, 232, 196) !important;\n  --n-border-focus: 1px solid rgb(242, 232, 196) !important;\n  --n-caret-color: rgb(242, 232, 196) !important;\n  --n-color-focus: rgba(242, 232, 196, 0.1) !important;\n  --n-text-color: rgb(242,232,196) !important;\n}\n\n:deep(.td_css td) {\n  color: rgb(242, 232, 196) !important;\n}\n\n:deep(.th_css) {\n  color: rgb(221, 242, 196) !important;\n}\n:deep(.n-base-selection-label){\n  height:5.4vh !important;\n}\n\n:deep(.n-radio){\n  --n-box-shadow-active: inset 0 0 0 1px rgb(242,232,196)!important;\n  --n-box-shadow-focus: inset 0 0 0 1px rgb(242,232,196), 0 0 0 2px rgba(242,232,196, 0.3)!important;\n  --n-box-shadow-hover: inset 0 0 0 1px rgb(242,232,196)!important;\n  --n-dot-color-active: rgb(242,232,196)!important;\n}\n</style>\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/home.vue",
    "content": "<template>\n  <div id=\"father\">\n    <n-divider>\n      <img\n        id=\"avatar\"\n        src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAi4AAAItCAYAAAAe3vFxAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAGlmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4xLWMwMDIgNzkuYjdjNjRjYywgMjAyNC8wNy8xNi0wNzo1OTo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI2LjAgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyNC0xMi0xMFQwOTo0OTozMCswODowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjUtMDEtMTNUMTE6Mzg6MTErMDg6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjUtMDEtMTNUMTE6Mzg6MTErMDg6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmE2OWZkODc2LWQ5M2UtNDY0ZC05NzQwLTQyNjdiNDcxZTg0ZCIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjgwNjBmYjE1LWM3NDEtMzE0NS1iOTM3LThlZTExYjcxMzQ4YiIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmFlYzI5ZWIzLTE3ZmMtZjc0NC04ODNlLWY0Y2RkMTcyZmVhNSI+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6YWVjMjllYjMtMTdmYy1mNzQ0LTg4M2UtZjRjZGQxNzJmZWE1IiBzdEV2dDp3aGVuPSIyMDI0LTEyLTEwVDA5OjQ5OjMwKzA4OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjYuMCAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmQ4ZmY3MDQyLWMzOWUtMDU0NS04MDU3LWZmYWM3ZDIxZjY4OSIgc3RFdnQ6d2hlbj0iMjAyNC0xMi0xMFQxNToxMjowMSswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI2LjAgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDphNjlmZDg3Ni1kOTNlLTQ2NGQtOTc0MC00MjY3YjQ3MWU4NGQiIHN0RXZ0OndoZW49IjIwMjUtMDEtMTNUMTE6Mzg6MTErMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyNi4wIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7+cTAcAAGUPUlEQVR42uy9BXyU17b+/7/2u/ece4/3nJ721J3iFGiBlkLx0uIuLU6BQHB3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\"\n      />\n    </n-divider>\n    <n-gradient-text\n      :gradient=\"{\n        from: 'rgb(242,201,196)',\n        to: 'rgb(221,242,196)',\n      }\"\n      id=\"WindHide\"\n    >\n    Wind Hide\n  </n-gradient-text>\n    <div style=\"flex-basis: 100%;\" />\n    <n-highlight\n      style=\"margin-bottom: 5px; color: #DDF2C4;\"\n      :text=\"headText\"\n      :patterns=\"patterns\"\n      :highlight-style=\"{\n        padding: '0 6px',\n        margin: '0 6px',\n        borderRadius: themeVars.borderRadius,\n        display: 'inline-block',\n        color: 'black',\n        background: '#F2C9C4',\n        transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n      }\"\n    />\n    <n-highlight\n      style=\"color: #DDF2C4;\"\n      :text=\"text\"\n      :patterns=\"patterns\"\n      :highlight-style=\"{\n        padding: '0 6px',\n        margin: '0 6px',\n        borderRadius: themeVars.borderRadius,\n        display: 'inline-block',\n        color: 'black',\n        background: '#F2C9C4',\n        transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n      }\"\n    />\n\n    <div style=\"flex-basis: 100%; margin-top: 20px;\"  />\n    <n-button ghost color=\"#F2C9C4\"  @click=\"openUrl('https://kdocs.cn/l/cpTkEdhxIRob')\"  style=\"font-size: 18px;\">\n      {{ t(\"home.tutorial\") }}\n    </n-button>\n    <n-button ghost color=\"#A3F6EC\"  @click=\"openUrl('https://qm.qq.com/q/KxkCQdS7OA')\"  style=\"font-size: 18px; margin-left: 20px;\">\n      {{ t(\"home.qq\") }}\n    </n-button>\n    <n-button ghost color=\"#D0BDF4\"  @click=\"openUrl('https://pd.qq.com/s/9boevqcwu')\"  style=\"font-size: 18px; margin-left: 20px;\">\n      {{ t(\"home.qq_sb\") }}\n    </n-button>\n    <div style=\"flex-basis: 100%; margin-top: 20px;\" />\n    <n-button type=\"info\" color=\"#F2C9C4\" text  @click=\"openUrl('https://github.com/windhide/SkyMusicPlay-for-Windows/pulls')\"  style=\"font-size: 30px\">\n      <n-icon>\n        <GitPullRequest />\n      </n-icon>\n    </n-button>\n    <n-button type=\"info\" color=\"#F2C9C4\" text  @click=\"openUrl('https://github.com/windhide/SkyMusicPlay-for-Windows')\" style=\"margin-left: 20px; font-size: 30px\">\n      <n-icon>\n        <LogoGithub />\n      </n-icon>\n    </n-button>\n    <n-button type=\"info\" color=\"#DDF2C4\" text  @click=\"openUrl('https://github.com/windhide/SkyMusicPlay-for-Windows/issues/new')\" style=\"margin-left: 20px; font-size: 30px\">\n      <n-icon>\n        <Build />\n      </n-icon>\n    </n-button>\n    <n-button type=\"info\" color=\"#DDF2C4\" text  @click=\"checkForUpdates()\" style=\"margin-left: 20px; font-size: 30px\">\n      <n-icon>\n        <CloudDownloadSharp />\n      </n-icon>\n    </n-button>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useThemeVars, useDialog } from \"naive-ui\";\nimport { GitPullRequest, LogoGithub, Build, CloudDownloadSharp } from \"@vicons/ionicons5\";\nimport { getData } from \"@renderer/utils/fetchUtils\";\nimport { useMessage } from 'naive-ui'\nimport { useRoute } from 'vue-router';\nimport { onMounted } from 'vue'\nimport { setConfigShortcutKey } from '@renderer/utils/configStore'\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\nconst route = useRoute();\nconst themeVars = useThemeVars();\nconst dialog = useDialog();\nconst message = useMessage()\nconst headText = t(\"home.head_text\");\nconst text = t(\"home.text\");\nconst patterns = [t(\"home.patterns0\"),t(\"home.patterns1\"),t(\"home.patterns2\")];\n\n/**\n * 打开指定链接\n * @param url 链接地址\n */\nfunction openUrl(url: string): void {\n  getData(`openBrowser?url=${url}`);\n}\n\n/**\n * 检查是否有更新\n */\nasync function checkForUpdates(): Promise<void> {\n  try {\n    const clientVersion: string = await window.api.getVersion();\n    const cloudVersion: any = await getData(\"update\");\n    if (!cloudVersion) return;\n    const clientVersionNum = Number(clientVersion.match(/\\d/g)?.join(\"\") || 0);\n    const cloudVersionNum = Number(cloudVersion.version.match(/\\d/g)?.join(\"\") || 0);\n\n    if (cloudVersionNum === 404) {\n      message.info(t(\"home.update_info\"));\n      return;\n    }\n\n    if (cloudVersionNum > clientVersionNum) {\n      dialog.success({\n        title: cloudVersion.title,\n        content: cloudVersion.content\n          ?.replaceAll(\"\\\\n\", \"\\n\")\n          .replaceAll(\"\\\\t\", \"\\t\"),\n        positiveText: cloudVersion.positiveText,\n        negativeText: cloudVersion.negativeText,\n        contentStyle: { whiteSpace: \"pre-wrap\" },\n        positiveButtonProps: {\n          color: '#F2C9C4'\n        },\n        negativeButtonProps:{\n          color: '#A3F6EC'\n        },\n        onPositiveClick: () => {\n          openUrl(cloudVersion.downloadUrl);\n        },\n        onNegativeClick: () => {\n        }\n      });\n    }else{\n      message.success(t(\"home.update\"));\n    }\n  } catch (error) {\n    message.info(t(\"home.update_error\"));\n  }\n}\n\nonMounted(()=>{\n  console.log(\"params\", route.query)\n  if ( route.query.show === \"1\"){\n    checkForUpdates()\n    setConfigShortcutKey()\n  }\n})\n</script>\n\n<style scoped>\n@import url(https://fonts.googleapis.com/css?family=Pacifico);\n\n#WindHide {\n  font-size: 30px;\n  font-weight: bolder;\n  font-family: \"pacifico\";\n}\n\n#father {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  flex-wrap: wrap;\n}\n\n#avatar {\n  height: 250px;\n  width: 250px;\n}\n</style>\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/home_loader.vue",
    "content": "<template>\n  <div id=\"father\">\n    <n-divider>\n      <img\n        id=\"avatar\"\n        src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAi4AAAItCAYAAAAe3vFxAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAGlmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4xLWMwMDIgNzkuYjdjNjRjYywgMjAyNC8wNy8xNi0wNzo1OTo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI2LjAgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyNC0xMi0xMFQwOTo0OTozMCswODowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjUtMDEtMTNUMTE6Mzg6MTErMDg6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjUtMDEtMTNUMTE6Mzg6MTErMDg6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmE2OWZkODc2LWQ5M2UtNDY0ZC05NzQwLTQyNjdiNDcxZTg0ZCIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjgwNjBmYjE1LWM3NDEtMzE0NS1iOTM3LThlZTExYjcxMzQ4YiIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmFlYzI5ZWIzLTE3ZmMtZjc0NC04ODNlLWY0Y2RkMTcyZmVhNSI+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6YWVjMjllYjMtMTdmYy1mNzQ0LTg4M2UtZjRjZGQxNzJmZWE1IiBzdEV2dDp3aGVuPSIyMDI0LTEyLTEwVDA5OjQ5OjMwKzA4OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjYuMCAoV2luZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmQ4ZmY3MDQyLWMzOWUtMDU0NS04MDU3LWZmYWM3ZDIxZjY4OSIgc3RFdnQ6d2hlbj0iMjAyNC0xMi0xMFQxNToxMjowMSswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI2LjAgKFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDphNjlmZDg3Ni1kOTNlLTQ2NGQtOTc0MC00MjY3YjQ3MWU4NGQiIHN0RXZ0OndoZW49IjIwMjUtMDEtMTNUMTE6Mzg6MTErMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyNi4wIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7+cTAcAAGUPUlEQVR42uy9BXyU17b+/7/2u/ece4/3nJ721J3iFGiBlkLx0uIuLU6BQHB3iEKCBAhWnCIthRYp7u6EEJzgIUJIIIqt//6+maGBJjPvJDPJJNn783k+gcjMO6/s/ey1nvWs/09E/j8NDQ0NDQ0NjbwAfRI0NDQ0NDQ0NHHR0NDQ0NDQ0NDERUNDQ0NDQ0MTFw0NDQ0NDQ0NTVw0NDQ0NDQ0NDRx0dDQ0NDQ0NDERUNDQ0NDQ0NDExcNDQ0NDQ0NDU1cNDQ0soCEhIR/u3379n/cuXPn3/PiccfGxv67vo4aGpq4aGho5HNcv379v9euXVs2ICBgkbe393GFXXPmzOkQEhLyHKTAXY/71q1b/7Vly5aigYGBwZbj3j9jxozehw8ffjE+Pv7f9LXV0NDERUNDI5/h9OnTf/bx8dkcGhoq9+/fl8ePH8ujR4/kzp07Mnv27PsrV66sHBcX53aRjPDw8N9BtA4dOiSpqalPjvvu3buycOHCh0uWLKmb1yJHGhoamrhoaGjYQExMzH9MmTJl1MWLFyWjARGAvOzZs+cNdzpu0kLBwcEDzp8/n+lxz5w5M3Xfvn2v6uusoaGJi4aGRj7BqVOn/jpu3LhYFvrMRnh4uEybNm2IO0UvTpw48fcJEybcI8qS2bh27ZqQNkpMTNQpIw0NTVw0NDTyA/bu3fv6kiVLMmctasTFxYmfn9+aiIiI/3IXIe6qVasq7dq1y9ZhS1JSkvj4+OyMior6T32tNTQ0cdHQ0MgH2Llz5zsrV658bIsAoBlRBGDrjRs3/p87HDORHyIpV69etUlciMZMnjw5kaiSvtYaGpq4aGho5AMcPXr0n8HBwSm2CEB0dLQEBATMQQ/jLvqWKVOmeN28eVPsjfnz5z84duzY8/paa2ho4qKhoWEDd+/e/TdKjKnYYcd/5cqV37ljZQ7HRTqFqEpmY9u2bUJlkbtoRSzHvFcdj92IiyJc8WfPnv2ju5130lcXLlz4P+4NvipyqNNZGhqauGho5A4uXrz4v7Nnz+6iFtebixYtoiz3kb+//+3Jkyf7h4aGulXaAjKyffv2QqRU0IQ8u/CrhZXFfxFkwZ3Kt319fSMfPnxok7hAbNDmEKFxpyqujRs3loB4TZ06NZl7Y8qUKcn45mzevLm4Ox2rhoYmLhoaBYS04ImC/iJ9xQv/xheFBdfdUhdEhw4dOvQSBIVFdO3atY+XLl36SC2mF5YvX17r2rVr/+1OxxsWFvYXRUhibFVCWUXFgYGBs/h87nDc9+7d+ze8ZdavX/8Yv5z0g/+jNfrhhx+q8Xv6WdLQ0MRFQyNHohcsTIcPH850MVU7bhk3btwSHF/d7fhZMDkuyNfly5d/5672+RAXf39/s8Ql2F2IAOQQYphZCTcRJAiZO6a2NDQ0cdHQyIdg0VcLz8/2tBcIRt3N0C0vgXSbPe+Z9BEXdyAu6J1IW3FMtsaGDRsekzLS11lDQxMXDQ2XA5Glt7f3ZXvai2PHjsnixYsbunMPIHcGJdzq/D20V1FE1dHUqVOHu4Oo+OTJk39TJCrelmEeIywsTBYsWNBcm+ZpaGjioqGRI6JRUhj2FqeoqCgEr/O1MVrWgO7GVjrOOjZv3iwIYd3hmGlgSTTF3jEjhtbERUNDExcNjRwr0/X29g558OCBzcWJhoAIXy9duvR7fd4cx7Jly2oTtbI31O89whk4t4+XSiFaJtgzzGMo8ivz5s1rraNxGhqauGhouByRkZFoXNYkJyfbXJyIyNAA8ODBgy/r8+Y4duzY8S5VT/bOcVBQUNLx48f/kdvHS1UW5c72tE+MnTt3CtEZfZ01NDRx0dDIkbJi/FtoSmhmgVq9enUFfd6yJs7FF8eWODchIYGo1i53aFMAeaIhpD0xMWSLqiMaSOrrrKGhiYuGRo5g06ZNJbZs2WKXuERGRsrEiROD3Knjcl4BZITqLVsVOmhgFi1a5BYCaHU/FF23bp1dfQteLopshbmbb46GhiYuGhr5PBowfvz4OHsCXXQwapE6d/Xq1f/R581xbNu27f3p06enZqQnwisHrdGZM2f+lNvHGR8f/2/BwcEDrl+/bpfMKkJGxMXLHVtDaGho4qKhkU8RERHxXzjnpqSk2F2oaAdw4MCBV/R5cxws7njhcK4XLlz4kNQbVUS0Lpg0aVKgu3SEvnnz5v/D3h9Btr2xf/9+WbVqVSV9fTU0NHHR0MgxYHZGVci5c+fsLlSKtKBzKafPW9ZBSTmRFYTOR44ceQHXX3dKv6FvQSRs716wiol1J2sNDU1cNDRyJY1Bvx97i5VaZGXu3LlttWdH/tY80V3b3kCv4+fnt5LKNH3eNDQ0cdHQyFFYuxfbqyJBoIumwV2aAGo4F0R+JqoRGxtrl7ggJsZYT583DQ1NXDTyEdiNkhZQk/yLNKw7d+7cHzD3cseqF0VcNlCSa2ucP38es7GW+trmTyC8RiRsrwUEA1+a3bt3v+mOnwOdTkhIyHP79u179ejRo/+kASeiY32NNTRx0dDIBEQkLELMrTQo3LRp02MQHBycEhAQsMjddAEcL6W4ilzZXKz4DJTK6mucP8FCz/1qj7RAbBTRjYCIu5t+CA0WLs/ff//9IwTQlHVTNTdz5kyP8PDw3+nrrKGJi4ZGBiDCoghKfEbOo3fu3KH09TJlyO50zFS1sBhlttu2eHZc1rb/+TdNxOKOjsneoHx73LhxS9xJ30LV1pIlS+rRX+nZexghMc0g8SHS/bY0NHHR0HgGsbGx/x4UFORDp9/MxokTJ4yUCxU97lRdpCb9UnPmzLlPCwCrrwtfSSHhkLp169Yi+hrnT1y/ft2w+TdTFm9trOhO/YnQafn4+Ny0leZasWLFY9ov6OutoYmLhkY6EJFQC0C4LaGru1ZksGtFizN16tTh6jOcQbDr5eUVqkjLKL6vdQL5F2baEqQnAFSiudPxo7ex1w8KU70ZM2b01g0hNTRx0dBIB/q22PPBYFcLMXDXnDsEBsEu3aMROmpn1PwPMws/A2JDGtRdDPOsWLNmzYf2WlfcvXtXFDlb7o4CeQ1NXDQ0cg0IFv38/GJsWeiTekG4i2utPmca7iDOJvUTGhpqN9pijRbeunXLre5dIkCrV6+26UUUHR2NaZ6PLufX0MRFQ+OZUkxFSnba0gqgf8HmHT2MPmfOAWksokQ40VLWq5tBOlaNExAQMMeMfwsl8ZgQulu6BUE8OixbG4aQkBBZsmRJXX3NNTRx0dB4BmrnV4HqhowmTyZWetVs3769kD5XzokW7N+//xWqXAIDA+Mp56X/D+Rx48aNJWJiYnRawA7o7sz5yqgK7tmxatWqxzt37nzHHTcMkK/MmkMmJSWRnr3kbiXcGpq4aGi4Bdj5U1qKlwTlz5QSg4iICKFDMGWb0dHRuiwzm6D1wObNm4tzTkm/pd9tE/HCw4MUiBYV2wZaJrWo72dxtzWo2FG/d8VdS+LDwsL+Qhprz549RjqWTtzcB0SJOG68lfT11tDERUMjEyAAxLUTW/Tg4OAB06ZNG/LTTz9VRNSoc+zOAWkhqp4yS8tBZGbPnn1fd7S2T7R9fX1/uXfvnk3ign8LKU53vn/R3mCkR+NQjlVtIHpCbrlX9LXW0MRFQ8OByIAuwXQ+9u7d+7q9Spjw8HDISxd9/jMHWit6UNnyHmKQ/ly7dm3ZvPK58CbSDUE1NHHR0NBwGxDBUrtru1Uw6F90as426AqNfiWz83j16lUJDAwM1s6zGhqauGhoaGTDu2PXrl12iUtAQMB87d1hX6A7efJkf/QhaEPSp9vUz9CIhOFRpM+VhoYmLhoaGlkEWobFixfbbGVM7x3Kd3XKwFxlDpEXBK54EeGk6+XldYT2FGfPnv2jPkcaGpq4aGhoOKGMlwqSjAYurxMmTLh38uTJv+nzZR5UYdGOAqGr9sPR0NDERUNDw8lRFz8/vyiEpZTrktqAsGCmNnPmzNTVq1eX08JcDQ0NTVw0NDTcApASIiqUv/r6+m6gBxRdjmmmRxm07rOkoaGhiYuGhoZbEhgEuKQ4cMulFFafFw0NDU1cNDQ0NDRyVddEenDFihVVAV4+ly9f/p0+NxqauGhoaGhouA2IotEDjGqnY8eOSVRUlNHtmcaJ48aNi125cmVl7dWjoYmLhoaGhoZbYNu2be/PmTPnPgLsZwe+MzTX3LJlS1F9rjQ0cdHQ0NDQyFXgL2NxP5bMBn2U/P39l2tnXw1NXDTcPt/NLosGhgEBAYumTJkyCgMtut3q86OhkT9w7ty5P3h7e1+iw3pmg5+p37ngznoXmlOGhIQ8R3f4iRMnBtFCYdGiRQ1pxqr9cjRx0SgAOHLkyAteXl5HyXdjQJaamiqJiYkSGhrKBHaJFvbav8M1iIiI+C9KkBFJch3Cw8N/h2mZPjd5C1Rg0a2c67h///5XIAg0XHS34+Re8/f3j8koTWQd/IzfOXPmzJ/c9ZmZM2dOB0VUHqrzLnQ0B/xbEZlHM2fO9KBLt74vNXHRyKdgofTx8dmaWegYIoNgjwlZny/ngUWN7sCKGIavXr368YEDB2Tnzp0yadKkxOnTp/e7dOnS7/V5cn9QKk41jrqO+1esWGFcR5pVzps37wEpGXdzGr5w4cL/EU2xFXFh44KHjztGW9lAYYRIE0sMEp8dfE89V48RH+v7UxMXjXyKHTt2vLts2bJHYmPcuXOHiWzX1atX/0efM+csdpSfrlu37jHOtM9OvGq3TvfgWews9flybxCNnDhxYgI7/mcHTSkhpqGhoX91l+Ol9QD3FtGJzAY/I/Xijs00iaT4+fmt4dxmNviZ+p2fiYLpe1QTF418iB9++KEau0R748SJE0J4ltyyPm/ZQ1hY2F+w1rcVricKQ8dmfb4yjla5g46BhZFu2ZQTZzYgoUTQ3IkEECEKCgpKyuj+43vqeFN37979pjteexpUKjJ4JX3X7Uw0OpcvXrz4v/p50cRFIx/u/BcuXNgYLYu9QSRA/e5DIjR54bPRwRhxIVb1iIwRHh87dux5qipy+9g4FsLZts434XovL69QRNP6Xk2rhtm8eXNxiIKlFUEY/96wYUOp3Lqm58+fR+h6xRYBTU5O5joedae0CxoqnmN17Oe2bdsm4eHhcvXqVdm1a5cRIeL+dNf2DhaNzu1nI5XpBz/jd06fPv1n/exo4qKRD0G+mMnLzEhKSmJiO8eux50/EwZbP/30U0UMttAbqJ2XsfNVi9xjtYgcQa+TW2Jj3nfZsmW1Dx06ZPd847WBYLeg36PsnKl0279/vyHCZGEC/HvPnj2ifjYnNypgqGohTZSR1iL97t/Hx+emOz4zkOKDBw++jNYKQPIhWJB+d70X0H5B6DNKzVkHP1PzVIhObWviopGPK4qmTJmSbGvyTT9w15w5c2ZPd8x/WyMtRFioOMhoJ3z37l0Wkhu5JZokykUJJxVc9gZka968eS3deSHJieiAOl91iQZkNvgZv5PTZJQdPdU3tnb/FqHrBZ22cN6mBKsGIkSZDUXIhN/RZdGauGjkU7ArUQv5TrWgmiIuTNLkwBEluuPnYceIkJhqqMzGqVOnIAStc4MQWCMuZnRFlkWvQO8cr1+//t90qrZ1f7LDJpKW0yWw3Gu8r63dP8J2Pz+/lVpo7Tzg1QJh5PnI6F4YP3583OHDh1/U50oTF418DIR4U6dOTba1c0w/1C6YqMVeSqnd7bMQvp8wYcI9WxEkoi44g+aWzwb6AkpnzZxrrsuJEyf+XlDvTXRJlIjbup78LDAw8C4+Kjl5bAjVifRklmrlecJXBG2OnmecG1WFmFA5RHsCbARIGRJlheSS8tK+U5q4aBSAKg1SEmZ0F9ahJg5ZsGBBc3ebIMjZz549+76tY7fkwPfn1i4YvYOaYCPMEEUWxYJcXQTJw7PD3nlS5EA2btxYIjciljNmzOgNQcELiSgA99f169eFyp3ly5fX0g0LXVfVRYUehn8A4qojW5q4aBQgIHojimI2ZeSutuBmIi58Rn9//xW5FXFhwmW3iNjZ3jh//rx8++23ndDGFMT7kqohSIkZIk1X49wi/sePH/8H3jy0zAgODh6A2BXnWW0foKGhiYuGC0H41V5YPv1QC8Vjd9O6kL5ShOo4ZaiZDaqMsAXPzWgRO3G8cewNtDrq8xwsiD2jEFdOnjzZ35ZPinWQKqBCTj/HGhqauGgUsIUC0aoZ4ah1sXC3NIbFErwCGpKMCBhRDoR9CPxy8zgJbZNeMCOGDgwMjCeSVNDuR7oT+/r6/mJL/GrVuJCWKchaIA0NTVw0CizoZUKVUWxsrF3igiguN3QF9oCtORENPDaIrmABTnUHJcikt9Rxv5PbIXxSbHji2DIvsw5aA7jjec6JlJq6FzdnVD2SfnAOcUp1527GuUHgOR+HDh16adeuXW9D1N3BfFFDQxMXDZdFA8x4uxAxQMHvjp8BTQjeGUzaq1atqkQUBuGuuzjRQpxIV9nyo7AOvHMQQhc0PxeIC1UiJonLJW049qtgGK8lROq4YkPeEd4HBATEo8MhkqXPk4YmLhr5CpjL0Qpgy5YtmS4WFn+KNVrFn3Vs3769kD3rfwbl54h5C1p1CvcWnjy2Ohlr4vI0iKpMnDgx6PTp0xmm1BA6L1q0qKE2Z9PQxEUjX+52meDwSWDhtEZfWCSodMEYjUoKfa6yDso3x40bF2uvLJpzjm18QXNf5fzgz2Iv8mepcAvDrK6g31OkQW1ppzhXvr6+kTnteaOhoYmLRo6Jdak0IuxMpQ46AlxA6SitLcydszsmFZKYmGiqgou0V0E6P3xe9D32zo06j0L1UUGPIpBKJFKaUbQl/Vi2bNmjgnYvaWjiolEAhX7kxQnd6xCz80AfHnQuaBDsDXXuqZzxKUh+LqTSzHq4QKb1RuPOv0+ZMsUrMjLSrqieJqT6GdTQxEVDQ8NhUE5uS0tkHaSTqELK6X48uQnE1AsXLrRbdkWTxYLsLpxekI5ZYXh4uN0qNXXPFdXPn4YmLhoaGg6DMtXJkyebMv1bunTpo3379r1akKpj0FI9ePAg03PCeaOfE13Oc+KYEEiTPqVR5vTp0/vhe0SvL3chlBC4zHonWQkwnjc5db40NDRx0dDIZ8Dp18vLK9Re5QwD7QKC6YJSFo2VPukxW6kP2jfgO5QTwlyu1aRJkwLRG5G6473xO8KIkd5X7kAG6IPF/UQj0YzGpUuXMDQM1tWAGpq4aGhoZHlxpreNGT8X7P9xksVgr6Ccn717974+ffr01Mwqrygnx6PH1WQOi4CpU6cOp6Iuo4HJIdEhDBxzW6BLio1jCQsLM6qIqErDMRpty7hx45YoAvxn/expaOKioaGRLREqLQrsERdLWfQNGmIWlHOjCMG/Q0xIB+EdxDkARBQo+6WKxtX+NpY2EuXWr19v8xoReXEX0SupK/qIYVxISkudq3pEhCBg+pnT0MRFQyMdiAaEhob+FfddtADsQHOrC3NeAaXllJrb83NhLFq06CFRiJw6tpiYmP8g/YBDMvbx58+f/0NOG+HhMsw9RfdnolNEPtCY4CMEsXH1+1O2TusBe928r127JjNmzOjtbpVfudlMNDOQqsJLhugQOi/IeE5cSw1NXDQ0ntoZ79ix411y/YsXL36IQHDTpk2P6TaNLiAsLOwv+jxlDErNAwICFpFusDf27dtnlP66OjXCYseigm/PzJkzU6l8ojRZEYcUf3//5bml54AU5HSfKe5ddR5i7AmoFckTXGu1ZYBtIqzmhRLocBCbc18RyZowYcI9CCkkWZ8nDU1cNHIEW7duLTJv3rwHz4pMmewxCMPA7syZM3/S5ypjXQKiW3vGYQyEqorkzHd1vxmiK/S2ySjKQJrG19c34uTJk38rCNeH0uFVq1bZTeVBPNGQsDjr+zpj0kkqDcKS0Txx48YNUqFbdbNMDU1cNFwOGhcy4dhygKVtgNplHSlI+gxHQLTKjM7FatnuSoElqSCiZBBOW2kR0ja53WXb1UATMmXKlFF8XnuD80XUIL+fk6xi27Zt75PqtBW5IgKDnkifLw1NXDRcihMnTvydlJC9if3UqVOGBqCgNQs0W8YKITHj54JlOz1pXHUs6JK8vb3DEcFmNtDjcLxoXvLzdcFLhnJrKrrsDe3gmznQKKl76oq9Tt/W9g1aF6ehiUsBCsWSX+ehZ6eIt8WVK1d+B1Hg+8AVu0GqF2w1dksfDqZpIzsvfb0y1LnMp3LGDAGcN29eS1fpXBD/cp3sHQfaBFKE+Z2Um2n0yOCckWLT9/Nvxc1of8xErUhDIoR2haEfOjzrPEgTWUgpxQTMl3xPi4M1cdHIwVA2u5kVK1ZU5YH39/ePoeMw+gRElUymTLx8T/3stpeX11HcPqn44eF1xjFQFYDXhpgY7FzZzevutFnXuUBu1PWd46qJFh0Cpb32hlqkZdWqVZV0Cu9JBCoit31c3A0QAkqxzfScsgqcIfDOKNtGYE5qWr13cV6TCCHzIMCtGk0eX63fw2qAFCnRTHQ2BcXoURMXjRwrJaQ8lQZ96mG7ibEUDp5mymnZOUIe1E4SB814HlQmZ3QqWT2ec+fO/YHjMPP+DNw7aQanRYxPAzt/NAD2zh8pHBZJV3XoxjeF/j/2Bs0h6Y2TXzUdLHyzZ8/uYsYc8Pr164a+Re/anwYbJDZOttKO6QfEfc6cOR2yWlLO+acKjJSd2iDtQgiM6NdW24j0g1QW8xOVkZg98iyQxqUhqr6emrhoZJGwUEpIhQ4iNqoYzJIFWySGnTML4fLly2tlRdHPrgoSpQiM6fel0Rs7e3fa1TA54Q2CRwiLkPpMPTdu3Fgip3QcFj+XK2auKToXvHJctdgoYplsLz2CGJvFIb82fiSN4Ofnt8aW6Nw6iMq4Unf0bJSVcvQlS5bURTMGeaTyyd2qcUhV+/v7r4iKijI9L2S1jxKEhcgv7QyIMpOWMtNGwx6JgZwTTWajFRIS8pwWXmviouHARIUuhDSPWqzEnsAtK4PFkt0OkRPC/47aypOugvyYPTYmFdJZeIW4Sx6eBYCIBzs0+tBQCYWehHOCu21O2MqjBSBcbjba4YpjgqgRNrdHoLiGiricQSuQH587Kre4R+0ROM4TqYac8CBBs2Yx4HtEvyQ0IaQOiaBiYrhr16633WEzAJHA1RjfIbODjQ+Vao6miZh7iByjszPjhZSVDR7PJKklzr22ddDERcNElAUhJo3dsruDMEtgIEdqAZ1IUzlHNBos7nPmzLlvRshoFeJBxlyV8jALdlGLFy9umJmuIzk5WdTOO4oJ0tXHQimore6+6Y9JEcUNrqjQskR+wu0RF8Lv6vfOsZjmx2cP4TGRQXvXAoKLUZ+rq+W4T9FBcZ9m9IylpKQY96k7+OsQDTQTtXsmeudQryfSSRA1PjOp8pwYFk+qM0QltQZGExeNDACzVw/lz+ymzE4AzhqEWtUDegEtjdnjRZ1PfprjNTtYpBEW5+YkYFmoL9nKw9Ncj8+WE1UsijMmmLnehNUJX+cWcbFEXPIlceFehrybWRDRRLgq+pUebCRYNG1tYHj2iHTkps0/wnuO00wJuTWigaaEjY/Z96AKDxJHlMUVEWh7JIsNGqk6rdPTxEXjt74Hx82kDVw12MEhrNu9e/ebZidlVPyY0Zkp62WQkuH3c1MnQU4dK3tbx4mDLHoHV/tLQALUdT9IRMXeoFIDbYOzj4FraI/IWUXCpNHyYyUNi+/48ePjzBBI9C2OLLpZBfore/dpdHS0UXGWWwsqhIJ0ilm9G4N07LRp04aYPWbSujSOJDKc0xu69GSL52/u3LltXe1iraGJS54Au2jCpkxC2U37sLhk5+Fmd0EZNV4tZo+f3yVqYKaSgN+hD0xu5o3xLWHHZyK6cJxJ05XHgtAZwaXaXds9d9ZKFmf3xiE9iaiSFIi9gRDSVSLh3ASVdmZs/nnG0MHkRHk/9ynaFnvpV1KIrr5PMwNEmmfJ7JyDTofqHbPpYjY4kBZHtDOZEY/szo38LV5GpPI1edHEpUCDUj50H46SFhbWY8eOoU1JIMVDEzMiBCxAvB4hfTxeqEYys5vPiLyYNddCmEc5ohmtBg8/DdZckfJwZCerCECyiYjLypxooEclExOimWtOZMTZGiG0A0zGZnbNGzZseOyKqE9uguoy0oIIoO0NIovcF46K2bOaRkQ3Yut4qOChsiY3nGeZuxAIm51fIA48+2YF+kRkSMlRqu8I4bD2S0N4TwqUudDHx2cv142vpLUQo1M6zflz9LVpJsvz4gzvGQ1NXPIcqEqgn49ZoRkPDVoU7PYp12PnSwmi1QkSMR+wOkZiOEfJIN4UmDGFhoaaLqcmj0zayKzmhV07E6itfjfpBJ5XclOgS3oGckdqLLMBKSSnnVNEimtqbwLl55gMIhR09jFQEq7IpKk0SU6VAedkusOsizHkhrL5nCiTxWuJ7uu2iIG1e3hunDN6OqH3MTtI9SCKN+ORAmkhLWPGGNE60NhwfxLRWbt2bVlSmpALq0tu+rmR18ePCnE8LR4QZZslYNa0EZ9F+/ho4lKgwI4tKCjIx+yDT5dgcvAsMGgSHDFsQq9CyNXiCXOBnbWZXYZF+X/GbNknURRKpG1NAJZux4uc5eKbFXA+mNjYcWWU3iL6BbHJKS2HRYR53IzokKgWJlnOPgaqNeylJSC9VHTkRBlwTm8gzBoqcs9wrnLq2NasWfPh999/n+F9SrSA+zSn+0exWOOOSzTX7CAVCjk0Y3wJwYBQqGfUVCiE+YZzRM8jolSORp8gMWwG0ApBYMxUczJ/Ui5NilGvZ5q4FAjwYPHgkx4w4xnB7+FbgIA3qw6Tks6zg/ArD52ZhRIhHQTLTA6dygaEvWhYMtJLEOEgVEzuPrevAaWskBeInJokH9Mwj93r7Nmz748bN27JsWPHns+pY2FXyKQLqTOjcyHa5uwUlkWge8aWTsmip/iF6Fp+eh7N9mqypOrCc1KczAZn5cqVlYlSspATtSB1gkkaCy0LdW6cL6zzzUZvLTYIoWYJL1FefHLMEAgIEa8NgciuQJkoEmlQ0l/2IsfWCA/XhYipXtc0ccn3gN2TGjDz4LOoEmVxZoSCHRMPOsdgT1ALsWInblbXAHlh0Udrg9iRsmKiSmgjCMmS384u+XJm5IVFmFw9kyXVRqSwcqNCw6ztPmTTFToXrhupMVJkmQ122OyE89OzyOemzNZMmowFGJ1ETgszOUYiptynzB08XxDN3NBYYD5oqbYzXTBAepMNjVkxLhsHMySetDm/6+xngfNM5aOZCk+OgRS5Futq4pKvwaLIjtle51SrTT6kxRXCOxZtQt6QF3s7G9wpmawcESRyzOxMmWghBey2tAdC5sBEjGiUmcXAVToXomqUqZKOIjrGPQgQKrPbJ1LnatO13FiIaWNgxuYfcoOuITc9U3J77kIvR3TS7CAtTSWc2fsG/RSiWnuRaCItanO03FVtDyxu0pvtEShrysiRKkwNTVzyHFjEqRSwFW3hZ+Rs6SXkymoBJmBaC0BebAlVGTj55rdqEncCEzsTsZkFFMEi6QNXHAeRPTxKINdUYABLOeqr+bGKglQLhNGM5otnsiAvUDgLmyEV6bUnpFLMOvty76GDsVdhSRSXSAtRJ1d+XsS7bNjsNd2kZUhgYOAsHXXRxCU/R1tG2fPsII+Noj4nIhQo/K0CQHtCXSqg8qvduzuAVA2VX/YG+XfuI1d2sCWdSIQN5OdOuRs2bChFhYi9QUqVRdiRthj5CURP1ecPI/pmZnC+2BBB9MxGqIi24IxrL/rLPJRTAnGILdfd1sYOIofmyF36sGniouH08CMPgS1dCaJWnFRzUgCIzgPxr730FVGXnKyoKGiwlK7bVSRaRKIX3K07cF7Ut8ybN6+1Gf8WhJjotnLDLyW3AXlFPG7GJNE60GvR2sPseyA25z1saWcgCDwfZvUyzgB6PET8lFnb+rxhYWFG6wX9XGniku9ACN6eOydCWNI3uREyt2d5TsiUtIH2LnBpWfQlMw7ElOXm5ASeH4GmB8G4Gf8OFuL8Jkw2A2tpMkUCZkkLEUFSOY64+SKIxfTS3vxDpDGnU5akgOjibkvvQkSG0vTcbGWiiYuGS1IyCB9tldkRBmVXlxOunBkdH7tPdg62Hk7CxXqn7xpYd51mqhnI85NO1B1rs1c9YqY/EZozFtX85l9jBojAceC2p4GzDgwmMa50NG1CutqWLwzXCG0gUcncOA98HkTx9jadWqSriUu+Ag63+A3Y2k3v3LmT6o2yuSlUxJ8hs4mc72OV70qPE6I57lIunRvABfXAgQN2FwiaVdKjJjdIbn4Bz5oZEzXKoNlQFDSLd2tpshlPE+vACwk7fEdSahB2NnWIXO1s6pbnVmUiz5mfn9/PtjpgY/vAZkI/W5q45BvA2Cmbs7Wrw5U0Ky6YTKjsBkkd4M9CA7isKNz5GyYqW832EDI6O2ROdQBVMkxMNJtkQabsNDcbMWY2wbpa40AbBzNmaJBIdranT5/+s36+slbFRSWImegWUUiikQXp/BDJ45lkM2V2oBUiYuioQaGltcEuWyk7fKDU3FM8KzomSt7xaEL8y1feLyuRyp9++qmirRYEFDBQQq03E5q45BtQ2myrYoRdDQ+9o/oRoh8s9Ahn1SJmpBB4yEnpIKR19AFlsqKqyVaeOTg4eICzKk0IReNGyusSZrZ2caUkkugPu+Kc6Atja6dFqwQIHYJYgOEUk6Ardn8QUJw7zbiG4vNDiap+vrJcJXPFjAkkurTc0J3lpmgZPR6pEbPuuFQb4byclaICNlq2UnbMB7RkcNRojig33kNBQUFJhw4dMuZGvlLtRFTIUT0KZd0cZ2bnxLKZiC+IKUVNXPIpiCDYql4gxOpoDxoeJCZf0gYZVZ6gwGcCcuQ18etYuHDhQ1sEC48PZwh02QnhUEkYOLMJizLD3OoHws4MUR5EjvNpNWQj30+KAWMtZ9vfQ5To5WQmEsD9pHUuWQO29XiS2DvH3IMsVma9SPID+Kx0TzbTEsS6YHMuHZ1r0r8f0cPMiAupOjYOjrS5IKLG85mRZo/3gcDQLNORCKoZMTekCO2UfsY0cSkQxIWqBTwlHBHT4mLJLsKWDgIDMQiCIymtOXPm3M8J4oKQzZ5vA+WRlIdjBpXToXJ8VTKLPjH5Edmi5NOZmhyiS1jQ27Letw6a7CliNdHZfYsKSgTUrM0/5Jrde0E4L6SLiajaEuk/O3hGmIuy6qpsj7iwsbF07/53R+YWNec+tJWah2Q40meITQW9umx52RAl1sRFE5d8ky8mNGnLBwHtCCkJs6/JTp98qj1jJMKkjjRiI3WjJq5MX5SSQBZLZ2g9WPTZ+dgbiN7Qv5jpLOsssLvC6MqWmJrUFrtxZzdZQ+dixs+FqAyN9gqaaNQZ+hbLQmj33iP9qnbmHgXFAoCoCVo8sykiziHELjuVhjw/kIjMiAv3OZFPs+lpUl0LFixobmtTx6C1hSObRZx9EWlnFOG2DooXClJ0ThOXfAwWFh48W+ZKCDJpB2D2NS29NG7Ym2BwxEWP4Ui+me7OmS3YlijOzuzuQK0RDTO7XgYEJyf7xHAe2AXaOy4iI84+LhYBexVoOuKSvfPr7e19zoxfDsZjWU2B5DUgkseLxIyvTfqoRXb7ZjE/4UuU2ftAQIjomH3GiBohvLZHTHndOXPmdDD7umzWiDbbqrLSJdGauOQbkEpAJKYWe5tCS0cEgBYl/kF7Ik4Edijpzb4uPglEaTLb/SCaZZfvDGEqCwLN+8zm0dHebNy4sUROlEuzC8Q3wt5xWfqxhDmzQy0RAZyM7ZWharfOrAEdl5nKLRZmX1/fyKxU+uU1MJ+w2DvijkuKiPsvu0J95iciFbaivBQumBXpczxEyew5gWM7sGrVqkqOpNHsVV0y37rSLkJDE5c8rXGB/SuC4WPLzdFqDe/Ionro0KGX7GlceF9nhM4tFTRXzFTQMEiLqYUkwpHUV3Z2n7yXmYZypPmYAJ0pkuUzUh6fWVTA2pWWtJJ+vhyrmCHSZ0ZDRHQR7w5SBPn5nBCxQ1flSOkzGxj0Hs7oXWbtjG5H4zLHEYJE6TQaNFufwdEoN/cBTRdtNULVGhdNXDRxMVEZAcPP7IHHc2DZsmW1HYlQ2BPnYhKF7bYziAuLCN4IZqMuVuJk6dj6P668XkQ9WLTMhM0xpSLE7mxHYUqduRbPkheuN1Vo7Cpzy5Arr4ISWK6rrV1z+lQCWon8XrVFxAPiYFbXwsJNawpnaTnMinMdmXNIZaMBzEyPgm7GUZdyqzhXExdNXAoM1C6v3rlz5+zmWx2ZJAmdQnZI7aB3YIEDPOjkWpl0HRVuIhBev359pkSCdBdlhs7ycbG6c0ZERJje7UHI2DW72t+FXZutc5F+qPP22NmuxxA7doT49JAmQ0yIpwj6DN5Lk5asRbLw2jATSaM/T26V4ucUiJiwgJt9/jhvzC1btmwp6qxjCA0N/auta2JpNXLcUd8VdGpUVeKfxWswN/JV3QOGUZyj5o2WJrmXEeVndm4ggNoUUhOXfKXWt9WozJLWOedo6JVoCg8+FTrkgREBE91hF+WoaJP0E9oKSJAtkSykwdlpEUzobO1k0g8mIESBpLVcec2I6uDoacvmO311BQTMFRU+RH+YNMmdMxk72zumIAGiD8k0o29hkXJ1ZC83wX1F01RbxpjPDjZflhS10+5B0rKY19lKGUOWstJUlOtH5JLoJEJ2vjIXZ6W4gI0MWkRbczii+vx8z2jiUsDAwoPQz9ZOD/fb7HT8haiArFa4WI/RVsgYbwRSVM6OLLCDI6pgZifMoEQaAylXVhlBCiGBhw8fNrUTpYzcESG0Rs7CKtrk3rE30I6xQOema7OrQTEAz7PZZ45ILpEPZ6dCLO0Xgm1VXZIiJtKb1evB3zE3ZvXvrQ1Q0fZkNtjwUXXkrGi0hiYublESjcAsM5dYV6RhHAUdWklH2Ip0YL3tCjM48tc0GEToamZYhJNrstKTyREQ5SCMbSb/z2Jn6X+jUzhuCEujvJW2fDjSa86oYMvPGylIiNkoJ+QGF2tHxKyObFzQ4tnaIFgrvHLaiNIK+qbRJdsWyXPUi0tDE5cs78BY+FhocsIfBF0CE6KtyQFxV27s2qk8Isxpy+ab3YYrF2YWFl7fVtl4+rw3glhXO5pyf7DztldamT7qQkm5nlzcD9zjVNnZq2LjOlIK72xjQXdKEdGN2VaxQEa6MqKPrtpU8czYKolmUAlG9VNOR8H4zLTWwIzQDrGKIO2VE8fDNcypdUsTFzcBZbg42apJbD8RBBTyLJgYIbmy+69FPW9TGMgCiYLeUSFadsBn5nzYc7GlXJKojCuPBWEb18WWzsaqKaGnj6u7NQNKjtltmgmpUyGV3wWdeRXs1im/t2c8ZzFZzJddfolsUrqPsZ7ZFBFpGpyrXblJsETDfrYVAYJwEvXIaUKJ7w8bSltRV2u1pStJFaSIIg+cijEfRRfIHEia3dWRZ01cchmE/hHB0o2YCczaOI/+E4hnYdZZ7blh5uFEwGmrgR7HgtttToapEbnaK4fkXOVUqJaJAvGtrePBPIp+Mzm1QyXqYs8QzrozpcRbEwX3g6UjtN2IC8Z+isi3zo+7WVxu1WIXb9Y7iQoaSpVdLYS3pqppXmprYJCHyDanSCUWB6SkbWlbrOJhV25YrBs6omRck/TrFoJhtFsFibwUuBw3kRXYcWakgaZ/rmxhDzuGmNh6CPAOUTuL23iquPqcUKVCrtuWMM5V1US2doUs/lyLjMgLxI8+QixEOUnubPnbWAcVK84sFdVwHqjGYhGyVyVGyXl+1CpkxXoAOwA2CDnRVsLSLX6vPd0N5IYIsat7dLFhwfEczyRbw9KIc6erIlIQEqpF7a1bBaU1RYEjLvaMjqwCWXbXrkpBYK1NSNReHw00HKSViD64ksVDAGxFgKzHQpQqJ/K36cnLrl273ub4iIQpgmXkuGk+yI4rp70SKP9EXG3LqdiqcdGW3+4JwvhEUriXbFWGIODNbyWtVrNHs75E1hQRG72cLL9Xz3o5e+XqPGf8TlZ8qhwhC/RHIoJqhty5MoWOXQQRaFvHABklVVVQNC8FauKi1JiQnq0bAEdNDL9cqTEhomPvONKTFxZwZ9+QeL8gbrUXArVWWORUWiYjwkBUiBJsKhqIsuSEriWzNKPascZmFmYnjEs5pK4qcl9w3+MZkhFZJxLD9XVF5UxuA/Ern81MY0kGIn10FDm9QbCk8+xWO1nJC5EXZ6dIiJyoDcgA0tH2BusFUSJnu2anBykoNEm2joPzxbrlKpmDJi65CMS39m4AS9hvsyuFaOxg8ASw5aSb/oaEbSOoc0Zel0WVkCLmWmZICztQwqA5mZZx5x07KQQWALxASOlBLomeMYkSkXFms0WzO+n87DXiCoSEhDxH6B3BJfoAetpQ0UIaBQ2IMzcJVIAQvSHaC/h3TtsdUMrLJsWWFcOzFTL08cmNlCfnHpNAM/4y/Jy0ERFyPqMz3h+PGoojzJAWSCCifVenaNjokr60Jy9gni4oOpcCJ8y11fmYQSqASc3V+VMWOG40Mz1TmEh4kMjPUyqd1e7IPNw85KRebJU9p39fRLvZbVufn8C55zwSGsZ1lPNJiSaVRzlZhYLDMuX1OB1T8YH/DzuzgrLjyi6I2pH6hMRQpQIxd3akjPvE4madAEECPE/cM1Q25sTnZCEjemArPZaRwJyuzzmha8lsc4W2xOwxk96nISnPQ1YXbjaTbA7Hjx8fZ6+i0TrwvCIS7Yy+bbbAnE8K2taxsAllLigom5gCNVlZGqyttKUvYffl7J4zmYGQNJOa2fAtu3vKbVmoiB4RFbK3O2Qx5X1IYSAuNUOU0uduaSWgd/QZA6FybuSUuZ6U9TJhc+9AMElfYd2elR4sGi5LSYUTwc1IXK5+FuasKIEtEA1QxNpRd9xdOalns1HN87MtTdmz0ReqwbC2gIBQ/WiPUEDMuAYUHWCLQRTV7Hmiugn9z82bN11uWwGpop+UrbkbUlyQzO8K3ISCVoKKHapo0t+klJihHmeHlBM3ozUsShgQ8gIpMTuIlrAbIYUEEWO3ze6fXRImUVjhYzBFyBPfA6I1Zh0yrZEWNDiQltzadWlkHspGKJ1ZZQxkBmKr+6XkrsEb80hmVSAMzMwQf7oybWQR34dmRJ4ye+7pNo+mzh3OI1EwSyd4h+YuzjuVm2hl2LAxF9LAlrmRr0SgiE5AHmmzAjkyS1gYNMTlGctJckfUBc0R0aD0x8rGhfmdLIGrzTg1ccllnQJCNcK1sGwcMqk0Im2D6j4njd+sOXCagEFCzHorpN9l8DeQEkyzeACpBGCi4nuQIUceSOuDv3Tp0kfY7+eWCFYjc3CP2mrLwPUmH55TUUONjI3umFts+RBZnZ9dNd/wupiT2SJPzw4sDxC7utNmBaJOFNGMc3VGGhR8TpgLibJTecOGFdKPJsRspDv9QJeIFio3NH9opCBdRPKQPLDhVf8+SLrK0ea8mrjkYQdJIivh4eG/46KzS8oJj5LMdBOkfuy5M+bEIOQIaXG1xkcja/fsjBkzetvbgbJYQcx1s7fcAf5LiDbtbTqoGKRizhX3CdFXe07Y6Qf3VE47dpsFeiDcYu3ZNrh6QJ4gLbmZRuOZJnVEKo11C01PQbT91xNNNtI8eLIg7CP9hPCXGyk7Qq09e/a8QfTHkbSOswapMtJDkBZXi81cdT3YnSGUJbyMyyRVPqtXr67gylLFnASTFJ/JpO9OmDN3YUQqEU1CaF0xUaZ//dzaQDgL+G6wG7YXDSAq44oqNCLKuOOa3QQRfSD9mFsNDM0AskBa3JH+Ss4aVv0MEayCFtnQxCUfgYWQ/DSTEwp8RJH79+83SuMQlKFbyUqFAhM2BMjX1/eXkJAQh9M8WR3oIpi48LnJi5oWjnnlypWVUd6TA7YKVtECoSUgz58fTOGICpLLNlPGTu7eGRbkhMTRBhCup4Qey3xFroN5bWdU4dClmP4reFAgOOY+xGCQCGRe9cMhigtxtJX6JV3BZ8anyJnvTRTZbKPS9KlFquTcnTBCGtCo4BLraFo9q4NUE/M692hB0pBo4pLPQJUOYlhasGdELJiQWDT4nayGFPk7eiaRxzRbmpeVwbEyCSAkdEXIOqdg3WFmNpmROmG3lNc9DiBo5LjNLEponRAlZmcxsrSDOMhuExIIGQRoqLjHWUSyQy7I2SOgRDeQ/vWpnmAxpSQ2L5IXwvlE/mx5gWzevJnPWMkVxQdUD5rd9BDBgAznVEFCdsH9gL8MJoJs7lyVWmfzQ6oN527EyrpIQROXPA2znYIRguEtQDliVsqJ+RtCtxAYlP72+qs4MlgkWBggLIS18/JDSdqC3RDtAGztKonG8Fnz8r0HCVm2bFltSLOZawzpyKq3DCkbIh+Z9bXhnGISRmQkqwsQOhxbokvMIvNq/xV0CBBHIrLpF1cWREzT0Co5O9rCswCZpFTXzIDo+/r6RuTF8nm0OIr8FScC6EgZs9m0EISaqGJ+7BCuiUsBBJoJM/0rrJMUZm+UKmc1l41wF08Idp+UwzHpoXFwRBHPw0jVEQseGhpKBCmvy4taFsnASIweHfaqJxAdu7J7a04BM0BcXs1M1AsXLnzIdc7K+3DP2euPQsqKtFFWhNxWHYitz8HrEw3Iq8Qackb6lQ0C6UoAWeN7rhC/8yyQJjLjkGt1x6WiMS9rikjfUEGH9wzVkBBhR9JI3H9owiB7nA/0cfih5JUIlCYuGqZ2NISACVE68mCwIyB/j/Ylq5MwBAYxMOZjaA4wJMLlkV0vDyy+BYSf1Q7Y2KnyPUsaKJGHGuJDyJM0VH4Ke7IAsDDY63iLsSCTdF7/vJZeLmfMOB+TqqB8Oivvw27WXrM7Fj810cc46gLLQokI3F7ViyVqFJYdcTX3OqlEIlVEQIh08NnQoeTUNWODQAQGuHKzAFGiMsiMySSaPHcrfc4OiF6ReqRJI2SXSBLEnXkQYNyJjQBfrd8jpYZhHRsfyA/ifu08rYlLvgR5aR76rKZn0Chk1xyMiZ8FmwmdRQP3Rx46tRC8BLFht8z3+BlEJT+XzFk6/rYkvGtrqN95wAKW1z8vCw0RPDOmXETmiIg46sfDOWWBN+MBwnl1NKqDBgQSYcYVlW7gWW05wa4ZET3kns9C1JFoBBsPNhJE4PJ6BdOzmxvMJ+1poPAyQWydXytkIIds8qxzIyDCR5k6X63fQxjOPeIMZ3DOJdob7jeIEF3I0RsVlN5Bmri4OQjzYqGd1RwqkybaAa1QzzlBIvogok75JfzLgkuEzYyGgSodRyMWkCOiWCxw9gbPAoTZ0YXF0kXb7usTNeT6ZmURt/SQyvB1SQ/goJ3XdU/PgqiirUay3BP4x+THDti5BQgRzxmbJ6vxJwJ2nNipMs2J1g6auGjYBEweu2d7qQlbA40M6Z6sNkvU+G2YmCgEE8WzVQZ4VOCOnFdFnplV+1BFZUbnQkTE0UUK4oIWwwyxQHPlqEsvBJIdP9fGDHFR1/XVrJBZeyJ6rNtJoean55ANEXb2iNWf/exEnCAtPAsF0bTMFaCAQpGWkMzaKlirtrTIVxOXXAdpGcrkzPhp2Mjdn8svxmjuACYGi0hvPxVE5LcRIuN0ycKdn1xk0UogIjRjVLhr1y5Klys7khKxVmrhT2RvkJag9N+R8wvxYgG1R7wgoei4HC3VJ6JDKoqScFuDhZwdcX7TNbC5wgaeOYZIJFExiC6RXgwzNWlxHvC/sdWCg3sYW4usiuQ1NHFx+q6XyMuz5Y5mBbtUhjCJ6HPpXJBTRsBKeJa8c37st0SEgEiBmbJXfIDwsHG09Jayf5yU7b0+OhXSSo6IThFRIhq399qYf2H17uhuletOKbg9AbO1X1B+TNtCVCG4RAQod+acaC8S5+vrZs6c6WFPb7Z+/frHCML1OdPExW12+ajY2c2YUfI/qw1gccjv54iduN7hOR9UiJnRudDKwdfXN9LRPDtCZspDzRAXUhOOEJeQkJDn2IXae220Sdi8O2pCx3OFqNekBihM27hrZFUoj1bLnsicqGdWq/s0NHFx2c6GKh6iLydOnDAdcZkwYcI9Uk758Zyg1k9nE3+B3S9GennR6Cqv61z4OQaGjlbm0CLBlcTFTMSFVA5l/454nkCUFyxY0NyMZYElorPZ2UZwGgVn7udeQytlazir/YaGJi4u0R2QV2ZCtleNwYSsJsyd7tiJNbugwoSeNpSfWlNoLJ60lefcbNy4sYQzyg/zYnSOBRthJGWTVCLgJZJVYSgpMfQ7ZiJ9+Lngm+KKiAupKLQTjqQhqORBMO0K4sJ5QQxpptQaDQylq1nVP6GNgUDiHsw1RUQMaddduQsOeJ5tRT6J6uF1xOZWny9NXNw258mEz4KCYCsjd1tuZMLYTHT57fPjT8MONjPihqaANggs4AXlniBNhjgYrQYTHJEAtdgJ94e6T2IRwWal4oDXXbhwYWN7/jXWqAjkwpGoCOSCqhx7r001BdfckVJzLAUwALP32pAy9DmO6JTwLcKh1oxBH2ZkWX0OuYd5zkn54kjNNUXvhhsw+qPsejVp5J0qLrySMnoO2bBh4shzmh+1dpq45MPoC0yc/DzVLTSRoywOZ1tK59ih5Qe7fcmgBNWeoBNfDUd3/3m9Ao10WUaRESJSCPc4H1nRAbHDx1zN3gLN+yhycdMRt1iigaT40MjYS0WxWJslo3xOwutmCBckD8dbR1NctCqwl0Kz6FsuZMVBl79R53NvRuXivC+kFA8Zre0qGLB2rabgAgKLaB5XaDZptIjRqUhNXPKcMJVJjlI4UgM4OeZnJ0WEyrY64jJof4C7Z0EJp1OKbKu3lTWUnBUjNO4togtmerMQPXGkio3oIV4uZlJRjmhorJUYZiqiiIioc/eGI+fErLN1VqJQVkEmxMvWfW4hRZez2p9MI29GVilD5xlDHE7lHBtYfW40cdFwc6xYsaKqPYEyTdDQFRSE0kwWRTxO7PmJYOKWlaoDws8IY834CaFXccThlomY62SmYR/ExaxPhSPEhQaljpjPoTkxo/shAgWRI2Xl6DlnQYJo2mtySiRMu9PmzXS/jpRp4qJRgIByni7MtiZ0iA1h9PzUI8beQmpv8UfvkZVF1BrlsmWAlT6d40hJtCPExZF+QiwM9HMx02uJiIsjxAVhLM317KWJcOwl1ZOVFhBmzjcDbYP27sg7wnnS97hvo6ki0si1y4/FE5q4aGg8A0LjdFvNTBdhNd5ztLdNXk4V4uBqqz0E54pceFZLxTmX9jxLEEWjrXLEaM0scXHUJ8ZKXOxFXLhX0Ko44pqryEIJdGT2hjXqlxWdGcSFCJm9QasC0sP58Z4mrak+X10WeJpx0vU+r3rhYNCHezICa54TImkIuylxxnlYO95q4qJRAHwNKHemP86zVR2E59mF4ufiSHlrXs97I9pDmJ3ZQCuBZiKrmh+LS+x+PEls7f7R2jh6LSEY9jpEc/x05zZ7/JR/83kRMdoT5vL+jpwXds0QBlsRF4gWHkpZ7Tht6U1znFJtW6QLgz3SSvnpfqZSCsM1oqoQWrQ8LPbo1mhYSYPHvBRJJdJCRVBm3bRpqQF5QZuo53dNXDTyMdCu4OrKLoYFAhLDJI5vDaSmoCnsSZ+hd8hoMbV0Cg/KTuksOheiOplFMKhuYLHJiq09FTqkXjJbpLN6/AgY1YJwJbPXhdQEBATMcfR1cdiFFLGwZtSGA9KC1oeoSXbE4WhXiDLZOi9EI/KTEN9KODMTJbNRoa9UXmpjQkTMXrSSCB73i57bNXHRKABA30ETSVII9A7Kz9VUtoCOAoEuZc+kjKhmYYfKhEk0hkqE7L4HBIOoC9U0vD6mcJbqrVQiXFklRuyemdwpi6YyylnHz+sSgsfbhrQL4mWOGd0LvijBwcED8GPJyjFDjCkvhzRjQ8Dxctx0S4YsoV3IrqcGkbRnj5/3gTxm9/jdFXwedf7CbYmS+fykjvJKt21Klekob2uQMkJMnh/tKzRx0dDQsLmYstARSsfwjJQGhM6ZJeEICSEZz76HM1yKeW20NM4+fkL1GDaikeB1iU6hacluxRkLJ0JdBM+8LsdNiaqzTeFcdfzuCD6nveiERfS8NS9sUiCftCWxl7IkjUQT0YKS3tbERUNDQ0MjXwASaK+pJ5oXfIWcEUXMCWzYsKGUIuE2icvp06eFyGJBbFOiiYuGhoaGRp4FkSRK6m0t8rR/oPw/r9jbUx0VGBh4NyM9lHXQIDE/tmfRxEVDQ0NDI99rtehJZat6Db0IJpR5qZCAijh8eTISz1MNCBHLKxEkTVw0NDQ0NDTSAS0PVYIZCXQRJ0Ns8lpzSWz5ly9fXgsvJQgMPbQQuSPutvgN/U5fe01cHK5MQRSGBwU3F3lWfSNpaGho5DzQeWB1gJkh1VREJBC3Itqlci6v9maiyg0CgwkkAndSSNgH5JXqKGcAKwFK2desWfMh5oKYOeJf467nwC1PItUKKPTVA3IG9hsbGysYHlGaNmXKlGQs43UDKw0NDY2cB9VUoaGhf6UBJgs9pdIFpWlqfgREzc/Pbw1klL5n9PqixJ9WJDhMY2ehiYsJUDqKEyPldc8OhFT0MMGrQTfD0tDQ0NDQyBogJd7e3rsya0tCbznIi7sZh7rdiUSRjuEPZWiZDUvvlbC82h9DQ0NDQ0Mjt7F27dqytATJbK0lUEDPMCQbmrjYEUtZSuoyJS5ZacCmoaGhoaGhkQYyFvPmzWttq5caY9WqVY+3b99eSBMXG7A0jdtFgytbg54j+bH7qoaGhoaGRk6UgyOqttW9nkG1lbv1a3LLiIu/v/9ydVJtRlwmT56ciEBM34AaGhoaGhqOgYohepnRe8zWUKTlMaXwmrjYAM2sMAWiw2pmA9Eujd+y0vFWQ0NDQyPvlWLrRofOB67AEJPM1lo8e+j6ffLkyb9p4mIHirQ85+PjczOzqqIVK1Y8zkroipI96tXxh9HlexoaGhruC+ZqmmPSbVttVI8rnAsMDAymwzdOvvoc/brZp7EljSDxpHHkbzEM9PPzW3njxo0MicuBAwfw6enibk0m3VY0pE7YK76+vhuoJSf6gqMh6mcIzapVqyo50oEU07ply5bVxtlR3fyXLdhF9RI17LqBloaGhoZ7gE0lhIX5esOGDY/x8GLDCtjM4u3FYksH8IJ8njDMowGkl5fXEdZFiN1ENfDXcaRDOa/D3+GKfOzYMaOxJOeY3lS8vjtW77r1haF2HB0LZnTk2CjJunz58u8c8W85d+7cHxQB+gWHxwcPHhj6GEAIDLMdLta0adOGKGL0F+0Lo6GhoZF7UDv//4fBqFow79sq0GA+nzFjRu+Cmj6iMAWyglEcaxlrGsSORpcUrtAzypGsAtEtCAzu9Fu3bi2yb9++V/F4cdfMRL5n7uhlDh8+bFN8BIHBtpqQpCYwGhoaGjkPot9qMd6J6VlGTQ+f1V6oDWmEO7q6uhqkd4hGEYnKaLBBDwgIiOd85tdzkK8vMF09yY3ev39fzAwqmWD606dP74dHjNbBaGhoaLgWmI6yyx83blys2jSK2cFcjct6QTtfe/fufX3RokUPbZ0b5BXIIzRxyYMgeoIi2h57f3ZERUUZfRr8/f1XHD58+MWC1GxLbNT8QwTJK5OuY7LRk66GhkZ2QCp/8uTJ/rRxIVLgyFi4cOHDgujltXr16go7d+60u4ZNmTLFK79mD/L1BUYfExgYeNdR4mId5AunTp2aTF8kcoAFdTekHpJ3/Pz8fkashSYoKCgoCXEzlV15rY29hoaGe+DYsWPPe3l5hV6/ft3huRk9B5vSM2fO/KmgnTeKU/bs2WNX/gAhzK+b7nx9gYkM0GGafGhWB3/LYu1ulsc5AUrr6GWB2OvZ0nTSb4oYChMPFQA6KqWhoWEWpOLV3HyBTsRZGZGRkaI2pbMK4oaSjeT333//yNb5OXfuHBGpxjpVlEfr21Genz9/XrIz0L7g5ov/S0F6QCzELyQjPx3rSE1NlSVLljxSqFdQo1IaGhqOFU1gRZHVeZkmu2o+jjl+/Pg/CuL5u3Tp0u/RbnIeMhpkGIKDg1Pys/4n319kHP+ICmRmsGM26oL3Cwt5QXpA8NKBlNg7Pzwo5FwxhyI956gJkoaGRsGqimFDZLZo4tkUiK+vbyQC1bz6+YlO441CqoxoNYarlIE78hpkAGg0jJwhvRSCc7pu3brHNE/MzzrEApHuICypLnIgjruZlZDZy6eieD979uwfC9IEQ5po165dDoVvyTv/9NNPFfHg0ZO0hoZGRkUT/v7+tx3RHrJ5pNmfmoeXEGnJq6JTNr+QCiJGCJL5TKR9FJELx3vl1q1bpuZNolYIkzGOg8ihO1Qbx3gfH5+tzNtmX0cTFzcHaQxueOyLEdwq1utoxOVSQROiYvqHW7Gj0an169c/5jzTMFNP1BoaGulBZSLmaWwIzQzS0fiSUDKdlxdk3N6p9KFU+VnSxrlgkwipccSGAzkE0Rrc4VmfCoqcocA9NDB1IieYzZEGMUNgcCdUxDaooJUAkyNFmJyV9BqVAuRheQ3dUkFDQ8MKmuOquWF/ZhqN9OPatWvMI2HYUuT1z81nQHuSWaQJ8kLlZn42jtPExQllvuQYp06dOpybKSIiIkO3RmynSRMVRL8AmDxl0OpcZUkbxLnDJAp1u26KpqGhYdV4qE1j3X379mU6dyQlJRk+LRYRb77oSUQKnaaFtgZRF3xa9H2iiYtdAgPDpfoIzxdyjoTysJ1etWrVY8X2D9K/oaBGDRCPQdzM7I4y20XgOUBVFsJd/dBpaGggTsVnhPmWucXaQ44KRoT+aDUQ4DrSLNDdyRrp86tXr9qcL2kmPHfu3LY6Sq2Jiylwo+AMi3CMkB7A1bGgi0xJrTGBIADLirDZOlC/IyBbs2bNh/llMtLQ0Mg60GPQzI8WK/Qoov8Oizvfy4/zLhb8NIe0Neirt3z58lr6/tDERcNJgjp2SFu2bJGsGvoRfUFJz+RU0ErLNTQ0bItM83tvOMTFlCrbmiOpfN2xY8e7+p7QxEXDSWAXhM3/hAkT7jnSDC39IBx8+vRpw3GXFJxuZKmhoVEQcPHixf9V897RzApCYmJi8Kj5BfGyPl+auLjtDoPybMKH06ZNG2Kpcqrn7mFSUmqHDh16iV5FhD2z2geKvDatBFauXFlZp440NDTcFXiBXbhw4f82btxY4ttvv+0UFBTkgyZy06ZNJShDduS1mN9pdYCWhTmQxpJsAhHtki7DMFWfc01c3BL4m8ycObMnYUGcIBGkATQkCFnVDbyXfhTu7FmAHgiiBfnITupIEbdHRHHyaxdTDQ2NvAvs9efNm9dy8uTJiYqkGJWSEA6+0rIAP5pdu3a97chrkiYnbUTKnPQ7r6/m/Td05aUmLm4tAibKgpo+s4HhEiIt3BUxJEIk7I42+qR5yMfy8FJOntXIC66RfEZ9f2hoaLhLWmfRokUNMb7DkyqzyDIbTua/rFZM6ua0mrjkCRBypGO1mfJiHhZ6LGFKtGDBgub8rTtGJmgtT0sFXHbNumGmH0RdiDDp+yP34f9Nnz9O6jviTwvGTXl/5ezvyk7sNazwJM9B/1oyaeY7c7wnfvKtV+BnwUO93/Xt1PN/Zw7z1bl4jXxHWPCdwhqDuddMKvzYsWMCydFRY01c8i0os6blgCPaEH6XMCUEhvwqGhN3E7VS2kjKx9r4y5GBb4M2Xco5zBzp97tAz0HvTxkwupEiKm3Hdek7yruDp//Aui3X9KnZ+FSfGo1CelSqc7vbx5+nelT84k63Tz6/0rVCzUiPirUfKUiPynVi+n3e9NjAOi0PDm/WYe2olp3njOvca+hc74m1Z4zwK6TPsUZeAlGP06dP/5noNp5VpIAc2YBFRUUZDWZv3779H/p8auKSL0EuE0fIrFbkoINBV0IExt00MEwAuBH7+fmtCQ0NNf25Nm/eTJl0WX1/OB+B3Qf+vzmjxhf1bt+j7YjmHecPbvDV9j41G93sWLqytC5UVlq/V1aavlZcGv3rfWn2enH56v2PpH2JitKmSHkDnUp/Joq0yDcfVZMOpSpJO8vPWr1bRv1+CWnyShFp9FJhafH2B/J14XLyTbnqosjP4TGtu8yb1Hto82+9Jrypr4OGuwJxLYQFjylau2Sl2IA52d/ffwW9iPQ51cQlX4IW5oQhs1qNYyUwhw4dEsRdVCe522dEZIal99KlSx+Z2bksXrz4IYRO3x/OwaxR497w7uD59cgWnb7vXb1hOGSiTdEKimQUlaavFpOvCn0knp/VkSEN24hPh54ysddQmT0mUOb7Bcm65T/Lvh37ZduaLbLl542yb/sBOX4kVI4ePil7t+2THRt2yKaV6+XnhSvkhxkLZZ7vZAke6iNjvu4mPavUk85lqygyVEYav1zYeE+PT7940LtGoz3Dm7YP/nbshArz/adoAaINeH5W938UKiq0VvBSmKgwVWG6wgSFEZaflVHQC2UWgUBWzTsNiWLT1T47A8JD80R3nIs1cdFwCujgiUNkfHx8th4WCAF+KhAhd/ycpLLoLo3jLuK2zAZ9kCgDxAJc3x9Zx6KAaW/5duzZb1C9Vtu6lKvxuHWhD6XJy0WMCErnD6vKkAZfy8LxU2Xl3KWKkGySsNOX5FrkHYlOuC9xD0QS1YskSdrXBMtXgOPEXcWx71q+b/0Zv5ts+crv3IpPljNnL8uJY6dk9cIfJNBzsPT7vKlBXlq8VUpavVPGiOT0qdHoat/aTYMH1W3VZPGEYN0CIo2s/KdCPYVZClc8K30pPRTZ7F66kniUqigeJT8Rj+KKBJb82Ph/93LVhN/xrFLvkoXMfJzJ6/5O4S2FfykU+DQGEWGKANCjkBKigWN2NpDpI8b0IdL3siYu+Rrbt28vhM7l/v372XpgqEzasGFDKXf9nFRCnTp16q80spw9e/Z9djYQLiYL/AvIJeNpQD8kfV84jvn+Qf8zpo1Hk/61m67tVLbKg6avFZNGL70v7Ut+KkMatZHFE2bI9l+2yeH9x+XqzdsGyUixEI+4hyIxSQ8l8m6K3IpLkpu37xm4EXPXIfA3EbEJEnUvVe48SCM2vA9E58KlG7Jn2z5ZOec7I7LTpXwNI73U8u3SRmSmd/WGt9T3R45q3aVYTpwvj9k7/k2hvUIDhf8U94iuDFUE5FyPirUNUtKt6EfSvUwl6VmrifRp2VX6fu0p/Tr0kf7dh0m/Tv2kb5ue0qt2c/U7laVb4bLGV/UaYJNCecvrPqcQ4Fm5ztUen36RqnBXEZ3T6nsrFD4vaM8Jolk0LHiwBAYGxivyIlkpIsho0HuI1Dhl03pO0sQlX4NoBKkRtWhfQtiV1cEDOGfOnA7urmbHYI4eUD/88EO1gICARUScqEKCdGnrf8cxdcCoP/t27OnXs2r9q+hK0Jh0UTt0/y595fvp8+XArkNy607ik6gIERFIyo0sEJOsAjITm5pGYtQXuZ3yWEJDz8ny4Pkyrmt/6VqhlqGpaflOaUMXM+CL5lumD/Gq5WLi0kpBLCiWy6Slo2eV+gZhMcjKh1UMojJ47DQZMW+NjFl/TLz3Xxbvg1fF5/B18T1+S3yO3BCfQ9dk7JZQGblgnQwaMVF6N2gj3Yp8KB4ffJpGYKrUW+pZtf7F7h9VFY9i5YWvPcpXT4vWlKggvJ963x3qd8sVlAg3PinBwcEpeGY5I8LCYNOJDxd9lqhE0vOSJi4FShiGyFYx9hhIiKMPFW6Lq1atqpTXdj8QN3f0pXF3BA8a+6ZX2+6BXT+udbPJq0Wl+Rslpf8XzWSu9yQJCTljRDxSLREVUkAQlevR8TlGVjKFOobIu8kGgYJIkZo6GXJaFk+cqY6/ubQt9rEhEG5XvCL/P+zbqXeX4CFef3YCUfmHQhOF7xVmKJxMR1wCFF7PJdLipwiGQSa6K8LR75uBMnLJFkVQronf6TjxDb2tCMpV8d5zUbx2X5Cxu87LyO1nZOi2MzJ8x1kZvOuiDDocIcNOxsronedk6LTl0rtpJ4PAkF6CCPWs0ViGeM+QUUs2y8jFG2RY8HLp7zH0SfrJs2o9iE71/Pqs4Je1ZcuWov7+/rfRoDhr4NuyevXqx1QRkabXXZw1cSmQYCEnzKjYe1Vvb+/LJ06cMNIoZgaiViyk9XnM5/qVCdP/MKplpwFdytVIQGCLfmXMV11kww9r5HpUrJH+MXQmcUm5T1LMRGPuJD5JKfH/XZt3y6Tew4wKpsYvFTaqk9SiGjmh55DO2SQuHdMRlcxQMQcJy+89q9bf1ePT2tL1vQ+kd5MOMmr5NvE9FWuQFW9FUry2nxbvHWdkxNYwGbDxpPRZH6K+hsoY9f3AvefFb9dZmX7oksw5clmm7b8gw3ddkGGhd6TvrnDp3NdPOparKb2/9pSxm0PE/0Ki+IZEi+/xSPE7E2/8e/TKPdK7UXvpVqi0Ii/1JTN9TF4GmyKcaam+dFZKiMoh/KaIGKsN4yu69FkTF410BAYvFMSqK1eufJxZMy4GYU8/P7+VN27c0FUa+RgjWnbq0rdm4+vN3yxpiFy9O3iqhX6XxKY8NKIrpGNY/N0isuIAOF70MTHJDw3iBZGhemnGcF98Yozqp7ZFK0ivavUPj2jRuWkWicvvFQYqHLdBXOrkEGn5gyIKIT0q1BCPEh/LwN5jjTSQ39l74rXrnEFYfHaelWFbTknPdSdkrCIvMxRB2XopSk5H35WoxBRJUWtwwoOno7JX45MlLDJOdkcmyppbyTJ++ykZuueSDNh7RYZuChUv9ToQIV6f9/E7d89IQfVt7WEch2eV+iH57ZmhHYmaQ7dmtRFs+sEcDAHCmv/gwYMv65JnTVw0MkFMTMx/YCGNqJWSYiqQrKJWcqt4pEBu0I04+tqxsbH/TooKF158YLTbo9v6r9QcUKfFATQgjV8uIkMbt5XNq34xIisQFsSweY2s2CIx1igMJObi5QiDwHxTroZRwt2upJFCWj914Ohy2Yi+1FB4aCErNxTGKTTNsWhLlfqbe1SoaaRzhvjMEP9LyYZ2xWvbqTRiodBj7Qnx33VWdl2OkdtJWRPuYxB1NeG+7L0SLWMVWfFUJGjI5lMGKeI9vLaeUmQpXsZuPindy1eXHh9VE0tlUnWFfDEXMC+SIsqOnoV5du3atY/R4tH4UJc6a+Ki4YCIFwKDqyxNGSeqgRiXpl6ONuQimoOqHj3NqlWrHq9fv/4xgjWMk9hJ6J4Z7oEFPpP+c1SrbyZg9IYpXJ+ajWX1wu8VUUmR+1bCEpU/CEvGUZgEoyIJLUzYqXMSPMTbML6jYqpjmSri16mn93zfSb/PAnH5e7ooS3COC3ErfSEexcvL4JGTFXG4K957L4rX9jDx3nlGRm9LIxhzj16WmMTUpxbQx2rDciHklGxc9L0s9psk80aPU/CXid0HyEKvQFk+cbps+u4HCd13SJLvPR1huJvyQHaERxvppV6/hBhRHN4PAuN3KlYG9vWSLq+9Lx7FyhkCXs8q9U6qY22e158hqzt5VggLzRO///77R4GBgbOOHj36T01YNHHRcIKoNSsRkvPnz//B19d3gyIvvxEAY8+PId7u3bu1w2kuY673hGq9qjUII8pApGVS76Fy9VaMkKUnpZJfCUtmBIZlGLJ2eP9RGd6sg7R4s5Q6L2Xwgrns/03f6g4Sl+cspCVBoUgOkpbnPKvWv0fp8oDuw8XvfIJ477uUpmVRJGLk1jCDtKw+83ST0tu3ImVZwFQZ3qSttFfEre6/ikutvxeRz/9RTGo8V1Q+f76E1Pib+v/fC0vDV0tK68Llpd/nTWSp+ptLoaefTnekPpDZh8Ol+9oThnbGBwKzP1wRmNMyfNoy6d9tqFFthFeMZ+U6EJiZefk5woIBnxZHIi5EtYluBwQEzEHDQgsTPSdp4qKRi1EbDJf2799vTy/zs26rnnsY3eob7/YlK0qDf74rg+p/Jbu37Hrih3I9Oq0ypyCQloxSSGyd0fT8MHOhdClXQ5q9UcLwhBlUr/UEn449/9MB8vJJTpIWC3GZ1L1CDUUMPpcxaw6K78lo8doWZqSHRm07Lb3WhRg6licpipQUWeg9wXAh/uL5QlL7hQ+k2fufSf9aDcS/dSuZ3LGNzOzRQeb26SSze3aUsU2bG5qgVsWqSb1Xykpd9TdE6xZ4BUjktaeNH7ddipZ+G07KsC3q/TmG/ZfTRLuhMUb5db+O/QzRsBF9qVp/PT4zefFZQvenNmq/mNG4EGFZsmTJI1JCR44ceYE0vZ6PCjhxoVSMFAUGY5SmofTeu3fv60QAtCo7ZwAZQcRry6kX/cz48ePjMGnS5yxnMWOYzxt9ajbey2Lc8t0yMsdrgkTdTZYHliqhghJlsUlg1Dm4bRHxXrx8XQI8Bkmz14oZTrw9q9U/OrnPiNfc8dqqhf+/FWJJxQwc6GeUOnttT0vVkLYh0rLp4q+k5ealyzKkQWup+8L7Uu+1ctLt07oGSdkxtb/c3uEvD49NkscnJoucniJyZqr6OlWSD06QGxu8Zd+sgTKp2zfSqVJjafBGBanzz8LSVRGmrctWPvWs77t22xD/jrKQJ0O0u/NsWvWRwhDfWYanjCV1tCU3zx9pGtaJrKSxd+zY8e68efMyrSpKSkoyfFgoa6a/Gl5Tej7KnlcX6zrRKqL3J06c+HtERMR/5TnigrUySmxuHsSkdDcGYWFhRlmZt7d3+JQpU0ZxgyEU1blE1wBzJC8vr9CUlBSbOw+uEzedPmc5h6C+Ixqo3XJE/effMbQs+7bvNYS3uNpei4or8IQloyoka0uCH2YtlDaFyxlNIrtVqHU7qN/I+m5IXIr0qPSldC/9qYyYu1r8Tt02iAtCWTQn845eefL8kd4hilT3xWLSslgNCercVq5t8FFMLVhhukjIZEk5NMFA0oHAJ7h/ZKJIaFDa752fIed/GSdz+3eVbz6pJ1+8WFoavlJUZg4e89SzvuZshPH+XhZRsAEjAhMu4648kGGTF0u398saUSJFXibk5Dmj9Qf2+ePGjVui1ogwhStET/CrwkzOkUgzLUdYZ4g2Y/QZExNjmHZSJUSEBcJCsYKei5ySmlvCuq7+bTii79mzR2j3smbNmg9dEaRwmbEaN5st4x/yj7BebqRFixY9pHxt5cqVlbmZuHk1kXHeRKAe3v0YJ9m6FojZjh8//g99znIG/t/08W+pFl1cb73be8rl65GGliUiNjHfVAu5JvoSJzGJ943qmb3b9orHp19K01eLSscPKotPB8/ebkZcGlP+7FmtgYxee9CoIkLXMnjzKcOXJSE1za8pLua2dPu4ltT9Vwlp/+EXsnlS3zQicm6aJO4LkHt7AyRhn23wO0n7x4ucnixyeaZc2eAnge3bSKN3KhnRlwke/SU5MenJMz9p3wUZuDH0afKC7mbPRSN9NHCAr1EBZWknUMPVvitE5pcvX17Lz88vioUPLyvmJfDw4UNBn8cGjJ28I699/fr1/6b4AOLD+oJj+ZkzZ/6kCYtzQNBBrS+7IiIiMozkI3SGiDq7+MMlNyEsa926dQ7VolF+RtMrGlbRPBDNBR2GuemwhddEJmvAd4BqpIxurPTnHvM7bV3tekwZOOYvfWo0WkOkAKO1xRNnGE0MiSRc02kh89qX2AQjnXbxyg0Z/VU3o+ro6yLlZNRXXSa5EXHpTtqld/024rXznCHKJUXUZ/1Jw5vFOsZ16iX1/lVMkZbacmT+EJEbs4xIyt094+0SlowIDGRHzk8TuRAsy4Z1kxZFq0mtv74tkzwHPnnPsKi70ttSafQ0eQkT74NXxPdkjPT9ukeaYDetmeN/O/v8sBNno0qlpL+/f4y9HkJshDGAw8ZBzyXuYfRHGxeiK7Z8cBThPEIww62JC0w2ODh4AGmh7AwWU5rycVKCgoKSqIpZtmxZbQRUrsyd5UfQ1BGX3czONem7GTNm9NZ5Xtdi849r/7d7pTqhlDkjoNy2ZpMRObid8kinhhxuI5CmfUmypNZmjhxnNHCEEA74ssXSVd9+9+9uQFwq08m5V62mhvjV5+BV6b/hpGEsZx1bl6+SBi8XkaaFqsgv/r0M0pJ8MNBUlMUmgVGk5+FxxeGuzpQVIz2k6ftVpOHLxWTltG/T5tdHj2Xc7nNG9MfrWfKyLUz8Tt+REUu2ikeZKuL5aW2iLl86Uw/BhlSRleXoTCgOMONwy++wqcVXRc8n7uE3hkZIXU+b0fxJkyYlOhopy3HighiUG9LWh8nK4KaldFcxdENISnMrRL/aOdYcmSQMi3o+vdaFcxoSEiLkJx3pbsrr4S+zdu3asuo16/EVzwNNKDPHHK/At3tUqnMGR9iBdVvJkQPHjFLfyPhkLcDNBiB8EBcSocumzJGv3y8nrd4tI/2/bHEgl0lLU8+q9Q95fFBRupf6REav2iM+R2+K59oTsvNy9JNncEiDr+SLF0vJ2GYt5FFokDw4NinbpOU35OVisAR3bSf1XisvbYpWkJibt55UGfX65cRviQvl0nsviNfhG9KreVfprj6D+jwzsntOSBeQjma+IbKemprq8DpA6mHnzp3v6Dkl94HmiGiKveuI9gXvMbcmLrCwoKAgH0UoxJUDfQwkxtvb+wwCX13GZr/CC3KBkZ2Pj89edcMdxWRp06ZNJRwhHDQWw7QOAzsEb1Qr8fXQoUOIsSJI7yHM1oZ2v2L2mIBC3SrUulH3uTdlSMM2EhmXYJCWGzH3tJ7FblrIHHmJTkg1NEJrvvvR6OX01fsfSa+q9X+Z7zUhx3fnnlXqjUIbQndm3HL7ewwzOjqP2nPRcLO1uuIe2rhNmr5ZWr4qWUNOLB4mEj49S+khe+SF6qN49bV3jQby5QvFnoh1E+8/Mkqy8ZL5DXlRx+l7Jl4GjQ2WbkWN3lEXFRyuOiSdgM6EnmrszvFKoQQ5q4MGh1Sn6nnFPWQIkFBbrWmIuGB0SqbErYkLCxa7e3WjSk4MRKcLFy58SJNC3anTHIHhhiNP7GhqCIaN9khNRBleC0R05KkDAgLi582b1xrr7YKefvpx+txXO5WpEt/wxfdkePOOcjUixkhvaMJih4yo83MlMs74ivaHf19VyIzIXLd0oCb1tnaxIi/vlpFW75WV7pXrHs7ZSEs9H0zcuhUrZ/QDGrv+qPiGRInP7vPSffUxmXP08pPnZe4oP6n13PsyslFzeXR8kqFrcSZpeYq8XJ0hu4L7S5P3KkmbYp9I1KW0VD4NG2nkaHXUTQ/fE5EyYvEm6V4eH5rajxRxKezIuSCKy0ZGbS4vbdiw4bEtSwYzw1WLoEbW13o1z7dEapDZIBpDZRel0m5fVUR5lNrV30CnkhODk8NuPyu9ezTMgxAtoVozEwxiYEKEiuisocy6oJLKntUahDX8VyHx7dxHbiffz1MiXI4TQgBZuBqV9tWKTCMk6UgHf3M1Ks74N39zLTreLmHj55fV799U/469lySpDx5KcuoDiU9IkTgFjulaJq9Byi0yPsmIZm38cZ20fq+MtClanj5Hy3Oq/Nmzaj3xKPKh9O88QHxP3TbM3Xx2oSUJlYEbT8qpqDRR7kM1N45o1l6+fKmMLOjfOa2CaH+AS4gLeHxyssTuHCf9ataXhq99IPvXbjSOY+flGOmiCBWRl2fJC1VQo3/eL4qMSY+Paz1Wn+9zs5U86BHZwFBw4awOzURqiBbTRFHPx+4BUn/0haIKLKOBFIFWM87ewLrsA6E/gbzYqmZx5iBnStpD30yuA1GtEydOOCyyVtflsZrE5iPQKijVYfN8Jv1H90+/3Nn4pcJGeoj0QJI415+FRf6aicgNv3PVJFm6bvldEBF778nfR91JMEhJGnH5lZg8ITMxdw2SYv272HvJEhWXKLcVkYCA8Dv4sPB6/K2ttFB8Yoo8fJRxUSIkxiAvmXyetMhLilFxtHHFWmlX4hNpW+wTKmMW5ABx2dC9TCXpWae10fnZ9/gtQ+g6dPMpIx1z4+7TlgS9azSRJu9UkPMrR4ncnCUPjk40fFoQ5zqbxKSq15XQKeLXqqXROuDotl1PjmN7eLRRYUSJ9lPE5cgNGfPTPqMNgCIupIs62tp9E5GlohT/jsyistkp1pg+fXoqsgA9F7tXZREbWsgLVV8QGCLvSDlYk5GNOOK/k+vExVrjbWnsF0WnTXQvfChXDJgdQtGsnHjK8uhNoVNNmYMeSZQtZrVajDwo0Rpyojgr5ndN0sgWHZfT1bn7p1/IpSs3DfGoc0nLXQsZSCMC1rTKswSE70MYIB5XI+NsRlcMIqL+fSs2QRJT7qd1I3/wSFLupz2zKfcfGBEQ/g8p4fes5Im/vaUIS5IiFhmRjlT1N3yfv4fUEFW5bERi4o3oCsdwKeKOxCXY740HebluIUA3MyEvt+LSdBTrlv4kzd8oKZ3LVpX+XzYf5kLS8ja6lm5FPpKBfnPE70KiQVogAL3Xh8jhG7FPfQZ6CrUpWUW6fVLb0LckKrKCDuXRiUkiJ4PSypkNU7lpvwK33LApac65T5DmoCthU3/995l0X62vEz7diOqMb9NK6r1cRhZ6BTx9PCevGaZ03uk0LjRiHD57pXh88Kl4VvqSVFGZZz8386ZVvzJ58uREDMicFWGxahm3bdtGpGUnm+GCPkcTueCcY7DnTuQFbxz8WqZNmzYE+425c+e25b5wVc+nHDnR1HDTsRNigTEd5c0Ia+klkZ3W4+mHen1BW+OI1oNj4kR7e3sfVAhhUaVCRlfHZAxq9iGI2RlUhpFCon9Sfo2+DGrYpiuVLZ3KfCYnjoUZqQtnalquWchCqiIV9x+mEQGQnsSwsCckp0pcYoo8eJi2kMTEJxlRkcxcaROS7z/5XdNpWkVEDNx3bEOSqN7rblKq8b7ht+7I5VtxEqH+bfb90yIvtqI3aZoXzv3iSbOk2evFpUu56jK44dedXERcuho2+TUay5hfjhhpFgjA4E2hErD3/JPjjou+baSI6v+rqDqez6VvzQaKvNSRnpXrSf8ajcS3RSuZ2PZrmdu7k/zk1UN2TesvO6f2l02BfeTQ3CFyZsVoObVspIQtByMk7Puhcvr7YQZOLh0qJ5cMl2MLhyoMl/2zBsta314yp2dnmdalg0zu9LX0r9VQOn34pTR7q6wMb9rWOB7GA0Uq6SLN8VojLnSxHtBnjEHG1Of7TZUW8zoOtCtXrnysnmWnzeVW7SKl0szJOOAW9PQQMgh0g5i9sVbRxoX52Nn+KNkFhIo139XFGbnCGDGUo45/4cKFjXF1VTv5+4g67dnS2xoY3plVm1POC4liAYU8sUMwdpf37wupEG4KokWarDwN+kzhcpzdSYnrrK77cXLh+e0cfTt6XAVKTvEU2fzTRqPS5YYlReKUSIuFuNxN+u2zwqJPFAQCkJIJkaCiKf1iT9QG4pCUmjN6tIwICOQlOi5RHjm48BENojIrU/Ji9Dh6YOiKJvQcYpCXDqUqSfDAMVVcQFwGdS9dSfo06SDeey6I996LxuKP8HXrpV/Ln6f1GyFfPPeOdP+0rni3bSpBvZrL6NYNZWD9etL3izryTcXPpWP5WoZpXMO3qkjLojWMqqNO5T+XLp/Ulq9LfS4ti9WUZkVqSgv1tWXxGtJc/U7a1+rG91qpf3coV1v9TW1pV7qmDKxbV0Y3qSctCleXjmW/kJHNGkufmvWkzt8LiW+77iKW0374xh3pu/6kjMXH5dw9GbP6gOD8a0kTDZYM/KEgLc5OCRGdp+JRW/KnpeA2btxYgs0+FiPWtYrMBfohNY9eoFq0oJ0Xtwh9wRoJK82ePbuLuhDn8BvhophNKxFOpK+FWS8ScnJUImW2Q4C8kBZxp3CcOwCPHrQqXJvsDK4rD1x+20VNGTj27x1LfxbDAjl7TKDRdwixqDOjLVaNiaORkScLgzr31oiEVTB7+26SmhAfS14cpJ+sqa7MSqXj1TQCgRnWpL00f7OkeHz8edJ3k2b+zcnEZRTEpXejdmkuuYq4jN522ujEfD0+Lf0VHxMr3T7+XNqVqCLebRrL7OEtZdqAFjJ9UAuZMRik/X9a/xYysUczGdGsofSsUlfalPxcBn/ZUDZP6Si3tveScyu7y8FZneXY/C5yYlFXOTTnGzm+sIscX9BFTn7XTc4s7ybX13lKzKaecv/kAJGrQ2Ve39byVfHPZezXjeXbUa0koGtT8aj4pTR6pbgc2rzdOL7Y5PsykvTWqVjD5bd3045pzrlV6z9Un+/lZz8zmkLSONkdzMNUHEFY8ABjU6st+Z8udMlsU0//JbIY+XET6NbE5VkdBWkazM3oK0GYEKEX2oiLFy8a1UPpyQbsE3ddDOmItpBrs/ce6Flo7mjLZ8ZigX+OPj/64Xka5DInTpwYhI9LVqvGLMTlkitEW7mJ4U3a/0jDxIDuA41dPlVE153siMsCTUQlq2F50jrpBbYZRW7y2kBXc9mSHsvsnEEdzpy9LN98VM0gLwPrtd7kZOLSsXuZymnEZRfE5ZKM3n5ahm45JedjEozjDDtwWL4uUkG6VPhCEZPmMmdkKwke2EKm9mshU/o0l6DezY2vAAIzUxEZvjf2q8bS7dM64lm5rmyc0EEkerjIgzEiV4aIXFa4OiTt31aEK5wbJHJ3pEFa/Fs1lSbv1RS/Dk1l9rCWEqxe+1v13kMbNZIGL5WUWUPGWkjtIwk+FycDFm+WntUbiUeJjxE1E21pmdFnhrioTWC2CAuRdj8/vxg2raTusWrQ8+yvQOxMcYOtc6jO3X3IniYubiREgkli8cwFRABGZIXSZ3rr0JiROnKIjtmcGq+H0MuWCRI3gyI3yc62Kc4vUGTxv7Zs2VKU848hFBEvh/QNaWWNO/OTlsinY0/PVu+Wlq4VasmF8BtOryBKvwiTDsrquJecailPTqvMyWrkxt0GGh9blVOQGiqNNq1cb/SIaqMIhG/7HoOdSFzKGimVynVk9Kq94nMswiAuQzafkvA7aXPN5dNn5etiH0vnD2vJ6BaNZdw3TcWvYxOZ3EsRlX6WyMugluprS+PfEAwiMRCcmUNayOAGDaTem9Vl8JcN5MxqT5GIYSJEVA73FzlqwRGFYwrXh8qVLb1kiPrdFsVqGe8xf2xr4zUhQ0RcBnzZUBq+XMJowGgdUxf+LF+9Uzo9aema2WemYSHR8awQFrVpMQgLukR6pOnCiIx1mBS30HTS1qB6B22mJi5uClI3MHJs/klbZKVdNvoaXGPt6WnQ3WijI9tAMX7o0KGXIJRExWx1oE4/2EEowlMhv5yHxRNmvty22Cepzd4oIRt/XG+YoJlxfM1qqgiBLRU+WRJHJ6U8KWW+l5QqeSFBlJRiP7JHJMkmcUGsG58m1p3Qa5g0eaWoeHxSW8Z16290RP9+xsI/ebXtPiCg+8CB3wVO+0sWiMu/DLfc4hVk2JSlRodltCJ9NoTI8VtxT44zoGtfqfdCIelRua6hc+lesY60+7CmdFKkp0/tOjK0cQMZ+1Uj8WnXWPw7NZHAbs1kfJemMqF7M5k+sIWM69xUWhSpJS0VtgR9o8jLcJGLg9PICoDIRA+Xcz/3kLalPpfG79SQUS0aytg2DaXX51/KwDr1pV+t+sZ7f1OuljR5vbjsXr0+7Twr9GnbSzq8VkR6Vmt4W32eT2x9ZlK9pCkQ5polLHR5psoUnxcIi5koeV4lHadPn/4zhGLx4sUNsZIgKuJIg0iKF+j7Zy81Tz8/MhSauOTzaAEpKFsujqSgqEvHul4TFHNiZ0gegrpVq1Y9thXNolxy8uTJ/hDP/PL5Bzf4alv9f74rUwaMNlISRv8hFzrjQlxu3UlwWMyKYNf4e0uJdMb3/mNDMAupuZOQbIhmY+ITDfO3pJQHpiM0/B6lzaS1+Fte72EW0lscC+JhSq0f2iiz5VzwXrZ8bRDrxj1Uu/2b0dKvdlNp+U5pGdLo62VB/UZ+0OOzelc6lfhYOmBvX6Xedb+OPYs6SFz+U+E0xKVfpwFGKTEpo4GbQmXSvgu/EsfYOzK8SVup8/x70umjmjLwi8ayaEAX8W3eUgbUbKS+94W0KVVLvipRU74qifi2uiHObWkIcKtL2w9rSOuS1aXeG59Jpb9WlDm9vpKUU4N/TRPdoKKoqzQpVE3qvlFFOpb7XDw+/VK6fVxHRjdsLn2rN5TOH9WWpm9+ILX/9qYsGR/05NjC1F6u+6Sl4vFhFenx6Rep6vMUt/e5EYYSAbf1zJPiZ7OCeRwbFrSI+ZWwWAndzJkzPWhsiySBtQYtCm7ynANEx2ZfC+dhKnBtDQTSBc3fpkD6kdhrSYBuhvbprsq3cgwwb2yQSXPBzNHT5PXyYCJg5KnZJaA7QpcECQT4uJBWmjp16vD8pB0a83XXpvTGQTtx5txlQ9vi6qaJVu8URwS11hSRIWK1RIPQhqQXuUJsIAhW/5e0yEzck/9fs/i8UGKNky3l1o+MCofHxt8n308ri8YD5sbtu0aJs/XvDfKhyNZ9B1JTaceTVgXFa3Fstj7x3cSUTCuMfi0lv2tExHas32H0NMJnx7NK/cddS1aQnp/VFc+qDaRriQqQl9sD67Uq4iB5aasWfPEo9YmMXPiL+J+/J97bT0vPdSdk5elfNXX3U1Ll+4nTpf0HVaR18WpyatkIkfj5knQgUC79PEaOLxomB+cMlj0zBspa356yPaifrB/XW34Y5iE/juwuP43tIevG9ZLFg7tI86K1jMoh/3aNZWq3ZjK6SX2p8eKn4t2ilZxYOlyOLhgqF1aNkbhDEyRis48iMYoYlahs6Fq2ff/TU8Qv8OAVGbznsvRt3iXNu+Wzur72PjMEhEiCl5dXqJrHniqoIKpNtSe9zahIZNNYEDZxlC0TBckwpRkbi74vxOymmKIVjPcy07ShM0S8i/ZQE5d8DkKUWNETtnz2hsBnhEWXB80V7009Pgs7uxR1gz8gxQIznzhxYoL63gbCirw3i3tebVRImJRycsLB7DDAjBkzepMTd5UhUW5gvm/Q77uUrxHX+JUisihwelrjRCeWPtsjL5jKJdpJo0Ao4pNSjAX72VQKRCTmbpJRVYQHjNW0LtN+QJb3vRKVZh4HeYp48nnvPbH0h6xkFHGyvnakOm6iMfjGZBSpgQBBjJ4QLcvfX468I9HxiZlGXPCFMdNO4VZ8shEZC/AYaJRIe1aoLj0adxKPaRvEY/pm8fyilfT4wHDbvdG/dlOH7lfPqvWPdS+tFv3qjWTMttPifzbecKTttz5EloRck/iUX8ni6Jad5Mt/FoU4yUnIy+UZIrfnqp3TtyKXpoucnSZyIdgwjjO+XkwHDOWuzpTr671kcse2ioDVl44f1pE+6n1X+/RMM7K7PlPkinrNO/MU5srcvp2l6p/fF/+Onk+du7Cou0ZUaMCGEPE/HSeDR0wSj7TGihvMfm6iKKQraHqL5gIPFmwleOYLkuCWTai9dje7du2SVatWVTLzeugA8Rpjo/2ssR/vgcaI817QNEIFNr3Bg7ZgwYLmiHwpjaZraWBg4F3SHaQ9XHEjQFoQF2ONnBGD5kZUC7scOHDAIE8cC6FVSuKyoufJbbAbY9LKr67EI1t0WtDszZIyoG5LY0G8k/ooR5snpkUznjZus95XRCti7yanWexHZdyc0NqDiNe4Fh3vsC7H6ilzPfrXnkb2XiO9oy8gFQWJgYDdsxjSXbVY+mf0WkReMNJ7NtoEobliUgxNRIxE2emzl40oS+d3S0j3fhPEY/118VgRZhAYz09rSzdFQAZ82Xyxg1GXjxV5EY/i5aXHl1/JqPXHFRm4I167zkvnVUdk1uHwJ8ccsme/tHintNR/5QNpX7qmjG/TWtb69ZSzK0ZJ8uEJFsdci3vuOQusjrmnpqQ540bMVmRnTtrvhAYZzRSJ3kBYHh+fJHG7x8v+2YMkqFNbaVaoojR+vaQc2ZJWCRSdmGocz8CNodJvw0nDNZcU18ABvmll0J/V3ZKVeRWyQgqpIFYIselkPbG1mWD+nzJlipdZuw0KSiA6aDOpIGKtwqWYzTfWHnlxbdDEJZvAeh7BLg8c6RtXRTlYuCn5s6cQf7ZsGCJjsby+QQUVlU4cJ+kmra9xLeb6TM5UnD2l/6giOOO2eKuUrF78o1Gx4ipBrj1AAIhisHiTTqE/0HUjQhFnqpdRbuIJibGklMwcrzVyRE8jCBriXYM4OZCiux6TpvFZPHGmNH7+LekJ2Zjyi3h8d1Q8fjgl3Ud+K56lykunUp/KxD7DezlIXppRkeNR8hPpjlvvmKmGr8sYRV76KoJw+c6vUaOQ3ful3+eNpcErJaT2P0tIvdfKS7syNWVss+Yy27ODLB/eTXbPGGCQj32zBsrZH0bKme9HyjlFbmgVcHzhUDmxaJiELhkup5ePVL870CA/y4Z1lQntvpLBddRrv1FBqv6pkNR74X1ZGjDlyXsvPnFN2ikyhd+M9/Yw8Qu7I2O3nETfIj3K14C4dNPzgGPYsGFDKVvlyww0L4p0/OwosSMNhX6GtQqNYEHp+6aJSy4CzxKiLVnt1cROGudEwowTJky4B9vGNp8cKKmvgsi6XYUpfYc/P7BOyzmelb+M71WlXsig+q37Txkw+qlJZkijtj+0eqeM9KvdzPBqiU19lOudnI3IiYUIXI/OGx2os9P2wJpKyio5i3/wSM6eu4zBmnR6q6h4tuqZRlzm7RWP5WoBbzdAehQrKx1LfybTBnuVcFTv0rNaA+n6dgnp0+Ib8T54xSAvNDNcHvp0A8LU5GTZtuoXGd9ziPSs9KW0er+81P5HEan+t6JS+4VS0vCNctLsvYrSoshn0vHDmgo1pGPZ6tK2VDX5qngV+apEVQOtilaWxm9/LHVfKWv8bY3nisiXLxSTnlXqyyTPQXJ486+eK1fjkmTo1tMyEtKy75LhlOtz+Jr0bdtLES6jFDpWfYbf6/nAMdBPaf78+Q9MRFxGaYNTTVzyhAMiqShnlIdCYlDq8wAQjZk0aRJhw58JJxKR0b2WsocuFWqd7lLmMzWBV5DupdSu+ZNa0qdWkzPffFTd8EpYNWth4Y7q5xiZLZs2N03bEn03XxMFd8b1rP6dIj0k2NZ+t0pavVFcPMtXl+4BP6aRl0UHFQ6JZ52vpGuRMpQHn3eQuNTr8XENmhPKmHWHxfdEpNG4EL3LoE2hsuLUjQybUd6JipaTew/IiqBZEtC1j3h93VWGNmojvWs0kk4fVpO2JT+T9qWrGhVJ7UtXkW/K11L/ri7tP/hMun5SW/rWaiJDG34twQNGyqrgObJn9Xq5HRH51HuE3rojYw5fl6GHboj/qdsGcRm5ZLP0btxBuhX50Orf8lV+eZ7xAyNKDYiwu7Ki6ezZs39UG9QrtjQumPbRkFDPtZq4uD2oIMJwyZmNyJ7VxyjCYpQdIvLFtK+gnWOP2Tv+B2TnNXw79xneoVBp8azZVLp7LZIenYaJZ5mK4lG6onQpX/N+YPeB7Yc1arsNEzPs2C9cjpC4B48VcYnXJCIP4nbyQ4m4kyAD67aS9q8Xlh4eo41oi8esbeLxfah4TFotPT+pKZ2KlZNhTTvMcoC47OlWvLwM6D1afENvP2lc6L3zjJGaodJo4t7zcuB6rP3qqqRkiY2MMgzsLoWeVl/PyY0LlyT81Bm5rr5ePXteLp48LTcvXZa7t2PlYWpqhq9z4fY9WXD8igw9Hi1956yR/u16ycC+XtKnWSd1f1dKqySCtFSp1zs/+KgQicbdl00d3jH+/v4xaBpx/iYy4oqIByQJ7SQ6xczSRF5eXkc4Nr0uauLi9sA0jy7UWbXJd2TgqUAUpiDV9ivCUlzhosJVhakKDk9K47/p/VePCrWkhyIpaBy6IdZUi1j3sYvEs0YT6fkBrqdVpWuFmob76nz/KUZ1yo3bCZoE5GGwzK/8dom0fr2Y4XzrMXW9eCw+Ih4zFXlZeVZ69B4vPUqWl05lq8iMkX5vmCAt/6YQTlflIf7fGmZ0VuKSnsAgiu299pjMDLkhO2MfyrkUtbA5cR64k/LAcO3dejFKZh4Ol8F7wmVA2D0Z+fMB6Vnxc+n6dknppggZrQqIDCnCckgd90d58flHm8gcS8QZszfKs9nERUVF/aYa58GDB4bb7MyZM3u6QkCM/mTu3LltEekSFYesUAZt8XHZXBA3lZq45FEQnsQ/JrP6fldEYIjw4BNTAEhLKYUIBUmHrQrPOfI6ParUH9iteDnpSWks6YK5e8Rjzi7x+PGM2oFvlx6NOolniXLS7aNqisBUM6z9Db3ArTuaAORVRMcb1WC0Z+hTs7F0eru49Og1zhJ12ZGmdyFl1LizdC7yoQyq12q1SeJywEORgoH9vMX/QqJ47TyrCMvpp8nLtjDxPnzdKEPuHrxSen+3Tbx/OSILD56TdScvy8GLN+XcxStyev9hObP/kMTeTRSaPdyhIijpvtxOTJWbd5MlLPKunIm+Jyci4mTrpShZGXZDZhwKNyqZhu6+JP0P35LBR27J6C2hMtRnhkFSaAjpWbX+T+o4P6UXUV4kLIhVQ0JCniPtQvNXtH+kYTB9s6clJPKNWaarrPIRziIPQKyLLQRp/AMHDrwCudLroSYueQp4s0xUA+btqpTRU7ns0FDBF6YAEJeGz5AWK2qafY0lQbP/s+/nTa53K1JGug+cYlSWeMzenvY6pA2WHjPITI/2g6THBx/LN2qXGtR/lFyPTus+7Iq+RBo5hNsJRuRs1ugAafXi2+LZoL14LDyoSKsirgsPGfcA3i6e5auJR8XaMr5r32omyIt/j49rSo9PPjf0I/5XHojv8VtG80Xv3efFe3+4EYnxDYmSvl91TyufrlRHulRpIG0+ayitKzWQryvXl44Vv5D2JT+V9kXKS+/azWX4+LniteWk+JyIEl+qgEKiZfCB6zLkwDUZuO+a9NtzRfofipChx6Jk1KHrBlkZMW+NDOgzVjyrN5RuhctKd0W88ZtRx5hnd/74ROGHRWsWKjUTEhIcnlNpVUA36vzkLaWJi4bLWg7gzYJPC51RUzPJRzslVHznDg7Ac/J7xZFaWKorPMqAuHQ0+xrBQ73LdVY75B6ft0j72/n7n34tyAuL2YrT0qPDEPEs/qE0euE98e7Q03DLte7aNRHIg+Le6HijT8/BvUelQ4lPxOPDz6T7mAXisSxEPJYckx4d1fUuWd4wiuv6cS3pW7PxVhPE5XlFDm53L1NJeiiyM9h7hoxesUu891wQn0PXjIjL6J/2Sf9vBgqRmR6f1BKaNPYoX116lKtmwEOhW/kakKWHON52KllROrz/oXSp2kB6dR0q/f2+lUFBS2T4og0yfOlWGbF0s4xavk2Gz1opg0cGSb/2faRXndbiUfpT6Va0nHT/sArpoGiFQer48mwpLZEMUkE4nGdnWLrUX6G8WK9NmrhomEgbUR5NKTOOsrjoYo1NMy1SPM6KxuACjHulo3lc8sVUJrGrwQkSIRl5W3c1kVPEokwmxGWvwj8UXlewqffx69w7oMObRaRH5+FposyMIjiztovHggPisfS4EXnB56PFmyVk9tgJxsIXdS8l35ch51dE30uVW0kPZUS7ntLhlXel51e95KsFR6TZ7APyVZ2O0v6NIvJNuerSpUJN6VWtgUz0GPCBCfLyomfVBncgI1TrQE4QwvZt21N6129jkBSPEobRG4Sis/paTKGS4QPzWd0WCo2pTlJ42/hZlXpz1Nfbxt8VK2+YxCGoxXMljfjUNL4itIWo0OG5+0dVxbPyl7zHZoWeCnm64z1VQZQS43qe3WHpSRdT0OzyNXHRcIr6HVOh48eP/2P16tXlaECodgEXsHKm109WfV8YECGIkSOmeuSMOQYeaMRltCSgNcG4ceNiCasifKNJmLuEVy3RljWZpIrAbYVEhVh+N7PX6Vuj0WV61HQfPT9N3/Ab0rJNPObuTtO+rDgtHmsui+fXfcSjcGnDNn7V/OWGyBPre00E8h5uKpAumhk4S1q8qghs5Triv3i7TN9/Q/yX7JThX3mI5yc1pbciLQi0hzZq0y8DotJeYbLCaIWBCqUVnlOEY4z6ep20EdoSw5juw8+MNJL62Tb1s6oOVCv9TaGdwlLPynWOeVb6Mr5HxdrR6rXU188fq68JnpW+iFQ/D1GYqgAhKpJf5ktIho+Pz83szItPqrVSUoi4HMxPDV81cdHINSLDg4SolpQSpXzYO+/fv99Qpz96ZL5JHcTDkZ5Lhw4desnX1zeSTqbPRn34Pw86ZAhRG6FanICxnCYig1AuhwlLT4X9NghLRnio8PKzrzXPb3KZzmoH26NGE/GYsTUtqvLs3yLSXXRIevQNFM9azYxKI3QwPet8JZ0KfSCdylaVU6fOy91Hokuj8yhS1M2wZXeItCz5mbR+s6Sc2b33V7G7ehwir1yT7/wnS5PXS8qIZu2DnyIUVeoFEzkhAkJ0xaNURWskpZOFcPxBoZZCFwUPiyA228JQ9RovWMjMSxAUhVd4L3eu/slO5BaBK7b3zohIq02a4EaeV3vCaeKi4dbKeUS9dGBdsmRJPUUsfoGQ2FLOQzKoXpozZ04HfAXMlmvjxgs5MhtmpeNzWFiYLFq06KHauRz/9ttvO+3evftN0mCuSitR5qxQ3kHCIt3ALENs+xtjLe+23ae2e72weHYYZIm27PztaywLke4Dg8SzWBnpWaysoXnoMnG1dPh2j3St+IU0/1chmT7U29C73Lytoy55ETGk+hIfyoCvPKXuX1+XWQNH/ea+/2nGXGn4clEZXK/V0ifVaJXrfA1J6V6umiG0HTR4vPRr2zMtTQN5cSCikt+AVwqmbGvWrPmQFA+pa7pF0yV+48aNJWi34sjrMQ/OnDkz28JA9DFqztpPOlyvM5q4aOQAkUF3QhnfpEmTAtHH0F0ajYz63mNU9hgcMVE4ks6hKRrt07OTL0bZTyUTE4uaFHZRBmh18nWWW6UiEf+rsM9R0tLj253Sa+4uRV52vPnsaw6s3fRwl+LlpLvfMvFYeSbNv+PZ1/jhlLRv3V86vV1Mun1cS9q9VVy+6jVJum6OFM8+46WD+v/g+q0NC/roxAeaCORRkS4PwHezlkqT10pI2+KfyJnDx566z8d37CmtCn2EzqWH9f7p+VnddR4fVJR+7XuL74ko8b+QJL7HIxWJ6SEepT6FuOwtSEQFMkKjxXnz5rX28fHZyfx0/fp1I2LLZgvwb1LhRHjxmzLbe41Gtdg8OBJ5Tr+ho5KIztWQKExB9ZqiiYtGLqSVIAU8gKSWUNujkM+K/mTr1q1FID/OqmhicmJXg9GT2mHdproJLwPMl6isygZx+S+FtY5GXLor4uI5Z+eObjO3PbXDG1z/q997VvoizhNho4eXeCw8YHh3dFd/02XmdvkqaJM0Hv+LtJy5V/oH/Sx9q9WXNu+XFe823eT4+ZsSk/JQTp44LTRc7FSmihw7fFLuPhZNBPIo7j4UCTt3RbpXqSf13i4tyzoqfjJ7jkjCPdm1abs0f6cM+pcHAV36PBG5elaus6dbkbIyxHu6jLv6QMZuCxO/8wky8ruNaSmjSl9GKPKSb0tueZ4hFKS2ce1m46I2LEZxgD2CkZycTAFBFBscM+9FoQEaPFLWZv2s+F20euhZ6O92+PDhFxH56jVEExeNPI7t27cXImLjirJsqz4mPDzcmEBId2XHGE8Rkb8oDFT4QSEqHUF5nAFpodrIW6FPt1nbf2OzPbxx2wqUmuKY2rNYGfHsNlrazTskDcevl68mb5J+C/fI0t3n5ER4tNxTZwfr9UsnT0n6JN0V9f82xStKhw8qyYHdhw2TsHwRgYiKk1v3UuWuxfTs5u2EXKmaoonirZh4SXggQk/nW3dTjGNzxXvdikuWeLXWTuozXOor4jJGEVXxGyc3x/pJu49rSauiFWR4k3YDntGZfN+97GfSu2E7o5Gi/8UkGXdTZHjwcule8hOqehLV7/wpP26ctm3b9r4iBCHLli0zigmy4gyuiATp5oZmoy6QHDR2EJJniREbJtxyMaLDckJtmBZZe7i5wiVXQxMXjVwElUJTp05NlhwY+NeQ4zarv7FDYp6j1NliQvcgA+KSrPB/NsSN3dAh9FQ77B4lykmzaq2l1/LjsvJguJy5HisPHtoPSe9cuUaavlZculf6Uk6duihxD80RF7QwN2Pds13A9cg4ua0+R2TCfdm3YpWc2LVPolMeG+Qlp48l4rY6V3dTZXfIZdm1brNE3ksxIl2uIi8svSvnLpWmb5aS3lXry8E+g8WrekNpXri8DPii+cFn76GeVetXxOMF6/xe9dvI8Ok/yLApS4Tu0D0q1CBVtDU/zhlsPkj1EDXJrt6E/kGO+E2hTcFckygKBCU4ODgF51wfH5+taAEpNEAb6Iw5RkMTFw03BemlwMDAYHYrrh7sytSEE3b9+vX/drJwNyYD4pKqUMgGcRnZWy1KHUp/JvWff0eWzP1e7qTYISupqZI4aYqkfDtPJCFBFoyfIl/+7U3xbt9DLapJEqkWWbtRhKh4iU3F+yXV6FLsXpGWeIlRpCU65b4s69FTRr74gox9/TU5+NNao5dOTh9PkjqO9ZfuSedmPWTw3/4my4YMlzh8cxLvuyQCRFTn8P7j8s2H1QzzOI9KdaRDhVrStXzNxOD+IytkdB8p8jIM8mI0KyzxsVHyjL+KZ7UG19Q99lZ+nDNIL2/YsCHbUVoKAhDtZiWFDDGhChOSwnyiiYomLhoFDOSpEfaS0nFlSwKLY+Ul/GucTFzmZKJx+cQGcZnU4YPK4texp+xbv8W+CFlNsslBwXKvz0BJGThM7isC49O0nXzxUmGZ7x9klNSaIQYsjvu27ZMtP2+U+AcP3ap3T2RCqpEaWubRQ0Y8/7yMK/WBjHn5ZVnWvYdBGHI6SpT84JHM23tZeiliEFi0sAx8+TXZtXxlWoNLF/jmIK7mMw5v0l7alfxUunz6hXRXUAQ33Ltt90x7+vSsUg/juA2elb8851npyzPq3wvzY4rICjovb9u2LdvzASkfIrCu6NasoYmLRgHAuXPn/oBpHWFXWrMjsHMRcbngbOLS/dudDTIhLpm6nHYpX9O/2VsfyGK/SelLpOTxvYTfHveFi5LoFyCxA4ZJvP8EkYlBcn3QcPH85HNp8nZpWbf0J1PEJfJuisQkpcrwpu3V36xyL01M9D2DVO3+brmMfuklGV+ytMz64ksJKFFCvm3YyEhvRSblHNG6jr/K/Yey4HCE9GzQUYI+KCm+ZT+SsSVKSejBo0YEyNlRFz4j12TGMF9p/V5Z6Vm1vrQrUVFavFPG6AruUfGLY/4de3rYIMMFQvjpLOKyfv36x1RB6vlXQxMXjSyDzqZW7xhav+OaC4mh3NkZIzExkfbuW2/duvVfzj52j293BDxDWubb+v2eVeqWa1+qsigCI7euXk+rdNi4We6NGC3JK3+S+wcOyv1DhyXlp9Vyb+hISRg6SpGWQLnrGyASNFV29ugvTdWiRol0WNglo+GiGaOzVXOXGn9zIypeohIfuk20JebBY7l6I1KmVK4sw59/UX4ZPEAijuySCYos+BV6T478silH00U3b9+Vu0kpErjruvT4qp9MLVFMJnxWVYa9/obMad/ROBbEus4ui+YarV2yyiAu3BuIdZcETJUhDb+WZq+XkGZvlJR+XzTb8+3YwJIFdZ6g5Hnp0qWPsjMX3Lx500gT4f2k514NTVw0nNZXiZJryph/+OGHaopwbEbEe+zYMSM3nZWUEjss2htk99i8dpz5h9f2019kEHmZpgjLQoVWCnY74A6q1+pAvX8VlkmDRouEX5bUMT5yd8gIuTtgqNwdCIbJvUHDJMHLTxL8AiTRd7wk+Y4ziMu8Vp2k5qvFZHLf4UYZdMSdJNtC07hkw113aOM2VKcYRCfiTqKbEJe7hoHejrkLZNQLL8i4EqUk4WKIcc3mN24kQ/74R9kwYVJahCiHqoti4hLlqiJ3nqvOSp+uo2R66ZLiW7qsjC1WSsYUKSYH1mwwIkTO1gnxmkcPhkjH0pUVPpMz5y6nLbTqZz/MWCC9qjU0Wj3w80DPwV8UxLnBYlq5kmaujg6ay27atAk/FS+ct/Vcq6GJi4ZLDfDwiqFB5IIFC5pDZIKCgpKwz7bn2wDJOXTokDBZZbc/iCIt/6NwgC67XtvP9MnOay3ym1S8Q5kqKc1KVZKd33iKTJ4qiX6BkqAISoLPuDTw73R4GDBR4r39ZWD1htLwzVKy4Ye1RjWKvbRF3AORsLCL0uKtUqJ262k6DTdpERCV/FCuRcTI9Bo1Zejf/i4/98ZjDUu2ZFk7oI8M+sMf5fsenhKrLvHNO8k5ckz3ElPkxOVoabfkpAz09JIJb78p33fpLEs6dZRB/3xJZjZtLjGpjwxdjjPf9466TufOX5He1epLq3dKy85Nu4xGmgiqHxoRpzjxatdDGr9cWDp/VE1mjvAvVBDnA4wrvb29L9sjLwjyqR5CzEuvoYlqYMHgLj3PNDRx0SggwHcBbwScfDdv3lyc3kU45mJAderUKcNcCj3LgwcPRBEeozUAv+OssLAiLbcN4rLjTHhW/n7aYK//6fBB5WIBHgPfHdLg6/1ty1SRzuVryoVho0WCZyjyMl7uZUBa7vmMF5kSLDu695NGxT+RLuVqyInjZ9L6FJlIE/284Hup9b//kjk+kywCUzcxXyPKsHGb+Lz1lvgUKizhm39myTFwcEaQDPv78zKzZk25fC1Sou4/zpFjSk29L6sOXJQGc47I0L5+4vX3v8nBmVMk7sxhGfVeERn+2huye/lKSxTIee97W5G4yzeijdRQ43+9Lz/MXGgQl/SRqTvJ98WnQy9p/FJh6fbx5+fm+wX9tSBGZI8cOfICDrlsSvBrYoMCiMhu2bLFMJgLCAiYv2TJkrr79+9/RZcpa7gNccGMCPaMI6FZIyGN/DeJEZHB8pvmjgsXLmyMtTY6GVJD+D44q3JAkZVXFI5ZiAvY6bX9tL/v3vN2e5+MaNbxL76de43qXaPhlS7la0hHRVh6VK6ThGfHV4qEUP56atAIRU6mSap/4G/IS4r63uMJk2Vcg9by+StFZULPIWkpn7gk+xUy6gCWTJ4tdf76hqz97sdfF0M3IS6/jBsvQ//yF5nbqKFIwk2R5Egj4nJt5wbxe7+wjCtUSI5u2mpUF+WEviUpJVUmrTkmDecclcGD1Tl/5V+ysntXlFLyXbt2Mggy1aiJRCWkSGTifae9N14xt+KTxbtdd2n4z3dkUq+hxjW+ZbnG16LijGsXGZcgA+q0lCbqPuhXu9mhgvrsk04mCku/MrxVAD4rGL+hZXNV7zKNvKObhB84qxlvtm/WXbt2vR0cHDxA3ahn6HUzadKkRMW+906bNm2IWrA8AB04qflnZw7b1nbLBSsq46w+RRbC8geFyQoP05GW9Ght6+8Dug/84puPqt/8qtCH0vTVYtLxg8pGqWu74p9Iy3dKS+fSleWrstWkTYWasq/nQJGp00UCJz1FXmTSFLk4ZLS0L19TWr1fTvZu22dEUuyliVj0YlMfiQ/9bt4rI6dCzxtkwZUVOXyNj0+UqNh7hgNtpgt1AiXA92Ru06Yy+M9/kc1jhqdFW2KviKRGyYPbl2VewwYy4u9/l53zFrj0uK3HfjcxWS7cjJUe3+6Qr5aEyuCBE2Xim6/Kt/XqqXd/IJc2rJJhr74lXopQHd+5L+2YnJR2o/IrOuG+jO/SV5q+/L6MbeNhXD98d9J78ZBIC1XXsUu56vLV+x/JuM69mxT0zQvzuyNmchp5G3TXJvWPVonUIU7FEFjL+t8zMDBwFulBunoHBATE+/n5/Uz0Dd1kVjtzZ8vzgwOgC/Gz2gbSA0lJSUYVChUkhAxJHagP9Jg0AnbNNODKzoFrFEwoYvJ/CusyIS1bFd7IVIRbt+UX3T75XFq+/YH0/bypfD99vuzfcUDCTl+SnRt3yjzfyTKoXivpUKqStCz6sbQqV1OWtOkiDwImigRNk2SEuYrAyNRg+b5tN6n1eikZ0ayDRCemGGZodoWmyY/kSsRt6V29gXyjFjoEn2heXEkAou8kyJGrMXLm5h2JjM3c8wSFwqn9RySgZAkZ+/Y7cm7NDwY5EEVYJI6+MPfkJ8/uMvj3/ye/+PrnSGWRPHooszeFSuOA9dL5+1MyZNAkmfze2zKtalW5H3VRJDFagmvXlkF//busGjE6jbg4qTO3QTIVb5vkOViavVJYhjVuK1dv3VHX+pkKMPV+yNPn+0+RRv96X/rUbLx7XNd+etHWyPcgkkbLB/rQ4V6syMgjUoP48qh1/cn6b00fWnWO6J2oJiPQAYHJSiAjyweMRfPVq1ez7OMRERGBSDP5p59+qpid9AE7esJQztzVa7g9efl3hWIKtRT2pCMuH2f2N9OH+73VvkTFBKz5/dUu+lpElCGyJNwf/1iMFE6KZce+b8d+GVinpTR9u7S0+Ki6DK3VWI73H2qQF5k5W+K8/aV3lXpS95WisnrRCmPXbcZLhB44RFk6la1i7NBPnTxrqnw6qxELIi0Xb8VJv42hsutipCTcS8q0DBoicviXjTL21VdlWpXPJDH8pHpQ76RFXIAiMbsDfWXwH/4k37Vrb6RlbsWn/GYRxwPF+tUwqrP83/jenUQDaT9PePK7GfUmQttyIjxK2k3dIh2Dt0qn5adk8JAgmfTuWzKjVi1JuhxqzCVb/cbKoL+/KJMqVpKLF65IzEPnaG8i1LEnqPtintcEI+IysE4LuX4jCiontxQBvB79a+n0Pa7rqQtGy4cuH1WTbhVrV9TPqYY7Eo0zZ8786ezZs3/MrhUF0RV0S/SEgpxkpbqUYAe6R7IxOUJc6AMBW3KGERmpJbp1OhqOpBMyVS10I/X29j7u7++/YuXKlZXDw8N/p2/SAkVi/pmOuLyU2e/1+7zpiZaKiIxq2VniHjwyCEtGZOO2xe4/If6uTO0z3CiFba3IS5tyNeXblh3l3IixMrtVJ6mtCNDAui3Vzvye3E5+YGoxhBj9sny1NHjhPeM4bhourfddp1m5myirQq9JlzXHZdPZm3LvbsbEBYJx59Fj+WnoMBn217/KwhbNRO7dUKwuIh1xSZUzq5bJ6JdfkeAqVeTarTsG2btrQXwGuPPM/2+rue32o7R/xz3zs7vpfofzdDkuWbrP3yutgzYbqaKO34cZGpdJb70u39atI/dvXWD/JlFHdon/B2Vk9Guvy/5Va5yWwqJEHbH1zOG+0urNEtKz0hdy8FCohN9NkbiEJElMSjGIF/fQzTtJRvn05L4jrIZ14/SzqeHKdBxg0060gr5NZC9CQkKeQ1OEvw7yDFI0NJkEZEfUGnmbqi7sKPg3P9+4cWMJytodeX+E1aSAwsLCsu3pFR0dLRyfow0ws3Ti1IcvRUjIGeP06dNCPsxsygiRF+8/efLkRHXRDNYG26NyhQiQIjFXDhw48Ep2RESQH26A48eP/wNmiaBIR3Tcmrx8o9Ap05+38WiB4ylRjtNnLxsL47V0DfquW4SgLOx34xPl5JVoITmy+ufN0r7wR9Kh5KfS8v2PpFnJStKubDVpohanNur1Du05ZCzeZjxEWOR43wXjpsjnf3hJggakpTYiYl3j4RIblyjnIu7IiG1h0mdDqGw7fytT4oKBG6XQi9q2lSF//otsGDHEEL8aKaInxOWu3Ak7LBM/KifjixWTgz+tkbNHj8muhd/JgVU/y855C2XTpCDZOGGibJocJBsCJsjaMV6yaeJk9f3JxvdWDhgkP/YfYHxv/bgAA5uDpsreZT8Yr3d47Xo5c+S4RF6+YghyG0zaKl2WnjCiLV9vjJGh/QNk4r+el6Xt26SJhh/cVnwqWha2aikD//hn+Xm0l0F+MmtJwHW+pa7D7bgEc8RFkagZQ8ZK27dLSq/KX0rvoNXyzcLDErw+RMKuxkhySqrEJyQbESLug5VzlkjLtz6QPjUandLPpUZ2iAl9m9CE0vwWoB2hfHz69On92KxTxYWWFO3I999//wiDUKq66LTNmqrWMWNNJDgArOvksyXqap0T9Xq/EIUxe3z8rvqbCFvWF474+aCPpaDDpcSFk4oRGSfKGYMy2XHjxi0xy7ggFIo9xmTWPp3XoyTXkRMBaYKxzpkzpwPRG/X1/v79+40bYeHChQ85sTi94lnCRcaHZO3atWUhSER+stIcTCPnQEdf9AczR/obof70HY5ZzBCukkbZHx4lcw5dFK+weBn4w27pVqmOdCpeQcZ7DJCJvYYaTrcdylSRLhVqys71241CYbO9coyFUP1+8OAx8uVfXpPgId5pxOWOa/r+JKrPs+HsTem7MVQGbT4lW85FZExc1KIblfxIIhRhm4PJ3N/+LkfmziCQ+ytpAfduijyMlUXNm8mY116XqRUryvgiRWXsyy8bGPmPf8jwv/5Nhv7pT4ZR3bA//1kG/+//ycD/+d0TDPkDP/uTDPwd//6jDPr972Wo+v/oF16QsS+9JF6vvSaBJYrLlIqfiH+12jKufnPxbdVZRncZJINGTBe/lp3F55//NDxljCRf/DXjOPdMnSAD/vgXmd/6a7mVkKqIWGqmVUp8vRQZZ3Sctkc0ISPLp8yWtm8Vl94f15CO43+S9stOSYvA9dJ26maZpghMhPo9RMSUR6OTalvsYyrUzuvnTiMzII1gcwwZobiFbtZEHSyEZDPrl7+/fwzREfyxrLh06ZKRlrGSECucETygwMZsiToZF4S2zlj/IVeQL1rNuDzigiBn9erVTunCh3AXMkCFkhnStHz58lq2SBMXEuJBaZ5ZIgaTxdYe3U1GLJLvASt7RXTETQS7he1CbLj5HGWNGq7HPL/Jb7Uv+al0VWTj+LEwY4GxpoiuRd+VOLVgJ6td85qwG9LnlxAZcPCGjPjlqHT/rJ50KfKRfF20guzfsd/Qwxw/ekoO7T0i5y5cM3bjN2MTTffJMfoTJT4Q3069pO5zbxpiziQjOuD8JoERFn3L4mNXDOIyWBGX7c9GXNRxo9OIeZCWmrl49pIEKTIy4sWX5OTSeWLYrKUnLkbUJVEOzZsp3u++J6NeelnGFSumSEZFmVG9mixs0lgWNWsiyzu0kR+/6ai+tpVfBvWVjSMGy+bRw2TL2BGyThGOXwb3k/VDB8iqHt1k3aB+8kPnDjKnXh31GtVlepUqEli6tIx9/U3xffUV8X/xefH/x18l8F/Py+Q3X5Gg0qVk9FvvycHpQb9WPKmjv7Z7k4x5+12Z+PEncvHiVYnNpLrorvr8a0/fkDHbTxvXPsYOaeS8rFm4XNq++4H0KldFejbqJB5zd4vHD6ek0/StUt9/rQxevFei7qS1wti6dot8/f5H0qtag0NLJs/SEVqN32QLWPTRh9ILjj5PFK2w7hB5sBUdceUgCECmgpSTmc+B1cXixYsfOuO9KeJR772fzt4uJy4IfGBJnOTsDi7a5MmT/c2wPVI2dBG9ceOGzdfESpqIiFmRkZeX11FU0Fkd3Gjnz583Ij2OMkcN16J7xdpd2AV7d/CUmOTHikCkWkSVaamh87fiZOahSzJw40kZdfCq+O6/LL3qtJJuRT6Urh9/Lh4Va0toyFmD8CDi5S65c1+eCDNNV/ck3Dc0LcOatJOGLxaSNYtWmGrImCXiQjpELaZzD4fLwE1pxAVxLp+XY8Zv5o6kCZKvR8bIxkmTZdaXdQzSML5kKbm5d3Naqig9aaG66M41tTOIl8jDOyX0+0VybddGuRN2SBIRyt65qk7QdTUT3TLSN5IUKWlnK9EigU6y/B8kGNEb49/qdx9Gq51keKgkhJ80Xvvihp8k9IdFsjPQT9YPGyRL230ts76orQhTIRlX8gNJvn72V+Hww9uSfPWUTP3sM/F6510J2bXXiKqhoUF7kv4aEVVbf+amdFx9TDaejZAURViv2zCt44g3/7hOOhYtJz0rfi6excpKr8+bSveAH6Xbj2fFY94+aTRunQT8fNSYB36eu9SoWOtZtf4G/expPAuaUqINpQo3J4mJvcGxBAcHpxABMvM50NKgTXXGe6v1UiibRqLhcuJCaoVa7XXr1j3O7gVwhGTgDQDJwTra1oDJUq1k5jV37tz5zooVK5xyF6GxwXBNu0K6Dzw/qzsGf42g/qMk7uFjI2VDeoiFnR134J7z0mPdCRm765z4n7snA/t6Sdf3SkmPz+oaHYER0d66m/yUf0eWNCepj+XCpRvS9/MmRo+bX5b+5DLXXIgLn222hbgM3RwqBy9HSfL9NBHsbbXfCDt0TDYHBclMRQhGv/iijH3tdRny3PMytVJleXD7quHd8puIi0FerqYRD1JJaTVZaSQEzQmkJSEizbiOrxAZdDJW8H8rEP8aX9XvpkSlvYaVzBhJuFRLnVeS8dopty5I+OY1cvqnZYoL3Uo7Do4p8abx/zkNG8rwF1+WqdWqyTpffzl99IRBzvi8t9S1g8AgVj5yJUZ6rz8pvrvOGtoUW1EXPuWeTTvlmxIVpH/1+on9ajS637VQKelVoZp0HxgkHkuOSZdlJ6XJ9D2y+0aSLBw+Rr4uUk7UPTdVP3vurSFhw0qknUg5RR3oSFzZfoDNProQZ2z2XTHIUhANMvNZEPOS1spu012CBWqzfwlrlRypKgKomWlFToiJkijIBB8kM+1JRiwPtkU1EKZ0ZkufcWMlvGZrUE9O7tDMa0Jw0LM4YxB5ITeZF6MuRLOuXbv236S7uDEdZcDuip5V6i1sXehD+W7STGPvT/ktC/s9tYgtPHZF+mw4Kd7bT4vf2XgZMedn6VbiY/FUu+te1Ro8bvVuGaOfkPXvskMm4iALpy+xqEnLdz6QzavWu8w110pcZh68JAM3hMig3ZfkkOIB9x89ln3Lf5BFbdvJhA8+kGFoUhR83y8i02vWlB+7d5XwbetEHsT+lrTkBiAndyz6GqI4xhlL+ZVEGb9zxYgdHfw22EgjDf37P2Xgn/4i40qUlGWeveTolu0GUTNiPckP5OjlaBm57bR4/hIiG87clKR7STYbLe7fule6qHuid6XakXNG+pUc0az9mvaFSkuP4h+JZ4vu0mP8D9Jh1i4Z4rdABlT+3CiH7v9Fs+qaIDiPZEAoaBPCOkEZb3a8v5jj0DKi0WCjiVSBIg+1XoiXl9cRdIuuKMSAHCEtcMdhXbccEeiy4adABs2N2fWeFjCIhslOUAaNtpXoTVbOZ7ZdUVnoKL/C3nnGjBm96RZKqRUhMW4OmNzatWsfh4eHG0Z13CwY0ZFq4gYym1ezgvfiNTOL9GB2Q9MvGK6Z11uxYkVVZwmNGfPnz39glrm6Q84VsTPXTl23Neh8aJjIzoCbihAeFV9W8Hucf64Z1x0wmeCa6K6W3ooozMUld2nQt2kl0KQAEpLlxLUYGbjplIzcckp8T0TK2PXHxLPSF/JNsfJYt0/rW6vJ+pbvlHmS0rmeTUfWX4lLPWnxZknZtHKty4gLKam7cQmy8nSE9AuJk1F7LsrCgKmyvFVL8XnrbRmiFna0LNOqVpONY0fJ2V9+lOSb5yzJo6Q0UmAlBu6O2wrxNwxicytkv+yZNklm1a0rw/71ivT//R/E691CMq/117Lvx5+N5zNMfcShm0KlryKsixRxReN083bmxOXA9n3StUQF6VGheor1nhrXpe+wruWqyTeFy0iP8tWkZ+0W8k2FWtK2SAXpXb3hweBhPlrfYmfTCxGxziEIVWkHwkaYNSH9nEMEm/YBgYGBd0lPqH+foziCtIujPc+IhLPxJSKf0fpBBEDNfZHMic78vGwCcZJHFuGOg5Jk5ntHvF0QGKMjJfAwderUZApZKIwBx44dEzQwrP8YzuLXpq7bBRprck1p/wJhcbQE2mnEJSMiw84doY31pqSTMAdJEz6qkfhKBQ+7+qwsdnxYGvWpk5Yhc1y2bNkjoihmXxuhMSkvZ90E8+bNe0DTsbwweSjW2xDmy42LuvtZd0PYdHpwU1I+B/HkPIOlS5c+UvdjAsSH2n7rhMMExEQEi0d4zUPBtctpguNZpd4iiMuM4X5G2iAmLsmoGAncc04GbTwpPgeuiG9ItPRt1U06vVVCBjX4+uSoVp3/t/OH1c50KlNFDuw8mNbAL5tkAuKCNXyPSl+mRVx+2uDSPkUJyamy51KUDA2YK0H1Gor/qy/L4D//Tca88Y4s/uorOThvlty9dparnSbEvR8jEnc17xCW9IgJT0s7GWdU5EHcdQlZuUyWdekso954WwY/97z6+oas6t1Hwi7fkIALiTJwc5j47zpjVBhlli4yUkUbd0jnIh/KwFqNzk3rO+yJgHD8N73LDqrT8pcen3yeAHnpVr76g4H1Wq2a6zv5HwWRjDDvU13Jcw6Y35kHScU8Q0S8IB9s8KxzCAUOal0QNrdWt1UrrI1a08/xCDrxEOF1HPEAYy5SG+YbtrICvC7H6ayeatZFnjJm3GLdbXB+seGn+WVW1xHSbvw98hGAeJesQ/rNLfcE58FZ0aw8+ZAQOkQXA4tbuXLlYzxlYHiULHMCHVkcuZnV64Sj6naGyImbwGy0JzeB8ZCzKsOsnz195RWA6NASAqLDdYIkIWDOSWLXp2bjfvQhGtXqG8PG/f6Dx0YFUa/1IeK954L4nY6TwcMCpUuhMuLxyecyY4T/i4q4vNKmaHkZ8GVzCb8eJbdTH2WbSOCaezLkjCH2hUjt+GVbWgrKRcQlJvmhnI+Ilek1asr4f70gvsVKyJKvv5ZTq5aqixWXdtEe3rY0UVT3/qM7T6do8hp5saaPgJFWMmoW5PTaVTKlSlUZ/tpbMubNt2TSx5/IhPk/yfBT8TJm1zkJuxEjd+ITMxXnbv1xnXR4u6QM+aLpuozur5FN273QvVKdoj2r1nutIBIWdIekQUg1QEB4zgFzS/oO8ekrZpw1IDnYV5g1HYXk2CvjtdpzOFvvQjVsaGioW6SFWOuI/rDpxK4/q+ma3ESetzDGpAejOBheVm42SA6hK0Ja2aksYtCjYdKkSYHu3kSSnZGaaJaTusvpcefOHSabC0TdcuKz9qresGKXcjXkm4+qGXb7jLkHL8iATadkXHiqDJu6VDyKfiRdynwmfWo16c/f9Kj0Zb+2xT8Wr3bdJTrpgUQ+a22fFeKiKOLJk+cM4oIZ3u5Nu1xKXCLpqRN1R2bVqy8+770vJ5cvtKSCHlhErylGtOV+xHnZ5jdG4s8c+TX6khojEnMpb5KXJyQmPE0AzAIXeVW+79JFxhYtZZRwjy9SWLxnLJdhJ24bYt34TIgLZ2vt/KXS9pXCMrxu85U6zfPbuRPSQnGDMwmJIwMXWDZhZo4X3aO9QgzWADbAjrrJ2gPzHRIKZ4tz2TASgaLSlogVQEPCZp5KIVJsVrBBh6gQDWfNw4PMWd2aNXHJpTAn+Tp1cYMtLQgMRspuwZGKIurRIVLu/nnVjf0HQqa5NdkgynbE8Cg7GNyozR+7VKgZQWXRrL7D5arab/mfvydeZ+/JiLmrxbNCDWn3zgcyrHmHpel0Md/TKfrbsQFpXitOaNwXZ+ln06NSHUH0u3XNZpemiqJSHsvlyzdlcqXKMuHDj+SRxfMEmeq5n5fLgWkT5cruzbKweVMZ+vyLEly1iuyaNE72TPSTqMM7LQGLSJHoPEBgOEZcdKGCVDPdSZfygoBR+3ThhPiV+Uj8PvpYvP/1oni/8YZ4/bRXQhMeyp0MnHRx3yVVtNArQNq9WlhGN/56ip4rnwYLH5oQswUZrhj4aZGiNhNlR3uIPtJMxCU7+ovMKnFJnSMlQIdpZvB7FL2QYgKsMVa7fqpxLDhOpS0EEkd5gP6HzAPZBKJRViDhYK1D0pHX7z39AD6TiyQnR0iRUjlynSjNYaoIflnsESIhPuKG4qEh3IYPTF4yoCM0CAPPLS8BJjo6hDtqOpRVTPQc3LFt8U+ka/GPZVTv0TJy9QEZNnGhdP+oinQu/JEMbfD1fuvvdilX/T97VK5zk0qk9ct/NopynUEkDHHumfB04tx1ricuV2/JtJqfy5g335bL238xIirJEedl8icVZcTLr8mEsmXF5/3CMu2zzySgdGnxevtdGfL3f8r3HdvJ1b075P6t84oI3HLv1BBERZLl3vljcn3XBguBSUgryUb7wu/dj5b7UZdkUqVKMrtRU/lp9kLp/25hCW7aUqIfPDZSiL/tDp1spAiDuvWVjm8XF69m7abpOfK3+kAW0txMfTAPY+hmJsqNFgNdjC2ihUMtAt7sVC6JHQM6ovKQD6pxISS8JxF/1hfLWhPOmkKxCw0IiRQBCiOs+lA+L4CIuOJYNXHJ40ARzs1BdICvKNmtVs2wWqIX5Hnz0meCYOH2m1ueArwv6SJKE3NQpLulXclPpW3hctKjXHXpVryCeJSoIO0/rL5v4Xc/P9Ek9aj0ZYmuH9cy7P1DTpw1UjxOIy5UFVVJIy6/LPvZZT4uRqoo6aFcuxWrFupGMvT5F+TogtnGuT8+d4aMfPUNCfrkE5n40UcyVS3mUz791ADOuVPU/wNKfSDDnntejs6bnnbB3FGwa0RS7hranOSYK4psdVDEq5DMb9JYTnw3V554wUBgUqMkRRG2gA8/lLktWhv+LofDLsmBpd8bLsM3M+gXZXj3JKRKYLuu8k2h0jKqfqvFej78raEaFTq5ORDT0lDQTBSBBZ4qUshWZlVFRDFcHTXnOChYgIRARtD8IWBlHWGNAfnFjkITFw2nVhTB+u0Z+eUn4hI8zOd/Bjdq46WISZJHhRq4m0b3btjOV35bPj2MFgE43JIiik584FTiot5Xmr5aVH6YsdClxOVWfIpEKfKysH0HGfCHP8uReTONc7+2fx/xfq+wQVCshOVZ0IfI571CsqR1S3l8LyJNwOtukZb78RITekCWtv1apletYjR/nFD2I0Ve3pMxb74jm8eOkuizx0USIygzktRbF2SSImvB9RtJ9L0UQ190RzJ3QL4Vn2xc+0kde8g3730gw79svkzPHb8lLkQNcnM44tkFIAzLli2rTb87jp20NREPCgfQ/WFEp6+tJi4aboqDBw++TLooN/LTlDkigDPTn8rZmOc14VXPTz8v49V39F8yicysa/VOaZkx3MepqZxYdZrPX7qOR4zQ8HHh+GkGcXGGfiazJoF31KbyxyHDZNCf/iLbfMfK8SVzxb9EKQn6pKIiKDaIi4W8jH3zbTm3akmaYNedoi648EqqrPLoIgP++FcZX+oDI4I0tXJlhc9kUrkK4v1+EcPDZePwwcbvPowOl8CPPpJZTZpLZOJ9oyO2vaaYRNvmDB4tHd8oKsO+aHJYzxu/9dSCOOQWaUGESprI0XmElA1RZ9I22HMgC0Cv42xdi4YmLhouCFeS6oJAYBCIKC2nmnvR5mH16tUV3O2c9KxS738UriCe/Xn+8rReQtk0nktfDn3q1HlRry/N3yghUweOMb7HAumSqAsW9+r49y7/UUa9/IosafOVLGzeTHyLljAWd3vEZVqlSuL11jvys6eHyOOENJ8UdyEu92PkfsRZmfVlbaO30q/HXikNlSpLkPrqVaiIUf78+N51eRB5UXwKF5EFHb6R2/cfG/2a7BE/ojLfT5gm7V8pJMO/aHJazxtPA40a/k1UCubEsPpLQVhwbcXPSze21cRFowCCEnLKyQmfWkRjy3E1xouBUCpW2HzFGVHtSJ54MaSHIwMvA1TwuO2627nw/KxulS7lqhvpnNOnL0n8w8dOIxIsgnu37ZVOpSsLFUvTBo+Vu64kLpAl9Z5HNm4Vr7ffkQXNmsqqHh4y7oMyvy7wmZCXqRYEli4jwZ99JqnXT6f1EXKXNJE8kPOrvxfvQu+n6XKeJS4WTKrwiSJqxSXxYohEHtklA/7wJ1k5bGRaA0YTkS4iYusXfS8dXissw2o3PjNnlP9/6TnjaaD3Y75wtG+N1fcpPaiioZwXc1HmHUBZL8JVKjYDAwNnYeSmvlcUY1N3devW0MRFIweBwI3KKlTrmOghHrOCSitK7rDghnhYwWSiJpUwygzxSLAaUG3YsMFo88BkxC4JzxgiO/y92d5UuUBcfDGrG/1VV4lJfmQ3neAISDttX7tZ6FRNB+EVMxc6rWLJFnE5vm23+JcoKVMqV5ZZX35hRCCCTBKXKYoUeL/7npxavsAgC26RLjKaPCbJgeCJ4v3e+8YxPn38v362oIqfite778uJxXPkys4N0v///iQbg6YZkShT7sPq9/Zs2CYeRcrKwM++vBfYsafWP2SSdqZK8PTp00+ed+szj34EMzrrvIBJ3YQJE+4psrOZjZJ1HuHftBiBlGC5z5xDGwBSOFQDscEiSuyKPkIamrhoFICmZxAcK9j1kGOmugo1vhVEcUgH0aMDm29Ky8mJu7IDqxOIy170LfN8JjnNv+UpF9afN0mbIuWlbdEKsm3dFpeWQxvuuQ8ey6VL12Rq9Roy/oPSMlkt5JCWoGciE5mSl0qVxOfdQrKmT095lHJb5O7N3CcuKVHyMOaSzKlXV/yLlcjg2NMRFyqkSpeVuQ0byo8eXWX0a2/IgZ/XGYTOlKAa08Bjp6Rf+SrSp1zVR0E9BhXWc0DGIAKS/nm3PvOUTENArPMCGyLSO1TQpJ9HgCYlGpq4aLhNFCcvTEqKtPyjR6U6CRjV7Vi/LS0a4iR9izXtsGruEmnxVinpVqGWHD96ymml1plWFt27r5Aq81p/JX5FispkYzGvnAF5yTzqMvHDDxU+kuijO9PKj3ObuCSnEZe5DerZJy7pMA4tTJUqcvH8ZUXoxGTbhEdy5XqUjPyyiXQt8qHMHDi6ln6m7T/vREY0EdHQxEVDw/XEpW2HDyrL4Pqt5WpErNHrx5kkAqHvDzPmS+OXC8uAOi0k/Gqk3E557FLiggD19kORJR49xPu992Rypc+eWsxtERcreZlcvoLh63Jp/SoxnGndoqIoQdYN7Ctj33ong7Lup4kLZnt0wR5fsqTMbtJUIuJTFJl7YLqknJLoCR08pONbJWR6nyGN9bOioaGJi4aGuxCX72h+OLnPMKFjVUamZNlNFc3xnih1n3tTvNr1kKh7qRLpRA1Nhrh9z9Bz/DJ+gox54y0j4jL5mUiEvajLpI8+kqCPP5boo7vcI+JiiHNT5crWteJfvIRMrvBxplGXIEuECV3P2Lfeki0zZlvSRPdMlpQnGOfv28Gjpe0r78v4dh59nHnPee04U1ihs8J7+hnU0NDERUPDEdLynwqR2Pz/vPAHpxvDRcQmSPyjxzKx11D54s+vypSBY4wFkYXRpcRFgfc5uHaD+BQqbBiwOU5cyhmIPLjdiHS4hzg3QUK+m5tGXD62Q1ysIl1FXA6tWW9c2+tRcQ4RzhVBs+TrF9+Wce27T3cSYamscFRBLNip8Ff9LGpoaOKioWGWuFTuWqGmdP+0toSePCf3HjmXuEQl3Dea9o1q2VnqP/+OLBg/1aWdoZ8yvnsscubEKQksX0EmKALiSNTFakTn/c57sivAR4zu0hCHXCcuifLLoH4y+o23nmpZkClxUfB9v7DMa/WVRCc/kKjE+6b1S1ynLSvWSoc3i9EhepcTSMt/KJxKR1qsWKqfRQ0NTVw0NMwSF3/KlEe3/kZuJz+UW3dTnVvdk/JILt+IlkF1W0mjlwrLmsUr0sztcoC4RCY+VIt0nMxq2Fj8iFA4SlwUxrz+pmweNTStJNodvFwkSSIPbpMJZT6USeXL2yUuUz+rIpM+rijD//mCkS6izPl6tLnzR9rw8J7D4lG8vPSr/MX1NQuW/3s2icvLGZAW8IN+FjU0NHHR0DDpmFv3FKZwiyfMcHoZtJGueSxy4niYfPNRNaMcet/2fS4vhX6i04hNlNhHIkt79DLErFbi4gh5GV+ipHzXqqWk3Lwgkhqd+8RFHcOj2+Eyr0F9GYdHjR3iElD2Q1naoZ3hZeNfuqxcuR4pt+8/MhV1iVPnLuzUeen7SU3p8WGVR/PHjH8/m8Tli0yIy1T9LGpoaOKioWEm2lKma4Va0qVcDTl16oKxw77uxDJoayn0L8t+kmavFxf1fnL23GWJe/g4R4iLVeeyMShYxr79rkz6tLLDIt1JH34ok8qVl9iT+9UrxWdNUHvvpsiD20Y3Z+M1+ErzRro3373h2Oupv713/rgEV6tmuPvaK4ce804hOfRtsByYOVV6/sf/k43TZpo2oaPyK/xalAyt2VDav/uBfDvSr0YWCcurCp0UHmZCXL7Uz6OGhiYuGhpmiMtkoiBebburReqhUQLr3IhHgqGTmDnST+r89XXx6dhTYlzwPvYcdA/9sll8CheViZ9UcjjqEvhBaZlRs4YkXDqpyEesebJiVADx7o8M47j4SyESe/qwRB7bK7dPH5H7UZcs3ZtvG5VCIjT8TDF+98nfZ/Ta6veTw08axCVAHZs9Ye7ot9+T0z9+J6nq/Ya+9KrMatZCohUhiTBxDbh+tGb4dqi3tH65kIzr1HNoFkhLLYU7mRAWK17Tz6OGhiYuGhr2SMu/9axSLxZTuO9nLDCWTWdHWyLvpkpM0gNFjDzkS0Vcvh0baOkK7eKKIj4HiIozPGmuXImQKTVqiX+p0g5HXUjHLG7eVFJuXVCkItocaTH8Vh7LnXPH5Kfhg+Tb5k1kWtWqMqliRQn48COZUOFj+bZBPZnXoqnMa9NKlvfuLut9R8u5TT/JQ0OAixD4yq/kxUpkYsLTGj4mR8nPPbuLz/tFbEZbcAse8+77cnBGkDDmtWguw998R04dCTGEy/bOI/cD12vn2i3y9RvFZGjd5juzIMa9boe0gPMKgQratE1DQxMXjdxAbGzsv9NIkb5HVtAa4M6dO//uRsSlSbePSRNVk5MhZ51eTWSkaR6hbzklNG/8qnA52bVxp0v1LTcVomPvSQSkJTJObkbeMf5NauSHAYNlzFvvKOLyWYZRl8yIi9fb78qGoQPTDOjMVBVBOCRFTq7+QbyKl5DZJcvIgZZfy+U+A+Rir35yvldfOd+zr5zr1lOOfN1e1n9ZX1ZWqSGLPq4kgYokjfu4gpzdvDpNDHw7/FfCAqItUHRizwQ/o7LIVjWRlbjsnuBvEJfdQROk1//9RXYu+d5ICz57/q4poofpHLhmKZsmYraDPlPvlJQBNRvecpC4/JvC1yaIixX7FErlpWc9Li7u37H8p6cQHaN51q1fo6Ki/hMXXT0namjiopFrwM4bAnL16tX/oe/I1q1biyxZsqTeokWLGoKFCxc2njFjRm9vb++DNFOj/bwVgYGB8XSfpo+RWxCXKvW2f1XoI8NfJUHtviPikp1OJEiArP3uR2n8chHpXb2BnLtwTe48EJdEWK4rohJ1WxGXmDhJiL8nkVF35EbEbbkZEWMs0kfXbRKvQu/LxE8+NRF1SSMwlBsj6t0wqJ/iEXcUKblmu9nibYXHCXLr6G4Z/PIrsql+Q5GZc0WmzpDHE6bI44lTRCZNFZk4Ne3fk4NFpkxXmGH8+56Pv2z8or74vF9YLm37ReThXQtZuSRCainyoiIwlw2B7srOHWT4S6/I1MqVMyYulSob0R3fkqXl9pFdBnE5t+YH6fOX52SDes9nicv1qHgjXXjpSoSEX7slt1MfGZ4vserr2XNXZGDNhtKhaHmZ6DGgchbSRX0dIC+JCm/llQ3KihUrqqrnOoZGq0FBQUnA+szTOTogIGD+vHnzWlvnCMDf0JwxPDz8d5Acehfp+VVDExcNp+LWrVv/tX379kLjxo1bogjIXTX5PFy3bt1jtcsyusDS1t6K5ORko019RiMmJkboJk3DtVyOtrzrWaWu0Tto3dJVLkkTUXJL2fO3YwKMNNHIFp3k1t1kibyX6vy0kFp04+PuSciFm9JvwW5Ze+C8JN6Jl1uKtNy8Hi3RtxWRUSRmRr0G4lO0eKZRl2cjLxPoVVSunMQqIiKP4hV5uJhGJGLCM9ahGCmiFFnu2U1mf1BGZNosuT9+oiIk4yTBd7wkKiT5B0qiX4Dxf+v3Eizfl8nTRJb9KItLl5NFndulRV2iLYSFVFXEOYXzBomJObFPlrdvYxjRZdijSBGX4a+9JZuGD1FEJyYtCrR0vvT8w1/kZ99xaQLddGXRN+8kGmRm7qCREtTZ00gRQWSux9wzvj9j8Bhp/MI74t/O49ssCnQvO0Bemrn7nEAkZc2aNR8uXbr00cOHDzN83h8/fmx0ik5MTHxqjoiOjpZDhw7JsmXLHkF41JxwSX3tEBIS8hyNW/Wcq6GJSwGNilh3M9lNzxAhUTunvceOHTMmoeyOsLAwoYV9fHz8v+VetKVuYMcPKknv6g0l/HqU2l3b7k10TRGDqxaY9295qP7ujgys29IwnpvrPTFjV15FPBCBOlyGnU7HEhkdJ3fj7srk1cfkc5+10ihwg+w+dkkexN6RiKsREnH5hkGitk+fJSPfeNPoW2Sg4qcy8ZOK6uvTxGVa5c8UYSkv/f74F1nTu4cYdv9RFvJgkJdLFvIS/jR5oUooJVpmNG4oO5u2EJk6U+56+0uy/4QnkZVHE4KMiIsRZQmangZ+NmmaPAgMkrBvuov3S6/K3umT0tJTkRfSyMpNRVpunBW5dkbkyilDzHtt/SrxLlTEsP5HiItfyxRs/tVnGvVOIZlatZo84G+SIg1R7+VNq6Xv8/+S74eOSGvtYDmHkFb8XY4fOC493i0hHV56R36YPNM4Z6mW+/YXRXBbvl5MBnze5HAWSMuLClccIC5vuvs8c/bs2T8qwnHZGXMCBEfNU8KGiOgMG6XsHBvkRzd51MRFI5fBQxgTE/MftIS/cOHC/4Hz58//Qe1aXlK7ltrBwcEDpk6dOnzKlCmj/P39V4wbNy6W3Yz6fgqkY8GCBc0hII6ShStXrvzOz89vjSJC4qyRmppK1OU4OfBcirb8xbNKvZSWb38g302aaSxM120QBMhK5J0ESUp9ILH3kuVK5K+W8dctpCYzu/id63cIPZAwuNu/88BviAupiFvxycaiGZ30QK45EvWxkBZ0LFHRdyQmKlaGfbdPWgdtkhaTN8mIJfvkzvVbcvvqTbl16ZrE836nzsuEipVlXOmyEvRZVfErVcYQuPqXKStTFVkhSsHC71eshAR++JH8+E1HidyzOW3hhwBAHm6dT4uAkLpJH32xeKyk3DwrQdWryeG2HRUpCZbkcRPkru942fl1W1lRpYYsqFBRllaqKus+ryM/VftcVteoLWtqfSGL1XFNKVFafMuUka2TxhkCXCMtlJ6wXA1LIy3hoUaJ9a2ta2W8OvZRb70rXoWLybgPyohfiVLio44fQha9e1Na2TW//+iOXFHEpdc/XpC1iiBxzjl3xjlUxJHrtWDoGPF4W5GTj6tJl/fLSHDf4bJ303Y5uvegTO41RNoVKSd9qtU/mgXi0j0TghKtEJHu/7cUpij80d3nJCKwa9eufSxOHBCYFStWPCaS4+jxoKkjda3mQC/mrMDAwOCVK1dWhmDpNUQTFw0XRUkgCZCL3bt3v7l48eKGkyZNCuThAwEBAXPUYh8yffr0VEKzAGKybds2UQ+sJCUlGSkawA6ICcA6CONGRUWJ2sk8gMBERkaa3s3s2bPnjfnz5z9I/3rZHRyP+iwXrl279t+5RFz6fPNRden+6Rdy4fJNiX8omZqRQUoibt+TR+k+PiTmsiIvEBrj57H3nkRjbt5+ugx6xnBfqf+Pt2VYk3bG9yAnT15bvQZOvZCZRRNmyM4NOyT+gTljtCekJeqO3LwVK7GKuFy9FiV95u2SdtO2SNdZ2+XrqVvk+PEL8vBmhOIaVyTyXLgk302RjX4BMuKNt2R8uQqyrm9vCd+yTpa3bSMD/vmSeBcpLiMVCQhQxObc8oUW35araQv/tdOK4Z1JIxJEQH4TfVEk42Gs3Lt4XCZX+lROe3impX6Cpsvhjt+I18flZYlnF/nFa4RsmzJevu/bQ5Z6dpPlvTzkh3495RfvEXJowUyJv3AirSya9+X9AO9tJSyUZfM74Sfl8fnjEr1jvWwZOkgOKbIT+m2wUbG022e0JJxV/CJKHdfFk2l/c/+2bBo7Urr/+R+y9/tVacTl1m25ocC/Tx49JQPKVhTPImWk38fVZeBnX0qnQqWlzVslpM07H0ib98pI909qyQSPfi2zQFyWZEBaEhReUPiHpaKon8If8sqctXnz5uLMP84epJNJSbNRM3ssJ06c+LvaoG09cOCAkYp68OCBpKSkyKVLl0SRmKgdO3a8q9cZTVw0nEhYICtEStCOMBGEhoYaOWAePEiIFZnpRswO/l4RoofsSswe36pVqyop8uLUiclCXC4h8M0F0vLfPavWj0LbMmXg6LTSZBudoCEj0XGJT59HReIgK7cUiMLA6RJT7huExhp9oftzRFyS0Uag7t/fkoXjpxqRHWtnYipWEtMSIUaJdPX/fl5mDPPG8cS+Hb1F03LTiLbEys2I2xIZESPxUTEy8acj0jJos3jM3iEtgrbIT1tD1Ae8LlFnLkrkqfNy70aU3Dx6UgI/+VSGvPJ6mv5Djaita2V1926ypFVL2Tyov8Qd2qE4yw2Ry6fSSMLFkLR/E/Eg8nHdGn258LTu5cFtuXvhmEypXEku9OprpH8gLnuatJRZTRqmlTkbn5L0QpLlDFiRnJaYQY9yy5Iaum6JsvDeVsKiyIpASsIOi5w79mv0B+HwjXOSfHBH2vHh8svfnD5ivN6Ds8fE75NKMqJ4aTmvzkFc4oO0c6cI5T11Dad18ZQO/3pTfJu1leGfN5Je5arKwOr1I8a27HhkWP2W4UPqtdo0rnPvBlnUt+zPgLicy8tz16ZNm0rs3LnT6cSFuU7ND+fMzg9EbiE6mUWF2cwpUnODYgK95mjiku9TM+RZudlPnjz5N0Um/opwjEWflIxi8T8TBSEUeerUqb9S9peVMkLU9eR1Ea/lxODhnjhxYpAZFT/ngAoA9bmdegxMJGpi2k9oNxeIS2NKoDuW/kyOHjppLJe2RLnXLGmi35DADCJQyYrEWNNIMUkP5WpErAyq10rq//Nd2bp6UxpBUIQmNvWxsXTfuhMvUwaMlsYvFzZSSX1rNZErN6Il7sFj20LhdCkiIgY3byLAjZKHsbGy4/D5J8Sl84zt8vW0rbJvT6g8unhRok6ekagTYfLw9j3ZHjBRhrz6mgx/5305822wEY0wCADRiVsXDQJgEAQIy5mjaf++EJJGBIh8XD39DHmxpI2SIuWBIjJTatSQE526ikyZaWhZNtdrJHNat1CsNU4Ue/q1YaIV/D8m/FchLhEdIz10+lfScv5EGlE5YyEtpw6JhB4UCdmfRmQAxwuxClHfX7VchGoi/iYlWk4tmiPf/N9fZJFnH7mXcF9uqfN2Q5036NKhzTul6xuFxbPYR3LhwhVD39L29SLS97MvD3DfbFuz0ZROTJ33rgrLu87a8dTmwGv7mTUZEJdeeXmO3LVr19ukdZw9R7HBIkpCKtzMcZAuJyVu6zXZDBLF1mubJi75zneEShdyq5MnT/b39fXd4O/vf3vz5s2CKBWcOHFC1C7AiISQOiFyEBkZKWrn8ZhKGcKRjmhIDh8+/CKlg9mNpDgyIEjqWHeZ1Zds2LChFJ/PmcdAVGn58uW1coG0/EfPKvVOtny7tAT1HZEWbbmTaLcyCB3Lg4f2rxHRl6sW4nIrLknu3H8svp16Sb1/vC1B/UfJ1ZtRxvfDr0UqIrNRkZrW0vCF96RdyU+NtFUrdVyzRo0zIjOklWwRF4O0WKItEYrsRKjXvHcrSs6fvizdFWnpNH2b9Ph2hzQN2iIjFu6W1DNnJf5kmEQfD5W7Zy7KvfOXZVb9hjLghZdkStVqknpsbxoBgSCcOZJGClj0j+5Ji3IY0Q0LgeF3IBOQCshFhEXzAukwmiCmyjLPrjKjeKm0Uug5i2Re2XLy8/BBxNvU71zO2LQO4gIB4jis0ZYrYUZKyDiGs8fSoidhFsJyUnGKkANpRGb7ehFvL5Hv5qcd02L1teXXItOC0loKKLI1vko16fXiqxK6ebskJT+Sm1ciJEad5zuJqTKhZXtp9cd/ytxhXsa1PHYwRLoWryA9/n/2vgMsqnPd+jc3+XNz89+cnJOTk3NMYmKKRhN77wV7w16xV6zYsWOjqdgQsGBDVGzYG4KIShuK9N577728/7f2zCggzOyBGQTZ+3nWAyLM7NmzZ39rr3e96+09lJZ27jdUDlkZzWDLcIahGKSR4WzF39F1CFKvQlpsGf67MV8zUdrGtYRd85R6jcL1FXEKaDDgsx+4mbx37165vPITSu8fsiFAUaCxwsPD49+2trbt8BrZGvQdVCjBdNzIiQvIBpQDlFvq8jgIToKKcurUqSJGXrgaKUiJIr4OfNjw92xR5jWEDa2E8Jugw6Y+N4na8QYXHT77iQ8OSljKIlc4vlCq+D6/konL9FX9R9P8DjDKijjiwqcFOpKRhMzcQrmvLSUrj6IloWXoEIKag0Teif9uTRqtu9HaoZNIZ9ZS2jx2Bs1u3Z3G/r0lrRwwml49sad981aQRquutKzHEPLzDRYrQcmZNXYSidWWdE5tSYhLpoToREqJiqPs6FjStXIiDWNbkiygjLzY0cOnjHgEMuLi7k0pIk8qjU2i4Nv3yKBrN9r8/U/0aJs2kYsD0UFDIufnYpVCV5dIR4et4q/FhAWkAeQBJEKqvMQEVikZMeJRlkOJjPBs+/kXejR8DDlPnUU7f/iZol89FZeHqst/kYbLcZ1LkjKRVG2BioLn5wgVex2+jKxgbpKXE9EbhnD2/zevEC1YTLRps/jnN68SwRxseoIjRXc2rqdF//M13dyyk4pyiygpMo4SIuPRbE3Pr9ykxd//Sht7DubmSOWyUz2jqJQOLdWiBW260YahE17JIS5Lpce6ArxXnH7nqzB0Dv2OEZVUhkCGeQz/+BgWECcnp5/QCACPnbK2iIgIwvUYirSybq5ArpAn05ACMGWtayjDwQf4+PHjcqhFAOInUGLH//E9NgJx+UAAQ0YHjbOzcwtIkwDYp5mZ2Ua04iH4CKFmOHnxe4o+fkpKyqfwlyiDQEjUDFc+plM8Lz5I7ASsV+KCzBU47vkadGGQO3PmjCYUp7p2C8A4d4RtaNP+EOfS2iETQuFtOaC5gSMG6Obh072DchGUl+KS6skbykYcaUmqTDSSsvIpky2AlofNSLPnMJr+cweOxEz7qR0t6NiPDJatozeefmIV6r4tIzfdaUbLDnRoxUaOVCVh/6oSqyplogQQF0ZCEqMSKCkilsrj4+n8Q3eadNiGU1ygvsw8YUdbL76kAm8fyvP0olRXT0oTebADkEoPtbfRVpSMuvYg70VLiDawhf+0GZHbS6Jt24mWahLduir2mUCFkfpKOHOsr/jnVVWX1HCOoEQ8f0inJ40n07GjyfPKBfFgxeyYmtWWt3ktFcpEeA6UqDi1xU1SGmLExctZTFpAqvAzV0a6du1iZGURkdUl8f7t309kdoKe6uygRX/7lvQGDKGUoHDKBfELiaSc7EKKi4qnXWqjafbfvydLXSOu/Tk2LZf7anf3Cc1v3ZXWDhpHa9XU+8ohL4YV1BYpSpaffD5N+jt6r4N/YITl849pAcENGMgLgubYgquUjkN2XcyCGq1Iyer69esy76ygjKPzsjGk+OL1MOJWUF2bOY4PW68KHB0dWwrEpZ4ICNQRAIsh/A3wjeBNQlsdAL8ITFZs8Y/CB0FfXz8BaatgnbGxsZzcB6DfHwpHRbMnzKw4eU1MTLahZZjvfkFRQMKjMrpm8Bh4LLwuec8L/wwjENZQd+pzQ7kLSo8iKhUk2ytXrqjjggICA7IFBQbA+4DyGcKkGLnkADOvJFTKlf3NJQDvC95rRToFlKy2zNPsPZyWdB1Mnm6+nC00VoFMlmgJeckvLCHpmVLCXn9OfhHXSRRVjToCAy48LSBJgUER9PyeDd29eI0LvPMUeVNGsdiOmsQWUIwGMFiyjmb+2plms8XyyY37KKq8b9R9j7ikSIhLPCWEx1BRTCz5eATS0pPPaclJ+3eqi7Ed3bzPFnxfb0pz9aA0F3fK9Q2kDLc3ZDJiFG399XfS69mL4rW0iA4eIHKxJzI+RjR3IdHZU2LVAwQB5CWwQskIqgvXaRQizlsB+QC4AYvsKBensi+JYtMtwulAUPgSl2gpcZF4W/xqIC5ur8RqzMPbRJu1GdGyEs9UcnlB96ZMp6Xffk86XXtSuIMTFaRmUSIjLynseLG3ki5u0aF5/2xBWwaMpIjIeMosEatwKbnFlFZQRHtmLKQFf/aktUPUXXn4W25Xo7wcaQoLCSL/4deTdEByn3ncUMIUizKO9NoA4FoBVQXXDlxDsBjHxcVxigL7fQck6ipCMOBDxJohK08Ga4ODg0Orhn4ccUMLqwLWO1kkjB3n06pKG8ZaLU1Fh/LFjm0grBD4HmoPqgpYr3E9h/8T64N0bYdaVNcKSL0RF7xQeCZw8qItDS8OJAQnMrwMp06d0kKWCIgITFcAyg84UdGuFhMTwwEtu1VbeRXdIKmhj5+vogClxtbWVmnEAEZbFxeXFvKeFwFJiMaXdYIqe0PbNMpE/v7+f6/NnRUIIe6uYNiVtmjjLgbvNwgguqMAmJihfknLeMCHvNNhpOUzLbXxiSAF6OABIYirxZBDZKxI25+TM/O4chDMuDEyCBAWQfweYv4L6B1yOcJSwJWDQKDw79CwGIJxeNZvnWnVgNEUGZPA/TymIimqSlwk/hYQF2S1JAYzEhAdRcdvudCUo884xQVYxEjMAjN7Cn7lTmWMfKYy4pLqJKKSsCiKeWpHB3r2pk2/taLDPftQxv59YtJg+5Bo4yYiKwsxeYCnBMQBJSMQCZCZt8Slgkm3Yq4LAukwAVrefCNpqag64oLnCZb4W0CcfCoSF0exD8dDoryAUKVHU8wDazqloUFLmregPd37UPjzV1SWlU9JASGUwIhLCXs/3B7b0ao/u9Cin/6gOyZnxXk+KZVTj59jRlHbHrR6wBjSGqyuJoe4OEvIShmDBcNBhn81pTth6ecdwDUON6jwDmJdkALXCPg2cP3DNQQLIryFWARrEzwnbXJAPERV8gJiBKUXqnptGijqG7jG7t+/373ijXkNXZlRqlCuUS2Awo4bT6zNqCJgPQbwPdYQ6XqN1HS2fpZjLZeu62y/IiA+YPQL3hPgzp07/RHxgTwdWASU8T7UmR2CdeHkYzudCo/H7du3y/38/AgLMgAmDQlRSkgqQhUbTtQjR47kYiHl0zUDJQEqhLI25KzwncUD5soIXrmqiAqOOUpDUEmglqC8hg4oZXRc4WIBNIZ4bkZcdi7vPYKWdBtMfn6hHBmoS7y/OEU3U7GwOB7jAaB1379iTTAPz/ylIxmt3MSpNUk5he9KRjJKRYkRsWzNj6TSyCh6YPuGNE7Y0fLT4jv/VeYvaMrx53TEii3wPl6UIfLglBcQGPaA5HPpCu39qz1p/9qKjEeMonyRg5hEoLUYpACdO7UhLnxRrcclsEJHUYUW6LfGXPhcJMQl+A03J6mA/f+z/btp6x/tacH/fE0nZ8yhBHcvKk7JpGS/YEoMDKNMdtzSk9LpwJQ5NONv/yGDWYsou7icUrIrl+akwYC681fSbHiUhkwIkkNcXCTE5Z7Q8MCP5CjrGoK1CNdTNFWgzILrKvKnoBbgGv8hohdqA0kacRRyaGQp+6hEKONaXvX9wLHCjbwi63PFNR3rLwgOulelHACKPJQ23NSjIoE8svPnz8+qzQ10nYkL2B48GmCzkPpURURqs4E88c0qefr0aUdlKS442WCe4luqgsQGz0dwcLBCJwkYtxRg5iEhIQQ5VhpMJ/3AIlYfbBcKEJh0fUh4DZC0fM0WnJJpP7WnkzsNuPSQuPQ8lU1nrj1xyaJkRlCwUBosXc8RF43fO9Oz248rZ7tUIi4Sc25sMiVIiEtSaDTlR0QxXhHIhdBVLBctZt8vPmVPIY6MdPiITbppDOlujLgnpJKXxWXa264DbfrxZzo9Tp1y4XOBz0RamqlaKgqrUCpKqFAqqg1xqdRVFCaeSQTVhesqqlAuCqxAXtBdBFUmPZoKvZzIxeQ4HRykRvP/+39pV+ce9ET/EOXFJFARIylJjLQkIcuGHR9cqe4eMaW537Ukra79ydPRXVw6TBKT0beqCzvOuO99+fQFzWvbg1b2H00weMsgLr9J2qG/FojJhzO24q4eBABrFErTjakLR9Kp5cpDcYlUxBLBt9wHxUQWaVLGJh3vgBZ2tm71qg1xrTW7RTkGUlFD3F6+fEkoVfF5LcgAgEqiDOIFZzueV5EPClreENkPBznqsJDn4CFB9400sh/7h68wIkOGwzAy+FQA/C1kOGQe4KQHcHeB90i4kHEToHchs0VLbTyFhsdSdmm50ocpKgsoCWF+TmRMIi3vPZwjL6v6Did/vxBuYX1bMqrYVZQg6Spif5MYGceVi9LCoigvPIKMrjvRNJSLzN+pLhomz2nLBQfK8mKkIzqW8kIiKd3Tl9I8fKg8MY3cz14kQ8wo+v5nurFoIZVzAW5u70iLVG2Rac6tA3FJkZKXCqqLNDE3TBI+h+8RNsd+N0PkQK+OHSIjtaG08Iu/0cbf2tDNzdsoyklEZRm5lInyGSMtyUHhlBAYTqXF5eRt70gbug2gmd+0IKtDJ7jOopjEDO74IiWZa4GXnCMIEUQJ6YT2HprVqivOoyDhcyVAVUAZBWV4WSNWUMGAf0jZ13hUKc6cOVNcX+s01BmUpGrjPar1C1SWoVUVG9QH1FAVUD2O15aEgf1CCoPT+8qVK+NrU7+D/wO1YNR4oQCBjEAxgpQGVi0FSA7uKIQ+ft5qS0utweNpxq+d6fbZK9ydttxU2g+tvDBgoXz17BXN/6sXTWn+B22foEGZRSVi42iypB1aqrokpElUlyRumCJUl/jQaLbox5GvyJ80jO1I89Q71QV+l0nH7ejiPRElPn1Kkc/sGcmJppL4FCpLyeDOaTtDI9L+qSUjMH0p96WNWNWAygG1I7imduiQdyF0ipKWak26oWLDLzcfKUhMijBzKD+RymMDKdjaii5rLqMD3bvTtm//RVtb/0lX126ikOcvqYQRljxG6JIDQsUqS3Ak270Iyk3P5cjd7pETafrffyCjeZpUkF/AEReoWFm5BVyHGFKQuU6y1CzueIM0ensF0oIO/WhFn5FQXTSEz5cAVQElLyzo1UVQYL3B/6lihAEIhCqtC9VtIGggaoo2bdTqBWJxVXYomTJZ3OHDh3MQ1qNIXRHkBSUmdCdVHNGOx0MGAIzDcHPDnIR6HYLjINchQffGjRtDUW9s6r31DVBtObu46yBaN3QiRbOFLKOorEGTloqTonHJun3Oiub80YOmtfiLzu4z4hbY5NxCrqRRNTn3reoSFc/W/1gKDIykmPAYuvrQjaYfsaGV5u86XZZYutPKgzdpf9fuXAS+xbKV9PqkOXldtyY7o2N0asoM2tzydzJTH0+l0rTcIGl6rpfsALrUOhIXpOjmsrvNcsQEZDPkiDuT2ONH2T2gB7t3kumEibTvt99o57ff0t4+A2nFvE1068Yzorx8KsvMpcLwSE5hgVE5KTSKEhnS2PHBMTVfv42mf/09begzlLJS0yrJ1xW3lKz8tynICCnM41SXvWLVZciEZEZevhA+YwJUASziMCvDNwq/KBR4AN8jFBX/hxtYZT8v1kz4VOtzvUZJbP/+/b6Klr1q1bePhRreloa4oasILnVFlQ+cLHC8wxMiGWgYLsmJuYbXCwUHABtGeQklGfyNQFYarNrSXEttfAlyW64ePyNuLW7opKWC3wUZLlhKzfcacUMaNdjruHL0JPc6kA8TC9JSLXlJooL4RLrlEUY6L4Po3OtAWnbKnjTN7N6RFwtX9m9b2jmCEYD2HWnLnx1pe7tOtLNDF9rSui3psK9GQ4ZTqiO8X4XiCc0VY/i5jJWgCqQltPpJ0TUBSbYAOo4KkyUEBQo1e3XlGVTCHivOyY4C7liR1zULurlhHZkwErXpx19I84uvaCfbx32T5pD25sO08qQtTbnkQ7Y+6FxK4YjKK+9wigqNZrsSS4nhsZTEjgmO232zc7Tk1/Y076e29OTSTZnXkdyC4rfEBV4XqC5+/mEEIry8zwioLoeFz5kAVXcYwQaAzlysQfgePhRVKe4Sf403PKv1tcFPg+gTRSd41+oFooyBVuaGpLJAckJ9Dq1cdU1lRXs36oeAQEwaLXHZwU2A7j+aQsLjuAnQDdXbUi15YYtlZkkZJWdk0545y2lai/Y0p3U3enT1NkdoEtJzxeSlQvS/lLzkJqSQY0A0bbDxo12vQmifrR8tP/X8HXk5/ZyWWgfTxq3GZNCxIxkMGUW7uvaiTb+1YeSlK+1o34UsFiygwJuXKeTONUp69YxyvJ2pDEZZkBgQDoTJcY4cAHoElvYCMdF5i6IqKBZ/LU1jf5/OkZYSRnaSPB0p2OYeeVpdpGurV5HpxEmk16c/bWvVllb97ze06m//pO1tO5DJzLnkd/UyPbpvT3POONHiG4G09KIrzTd+RgE+YZQSn0SHXwXTZtsACguLpczYBK58BqXF6YENLW3diTT+/Rud1t7NDVUsLC6t8ZqSkVPAZfdI3w8M4sQrMN93iEs4ZqS4jJ1j3wqfNQEfC0CI7t271+fBgwfl9WUDQZI72r/5hLbWmbigLAIZq2JJRdmuY2nAGYA4abRVId0WgGQGA66kXBNoaGh4E4wUoTmNaRaFANWBLSyuiNk/uUOPW1LjG2AnkdzQuyTxnX5KbgGtHzGZJjdvQwva9SGHxy8kQxrzuLLR2ynREuUlLzmNRMGxtOWZP+17EUiGzqG07a4nLTO14wgMVJfllu60+sgd2tdPjXZ16k4XtTbSLZ39dGziNDo4fDTpDxhKm1u140jM/j4D6MDgIWQ6eQpdXLiQkYuV9Hj3Tnp+QI/sGB7v200uZ0w5ODF4Xr1I7pfM6bXZcbI7ZEAvjQ/TM4N99GS/DvtdHbJcsoguL11M5+bMJiO1IbSjdVta/+1/aMV/f0Vr/v4d6bTvTPu696ZDbD9u7NpLr67fphC/YMorLOGoj5FtKGmYwLdjT/NNbGnvFUeOqBkw0rLooQ+ZOYdQRnwyp7SgvObj7EnregyiGf/8mXTGz6LUrDxKK2A3O2nZ1Q7LzCkoosgqKcggvZzXxdOfFnUaQCv6jYLqslT4rAn4mID8Myg8yGZBgwiIhSpn6cFbiiwwRUcx1FqRgIEUibaK9ntXJCTIGAEJcXJy4oAR6aixQa5CPz6AeHp0MIEJIjMGchmAcg1CzlASUkW9T0CjVlv+s2rAmMKFbIFxcXARx7g3IrWlamYM9t/XJ5CW9hxKU39qTws69CWHR3Y1lI3SKS05nSJiksnQIYi22fqTrkMgGTiF0o6HXqTJyMsKmHXPvqTll9xp+7TFtOHfzem2vhH3GU1LzqCowDA6t2wV6XTtRfv7DSZdhh3tOtPqf31P65r/zGWkbGPY/MsftOaf39Oab5rTxha/kTb79/bW7Whn2w6044+/2PdibPutLa39x78YvqN1335Pm39iv/vz77SzTTsyHMgI0XQNMl+0jG7u0SXnu/fp0tqNtPrv/6Kb+wy5fYKek86p1+V0xd6fxhk8pFXmDmK/zglb0rvnQbqOobSFvdYddv70OiiWchl5w+U22DeYNvYbTjP/9Sut6zeCAn2DJK3PGVwpKDkzl4pL3t2A5RUUv01JrvpeoMMIyt2h1do0p21PqC4vhc+bgI8NWN+Dg4P/F15WrL16enrPEB6LSeDStRrA2g3/Z8U1XRE+gPUfycqwaNRLV5G0bQt+ENSnMO1XampF6BnUEbww/BxAWQkBaOzFP0I7ryQS+oK5ufkSuKPRpQTAHIS2XpRowMAAlGqaYv7Ix4j6Ss9lxKWvZq/htGaQOgUERVAW+yw1RtJSMZwOSoOXpy8t6z2cJrf4i+b+2ZPuXbzGlY1S80u4hVhq2I1j5KUoI4scguJo3RNf2mcfSPsZeTngEkZbbrnREuNntPK0PWne8KON6w1p2++tyWDsZEpOEncVvbp2m7Z26EZ7+g6mPb0HkO7AoeT6wIZenLtIxyZNoy2/t2Xk5S86Pn4S3di0kU5pzKFDQ4bTvm69OYJzYPBQ2tWuI+kw7OvWk07PX0xejq7k8eI1uT9/RV5ObuTj7M6pKNFxyZSUU0QpheVcKQaWXOMZc2n1t83p8ekL4mGTKZmUm5tPfhFJ3CiDRSZ2b43GIGJb7nqSHiMum2386PCrIEpNyeCOS3AAI2sjJ9O0v7cgrd5DyZ+RlmKurTyrEjFEdktyRh6lZOZJ5lJl1eg9Aol8bfeKFnUWT/Rm59pvwmdbnF4LuR/Jt0LX48cVEoh1GB2tqLRI12oAXUjnzp2bD08o1nXJuJ43sGw8e/aMEyIAb2/vtwRHmjtmaWlZCv8o37BWpRGXitISXhCczohwBhmBgRUxzyAhUEUwfRltx2ByFSOhhRPj46+Z4mKGMQGQA0FcETikaoWMLSZtYKCEnO/nH8q5MOIaqeLyNnQuLYcre3h7+NKKAWNpys/taQ4jL5cPm3GhdXiN3DRpAEoCW+wz0zLJzCWUNjz15VQXvZdBZOAYQhuvudLSE89o+RVPWmNwlXb2GkDr/mhPng7O5O/uRZs6dKedHbuSXqfOtL9zV9rWvivd0j/MkZqsMiLHuw/o0LhJtL7Fb/TQ0ICoLJvyU6Mp3teNnh7QZ+SlC901Ok6nl66ijT+0pP19BpIXIyrc30vICShSWilRSkEZJWYXcSm16YxtBPmF0t7+Q2j9r23oxa173OtKzsihspISMrztTpMOPqLVZ8Vqi6bZc1p9/iVHzPY5BJE2e532Eanc87i9cCKt7oNpxr9+Ia0+w8jLzZsjLbE1EMNoSRqyPAN3rqQ1GufW8r5ca7R6U/+c4xqPIE1kTSEmA52WGKUCc2ljGGoooO43pNI1HWNekCOGcwLrPwCSAysHmmaQmPv69etfYDKuyzogHHgBSm3jA0lFGU86MBPx2+j0gk8JahxazpF3o6oBYRLi8iVDJqYt3z53lVvIGnp+i0zSIrnblyov4ZGxtG7kNBr/nzY0pcVfdGzDTkrOyuH+LzEznwtSA4nJzsyh8IR00nnuLy4ZvWDk5VUwR17WX3aiJScdaMW517Rt/Bza0r4LGU6ZTXtGjCftNu1IZ+w02rjNmLbPWUX7GHnR+uEXurh5J1dmQQkmtaCITOctodn/5wu6vmWLxHhLFPD4Lmn+8wcKj0qgPEZEjGfNp9X/+oH2MnIUEhhG6cU1t6SD1IievybtTj1oc8fu5Gr3Smz/zSuk62yf5xo/q5RJs9TEljZdd6EDTqGk9dCL7saIB5Y+PH+FVnbpT9O+bUnrB42hoKBwTimJS82p8/uBZ/B6409iYjxSZpJuUwBKCijnY2hixawRBGnizhspsBg1wu7AO2D4LPKqGsOYEAENG8JBEFBnxQ3BeRimpaenZwfDNGRChPLB2FV1kwYoYbqoijNcTi/trsZ1FWEyc3FjJi9V1AEswtFxSWS4YhNNadmBpvzcgTaNnUGvnjm8HeAYJ0l/zc/Oo9dhibTxqS/tsgvgyIv+62DSY1h7yZEWX3pDGxdpk063XrShWz/S7tCNdqmNojXGD2nZwxhafs2HtizcSLvbtacV3/9MTy9c5Z6DS1kpLSfzJZo04f/8Fz0y1Ofe3yPqE2j3oFGMQOVyvxeXlkWHJs1gZKY52V25wf2splIMSMrrR89Iq01H2t5XjXw8fDmVKSQunescAnFZLfG2cD6d0y9o91Mf2uscSUcjCsgjJI4urN9Ks1u0pSn//Jm2jJrC3vsKpKWOqhvC6LDZP7SleX/1ptUDx4K4tGnKn332edeTNbIEn3dkkODmhd2wlGEOD3wTKDMgkl9RU6YAAQJxEVAnAxf8SejqwoRQDNPkO+MCcyrQCabKaa1sQflh7dCJNPfPXlwAXUR0HPfc6UXl3AIW24hLRzFJmZz3A56Qa2bnaE6HfjTx+7ak0aYHHVm3lULDojjjLrw9mExdmJNPtsEJpPXIhzOvislLCEdgVt4OpJUr9Wh71160lRGOHZ270/qNRqRpHUyrTj+nFRYi0rzhT9rz1tHW31vTps69yd87gFNH0tjbjXf87OIltPznNnRFezNt6dyLXOxeiQdZpokVEGsjY5r//76hW0dOiElVDcoH/s/J5gWt/L097RquTiFhMdzf33UNo8mHHr3LoWFflzISA9XoQHAm7XGLI1Ozy7R/5ESa9q9faMEf3ej42q0UnZAmNuKm1D1XJzZVrGjFJqWT9riZBOO3ltr41035GuDq6vojVBVFGzRyc3M534NkpporJgm7u7v/pzaToQUIxEWAAF6A3Av5F8Mpa9MqJxlGGaxo734tyMsYrSETuLvjdcMn05PrdzkTqzRhBHf4maViMpMMg2huMfc1u1ycQpLBVqqYKm2xDWmuUWpeCfc6fLz9afuMRTS+eRtGYP6kVYPG0aXDJhQUHPG2tIPtSXga7XgeSNsYdB2CSc85jAwjSmjbLhPa2L4bbe01kLSHjhcrGoywcCSBkZfllz1oxUUX2jFqCq389490YtkaLjIuLj1fnOKSk04G4ybS1P/6ii7vO8CRmcwy8fO6OTjTzkEjaR17/B0DR1B4ZDxllFbvOcJjuju6k1YHRja79acQX3/KZO/Fxouvad6JZ29LRMtP2XPt3HvepNB+6xe0ddYyWtGqA03/7lfS7DqQnl6/w71/2VRhvlMtCUscI1+ZkqYjf79g2jRmBiPDvTEpGmpLj6Z8HUD5p64DakFkUEZGhwo6Sg0MDKzhg4NvUtEYeAECcREgoMbuAXhU0C1W200y3TS8PkbNs8WlD1tkUhd1GcTFtW9mC4/FIRO6d+kGebh6UWBQJIVFJnCBblisYBL18Q7k0nZvnLzIZahI/68hJuxCUQF5ScrOJ8tjp2lpnxGk/l1rmsBIzOpBY7gcG0yY9vMKoOL8QgrJK6ejvsm0700i6Xol08GnHrRnxkJa23UAbenUg9Yv1Kbl133fkgQpedG8FUhae87Sti49afmvf9LrR3bce5kreU8fml+k+d/+RF4iL25/4pLSyPbKDdrQtR+t7dSLdgwZS8t++ZMemF/i/r86FQSkMSmnkA7MWUaz/vED2VteJcvgfJp06Cmthtpy9iWtuOxJy618SPuiLe3atJc29BhES35sRXN+bU+HNNe99bPgsWKTs95TqmAu5gy/uUWcH4gLl2PHEOZnruU5I4/7W/xesSRGLzI2mS4fMaNlvYZxCp6EtCxs6tcCEJe6XAeq26RdqZg3h8GzJiYm26DsoiwlXH8FCMRFQK07CFAekjV2nSdxCVW14lKBvPyopTb++JpB6vmYFI1gutl/9OAmMGsNGE2bRk6lXdMW0A71mZyqsKTLQJrfoR/ZP7TjBhvGp+U0+NIRck4gDAQEhNDpvQdotdp4mvTDnzTmHz/TjF860vJeQ2nP9IV0aZcuHdmyl7S1dtG2pRtpTZ9htKZrf9o8eAxt6jOEVhtcpRVWXly4WyXycu41p7xsnrKYVv/0Ox2au4w8XzrRi7uP6ZbxGdJXn0qbWrejAxOmkcGU2bS+x2Ba2uIP2thjAG0bMo62Dh5Nazr1IZ0xU9j+plNaDXOjoBDdPsVI0A+tadvAUbRmvwUtu+ZHK675MtLiQasO3aT1izbTliFjSPOnP2juj21Ie/RUsmXkLFuS+fJWLan42Ow9BCl6bfuaRI7uXHhfWkEp9/u5EuB75LQgG8fXJ5ieWj+gU7v0ae3QCTTz1860rMdQ9v3EaKGTSHmKi7zrBCYhI8nVyMjoNIzAwnEXIBAXAQoDtWgYcOsSCY1hlZgIqsrOopoIDMN6Bv81bGFf3m0wLes8gBa370ML2nSnxWxh0lSfS/O7DKYt42ayxS6b0grLGs18I6gYuZL+HvhD7ly4SgdWbKRVA8fQ7FZdaeK/fiP1v/9Es/79G8377hea+fX3tPTP7rR5xCTa2GsQrVefzRGUlecdK5MWTnWxp+U3/Wnt+oO0vVsfWttTjVa26UJzvmlBs/7WnFaPmE4bMTuo/1ha17UfHVuxlvbuOUHr1CaQdr/htHnQaA6Lfm1Pz24+EPtFqinjoOsoOj6FNjBCqfGvlrS273DaMG8drV25l9bPXkMb+g6lFb+0pTmM2KztP4ouG5myx0kXq07VqCxvw+MYUcGxMdTcQNNbdqDds5bSwRWb6OQuAzqlY0jn9I5yStyRtdtp7xxNWoXn/6M7R3KX9hgCP0smO292MXwtXAfEQO4W2p/rIx4eOWHww6BrUTj2AoSDIEAhILX40qVLpXW5izI2Ni5AtsuHeg1s8Xm5smNf2rxiG+198oZ0Lj8lnUtPaJ+NN+k6htGq0TNoeef+5P0mgCsZNK6uoyzO/JopMc7Cv+PvH0Z2d5+QxcETZKq9h4zYgo2v106cocdXbnFKzOo2nUhr2U5aYeVdaZJ0Ray44kmrjaxpMyMiG3sMonXDp9DR9dvJ3uIcnXwoIo0r/jTvmA3dePCCsjLj6IJjMC0eMZs29xxEm/qPoE0DRtLSdr1If/YSSs0t5IhGdV1TIBhuTm60bdwMWvjLX7T4+19pyQ+/0kL2demf3Wjr2Gl06YAxhTJyli/xKXGvW47hGt4lNycPmtu2J+dTmdeuN81u3Z1mM4Iyu00PmgOw/1vQsT8t7z2CVg8al8XOlfsMWjB7C5//ysCNx6lTp7TQMVQfm0gkQmeSupANI0A4CAIUgre39z8xx6I2d1moX6MVGuMbPlQbJFuAOq8ZOJZWdupLu8zv0oHYctJ7k0j6gE8q7X8RSGtGTaf5rbvQK9tX3MLYeFunszgfBxZ2tCEXSAyr6YXlXMcRNuStrOk9lLTadaU120xoxQ3/akkLR1wuODFS40AbRk2jjX+0I83ZG+lZeArlZ8fRLQdPmn3cluabO9EjFx9KifClK6/9aNGMdbSpU3daP2khrR81lTYw0rOgVWd69eRF9aMYJP9G2SY+PZeeXLtLp3foktHy9XTZyIQc2XsSnZgubskuq6EsVAPgX8JwxQPLN3KERWvI+HyJinKa4R7DbQZDhrUMIxi+Ez7zsoGWZpRxPD09SdXKC7oRkQ2FZHXh2AvERYAA3kD0MwKnkM3AV2GJiYkhZLvo6ur6w2j3IbMb2GKkv6rnEFo7Zibte+ZNei5RHFkBdF+Hkq5LJG2Ys5pm/vt3umVuKckAaXikBL4bLOwwksKrgQ4okKzqIPVxgLRklCA8rpQrneC1Pbx8kxGJTrSp50Bas+ecWHGpgbhw5IX9/9ol22jTX51oyeDJdO3hC0qOCaLbdi60wNSeZh5/ThcfO1NBjA9ZuQTT/HnbaGPbdqS1YBOn6Gzs1pfm/t6Zzu45wD1/fHXG5xRxZkpqfuk7slX8bgY1BiSijKdoS7t0UKKHqzc3rHJF35El7HzoL3yu64aoqKgvMLuOfb4j8TlPSEjgHY2gyAZf3f79+z3qw9QvQCAuAlScp+Lv7//3Bw8edEceAuZHYf6DKlsJER6FRFxZFydkNTg7O2OIVjymjWKQVlxc3P/90McLd9YrO/ShTcu3kp5nIu13CH5LXAADv3TassWQpn/dgk7u0peEqH34riJOOSkWqyalEvUEi3BiZh5FxCZTcFg0OTq4kIONA722e02292zoyY37DPfI4dFzcnnhTD5eARQWGU/JecWcJwTbOR0DWvRzW9qoNpZWnXhCKyxcZRAXe464rNa1pI3d+9OibkPpxKWHlJ8aTravRBxxmXviOe2wfEnOInfa9ziAlizWoQ1//EVas9fSKrNntH7AKFrdpR+t7juMAgLDOQVEXokHJA1EK04JJmk8Do6d6dZ9NOu3zugQSmbnhHAHX0dgvAc+37j2QFE9evSoET77L1++5IbpKUONwTUFA/8UzXtBvDxumFBmQkckIufrqzFAgEBcBFRzp4N2watXr5YhAA4XiOTkZE7dwLwQzItSFVmC1wVmObQtosaNiG+MQbexsSlnz5166tSplYj+xwWiocylYgvU/2WIBnHZpmvGkRTdFwG0yz6ItjwPpt32gWQYkEnbD56jBT/9Sdsmz6OE9GxKLyqt98C6hIxcyikVG22BjMIyCgiJJrtnL+nGpRt0ysiUju05RDsWr6G1EzRo9ZhpNLdzP5r3Vw9a0L43zW/dmeb92o4WMCxm0PyzG63rNYS2DFOnA/OX0w3j02R/7yntGjeD1rbpSOsWbaHlV724UpBMxYURm1UnHtMGtXG0tkNPWr/7DN31DKWD11/RQkZcVpm/oGWn7GnZ6Re05PIb0lqgzYhLO1o7YyWtuBtOq3eeofU9B9Gcln9xxlqudTq1/rq2oORAfQoOiaJV/UaSZq9hpDVYfadwPVEu8JnHfDo3N7fmuKFi14qX58+fL8E1gpGcWhEZtElj3g1fxRbRDbihMzIyykK6L1RiaYovph3b2dn9JczME4iLgHoEFBWEwNVkjIMLHxH8qryzwJ0PgqJgtMVFgN1d/Q4PDJ6zIc4jYaTlP2sGjs1b1W0Q7Tpzm/O07Gak5ehLf7rt7EWHXvjTHq8U2m8fQFojptCMH9qQ9YUb3PGUljBUncmSVSw21UJN8Q+OYkTQgcyOnaYda7fRgnGzaGIPNRrdphuN/rUDjf7xD5rye0fSaNeT5nXqS8uHqNMqdQ1axfZ93XgN2jBpHm0cP4s2TVtIG0ZPpbU9BtOadt1Js00XWvRbB1rOSM6mvsNoW+9BtEb/iji/5bS9TOKy8uwrjrysn7KYtFu3oVVzNtBsCy9aaPaCIy3S31t21pFWsN9dN24OrW/bQWz8venPeWi05m+k5b+3I+1RkyWdW6X1rGCJU3DP7DlAGlBd1NS9GXkRFjAVX68wcA/XiLNnzy5i1yZHDGWE4RZKirwNQZdQeV1cXFrwfU48F8gSytXV+e2OHj2ap8jjCRCIi4B6MMkiHApTu4Xj9Za4/IsRl4xVXQfRTrMbpMuIyw5GXJ65vqE0bxe65+pN251jaefZe7S6xxBa3KozLe4zmtw9A7njKQ41y1S6ApCcXcgtpFAfwqITyerKbdLR3ktzJsym0T2H0OA/utKwVp1oIiNcs4dNoEWMkKxYsoHWbTWkTbpmtM3Einaev0d77jjSPjtf2vvYg/bb+nIEbD/79/5XIdzXfc/9aO8DEelsM6StA0eSdm812tpnMG0F4TF+RMsviWSTFqnqcs2HtLSPc6ZbKC8rjB/TiktulVqnUVJapXeZ1vVSo3Vd+9JqHXPuZ/jbVQdv0IZeg2j+r+3psdVtcSBdcla9mpZBDJHpsrTLAFo9YFSx1uBxPwqfkforK8FgCyKDsrOxsfFuKCAYwBoWFsYpMkVFRRy5wLwzqLm41uFaBrWXz3Pg8WHkhQpd0xYfH0/Hjh0zFOYlCcRFQD2BkZK2Dx8+LJeXl4KBZnw/7E2AuHy9ZvC4lJWd+9MO4yuk55tG2+0C6c6bEIoI9iNPLy/aOmclzf/Xr7R+8gJaP3YWzf3pT1o+YCw9vnmPM4eWSLpyOM9FHUocWDxTc8UTlbPZl+cvnMlg/2GaM2kuDe7Ylwa07kJjug6g6UMn0MIFWrR693HabHqddt58QXttvEjPJZIMvZLJkL0GQJ99r+cWS7rOkaTnGs191XWK4KDnn0l6Ibm0/+kb2q1nQjvHz6TNfYbQ1gEjaFf33qQ9Q1NMPM6+4kdc8LsmT2jTwNHcFOc1W08wUuLz7nfMHWjF1Te0VmMNbWjbntaNmi4uQZ13Eis2lz1o/XRNWvrjb3RgwUquFFdda7TqykWZnM/Fy8OXlndXo9X9RpauHTxO6CD6gD49mP4xrPXp06cdUWaGRwbdSigNodwTGBj4N0XKOgjKNDAwSJZ1YwdihDBNwewrEBcBCtR/kQSJuw7EWSuSTYA7Frj40YIoz8zG7mSe4LmE484Rl28ZstEKvf3IJdL3TSEdzyQ6+MKfPF2cKDI0gM7vP0CrNh0gfe9k2mP9mrTU1GnuD61pxq+dSU9zPdnceUJR8SlcToq0xTgDs46yC3mNBojlZgwVEy6nqTmFZG39iNav3Ewj+oygvn90o5HdBtLMSfNoidYuWmd0gXZYPSfdV6F0kJGTAz6pZOCZwHVC4Wf7HYIqGYsrwd6f9juGk15QDu2770I6mhtpa/d+pNXqT1rZoTvtHTqG9g0dSzqdu5L20q1cWi5KPavO2DO84FBzueglrbB0p41Tl9DWX36jdYu3ccm2XJkJgxmv+9Kqgzc5VWVj+86ktXo/rbjhJ/l/e/b/frRmnwVt6tqXlv/ZjZyfO1WeGi3NZAGgcFVExf+rhe8Iz4G4fxQPzHfp0YK23Wjd4HHWwuejYSkyuB7iOlnbzBZ4azAAUl756dChQ1kodwvHXSAuAmR8ID08PP7NPiwXkDiJKGtJnHU2JEtfX99/qEBx2S0oLm+Jy38hNXdlh96kvdmADsQT7bP1ocV9RtF1XT1Kig2nVwEhpOuXTnudIkjfJ4Vrmd64dBNpdu5PU//1K834vQttmDCb9FZtpgtHT5Pzazdxp052AWf6hCJTWKHrJ5e9Q9nsh/CupOWXioc35pfQHUaAVi5aQwM7D6D+f/Yg9f4jaO681aR16BzteepFhu5xdNAvjQzfJJKeY5i47FMTSamK5/6k65FAur7ptPvoRdreV43W/daGVnTuRQdGjSfXtZspZMsO2j94BO1kxGXjDjNaaeVNaxjpWM2IixQ1khik6DLysXbrCdr+ZwfaNGammMxAUTn3misJrZu1mjb/1ZE2DJ9Eq07ZvRvaCMUGybwMm8fNomXf/0pm67dzxy4e3VuMnMRzyBAjqQq4n4t/5z0iw4O0pJeIu7JumZ2nxW260dqBo2n94LFCOfUjAxQXdtOWxENx8Rc6jATiIkAG0BLMPihRqamplT5A+HAh+wAfIr6dQJBVcbcg64OJ7qInT550Fo59JfJyE11F2hv2c96PVV0H0Pwf29Ie89vkGxpKPp7upPcykOswgmrBBdN5J5POFRvasHIHaQ4aRxqtu9CkH/6giS070MwuA0lz9DTaunANHdppQOdNztFDRkqePHpOz587kqdXIPkEhJFfcAQlpGWRyNNfTFi6DKLBnfrR5BGTaP7SjbTB9Brpu0TSIUaaDEQxpPsymD9RqUJa9HzSaB/7unPJOtJu25GW/fQ7be/ej5zWrKciw8NE5y5Q0ObttLFzT9rXT402Gt2k1ZdEtJYRFy0J1jBysvp0ZQLzXncR+/+tQ9UZeWlPWrtOc2RmOcy3W01Iu1NP2tK+K61bsYeW3wqsYvq1535v/foDtLlNO9rYazAF+odRNmMUYoKSTvGJQJoYCZKvb3+WXoXISJSZ6ggLIysJGfnclGmQypScArLYe4AWt+pEa3sOoU1q4yyEz8XHaQZm18dL7KatxusjOjFRSlelxwU3jcnJyZ+iVRzKOm5ehfdHIC6NBvhw4EOCD0tNG4xp6BTio5Ckp6d/glqwv79/tY+FlEl2x/GoIWSnNDDiorO670haN20xrR4wmpa360F7rj+n3X6ZdMTBjy46+tI+RgD2vS25BHAEx8A3lfS9kmjPPWfadvwKrVu3lzQnzqMFg8bSjC79afzvnWjUz3/R6D970ST2+ON6DKExDJMY0Zk9bhbNnTyPls9fSVPHzqRBjLCo9xtO85ZsoO03HcjALYYO+aaRnmO4YsrKe+WhAK40tPeRO20ZMZ42//EXafcaQJcNDlGa9R2ibTpUsl2HaL8B3Z05jzb92Y72TppD6y68pvXmL2j9aTtaJ8HatwTmeQUFpqL64sB1IW1YvY92/9KSNk3XpGX3o2jF2dekrTaOtnbsTtqDRtMqkyrG3bc+GRGtPmnLTY1e/n1Lumd2ljtv03KLKAm5NYycJMSnMaQypHCIZ9+/RQUykyBVaZD5glbyzHxKLxVPgeZGAjDSEhIcTo/PXyLdSbNpya/tuW6qLWrjLgmfiY8Xjo6OLVEuqu7mDmUidBVh9poqnjs+Pv7/3r59eyDawGE8xk2mnp5eHDw7rq6uPwrle4G4NApERkZ+wU7icHxg5EmXfMkGfg/k5cqVK2VwyOPuAjkuT548KYejHnJpUzm+bOFux3CJYZSs31utNn7w6qETaWV3NVrZexjtvv6CDEPzSZct+jufB9K258E1koL9L4NJ3z2ODP0zyMA7mevS2X37NW0zv0PrdI7Rms36tFhjOc1UU6fpI6bQzDEzaB4jLDMZcZkwbBKNVZtAo3oNoRlT5tPGk9fJwDWaDnqncIm9dSIsFZSWPdftGHEYRVvad6Z1HbqSpfb2dyeYs4goJpYoIorOTp1JO1q2pL2zV9CGq560iZGVTadsaSPDBgnEBMaOIzDvqS/wqoCQsK+7BgwjnXYdSEv/Mq3bdIR2dOpK27v2og2aOzkVpippeUuArnvTloUbactvrUl37CTycfGghIRUSknJouz8Espn5INDCb37HmAfobxyem+yc46EpKQWllNwUDi5PLWn+6bmdHKFFm3vP5SW//Inre3Yi7YPHp2/bfDozcJ16eP3EmKCNbsWpktzXHBD5+3tjaiIOLRLq0IBgRrOruNvcJNalTShWyokJITYdbuIkZmz9vb2bTA2QehsEohLgwRO5sOHD+fIM4sZGhqmBQUFfcX3caG84LFREkIyJFIr4aNRNF3yIyAuJpJFvIDhf2skLkMmfrlKbXzM8k59afMWQzIML6iVsgFjrJ5zhJjIMPJxMDCLfU2lJUs20Ii/epLlhWuUl5tH9i+caTryV0ZNo/EDRtHcxetpn70/GQVkkp5TOPu+joRFYsTlUoAZednMSIt2+460c/Bw2tVfjQ4MHEjHhg6h8/Pmk8PVa5QqaQ81mTaT9v78M+3WNqLN1kGkfdmNNgNnX5D2yWeMxDzjyMv6SupLFeWF/UwTJZ9dp2hvu3a0q/dA2qE2mnb26k/bhqrTKvY41akt4r9/TiuvvqH1+ldpX+9+tKN7X9rRcwAdUp9CJrMX0uXN2+mB0XG6f+Ao2Z+7RI5W1vTS8hqJ7jwk19sPyOnmXXK6cYdc7j6ix6Zn6Ompc3TnwBG6tHEbnVm+hvPvaLfrSmt/+5M2tO1E23oNJJ3BI8N3DR55ePugkb8J16SmAZh7cQOH5NwbN24MBZCcixtJVTwflBQjIyPT6Ohoudk0GGHg5+dHUIVAdDCwEplYTe3aLRCXBgx0EDFSkirLkwLigjsBRFTX1vzbVI8vW8DXVVjMVzD8jWERIxkDqv7uqiETNq3oN5IYgeEyT+BjqaviARPtzhsvaMrAMTR12CTKKiqnvKISWq25gUYNGkdjew+hOYzUwL9yEGqNMgiLFC9DSM83nbat3kqb/mxPO/v0p03bjtOGEw9p0w5TWr9sF60fMonW//4nGTCScGnhEjo6YhQd6N2XDCdpkP7MJaQ3fzXt2X6ctp+xI+2rnqR91oG0zZ5yKoy0hCQlL6sqKC8rzr6kZTcDaPOq3bSfkRedvoNpVz812qk2hlYff0DLqxAXMWkRE6A15g6kdcmVdk1bTLpdutHuPoNpZ5detPXPTrTxl9a08dfWpP17G9ratj1t/6sTZwTe2a4zQyfa8RfQkft+a6s/acvvbWkLvv7Rjv1+B9rNiNC+/kNS9g0c5rB34DCdvQOHj9MZNELwFwhQuY8RSb2ylPXqNoTkITQUSeRQy4VOJ4G4NAiAiTNS4gCpsKYNwUtoX4aZSzhmChOX/8eQJlnM8xjiKygSXSr+7sqhE39YwcjF0o59aKPWbjIMzOTKQHXxlhzyz6D1hy/Q6I59ad3yTXTvvg3NmbmUBndXowmDRtPiTftJ3ymC6xaCcVZppAW+FiQAn71Dm7r3oZ1du9KW5Tto9b1wWvMgmtZf96ZtB67S3kUb6MDwMaTXtTvtbNOO9Hr0ooP9B9GhLl3oSMd2dKTDX3SkWxc6OGYi7dtkSNvP2tPma9602dyeNp58JlFeJGWjqiWji86kaeVDO6YsJN32jDQMHEa7ew8grUM3aMlVH1p28jmtkJhzpcQFBEjrFHu86z60Zfdp0u/chfQGDKWDI8aSyTQNOjV7fsnhkWNNDAcOMdXvP/iVwQC1KP2+A4v0evcr0u87oMyg/6BEwwGD/dnXoAMDhwSz33NjuGUwcMg+hg16A4eO1h049BvhsyGgPoHyk5WVlWKspXp/YoKnp6eQLSQQl3dIS0v7L6gamLdz6dKlSWfOnNG0tLSchHoounpU1T7M2HQv+E+qO1mhxFhbW5djHz7GWjNKWrXNZOBJXPowJNWwuHeq+vvLh03S0Rw8jpZ0GUA7zO8w8pLFlVpqQx50X4WQvms0LV6+hSYPHE1zpi6gkQPGcEFyE4dNoLXHLbluIUNRjHJJC6e2BJPemyTaukiLtrRpQzvGTaU1twJovYUL7Vq2hfRGTyDDrl1I57ffaNtvrWln2w60t0MXMuzVhw726UcG3XvR3vadaE+7TrTr9za09+eWdPivNmTECMxebSPSvuBIGy+7SZQXW65stOY9v8tz0rzsSavOvaKdQ8eRzp/tSbdnH9q804wW3wqhBabPaeaRJzTt0GOac+wJ1420lv0tHms9+5tN7HvdkWw/e/Qk/YFD6NDQUXRs3ISyY2PHnz8yfLT6ocFD33baHR424p96vfr8rNujF1dOZcTlkwMD1QR/QAMAZgPhpqsp+zVsbW3bIeKC6rjBr2hgYHAfnUjCudVEiYs08A0M9vz587MxGh3mKDc3N06eg2kLLcpS0xRmacAVrgqnOcy0169fL8NzQh7EhGXsw4ULF0owjAxR1R/LcQdZgbP/yJEjx3HM0TGFBEwVkJa11SzqmQz3GDrW9HfLRkx5s7jXUFo6dCJHWpBAu8/OT2HyYOASRXufetHU4RNpfO8hNK7/SFIfok7zGJHZdu05GTHSovc6jPO2KJW0gDRBwbnjSNpDRtGObt1o066TtNH4Ae0bO4n0/vyDtv70C+m070wWCxbQ413byfGwIQVduUCJT+9Sst1Dirl3g/wvnCbf86fo9UF9urJ4Eel16kq7/9OcjrZtRYcmz6btx+5wBt4N5va0jhGYNVVVF6go7GdLr3rTcrNntH/QCNr+i7gF+6mdiCLyiF4FxNMDj0jac82FZho9pumG92mZ8RNOzdl0zZv2rNlLhzp2oENqw0ivdz/a+ivb99Z/km6P3mQ0eEgQI1qbj48c3VK4aDfMjklE92OhxYBVXV1dZ9wIojze1I4FBsuy61yRMqZhY02AX1E4x5oQcYGqAlMWhv/BvQ1/CZgw8lKqG7pV0WeC37O2th6kCoUAxASDvUCgkDOAMDqoPmjLw0L/sRx/GIzR/n3z5s1yRhy5Yw6XPbuohSqzBZEt3sNrWNTt5f3t0hGTOywdNY3mdxtImlMXcarJAb80hVURZK6gDKRldJ7mLFpHy7YfpC1XbOiAZwLXNfTW0Ktk0gLA26Jz/BJpd+lGO0ZPoJ1zVtD+Pn1pyy+/0Y6O3em29kaKeHKHKDGUKCeBKCOGKC2KKIH9Oy5Y/POUCKLUSHabF0uUHEExj2/TjeWatPePP8ng5xZ0vG9f2sUI0VpGMNaddeBKPBW7jKQloFmHH5GxUwLFR0TT0VHjaNU//kXnJk8mKsqr9BlzC00iC3aMt55/QfMM79LK069o98ErdLB3b9rTvhM92bmdPC3M6dYKTTo2dBjt+OMvTsXR69aTTo6f+OrRrr2ThIt3w7k5uXbt2kh2DSvFXCEs2LgZgzkVJAZNA02p9A3TLwZIypqRxHd7+fIlYQSCcJ41AeICgyrinuEVQZswck7g3laEAefn5xMUAlUmKmI/Ia0CH5upFsYydvx80ZpdXf0W80H4Bu3xIC4ukkX8OsNkhkOSf5cxyDU5Lx45ZesiRl7mdOlPy+evIV0Ybb2TFSMaki4jQ494znx74E0iB5SQ9qmIsLwlLn4ZtNvInLZ27U67h4+hXd170rpfW9PFxUsowv4RUS4jKwXsfYjwJQp0J/IXEfm6EvkALhUg+XeQB1F6DEdigm5b0fFBQ2j3Dy3IpEtH0tl0gFbf8CMt8xe05tTzSsRliZkdTT/8mOLTxZN+k0LDaG+vfrT0f/9Bd3bvq/ZzlltQTK99Y2jH2ee06JgN6U5dQDo/fE931q8VNzknh1Ou83NyNz5CVosWkQEjLpu//4n2/tmOzMaMdby6bMV44SL+YTt2MPgQno7qzKj4GdK9oSQ3lfIRjglulqG6gMAJxEUgLrxqrGgHxrh0PqPSa9pAco4cOZIrOLtrJxuj1Obr61vj8QWZRMlMGV4itngPZeha5Wc3GS4z8LrTWzB6+piFY2ZkanQfRPNHTqU9j9zpUECWeBaQIsSD/T6XeCtrhpAy8dyf9ANzaN+5u7QL5ZWefWhD+y5kd+QgUVEKUWk6UaSfmIwEMvi7SUgLIyjezkReTkRvGLycxf/2lhAY/E7IG7byZFC2n4hMh4+gPT+2INNO7WjXZiNaeTOgks9ltbkDTTn0mMxtK4chiqyu06affqPtbTtQnJ9/jedDdm4hGT8LpQ1aB0ivbVvS69Kd4h/eEitB2H+oQbFBlPD4Nt1fr0X6nbvR1h9bciUt01FjnpuOHD1Q+Ox9GFWV3YREIn9KVjYVclQwzb6pHBdc15ydnVvg5hfXOkU7jKSbpaVlKUpPwrn2kRMX+CngUantiVJxY3cJpUg4FE4SxYApr3p6es9kEUdJ0J53Q0r1nTdmxt7542aVzew3guaMmkbbLZ9w6sn+F/VEQmrRTaTrHs+RF53pc2lThy60nsHn7nXiJiWhHBTuQxTmTRTsSRTgTuQnekdcQFbeVCUuzuL/w+9AmQlgRKcghQqiA+jM+PG0/8cfyaRHN9I2uEwrrrxhxEWsusw3fkbLTtpTQXHlEmxuaioZ9OlPm3/+jRICAuV+5oIjk+iQ2nDa+O1/yGbHFnFZC/sCQoX9iQ/hyEzc07uMwKwl/Y5daNevrehQrz50tN8AncvzFwgzZ+oRCE/jY0S1tbVF+b17Uzs+UOxRKjMwMLDGjTAjM5yaz2dDeZ1dR+1UlbCLm3wE37158+Zf8NGgWaUxqWIf1Z3+8ePH9aorT9RGccHgQ8aW/y5coBQDpl0jIVjWXRj8LvC6fMjhZoyo/A/DyrljZ9xliJgzamrK7JFTy+eMm0nT+o2kmSMn057HHly6bYMkLgjAC8ohnQ27SPv31rSxay9yu3yOvbQitriHE0X6i9UKjri8eZ+4SBUXwLsKcfFzFaszQZ5i0lOSRoWMvBgPHUYHWragI0NH0Joz4jbo1eb2NEb3Hlm7hr2vpCQlcS3Xu9q2I/cbNxl5CaACGbNjsNnoG9DGb/5FZyZMpBLsM/ZfWtrC/uH7RPZc6dGUaHufrs6fSzq/taZ9bf+iE2pDgh7s3tdX+BzWD2xsbDo+f/5c7vUUIWsXL16c0VRzpuADAjGAgRm+Pwx/ZMeuHJ6/qtdJrD0YjovfgRdSFRYFyaDfSydOnChAlyv2BaUtRrDuIgAPzSwCcalHdov0QVnGW76blO2qorPoYwc+oPC3yMqrkRCX8Ojo6P/+EPs4d+zMRXPHzQrTGD6ZpvUdTtP7M6IyYjIjK1No+rAJNJkRF/VOfUn77F0uLK4hEhddr2Tac+4u7ejVlzR/bk3Pjh0SH9w0lFUCiRjReEtcQjyrlIqk5EWCij4XP4naAj8MCA/+HsoNI0Rhd6/RbkaSTP9qRbvW6ZHmrQCafOABGT/0ptKy92+8I1xFtLdDJ0ZeBpJBz96k370nGY8eS5ZLNcnW6AjF+bxfToz1fEN7/2hL+/7qQLH3b7DXEy0mXFLS5SfZd5AaqErJEeRjYU4nBqvR9h9+ooPdupPloqWLhc9i/RAXthjLvZ56enoSUr2FYyYuI2GtQofrnTt3+iNsDmnpsDdAlcG1E/EcsCmogughIA8hp/AaVuftxD6gciEQl3q802dvSHxdy0RgvGhXFqYq177lG8xd1lRWdB+gZbK+ieGccTP7z1Gf5anBCMqU3kNp1uhptGKrIW0ysaId158z2NO2q89I64A5LV63h3bddSJ9l6iGR1xehZCuRwLtmLOE1rX8jQwnTKayDLbAF6cSJYQQxQcTxTDiEu0nJh0hXmLlhDPnulUmAlJIfwZCAE8Mfj+UkZZIRi6i/TmjLDwzt1ZqksH3/yGjidNJ4+QrWnzmFWXmVk9SX5iY0s5fW5FR/0F0sG9/OsSwr30nWvfNd7ThH/8i/U5d6NzMWeR+5eq7zx/7/J4cM442f/tverptM1FWnJh0BUj2XQr8G6UskLOyTCpgBMtqwTza8ePPdIA9rtnoMcIsonoIW0PXoLxr6uPHjz/KfCplERmUg6Kior5AmR3dsKrKu8JzmZubLwkICKjxvULXLdSYhj524KM5AXCg4a2QdacvawPhQZ7KsWPH8tiHccjHlKdSn4DMiHkg7EJV47GGvIwWyvqUjmePmzV/9vjZNG3QWE5V0dywlyMmB33TGFK5yH5DzwQ64JXMkMT9W88xTPmBccpQWzziae8tB9oxeDit/LUNOV5CiagcrTxigLzEBokJB4hHWEXy4vFu0X9LAiREAP8H0gJjbqiXuBMpyl+s4ABUTAG3LtPelr9yibvrD1yliJzqOyfKSkvopPoE2t+uI+1t35n2d+xKhj360K3ly8jlkAGZDB9B2376lbT//QPt/uU3Ojt1OoW+EN+9iywsaOPf/k4mw4ZTAUgVvC3Y9yCPd8C/pfsJgpWXQFSUSg4HdGkPI0sGHTphHw2Ez6TqgMUWyjQysGra4HVjNynBTTHTpSHeVOrr6z9CQntNGzqhUKZSRd5WoyIu2dnZnDQGIxBSAFXFJrFgIhtFFpusrmSBvAEYcSHRnTx5ch3qf9hn4USvPfBeMwJoiPop5EeoWNJ8B8jGRkZGp3HRq6/90RivMUODkZaJvYfRnBlLaOcdRzFZwWDCGvwj9dYZVBvighZofRPa0uYv2jVwCKVBKSnPFHtbksOIEiWqS0XyAuUFizwWe5SAgj2r4I2Y3IAEoDwUIVFaYgLFjwUyxIhBdqAbHRswkHb8+z/kdPlqjZ+tcCcn2gmC06cfuZ84QpemT6Otv7SiI/0HUtzta1QeHUAv9+mwxxpEu1q3pd2//UY6P/1MLucvUFpEBB3p3Yd2/vwrhd6w5J6X2yeAIype70pYkRJyFeVHBNWJSsnV7Bjt+b01GbbvQBfnzDsmfCZVB1wvsRjCJwGSghtAfNbxFRPrUQZBmmxj8E00hTI+I5H+svyHeN+OHj2aV5txAzD8QjWSrvWNkrhAlkKtDGUDY2PjApADnMQw0KrK9AqWCHYvi1HijWFvIGFSMxJd4XZHWx8OtEBYlBu0h64s1GtxYUOqJjsPduN416cpd9Z4jdazJsyhKWrjaM6clVyuyqHATHHbsoozVlRGXHzTabeOEa37oSWd01wubn3OjiFKjRCTF6nqwpGXQDEBiapAYMJ83icBUiLAqSx+Yo8M/jaOkZ+EYPFjZrLnyE2kKwvm0aav/k6OR4yq/YwV5uSQ2agxtP4f/yKr+fPYbVw6FTNydXHSJNrU/CfS7dSVMl88YWQri7IcntLtZUtoH8YEtOtA+1v/QZZz59G5SZNpZ4uWZLdvF2cO5vYdiJCA+7d0PwPE+wlw5KWcXhnpk07L38ioS1c6PWGi0C6tYrUbRtJz587NR6AmPu/4CuUaSosqR30IUKzjk62PL5FrJutmHuu0IlEgKG/B78Qe2xWG3/Pnz5cg8BXTrsPCwr5sNMQlNTX1v+Aixx13VbMsvA/o64d7WRXPjQMOwxPC55AlAkUFUf64I4ApycTEZBvc3XgThQ9U/dVxPxQpnDlxru+kIeNo5tSFpOcYzpWCGmL5hz+CaL93Ku3ZvJfW//ATXVixUuxtQeotR1wk5CWxCnmJkRh2QUqAyCqQ/hy/EyMhLFKlBY8FJQfEpTCFbi5fSpv+92/0TN+g2ovfnU3atPHrb0ivSw9Kenr37WMWeTqS8ZChtO7b5nR+4kQif3dxem98CPmeMSWDTl1oPyMwhxjZONqnLxl06EhnkbwLf01yqORxAt595UpYVfYTQOBeeTZdmTeX9v3emo4PGBh6uFdvYeZLPQWw4fMuXFsb5s2kkZGRKSwRNW1QyNHkAtWEz2MiFRmZXDBpV/WXpqeno8klHoGwjYK4vH79+hdZ8xpAXsD8VHXnjYMJ9QWKD5jgixcvWqNfHTU+4QPVdDBj4pyF09Q1aMIQddK2eMQNOlS6ylLvJSX2fD6ptHfXAdr6ays6NmkKFWHRLk4RdxQBIC9Y7JPCJAQmWLy4S1UJqWdFipjAd+pKXHBlIoDHwGOBDOXEsw9vDF2aOZO2/OOfZHfg4Huf7YAnT0nn55a09fufyPmgPlFekjgnxvM1t18xt66QfqeutOWHn+mlznaxfwU+m4wYin18m4706kN7W7XhuoSOYghkx84U8+w+Z8B9u39v91GynwkSb490P7HPVEYxDk9It81fdLhnbzIdMULoahHQ5IGyHYLtampigTfRyspqNN8bTWT5YNxDTWs9Wr5h9lV2Ho1K7q7Pnz8/S1ZyKrazZ88Wq4KJCRAgxfSJc53Gq42jRRv30SHfNHF5SEkEAqoNzLtGjEQc8IhX6Tyi9+CbTvuOnKPdf7Wjfb37URJIASLypcSlovICpeQtgQl5R2I4BFX4XkoCpIRForLgMbhZRgxFyVTM/v/06LG0/dvvyOvWrUqf6UhXV0Y0OtHmf/yLLKZNFf8dyEbFTqacBHqqvZELmTs2aBAVeLwiivAT/19uIqW6vaSTI0eRfvtOZDxoMO1u+Ru9PGxIXKgevDtvEVp5P5Mr7CeQG891QV2ZP4/2/taKTo4Ze0n4THxcQIkC3aQ+Pj7fwL8Bj4VwXGQDlgi0pqOkg7wY+A5RFYEKAzsHuo5QjeDraTE1Nd0MciKr9ISZVcoa8aIy4oIDAzkKB0XWhs4SoeVYgKowddLcb6dOnJOmPmQcbTh1U6lqC0jLAbcY0nsdSov3HKf15rfpsH8GGbrFqmQC9HuAqfiqDen27U/av7Qit8vn32W4pEdJyEs1BEZKYpJC3y38UlUlSaqugKxUJQJ4rHCuqyiREQvDjp1J58efKNjO7u3nOcbdgww7dabNf/8nnRgylHLgmSlIIQqvYKqFMTgrjtJePqVDPXtzXUU+Z82I8hPf+W0YQUlztefKRkd69yXdtu3o8ry5RHnsd7KiJfsm2ceU8MrEKjWy8jGgUnp15ABHfo4PGBh8boaG0Cn4kZQ8MCNJV1c3Asm9mOmDeUkYbgiVXfAqym9kga8TfkM0pMA+gVE5IBeKjGGRdCk9kZUGDCUGnheMQGjQxAVlGj7EBTHQwgApAaojLvP6TB6vQRPHzaSt156/U0WqkhBGZvRehbL/TxCn5DoEvR2MaOASRYaimHdGXgkOeacwJNM8bT0a2HMwjRo9lZbpm9G+FwF0OCCTmxStUvWFEab9Homkt3Al7WAEwnz2HHEppTDl3cL9lsBUUCGkJKZGRFRWLQCpipMTx5VfHmzRpi1f/4POTpxIJRKTX6yHBx3q2o20//kvOtClO6X5iohL8JWWn6TlKGmHUnE63duwltb97z/o4ZZNYk+KtJQFIkUl9Gi7Nu39rTUd6t6Tjg8cTDnofCpNq7xvVfdT+rqlYMTF7+YV2teqDR3rPyD7QKdOfxM+G40bEk+F1uvXr98bnItuGXgbb9++PVAgL4r5kmrzdyj/gLggl6vRExfIRxiyh+FSsrYLFy6UCLOABKgKUybPaztpwuySCYy4bLn67H3iIiUhXskc0dC+YkM6j9zpICMwB9zj6KB7PO1+8oZ23nehA26xnJqCn0NZ0XnoTrNW76ThQ8fT+OmLaNykuTRs0BiaPEuT1pldJ73XYWTkm8b9DSZE15nESP+eESxdtg/7g3JpH3t8Pa1tZNihI239tQ25nT8l/mBlx72/iEvJR0UlplpEVv7dt48RyT108N1rtPfX1rT9H99Q0JOn3M9cz5/n2o63/+d7rrU5AbOPsKG7B39bUfHB14wo7r/t9PbQuv/5G1mvWcX+lUeUnyCeZE3iVs17G9fR3t//oKN9+5F++44UbnMX1sHK+/feflYAXg/bfK5Z0B5GgI726x9tNnasoLg0csA/eebMmeKaPBXomMHgR2WXJgS8D4zZQacoQutklYrQjKPsgcUqeUHSYYc1nVySSH3HDzmr5mMEAt1AHIXMBPo/kyfP/3HypLnlY4aNJ23LJ2QSS5xKAk+KkU8KHfZLoyMBmbTjtiNprNlJo0ZNIfUpC2jJXmOuBKTFCMi4qQto7OS5NFdbj/Y89aI9Nl6keeAMjZ0wm4YPE5OWCRxxmUfjpy6kcWOm0Si1sTRj/hpac+Qi7WZEyNAtjitTIdzOgBEZPUaSoOC8nSJdBSA6es6RpIffZSRFzzuF9AOySM8vg/aLYmjfIzfaZ2pF+2fMI/2efejAoCGk16MP7e3QhXyReSK2v9e8oFclMrIIAIgMDLngIcFv6HCPnrT7hxZ0Z+t2ykxOoQfaW2j3Tz/TvtZ/0LnJkykb3UnYipLFk6mxH5QjJiZUKPlaTJmhb8h05Eja/v1P9GjnFiovTKby7Hj2Z5EU7WxHT3Zoc+Wo4/0HkPHAQbS75e/kcfG0+LEzozmDMGXHiskRgJ/h3wCC6MoyuJZoPB88Lnt++Z1MRoy8K1wjGn+Jw8LCYgpmH8naoLog1Vc4ZqoHzLk43jWt9SA16PJt8OZcaTs0DLqoP1YNu0GLFPrEG8M8hMZiUIMMh5Y0ZKVg6jLkO0tLy0kNPf1QxcTl08mT53moj51O89bvoY3n75OWiRWtPHyeVh21oDUmV2n5AXOOhAwbok7qk+fTGHUNGj5iIk2cu5JGT5xNI9nfjpk4h4YPn0iTNDRpwozFNHyoOvsbDY6wgKxMnLbQfvpsTbMp0xeHT5wynyaxxxk3YhKNVRtHk9nfLtTSoQ1mN2iblS3tuuNE+18EkL5rNOlDxXmTSAaAVxL3Vd8jnvRcomifrS/teeBKe+86k84Za9qpa0q7thnQzrmapDN0NCMpnWl/py6kP3AIGQ4aSkZqw2hf526098/2ZKO/lwpSIqX3n+KFHG3MNZGYqoAiAjIATwmVcI/hf/cGmQwaRHp//EnHe/emq5u30cnJ02jPjz9CyaDDvfuQxayZ9HC7Nt1cuYyuLV1Md9avpftbNtGT3Tvome4esjcyoKf7dOiWlhaZDh9B+h270tEBg+jk6NF0duIEuqAxm8ynTiOD9h1pf5s/6Wjf/pw59xgjL+gM8re+InlNueKwvZJ0CRGSAESpOI0jWjkRPhTr4Uj3N2ixv/2TjrB9vrJ8RX/hetH4r3UItpR1h48NrbmYAyQcs/ox+2LtQTdSxegTEBkMPGbrUVSjaYcGMBETWS1Hjx41Qn4K5CL0hyOQzNfX9x9NdVKoMo8vyB/GHMAvVDG1UuoSx/gC+IiaqgIzacr8AZOnLaKxo6fSqGHjadSIyTRy2AQaMVwMqCbjGLmYMGNJ+vhpi2YzzBs/fVHiKPVZNGK8BqnPWGzC/r0cJGXM+FlvCcuEaQsDJ0xdaDB+yoJ+0udatHTd/44dN2sxI0w3pkyelzJ10lyaPHYGTRg8jiYOHktTR06hWeNn0/w5K2npiq20nBGaVZsNaPWm/bR22wFau1mPtNbsIq3FG2gNI0BrRk6mtcPH04beg2ljh260pX1X2t6lJ+n0HUR7Bw6j/YOHkx4jLYaDhtCBgWp0WI197dWXdvz8G5mOHEXPjxykaMdnjHcki0ss8JygM4db6NnCX54hDq4rSZUoI7kSVaRIjMIUimJ/f2v1Ctr36+9k2K4jmaipkfFgNTrYsSMd6tyZjjNiAeICcnGgSzcual+HYfdvrUmn5e+0i+3Lzp9+pZ0tfqEdP7bkviIUTo891uE+/TgYsr9DdgvIif5f7elwr97cYx5lj8mhbz9Oebk4bRpdX7aEHm7Vprsb1tKtVSvoya7t9HjXNnq8YxtXcrq+bCldmq1BJkMYoWvXnvayfUECL9vPFcI14+MoTaCLJTY2ViZxQX6Y0PhRv76j58+ft0XbM9Z6CBP79+/3gHgBE7AqnlPlLwomKSQrxsXF/V8oMUKOSt1PklevXv0KdQUsV9ZsJqhdIIyYCNpUj9ekKQv0J05dEDNhyrwIRjSSJkxdEDV+6oIghvDx0xZmM1gwvL0jGD914bcTZyy5rLFwzZa3P5u2cDwjK7oMsxlh6c3DGPz1tIlzZ06fOMd0xoQ5L2aqzyqYyUgMpk/PUFOnGZhG3XcEafQZSrN7DaF5PdVofs/BtKjHYFrKvq7oO4xWDxhJaweMoA2DR9HmIWNoq9po2qE2inQGjaA9DPsHDeOIi8FAMXE5yGA0SI2OqA3lUmi3/PPfpPtXR7KcN5db6F1PGVOE7X2Ktn9EmX6ulB3kTkVxQVQQ5U9pXo4Uz0gKPCzOxofpyY4tdHnObNJnj7MP/pA+fRl56E9HevYio67duDlFBzt1JqOePUFayo/2H5h/bJBa+okRo/1MRowOMhur/vSk+sRzZuPGX2OwMlOfcIl9vSz+OuGK6djxt9j3F9nvPTQZOTrAeOjwwKMDB2ezxyk60rc/R1ZAOA737s2eoxcd6taN9v3einY1/4F2Muz6vgXp/NCCdv7nh7fQYT/b9f2PtPeX38iwQye2XwMTTo0bf/PcDI1hwnXj4ymFI2OE3cHLNYMKiv6HCRqFAoO1HuqYKsUJ4YA3IsKCxF8oLNIZQHw2JycnwtDDpqxwMeLyBcOXjLR8y4jH/zIi8inD5ww/1Mfzzxqv8bOGukavOeNmzZw7dqbOvDEzDs4fM91q4ehpDxeNmnpvycgptktHTLHVHDH5yYrhEy+sGjbhkdawCSfWDVXfs2HIWO3NamMmMOKycMfgUVt3DR6pvXvQCL19g4bt1R04TF9/4BADw4FDdjPyon9w4GCDA3377TIZN0H31KRpooM9etH25i1o239acPH5GDx4gBEP+EagSpwdP57OjB2LVmE61L2HmKj8/geH/a3a0AFGTg51606GHcWZKieGDItjZMD+vMbsS5cWL9WxWq017vrGzX9Yb9/1003tbf++vkG72Y2N2gpnabC///TWtp3f39Te+uv1DZvaXVu/udPV1VpDrq5eM/rq6rXjrqxcPe+y5kqty8tXrbNcqqltMX+h7sW580wvaMw5f2nh4j2Wi5ftvDB7rrHlEs3NV5avmnV9/abet7bu/Eq4bnx8wE0Yu2lLrmnejiSt1S4yMvIL4Xh9vBAOQiOo68Joxj6MDqjdypozUd0WERFBkFchswrHs2nBetee1vd36micmz7T2Gz0WJfDffpGH+7dJ+Ng9550sFsPLpXWsHNXruUYPhVJ2Sf5aJ++6WYjRwWeVh//2Grx4t1P9fSHX1u7/hcb09PCYiDggwIK/rNnzzoYGRllYyq11BSKMjmudZhVJxKJfqiNWoDgNQx/VbVaIEAgLh/1BxSmJhhtoZrImugpa4uJiSG0rMETIxzXpo3Dffp9cbjvgObHBgxsw/CX5OtYhkUMGgxdGL7Rb9f+O+F4CWjIJSMMb8QQR3SsYHwMBuZivIuinaoobcDIi6YGpLkjDv/QoUNZeFw0PQhpvAJxEcAD8ANBYTEwMLB+/PhxuaIKS9XNy8uLLl26NEnwFgkQIOBjbJGGmlyb6xtIDsJSPT093xsQiBtFpLujNA/jKXwbwvEWiIuAajws6IlHSQiEBVk3dd2kRjWENgnHWIAAAQLEANGB9w/kRNYGLyF+Z//+/b5XrlwZ7+/v/3chJ0sgLk0ekCIlbc2Ozs7OtS4JVbfh8dBjj9kewrEWIECAgHc3ioaGhtf43iAiYiI+Ph7X0yJEeoSFhX0pHEeBuDRJwgIPC0pCmLuBKZ3K2KCyREdHQ+KMh4kNRjPheAv4mHHyifd/3XYOFc5zAbyBriNdXd3AiqFpfLeMjAzCdGWU4CMiIr4QyvACcWkyHxp24u+0trYuz8vLUwphAfFBrRYBQJA0hTsCAQIECKgeIBy1JS4VbxCPHDmSi5BVlPkxLVk4tgJx+WiVFszbwCj2muY7KPoB8vb2RhugP0aTh4eH/48wGVWAAAEClFcqknX9zcrKkvpgPOzs7P4SSvMCcfnogDY+RjIi6uplwQcmLCwMhCXiwYMH3ZFBIBxfAQIECOAH3OjJM+cqqnq7uLhwA4TRECFkZwnE5aOBh4fHv48fP55fW7UFbXshISGchwX5AwJhESBAgADFgRZndi3WE4lESlG/pRtuShEWitl8165dGxkaGvr/hEA7gbg0aiDUCEFHtSEsyGRhH4ZwtPHBwyJ8GAQIECCgbuQF5MLQ0DA1ICCAaut5qakTCao4Un7RicQe/2vByCsQl0YJHx+fb9iJnMWX4YOw+Pv7c4Tl3r17vRBJLZz8AgQIEKAcwBMIVQTXVyToVhdIV9eyPlqpobSzm9ZFsAsIWTACcWlUQGnHwMDgbmZmptyTHXcA7IMUefv27YEgLMLxEyBAgADVXp/hGUSzA5oelE1g4uLiCIo7Rgq8evXqVyGuQiAujQaI9Dc2Ni6ozqCLk5sxco6w3L9/v4eiszcECBAgQEDdS0jIwUKnEAy8BQUFpMytqKiI88FgFh0CSAUCIxCXRiFNStJyn124cKHE1taWgCtXrpRhuqm1tfUgYSy7AAECBHxYJCQkfObi4tICWS24VstTyhXdMIvOxsamHAQGN7TIghG8iwJxafBZAkFBQV8hQReAeQtMXzhxBQgQIKDhAK3Nnp6e34HAWFhYlKanpyuVwGAmkqQTKfL8+fOzsC4IXkaBuAgQIECAAAF1Ako6b968+dfJkyfXHTx4MBM+RGW2UsNTExMTQ4wg5cHIKySgC8SFNwTFo/o7Dvht4IhHGYvdcQjhSgIECKgToCqgHBMSEvK/6OyBCt0YlAbsI9RxGxubjggBRduzMgkMttTUVDp27FiepaXlJCSiCwqMQFyqZdKoZYLlHjp06BKA752cnH5qyhHOSUlJn8EkjLHu7ANU+vDhw/KrV6/CixNhZWU1Gh9e4fwRIECAojeHUC6MjIxOY3F+8OBB+b1798oPHz6cg5/hWtxYkmdxIwdfIrsmRqETSVkDc6XNGrGxsVwnEsLyAgMD/yacPwJxeesgP3Xq1EosyIykcIYpAIyXLc5l7P+0muIALWQN3Lx5c8j169fLqnZAIVwJU63NzMw2CrM5BAgQoAjgF8FAWHhFKioV+B4G2EuXLpXi2gIVprEoR1BFkGaOyH9cMzFFWpkbWqlBjjBOQCAuAvNvhuAhsP3qpD787Pbt2+Xo7W9qxwbyLcxiNc1VwrGB0174IAkQIEARddvY2Hg/lARZW0JCAtqFE5B30pgC26BSe3t7/xM+GBh5ldlKjYGOGCUAkiQQlyYMKCkIhMMJUdOGCaJoV0P9tSkdG5TJbt68KbNwC3Pa+fPnZwu+IAECBPAtrSD2gU+8PsouUC/g82hsyi6uiX5+fv84cuTIcZTClEVgUK5HxoxAXJow4NpmH6JQWXVJOL3B/JuawxveFkZeZH6IEGV97NgxQyFASYAAAXyAxfzAgQPpfM2s+D1ch9gNpjViI5CD1Zheb2pq6n+5urr+aGxsvBuvGz6YusxEYsePLCwspgjEpQkD/fKotco6kUBcDA0N09BR05SOjZ2d3V+M2cv8EEVHR3M+l6ysLEFxESBAgFzgOoobQUXj9OEZwbwfDEVsjL46mI1RfscIFyhOtR0pgGR1NI405S6jJv8hwgyg/fv3uyOCWZZcyU60QMyxaGoGOkZKimR9iGDQhaNeuCALECCAbzMEu1l0qE3pBAs9kmahOGRmZn7SmI+BpJU6nG0KtVK7uLg0+Wtuk/8QIY8EigFjwjWeKOjRb4qqAkxmhw4dusC+VntckPaIMltTU6IECBBQN+8Hum/kqbmySkfw3j158qRzYz8WFYY6voQPhh0bucQNqpO7u/t/BOLSxOHl5fUtFuDqYpzxM7BiuMSb4rFB1gJ7/c7sGHEt4iip4at0ECQ6igRjrgABAhRtijAxMdkG9aA2GxZ4dv1x/ViG0CYmJn4GH8wRtqEVPDs7u1rChoGP5ubmS5q6p1D4EEkAYgL3N9gsXNtgv5jgDMUBJZOmvDijCwB3NzCXIZgPQUhoIUe9Vjh3BAgQUNtyyZkzZzShntQUuSBLdcG1+mO7oQQhEYlEPxgZGZmy9SgXxwbrEfLEcKOIXK2mmCkmEBc55iks0nC9+/v7/x3+FyHa/h2QpYC6cmNz9QsQIKDhluodHBxaQdWuqSRd04bAUEdHx5Yf61okHbGC9QhfMRpBULcF4iJAgAABAhoAkJALxdvNzY23URWKeFMt4QvEpRHsJEyxQrutAAECBHy8gM8DpRDMLqrO41Fxg89OV1fXG6q4cOyUr6o39FbrBi0hotYHIxKSbZFcC2/F06dPOza1tmQBAgQIaApAGRrXfT09vWfsa7VBbeisQZouAjKF0olyyAqUq4sXL84wNDS8xo69HbydIJENdVZUgzyQCBc6f/78LJycGLiFHBWcwGi/xcmMBMXGMnxLgAABAgQo3nWEm1RdXV1/pOYifA4qjL+/Px08eDAT7dRIpBWOVd1Ji62tbTtM5YbHCCZprLXINUO+DLptG2LrdYM8mDBrMeJSUlOtEycvpjkL5SMBAgQI+HgBQyq6OtHFCAXA2dm5BcpDgtKiHMD4q6enF19TACvIDCoeDa3K0SDbwU6cOLETUfI1bZIk26imPiFTgAABAgQIqC0wfoCRQZlt50hPR8aMQFxkAC1gqG9iIrOs7cyZM8UYuCWcfAIECBAgQIDiTS9IhI+NjZW51iLhGOm+AnGRgejo6P9G/HFubq7Mg2lhYVHa0FigAAECBAgQ0BiArBiEiiYkJMhca5HWi1KdQFxkIDk5+VMjI6PTKSkpMuWrQ4cOZQUGBv5NOAEFCBAgQIAAxWFpaTkJnlFZG4L+Xr169atAXOS4nG/cuDEULK+mLTU1lQwNDW9iCKBw8gkQIECAAAGKA8nDZ8+eLa6pEUaSlxMRFBT0lUBc5CAsLOxLAwOD+9UZdDFcC+1wcJcLJ54AAQIECJCNwmZEBTxQ2OQ6lXDzjw7dly9fvpdYjLwcS0vL0nv37vVpaGNeGuwBRcvbpUuXJjECk/r48eNyGITgbsaQP0wsFtrhGieQyoj378qVK+oIFDx58uS658+ftxUSMAUIEFBnlBc1KyvN+qS0OPnz0sL4L0pygr8pTnFuW5Ro31Mukl51KM7ya15aFPdlSVHyZ2UlmZ9S+cdPZkBeQE4wxJF9LUe1A+UheE1fv379C7wwDW2fG/QBBTlBHz+8LBh6CONuQzyIql7kUYdkhO0s0gzZgj8eP2uMGTYgJyArmHaKYEFkB0CKRNCRoaFhmp2d3V8CIRUgQABflJfmfFJSGPdlfoZ38/RI27ZJfjf6x7iaaYTa6moHPd6p731nrYXzxTkOL89M83glD2dnuXjdWHU9+ImOftDTvdrRjscXpARcG5keadMhP92reUlBzJdlJVmffMwEBsMcfX19/4GqR0MO+BNO/gYIyHJIK4S6hHHmCAHCAg/AAX7hwoUSJAvDyNxYXhMydw4cOHAlICCg2loqSAwM1wibqk8/VURExBc41ig9IvY6Li7u/wrnoAABDbjsU5L+WWlOxFe5CaLmyf63eoa+OKDldXuVlZvFLDeR+fho0amRSc5mQzKcTdUYBmU7mwzIcTrRP1c+BuQ6m7Df5/5uSKro1IhUN/NxcW4WM7y8rVdaBz3bpx3vdVktN86pZUl26NdUkvYZlRcIN1oCcRGAQWPXrl0beeLEiYKsrKwau6qsra3LG1pvfU0ICQn5X3iWGEmQ6V7H/6N0BEKh6n0CYTl16pQWBro5ODgQQpigBCHYELIpxk4I56MAAQ0EZbmflBYmfJHFyEqsp8XI0Ge79X2uL7F1Oz8p2OXk8FRn08HZLoyguJzom+d6ok+e24meBXWBiAGP48oez9mkfw4e39lsWKrbOfVon2sL7UOe7DgcLTJXz4h51bKkIPZLKsv5RHifBOLSJIH4ZQy5wiIKY5SsDXM7QAYauuoCpQUdYLKSkKVbQUEBYcCXql8T5lzVRKQwpwMzskBelF22wuOpuhSmyudQ1WM3xn2u+hwNfZpuYy4FFWVHfJkZ8aRL+PP9+q4WcxxczowPdzYbngR1BMRCJCEaUrgpDb0kEH8v4khRvzxOlWEkxuX02GjRRQ2nIEZiUgJv9S/MCvm6XCAwAnFpSl4WzGdii2lyTSpLdQssW+TjGvLYA3iS4MsJCQnh9Zow4Gv//v2+SE9W1T5h5gb2SZb6AwKF/YiMjFSKYRj14nPnzs1HIjSDA8gp5q4oy5CM0iLCGI2NjfeD+Emfw9raelBdjyW8VJLH3l3xsbH/eH/rUqaDVwsKm/S4YCYKPFw4XnXZZwzow+RglCbxuMARtr18+fJ3jBRRVplRVfsvgP5PWXHGpwVpXs2TfC3Vgx5vM/Gw1HBzNhuR5Hyify6UkKokpSbSIlIacZHAuGclIuMCNYaRGNGF6V5BDzeZx3ucnZId79SyrChViOoQiMvHCxAPXPxwl4+Fm+8GRYZdmNMbaggfSjHw6LCLOO/XBBUJi016erpK7lqw2GCqLEpC8vYFPiJljJTAawFpkapoKPOBdOK46OrqvsHiV9fngEcH5mYcPzx+1eeorW8IpAXkB8cCIzgq7j/IaG33H+QBxAf5ESDq0sfFVyhz7HHDa5uKDXMhiBV777iZZtLjAX8YOhNBwOpK5uTtPyO9HlBPhetbbRWWkK8TfazUvKy1zF3Moa6oZbgygiAlLHIJh7F8QlNrGL//+C5sv1xM+uU5mw7OcD0zNtrbeqVV/JtLIwszAr4pL80WFBiBuHxcwILCLtLe6KqpKQBIljqBke+qVCdqCyweuPuU52mpumF8PRYEVe2Xj4/PN7ImoVbcbGxs0ILfoa7PCYc+nrM6UpqRkcEt0l5eXt/WhYyh6wwLdXVbcnIyRzDQlVcbQoRx9yAq1W3oDKvN/r948aI1Fv2ayqGSx41SlHDhJoCdd9ayzjuRSEQmJibb4CWrzfFGVyMCMtl5Wl7T/uO9gHm+PrxaH4+HJb9ZUXbklykhjzqEPdfV8bSc6QWDLEozomoIiXLQQ4K6+2HeeWIYgTEbkuFxcWpw8JMdh5MCrHsWZAR9DUImvM8CcWn0QAcLLvp8S0NVN0ZYCFO0UWZqaEoLVBNFlBZsSENGKUJVeS5Y1PT19R/Jm8sh3bAwIcOgrs8LxQLhTrLeR4y4qO1CitIXXhfUlpo2dHJB1VO0hR5KkTzyqej+YzHH48orH+J8AAnhm46NctnFixdnsM+VzMfFDQJIEyPJP9XmeHt4ePybvd6smsic9KYCZLWhpY02WJWlOOPTvARR84gXB7REF2e6uZwckQSj7XsKi7EqyIvy4copMCghDU11uzjNP+z5Pv3s2JetytGFJLzfAnFprEDHCmrufBfRqhtkb7ZYJYH8NKTXBfUHeTNQkBTZoDzAU1IbVYDvXfKZM2c0a2rFrq4Mxxan7LruDxZTEAZZ01exkB4/fjwf6kZtVTtjY+MCWYodXg87XxIU8UPBbApijPdG3rFip3IuX9UFxwRJnXzM2pcuXSrle1wkA+P2y5pxJt1wftaGyMGECw+LPHKEDfNfzp8/P1vIJZJBWMoLmyEkLjX0Xs+Ae2utnE+NiXYxGfiWsIiMay4BNSy8r9y8KyENyHE6NTLuzdVFtgk+l0ciC6a8TGihFohLIwQWRPhTFC0PYUtPT8edaGpt7xhV2akDpUVR0oI7a11d3WBleD1qgr29fRu2iJTwPd5QEY4dO2ZYVyMn/C0gqPIWUxAqeC9q04L99OnTjk+ePCnnQwJcXFxaKEJcsE8o28hTMBgRKeJLMKTEhU8ZESmeipznVlZWo/38/Hh1ryEVFOGWihxrHBOU5Xx9fXmRX/iOBNWlepQWpX2am+jWPNrJeIG75WwnJ64s1LdSG7PIuEc1BKHhkRYRh8qqUEVvDYiYs8ngbNcL073CnhtoZUW/allakCyoLwJxaVzAxRgLiSILPBYItvBw8jkWiYbUfinJabGuTXkISosqQ+fgMYEXiG9JDgsOMnQwfKyuzw3iY2RkZIrXKe84gPQpOjQUZUKoIvHx8XJfFzvGBG+GsokLtjNnzhTzNTKDuED94qO4PHjwoFyR90EkEv2AfeHzWYJKhHND0fcU5UNZQ+kqbjBk3759e6BwzauitBSlfJYR/rRD8CNtc7dzE8IrtjW/R1wqkZe6eFJ61Stxqfo6XIx75zmfGJgtOjM22u/uWovUwDs9ywoSPhfOB4G4NBrgzhedGoqUho4ePZqHFk9F7xJVDbQM10ZpAZEAaVFl9wUiq1E+UGTfcMcORUAZcdfwc/Api8CUjNlNipJRtCMzUuaK80Pexh6/TJHBpIoQF0UUF6nHJTg4mBfZUsSsjc+Gvr7+EwxilbcxQlGOCAJF31O0WqOdHqZnPsoOOoyEOVwSlBc1K8mN+SI14FZ/P+uVD5xPDk9yPtEvV1Rj946UuPRQudpSObSuB0c2pFC8RNWjRhMvXq/zyWGpPtcX2ya+uTSyJDv8KyF9VyAujQK404OHgs9dG+L+YeLF3WRDex24IKPlmc/dczVdI/6qbhm1sbHpCJOtgvvlirKXsvYBAyQxtqGm9xpqCxbb2mSi4JzA3T8fhQFlC0VeFzwjUIvQBi3vsTH8FKZVvo+NPBUcEz7vB84vRdrjQQD5lHJwzsLnUpuptyA8GELH55xCGe/evXu9mrzXpbywWVFO+FdxHmeneFjOckOs/rvS0DtiovwQueoVEmkHEDwoaGNGJ5Cr2VBuTAB8NkjgdakmL4ZfyaqHHJLUlysdic5O8Y98aaRVmO73DbqqhLVRIC4NGujAgIlVljkXd9FYdDGUsCFmtUg9LXzunCtu8HuAtKjS00Lvsk1SZXV/VNzQIo0AwLq0JtekisAvg84i5IpUXPBBSmGyVkQJqerpYPvLqyQHlUARzw7eXxh65ZFrSVt+FFrg+T42jjEMxfL2Ozc3F4TrpiL7DT8TxmHweb/ZfgfWJmQQJmf8LZ/cJZAvdMvVJayv8Ztw85sVZgZ9HSs6peGBNmeTQdmiSoSlHoiLcQXTrEn/HNHpkalvLk0J9rux1DbkwUaLsKfbTcJtdpqEPtpsEWi93MbHcpaX27kxcc5mg7Nd3itjyVOAesjMlpHC+cSAXNH5ycERDge18pPffEelgpFbIC4NHLh44+KHxauqxwJdC5CYcWfXEGfmIBkUnhZFy0O4iKM8pGrSAkMklBN5HTEVSQQCANndcWdV3Bmj2wplPowZAJlCOy2OA8pIyJapjV9J6p+BWVvehvMJplJFHh/vER81B88PVUSR8xTdcOikUgVxgZp58ODBTHkjM7Dh9dWmmwsqDbqL4Dnjc25BnQGhappKS0Gz/PSAr6MdjRe4X5juJfaz9KmitPRQff4KZ5jtm+dippbhgRblx1vNkz3OT8mOeNYhP0HUIj/F67v8FO/v8pPcm+dG27dN97s2MvqFgY7vjSX2ojNj4qDMiOqyf5W8Lz0qtE2zx70wOTjy5UHtglSf74SykUBcGjxwV4vsCSgQ8LBgOjIyOTA8EfkcDXGfUePHgqkoaUHOCIgaFmpV7h8WOXgoEDTGd0PZ4MiRI8cVNccqCpRfcPzw3mKhr4vBGiocusvkKSL4f3RUKarqwDCNv+NTymTnrpEieUIgLhhuyZe4KOI3grKB+H38rbwNQXFQrWprSGfncygf1QWKF16Hqs+vhlgeKswM/jrGxXSBx4Wp/q5ska4xjl/FGS0oz6AU5HdtvmuCq4lmfoJLy9K8+M/Li7OblZcVVvoclpfkNysrSP20OD3w68ygO/0jnu4wcb8wKdzFdKAM8iIhK8Y9FA6ugwLkYj4hOPLFAe2iNL9vBPIiEJdGASy2WMxgLlQ0W6K+gTtHvvX9ihduJASrKqelascWuoL43HFXIFTeDXV0Qk1At42lpaXcOhhKjmg3V3R+DjwrfAzkqiQukqGbjiB7fB8bfhhTU9PNfHxXUABR7qxN2ztIJ6a4o3OIzwYzsK2tbbumZMQtyon4Mt7DXMPz0owK5aH6B0cOTAdl+1yZ65bkfkajKM3/m/ISHlH8ZQXNyvITP8+JcmgV9VxXnyMvNSovUuLSsxYt3L0KMIMJ4w3CXxhq56f6CJ4XgbgIUBYU6QipSFpQFlG2d6Smu20YXfmUT6RlOXTE1Ka75EMCpYqzZ88u4jO8EsQCybaKlhxVSVxQyoO3Rx65hFoEgqNIaRGlPkz2xlwieZt0UGltzdjw9cA4z0d1gQIEJUgREtaYUZoX90WCp8VId4tZbk4nKpaHPkCSrUm/PPfz6tHRDgY6+Ume30FlUeS1QH3JjXZoFflsl4mb+ZikqnkzlQhKrYhLBc/LhSnByLYpzAgR8n8E4iJAGYBkj0A1Pq2g2NDyrOpwuYr7Zm5uvqSmmT01eT+QKYISTmN6H2AoxfwhPjOXoAigHKJoWQodS3wUHRAXmI8VIS4gUfDFyBpTIN2wD4qGLULRQdmVT9eehYVFaW0HOoLI49iinZ3PBk+NMgZ38m0AgH8HZWdkyaCTC6bi+uhuKitK+Sw95H5P3xtLbbngNY609FKZmiLvd+BrCbReZp8ZfLd/WS2D38oKEj/PCLrdP/DmMhs8nmqIWK8CF9PB2X7XF75OC7ipVloohNQJxEWAUjwakOFlRdhLN8kAQX9Ve1qkCwguznymPku3uLg4kgyCbHQZG1Cv+JRasCG/RdEwPSxuCKtDjoq8Dam/UH8UGSgIkoN8HXnBfNhQllR0/+ElgadEXiu31OeCFuraLugS1SWUD4mELwyfH1VNP5cCRAzmdAcHB0I4IboXMYIAhmiYtFXptSktyvgkLexZK4SsIa+kenVCucRFJMfbIjozOinKbs/homTP5lRapQRTktusNDf2i8IUv68Lk7y+K8kM/YqK3p8pVF5e0Kwo3f+beMcj2p4XJoWjtKOqPBnMOPK5qfkoOfBul9KiVIG8CMRFQF2BQDB5dX1JecidLWpf18c+4Q4brbt8JHts+D20PtcHqVIFkAvy/Plzua8T7ddsAYtUtBQiJRZ85v6g9Rh384o8PnxckhEHvIiLosMuQaJApvgYyKEYwZhdWzKBvzMzM9vIZ4QBSmOYtq3KpGh85qByVqdmQYFCWz662VRCXsqLmhWk+X0T9UJfR3RmbJyLikkLvzJR/xzPi1OCE1xNF5RmR1T2eZXkNytICfwqwcNSLdRmt37Io20mkQ6HtNIC73cpzgx/b6ZQeWHqZxnB93sG3tK0cTEbnK0yPw47bo6mw5KC7q+zyo173aq8LFfwuwjERUBdAIMtuzBG5Ofn19gei+6h+igPSbucsPDwWTikG5SZO3fu9G9IYxMUIRVYKDFPiY+qJEm/VWhRhrKG8g8fRQSjKxQNR1Q1cZGal9HizofEKppDU91z8R0DIJ3UraryJJQyWTcW2MfHjx+X4wZE2ed/aVHiFwneliPdL8zwgl+jcttzPRKWCj4TV9OBOb5X5nileFuql+XHV1JXMS8IJMXv9mpuwCMUIpH5+PCA22usU/1v9UfXUSXiUprXLC/BrXkEvC6nRyWpQk3i0nol5IXtS3TESyOt/Iygr0EKhfVHIC6NFrjYoPsIeRXPnj3rgBo7MiXYAjLJxMRkG+6U0WIN+RtAfghq3TCuKqNjCXezMLPC1IiLMOLVIZPjDg+5Fhhep8o7yqqLOF47HyOmdEO3CcLY2KLeKE2SkvAzbz4x/zguSO6tzXtsYWExhc80baTmKvp+Swct8iFftra2GLbYpzYlHD7t4lLVyM7O7q+6kGd0J/EhejAEY8CqKia74/OAwEp5hBCfV+QJKfPmoqwk89P0cJu2vrdWPHA8UdUD8gGIiwScZ+TGYvu0gFvv+VuKs6O+SPA4r+51eZaXs6nYQMyVgMzHxUU82304L96tOZVVLiEWZ4Z9Ge98QtNdheWit2Zdk0HZPlYL7JP8bvQvEYYyCsRFEcMn2kghv8IQqeidqzKRnJz8KWYcgZigzIHJuegqgcIBwFOCzgUoIWjzlP4ciwPKCpCoYYjEBRqBaHXZF/gBUH4AccIChIsluo1QMqjP/Blkk6Buz7f1GaUTRN/XlxqkCuAY8zHNYsHGe17bch1UBHnjErAAomOsNqmwOA8xRJEP0YQ6o2gpB78PgspnbhGGg+I8VsSnUxWvXr36le/8MfhNYApXdvQBrhHw9vDJsIH3BWRLKQS+rLBZfrLXd2HPdus7nxyR9CE7iKpOaEbybaC1pg1KPOVFaZU664oyw7+MczHTeHNpcjBKSm/nCTGy43ttsW1awJ2eVMVjUpqf+Hmqz9WRvlfmuYHsiFQ8P8n11PDUsKdbzXMTXVtULV0JxEVApUUZF3vUyHHHZmNjU/769WvurkyaZlufBAZEALIu2kfRBcPnTlvWwo2LNBa08+fPz8LduzKO14couUiUB1c+C1NFoyqyNBrr3BgcZ7xvfJQQEFiYj2vr3UDAmrzIf+mCX5t5P2i3hlrD14NSm6GXUCP5zC1C9xtSjdGJU8eOu+N8VBcQbXQ91WY6tbJKcNgwLkIZXXWFuXGfR7menuJ6dlIwSkTvVJZeKpzKzNMvwnUUrbDJDH3cobyo8usszAj9MtbxuKb7hYnhLib98ioGwnlcmBIc73pSoyQrvJIvpqww7dPMkIddgm6veoD5RtJ5RipTXU70z3U8PTY64vVRzeL8WGFYp0BcqicJKK8gxRYtv1Uv2qiHo6YP6VrVizWUHlx4sXhgoeKrKvDZ8Lpwx4XXiYUHvpXG5PeAsRA+AT5dL9INpA+vVdUdHapW3TDjis/iCDWOkZzZdSkJ4vxDqaY68gLCiHOztgZnqF4ICuRDXJDUXJuQOJSwTE1NC/kQCShxdQ0hhCKKXCA+5Smcu7VN7ZUFhOLxTY3GfkIlqss4gvLS3GaZMa9bBN5fb+FsOkTlXUSKAsQl5O7KB9nhNh3Ki7MqE5f04K9iXh3Wcj8/PhpZLxU7kVAuinyuq5Of9Oa78tJ3SgceIyfaoVXYo80WUENUTVzw2I4nBmZ7X1timxr6pG15WfYnwlotEJe3NXe0EOrp6T3Dh14WScCdLNof62Lmk7cvMCPC4ApJWZmEpboLF1qbMdsFXpjGsKhjQQVxhALGZ4HAJmnNftkYW5+rklkEnlUc1ihLXart8EYp4KWCXwoDEf38/DgSAcKL0iN8NjhPa0t4QVz4kArcQIC41EZxQQkL+ymvVRnn0ZkzZ+qcsYJ8GoTxwRQtbwPxY/vmrOzhiyCSKCXz7bBDyzhiC2pL2opzY76Idz+t4X5hcrDziX65DYm0YNF3PTk0I/T+mgc5Ec9bVQqe4zqgAr6OfnlA2/3c2LiqxEV0elQS5hnlxDi1KC95p9CWl+Q0y4t3bQGDLgY1yiMuojq/hh6cURfm4YgX+jqFMOoKa7ZAXHCxgcETdx58yw61ycbgA9xVoisAF1FFSiB13bAQotMA3SoNdUZSxQUPxkJFWp8x1BB3w439XMVr4DM/SNIpE6GMUiDKoiDpICkgjAg0Q5mnrt4IZNHwIS51UVxQOoEyxyf+H8e1tkF0Vb07fKZTS7vbbGxsOirzHMHNB8gmnwGQ0g2ktDadTmXFWZ8kBz3s8Obq4kfOpoMz6nP20PsZLj1qJC5hD9Zb5Ua/bAV1qCJxyU/1/zrSXl/H7czoKh1Cvbi/C76nZZ0VaV/p79BZVJDk+V3U832H3U6PluvnqdO0a2Px6xKbhgdmu1touMV6Xu5fnJ/4mUBcmnB3Dpz9MLOhjKDIhqRMdnEapOwyAHw1fGefqGKDkRfHo6EqE7iwotyjyMgBdNbgvaqL8bKhAAQbiwwf4yUM0w157hXKk3zSbUHgkQkUFRVVq3MSXVV8iAQMz8q4GZF4r97UFBdQcZOMAXCsq1m+Jv8Xn32QlsqOHDmSq2h3WFFW6FeRLw9oO54czWW2iIw/DHERVSIuvSqZW0WnhmWEP9polRfr1KK8YvgciEuK93cRtnv1RadGvkdAOG/M7RU2mSgxlVS4dpQWNENYXcwLA50aiYuxktu62VdXY0ZeTg5PDX663SQ3+c13AnFpgi8ad4tIkIQEjg4cRTfU/XHnqcz9gdoBE/CH3mC4BHmBObMhLnYwKfMplWCDSREGVWXL8R8CMI6yRc6OjzkbpRzk1DT018Mn3RaLKhSz2hpZodCBIMkquUqfg5HCOptlQRbhk+M7BuDJkyflCBRU9vFFlxPMz3zLqQjrwzWIL9kFCUiPsGvlc2OJrdOJgdlYWKsdOniiPslLNYoLiMvTreb5iWhtrjAFurywWR4jAGFPdx52NhuWyu2/ceXo/YCby2wyQp9UJi7sMYrSAr+OeXlQW6zU1EBcjJX/+mEa9r4y1y058E7P0ip+HYG4fORA5gJitxGHXRv/CC4EuCAoa+YIfASnTp3SQqIl34uMdMMiBuMu/hZkCmFdMA+jEwqvD10D6JhQdMNjolWytne5qsKLFy9a85XhcWzQFYayxsdw3mLhRjcYn/MTpca6+ltUDSyQJ06c2Clv7hVeD9SA2uaeQMnE511WJxYyiOBvU1a2DwgQe7x4ZLbw9Ji4Im5BmcdXknGkjusC35IqlCK+QyCL82K+iHM7rSE6PyG8+nJJj3rKb+khs50YQXGRtjomaNeu9BrKCprlJrg1D320xdzZVC2jskLEiIsJIy43ltinhzyuTFygNKUHfxX7ykjbzXx0kkhGiQcQKTVRt0+e6OzYuKjXRlqFWSFfC8SliQDlArju+X6Ya7qLx6Jel9ZJqtBCidKHIuUhXMiREouLOS7IkLfRvg1zHcybkIkxfRc/A7lCZwnMeiiH8bmQSjf4Atgd8TVly9h1LJWo8ynrgZBCTWvoi7ciwCwmPgMkYUSFeRznQkM3xCMwER4WVRIXeheD719dvgnOFQxaRJu8Ml8bFF3cOPDZkGfz9OnTjso+xui+Q3s0nyniOM5GRkbZUDXlPnZ5QbO8RNcWoY82WDmbsEWfLfTuxpUX7HoPnatGhQFxcT83Ji7KQV8HRlyqMqMoJ+Z1y5D766yQ2/KeumE6KNvv+iL79KCH1RCX0C/RjQTi8h5pM34/S0akpPlLXMYMI1SBt5fbZEfbdigvy2smEJcmAElXRiCfgWg11aTRAookWmWQKHgvoI7wrUPDcId6Pwx9KH/w7ejAXRQIDggXDIF8X7+EIB1XBklTBnBx55OSK82n+JCBgcq+e4Y6IW+Rx4bQQUZUrRvKe6YM4oK2/bomzUo8NWdhwkcrMvJdYEjH9QCGWmWfK9JrDR8TOW6GEA4JdUjZx1k6x0teiRHXF8y14qOylhalfRr7xmKki/kEcSeRcUVPS30Tlx41lo5guH1zcVJ4vIvpgqLMyr698uLMT7LCn3aAjwVBctWVZXyvzHVLDbjbpbyocvmsOCvyizhnkwVu58ZH4/WLqiMoSiAuouqIC3s+59NjoyOdjBcU5yd8LhCXJgAoEMhZqA1pgSEUAXSYy6KMADMnJ6efcIfDx6+BizvKHmhZrkvXDy6MKLegRZSvwZXd6XNzfRqC0RNlHygpskpqkP2R5lrXTI6GBJilsQjyUcyg3kFVbOgheyDuUAz5EBfkvSij5IcOQqgvIPFIIEZnkyq76NCFhZItn5sSlAFVkegMggi1Tl5KMSIDQJ74RCLkpgZ8FfJsrw68ISLjD932XDNJwpwiv2vzXVP8bvQvzatMCsvykz9L87+h5nttnquLyYCc94Pf+uV6W87wT/GxUisrSK30t6Xsb1P8bvX0u7nC2vWMeriz2YgkZ5MhqU4nBmeIZzSpJstG9C7ZNyPwwSbzrAT37+DVEYjLRw4ELWEhVtRHgo4DdPwoqw6N9lKQBz7R3DDLwmCKurmyFiOUk3C3y8cMjDtG5LwoQ2VShqETrbE1zbjBewUjJhamxpqOWxNh4xPWJlUnsCA3li4pPsm2KO2CtDe29w2fc3hd+HjpcCNR17ED8nx0NX3ecd7AG8cniK68NOeTjHDbVn43lz/ALJ26kgulEpeKwxWlWSxPtplkxzi1KCuurE6XZEd/kSg6pfHmAuL++71HNNAl5XlhUnii6LQGfrcS6UFLdGrA1ym+N/rHvjqsFWW353D4o80WQbeW23hZzvRyPTMmDr4ZTo1RAXEB0fK6PN8pJeBOl/KSpmnSbVIvFjkNfHIwKvo8cPeODAtlTXPFHRC8Gnx8LQiHQ+eFKvwKuJihnMKHvIA84e64IaguIHCIZ8fxKygo4Hw7ICwI64OPAe/xx0Ra8FqgoPDJ5ZDMDvLga7D80IDqiEwkPmZxDH1sbO8d1At8btCxw0d1qUv3FB+1FUQR1z8kL+NzA6BMhWYDnGN8snJKCxI/T3pjoe5xcWqwUwMLnHubwYLANpPBGd5scU/0vDSyKvFAS3NBktd3UXZ7D4tOvT/lGSoS548xH5OEvJb8RM/vqGIrNchLSV6z0oKUT0tyY74ozg77qjDV+7vcaIdWKb7X+0e/OqQdcHvVA7dzE8LhSVHG7KaqJTDROfXoOJcTmiV5TXMMQJN6sRKlI0peeQYLITp0zM3Nlyi7lVZiFIyU5zMBWYAnRZWZKjDv8SEvuKjiTr6hDCcE6QKZxGBH5JXgNeBusSEZiZXZBQeTNLwrfDxJOGcby/gGqHhnz56VawKRjC+Y1RjfP8lg1AI+qkttB0oqctOEZF2EXGJYKwCfHX7G96akMCPkq6gXBjrVZZ/UeZqzMpJyQVpMB2e8uTTdP+b1Uc2CFJ9vqLTyjUxpQdJnaQG3ewbcXGKPtueqr0NkLFZwRGZDsgJvLbfJCLrXs6wgRbZnjJEhmHjLClM+K8kK+Tonyq5DvIuJZsAtTRsR8l4kqk5V7wpfD0wl4oJMF1O1jLAnW83zU3y/EYjLRw58OHHnJmuhxsVfqrIo27AHGRhqi7y7Z0kQ3LX6aEfGwoj8BnlzfySzjYxqk2Cqaq/Ex6SwVAU6xJCCy8fkiZIKJnYrW/HB56A2gxSVRVxQRmmsxAUk28jI6DT7yquzB+pHfaQ843Oj6HuKLpbM2NctA++tseZfJlKAuBjXMqBNqrLAX8IIlc+1Ba/jnI9r5Se5N3+vlMIFyPl8E+NwQNvtnHq064l+eTWFx2FiNAYwxjgY6OQneTSn0hze6wFShUuywr7KCL7bP+yxtoX7uXFxeDxXyYgAUR2SdaWDIH2uL3ydhvlFCuyXQFwaKaCgoJYMky4kaORIYLYITHTwcqAWHBoa+v9U9dyYTyIr0VLqKVFWTgwfIGwO3UqywsBwUUVE+8eSi9JYgCAxtOvyKTVgUCCIjjKeF5kmIEEgq8g4gc8Knw20mCtLEVCEuCDGvrG+h5goz+c9rKC67IeRuKG9jtKS9E8T/K+puVnM8FL6XCIexIXr3pGUcTgY98mDF8XFZGCO66kRqR4Xp/mHPtI2T/a+MrIw1e+b8mpC2krzEj5PD7zTM/CWpg1Ui0pqi/H7ZScoMr5XZnsluJpoFiZ7NC8vSvsUqbu8jxl7vsywx13CHm+2EJ0ZnYTjpgylCq/b6cy48EiRmUZpceIXAnFpAoBfBSUbxIFDNoX7H91CMN+q0scB/wXCwWR1xcC7cenSpUn13cqLY4HymKyLKoyU2LfGNEm6sQNSPh8fEu7oQTKUcd6AyMJbhdwYqY8IQJghzhGolspQ3kCC8Xng4/WCmbyxjm2AqZzvVG+UsdFBqIwUX2WjMCf6i0jnY5oi87Fx4sW3h5LmDPWUzOPplwvVBKUeZ7MhNWBoqvPJYakuJ4cnuZ4enSQ6Nz78zWUNt9BHmyySPM9PyYt3aVGSG/d5een7KiyGLObGOreIsNtz2O3cuOj3TLnG1YfYIf7f23KmV7S9vk52xLMOJVnhX5aj0whDG/E8ZbI7e0ry4j5PC7jV3//mMhtnM5CluncdYb+czIYnBdnsOpyb5veNQFwEfLBZM5L0yg8SHga/Cy6usrwUUGT09fUfQf4W3k/VA+QAXVR8/C1IT1ZGdDzUFHiGagr6kwa2QUWo63NB2UQZTF6bN/4fv9fQkpwVARRUPkMlsSFfRpkjRZRWNkwN+Cr02Q4TEAiRnNRa/sQFZZ5+eVjQYWb1ujzfwe/2aqvgB5vNQx5uNZEiGHjEvn+8/XDo012HI57r6cQ4Gi9I9rqknhX2pENh0pvvSvPivqg0SLFSiSi3WVGq3zcJLsZaXpbT/REwJ6qgrNQ4Y8hY4ptBaeycenTATU0bzClK87KYkhP6oGdBrEPb4hTPFqVZYV+V5yd/VtXEKy6xFXBjAlC+8rw4KRxlHmX4eZxNBmb73Vr+ICPqVQuBuAhQmZdET0/PQVYQFBYLkJsP2eWBtkhZ5SJkz8DMJ7yn9VPCQ3iYPGOntIynjJZ1PiGNyF45wra6dtohORrZIcjekff60ObeEOdnKfJa+ZJQzE9T5ggCZSE30eO70IfrrbCIi5QUFocyj5u5enSg9aoHia4mmrkRT7oUJrq2LEp507wo1ee795AG+H1TnB70dUlW5JdleQmflxdlfoII/xq9OcWZn6DrJ9Ht1AJfq3murmZDM2QrRj2qDZIDwYL64mY+Ls7z4nR/7yvznXyuL7X1v7veIuK5vnay1+WRefGuLUry3g+GKy9K/zQr7FEXpN5yJE0ZIwBM+uX5Xp/vKva55DcTiIsApQOLPaLLZV2wsPjUtnMHd8oodSGjBRfJ2jwGunLgdZG1aCEHB0mjTY1A4DUjxh2lMoT4KXu2THVAHs3169fltqOADMNQrgxFAhkwCEOTVc7E82GuTV27uHDOwrgqb54W9sXQ0DC1oY8xkAckP2OoIh/V5d69e+XKNlrXBSi9pIU9a+V7baF97f0tlfNcsPC6nR8XF/50mzk6d4ozQr4qL8qonoTAV/IW/EPXSguSP8uNedUy7vURLZ8rc91cTg6tUKp5N09IpECJBgTG9UT/HOSpgHjhMd3Mx8Z5oWT1ZOfh1MD7HVCuqnz88pvlJ7o3x9wk8XDGvkrxuXhYTA2Of3NZraQg7ROBuAhQOuTNmpGMuH+Gko2i+QwoEWAhgV8AkeaQ1bHIKpoKCg8B2mll5U6gTRvmZlV0mTQ04HhgsUG+Bl43FljcDSMzBlOq0YKtqo4mPDfMsPB38PGAwNCpjKwh+E6OHz+eL4u4SEqagXUlSvCTnTx5ch0MqbI2pLqiy662hJyPGgrTMTr+rKysRqOso4qRCbipwOcUviF5Gwz8MPI3lEye8tKsT1OC7nV5c3mWl4uSPBqiU8NTQ+6veZAZ8qBnaZ6S4+tLcz6BFyU96H6X8Kc7TDwuTApHtL+LpKun+lbjHnVow+7DmYThuQm33aOfG+favLyk8rWhiBGzeKfjmp4YTFlN6J2iZmaYk93PTwyPFZmrF+c1rfK9QCrq0d8ia9gZSA2Mwop2fkCyR4mp4kKD79EpBfVE0S4TRKGzi3eNd/l4XCySDSGMTtVASzy6Xqor1cB3cezYsTyYulXlOUJpkc9IiOfPnyvF3yJtv5Y32RheJ8xDUkbnC7qmkEwt6/Wh+08VXUUwMsNLgi4+fDZx84DXBhM68p7g41EmMcVj4QYG7xefDZ2OGLfRED4LZaWZnyYHWvf3tJxRN+IiKb24Iv3Vcpp/gtvJBcVZoV8pK7oeBtySnKgvc6Ofd4h3Pqrtd2Oxveup0XHwlYiUnGD7/kyhXgUuZoOzA28stU8PvNuztLBy911pbvznyZ4X1b0vTfMX+1zqligsYsQFvqAYl1NTiqsoPAJxEaAUQAHBXbssc6UihjzpRVDWpGvkwaDTRJEFRl66MPJcQFw+lgGGskghjMiy/BcSpWO3Ko4F/Cp8zJzKjvnHHT58J7JmCKHLCeqEMhZ1lNwYUXKsqRVfGkcPQq3sY4zyH8716kgaCCPGLIC8KvM5JSGYgfKGHlYoyQWrKp5BoVbogrgv4txOabicUQ+vXOZQcPGVEBd0DgXdXmGTFfa4C/wf7z0nOnXg2wBK8it8z865klwu7A3tzmWMHJTmJ31WnB3xZUGie/OM4Ps9412MtYLvrbF2Oz8puGL0vqjG0lWPGglKdaMEoNy4nhyaAZICElepO4oREph/kzwtRpbmJ1YiE2WFqZ+m+d/s73tljpd4PlLtiEvF6dcgZeHP9d6ffi0QFwENkbiAjGCBkeUPkGR7pCoycFAgLmJgNo48P4IkYt9X2Ym9KMMhcI3PIExGHriSgjITnmHSRiZMdXlDKCNCbUHZQ1kqBAgESFp1IXuY9H3s2DFDZZdM+BBTlAUxXkKZz40SIMpR7BjzUl0aSodRaU7Y11EOhtovTUbEVc4hqc3i26vA5eTw1LDHW8zRvlxexdNSxohMcUbw14WMiHBGXQ6iFkUJri0L411aFsQ5tsqNftE2m5GedL8bagluZzQi2b6FPNps4Xdt4WuP8xPDOWJh2j9PZNJLhn+lZuJSVU2Rhr6JTo9M9bOa6xr5cI1N4HUNXxF7nspt3X3zUAqKdzFbUJJduZQKE3FmyMMugTeX2Dsz0iNSguLjZDo0NeihtkkuBi4KxEWAsiVp5FDIuouFCVORu0q+E4PRuor6Pd/H9fb2/ic8HTV1ssBvgIVLFR6AhgIsypj5I++uGMcI3S7KztyQdKA943NXDiKB9mVlZpyATMBMDuMsfFNQ9bCAoqSCMQvKNiaDqCEtFiQB56uNjQ0W63L4iDBDRxXdNSiJIS9FlpdH+vkBkVPmc0vawAP5pCFDNcVYC1X5e/gTl9CvI1/o67w0GV5rY6l4knQvsb/l9KikiGe7TAqSPL+rGOhWXpLfLC/J9+soZ/OR/vc3m/jd0bLyuysB+9739horP+tVVv43VzzwvbbI3sdylpf7hQnRojMjU11PDskSmQ7MEXH+kV68BzLKN8H2yUPrschcPTr0wVrrdJ9zC3IDLRfE2Gyydj89KrUikeNmHJ1Tj459ZaSNzqeqZayscNu2wXdXPXCpQnhqCyfTIYy4bDLPTXBrrkgwnkBcBPAyIWLYmqzY75s3b5Yrko2BxYMvcVEkQhwlB7Q813RBRzsnwskUNRE3FmDRxh3uw4cP5XZ/oJwAKV/Z86ygkGHR5jPfBqoQDMSqItw4z0DMsE8gVKoMgUOXEQi5v7//31FSQV6QqszPUBb5pPZCCUVJVqltxbm53OBMkUgk9/3F5xvk+EPPCQNxiXpLXOqS/CqO50eKbKTd3sMFKd6ViUtxTrPsyNctkNvieHJsNBdGVx1MBmejLZtLzTXpl+dajelWrj+EB3lB5xPUIe/Lc9yiHQx0spHdEmPbJdnthLb/dQ1flyrKCXdszMfGRb3Q0y+oMkcIry0n8kUrkB/XU8MyXOqcoNtLorhIiIuguAhQNpA2KqtbB4Y9RRYgdBNhCKOsmH4sfLhLRkow38eF2VRWminIF6R7ZU3LbmhA2Qd3/nzyNmDmRLkB74Uy9wHKG5+pyVjUQHCwyAufMcUg7zyvaEaHT0zZigeftvOK5mR0X33I8mxl4tK3zguu2+nRcZF2+/QLkr0rL+5F2Wxxf9ky9P4GC+StuFVTsqnNfB+Z85GMq0vzZQSLkSKoJyH3tKyTvS5OKUh0aVmQ4Ngqye3kAr/rC1+7nhyWWvVY4N/uZ8bEYfJ0QdKbSuWb8pLcZjnRL1uGPdpohY4qZUT/c4rLA0FxEdBIPC7SFmtZHQq1uejKuxP92D0uGH0A0sBnQcF4BkU7wfiUTXCuyGqdl26Ys3XkyJHjqpom/DEDChL8X/LeZ/h80J2n7NRefCZRAsJnVN6GGxBkQH1I1aU0mxEXe2UoLiAHEsXFdu/7xKWYEZcoh1YgLs6mQzL4jAtQNnEB+QBpwoTpSLv9+lmhj7qUZAR8U5js2TzJ/YxGZdLSqxIhE3HEZXRSlK2OCXJbKo4DQKpvTqxjy/AnWyxEp0ekuiiBuDhXLBUJiouA+iYumM4M056i6gDaoSE5VywZ4WKMbAxdXV1XRYy50rt9WaFnHzNxQWkC/h15gWjYJFkmkcpOc4WfA/sAY6i8DW27HzJp+SN4r+/KUiylnyUYh1Ux9BQ3Cehc4kOS8XmGT+5Dfe6UqbhgcXerSFwqloqKsptlRzq0DLm/3qom4uJW7biBHgUi4+qMtr1q9LNUHDsgJTAw4LqeHh3nd2OZbYLrKY2CRFGLsrzoL4vSvJsnMtLie23+a1dJiJ2oOiWJwf3MqKTIZztN8hJEzSuG6UFxwaykcJvt5vD4KE1xETwuAlQFDHLEHbq8soOi2RjwHTx58qQzfCcwG6I0BGMnlABF7xLhX4D5UlbeDDpdEFLXWAfeyWuPRTIwn24PkEVltQRX5zHi42+BfwmLn/D5qp2XCeVbPp1bqvIRYRYV2unlBfBJCRT73QJljHX4sB4XiTLBeVz26b/nceGIy4tWIQ8YcTEbklGbRN6qRIJfIB7anAdnu1+YHBz+dLtJetDdnsiXKS9M/Lwwxeu7BNHJBT5W816LxwWISYuohtcGxSXymc7h/AT3aoiLUwskBbtVJC7GgsdFIC4NFDA4olunprsr/Bx3X7WVg3EnBhKDtNzalg6g4EClkdXNAhMxIu8/Rm8LI3x2aC+Wt6ENmh2ncFXMzsGxxTHmUz6Av6Uxz+/50JAXtlix5Mo+mztVQdah5CDIkA9RRYcR1M4P0WGkdMXl9Bixx4WRgqoeF6niIvW4KEZceojzTUwH5oizVtQyZIfPwSzcP8f11Mgkn2sL7WMdj2rlxLxqWZIf/3lZcdpnhYxYSUkLiJRs0iIlLvC47DlckOhZ+bUVw+PyqmXY480WolMjxB4X47oQF8HjIqAepGksjLJIAaR/lJQ+1D4ibEuWKRQXV5Avtp//+NjuvuEvQssvH7UFfiR0haA7RNn7cf78+dmyFC/plpKSQpKhfYK/pZbgO8QSEf2MqL5UxVR0GLvhdeGjukjM2AmKpmE3TI/LmOrNucVZn2RHvWglq1T0HnGosPhz3UWMsKDjJ+qptlXYg7XWnhenBrucHJb6NojOuMc7lcVMrLKEPdI2T/O9rlac5v9NeVHap+UlGZ8Wpvow0nJaw/fagreelop/Xz2BYsTFfGxctL1uNa8NXUUOLUMfrLcSnRqWoQziInhcBNSLz8XPz0+ebyL8QyRl4gJ66NChC7K6aeAHYBfOJ6q4gH9ISNNb+agtkjTTUFUoHSgTolNM3rRkbDDvgjwJn6u6HW+c8/L8RNIyDTKOVLEfyFmCj4aP1+XZs2cY79BHVW3i9edxYcTFtvquInmKi0ziYtIvz8diYmSik5FOQdzLtrkxL9omuptrBN/fYCG6MCUYk5mRdismLcNSvS/Pc4p5aaSVE2nfqhSx+aV5zbhp0lBaXM0W+FyZ54bfk/+ae7wjLufGxcW8PKhdVCXNFsbj7IjnrULurbGGGiTLfyN4XATi0mAAWdjMzKxI1gUKPhgYLut7iCFKFFevXpV564kUU/g6lK00fGhgCi9fb4uLiwv3/qiibIC2dVnlxPpaSJuSzwUzkPj4XKDGoeNMFfuBTCR0h8kKqJRuILUg2crODpKHktzIr6JeH9Z6bTYqTqkel2qJi6Iel4qR+wNy/C/PCEx7c3ZBaU74V+XFGZ+W5sZ8URDv1DLZ/YxGwG1GGs5O9gf876yxSvWyVC9K9f+6rEhsei4vyWakxeebOBfTBV6XZ3nB9yL39VZSfPrmuZ+fEB7nckKzJCfiq6pqUlbokw6Bt5bZI/9FGYMqncyGJwU93nE4N8nrG0FxEaAS4GKDi051UeoVVRcETqmii6EmIAcESbEwCMvacFeI6cEfm7cF3SV8clsk3pYoRTu1+AIBhNbW1nIJlGSSuN3Hpnx9COCYy+qiq0vXnyKAwV7eiImKJEpZQzX5oqwk7bOUgBtqmMOjpByXdwF0dfa4VM1RGZka9mCddWbw/Z5iFYXdaJVkfVKSHflldvTLlkneVv0T31xRy4p80bIkO/oLqCxQK0BasD8gLVBa4I+pkbRUaaWuOKvozaWp/omeF9RL8xOqzCpK/yQt8HZ/32vzXBGcV9dBj1w79Xn16Bi2v8WMnAnERYBKgLt0KBayuouwYXgfFlOkiKp6n2DohfEQaoq8fVJFEFdDUFv4mGGl5ZlLly5NUoUahkA/GC/53HWz84JOnTql9TF2dtU3oHKxz1qyPJ8LSjQ2NjYdVbUfiowBQEkTNxrKHr0gm7hkfZISeLfLm8uz6jYdupLiwohLLTwushQPMXnpn+N+ZmxcyIMNFmmBd3uW5ICc5DdDpkoZe/zSvKTPSnITPysryqqQ2Jv5SUGyZ/N4VxNNH6s5rojkBzGo0c9SgzfFxXRQNmYZpfpdVystTK3UIVqSl/hZspflSB/LmX7i6dC1PX49GHERm5Ddz08Mj3U9M6UkL16YDi1AtcFX7AIVIe8CBbMeWpyVHXxVtcbPFsCV8oiUdALxh44dVzbQgQXPjrwsj4rGSFWl1GIBxWBDPj4HqDKqKls0NcDbhSwk5BPJ2i5cuFCi6lZkeFccHBz4cGiOSGEQaP0Rl5xmyUEPO3henu0Gk2udFRcux2XP4dp4XN7zutSgfIAcBd1fawWVo1SGIgGyVJjk2TzW6aiW5+UZXjDsVmpVVsCHAu9KkPVym/SQB13Kqky9Ls6K+DLB9aTGmwuTg+t2DN8RF9H5ScHRrudGFuclfSoQFwEqV13gleDThqnMSbxV6+oYziePtGDDqIIPGX6lKiC3hU9pRqq24H1T1b44Ojq2lOcxkpJItM8K/hblHnvE/9dEGiW+EjtlT6im6uMIXsoqJVdUXTAVHOS7Xo5TeVGzvERRi7BHax+4mAzKVpniooDHRVb8v7iU0jfP9czouGD2WBnB93qW5cV9UTHJ9q3SkuT5XZzTcc03loy0mA56n7QY9+SdB+N2akRq2KPNFmh7Rm5LxecqTPf/JvbVQR2Yd+uuWomNyH7X5rmmhz7qQmW5nwjERUC9eEr4JLSiNRaqANQOZXUS4PlRlkBbL58uGigBHyr4SpWLBAL/+LwHaIdl75evqkp3ILMoQcnqOJNu6IDB+aCKiclNWXUBiYd3BD6miiQR3icYphUZgFpXrwsmY/Mh08igUWSifJ3NzCl+X4c93WbubCrD+/GBPS7i2P2enCLBkReUZM6MiQu9v84qPcC6f2lW5JdUKg6FKy/K+KQg0a1FnNMxLZ/Lc973tCiktvQQx/0zUhL1wlC7sOqAxbKCZnlJbi0inu00wWt3VQJxwcRqn5vLbNMjX7Rsap9Z4cL1gYDE0wMHDqRjwrC8LTU1lTCQ7c6dO/3rMtAPPgp0D6FUBZ8Enw3+D0jSmHD9MR1/JKHyXSBsbW2VPiG4mlb0s+z9kbsvUMjQBl3f7bAfOxITEz+DAod2dHheYJBH2zsIPkh7fZ3/UFcxG4lPaz4GnqLMVV++s6KcqC+inY9oi8zHxtVt4VWyx+U9taVHJeUFZSMMdQy6vcY61fe6WklW2FflhUmf5yeKWsS+PqLldXmml3N1RlxjxeYk4Xm8LWd6JbqfVy/OjqmkhJWXsNcV+axDyN3V1mJC1qvOHUXOZkNTQ55tN89L8/1GIC4C6q1kZG1tPQi1aj4bzIMw0EKpYQtpO0UkYpSFkBVhaGh4zcbGppyPAVBqyEXIGS7qH5vawjclV5W5LVIgUIxPEJrUa+Hi4tJC+AypBiiHolsLny8QyvqOJcDzgZi+fv1a7rmgyjlK1aG0KPWzeF9LdbeLU/1djBlxqTGIrX48LvxmGEkX+n55olOjkgJvrXiQ4n5KMyvwmnrMC119dACJW57lEzGZpAVEwlQtI/DWygcZwY87lBVUDoYszY3/PNXbUt3PSsPTtZqOItGJHgoTF8dTo6MjnI9plhTFfSkQFwH1LlHzuUhVNIliWOPx48fz0eUDkybm2/j4+HyDBRBlIHwPDwRq92ZmZhsxvwjtnBVlcD6+Ftx9qtIc/KGA5F8oWHyMsPC2IOtDlXfcfL02eO8Z4YoXYv4/bqAszPf8hIkfybv1obqUleY2Sw23beVzY6mt84kBuXUhLsrwuNTGEyI6NTzV+9LUYL9rsz3dz6tHu2A0gJyyl0gmaenxjhiZq0djmnR+4pvvqCT/3fWirKBZforvN1EvDDh/C363KmmRgi85g0fGw3KmV4LfrZ6lJZmfCMRFQL0Chj909jACQopsuKihG8bf359AfPD3KOvA4InSBvwrICuo0fO5AFbcAgICkCVzqT7asT8EoFhAuZB3HFDGwzwgdoz/rso77LNnzy7iE4IGfws6zepSLhTQ8AGFFDcl8jqdpEoswgjrS4UrSAv8KvL5Pn3Xk8NTa1/uUKXHpWZ/ikiiVKCkg6A6EJnKpKXqUMZeFTwzsrwtiN4fnO17bZF9iu+N/qW5VfKVijM/yYp83ironpaVs1ld/UE93z5f6KONVrlJlechCcRFQL0BRsuTJ0+u49Pho+oNSgtKSmFhYR+t/IiZTJaWlqXyjoW3tzcmME9RZV4KFin4WzB7SN4G866q90dAw4BIJPoBKdt8PrNS1QXTplW9XyV5CZ8nuJtPca9TSy8Pj0tdFRfjavBWOelRY0lJFllwk+FtcTunHh1pr6eTn+z1XXlpfqXPZ2lO7OfJXpdHel+e7eUsc+Aj/5A90emx0TGvD2sV50R9KRAXAR8MqKubm5svgXKiqEKirA0lKNzRf8ykBUAZDbk0PMoycaqeGyUhLpdgwJa3nT9/vgQLmvB5+fiB4ZmIIMBEaD6qy5EjR3LrI2cJJtO0kEcdfK4ttnU+MTBb9tyeHjUoIFKPy94aZxUFS4iLSImlIr4ERVStX6ZHtcMVQSJcTg5PDby92jo96F7P0oKUymooIzEFSV7fRT/X03EzH/eeqVlWO3dN/+d8on/uG8tZbsm+19TKi9M/FYiLgA8KBMKhcwg5HXyMo8rasEgj9hwlCxhXP/bjDOMlIyXPZI04QKkN5un68DnxmVMjMQk7f2xGaQE1A141+NP4mLZx01Evacrlhc2yEz2/CXy07TAmE/MiLu+pHpLp0NyQRZ9qPS7BMhQXxfwgyiIu7/9bPKhxSIb3lXlOCe5npxRlhr43tbs0P/mz9MA7PQNvLrNxqWbukTziUn0b9OBsn9trLNKjHZtTeUEzgbgI+OCA58HJyekntkj5I8NF1eoLWiqR04I4c7RLN5XjjPwLEEQQghrKZTfrg8Th/T5//vxs+IpkbTgX4IUSykRNB/g84j2Xd25IVRe0cdeHcbukMOnzGDfzKS5nxkZX140jqlZt6VG5VHR6dFwEIy75MrqKuHboGrwq9a3EVC11QfVwNhuR5GO1wB6zjfA6qgbOUVl+MyhK0Q6GOp7n1aM5c7ASBis6nxwZF/HKSKs4r2nNJxKISyMA8hyQ1IqLEYybfO66FDH2wvgHUx/u0mA+bWoLopQgIswNJRi0iT98+LAcYWOQ6FUV7V8dXr169Sv2oSaSiiRVtGSja0z4bDQ9rws6CPncwMAjd+PGjaGqzvgpL8ttlhFp19bPerkN7v5FvDtwKntcIuz2vk9cOI8LIy4PNljUrLjUkLVirFrCwpWFTAbmuJwcnuRxYZp/MNvHpDeXRham+jHS8v71szQ/7otU/+tqfjcW2yPcTqRoK3d1s5DY8/tcm+eaGnS3Z1lxdjOBuAhocMjNzW0Gv8nNmzeHILkV02P5zNWpaUM7NLsQcjN32EI5C/NxPrZgudqUakBS4A+A9wWdVPWtPKH8Y2pquhnvTdUNmTvI6hBmEzVNSBKen2DsgLwN5wojuJGq9mUBRdlhX0U5HtFyPTMmrvoumV4yYvIlHhe7Pe93FbHFOCv6Vcvgh9rmTidHxSEd1tlkQI4ULhWAluzq4FTxa4W/rfjziqj4N86Sv3E0EX8FUWDkLANhb86nRse9sdRwC3uy1TzJ8/yU3FjHlsW5sZ9XNeOSJJU3N9q+bfjTLRYi8zFxLkow5YLIiE6NTAq326df0ARD5wTi0giBjgHkj4BwIPkWqa8o84CM4IIFQJUB0MYr/RnaodEujZReyeL4A4zAwjFteC2w7D3tjgnB8BtB/Tl79mwxxhKg1bW+g9AEVH8j8SGeEzcufMZzYHNycuKSlVW9r+Wluc3Sw5928L2+4DXKJoopH5KuItvdhwuSvSoRl7KSvGa5id5fR742meJ7a5WV7/XF9j7XFjEsFMMKWGDvdXWBg9eV+YCT1+V5DHPdgDeXZ3PwZAQD8LCcJQH+PUvy8wpfL2k4cV8vv/v5m8tznfC4eD6/m5oP4LeJfL5fP1F0WiMz+EEXzDYqzYv7ojqVRaoa5Se4NY9+oa/jdmFCNEgWNxCxluF2736nX57vlVl+Kf431MqKMz4ViIuARgPIwFjk/Pz8/oHYesy4QYssCI2xsfFu5D+cO3duPn6G/8PEWQ8Pj3+j5VrwRzQOAgMFCOW7yMjIL+qjxVVAzYiOjv5v+L9OnDixEwNPkSQN03Z9lu2goEBxrc6PVXWTDF/0rw+vS26KzzchNjsPO5kNT1Jsxk+vAuTAhD/ZZp6fIGpRXlrZYFpakPppXpLP1ygZ5UTadsiOePYWWeHP2gLZEmSF23TICnvKfv6kC4ewJx3EeMy+f9QlKxR42DMz9KHk+0ddMkMfvf2eQ4j4d8Rg3+NvGSnLwnNG2bfKi3NpUZTq901pTswX5SAM5fk1XkfLijM/yU90b475R16W0/2h2Ihkmpd7vM2CeUde3nmE0MkkBrJbhqQG3FtnkRnj2OSTs4WL00fm20DpR5hjI0BA3YGbAz09PQd4R1CqgboJvxE8Z/Ce2dvbt6kvFQY3IAiW5LPBr6XK2VpvCUZR6mfJAdY9va7Od8JU5bfKgHGPt0MOaxwQaKqWEXRn1YOcCJsOmND8vo+msFl5SV4zGF4roTiv+p9XixyG7E9QfuK+cv+u+v85sh+jlD1XWb7897i8qFlZISNc8c4tYx2PckMbnc0GZ7u8VVp6ySQuNXld3pKWE/1yPS5O849F91Ju7OcCcREuUAIECBDwnvKFkRc1BQNC/VB1qnJV5Qft8HxUF/jgGOFyrI8J4oUZIV9FvzLSEp0ZG+0i6TDiY9BF+cTHcqZfkru5Rkl2xJdY+Bvt+VKa80lpTuSXUH4i7fbpe16cjvlHGVLSoozAOSfT4UnBj7aa5CV6fIdJ0wJxES5SAgQIEPBepxdGaMgiCEisPXbsmGF9TWdGyQreJz6qC/Ydr0HV+1RWmtMsLdK2ra/1igfOJoOy+S/GmBs0Mins4QYrlIDKC1IbnWcDKk5JTtSXeTEvWyW6nND0u7HUFmZllIdqOz27OtLndKJ/rrvlbKcE/1s9y8syBH+iQFwECBAg4H0fGdqKMY2dR3ZKan21zmPgqa6u7ks+nYWIO8AYgProkCvIDP8y0vGYpsh8fLgiYwAQle95fnx0hO3uw/CtlObGfkElec2orLDhKQpQOVA2Ks74FGQlP9GteXrQnf6xr49qBt5eY+1xfnIw13nEXr9ICQF4orezlfrluZ4eHRdur69dkBEsxCEIxEWAAAE1mb/RhotW8Q/pl8rMzPwEQ0iRdIwI/Pp6XpjYYXZH6J+87fbt2+X11aoOPw2ynaprm6+6IfcF2UDIKlK98pDTLCvmdcugBxstnEzl5ZVUbpF2NR2Y435hQnTogw1WSe5np+RG2rUtSvZsXpIe8E1pRvDXpZkhX5cxlGYxZId+XZYd/lUl5IR/VZ4d8VV5TkVEciBGMMo5RH9Znhv1FpQXLUauGO/+L/LdY7DHLMsK+wr7UJzq811+vEsLGIFTfazU4hhJC3u8xdzHav5rt3Pjo11PDs3ghjZyKksvpWbHIP8l6N5q68xI27ZlJUJzhUBcBDQZYNGDnC+YlmUTFmTZYPwAQvjQio2vhw4duoCutPo8dsi1QecOOmlOnDhRgGGDurq64WzRHl8fvg0Y3M+cOaMZEREhlyDgdxBYWF/ZP+7u7v9B4jOfQDpEIcCnAyKq8pJRUdqnSX43+rtdnOWGTBR5QWoV1QUoL6JTwzI8L04OD7i13AY5KRHP9upH2OlpRz7X0wEiOOhrRzw31Ip4fkArwt5QO8KefX1xUCvyLQ69g4ORZhTw8nBlOEhQ9d9vYaQpfgz2eHguW12dsKc7DwffX2fld32RvdelqcFuyK4BWWGky9VE+WSl4kwiGHLjGKErzo37XLhOCcRFwEcO3Kk/efKks4GBwX1k2LBFOBsLIeYxBQYG/k04RpW70ZAhA7JS1fyJLhqQB1tb23b1sS9QetByjDJNxcUZ34MkoMunPlqR79271wuZKPI2ZCaxfYqvr/ZozDNDCYjP8EUcM7yn9aG6ACX50V/GuJ1c4HJmQrDrif458hJiK5dE+uSBwGCeD6L+nc2GpTqbDU8Sf5V+X/HfFX9e8f+lGPEWThW+r/rz9/+v4mNIn2NoKrqg4OHBPqpCWaku2t/11KikUNu9+rkpXt9hRpRwrRKIi4CPPHsDi5+LiwsXwocLOABPQmxsLHIuIqAiCMdKDAzzw+KLdt+aOmiQyFofXg4MGUU7b02Lsbe3NzezSdUKB1KlDQ0NU/koG/VZLpKqLpgGzWcMCAzEyHZC2U/lJaOyvGY5CS4tQp9sM3E9OSKp+kTdisSlx9u5RuIW6qqpu2K8M6tW83NjMar+X91QU3mrh0Ipt7LTg2WTFkeTwRl+N5fZZIQ96tLUw+YE4iLgowdkfiSNPn78uMYVB+QFJZH66gapya8AVQjqD1pq4eP4UAGB9+/f7/Hs2TOZCyD+n6GDqtUElDZkxduDXKFshFEYqvbXGBsb72cLvlxyADKFsMf6KqchlBDlKZASeRvIDdRGlAHrR3VJ/jTZ37qnz/Ultk6SlmA3mdOWKxAX4+qJQU0/rxjQpnzVo4fc6dAyTbbGffIARYkLN0TRZHC2x+XZTvFvLEaW5Md9IVzXBeIi4CMHSICenl5cTeqB9GKOu+n6HKRYEXhejF/AgoLRDWhxZXfFebgzRuhZfRM9JC3zmU4Nw6oq9wVpr5ijJU9JwEgEBweHVqo+NgiYw3wweeQgIyODmyZeH16S2nhdrKysyuqjNVqK0rzYL5K8L4/0vDzLy9Gkv7jLxljBIYhvJ0r3UGwwoRIhqhPpqc3z9SjATCMfyxl+iW/OahTDSCxc0wXiIuDjB3wtfBYbdFxgblN97x9KEPv373fHnKmqG7vL5/wSnp6e39Wnv4Udi9mM8MklLhcvXpyhyn3B4oqyi7z3Dkm2KCmp+thgNtjhw4dz5JEDEK2DBw9m4vfr631TRHV5/vw5QVWrv9bhwmZFWaFfRb0+tsD59DiFWqTri5Qo0pqs+D72UHjf8TzOJn3zXM6MiQuz3aeTm+T1TXmZ4GsRiIuAJmHIxVBCPpN0z5w5U4y71vo2wWKGlJubm1xPAsom9Vkqkhcnj8UPAWiq3I8XL1605kM6UZqxtLScpOrjAgUF84n4nE/1Tg4kqouxsXGBPGIFzxAIfb1+Hsvym2GCceTLA9oi8wnh78y6PT44IWmIxAWpw86nRiYFPtxikhn1ukVZcdYnwjVdIC4CmgAwdBKlFz7dFmj1hfpRn/uHNl95CyHMxLq6ulH1WcaCUoASDZ77Q5pzvby8vj1+/Hi+vPcvKysLwW93VW04hQ8JBMnT01MucUGpDcpVfbeNHzp06BIjWDLPdaiLmDBe359HTJDOTXJvHmGvpyMyHx+NMLWGoKTwM9bWhsTwG3fwfttzv1yX02Pigp9sM8mOedmqvCRTMOMKxEVAU0BERARSRd/wmeWCFl/MfamPTJCKwJRfGEtrIgjShQZ30fVZxoIShDtyqFBVj19BQQG3P3Z2dn+pej/wfrDj4yrr+EhbkNnvBaN1WtX7hAXf1NS0UJ6qERYWxnU71dfQRSlcXV1/lNVhBJKMuUVI3f0Qn0vE4uclujcPs9PVcTo1Lry2UfgNRX0RyfkdVwXmE4kkSguScUNtdh7OiXdqWV4qkBaBuAhoMuFpmIbr4OBAfDb8HgLO6ns/sXjs37/fQ55xmN1FZ3l7e/+zPvcNHU1QPE6cOLET5mYoUlBZ0FmD1vH66HhCaYY99zNZxwdbaWkp11mEtvd6IpuB8sgUVJlr166NrO9zCt1POJctLS1Lq+4jSAvOpfo05takvBSkeH0X8RzkZWx05Vj8XjyUjdq1FX8IcvNuGjQPTwuGJ54aGRf8SNtcrLQI5SGBuAhoamqLK5QUeRsjOYQgOlW309bU7ssWkrOpqak17h8UDuxfeHj4/3yoNm0QCKgf2N/6VBAaInHBMYAJNjg4WOY+MfJQDo/Oh3jPQF4QModzC+ZuGIVxfMzMzDaiDFjfKlD1npfcT/JSPJtHOBhqiy5MDnY2HZT9tlXauPEpMPJVmR4yW54xiFFkrh4d9GT74czoly2F8pBAXAQ0MSD1lY+3RWqiRM7Lh7qYY1/v3btX475iDg26d7AYNbX3kS9xgSoFVQiEtb48QAgtrKkMCWUDnWL1tT81AaMtkAeE/QDxRKt7Q3p/y0tzPslP9fkm3v2Mhs/1Ba8dTYZkcKUjY8WHDzZ8Q2/1Bl1xuJxaxpvLGm4xTsc0cxJEzYWAOYG4CGhikE7MZURELmmRhJeFQv7/UPubkJDwGbwQ6PSAclBxMUa3EYLx6sO70RCBFl8jI6PTyEWRt125cqXs9evXv9TXvjk7O7cwMDBIrrpvmAeEn9dXrH5jR3lZQbOSvOgvk/yvq725usj29YmhqTX6XowbH3GRm4h7YnCGu+Uch3jPC+pFOWFflZcI89ME4iKgyQEzdGQpGBU3EANM1/1QCbVSIK5eYvrcDOMkylzGxsa7HR0dW2LxbsrvJ2YE8fEqQZmCr6k+9w3lO6h16AyDERyhczdu3Bj6IYlwY0VJfuJnmWFPOoQ+3mrucmZ8uLPJwOx3IwIkasVHVELCwER0DgXdW2uVFnhLrQSTqYXzQCAuAurWVdIYJydjkcfAuerC3GpQW8Ib0iIDAoXXgNEDH5pMNRSgewlJwvLeT5hhQSI+FPGE96W+JkJ/rCgrzvwkN9nrm2jRKQ2f64vsXU4OT0WXjagRZb3IG1HgbNwvF4MaURqKfH1YKyvepUVpYapQGhKIi4DaliwwGA7GQ2RB4I4fs2jqu0W4LkC3C5JN+Qybw8BF3B0L733DBs7Jhk5cBCjT91LQrCgn5vOMiKcdgp5sMX9pNjYc5RRx5kuvBq661DRbSdxd5Gg8MBtdVEEPNlikBt3uX5Qd/lV5qVAaEoiLgFpBMs/Hwc/PjwsXg9cCigQ6J9DRUp+R83UxIio6aK6+5wAJEIiLAJ7qS0nWJwWZQV8n+FipeVuvsXA6NSYa5ZWquSgN2esiqlAWcjQbkeR2efGjaNcz6nkpXt+VFacLKotAXATUFmghRepoTWmbMBvCd/Gh2nH5QpEhc+y1EEiOIO03fCBzBEMB5b2nmPANjxDKnMJx+3hQWpT2aV6SW4sopxML3Czn2TqeHBnndGJArksFAtPwiEsPcYaLSf8cR7Nhqe6Ws50iXxpp5cQ7tiwtTvlMmDkkEBcBSlgYLCwsSuVlUsD0+rGoLSA4H2KgogDFgTEMGD9QseOquk0yhsAVJU/huCnu0WnIJL68NL9ZYU7UF+kRNh2inY5o+VmveOB6dmI42ohdGljyLhQhZ5NB2S6nx4X73Vxmg5ya5KB7XQqzIr7E6xDON4G4CFACkLKJ6bqyNi8vL7p06dKkhmrYhdpy9OhRXmoLyA0jLoaqnmsjQHmKIMYxIIhP1iaJ/fdHbolw3PiRfbRsw8uG4wvSB2P7y5cvf4c5vGGWj3KbFecnfJ6b5NYi2eeSeuD9tVavT08MdjQdnuR0YnCGNIFXVNFzYtyjHshKvzynE4OyHU2GpTqeUg/3vbn8QZzbKY2cBJcWxXnxn5cVCyqgQFwEKLWLBeFmvr6+MheFkJAQzF3RaoidLujmQAw9H7UFxObs2bPFQsaGbICgggDA2+Tg4NAKrdqRkZFffIiQPmTYIJdHXgqyhLgECsRFPmC4h0KJ7CAcV6iQAMjhs2fPMItqf0M+juVl+c3KilM/K8wM+jol9P+3d/YxdZV3HE8XjTpX3aazS7N18Y/NzGjabIkvcYnb1D9Mk82tMZtzLtliXGrM4kyc23/bHwVu9V6hL/IivaUNDUIhZQaUvkClCNyWlpdbSilQsAVrgWpBCm3XFnY+t/cuyrjnOdVyzwP9PsknTduUPpxzuM/3/F6+v6qlR+sy/3Ro21+27d/0ZFck+7FTjbQax7qRLhfGXvaAudxO3XQVhEwsquKIJGpXItmPnN6/8de97aXPv9tdk/Hiyc7yByZOty+6eG7wBvap503CRcyST4bzluV6KCT8TuZ6bQvW+vHpuUonJIEJw0xApniZzitEKxG3nJyc89SQIGAsFi5d16pZ35W8rBBlRbQku5bV1dWxOUtWjAYwppHGvnJx4sObzn0cXTzau2PpwL7c37eV/3XD++HfNtfnLj9OOimy/uEztCHvW/eT8cvmdg+e9QoiJWbJ7/y7vW88PBZ54+enG3OXf1gf/k30QPHzW4+9n7lypKfygbPDLYsvjPffdEnzhSRcxOxDrQfTfpMd/IkoRSpdSa8EphjzluhlFRQUXMDxVPc9ea2Dc42eRsjO9Dz09fVNvfrqq0WpFAfUrGDsNjIyYoym8Ry3trbeoXvpLgQzMjK2M5Yg2WI4YyAQOHXw4MHb5lYr9cSCi+eGrz/3aedtp/url/Y3h5/srQ38vavqHxvay17YFi3587vNW/7Q2JC/oqMu9xe978epS0J93q+6mjb/bv/BkueqoyUr/32k8m8bPqgN/HPA+boj/bt+fHbk0CKM80hh6dmScBEphFqP3Nzcl6hzmemwikajU1lZWaETJ05Y5+dCSqO4uHg5ESEvtS1MOrZh5g/7JsXFeAIOElvmEDENminQbj44ZWVlk5jCpWpPzNfZuHHjHzs6Ooz3mChCKvdmSmFyf0m52DQjiGJnBi+aip3jUdYn5uTn2uT5BZOXxhcQ/bh4fuiGc6O9N58Zit42drJpyeljNXcPHSp55KPWgidPTuOjOP/7s7Ytj3/SU7X0zMn9i8dOtiw6e7rrlkvO1+Pr8vX5f3SGSLgIH3PepAect+lPeNvGz6W+vj7mdcKhker0gFcIZbNvxJWpk4jiXQ5mv/fc1dW1kNlEuPaS4uIa8wbsHLrLOOz83Bt7IE3gtng2CgoKnklV2zEij7QFlv6mxcBMvgc/r+GRI0du2bBhw3PMwIrf39FAIFCBmaMNRa8MiCSaYhIuiTlefg+KvKoRmcmzCzB8w6EXHxUzp68jFRX7d5NqYZZwEVYWZBJVwZTNedtaTJgYQWN7nruiouJ+Diy3RZqBw8Pv2pb4VOEeR6B8LrrFIdLY2BjzIfFLvCQKtZ03ctdr6TwjDH7MTNUhzHOJwzH1NqbFTCM/hQtpKuf+HsP7aPr9JaLJ/fVbvBw9evRmiphJB5kWYhHRqM9HIeEixFU+LILB4GiyN0iiLfn5+f+pra29y++UnLPPMAXCydbWrVsv4RTrY6H2QwgoLx1mqUp/JCIuXoQL0UJqnvy6v6FQKNttTlZlZeUkkRe/o6sMhfQycRtxgxAjiqTPGiHhIsRVgqGE5OIxyZsuXhAtFO4Suvfbt4VoS2Zm5hm3g4JDDy8Nv2pe9u3b911EntseSSXRiZZqQWWKqrEYUREOh5/1I0pIpBIB7dbd5uwLIVCHN42f6VWupyPwPE1QJ+pCJM6mOh0hJFzEnIfwO5EK5i3RAcWbLW7Aq1atOrBjx45lNrQ/v/feez80zdxJuL/6NdiS60TUgHSQy/56qNNJdedbdnb2OdMhS8u08wzU+HG/8buhcNm0R4Sh367N1K04PxvN1LGYVvyef9DZ2XmrPmuEhIsQs9CBwqFPHt+mbp3Ewea86boebBiAMRfKzw6u7u7uhbQf86bNoUXUipQB0QycaZnA7UcnDIXjJq8e9smB7Iftv5daK78iVjPhiPv73LxcPruIZtrSrSWEhIsQKUwV0dnkdkAw6NLPVNFn6yCoCcrPz1+ZmZm5FpdVajNo7/VjP7ztO2LqlM3CBat8apRMIsC5trGRE6Q4/bzHtGk7InkX6SvTwkqA59LvPQsh4SJEin09QqHQmzYX506HlmdM6fyub4gLl49tFi4IU1qfTXskncUebbAYKC8v/6lpTlmiVswRLhO4VOtnWUi4CHGNRV2cQ6t9aGjo/w4GWnnxd/Hby8VG6GrBe8QkCijOTktL6/PDe4Tib1yF3RxpWQmHXxtEQEdHxze8eLokooHUPzGcUc+kkHAR4hqCGhJM/fDSoMuIThTaU4m02DqV129IXWHSZ5pXxKJAlrRNqveIDw4dTb29vcY90trt7PNRv68r0TRa26lf8rKKioou2Tr6Q0i4CCFm+ZBjmKFzyH2VlIFqB8zXi3qb/v5+4+GKlwuFp37sk7qg8vJyY8Erbe/UudjQYkyxtWnMQ2KR5ly9enWJjeM/hISLEEJYBaMdvEQGiLjQweXHHnGbZoSDx5TWMRvqXBDNXqMufF9MCfe7nVsICRchhPU0NjZ+zxEvF02CID09/UPa4f3YI1E0Rkt4SWnhM4Thnw3XFvdpL4XFrJaWFmZVPS1DOiHhIoTHt0PaOIH8vK7JtVXnkpaWFnGbscNMKlIZfhU4c5hTYN3X12cUAI64igkAG64ttVW0vTNjybT8MiEUQsJFzCkwIMvJyXmZt+n169efBefDs6uwsHDFfJpeK9zB5K2qqmoyWRqD4lG/28mpc/HioDs2NobIKrOlIBufHi/1OSyM9mil1jMpJFyESNKy6YiU1oGBgc9N3KWYkEnGgUDgbYpcda3mP6RimDuFQKGlnLd/wNQNK32ErN9CgJlFmOWZil15lukos2WAIVHMjIyMd0dHR43CBYdn2vr1cyckXISYBg6ypsJB/E+YHuzHYD3hT1oDD5TS0tLHcPQF3v6j0ejtNqQPmZPkCJJNbkaDiUWEw4/W7WRUV1ff6zXqwhRxRV2EhIsQ08Binny629urc1jF6hr8nv48X0QBBaP4zGA2hijYuXPnMhu6X2ZifHx8Adi2L6YvI6hNq7u7mzqXZ2wR3cz38joGgJZu0rc2Xn8h4SKEb9Be+vrrr4+ZwtakkvyaozOf6oioucAHhfoLimBJw3C4UltkU2TAdiKRyJJNmzZdMB3+CdFNCsyWvVPrwlBF095JKQWDwUI56QoJFyGm1QvQpukh337g+PHjN9q2f96kqQOglZeiUQ60np6erzEDyLbaEbpKknXDYGPviMNeW+oxbAd3ZOd6fWCy0ieSiOW+Tdc1HuWsM0Vd6OByhEtY3X1CwkWIaaFr50M0euFC8pdXagl487Ntxg/uoqRcsrOzz7W3t08hCviV39MGa9NbNumhvLy8824HFTb1qmnwBkMeKRoncmVaDNakE8mWveNSTM0YkTe3xWgDnm/dbyHhIsS0iAWOqfv370/6AfrOO+9M0iZr076pt3EEyiuHDh2acc9NTU1TdMfY8LbKQUU3Tltbm+tB5QgxRNcrei691d5QPOz23CYWzwhC1qbiciwG0tPTG5IJLyJFOARTEK37LSRchJgGqRXqADjsqbugjRRIEe3cuXNy3bp1q4jM2LTnhoaGO7FGT+ZEygf/mjVrxnEstUFk0QVDvYXbitvU99h2rW2FZ8Dk9JuIGDJVmm4k2+p0SHcdP348du95lnluMakjakgBMqJX91pIuAgxA3S18EHJAUs9C2RlZYVqamruISxv015x93XE1L/4wDe1kzrf04OWpDUqvHSSUG+EkNQz6S1qYeqISwhCR7h8Qj2XbVGjzs7OW4uKip7A34Vp5tS+5ObmvkRqUbUtQsJFCA9gqY4woG3XtgLXaXU5ETpy3BaGerST+v3WisEfBaKmA5a/j7+B36hn0ZuARWhT2Gxau3btmtqxY8cyW78XOoeIzPE9yS9JSLgIMc9obm7+9tq1aydMA+twe8UnxW/hwttzQUGBsXV3cHAwtl/dY+9QexWJRIzCBYNFap6UehFCwkWIlLN9+/YfVVdXeyrKLCoq+qUNtQxMKjbtl9QXZmm6x97B4ZdRBKZrG/ciitCJpusmhISLECkNqa9duzYdV1HTwlnVhvSAV+FCO7ct04znCqQNV61a1ezWzs8iOpeVlTWuLh0hJFyE8OOgOkD3k+mgwhHYhoJMzPEKCwslXGZRyJJmMy18U2xr6xdCwkWIeQ71IuFw2JgaoHA3LS1tnw0dUXQ27d6921Nqq7i4eLnu8+ykDh3RG/PJoQBd100ICRchUiUCHqLN2Wsxpt8dGkzfpuCWQmHTYvZOU1PTd3Sfr7zOZd26dWdNxdrnz59ndEWzcy9U5yKEhIsQqWl/xVtmaGjIKAJw+2WYnd97xotjzZo1q4eHh42prWAwOKpZRV8sfZienl5jsv9P1LkwWFTXTQgJFyFmHWYPOQfULpN/i02GY9RgeBUur7322khXV9dC3esrj2qFw+FnOzo6jIIWJ+jq6up7dd2EkHARYtbBURaDNpOR28TERCwlYIORG1EipkJj4y7hMrt1RJjMmRbihpZzmbwJIeEixKyDPXogEBgyCRe6c6grIdrh956xpXdEVDv1FW6Ldl5HlPUxekH3+sppaWlZRBrIJFyYuJyXl/eira7QQki4CDGPOHbsGLNpoibPjvr6+qlt27b9jFkwfu+5ra3tW7j8mg5U2nlDoVC2DWJrLoLgc56NVlObvCNwpkpKSh7XNRNCwkWIWYf5ScFgMDwyMpL0YCIaQ8rFlgJMxhMwxdokXIgSEQlQCuOLgZX/li1bVjhC0fU6l5WVTdbV1X1f10wICRchUsLu3bvvfuutty4la32NRqNTFGra4tXhVbiQwsjPz19pm3AhanX06NGba2tr78Jjxjn4H8VLx8aW4vi06Giy4m3nmZhKT0/fQxeSfpaEkHARIiUMDw9fx5s1JnQnTpyIGc1RP3Lq1KmpysrKSVxUbZqu7HWWTrz24gWbhAtdXIWFhStIdR0+fDh2jWlFZ6ihIxC69uzZ8wPbhhbu3bt3ibO33vb29innWsaeDdqkicQ4f94hnxwhJFyE8KXFGEHAAMVMZ4VCoTc3b978FNb6g4OD19u0V7xktm/fPum128WGupxE6oUIC506M0W3EAUUSlPDY9vz0d3dvRA33ZycnJd5NviVmVVEjvTzI4SEixC+QncIaSFbDvzpaRbcewcGBoxtuqS/SMfYsvfDhw9/PSMjY9Ctg4soDGk5W58Nolc8G6obEkLCRQjh8eCk4NY0yZqIBpb11MPYsncvgyEd0YjRXxHuwLrfQki4CCHmAbRlNzU1uQoXnH7phGpvb/+mLfuuqam5h5oht33HB1nW2ZaeE0JIuAghvkSxKMMTTZELZu0MDAxY0+0SiUSWmCIudOkEg8FCLPd1r4WQcBFCzAPiYwq63JxzaeGmuNgmN9f4vnuIBrntm64j3WchJFyEEPOoeLi0tPSxqqqqyWTdOQgEimFtKyyuqKi4v7y8fMZ902JM27Ft+xZCSLgIIb4k1IDQuh0KhT7Fcp4uI3xbEAWBQODtaDR6u437pu2c4YWrV68+tXfv3qn+/v6Ywy8iDCM3WtJ1f4WQcBFCzENoy8VfBLt5xAC+Iq2trXdg8mbzvvFzwf+koaHhTvZdWVl5H4LFRudcIYSEixBCCCGEhIsQQgghJFyEEEIIISRchBBCCCHhIoQQQggh4SKEEEIIIeEihBBCCAkXIYQQQggJFyGEEEIICRchhBBCSLgIIYQQQki4CCGEEEJIuAghhBBCwkUIIYQQwg7+C45DrSyPXuiiAAAAAElFTkSuQmCC\"\n      />\n    </n-divider>\n    <n-highlight\n      style=\"margin-bottom: 5px; color: #DDF2C4;\"\n      :text=\"headText\"\n      :patterns=\"patterns\"\n      :highlight-style=\"{\n        padding: '0 6px',\n        margin: '0 6px',\n        borderRadius: themeVars.borderRadius,\n        display: 'inline-block',\n        color: 'black',\n        background: '#F2C9C4',\n        transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n      }\"\n    />\n    <n-highlight\n      style=\"color: #DDF2C4;\"\n      :text=\"text\"\n      :patterns=\"patterns\"\n      :highlight-style=\"{\n        padding: '0 6px',\n        margin: '0 6px',\n        borderRadius: themeVars.borderRadius,\n        display: 'inline-block',\n        color: 'black',\n        background: '#F2C9C4',\n        transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n      }\"\n    />\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useThemeVars } from \"naive-ui\";\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\nconst themeVars = useThemeVars();\nconst headText = t(\"home.head_text\");\nconst text = t(\"home.text\");\nconst patterns = [t(\"home.patterns1\"),t(\"home.patterns2\")];\n</script>\n\n<style scoped>\n#father {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  flex-wrap: wrap;\n}\n\n#avatar {\n  height: 250px;\n  width: 250px;\n}\n</style>\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/hwndHandle.vue",
    "content": "<template>\n  <div id=\"father\">\n    <n-gradient-text\n      :gradient=\"{\n        from: '\trgb(254, 1, 1)',\n        to: 'rgb(254,115,1)',\n      }\"\n      id=\"WindHide\"\n    >\n    W A R N I N G\n  </n-gradient-text>\n    <n-highlight style=\"margin-bottom: 5px; color: #DDF2C4;\" :text=\"headText\" :patterns=\"patterns\" :highlight-style=\"{\n      padding: '0 6px',\n      margin: '0 6px',\n      borderRadius: themeVars.borderRadius,\n      display: 'inline-block',\n      color: 'black',\n      background: '#f58f98',\n      transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n    }\" />\n    <n-highlight style=\"margin-bottom: 5px; color: #DDF2C4;\" :text=\"headText2\" :patterns=\"patterns\" :highlight-style=\"{\n      padding: '0 6px',\n      margin: '0 6px',\n      borderRadius: themeVars.borderRadius,\n      display: 'inline-block',\n      color: 'black',\n      background: '#f58f98',\n      transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n    }\" />\n    <div style=\"flex-basis: 100%; margin-top: 8px;\" />\n    <n-button type=\"primary\" color=\"#A3F6EC\" ghost @click=\"getHwndMesseage()\">\n        {{t(\"hwnd_handle.refresh\")}}\n    </n-button>\n    <n-button type=\"primary\" color=\"#f58f98\" ghost @click=\"resetKeyToDefault()\" style=\"margin-left: 10px;\">\n        {{t(\"hwnd_handle.reset_sky\")}}\n    </n-button>\n    <div style=\"flex-basis: 100%; margin-top: 8px;\" />\n    <n-gradient-text\n        :gradient=\"{\n          from: 'rgb(242,201,196)',\n          to: 'rgb(221,242,196)',\n        }\"\n        id=\"hwnd\"\n      >\n      {{t(\"hwnd_handle.now_hwnd\")}} {{ nowHwnd == null ? 'Nothing' : nowHwnd }}\n    </n-gradient-text>\n    <n-data-table :columns=\"hwndColumns\" :data=\"hwndColumnsList\" :bordered=\"false\" :min-row-height=\"48\" ref=\"systemMusic\"\n          :max-height=\"475\" :virtual-scroll=\"hwndColumnsList?.length > 7\" row-class-name=\"td_css\"\n          style=\"\n            --n-td-color: rgba(57, 57, 62, 0);\n            --n-th-color-hover: rgba(57, 57, 62, 0);\n            --n-th-color: rgba(57, 57, 62, 0);\n            --n-td-color-hover: rgba(0, 0, 0, 0.2);\n          \"/>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { NButton, useThemeVars } from \"naive-ui\";\nimport { sendData } from \"@renderer/utils/fetchUtils\";\nimport { useMessage } from 'naive-ui'\nimport { h, onMounted, onUnmounted, ref } from 'vue'\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\nconst themeVars = useThemeVars();\nconst message = useMessage()\nconst headText = t(\"hwnd_handle.head_text\");\nconst headText2 = t(\"hwnd_handle.head_text2\");\nconst patterns = [t(\"hwnd_handle.patterns0\"),t(\"hwnd_handle.patterns1\"),t(\"hwnd_handle.patterns2\"),t(\"hwnd_handle.patterns3\"),t(\"hwnd_handle.patterns4\"),t(\"hwnd_handle.patterns5\"),t(\"hwnd_handle.patterns6\"),t(\"hwnd_handle.patterns7\")];\nconst hwndColumnsList = ref([])\nconst nowHwnd = ref(\"\")\nconst hwndColumns = [\n  {\n    title: t(\"hwnd_handle.columns.title\"),\n    key: 'title',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },{\n    title: t(\"hwnd_handle.columns.exe_name\"),\n    key: 'exe_name',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },{\n    title: t(\"hwnd_handle.columns.pid\"),\n    key: 'pid',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },{\n    title: t(\"hwnd_handle.columns.hwnd\"),\n    key: 'hwnd',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },\n  {\n    title: t(\"hwnd_handle.columns.operation\"),\n    key: 'operation',\n    width: 60,\n    className: 'th_css',\n    render(row) {\n      return h(\n        NButton,\n        {\n          size: 'medium',\n          text: true,\n          onClick: () => setHwndMesseage(row)\n        },\n        {\n          default: () => {\n            return '👈'\n          }\n        }\n      )\n    }\n  }\n]\n\n\nfunction resetKeyToDefault(){\n  setHwndMesseage('reset')\n  message.success(t(\"hwnd_handle.reset\"))\n}\n\nfunction getHwndMesseage(){\n  hwndColumnsList.value.length = 0\n  sendData(\"config_operate\",{\n    \"operate\":\"hwnd_get\"\n  }).then(res=>{\n    hwndColumnsList.value = res\n  })\n}\n\nfunction setHwndMesseage(data: any){\n  sendData(\"config_operate\",{\n    \"operate\":\"hwnd_set\",\n    \"value\": data\n  })\n}\n\nfunction getNowHwndMesseage(){\n  sendData(\"config_operate\",{\n    \"operate\":\"hwnd_get_now\",\n    \"value\": \"get\"\n  }).then(res=>{\n    nowHwnd.value = res\n  })\n}\nlet nowHwndMesseageInterval:any = null\nonMounted(() => {\n  getHwndMesseage()\n  nowHwndMesseageInterval = setInterval(getNowHwndMesseage,1000)\n})\n\nonUnmounted(() => {\n  clearInterval(nowHwndMesseageInterval)\n})\n</script>\n\n<style scoped>\n@import url(https://fonts.googleapis.com/css?family=Shrikhand);\n\n#WindHide {\n  font-size: 30px;\n  font-weight: bolder;\n  font-family: \"Shrikhand\";\n  margin-bottom: 9px;\n}\n\n#hwnd {\n  font-size: 20px;\n  font-weight: bolder;\n  font-family: \"Shrikhand\";\n  margin-bottom: 9px;\n}\n#father {\n  margin-top: 10px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  flex-wrap: wrap;\n}\n\n:deep(.td_css td) {\n  color: #A3F6EC !important;\n}\n:deep(.th_css){\n  color: #D0BDF4 !important;\n}\n</style>"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/kube.vue",
    "content": "<template>\n  <n-flex align=\"center\" style=\"margin-top: 15px;\">\n    <n-switch size=\"medium\" v-model:value=\"is_singular\" @update:value=\"singularChange\" :rail-style=\"railStyle\" :round=\"false\"> \n        <template #checked-icon>\n          🤔\n        </template>\n        <template #unchecked-icon>\n          🧐\n        </template>\n        <template #checked>\n          <p style=\"color: rgba(94, 104, 81, 1);\">{{ t(\"kube.odd\") }} </p>\n        </template>\n        <template #unchecked>\n          <p style=\"color: rgba(94, 104, 81, 1);\">{{ t(\"kube.dual\") }} </p>\n        </template>\n    </n-switch>\n    <n-switch size=\"medium\" v-model:value=\"semitone_switch\" @update:value=\"semitoneChange\" :rail-style=\"railStyle\" :round=\"false\"> \n        <template #checked-icon>\n          🤔\n        </template>\n        <template #unchecked-icon>\n          🧐\n        </template>\n        <template #checked>\n          <p style=\"color: rgba(94, 104, 81, 1);\">{{ t(\"kube.half_t\") }}</p>\n        </template>\n        <template #unchecked>\n          <p style=\"color: rgba(94, 104, 81, 1);\">{{ t(\"kube.all_t\") }}</p>\n        </template>\n    </n-switch>\n    <n-switch size=\"medium\" v-model:value=\"detail_switch\" @update:value=\"detailChange\" :rail-style=\"railStyle\" :round=\"false\"> \n        <template #checked-icon>\n          🤔\n        </template>\n        <template #unchecked-icon>\n          🧐\n        </template>\n        <template #checked>\n          <p style=\"color: rgba(94, 104, 81, 1);\">{{ t(\"kube.other_key\") }}</p>\n        </template>\n        <template #unchecked>\n          <p style=\"color: rgba(94, 104, 81, 1);\">{{ t(\"kube.range_key\") }}</p>\n        </template>\n    </n-switch>\n    <n-switch size=\"medium\" v-model:value=\"split_switch\" @update:value=\"splitChange\" :rail-style=\"railStyle\" :round=\"false\"> \n        <template #checked-icon>\n          🤔\n        </template>\n        <template #unchecked-icon>\n          🧐\n        </template>\n        <template #checked>\n          <p style=\"color: rgba(94, 104, 81, 1);\">人声分离</p>\n        </template>\n        <template #unchecked>\n          <p style=\"color: rgba(94, 104, 81, 1);\">原版转换</p>\n        </template>\n    </n-switch>\n    <n-gradient-text  gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\">\n      Tips:人声分离速度会很慢\n    </n-gradient-text>\n    <div style=\"flex-basis: 100%;\" />\n    <n-gradient-text  gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\">\n      {{ t(\"kube.Streng_filter\") }}\n    </n-gradient-text>\n    <n-input-number v-model:value=\"velocity_filter\" style=\"flex-basis: 20%;\" />\n    <div style=\"flex-basis: 100%;\" />\n    <n-gradient-text  gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\">\n      {{ t(\"kube.dynamic_merge\") }}\n    </n-gradient-text>\n    <n-input-number v-model:value=\"merge_min\" style=\"flex-basis: 20%;\"/>\n    <n-gradient-text  gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\">\n      -\n    </n-gradient-text>\n    <n-input-number v-model:value=\"merge_max\" style=\"flex-basis: 20%;\"/>\n    <n-checkbox-group v-model:value=\"chooseType\" style=\"margin-left: 1px; margin-top: 5px;\">\n        <n-space item-style=\"display: flex;\">\n          <n-checkbox value=\"2\" :label=\"t('kube.scale.scale2')\" />\n          <n-checkbox value=\"3\" :label=\"t('kube.scale.scale3')\" />\n          <n-checkbox value=\"4\" :label=\"t('kube.scale.scale4')\" />\n          <n-checkbox value=\"5\" :label=\"t('kube.scale.scale5')\" />\n          <n-checkbox value=\"6\" :label=\"t('kube.scale.scale6')\" />\n        </n-space>\n    </n-checkbox-group>\n    <n-divider style=\"margin:0px\"/>\n    <n-gradient-text type=\"info\" style=\"color: #F2C9C4; flex-basis: 10%\"> {{ t(\"kube.transfer_progress\") }} </n-gradient-text>\n    <n-progress\n      color=\"#F2C9C4\"\n      style=\"flex-basis: 80%\"\n      type=\"line\"\n      :percentage=\"progress.overall_progress\"\n      indicator-placement=\"inside\"\n      processing\n    />\n    <div style=\"flex-basis: 100%;\" />\n    <n-upload\n      action=\"http://localhost:9899/fileUpload\"\n      multiple\n      style=\"width: 100px; height: 34px\"\n      accept=\".mp3,.flac,.wav,.m4a,.ogg,.mid\"\n      :show-file-list=\"false\"\n      @finish=\"handleFinish\"\n    >\n    <n-button type=\"info\" ghost color=\"#F2C9C4\"> {{ t(\"kube.chose_music\") }} \n      <template #icon>\n        <n-icon size=\"25px\"><CloudArrowUp32Filled /></n-icon>\n      </template>\n    </n-button>\n    </n-upload>\n    <n-button type=\"primary\" ghost :loading=\"processFlag\" @click=\"handleStartTranslate\" style=\"margin-left: 7px;\" color=\"#F2E8C4\">\n      {{ t(\"kube.star_transfer\") }} \n      <template #icon>\n        <n-icon size=\"25px\"><ArrowSync24Regular /></n-icon>\n      </template>\n    </n-button>\n  </n-flex>\n  <n-card style=\"margin-left: -24px; width: 640px; margin-top: -15px;\" :bordered=\"false\">\n    <n-tabs type=\"line\" animated @update:value=\"handleUpdateValue\">\n      <n-tab-pane name=\"translateOriginalMusic\" :tab=\"t('tab.translateOriginalMusic')\">\n        <n-tabs type=\"line\" animated placement=\"left\" style=\"height: 500px\">\n          <n-tab-pane name=\"all\" tab=\"所有\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"translateOriginalMusic\" tab=\"原曲\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic.filter((res: any) => res['name'].indexOf('_vocals') === -1 && res['name'].indexOf('_beat') === -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"vocals\" tab=\"人声\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic.filter((res: any) => res['name'].indexOf('_vocals') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"beat\" tab=\"伴奏\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic.filter((res: any) => res['name'].indexOf('_beat') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"C_c¹\" tab=\"C_c¹\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic.filter((res: any) => res['name'].indexOf('C_c¹') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c_c2\" tab=\"c_c²\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic.filter((res: any) => res['name'].indexOf('c_c²') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c¹_c³\" tab=\"c¹_c³\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic.filter((res: any) => res['name'].indexOf('c¹_c³') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c²_c⁴\" tab=\"c²_c⁴\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic.filter((res: any) => res['name'].indexOf('c²_c⁴') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c³_c⁵\" tab=\"c³_c⁵\"> \n            <n-data-table\n              :columns=\"originalColumns\"\n              :data=\"music.translateOriginalMusic.filter((res: any) => res['name'].indexOf('c³_c⁵') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n        </n-tabs>\n      </n-tab-pane>\n      <n-tab-pane name=\"myTranslate\" :tab=\"t('tab.myTranslate')\">\n        <n-tabs type=\"line\" animated placement=\"left\" style=\"height: 500px\">\n          <n-tab-pane name=\"all\" tab=\"所有\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"translateOriginalMusic\" tab=\"原曲\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('_vocals') === -1 && res['name'].indexOf('_beat') === -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"vocals\" tab=\"人声\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('_vocals') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"beat\" tab=\"伴奏\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('_beat') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"C_c¹\" tab=\"C_c¹\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('C_c¹') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c_c2\" tab=\"c_c²\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('c_c²') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c¹_c³\" tab=\"c¹_c³\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('c¹_c³') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c²_c⁴\" tab=\"c²_c⁴\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('c²_c⁴') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c³_c⁵\" tab=\"c³_c⁵\"> \n            <n-data-table\n              :columns=\"translateColumns\"\n              :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('c³_c⁵') !== -1)\"\n              :bordered=\"false\"\n              :max-height=\"350\"\n              :scroll-x=\"100\"\n              row-class-name=\"td_css\"\n              style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n        </n-tabs>\n      </n-tab-pane>\n    </n-tabs>\n  </n-card>\n</template>\n\n<script lang=\"ts\" setup>\nimport { getData, sendData, getList, setConfig } from \"@renderer/utils/fetchUtils\";\nimport { h, onUnmounted, reactive, ref, watch, CSSProperties } from \"vue\";\nimport { NButton, useMessage } from \"naive-ui\";\nimport {\n  CloudArrowUp32Filled,\n  ArrowSync24Regular\n} from '@vicons/fluent'\nimport { useI18n } from \"vue-i18n\";\nimport { resolve } from \"path\";\nconst { t } = useI18n();\nconst message = useMessage();\nconst processFlag = ref(false);\nlet progressInterval:any = null\nlet chooseType:any = ref(['2'])\nlet is_singular = ref(true)\nlet semitone_switch = ref(true)\nlet detail_switch = ref(true)\nlet split_switch = ref(false)\n\nlet merge_min = ref(20)\nlet merge_max = ref(30)\nlet velocity_filter = ref(10)\n\n\nwatch(merge_min, ()=>{ setConfig('merge_min', merge_min.value)})\nwatch(merge_max, ()=>{ setConfig('merge_max', merge_max.value)})\nwatch(velocity_filter, ()=>{ setConfig('velocity_filter', velocity_filter.value)})\nsendData(\"config_operate\",{ \"operate\": \"get\", \"name\": \"merge_min\"}).then(res=>{ merge_min.value=res})\nsendData(\"config_operate\",{ \"operate\": \"get\", \"name\": \"merge_max\"}).then(res=>{ merge_max.value=res})\nsendData(\"config_operate\",{ \"operate\": \"get\", \"name\": \"velocity_filter\"}).then(res=>{ velocity_filter.value=res})\n\nfunction handleFinish() {\n  reloadTable()\n  message.success('OK~')\n}\n\nconst music = reactive({\n  translateOriginalMusic: [], // 导入的音乐\n  myTranslate: [], // 扒谱的音乐\n});\n\nconst progress = reactive({\n  overall_progress: 0,\n});\n\nconst now_translate_text = reactive({\n  process: \"\",\n  text: \"\",\n});\n\nconst originalColumns = [\n  {\n    title: t('columns.name'),\n    key: \"name\",\n    className: \"th_css\",\n  },\n  {\n    title: t('columns.operation'),\n    key: \"operation\",\n    width: 100,\n    className: \"th_css\",\n    render(row) {\n      return h(\n        NButton,\n        {\n          size: \"medium\",\n          text: true,\n          onClick: () => {\n            originalClick(row.name)\n            window.api.sync_sheet_2_el()\n          }\n        },\n        { default: () => \"❌\" }\n      );\n    },\n  },\n];\n\nconst translateColumns = [\n  {\n    title: t('columns.name'),\n    key: \"name\",\n    className: \"th_css\",\n  },\n  {\n    title: t('columns.total_duration'),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n  {\n    title: t('columns.operation'),\n    key: \"operation\",\n    width: 100,\n    className: \"th_css\",\n    render(row) {\n      return h(\n        NButton,\n        {\n          size: \"medium\",\n          text: true,\n          onClick: () => {\n            translateClick(row.truthName)\n            window.api.sync_sheet_2_el()\n          }\n        },\n        { default: () => \"❌\" }\n      );\n    },\n  },\n];\n\nfunction timeToSeconds(timeString) {\n    var splitTime = timeString.split(':');\n\n    // 如果是 HH:MM:SS 格式\n    if (splitTime.length === 3) {\n        var hours = parseInt(splitTime[0], 10);\n        var minutes = parseInt(splitTime[1], 10);\n        var seconds = parseInt(splitTime[2], 10);\n        return hours * 3600 + minutes * 60 + seconds;\n    }\n\n    // 如果是 MM:SS 格式\n    if (splitTime.length === 2) {\n        var minutes = parseInt(splitTime[0], 10);\n        var seconds = parseInt(splitTime[1], 10);\n        return minutes * 60 + seconds;\n    }\n\n    return 0; // 如果格式不正确，返回0\n}\n\n\nfunction railStyle({ focused, checked }){\n  const style: CSSProperties = {}\n  if (checked) {\n    style.background = '#F2C9C4'\n    if (focused) {\n      style.boxShadow = '0 0 0 2px #F2C9C440'\n    }\n  }\n  else {\n    style.background = '#F2E8C4'\n    if (focused) {\n      style.boxShadow = '0 0 0 2px #F2E8C440'\n    }\n  }\n  return style\n}\n\n\nfunction singularChange(value: boolean){\n  sendData(\"config_operate\",{\n    operate: \"set\",\n    name: \"is_singular\",\n    value\n  })\n}\nfunction detailChange(value: boolean){\n  sendData(\"config_operate\",{\n    operate: \"set\",\n    name: \"detail_switch\",\n    value\n  })\n}\nfunction splitChange(value: boolean){\n  sendData(\"config_operate\",{\n    operate: \"set\",\n    name: \"split_switch\",\n    value\n  })\n}\n\nfunction semitoneChange(value: boolean){\n  sendData(\"config_operate\",{\n    operate: \"set\",\n    name: \"semitone_switch\",\n    value\n  })\n}\n\n/**\n * 处理原始音乐删除\n */\nasync function originalClick(name: string) {\n  try {\n    const baseName = name.slice(0, name.lastIndexOf(\".\"));\n    const suffix = name.match(/(\\.[^.]*)$/)?.[0] || \"\";\n    await sendData(\"config_operate\", {\n      fileName: baseName,\n      type: \"translateOriginalMusic\",\n      suffix,\n      operate: \"drop_file\",\n    });\n\n    await sendData(\"config_operate\", {\n      fileName: baseName.replace(\"_ok\", \"_basic_pitch\"),\n      type: \"translateMID\",\n      suffix: \".mid\",\n      operate: \"drop_file\",\n    });\n\n    handleUpdateValue(\"translateOriginalMusic\");\n    message.success(t('messeage.remove_success'));\n  } catch (error) {\n    console.error(t('messeage.remove_fail'), error);\n  }\n}\n\n/**\n * 处理扒谱音乐删除\n */\nasync function translateClick(name: string) {\n  try {\n    await sendData(\"config_operate\", {\n      fileName: name,\n      type: \"myTranslate\",\n      operate: \"drop_file\",\n    });\n\n    handleUpdateValue(\"translateOriginalMusic\");\n    handleUpdateValue(\"myTranslate\");\n    message.success(t('messeage.remove_success'));\n  } catch (error) {\n    console.error(t('messeage.remove_fail'), error);\n  }\n}\n\n/**\n * 获取转换进度\n */\nasync function getProgress() {\n  try {\n    const res = await getData(\"getProgress\");\n    progress.overall_progress = res.overall_progress;\n    now_translate_text.text = res.now_translate_text?.[0] || \"\";\n    now_translate_text.process = res.now_translate_text?.[1] || \"\";\n\n    if (\"\"+progress.overall_progress === \"100.0\") {\n      if (progressInterval) {\n        clearInterval(progressInterval);\n        progressInterval = null;\n      }\n    }\n  } catch (error) {\n    console.error(t('messeage.progress_fail'), error);\n  }\n}\n\n/**\n * 开始扒谱转换\n */\nasync function handleStartTranslate() {\n  if (processFlag.value) return;\n  processFlag.value = true;\n  message.success(t('kube.star_transfer'));\n\n  if (!progressInterval) {\n    progressInterval = setInterval(getProgress, 1000) as unknown as number;\n  }\n\n  try {\n    await sendData(\"translate\", { operate: \"translate\", value: chooseType.value.join() });\n    reloadTable();\n    message.success(t('kube.transfer_success'));\n  } catch (error) {\n    console.error(t('kube.transfer_fail'), error);\n  } finally {\n    processFlag.value = false;\n    window.api.sync_sheet_2_el()\n  }\n}\n\n/**\n * 重新加载表格数据\n */\nfunction reloadTable() {\n  handleUpdateValue(\"myTranslate\");\n  handleUpdateValue(\"translateOriginalMusic\");\n}\n\n/**\n * 监听进度变化，自动更新表格\n */\nwatch(\n  () => progress.overall_progress,\n  () => {\n    if (\"\"+progress.overall_progress === \"100.0\") {\n      reloadTable();\n    }\n  }\n);\n\n/**\n * 更新音乐列表数据\n */\nasync function handleUpdateValue(value: keyof typeof music) {\n  try {\n    const res = await getList(value, \"\");\n    music[value] = res;\n  } catch (error) {\n    console.error(t('kube.get_fail', {value}), error);\n  }\n}\n\nreloadTable();\n\nsendData(\"config_operate\",{ operate: \"get\", name: \"is_singular\"}).then(res=>{ is_singular.value=res})\nsendData(\"config_operate\",{ operate: \"get\", name: \"detail_switch\"}).then(res=>{ detail_switch.value=res})\nsendData(\"config_operate\",{ operate: \"get\", name: \"semitone_switch\"}).then(res=>{ semitone_switch.value=res})\nsendData(\"config_operate\",{ operate: \"get\", name: \"split_switch\"}).then(res=>{ split_switch.value=res})\nsendData(\"config_operate\",{ operate: \"get\", name: \"velocity_filter\"}).then(res=>{ velocity_filter.value=res})\nsendData(\"config_operate\",{ operate: \"get\", name: \"merge_max\"}).then(res=>{ merge_max.value=res})\nsendData(\"config_operate\",{ operate: \"get\", name: \"merge_min\"}).then(res=>{ merge_min.value=res})\n\nonUnmounted(function(){\n  clearInterval(progressInterval);\n})\n\n</script>\n<style scoped>\n:deep(.n-tabs-bar){\n  --n-bar-color: rgb(242,232,196)!important;\n}\n:deep(.n-tabs){\n    --n-tab-text-color-active: rgb(242,232,196)!important;\n    --n-tab-text-color-hover: rgb(242,232,196)!important;\n    --n-tab-text-color: rgb(221,242,196)!important;\n}\n.n-input{\n  background-color: rgba(24, 24, 28, 0) !important;\n  border: 1px solid rgba(242,232,196,0.5);\n}\n:deep(.td_css td) {\n  color: rgb(242,232,196) !important;\n}\n:deep(.th_css){\n  color: rgb(221,242,196) !important;\n}\n:deep(.n-checkbox){\n  --n-color-checked: rgb(242,232,196)!important;\n  --n-border-checked: 1px solid #F2C9C4 !important;\n  --n-border-focus: 1px solid #F2C9C4 !important;\n  --n-text-color: #F2C9C4 !important;\n}\n:deep(.n-input){\n  --n-border-hover: 1px solid rgb(242,232,196)!important;\n  --n-border-focus: 1px solid rgb(242,232,196)!important;\n  --n-caret-color: rgb(242,232,196)!important;\n  --n-color-focus: rgba(242,232,196,0.1)!important;\n  --n-text-color: #F2C9C4 !important;\n}\n</style>"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/magicTools.vue",
    "content": "<template>\n  <div class=\"father\">\n    <n-divider>\n        ⚠\n    </n-divider>\n    <div class=\"father\">\n      <n-highlight style=\"margin-bottom: 5px\" :text=\"headText\" :patterns=\"patterns\" :highlight-style=\"{\n        padding: '0 6px',\n        margin: '0 6px',\n        borderRadius: themeVars.borderRadius,\n        display: 'inline-block',\n        color: 'black',\n        background: '#F2E8C4',\n        transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n      }\" />\n      <n-highlight style=\"margin-bottom: 5px\" :text=\"headText2\" :patterns=\"patterns\" :highlight-style=\"{\n        padding: '0 6px',\n        margin: '0 6px',\n        borderRadius: themeVars.borderRadius,\n        display: 'inline-block',\n        color: 'black',\n        background: '#F2E8C4',\n        transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n      }\" />\n      <n-highlight style=\"margin-bottom: 5px\" :text=\"headText3\" :patterns=\"patterns\" :highlight-style=\"{\n        padding: '0 6px',\n        margin: '0 6px',\n        borderRadius: themeVars.borderRadius,\n        display: 'inline-block',\n        color: 'black',\n        background: '#F2E8C4',\n        transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n      }\" />\n      <n-divider />\n      <div class=\"father\">\n        <n-space style=\"width: 100%;\" align='center' justify='center'>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('Y')\">Y</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('U')\">U</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('I')\">I</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('O')\">O</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('P')\">P</n-button>\n        </n-space>\n        <n-space class=\"dynamicSpaceStyles\" align='center' justify='center'>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('H')\">H</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('J')\">J</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('K')\">K</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('L')\">L</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress(';')\">;</n-button>\n        </n-space>\n        <n-space class=\"dynamicSpaceStyles\" align='center' justify='center'>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('N')\">N</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('M')\">M</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress(',')\">,</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('.')\">.</n-button>\n          <n-button class=\"dynamicButtonStyles\" ghost @click=\"keypress('/')\">/</n-button>\n        </n-space>\n      </div>\n      <n-divider />\n      <div class=\"father\" v-for=\"button in buttons\">\n        <n-button dashed :color=button.color @click=\"run(button.value)\"\n          :style=\"{ marginTop: '10px', marginLeft: button.value === 'autoFire' ? '0px' : '15px' }\"\n          v-if=\"button.value != 'developer' && button\">\n          {{ button.context }}\n        </n-button>\n        <n-upload v-else action=\"http://localhost:9899/autoScriptUpload\" style=\"margin-top:10px; margin-left: 15px;\" accept=\".txt\"\n          :show-file-list=\"false\">\n          <n-button type=\"info\" dashed :color=button.color> {{ button.context }}</n-button>\n        </n-upload>\n      </div>\n      <n-input-group class=\"father\" style=\"margin-top: 20px;\">\n        <n-select v-model:value=\"selectValue\" :options=\"options\" style=\"width: 15%;\" />\n        <n-input-number v-model:value=\"mathValue\" clearable step=\"0.01\" style=\" margin-left: 20px; width: 20%;\" />\n        <n-button type=\"error\" dashed style=\"margin-left: 20px;\" @click=\"checkFile\">\n          {{ t('magic_tools.buttons.check') }}\n        </n-button>\n        <n-input-number style=\"margin-left: 10px !important; width: 30%;\" v-model:value=\"QCount\" />\n        <n-button type=\"primary\" @click=\"run('alwaysQ')\" dashed >\n          {{ t('magic_tools.buttons.abaaba') }}\n        </n-button>\n      </n-input-group>\n      <n-input-group  style=\"flex: 0 0 100%; margin-top: 10px;\" class=\"father\">\n      </n-input-group>\n    </div>\n        <n-input-number style=\"margin-left: 10px !important; width: 30%;\" v-model:value=\"sheld\" step=\"0.01\" max=\"1\" min=\"0.3\"/>\n        <n-button type=\"primary\" @click=\"setConfig('sheld', sheld)\" dashed >\n          置信度变更\n        </n-button>\n    <n-divider />\n    <div class=\"father\" v-for=\"button in fileButtons\">\n        <n-button dashed :color=button.color @click=\"openFileHandle(button.value)\"\n          :style=\"{ marginTop: '20px', marginLeft: button.value === 'systemMusic' ? '0' : '15px' }\">\n          {{ button.context }}\n        </n-button>\n      </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { sendData, setConfig } from \"@renderer/utils/fetchUtils\";\nimport { useThemeVars } from \"naive-ui\";\nimport { ref } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\nconst themeVars = useThemeVars();\nconst headText = t(\"magic_tools.head_text\");\nconst headText2 = t(\"magic_tools.head_text2\");\nconst headText3 = t(\"magic_tools.head_text3\");\nconst patterns = [t(\"magic_tools.patterns1\"),t(\"magic_tools.patterns2\"),t(\"magic_tools.patterns3\")]\nlet mathValue = ref(0.5)\nlet selectValue = ref(\"image\")\nconst QCount = ref(300)\nconst sheld = ref(0.7)\nconst options = [\n  {\n    label: t('magic_tools.buttons.heart_fire'),\n    value: 'image'\n  },\n  {\n    label: t('magic_tools.buttons.key'),\n    value: 'key'\n  }\n]\nconst buttons = [\n  {\n    color:\"#F2C97D\",\n    context:t('magic_tools.buttons.autoFire'),\n    value: \"autoFire\"\n  },\n  {\n    color:\"#fe6673\",\n    context:t('magic_tools.buttons.developer'),\n    value: \"developer\"\n  },{\n    color:\"#ff0000\",\n    context:t('magic_tools.buttons.shutdown'),\n    value: \"shutdown\"\n  },\n]\n\nconst fileButtons = [\n  {\n    color:\"#afdfe4\",\n    context:t('magic_tools.fileButtons.systemMusic'),\n    value: \"systemMusic\"\n  },\n  {\n    color:\"#45b97c\",\n    context:t('magic_tools.fileButtons.myImport'),\n    value: \"myImport\"\n  },\n  {\n    color:\"#ea66a6\",\n    context:t('magic_tools.fileButtons.myTranslate'),\n    value: \"myTranslate\"\n  },\n  {\n    color:\"#ef4136\",\n    context:t('magic_tools.fileButtons.myFavorite'),\n    value: \"myFavorite\"\n  },\n  {\n    color:\"#9b95c9\",\n    context:t('magic_tools.fileButtons.translateMID'),\n    value: \"translateMID\"\n  }\n]\n\nfunction run(value: any){\n  console.log(value)\n  switch(value){\n    case 'shutdown':\n      shutdown()\n      break;\n    case 'alwaysQ':\n      for ( let i = 0 ; i <= QCount.value; i++){\n        keypress('Q')\n      }\n      break;\n    case 'autoFire':\n      autoClickFire()\n      break;\n  }\n}\n\nfunction checkFile(){\n  sendData(\"test\",{\n    operate:selectValue.value,\n    conf:mathValue.value\n  })\n}\n\nfunction keypress(key){\n  sendData(\"test\",{\n    operate:'press',\n    key\n  })\n}\n\nfunction autoClickFire(){\n  window.api.system_notification(\"🔧🔧🔧🔧🔧\", t('magic_tools.messeage.start'))\n  sendData(\"auto\", {\n    \"operate\":\"click_fire\"\n  })\n}\n\nfunction shutdown(){\n  window.api.system_notification(\"⛔⛔⛔⛔⛔\", t('magic_tools.messeage.stop'))\n  sendData(\"auto\", {\n    \"operate\":\"shutdown\"\n  })\n}\n\nfunction openFileHandle(type) {\n  sendData('openFiles',{\n      \"operate\":\"files\",\n      \"type\":type\n  })\n}\n\n</script>\n\n<style scoped>\n.father {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  flex-wrap: wrap;\n}\n.dynamicButtonStyles{\n    height: 50px;\n    width: 50px;\n    margin-left: 5px;\n    font-size: 20px;\n}\n.dynamicSpaceStyles{\n  margin-top: 10px;\n}\n\n:deep(.n-input){\n  --n-border-hover: 1px solid rgb(242,232,196)!important;\n  --n-border-focus: 1px solid rgb(242,232,196)!important;\n  --n-caret-color: rgb(242,232,196)!important;\n  --n-color-focus: rgba(242,232,196,0.1)!important;\n}\n</style>\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/music.vue",
    "content": "<template>\n  <n-flex align=\"center\" style=\"margin-left: 6px;\">\n    <n-gradient-text :size=\"20\" type=\"success\" style=\"width: 100%; color:#F2C9C4\">\n      {{ t(\"music.chose\") + nowPlayMusic + '' }}\n    </n-gradient-text>\n    <n-gradient-text :size=\"20\" type=\"success\" style=\"width: 100%; color:#F2E8C4\">\n      {{ t(\"music.play\") + nowSelectMusic + '' }}\n    </n-gradient-text>\n    <n-flex style=\"width: 100%\">\n      <n-slider v-model:value=\"progress\" :step=\"0.1\" style=\"max-width: 51.5%; display: inline-block; margin-left: 3px;\"\n                @dragend=\"drag_progress_end\" @dragstart=\"drag_progress_start\">\n        <template #thumb>\n          <n-icon-wrapper :size=\"20\" :border-radius=\"12\" style=\"background-color:#F2E8C4\">\n            <n-icon :size=\"16\" :component=\"PawSharp\" />\n          </n-icon-wrapper>\n        </template>\n      </n-slider>\n      <div></div>\n    <n-gradient-text :size=\"15\" type=\"success\" style=\"color:#F2E8C4; margin-top: -2px;\">\n      {{nowCurrentTime}} / {{nowTotalTime}}\n    </n-gradient-text>\n    </n-flex>\n    <n-row gutter=\"12\">\n        <n-button quaternary circle type=\"info\" size=\"large\" @click=\"playBarClickHandler('resume', '')\" v-show=\"!isPlay\" color=\"#F2C9C4\">\n          <template #icon>\n            <n-icon size=\"25px\">\n              <Play />\n            </n-icon>\n          </template>\n        </n-button>\n        <n-button quaternary circle type=\"info\" size=\"large\" @click=\"playBarClickHandler('pause', '')\" v-show=\"isPlay\" color=\"#F2C9C4\">\n          <template #icon>\n            <n-icon size=\"25px\">\n              <Pause />\n            </n-icon>\n          </template>\n        </n-button>\n        <n-button quaternary circle type=\"info\" size=\"large\" @click=\"playBarClickHandler('next', '')\" color=\"#F2C9C4\" class='actionButton'>\n          <template #icon>\n            <n-icon size=\"25px\">\n              <PlaySkipForward />\n            </n-icon>\n          </template>\n        </n-button>\n        <n-popover placement=\"bottom-start\" trigger=\"click\" style=\"width: 450px; --n-color: rgba(47,47,55,1); border-radius: 10px;\">\n          <template #trigger>\n            <n-button quaternary circle type=\"info\" size=\"large\" color=\"#F2C9C4\" class='actionButton'>\n              <template #icon>\n                <n-icon size=\"25px\">\n                  <Settings48Filled />\n                </n-icon>\n              </template>\n            </n-button>\n          </template>\n          <n-row gutter=\"26\">\n            <n-col :span=\"15\">\n              <n-gradient-text type=\"info\" :size=\"13\" style=\"color: #F2C9C4; display: block;\">{{t(\"music.space.title\") }}</n-gradient-text>\n              <n-radio-group v-model:value=\"delayStatus\" name=\"radiogroup\" style=\"margin-top: 5px; margin-bottom: 5px\" @keydown.stop.prevent>\n                <n-space>\n                  <n-radio key=\"system\" value=\"system\" style=\"color: red;\" @keydown.stop.prevent>{{t(\"music.space.chose0\") }}</n-radio>\n                  <n-radio key=\"random\" value=\"random\" @keydown.stop.prevent>{{t(\"music.space.chose1\") }}</n-radio>\n                  <n-radio key=\"custom\" value=\"custom\" @keydown.stop.prevent>{{t(\"music.space.chose2\") }}</n-radio>\n                </n-space>\n              </n-radio-group>\n            </n-col>\n            <n-col v-show=\"delayStatus == 'custom'\" :span=\"5\" style=\"margin-left: -40px; margin-top: 25px;\">\n              <n-input-number step=\"0.01\" v-model:value=\"delaySpeed\" size=\"tiny\" :min=\"0\" :max=\"2\" :placeholder=\"t('music.placeholder1')\" style=\"width: 150px;\" />\n            </n-col>\n            <n-col v-show=\"delayStatus == 'random'\" :span=\"11\" style=\"margin-left: -40px; margin-top: 25px;\">\n              <n-input-number step=\"0.01\" v-model:value=\"delayRandomStart\" size=\"tiny\" :min=\"0\" :max=\"2\" :placeholder=\"t('music.placeholder1')\" style=\"width: 83px; float: inline-start;\" />\n              <span style=\"margin-left: 9px;\">&nbsp;-&nbsp;</span>\n              <n-input-number step=\"0.01\" v-model:value=\"delayRandomEnd\" size=\"tiny\" :min=\"0\" :max=\"2\" :placeholder=\"t('music.placeholder1')\" style=\"width: 83px; float: inline-end;\"/>\n            </n-col>\n          </n-row>\n          <n-row gutter=\"26\">\n            <n-col :span=\"15\">\n              <n-gradient-text type=\"info\" :size=\"13\" style=\"color: #F2C9C4; display: block;\">{{t(\"music.space.title1\") }}</n-gradient-text>\n              <n-radio-group v-model:value=\"durationStatus\" name=\"radiogroup\" style=\"margin-top: 5px; margin-bottom: 5px\" @keydown.stop.prevent>\n                <n-space>\n                  <n-radio key=\"system\" value=\"system\" @keydown.stop.prevent>{{t(\"music.space.chose0\") }}</n-radio>\n                  <n-radio key=\"random\" value=\"random\" @keydown.stop.prevent>{{t(\"music.space.chose1\") }}</n-radio>\n                  <n-radio key=\"custom\" value=\"custom\" @keydown.stop.prevent>{{t(\"music.space.chose2\") }}</n-radio>\n                </n-space>\n              </n-radio-group>\n            </n-col>\n            <n-col v-show=\"durationStatus == 'custom'\" :span=\"5\" style=\"margin-left: -40px; margin-top: 25px;\">\n              <n-input-number step=\"0.01\" v-model:value=\"durationSpeed\" size=\"tiny\" :min=\"0\" :max=\"2\" :placeholder=\"t('music.placeholder2')\" style=\"width: 150px;\" />\n            </n-col>\n            <n-col v-show=\"durationStatus == 'random'\" :span=\"11\" style=\"margin-left: -40px; margin-top: 25px;\">\n              <n-input-number step=\"0.01\" v-model:value=\"durationRandomStart\" size=\"tiny\" :min=\"0\" :max=\"2\" :placeholder=\"t('music.placeholder2')\" style=\"width: 83px; float: inline-start;\"  />\n              <span style=\"margin-left: 9px;\">&nbsp;-&nbsp;</span>\n              <n-input-number step=\"0.01\" v-model:value=\"durationRandomEnd\" size=\"tiny\" :min=\"0\" :max=\"2\" :placeholder=\"t('music.placeholder2')\" style=\"width: 83px; float: inline-end;\"  />\n            </n-col>\n          </n-row>\n          <n-row gutter=\"12\">\n            <n-col :span=\"5\">\n              <n-gradient-text type=\"info\" :size=\"13\" style=\"color: #F2C9C4; display: block;\">{{t(\"music.space.mult_speed\") }}</n-gradient-text>\n              <n-input-number step=\"0.1\" v-model:value=\"playSpeed\" size=\"tiny\" :min=\"0.1\" :max=\"5\" :placeholder=\"t('music.space.mult_speed')\" style=\"margin-top: 5px;\" />\n            </n-col>\n          </n-row>\n        </n-popover>\n        <n-button quaternary circle type=\"info\" size=\"large\" @click=\"reloadMusicList()\" color=\"#F2C9C4\" class='actionButton'>\n          <template #icon>\n            <n-icon size=\"25px\">\n              <BookStar24Filled />\n            </n-icon>\n          </template>\n        </n-button>\n        <n-popselect v-model:value=\"selectMode\" :options=\"modeColumns\" style=\"height:100%\">\n          <n-button quaternary circle color=\"#F2C9C4\" size=\"large\" class='actionButton'>\n            <template #icon>\n              <n-icon v-if=\"selectMode == 'order'\" size=\"25px\"><List /></n-icon>\n              <n-icon v-if=\"selectMode == 'random'\" size=\"25px\"><ShuffleOutline /></n-icon>\n              <n-icon v-if=\"selectMode == 'cycle'\" size=\"25px\"><Sync /></n-icon>\n            </template>\n          </n-button>\n        </n-popselect>\n        <n-upload action=\"http://localhost:9899/userMusicUpload\" multiple accept=\".txt\" style=\"width: 60px;\"\n          :show-file-list=\"false\" @finish=\"handleFinish\" @before-upload=\"beforeFileUpload\">\n          <n-button type=\"info\" quaternary circle  size=\"large\" color=\"#F2C9C4\" class='actionButton'>\n            <template #icon>\n              <n-icon size=\"25px\"><CloudArrowUp32Filled /></n-icon>\n            </template>\n          </n-button>\n        </n-upload>\n        <n-button quaternary circle type=\"info\" size=\"large\" @click=\"locationNowPlayMusic()\" color=\"#F2C9C4\" class='actionButton'>\n          <template #icon>\n            <n-icon size=\"25px\">\n              <Location28Filled />\n            </n-icon>\n          </template>\n        </n-button>\n    </n-row>\n  </n-flex>\n  <n-card style=\"margin-left: -16px; width: 640px;\" :bordered=\"false\">\n    <n-tabs type=\"bar\" animated size=\"small\" @update:value=\"handleUpdateValue\" @before-leave=\"handleBeforeLeave\" :value=\"tabsNumber\">\n      <n-tab-pane name=\"systemMusic\" :tab=\"t('tab.systemMusic')\">\n        <n-data-table :columns=\"musicColumns\" :data=\"music.systemMusic\" :bordered=\"false\" :min-row-height=\"48\" ref=\"systemMusic\"\n          :max-height=\"430\" :virtual-scroll=\"music.systemMusic?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n          style=\"\n            --n-td-color: rgba(57, 57, 62, 0);\n            --n-th-color-hover: rgba(57, 57, 62, 0);\n            --n-th-color: rgba(57, 57, 62, 0);\n            --n-td-color-hover: rgba(0, 0, 0, 0.2);\n          \"/>\n      </n-tab-pane>\n      <n-tab-pane name=\"myImport\" :tab=\"t('tab.myImport')\" ref=\"myImport\">\n        <n-data-table :columns=\"myImportColumns\" :data=\"music.myImport\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myImport\"\n        :max-height=\"430\" :virtual-scroll=\"music.myImport?.length > 7\" :row-props=\"MusicSelect\"  :row-class-name=\"rowClassName\"\n        style=\"\n            --n-td-color: rgba(57, 57, 62, 0);\n            --n-th-color-hover: rgba(57, 57, 62, 0);\n            --n-th-color: rgba(57, 57, 62, 0);\n            --n-td-color-hover: rgba(0, 0, 0, 0.2);\n          \"/>\n      </n-tab-pane>\n      <n-tab-pane name=\"myTranslate\" :tab=\"t('tab.myTranslate')\" ref=\"myTranslate\">\n        <n-tabs type=\"line\" animated placement=\"left\" style=\"height: 500px\">\n          <n-tab-pane name=\"all\" tab=\"所有\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"translateOriginal\" tab=\"原曲\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('_vocals') === -1 && res['name'].indexOf('_beat') === -1)\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"vocals\" tab=\"人声\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('_vocals') !== -1)\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"beat\" tab=\"伴奏\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('_beat') !== -1)\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"C_c¹\" tab=\"C_c¹\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('C_c¹') !== -1)\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c_c2\" tab=\"c_c²\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('c_c²') !== -1)\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c¹_c³\" tab=\"c¹_c³\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('c¹_c³') !== -1)\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c²_c⁴\" tab=\"c²_c⁴\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('c²_c⁴') !== -1)\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n          <n-tab-pane name=\"c³_c⁵\" tab=\"c³_c⁵\"> \n            <n-data-table :columns=\"musicColumns\" :data=\"music.myTranslate.filter((res: any) => res['name'].indexOf('c³_c⁵') !== -1)\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myTranslate\"\n            :max-height=\"430\" :virtual-scroll=\"music.myTranslate?.length > 7\" :row-props=\"MusicSelect\" :row-class-name=\"rowClassName\"\n            style=\"\n                --n-td-color: rgba(57, 57, 62, 0);\n                --n-th-color-hover: rgba(57, 57, 62, 0);\n                --n-th-color: rgba(57, 57, 62, 0);\n                --n-td-color-hover: rgba(0, 0, 0, 0.2);\n              \"/>\n          </n-tab-pane>\n        </n-tabs>\n      </n-tab-pane>\n      <n-tab-pane name=\"myFavorite\" :tab=\"t('tab.myFavorite')\" ref=\"myFavorite\">\n        <n-data-table :columns=\"favoritColumns\" :data=\"music.myFavorite\" :bordered=\"false\" :min-row-height=\"48\" ref=\"myFavorite\"\n        :max-height=\"430\" :virtual-scroll=\"music.myFavorite?.length > 7\" :row-props=\"MusicSelect\"  :row-class-name=\"rowClassName\"\n        style=\"\n            --n-td-color: rgba(57, 57, 62, 0);\n            --n-th-color-hover: rgba(57, 57, 62, 0);\n            --n-th-color: rgba(57, 57, 62, 0);\n            --n-td-color-hover: rgba(0, 0, 0, 0.2);\n          \"/>\n      </n-tab-pane>\n      <template #suffix>\n        <n-input v-model:value=\"searchText\" round placeholder=\"搜索\" clearable\n          style=\"top:-3px;width: 25vh; margin-left: 5px\">\n          <template #suffix>\n            <n-icon :component=\"Search\" />\n          </template>\n        </n-input>\n      </template>\n    </n-tabs>\n  </n-card>\n  <n-drawer v-model:show=\"active\" :width=\"400\" :placement=\"placement\" style=\"border-radius: 30px;\">\n    <n-drawer-content :title=\"t('tab.title')\">\n      <n-button type=\"info\" ghost style=\"margin-bottom: 10px;\" @click=\"clearPlayList\" color=\"#F2C9C4\"> {{t('tab.clear')}} </n-button>\n      <n-data-table :columns=\"musicListColumns\" :max-height=\"570\" :data=\"music.musicList\" :bordered=\"false\"\n        :height-for-row=\"1\" :virtual-scroll=\"music.systemMusic?.length > 7\" :row-props=\"musicListSelect\" />\n    </n-drawer-content>\n  </n-drawer>\n</template>\n\n\n<script lang=\"ts\" setup>\nimport { getData, sendData, getList, setConfig } from '@renderer/utils/fetchUtils'\n\nimport { DataTableInst, RowData } from 'naive-ui/es/data-table/src/interface'\nimport { h, onMounted, onUnmounted, reactive, ref, watch } from 'vue'\nimport { NButton, useMessage, DrawerPlacement } from 'naive-ui'\nimport {\n  Search,\n  ShuffleOutline,\n  List,\n  Play,\n  PlaySkipForward,\n  Pause,\n  PawSharp,\n  Sync\n} from '@vicons/ionicons5'\nimport {\n  Settings48Filled,\n  BookStar24Filled,\n  CloudArrowUp32Filled,\n  Location28Filled\n} from '@vicons/fluent'\nimport { useStore } from 'vuex'\nimport { debounce } from 'lodash-es'\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\n// ---------------------------------------------------\n// 响应式状态和常量定义\n// ---------------------------------------------------\nconst message = useMessage()\nconst store = useStore()\n\nconst music: any = reactive({\n  // 音乐列表\n  systemMusic: [], // 原版音乐\n  myImport: [], // 导入的音乐\n  myTranslate: [], // 扒谱的音乐\n  myFavorite: [], // 我的最爱\n  musicList: [] // 我的最爱\n})\n\nconst nowSelectMusic = ref(t('controller.no_music')) // 当前选中歌曲\nlet nowSelectMusicTruth = \"\" // 当前选中歌曲真实名称\nconst nowPlayMusic = ref(t('controller.no_music')) // 当前播放歌曲名称\nlet nowType = 'systemMusic'\nlet progressInterval: any = 0\nlet socket\nconst searchText = ref('')\nconst nowState: any = ref('stop') // 当前播放状态\nconst delayStatus = ref('system')\nconst durationStatus = ref('system')\nconst isPlay = ref(false)\nconst active = ref(false)\nconst placement = ref<DrawerPlacement>('left')\nconst selectMode = ref(\"order\")\nlet cycleMusic: any = {}\nlet shortcutKeys = {} // 快捷键按键\n\nconst modeColumns = [\n  {\n    label: t('rule.order'),\n    value: 'order'\n  },\n  {\n    label: t('rule.random'),\n    value: 'random'\n  },\n  {\n    label: t('rule.cycle'),\n    value: 'cycle'\n  }\n]\n\nconst musicColumns = [\n  {\n    title: t('columns.name'),\n    key: 'name',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },\n  {\n    title: t('columns.total_duration'),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n  {\n    title: t('columns.operation'),\n    key: 'operation',\n    width: 60,\n    className: 'th_css',\n    render(row) {\n      return h(\n        NButton,\n        {\n          size: 'medium',\n          text: true,\n          onClick: () => {\n            heartClick(row.truthName, true)\n            window.api.sync_sheet_2_el()\n          }\n        },\n        {\n          default: () => {\n            return music.myFavorite.filter((res) => {\n              return res.truthName.replaceAll('.mp3').includes(row.truthName)\n            }).length == 0\n              ? '❤'\n              : null\n          }\n        }\n      )\n    }\n  }\n]\n\nconst favoritColumns = [\n  {\n    title: t('columns.name'),\n    key: 'name',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },\n  {\n    title: t('columns.total_duration'),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n  {\n    title: t('columns.operation'),\n    key: 'operation',\n    width: 60,\n    className: 'th_css',\n    render(row) {\n      return h(\n        NButton,\n        {\n          size: 'medium',\n          text: true,\n          onClick: () => {\n            heartClick(row.truthName, false)\n            window.api.sync_sheet_2_el()\n          }\n        },\n        {\n          default: () => {\n            return '💔'\n          }\n        }\n      )\n    }\n  }\n]\n\nconst myImportColumns = [\n  {\n    title: t('columns.name'),\n    key: 'name',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },\n  {\n    title: t('columns.total_duration'),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n  {\n    title: t('columns.operation'),\n    key: 'operation',\n    width: 60,\n    className: 'th_css',\n    render(row) {\n      return h(\n        NButton,\n        {\n          size: 'medium',\n          text: true,\n          onClick: () => {\n            deleteClick(row.truthName)\n            window.api.sync_sheet_2_el()\n          }\n        },\n        {\n          default: () => {\n            return '❌'\n          }\n        }\n      )\n    }\n  }\n]\n\nconst musicListColumns = [\n  {\n    title: t('columns.name'),\n    key: 'name',\n    resizable: true,\n    className: 'th_css'\n  }\n]\n\nfunction timeToSeconds(timeString) {\n    var splitTime = timeString.split(':');\n\n    // 如果是 HH:MM:SS 格式\n    if (splitTime.length === 3) {\n        var hours = parseInt(splitTime[0], 10);\n        var minutes = parseInt(splitTime[1], 10);\n        var seconds = parseInt(splitTime[2], 10);\n        return hours * 3600 + minutes * 60 + seconds;\n    }\n\n    // 如果是 MM:SS 格式\n    if (splitTime.length === 2) {\n        var minutes = parseInt(splitTime[0], 10);\n        var seconds = parseInt(splitTime[1], 10);\n        return minutes * 60 + seconds;\n    }\n\n    return 0; // 如果格式不正确，返回0\n}\n\nconst progress = ref(0.0) // 播放进度条\nconst nowTotalTime = ref<string>(\"00:00\") // 播放总时间\nconst nowCurrentTime = ref<string>(\"00:00\") // 播放时间\nconst playSpeed = ref(1) // 播放速度\nconst delaySpeed: any = ref(0) // 延迟设置\nconst durationSpeed: any = ref(0) // 延音设置\nconst durationRandomStart: any = ref(0.5)\nconst durationRandomEnd: any = ref(1.5)\nconst delayRandomStart: any = ref(0.01)\nconst delayRandomEnd: any = ref(0.06)\nlet clickTimeout: any = null\n\n// ---------------------------------------------------\n// 事件处理函数和工具函数\n// ---------------------------------------------------\n\n// 单击/双击选择音乐\nconst MusicSelect = (row: RowData) => {\n  return {\n    onClick: () => {\n      if (clickTimeout) {\n        clearTimeout(clickTimeout);\n        clickTimeout = null;\n        playBarClickHandler(\"start\", \"\")\n      } else {\n        nowSelectMusic.value = row.name;\n        nowSelectMusicTruth = row.truthName;\n        clickTimeout = setTimeout(() => {\n          clickTimeout = null;\n          store.commit('addPlayList', { 'name': row.name, 'truthName': row.truthName, 'type': nowType });\n        }, 300);\n      }\n    }\n  }\n};\n\n// 播放列表项点击（用于删除播放列表项）\nconst musicListSelect = (row: RowData, rowIndex: number) => {\n  console.log(row)\n  return {\n    onClick: () => {\n      store.commit(\"removePlayList\", rowIndex)\n      music.musicList = store.getters.getPlayList\n    }\n  }\n};\n\n// 刷新播放列表\nfunction reloadMusicList() {\n  active.value = !active.value;\n  music.musicList = store.getters.getPlayList\n}\n\n// 开始进度条追踪\nfunction startProgressTracking() {\n  if (progressInterval) return;\n  progressInterval = setInterval(getProgress, 1000);\n}\n\n// 停止进度条追踪\nfunction stopProgressTracking() {\n  if (progressInterval) {\n    clearInterval(progressInterval);\n    progressInterval = 0;\n  }\n}\n\n// 清空播放列表\nfunction clearPlayList() {\n  store.commit('clearPlayList')\n  music.musicList = store.getters.getPlayList\n}\n\n// 播放条点击处理函数\nconst playBarClickHandler = async (status: String, type: String) => {\n  stopProgressTracking();\n  if (status === 'resume') {\n    if (nowState.value == 'stop') {\n      message.info(t('messeage.double_click'));\n      return;\n    }\n    sendData('play_operate', { \"operate\": \"resume\" });\n    isPlay.value = true;\n    startProgressTracking();\n  }\n  else if (status === 'pause') {\n    sendData('play_operate', { \"operate\": \"pause\" });\n    isPlay.value = false;\n    stopProgressTracking();\n  }\n  else if (status === 'stop') {\n    sendData('play_operate', { \"operate\": \"stop\" });\n    await clearPlayInfo();\n  }\n  else if (status === 'start') {\n    setTimeout(() => {\n      sendData('play_operate', {\n        fileName: nowSelectMusicTruth,\n        type: type != \"\" ? type : nowType,\n        operate: \"start\"\n      }).then(() => {\n        progress.value = 0;\n        nowTotalTime.value = '00:00';\n        nowCurrentTime.value = '00:00';\n        cycleMusic = {\n          fileName: nowSelectMusicTruth,\n          type: type != \"\" ? type : nowType,\n        };\n      });\n      message.success('开始');\n      isPlay.value = true;\n      startProgressTracking();\n    });\n  }\n  else if (status === 'next') {\n    // 直接调用下一首逻辑，不依赖 progress.value = 100 触发\n    if (selectMode.value === 'order') {\n      orderMusicPlay();\n    } else if (selectMode.value === 'random') {\n      randomMusicPlay();\n    } else if (selectMode.value === 'cycle') {\n      cycleMusicPlay();\n    }\n    return;\n  }\n  nowState.value = status;\n};\n\n// 拖动进度条开始（暂停播放）\nfunction drag_progress_start() {\n  sendData('play_operate',{\"operate\":\"pause\"}).then(() => {\n    clearInterval(progressInterval)\n  })\n}\n\n// 拖动进度条结束（恢复播放）\nfunction drag_progress_end() {\n  clearInterval(progressInterval);\n  setConfig('set_progress', progress.value / 100)\n  sendData('play_operate',{\"operate\":\"resume\"}).then(() => {\n    progressInterval = setInterval(getProgress, 1000)\n  })\n}\n\n// 获取播放进度\nasync function getProgress() {\n  try {\n    // 如果当前状态为暂停或停止，则不更新进度\n    if (nowState.value === 'pause' || nowState.value === 'stop') {\n      return \"paused_or_stopped\";\n    }\n    // 当进度达到或超过 100 时，认为本曲播放完毕\n    if (progress.value >= 100) {\n      // 停止定时器，防止重复调用\n      stopProgressTracking();\n      clearPlayInfo();\n      // 根据不同播放模式，延时调度下一曲\n      if (selectMode.value === 'order') {\n        setTimeout(orderMusicPlay, 500);\n      } else if (selectMode.value === 'random') {\n        setTimeout(randomMusicPlay, 500);\n      } else if (selectMode.value === 'cycle') {\n        setTimeout(cycleMusicPlay, 500);\n      }\n    } else {\n      // 请求最新进度数据\n      const res = await getData('getProgress');\n      if (res && res.now_progress !== undefined) {\n        // 更新进度，转换为数字\n        progress.value = Number(res.now_progress);\n        nowPlayMusic.value = res.now_play_music || t('messeage.unknow_music');\n        nowTotalTime.value = res.now_total_time;\n        nowCurrentTime.value = res.now_current_time;\n      }\n    }\n  } catch (error) {\n    console.error('getProgress 出错：', error);\n  }\n  return \"ok\";\n}\n\n// 随机播放\nfunction randomMusicPlay() {\n  nowSelectMusicTruth = music.systemMusic[Math.floor(Math.random() * (music.systemMusic.length))].truthName\n  playBarClickHandler(\"start\", 'systemMusic')\n}\n\n// 顺序播放\nasync function orderMusicPlay() {\n  let struct = store.getters.getNextPlayMusic\n  if (struct != null && struct != undefined) {\n    nowSelectMusicTruth = struct.truthName\n    let type = struct.type\n    playBarClickHandler(\"start\", type)\n  } else {\n    clearInterval(progressInterval)\n    playBarClickHandler(\"stop\",\"\")\n    console.log(\"叽里呱啦\")\n    setTimeout(()=>{window.api.system_notification(\"😳\", t('messeage.order_ok'))},1000)\n    nowPlayMusic.value = t('messeage.no_music')\n  }\n}\n\n// 循环播放\nfunction cycleMusicPlay() {\n  nowSelectMusicTruth = cycleMusic?.fileName\n  playBarClickHandler(\"start\", cycleMusic?.type)\n}\n\n// 更新数据（如收藏、系统音乐、导入音乐、扒谱音乐）\nfunction handleUpdateValue(value: string) {\n  tabsNumber.value = value\n  getListData(value)\n}\n\n// 处理抽屉切换前动作\nfunction handleBeforeLeave(name: string) {\n  nowType = name\n  return true\n}\n\n// 清除播放信息（停止定时器、重置状态）\nfunction clearPlayInfo() {\n  // 先清除轮询定时器\n  stopProgressTracking();\n  nowSelectMusic.value = t('controller.no_music');\n  nowPlayMusic.value = t('messeage.no_music');\n  nowState.value = 'stop';\n  progress.value = 0;\n  nowTotalTime.value = '00:00';\n  nowCurrentTime.value = '00:00';\n  // 确保其他状态同步更新（如 statusbar，确保 statusbar 在当前上下文中有效）\n  statusbar[0] = true;\n  statusbar[1] = false;\n  isPlay.value = false;\n}\n\n// 收藏点击处理\nfunction heartClick(name, state) {\n  if (state) {\n    sendData('config_operate', {\n      fileName: name,\n      type: nowType,\n      operate: 'favorite_music'\n    }).then(() => {\n      handleUpdateValue('myFavorite')\n      handleUpdateValue(nowType)\n      message.success(t('tab.love_success'))\n    })\n  } else {\n    sendData('config_operate', {\n      fileName: name,\n      type: 'myFavorite',\n      operate: \"drop_file\"\n    }).then(() => {\n      handleUpdateValue('myFavorite')\n      message.success(t('tab.remove_success'))\n    })\n  }\n}\n\n// 删除点击处理\nfunction deleteClick(name) {\n  sendData('config_operate', {\n    fileName: name,\n    type: 'myImport',\n    operate: \"drop_file\"\n  }).then(() => {\n    handleUpdateValue('myImport')\n    message.success(t('tab.remove_success'))\n  })\n}\n\n// 文件上传完成后的处理\nfunction handleFinish({ file: _file, event: _event }) {\n  handleUpdateValue('myImport')\n  nowType = \"myImport\"\n  window.api.sync_sheet_2_el()\n}\n\n// 文件上传前处理\nfunction beforeFileUpload(file) {\n  return window.api.readFile(file.file.file.path, false).then(res => {\n    if (res) {\n      message.success(t('messeage.sheet') + file.file.file.name + t('messeage.ok_import') )\n    } else {\n      message.error(t('messeage.sheet') + file.file.file.name + t('messeage.no_import') )\n    }\n    return res;\n  })\n}\n\n// 获取列表数据\nasync function getListData(value) {\n  await getList(value, searchText.value).then((_res) => {\n    console.log('list11',_res);\n    eval('music.' + value + '=_res')\n  })\n}\n\n// ---------------------------------------------------\n// 监听器（watch）\n// ---------------------------------------------------\nconst fetchListData = debounce(() => {\n  getListData('myFavorite');\n  getListData('systemMusic');\n  getListData('myImport');\n  getListData('myTranslate');\n}, 200);\nwatch(searchText, fetchListData)\n\nlet randomInterval: any = null\nwatch(delayStatus, () => {\n  switch (delayStatus.value) {\n    case 'system':\n      delaySpeed.value = 0\n      clearInterval(randomInterval)\n      break\n    case 'random':\n      delayRandomStart.value = 0.01\n      delayRandomEnd.value = 0.06\n      randomInterval = setInterval(() => {\n        delaySpeed.value = (Math.random() * (delayRandomEnd.value - delayRandomStart.value) + delayRandomStart.value).toFixed(3)\n      }, 1000)\n      break\n    case 'custom':\n      clearInterval(randomInterval)\n      break\n  }\n})\n\nlet durationInterval: any = null\nwatch(durationStatus, () => {\n  switch (durationStatus.value) {\n    case 'system':\n      durationSpeed.value = 0\n      clearInterval(durationInterval)\n      break\n    case 'random':\n      durationRandomStart.value = 0.01\n      durationRandomEnd.value = 1.5\n      durationInterval = setInterval(() => {\n        durationSpeed.value = (Math.random() * (durationRandomEnd.value - durationRandomStart.value) + durationRandomStart.value).toFixed(3)\n      }, 1000)\n      break\n    case 'custom':\n      clearInterval(durationInterval)\n      break\n  }\n})\n\nwatch(delaySpeed, () => {\n  setConfig('delay_interval', delaySpeed.value)\n})\nwatch(durationSpeed, () => {\n  console.log('延音设置11durationSpeed',durationSpeed.value);\n  setConfig('duration', durationSpeed.value)\n})\nwatch(playSpeed, () => {\n  setConfig('play_speed', playSpeed.value)\n})\n\nconst systemMusic = ref<DataTableInst>()\nconst myImport = ref<DataTableInst>()\nconst myTranslate = ref<DataTableInst>()\nconst myFavorite  = ref<DataTableInst>()\nconst tabsNumber = ref(\"systemMusic\")\nfunction locationNowPlayMusic(){\n  searchText.value = \"\"\n  Promise.all([getListData('myFavorite'), getListData('systemMusic'), getListData('myImport'), getListData('myTranslate')]).then(function(){\n    let index = eval(\"music.\" + tabsNumber.value + \".findIndex(item => item.name === nowPlayMusic.value)\")\n    if (index === -1){\n      message.error(t('messeage.no_now') )\n      return\n    }\n    eval(`music.${tabsNumber.value}[${index}].position = true`)\n    eval(`${tabsNumber.value}.value?.scrollTo({index, behavior: 'smooth',})`)\n    setTimeout(() => {\n      eval(`music.${tabsNumber.value}[${index}].position = false`)\n    }, 5000);\n  });\n}\nfunction rowClassName(row: RowData) {\n  if (row?.position) {\n    return 'table_position'\n  }\n  return 'td_css'\n}\n\n// ---------------------------------------------------\n// WebSocket 初始化及相关处理\n// ---------------------------------------------------\nfunction initWebSocket() {\n  socket = new WebSocket('ws://127.0.0.1:11452')\n  // 添加 WebSocket 事件监听\n  socket.onopen = () => {\n    console.log('WebSocket 已连接')\n  }\n  socket.onmessage = (event) => {\n    const key = decodeURIComponent(event.data).trim() // 获取按下的按键\n    console.log(\"按下\",key)\n    if (key === shortcutKeys[\"start\"]) {\n      if (nowState.value != 'stop') {\n        window.api.system_notification(\"🍎\", t('messeage.msg1'))\n      } else {\n        console.log(\"else\")\n        if (nowSelectMusic.value === t('controller.no_music')) {\n          window.api.system_notification(\"😭\", t('messeage.msg2'))\n        } else {\n          window.api.system_notification(\"✔\", t('messeage.msg3'))\n          playBarClickHandler('start', '')\n        }\n      }\n    }\n    if (key === shortcutKeys[\"resume\"]) {\n      if (nowState.value === 'pause') {\n        window.api.system_notification(\"▶\", t('messeage.msg4'))\n        playBarClickHandler('resume', '')\n      } else {\n        window.api.system_notification(\"🍎\", t('messeage.msg5'))\n      }\n    }\n    if (key === shortcutKeys[\"pause\"]) {\n      if (isPlay.value) {\n        window.api.system_notification(\"⏸\", t('messeage.msg6'))\n        playBarClickHandler('pause', '')\n      } else {\n        window.api.system_notification(\"🍎\", t('messeage.msg7'))\n      }\n    }\n    if (key === shortcutKeys[\"stop\"]) {\n      window.api.system_notification(\"🛑\", t('messeage.msg8'))\n      playBarClickHandler('stop', '')\n    }\n    if (key === shortcutKeys[\"next\"]) {\n      window.api.system_notification(\"⏩\", t('messeage.msg9'))\n      playBarClickHandler('next', '')\n    }\n    if (key === shortcutKeys[\"add_duration\"]) {\n  if (durationSpeed.value * 100 === 200) {\n    message.info(t('messeage.msg10'));\n  } else {\n    durationStatus.value = \"custom\";\n    setTimeout(()=>{\n      durationSpeed.value = Math.round((durationSpeed.value + 0.01) * 100) / 100;\n    })\n    message.info(t('messeage.msg11'));\n  }\n}\nif (key === shortcutKeys[\"reduce_duration\"]) {\n  if (durationSpeed.value * 100 === 0) {\n    message.info(t('messeage.msg12'));\n  } else {\n    setTimeout(()=>{\n      durationStatus.value = \"custom\";\n      durationSpeed.value = Math.round((durationSpeed.value - 0.01) * 100) / 100;\n    })\n    message.info(t('messeage.msg13'));\n  }\n}\nif (key === shortcutKeys[\"add_delay\"]) {\n  if (delaySpeed.value * 100 === 200) {\n    message.info(t('messeage.msg14'));\n  } else {\n    delayStatus.value = \"custom\";\n    setTimeout(()=>{\n      delaySpeed.value = Math.round((delaySpeed.value + 0.01) * 100) / 100;\n    })\n    message.info(t('messeage.msg15'));\n  }\n}\nif (key === shortcutKeys[\"reduce_delay\"]) {\n  if (delaySpeed.value * 100 === 0) {\n    message.info(t('messeage.msg16'));\n  } else {\n    delayStatus.value = \"custom\";\n    setTimeout(()=>{\n      delaySpeed.value = Math.round((delaySpeed.value - 0.01) * 100) / 100;\n    })\n    message.info(t('messeage.msg17'));\n  }\n}\nif (key === shortcutKeys[\"add_speed\"]) {\n  if (playSpeed.value * 10 === 50) {\n    message.info(t('messeage.msg18'));\n  } else {\n    message.info(t('messeage.msg19'));\n    playSpeed.value = Math.round((playSpeed.value + 0.1) * 10) / 10;\n  }\n}\nif (key === shortcutKeys[\"reduce_speed\"]) {\n  if (playSpeed.value * 10 === 1) {\n    message.info(t('messeage.msg20'));\n  } else {\n    playSpeed.value = Math.round((playSpeed.value - 0.1) * 10) / 10;\n    message.info(t('messeage.msg21'));\n  }\n}\n  }\n  socket.onclose = () => {\n    console.log('WebSocket 已断开')\n  }\n  socket.onerror = (error) => {\n    console.error('WebSocket 出现错误', error)\n  }\n}\n\nsendData(\"config_operate\",{\n    \"operate\": \"get\",\n    \"name\": \"shortcutStruct\"\n}).then(res=>{\n  shortcutKeys = res[\"music_key\"]\n  console.log(shortcutKeys)\n})\ninitWebSocket()\n\nonMounted(async ()=>{\n  await handleUpdateValue('myFavorite')\n  await handleUpdateValue('systemMusic')\n  durationStatus.value = 'custom'\n  durationSpeed.value = 0.03\n  setConfig('duration', 0.03)\n})\n\n// ---------------------------------------------------\n// 组件销毁时的清理工作\n// ---------------------------------------------------\nonUnmounted(async () => {\n  if (socket) {\n    socket.close()\n    socket = null\n  }\n  playBarClickHandler(\"stop\", \"\")\n  setConfig('delay_interval', 0)\n  setConfig('duration', 0.03)\n  setConfig('play_speed', 1)\n  clearPlayInfo()\n})\n</script>\n\n<style scoped>\n:deep(.n-slider-rail__fill){\n  --n-fill-color-hover: rgb(242,232,196) !important;\n  background-color: rgb(242,232,196) !important;\n}\n:deep(.n-radio){\n  --n-box-shadow-active: inset 0 0 0 1px rgb(242,232,196)!important;\n  --n-box-shadow-focus: inset 0 0 0 1px rgb(242,232,196), 0 0 0 2px rgba(242,232,196, 0.3)!important;\n  --n-box-shadow-hover: inset 0 0 0 1px rgb(242,232,196)!important;\n  --n-dot-color-active: rgb(242,232,196)!important;\n}\n:deep(.n-input){\n  --n-border-hover: 1px solid rgb(242,232,196)!important;\n  --n-border-focus: 1px solid rgb(242,232,196)!important;\n  --n-caret-color: rgb(242,232,196)!important;\n  --n-color-focus: rgba(242,232,196,0.1)!important;\n}\n:deep(.n-tabs-bar){\n  --n-bar-color: rgb(242,232,196)!important;\n}\n:deep(.n-tabs){\n    --n-tab-text-color-active: rgb(242,232,196)!important;\n    --n-tab-text-color-hover: rgb(242,232,196)!important;\n    --n-tab-text-color: rgb(221,242,196)!important;\n}\n:deep(.n-switch--active){\n  --n-rail-color-active: #F2C9C4 !important;\n}\n.n-input{\n  background-color: rgba(24, 24, 28, 0) !important;\n  border: 1px solid rgba(242,232,196,0.5);\n  --n-text-color: rgb(242,232,196) !important;\n}\n:deep(.td_css td) {\n  color: rgb(242,232,196) !important;\n}\n:deep(.th_css){\n  color: rgb(221,242,196) !important;\n}\n\n:deep(.table_position td) {\n  background-color: rgba(242, 201, 196, 0.507) !important;\n}\n\n.actionButton{\n  margin-left: 20px;\n}\n</style>\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/music_edit.vue",
    "content": "<template>\n  <!-- 状态显示区域 -->\n  <n-flex>\n    <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\" style=\"margin-top: 5px;\">\n      {{ t(\"music_edit.total_column\", {length: notes.length}) }}\n    </n-gradient-text>\n    <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\" style=\"margin-top: 5px;\">\n      {{ t(\"music_edit.total_time\", {length: `${Math.floor(timeNotes.reduce((acc, currentValue) => acc + currentValue, 0) / 60000)}分 ${Math.floor((timeNotes.reduce((acc, currentValue) => acc + currentValue, 0) % 60000) / 1000)}秒`}) }}\n    </n-gradient-text>\n  </n-flex>\n  <div class=\"midi-editor\">\n    <n-layout>\n      <n-layout-content class=\"midi-content\">\n        <canvas ref=\"midiCanvas\" class=\"midi-canvas\"></canvas>\n      </n-layout-content>\n    </n-layout>\n  </div>\n  <!-- 播放控制 -->\n  <n-flex justify=\"center\" style=\"margin-top:0px\">\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"isPlaying ? pause() : play()\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <Pause24Filled v-if=\"isPlaying\" />\n            <Play24Filled v-else />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\" v-if=\"isPlaying\">{{ t(\"music_edit.tips.pause\") }}</span>\n      <span style=\"color:#F2C9C4\" v-else>{{ t(\"music_edit.tips.play\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"previousColumn\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <ArrowPrevious24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.pre_column\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"nextColumn\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <ArrowNext24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.next_column\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"insertEmptyColumn\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <TableAdd24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.afer_add_column\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"deleteCurrentColumn\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <TableDeleteColumn24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.delete_now_column\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"isPlaying ? pause() : reverse()\" quaternary circle\n          style=\"font-size: 24px; transform: rotate(180deg);\" color=\"#F2C9C4\">\n          <n-icon>\n            <Pause24Filled v-if=\"isPlaying\" />\n            <Play24Filled v-else />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\" v-if=\"isPlaying\">{{ t(\"music_edit.tips.pause\") }}</span>\n      <span style=\"color:#F2C9C4\" v-else>{{ t(\"music_edit.tips.upend\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"playNowColumn\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <MusicNote120Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.play_now_column\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"copyNowColumnToStart\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <PaddingLeft24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.copy_now_to_head\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"copyNowColumnToPre\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <TableStackRight24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.copy_now_to_pre\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"copyNowColumnToNext\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <TableStackLeft24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.copy_now_to_next\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"copyNowColumnToEnd\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <PaddingRight24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.copy_now_to_end\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"musicActive = true\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <AppsListDetail24Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.select_in_music\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"saveSheet\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <Save20Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.save_sheet\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-button @click=\"clearSheet\" quaternary circle style=\"font-size: 24px\" color=\"#F2C9C4\">\n          <n-icon>\n            <DeleteDismiss20Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.clear_sheet\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"hover\" :disabled=\"!showTips\">\n      <template #trigger>\n        <n-upload ref=\"upload\" action=\"#\" :default-upload=\"false\" accept=\".txt\" @change=\"handleUploadSheet\"\n          style=\"flex-basis: 1%;\" :show-file-list=\"false\">\n          <n-button quaternary circle style=\"font-size: 22px\" color=\"#F2C9C4\">\n            <n-icon>\n              <ArrowUpload24Filled />\n            </n-icon>\n          </n-button>\n        </n-upload>\n      </template>\n      <span style=\"color:#F2C9C4\">{{ t(\"music_edit.tips.upload_sheet\") }}</span>\n    </n-tooltip>\n    <n-tooltip trigger=\"click\">\n      <template #trigger>\n        <n-button quaternary circle style=\"font-size: 23px\" color=\"#F2C9C4\">\n          <n-icon>\n            <Settings28Filled />\n          </n-icon>\n        </n-button>\n      </template>\n      <n-flex style=\"width: 200px;\">\n        <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\"\n          style=\"margin-top: 5px; flex-basis: 12%;\">\n          {{ t(\"music_edit.title.change_send_key_in_game\") }}\n        </n-gradient-text>\n        <n-switch v-model:value=\"sendToGame\" size=\"medium\" :round=\"false\" style=\"margin-top: 5px;\"\n          :rail-style=\"railStyle\" />\n        <div style=\"flex-basis: 100%;\" />\n        <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\"\n          style=\"margin-top: 5px; flex-basis: 62.5%;\">\n          {{ t(\"music_edit.title.func_area_tip\") }}\n        </n-gradient-text>\n        <n-switch v-model:value=\"showTips\" size=\"medium\" :round=\"false\" style=\"margin-top: 5px;\"\n          :rail-style=\"railStyle\" />\n        <div style=\"flex-basis: 100%;\" />\n        <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\"\n          style=\"margin-top: 5px; flex-basis: 62.5%;\">\n          {{ t(\"music_edit.title.sheet_area_color\") }}\n        </n-gradient-text>\n        <n-switch v-model:value=\"showRowSpaceColor\" size=\"medium\" :round=\"false\" style=\"margin-top: 5px;\"\n          :rail-style=\"railStyle\" />\n      </n-flex>\n    </n-tooltip>\n  </n-flex>\n  <n-slider v-model:value=\"progress\" :step=\"1\" @update:value=\"updateProgress\" :min=\"1\" :max=\"notes.length\"\n    style=\"margin-bottom: 8px;\" />\n  <n-flex v-for=\"(row, index) in keys\" :key=\"index\" justify=\"center\">\n    <div v-for=\"(item, idx) in row\" :key=\"idx\" style=\"margin-top: 8px;\">\n      <n-button v-if=\"item.type === 'dmcr'\" color=\"#F2E8C4\" style=\"height:75px; width: 75px;\" :dashed=\"!item.active\" @click=\"handleButtonClick(item, index, idx)\">\n        <template #icon>\n          <n-icon :size=\"65\" :component=\"dmcr\" />\n        </template>\n      </n-button>\n      <n-button v-else color=\"#F2C9C4\" style=\"height:75px; width: 75px;\" :dashed=\"!item.active\" @click=\"handleButtonClick(item, index, idx)\">\n        <template #icon>\n          <n-icon v-if=\"item.type === 'cr'\" :size=\"65\" :component=\"cr\" />\n          <n-icon v-if=\"item.type === 'dm'\" :size=\"65\" :component=\"dm\" />\n        </template>\n      </n-button>\n    </div>\n    <div style=\"flex-basis: 100%;\" />\n  </n-flex>\n  <div style=\"margin-left: 950px; margin-top: -260px; width: 415px; height: 200px;\">\n    <n-flex>\n      <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\" style=\"margin-top: 5px;\">\n        {{ t(\"music_edit.title.columnDownDuration\") }}\n      </n-gradient-text>\n      <n-input-number v-model:value=\"columnDownDuration\" style=\"flex-basis: 51.3%;\" :step=\"10\" :min=\"0\" />\n      <div style=\"flex-basis: 100%;\" />\n      <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\" style=\"margin-top: 5px;\">\n        {{ t(\"music_edit.title.columnAfterDuration\") }}\n      </n-gradient-text>\n      <n-input-number v-model:value=\"columnAfterDuration\" style=\"flex-basis: 51.3%;\" :step=\"10\" :min=\"0\" />\n      <div style=\"flex-basis: 100%;\" />\n      <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\" style=\"margin-top: 5px;\">\n        {{ t(\"music_edit.title.sheet_name\") }}\n      </n-gradient-text>\n      <n-input v-model:value=\"fileName\" type=\"textarea\" :placeholder=\"t('music_edit.title.sheet_name_placeholder')\" style=\"flex-basis: 58%;\"\n        :autosize=\"{ minRows: 1, maxRows: 7 }\" />\n    </n-flex>\n  </div>\n  <div style=\"margin-left: 1px; margin-top: -200px; width: 415px; height: 200px;\">\n    <n-flex>\n      <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\"\n        style=\"margin-top: 5px; flex-basis: 42%;\">\n        {{ t(\"music_edit.title.add_new_count_column\") }}\n      </n-gradient-text>\n      <n-input-number v-model:value=\"defaultAddColumnCount\" style=\"flex-basis: 40%;\" :step=\"1\" :min=\"1\" />\n      <div style=\"flex-basis: 100%;\" />\n      <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\"\n        style=\"margin-top: 5px; flex-basis: 42%;\">\n        {{ t(\"music_edit.title.add_new_druation_column\") }}\n      </n-gradient-text>\n      <n-input-number v-model:value=\"defaultDownDuration\" style=\"flex-basis: 40%;\" :step=\"10\" :min=\"0\" />\n      <div style=\"flex-basis: 100%;\" />\n      <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\"\n        style=\"margin-top: 5px; flex-basis: 42%;\">\n        {{ t(\"music_edit.title.add_new_after_column\") }}\n      </n-gradient-text>\n      <n-input-number v-model:value=\"defaultAfterDuration\" style=\"flex-basis: 40%;\" :step=\"10\" :min=\"0\" />\n      <div style=\"flex-basis: 100%;\" />\n      <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\"\n        style=\"margin-top: 5px; flex-basis: 25%;\">\n        {{ t(\"music_edit.title.global_down\") }}\n      </n-gradient-text>\n      <n-input-number v-model:value=\"globalDemoDownDuration\" style=\"flex-basis: 40%;\" :step=\"10\" :min=\"0\" />\n      <n-button type=\"primary\" ghost color=\"#F2E8C4\" @click=\"setGlobalDemoDownDuration\">\n        {{ t(\"music_edit.title.set\") }}\n      </n-button>\n      <div style=\"flex-basis: 100%;\" />\n      <n-gradient-text gradient=\"linear-gradient(90deg, rgb(242,201,196), rgb(221,242,196))\"\n        style=\"margin-top: 5px; flex-basis: 25%;\">\n        {{ t(\"music_edit.title.global_after\") }}\n      </n-gradient-text>\n      <n-input-number v-model:value=\"globalDemoAfterDuration\" style=\"flex-basis: 40%;\" :step=\"10\" :min=\"0\" />\n      <n-button type=\"primary\" ghost  color=\"#F2E8C4\" @click=\"setGloablAfterDuration\">\n        {{ t(\"music_edit.title.set\") }}\n      </n-button>\n    </n-flex>\n  </div>\n  <n-drawer v-model:show=\"musicActive\" :width=\"1000\" placement=\"left\" :trap-focus=\"false\" :block-scroll=\"false\">\n    <n-drawer-content>\n      <n-card style=\"margin-left: -16px; width: 965px;\" :bordered=\"false\">\n        <n-tabs type=\"bar\" animated size=\"small\" @update:value=\"handleUpdateValue\" @before-leave=\"handleBeforeLeave\"\n          :value=\"tabsNumber\">\n          <n-tab-pane name=\"systemMusic\" :tab=\"t('tab.systemMusic')\">\n            <n-data-table :columns=\"tableColumns\" :data=\"music.systemMusic\" :bordered=\"false\" :min-row-height=\"48\"\n              ref=\"systemMusic\" :max-height=\"600\" :virtual-scroll=\"music.systemMusic?.length > 7\"\n              :row-class-name=\"rowClassName\" style=\"\n              --n-td-color: rgba(57, 57, 62, 0);\n              --n-th-color-hover: rgba(57, 57, 62, 0);\n              --n-th-color: rgba(57, 57, 62, 0);\n              --n-td-color-hover: rgba(0, 0, 0, 0.2);\n            \" />\n          </n-tab-pane>\n          <n-tab-pane name=\"myImport\" :tab=\"t('tab.myImport')\" ref=\"myImport\">\n            <n-data-table :columns=\"tableColumns\" :data=\"music.myImport\" :bordered=\"false\" :min-row-height=\"48\"\n              ref=\"myImport\" :max-height=\"600\" :virtual-scroll=\"music.myImport?.length > 7\"\n              :row-class-name=\"rowClassName\" style=\"\n              --n-td-color: rgba(57, 57, 62, 0);\n              --n-th-color-hover: rgba(57, 57, 62, 0);\n              --n-th-color: rgba(57, 57, 62, 0);\n              --n-td-color-hover: rgba(0, 0, 0, 0.2);\n            \" />\n          </n-tab-pane>\n          <n-tab-pane name=\"myTranslate\" :tab=\"t('tab.myTranslate')\" ref=\"myTranslate\">\n            <n-data-table :columns=\"tableColumns\" :data=\"music.myTranslate\" :bordered=\"false\" :min-row-height=\"48\"\n              ref=\"myTranslate\" :max-height=\"600\" :virtual-scroll=\"music.myTranslate?.length > 7\"\n              :row-class-name=\"rowClassName\" style=\"\n              --n-td-color: rgba(57, 57, 62, 0);\n              --n-th-color-hover: rgba(57, 57, 62, 0);\n              --n-th-color: rgba(57, 57, 62, 0);\n              --n-td-color-hover: rgba(0, 0, 0, 0.2);\n            \" />\n          </n-tab-pane>\n          <n-tab-pane name=\"myFavorite\" :tab=\"t('tab.myFavorite')\" ref=\"myFavorite\">\n            <n-data-table :columns=\"tableColumns\" :data=\"music.myFavorite\" :bordered=\"false\" :min-row-height=\"48\"\n              ref=\"myFavorite\" :max-height=\"600\" :virtual-scroll=\"music.myFavorite?.length > 7\"\n              :row-class-name=\"rowClassName\" style=\"\n              --n-td-color: rgba(57, 57, 62, 0);\n              --n-th-color-hover: rgba(57, 57, 62, 0);\n              --n-th-color: rgba(57, 57, 62, 0);\n              --n-td-color-hover: rgba(0, 0, 0, 0.2);\n            \" />\n          </n-tab-pane>\n          <template #suffix>\n            <n-input v-model:value=\"searchText\" round :placeholder=\"t('tab.search')\" style=\"top:-3px;width: 25vh; margin-left: 5px\">\n              <template #suffix>\n                <n-icon :component=\"Search\" />\n              </template>\n            </n-input>\n          </template>\n        </n-tabs>\n      </n-card>\n    </n-drawer-content>\n  </n-drawer>\n</template>\n\n<script lang=\"ts\" setup>\n// 导入Vue核心功能\nimport { ref, onMounted, onUnmounted, watch, reactive, h, CSSProperties } from \"vue\";\nimport { onBeforeRouteLeave } from \"vue-router\";\n\n// 导入UI组件和图标\nimport { NButton, UploadFileInfo, useDialog, useMessage } from \"naive-ui\";\nimport {\n  ArrowPrevious24Filled,\n  Pause24Filled,\n  Play24Filled,\n  ArrowNext24Filled,\n  TableDeleteColumn24Filled,\n  TableAdd24Filled,\n  MusicNote120Filled,\n  Save20Filled,\n  ArrowUpload24Filled,\n  AppsListDetail24Filled,\n  PaddingRight24Filled,\n  PaddingLeft24Filled,\n  TableStackLeft24Filled,\n  TableStackRight24Filled,\n  DeleteDismiss20Filled,\n  Settings28Filled\n} from '@vicons/fluent'\nimport { Search } from '@vicons/ionicons5'\n\n// 导入自定义组件\nimport cr from \"../component/svg/cr.vue\"\nimport dm from \"../component/svg/dm.vue\"\nimport dmcr from \"../component/svg/dmcr.vue\"\n\n// 导入工具函数\nimport { getList, sendData } from \"@renderer/utils/fetchUtils\";\nimport { debounce } from \"lodash-es\";\nimport { RowData } from \"naive-ui/es/data-table/src/interface\";\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\n// 状态管理\nconst midiCanvas = ref(null);\nconst isPlaying = ref(false);\nconst musicActive = ref(false);\nconst fileName = ref(\"\");\nconst searchText = ref('');\nconst sendToGame = ref(true)\nconst showTips = ref(true)\n\n// 时间相关配置\nconst columnAfterDuration = ref(0);\nconst columnDownDuration = ref(0);\nconst defaultAfterDuration = ref(0);\nconst defaultDownDuration = ref(0);\nconst defaultAddColumnCount = ref(1);\nconst globalDemoDownDuration = ref(0);\nconst globalDemoAfterDuration = ref(0);\n\nconst setGlobalDemoDownDuration = () =>{\n  durationNotes.value.fill(globalDemoDownDuration.value)\n  drawCanvas()\n}\n\nconst setGloablAfterDuration = () =>{\n  timeNotes.value.fill(globalDemoAfterDuration.value)\n  drawCanvas()\n}\n// 界面交互状态\nconst nowButton = ref(-1);\nconst progress = ref(1);\nconst currentColumn = ref(0);\nfunction railStyle({ focused, checked }) {\n  const style: CSSProperties = {}\n  if (checked) {\n    style.background = '#F2C9C4'\n    if (focused) {\n      style.boxShadow = '0 0 0 2px #F2C9C440'\n    }\n  }\n  else {\n    if (focused) {\n      style.boxShadow = '0 0 0 2px #F2E8C440'\n    }\n  }\n  return style\n}\n\n\n// 表格配置\nconst tableColumns = [\n  {\n    title: t('columns.name'),\n    key: 'name',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: { tooltip: true }\n  },\n  {\n    title: t('columns.total_duration'),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n  {\n    title: t('columns.operation'),\n    key: 'operation',\n    width: 60,\n    className: 'th_css',\n    render(row) {\n      return h(NButton, {\n        size: 'medium',\n        text: true,\n        onClick: () => {\n          pause();\n          sendData(\"path\", { \"type\": nowType }).then(res => {\n            loadFile(`${res}\\\\${row.truthName}.txt`).then(() => {\n              musicActive.value = false;\n            })\n          })\n        }\n      }, {\n        default: () => '👈'\n      })\n    }\n  }\n];\nfunction timeToSeconds(timeString) {\n    var splitTime = timeString.split(':');\n\n    // 如果是 HH:MM:SS 格式\n    if (splitTime.length === 3) {\n        var hours = parseInt(splitTime[0], 10);\n        var minutes = parseInt(splitTime[1], 10);\n        var seconds = parseInt(splitTime[2], 10);\n        return hours * 3600 + minutes * 60 + seconds;\n    }\n\n    // 如果是 MM:SS 格式\n    if (splitTime.length === 2) {\n        var minutes = parseInt(splitTime[0], 10);\n        var seconds = parseInt(splitTime[1], 10);\n        return minutes * 60 + seconds;\n    }\n\n    return 0; // 如果格式不正确，返回0\n}\n\nlet nowType = 'systemMusic'\nconst fetchListData = debounce(() => {\n  getListData('myFavorite');\n  getListData('systemMusic');\n  getListData('myImport');\n  getListData('myTranslate');\n}, 200);\nwatch(searchText, fetchListData)\nfunction rowClassName(row: RowData) {\n  if (row?.position) {\n    return 'table_position'\n  }\n  return 'td_css'\n}\n// 处理抽屉切换前动作\nfunction handleBeforeLeave(name: string) {\n  nowType = name\n  return true\n}\nconst tabsNumber = ref(\"systemMusic\")\nfunction handleUpdateValue(value: string) {\n  tabsNumber.value = value\n  getListData(value)\n}\nasync function getListData(value) {\n  await getList(value, searchText.value).then((_res) => {\n    eval('music.' + value + '=_res')\n  })\n}\n// 音乐数据管理\nconst music: any = reactive({\n  systemMusic: [],\n  myImport: [],\n  myTranslate: [],\n  myFavorite: [],\n  musicList: []\n});\n\n// 键盘布局配置\nconst keys = ref([\n  [\n    { key: \"0\", type: \"dmcr\", duration: 0, active: false },\n    { key: \"1\", type: \"dm\", duration: 0, active: false },\n    { key: \"2\", type: \"cr\", duration: 0, active: false },\n    { key: \"3\", type: \"dm\", duration: 0, active: false },\n    { key: \"4\", type: \"cr\", duration: 0, active: false },\n  ],\n  [\n    { key: \"5\", type: \"cr\", duration: 0, active: false },\n    { key: \"6\", type: \"dm\", duration: 0, active: false },\n    { key: \"7\", type: \"dmcr\", duration: 0, active: false },\n    { key: \"8\", type: \"dm\", duration: 0, active: false },\n    { key: \"9\", type: \"cr\", duration: 0, active: false },\n  ],\n  [\n    { key: \"10\", type: \"cr\", duration: 0, active: false },\n    { key: \"11\", type: \"dm\", duration: 0, active: false },\n    { key: \"12\", type: \"cr\", duration: 0, active: false },\n    { key: \"13\", type: \"dm\", duration: 0, active: false },\n    { key: \"14\", type: \"dmcr\", duration: 0, active: false },\n  ]\n]);\n\n// 乐谱数据\nconst durationNotes = ref<number[]>([0]); // 长按表\nconst notes = ref<number[][]>([[]]); // 谱表\nconst timeNotes = ref<number[]>([10]); // 延迟表\n// Canvas配置\nconst canvasWidth = 1217;\nconst canvasHeight = 330;\nconst gridSize = 8; // 每个小块大小\nconst columnSize = gridSize * 4; // 3个小块组成1大块\nconst cornerRadius = 5; // 圆角半径\nconst showRowSpaceColor = ref(false);\n\n// 全局状态\nconst intervalId: any = ref(null);\nconst message = useMessage();\nconst dialog = useDialog();\n\n// Canvas绘制函数\nconst drawCanvas = () => {\n  const canvas: any = midiCanvas.value;\n  if (!canvas) return;\n\n  const ctx = canvas.getContext(\"2d\");\n  const viewportCenter = canvasWidth / 2;\n  const currentX = currentColumn.value * columnSize;\n  let offsetX = 0;\n\n  // 计算视口偏移\n  if (currentX > viewportCenter) {\n    offsetX = viewportCenter - currentX;\n  }\n\n  // 计算视口范围内的列\n  const visibleStartX = -offsetX;\n  const visibleEndX = canvasWidth - offsetX;\n  const startColumn = Math.max(0, Math.floor(visibleStartX / columnSize));\n  const endColumn = Math.min(notes.value.length, Math.ceil(visibleEndX / columnSize));\n\n  ctx.clearRect(0, 0, canvasWidth, canvasHeight);\n  ctx.save();\n  ctx.translate(offsetX, 0);\n\n  if(showRowSpaceColor.value){\n    // 绘制交替背景色\n    const startColumnGroup = Math.floor(startColumn / 5);\n    const endColumnGroup = Math.ceil(endColumn / 5);\n    \n    for (let group = startColumnGroup; group <= endColumnGroup; group++) {\n      const groupStartX = group * 5 * columnSize;\n      const groupEndX = Math.min((group + 1) * 5 * columnSize, endColumn * columnSize);\n\n      ctx.fillStyle = group % 2 === 0 ? \"rgba(242, 232, 196, 0)\" : \"rgba(255,250,205, 0.25)\";\n      ctx.fillRect(groupStartX, 0, groupEndX - groupStartX, canvasHeight);\n    }\n  }\n \n  // 绘制网格（仅在可见区域内）\n  ctx.strokeStyle = \"rgba(85, 85, 85, 0)\";\n  const startGridX = Math.floor(visibleStartX / gridSize) * gridSize;\n  const endGridX = Math.ceil(visibleEndX / gridSize) * gridSize;\n\n  for (let x = startGridX; x <= endGridX; x += gridSize) {\n    ctx.beginPath();\n    ctx.moveTo(x, 0);\n    ctx.lineTo(x, canvasHeight);\n    ctx.stroke();\n  }\n  for (let y = 0; y < canvasHeight; y += gridSize) {\n    ctx.beginPath();\n    ctx.moveTo(startGridX, y);\n    ctx.lineTo(endGridX, y);\n    ctx.stroke();\n  }\n\n  // 绘制列线\n  ctx.strokeStyle = \"rgba(136, 136, 136, 0.7)\";\n  ctx.lineWidth = 2;\n  for (let x = startColumn * columnSize; x <= endColumn * columnSize; x += columnSize) {\n    ctx.beginPath();\n    ctx.moveTo(x, 0);\n    ctx.lineTo(x, canvasHeight);\n    ctx.stroke();\n  }\n\n  // 绘制水平参考线\n  const fifthGridY = (5 * canvasHeight) / 15 - 1;\n  const tenthGridY = (10 * canvasHeight) / 15 - 1;\n  ctx.beginPath();\n  ctx.moveTo(startGridX, fifthGridY);\n  ctx.lineTo(endGridX, fifthGridY);\n  ctx.moveTo(startGridX, tenthGridY);\n  ctx.lineTo(endGridX, tenthGridY);\n  ctx.stroke();\n\n  ctx.lineWidth = 1;\n  ctx.fillStyle = \"#F2C9C4\";\n  // 只绘制视野内的音符\n  for (let columnIndex = startColumn; columnIndex < endColumn; columnIndex++) {\n    const column = notes.value[columnIndex];\n    if (!column) continue;\n\n    column.forEach(row => {\n      const y = (row - 1) * (canvasHeight / 15);\n      const x = columnIndex * columnSize + 1;\n      const rectWidth = columnSize - 2;\n      const rectHeight = canvasHeight / 15 - 2;\n\n      ctx.beginPath();\n      ctx.moveTo(x + cornerRadius, y);\n      ctx.lineTo(x + rectWidth - cornerRadius, y);\n      ctx.quadraticCurveTo(x + rectWidth, y, x + rectWidth, y + cornerRadius);\n      ctx.lineTo(x + rectWidth, y + rectHeight - cornerRadius);\n      ctx.quadraticCurveTo(x + rectWidth, y + rectHeight, x + rectWidth - cornerRadius, y + rectHeight);\n      ctx.lineTo(x + cornerRadius, y + rectHeight);\n      ctx.quadraticCurveTo(x, y + rectHeight, x, y + rectHeight - cornerRadius);\n      ctx.lineTo(x, y + cornerRadius);\n      ctx.quadraticCurveTo(x, y, x + cornerRadius, y);\n      \n      // 根据行号设置不同的填充颜色\n      if (row === 1 || row === 8 || row === 15) {\n        ctx.fillStyle = \"#F2E8C4\";\n      } else {\n        ctx.fillStyle = \"#F2C9C4\";\n      }\n      \n      ctx.fill();\n\n      ctx.fillStyle = \"#000000\";\n      ctx.font = \"12px Arial\";\n      ctx.textAlign = \"center\";\n      ctx.textBaseline = \"middle\";\n\n      let textToDisplay = \"\";\n      if (durationNotes.value.length === 1) {\n        textToDisplay = String(durationNotes.value[0]);\n      } else if (columnIndex < durationNotes.value.length) {\n        textToDisplay = String(durationNotes.value[columnIndex]);\n      }\n\n      ctx.fillText(textToDisplay, x + rectWidth / 2, y + rectHeight / 2);\n      ctx.fillStyle = \"#F2C9C4\";\n    });\n  }\n\n  ctx.restore();\n\n  // 高亮当前列\n  ctx.fillStyle = \"rgba(255, 255, 255, 0.35)\";\n  const highlightX = currentX > viewportCenter ? viewportCenter : currentX;\n  ctx.fillRect(highlightX, 0, columnSize, canvasHeight);\n};\n\nconst previousColumn = () => {\n  if (currentColumn.value > 0) {\n    currentColumn.value--;\n    progress.value = currentColumn.value + 1;\n    drawCanvas();\n    playNowColumn();\n  }\n};\nconst nextColumn = () => {\n  if (currentColumn.value < notes.value.length - 1) {\n    currentColumn.value++;\n    progress.value = currentColumn.value + 1;\n    drawCanvas();\n    playNowColumn();\n  }\n};\nconst playNowColumn = () => {\n  const progressIndex = progress.value - 1;\n  const currentNotes = notes.value[progressIndex];\n  const noteCount = currentNotes.length;\n  const time = timeNotes.value[progressIndex];\n  const songNote = currentNotes.map(element => ({\n    time: Number(time),\n    key: `${noteCount}Key${element - 1}`,\n    duration: Number(durationNotes.value[progressIndex]) || 0\n  }));\n  if (sendToGame.value) {\n    sendData(\"play_operate\", {\n      operate: 'start',\n      sheet: songNote\n    })\n  }\n  return Number(time)\n};\nconst saveSheet = () => {\n  const templateMusicFormat = [\n    {\n      \"name\": fileName.value,\n      \"author\": \"edit by SkyMusic\",\n      \"transcribedBy\": \"WindHide's Music SoftWare\",\n      \"bpm\": 0,\n      \"bitsPerPage\": 15,\n      \"pitchLevel\": 0,\n      \"isComposed\": true,\n      \"songNotes\": getSheetToMemory(0),\n      \"isEncrypted\": false,\n    }\n  ]\n  saveFile(fileName.value, JSON.stringify(templateMusicFormat))\n}\n\n//  清空工作选区的谱子\nconst clearSheet = () =>{\n    dialog.warning({\n      title: t('music_edit.dialog.title'),\n      content: t('music_edit.dialog.content'),\n      positiveText: t('music_edit.dialog.positiveText'),\n      negativeText: t('music_edit.dialog.negativeText'),\n      maskClosable: false,\n      showIcon: false,\n      positiveButtonProps: {\n        color: '#F2C9C4'\n      },\n      negativeButtonProps:{\n        color: '#F2E8C4'\n      },\n      onPositiveClick: () => {\n        notes.value = [];\n        durationNotes.value = [];\n        timeNotes.value = [];\n        currentColumn.value = 0;\n        progress.value = 1;\n        syncCanvasToKeysArea();\n        drawCanvas();\n      }\n    })\n}\n\nconst saveFile = (filename, content) => {\n  const blob = new Blob([content], { type: \"text/plain\" });\n  const a = document.createElement(\"a\");\n  a.href = URL.createObjectURL(blob);\n  a.download = filename;\n  document.body.appendChild(a);\n  a.click();\n  document.body.removeChild(a);\n  URL.revokeObjectURL(a.href);\n}\nasync function handleUploadSheet(options: { file: any; fileList: UploadFileInfo[] }) {\n  loadFile(options.file.file.path)\n}\n\nasync function loadFile(filePath) {\n  try {\n    const res = await window.api.readFile(filePath, true);\n    if (!res || !Array.isArray(res) || res.length === 0) {\n      throw new Error(t('music_edit.sheet.error.sheet_data'),);\n    }\n    const { name = '未知文件', songNotes = [] } = res[0];\n    fileName.value = name;\n    if (!Array.isArray(songNotes)) {\n      throw new Error(t('music_edit.sheet.error.data'),);\n    }\n    pause()\n    notes.value = [];\n    durationNotes.value = [];\n    timeNotes.value = [];\n    const timeGroupedNotes = new Map();\n    songNotes.forEach(note => {\n      if (!timeGroupedNotes.has(note.time)) {\n        timeGroupedNotes.set(note.time, {\n          time: note.time,\n          keys: [],\n          duration: note.duration || 0\n        });\n      }\n      timeGroupedNotes.get(note.time).keys.push(note.key);\n    });\n    const sortedNotes = Array.from(timeGroupedNotes.values())\n      .sort((a, b) => a.time - b.time);\n    sortedNotes.forEach((item, index) => {\n      const keyNumbers = item.keys.map(key => {\n        const match = key.match(/(Key-?\\d+)/);\n        return match ? Number(match[0].replace('Key', '')) + 1 : 0;\n      }).filter(num => num !== 0);\n      notes.value.push(keyNumbers);\n      durationNotes.value.push(Number(item.duration) || 0);\n      timeNotes.value.push(\n        index < sortedNotes.length - 1 ?\n          Math.max(Number(sortedNotes[index + 1].time - item.time) || 0, 10) :\n          10\n      );\n    });\n    syncCanvasToKeysArea();\n    drawCanvas();\n    currentColumn.value = 0;\n    progress.value = 1;\n    isFirst = true\n    message.success(t('music_edit.sheet.load_success'));\n  } catch (error) {\n    message.error(t('music_edit.sheet.load_fail') + \"=>\" + error);\n  }\n}\n\nfunction sleep(ms) {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nlet isFirst = true\n// 播放控制函数\nconst play = async () => {\n  // 避免重复启动\n  if (intervalId.value) return;\n\n  // 重置播放位置\n  if (currentColumn.value >= notes.value.length - 1) {\n    currentColumn.value = 0;\n    progress.value = 1;\n  }\n\n  // 开始播放\n  isPlaying.value = true;\n  intervalId.value = true;\n  let inWhileColumn = currentColumn.value;\n\n  // 播放循环\n  while (inWhileColumn < notes.value.length && intervalId.value) {\n    inWhileColumn++;\n    if (isFirst) {\n      playNowColumn();\n      isFirst = false;\n      await sleep(timeNotes.value[progress.value]);\n    } else {\n      nextColumn();\n      await sleep(timeNotes.value[progress.value - 1]);\n    }\n  }\n\n  // 播放结束，重置状态\n  intervalId.value = null;\n  isPlaying.value = false;\n  isFirst = true;\n};\nconst pause = () => {\n  intervalId.value = null; // 结束 while 循环\n  isPlaying.value = false;\n  isFirst = false;\n};\nconst reverse = async () => {\n  if (intervalId.value) return; // 避免重复启动\n  console.log(currentColumn.value)\n  if (currentColumn.value == 0) {\n    currentColumn.value = notes.value.length\n    progress.value = notes.value.length\n  }\n  isPlaying.value = true;\n  intervalId.value = true;\n  let inWhileColumn = currentColumn.value\n  while (inWhileColumn >= 0 && intervalId.value) {\n    inWhileColumn--;\n    if (isFirst) {\n      playNowColumn()\n      isFirst = false;\n    } else {\n      previousColumn()\n    }\n    await sleep(timeNotes.value[progress.value - 2]);\n  }\n  intervalId.value = null;\n  isPlaying.value = false;\n  isFirst = true;\n};\nconst deleteCurrentColumn = () => {\n  notes.value.splice(currentColumn.value, 1);\n  durationNotes.value.splice(currentColumn.value, 0);\n  if (currentColumn.value >= notes.value.length) {\n    currentColumn.value = notes.value.length - 1;\n  } progress.value = currentColumn.value + 1;\n  drawCanvas();\n};\nconst insertEmptyColumn = () => {\n  for (let i = 0; i < defaultAddColumnCount.value; i++) {\n    const insertIndex = currentColumn.value + 1; // 计算插入位置\n    notes.value.splice(insertIndex, 0, []); // 在光标后插入空列\n    durationNotes.value.splice(insertIndex, 0, defaultDownDuration.value); // 插入默认时长 0\n    timeNotes.value.splice(insertIndex, 0, defaultAfterDuration.value); // 插入默认时间差 0\n    currentColumn.value = currentColumn.value + 1\n    progress.value = insertIndex + 1; // 更新进度\n  }\n  drawCanvas(); // 重新绘制\n  console.log(notes.value, durationNotes.value, timeNotes.value)\n}; const updateProgress = () => { currentColumn.value = progress.value - 1; drawCanvas(); };\n// 监听器配置\nwatch(progress, syncCanvasToKeysArea);\nwatch(showRowSpaceColor, drawCanvas);\n\n// 监听列后等待延迟的变化\nwatch(columnAfterDuration, (newValue, _oldValue) => {\n  if (columnDownDuration.value >= newValue) {\n    message.info(t('music_edit.tips.tip1'));\n    columnDownDuration.value = Math.max(newValue - 10, 0);\n  }\n  const finalValue = Math.max(newValue, 10);\n  columnAfterDuration.value = finalValue;\n  timeNotes.value[progress.value - 1] = finalValue;\n  drawCanvas();\n});\nconst copyNowColumnToStart = () => {\n  const currentNotes = notes.value[currentColumn.value];\n  const currentDuration = durationNotes.value[currentColumn.value];\n  const currentTime = timeNotes.value[currentColumn.value];\n\n  notes.value.unshift([...currentNotes]);\n  durationNotes.value.unshift(currentDuration);\n  timeNotes.value.unshift(currentTime);\n\n  currentColumn.value++;\n  progress.value = currentColumn.value + 1;\n  drawCanvas();\n  message.success(t('music_edit.tips.tip2'));\n};\n\nconst copyNowColumnToPre = () => {\n  const currentNotes = notes.value[currentColumn.value];\n  const currentDuration = durationNotes.value[currentColumn.value];\n  const currentTime = timeNotes.value[currentColumn.value];\n\n  notes.value.splice(currentColumn.value, 0, [...currentNotes]);\n  durationNotes.value.splice(currentColumn.value, 0, currentDuration);\n  timeNotes.value.splice(currentColumn.value, 0, currentTime);\n\n  currentColumn.value++;\n  progress.value = currentColumn.value + 1;\n  drawCanvas();\n  message.success(t('music_edit.tips.tip3'));\n};\n\nconst copyNowColumnToNext = () => {\n  const currentNotes = notes.value[currentColumn.value];\n  const currentDuration = durationNotes.value[currentColumn.value];\n  const currentTime = timeNotes.value[currentColumn.value];\n\n  notes.value.splice(currentColumn.value + 1, 0, [...currentNotes]);\n  durationNotes.value.splice(currentColumn.value + 1, 0, currentDuration);\n  timeNotes.value.splice(currentColumn.value + 1, 0, currentTime);\n\n  // currentColumn.value++;\n  // progress.value = currentColumn.value + 1;\n  drawCanvas();\n  message.success(t('music_edit.tips.tip4'));\n};\n\nconst copyNowColumnToEnd = () => {\n  const currentNotes = notes.value[currentColumn.value];\n  const currentDuration = durationNotes.value[currentColumn.value];\n  const currentTime = timeNotes.value[currentColumn.value];\n\n  notes.value.push([...currentNotes]);\n  durationNotes.value.push(currentDuration);\n  timeNotes.value.push(currentTime);\n\n  // currentColumn.value = notes.value.length - 1;\n  // progress.value = currentColumn.value + 1;\n  // currentColumn.value++;\n  // progress.value = currentColumn.value + 1;\n  drawCanvas();\n  message.success(t('music_edit.tips.tip5'));\n};\n\nwatch(columnDownDuration, (newValue, _oldValue) => {\n  if (newValue >= columnAfterDuration.value) {\n    message.info(t('music_edit.tips.tip6'));\n    columnAfterDuration.value = newValue + 10;\n  }\n  durationNotes.value[progress.value - 1] = newValue;\n  drawCanvas();\n});\nwatch(defaultAfterDuration, (newValue, _oldValue) => {\n  if (newValue < 10) {\n    message.info(t('music_edit.tips.tip7'));\n    defaultAfterDuration.value = 10;\n  } else if (defaultDownDuration.value >= newValue - 10) {\n    message.info(t('music_edit.tips.tip8'));\n    defaultDownDuration.value = newValue - 10;\n  }\n});\n\nwatch(defaultDownDuration, (newValue, _oldValue) => {\n  if (newValue >= defaultAfterDuration.value - 10) {\n    message.info(t('music_edit.tips.tip8'));\n    defaultAfterDuration.value = newValue + 10;\n  }\n});\nwatch(nowButton, () => {\n  columnDownDuration.value = Number(durationNotes.value[progress.value - 1])\n})\nfunction syncCanvasToKeysArea() {\n  keys.value = [[\"dmcr\", \"dm\", \"cr\", \"dm\", \"cr\"], [\"cr\", \"dm\", \"dmcr\", \"dm\", \"cr\"], [\"cr\", \"dm\", \"cr\", \"dm\", \"dmcr\"]].map((row, rowIndex) => row.map((type, colIndex) => ({ key: String(rowIndex * 5 + colIndex), type, duration: 0, active: false })));\n  if (notes.value.length == 0) return;\n  notes.value[progress.value - 1]?.forEach(res => {\n    if (res >= 1 && res <= 15) {\n      let row = Math.floor((res - 1) / 5);\n      let col = (res - 1) % 5;\n      keys.value[row][col].active = true;\n    }\n  });\n  columnDownDuration.value = durationNotes.value[progress.value - 1]\n  columnAfterDuration.value = timeNotes.value[progress.value - 1]\n  drawCanvas()\n}\nfunction handleButtonClick(item, column, row) {\n  const index = row + column * 5;\n  const progressIndex = progress.value - 1;\n  item.active = !item.active;\n  if (item.active) {\n    notes.value[progressIndex].push(index + 1);\n    durationNotes.value[progressIndex] = item.duration ? item.duration : 0;\n  } else {\n    notes.value[progressIndex] = notes.value[progressIndex].filter(res => res !== index + 1);\n    durationNotes.value[progressIndex] = 0;\n  }\n  drawCanvas()\n  nowButton.value = column * 5 + row\n}\n\nfunction getSheetToMemory(startIdx) {\n  let demoSongNotes: any = [];\n  let sumTimestamp = 0;\n  for (let index = startIdx; index < notes.value.length; index++) {\n    for (let j = 0; j < notes.value[index].length; j++) {\n      let row = notes.value[index][j];\n      demoSongNotes.push({\n        time: sumTimestamp,\n        key: `${notes.value[index].length}Key${row - 1}`,\n        duration: Number(durationNotes.value[index]) || 0\n      });\n    }\n    sumTimestamp += timeNotes.value[index];\n  }\n  return demoSongNotes\n}\n\n// 鼠标事件状态\nlet isDragging = false;\nlet initialState = false;\nlet lastProcessedCell = { row: -1, col: -1 };\n\n// 网格位置计算\nconst getGridPosition = (x: number, y: number) => {\n  const canvas: any = midiCanvas.value;\n  if (!canvas) return null;\n\n  const rect = canvas.getBoundingClientRect();\n  const scaleX = canvas.width / rect.width;\n  const scaleY = canvas.height / rect.height;\n\n  const canvasX = (x - rect.left) * scaleX;\n  const canvasY = (y - rect.top) * scaleY;\n\n  const viewportCenter = canvasWidth / 2;\n  const currentX = currentColumn.value * columnSize;\n  let offsetX = 0;\n  if (currentX > viewportCenter) {\n    offsetX = viewportCenter - currentX;\n  }\n\n  const adjustedX = canvasX - offsetX;\n  const col = Math.floor(adjustedX / columnSize);\n  const row = Math.floor(canvasY / (canvasHeight / 15));\n\n  if (col >= 0 && col < notes.value.length && row >= 0 && row < 15) {\n    return { row: row + 1, col };\n  }\n  return null;\n};\n\nconst processGridCell = (position: { row: number, col: number }) => {\n  if (!position || (position.row === lastProcessedCell.row && position.col === lastProcessedCell.col)) {\n    return;\n  }\n\n  lastProcessedCell = position;\n  const columnNotes = notes.value[position.col] || [];\n  const noteExists = columnNotes.includes(position.row);\n\n  if (isDragging) {\n    if (initialState && noteExists) {\n      notes.value[position.col] = columnNotes.filter(note => note !== position.row);\n    } else if (!initialState && !noteExists) {\n      if (!notes.value[position.col]) {\n        notes.value[position.col] = [];\n      }\n      notes.value[position.col].push(position.row);\n    }\n  } else {\n    if (noteExists) {\n      notes.value[position.col] = columnNotes.filter(note => note !== position.row);\n    } else {\n      if (!notes.value[position.col]) {\n        notes.value[position.col] = [];\n      }\n      notes.value[position.col].push(position.row);\n    }\n  }\n\n  drawCanvas();\n  // 只有当修改的是当前列时才执行syncCanvasToKeysArea\n  if (position.col === progress.value - 1) {\n    syncCanvasToKeysArea();\n  }\n};\n\n// 生命周期钩子\nonMounted(() => {\n  // 初始化窗口大小\n  window.api.window_size(774, 1500);\n\n  // 初始化Canvas\n  const canvas: any = midiCanvas.value;\n  if (canvas) {\n    canvas.width = canvasWidth;\n    canvas.height = canvasHeight;\n    drawCanvas();\n    getListData('systemMusic');\n    syncCanvasToKeysArea();\n\n    canvas.addEventListener('mousedown', (e: MouseEvent) => {\n      const position = getGridPosition(e.clientX, e.clientY);\n      if (position) {\n        isDragging = true;\n        const columnNotes = notes.value[position.col] || [];\n        initialState = columnNotes.includes(position.row);\n        processGridCell(position);\n      }\n    });\n\n    canvas.addEventListener('mousemove', (e: MouseEvent) => {\n      if (isDragging) {\n        const position = getGridPosition(e.clientX, e.clientY);\n        if (position) {\n          processGridCell(position);\n        }\n      }\n    });\n\n    const handleMouseUp = () => {\n      isDragging = false;\n      lastProcessedCell = { row: -1, col: -1 };\n    };\n\n    document.addEventListener('mouseup', handleMouseUp);\n\n    onUnmounted(() => {\n      document.removeEventListener('mouseup', handleMouseUp);\n    });\n  }\n});\n// 组件卸载时的清理工作\nonUnmounted(() => {\n  pause();\n  window.api.window_size(0, 0);\n});\nonBeforeRouteLeave((_to, _from, next) => {\n  if (notes.value.length >= 3) {\n    dialog.warning({\n      title: t('music_edit.dialog.title'),\n      content: t('music_edit.dialog.content2'),\n      positiveText: t('music_edit.dialog.positiveText2'),\n      negativeText: t('music_edit.dialog.negativeText2'),\n      maskClosable: false, // 遮罩不可点击\n      showIcon: false,\n      positiveButtonProps: {\n        color: '#F2C9C4'\n      },\n      negativeButtonProps: {\n        color: '#F2E8C4'\n      },\n      onPositiveClick: () => {\n        next(); // 允许离开\n      },\n      onNegativeClick: () => {\n        next(false); // 阻止离开\n      }\n    });\n  } else {\n    next(); // 直接离开\n  }\n});\n</script>\n\n<style scoped>\n.midi-editor {\n  display: flex;\n  overflow: hidden;\n  background: transparent\n}\n\n.midi-content {\n  flex-grow: 1;\n  background: transparent;\n  padding-top: 10px;\n}\n\n.midi-canvas {\n  width: 100%;\n  height: 100%;\n  display: block;\n  background: transparent;\n}\n\n:deep(.n-layout) {\n  background: transparent !important;\n}\n\n:deep(.n-input) {\n  --n-border-hover: 1px solid rgb(242, 232, 196) !important;\n  --n-border-focus: 1px solid rgb(242, 232, 196) !important;\n  --n-caret-color: rgb(242, 232, 196) !important;\n  --n-color-focus: rgba(242, 232, 196, 0.1) !important;\n  --n-text-color: rgb(242,232,196) !important;\n}\n\n:deep(.n-tabs) {\n  --n-tab-text-color-active: rgb(242, 232, 196) !important;\n  --n-tab-text-color-hover: rgb(242, 232, 196) !important;\n  --n-tab-text-color: rgb(221, 242, 196) !important;\n}\n\n:deep(.td_css td) {\n  color: rgb(242, 232, 196) !important;\n}\n\n:deep(.th_css) {\n  color: rgb(221, 242, 196) !important;\n}\n\n:deep(.table_position td) {\n  background-color: rgba(242, 201, 196, 0.507) !important;\n}\n\n:deep(.n-tabs-bar) {\n  --n-bar-color: rgb(242, 232, 196) !important;\n}\n\n:deep(.n-radio) {\n  --n-box-shadow-active: inset 0 0 0 1px rgb(242, 232, 196) !important;\n  --n-box-shadow-focus: inset 0 0 0 1px rgb(242, 232, 196), 0 0 0 2px rgba(242, 232, 196, 0.3) !important;\n  --n-box-shadow-hover: inset 0 0 0 1px rgb(242, 232, 196) !important;\n  --n-dot-color-active: rgb(242, 232, 196) !important;\n}\n</style>\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/setting.vue",
    "content": "<template>\n  <div id=\"headText\">\n    <n-highlight style=\"margin-bottom: 5px; color: #DDF2C4;\" :text=\"headText\" :patterns=\"patterns\" :highlight-style=\"{\n      padding: '0 6px',\n      margin: '0 6px',\n      borderRadius: themeVars.borderRadius,\n      display: 'inline-block',\n      color: 'black',\n      background: '#F2C9C4',\n      transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n    }\" />\n    <div style=\"flex-basis: 100%;\" />\n    <n-button type=\"primary\" color=\"#A3F6EC\" style=\"margin-top: 20px;\" ghost @click=\"resetKeyToDefault()\">\n        {{t('setting.reset_map')}}\n    </n-button>\n    <n-button type=\"primary\" color=\"#f58f98\" style=\"margin-top: 20px; margin-left: 20px;\" ghost @click=\"resetKey()\">\n        {{\"清空所有映射\"}}\n    </n-button>\n    <n-divider style=\"color: #F2C9C4;\">{{t('setting.key_map')}}</n-divider>\n  </div>\n  <div id=\"father\">\n    <div v-for=\"key in customize_key\">\n      <n-input-group style=\"margin-top: 20px\">\n        <n-button type=\"primary\" text style=\"width: 15px;\" color=\"#FF6347\" v-if=\"key.name.includes('C') || key.name.includes('c')\">\n          {{ key.name }}\n        </n-button>\n        <n-button type=\"primary\" text style=\"width: 15px;\" color=\"#DDF2C4\" v-else>\n          {{ key.name }}\n        </n-button>\n        <n-input v-model:value=\"key.value\" readonly clearable style=\"width: 71px;\" placeholder=\"\" @blur=\"handleBlur()\" @focus=\"handleFocus(key.label)\" @clear=\"handleClear(key.label)\"\t />\n      </n-input-group>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useThemeVars } from \"naive-ui\";\nimport { sendData } from \"@renderer/utils/fetchUtils\";\nimport { useMessage } from 'naive-ui'\nimport { onMounted, onUnmounted, ref } from 'vue'\nimport hotkeys from 'hotkeys-js';\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\nconst themeVars = useThemeVars();\nconst message = useMessage()\nconst customize_key:any = ref([])\nconst headText = t('setting.head_text');\nconst patterns = [t('setting.patterns1'),t('setting.patterns2'),t('setting.patterns3')];\nconst keyMapStruct={ \"ScrollLock\": \"scroll_lock\", \"Escape\": \"esc\", \"PageUp\": \"page_up\", \"PageDown\": \"page_down\", \"ArrowUp\": \"up\", \"ArrowDown\": \"down\", \"ArrowLeft\": \"left\", \"ArrowRight\": \"right\", \"ControlRight\": \"ctrl_r\", \"AltRight\": \"alt_gr\", \"ControlLeft\": \"ctrl_l\", \"AltLeft\": \"alt_l\", \"ShiftLeft\": \"shift\", \"Enter\": \"enter\", \"Backspace\": \"backspace\", \"CapsLock\": \"caps_lock\"}\n\nfunction handleBlur() {\n  hotkeys.unbind()\n}\n\nfunction handleFocus(label) {\n  hotkeys('*', function (e) {\n    let demoTranKey\n    if (e.code in keyMapStruct) {\n      demoTranKey = keyMapStruct[e.code].toUpperCase();\n    } else if (e.code === \"\" && e.key === \"Shift\") {\n      demoTranKey = \"shift_r\".toUpperCase()\n    } else {\n      demoTranKey = e.key.toUpperCase()\n    }\n    \n    let tempIndex = customize_key.value.findIndex(item => item.label === label);\n    let tempArray = JSON.parse(JSON.stringify(customize_key.value))\n    tempArray[tempIndex][\"value\"] = demoTranKey\n    if (hasDuplicateValues(tempArray)) {\n      message.error(t('setting.repeat'))\n      return\n    } else {\n      customize_key.value[tempIndex][\"value\"] = demoTranKey\n      set_customize_key()\n      message.success(t('setting.ok'))\n    }\n  })\n}\n\nfunction handleClear(label) {\n    let tempIndex = customize_key.value.findIndex(item => item.label === label);\n    customize_key.value[tempIndex][\"value\"] = ''\n    set_customize_key()\n    message.success(t('setting.clearNow'))\n}\n\nfunction set_customize_key() {\n  const transformedObject = {};\n  customize_key.value.forEach(item => {\n      transformedObject[item.label] = item.value.toLowerCase();\n  });\n  sendData(\"config_operate\",{ \"operate\": \"set\", \"name\": \"keyMap\", \"value\":transformedObject}).then(()=>{\n    get_customize_key()\n  })\n}\n\nfunction get_customize_key() {\n  sendData(\"config_operate\", {\n    \"operate\": \"get\",\n    \"name\": \"keyMap\"\n  }).then(res => {\n    customize_key.value = [\n    { \"name\": \"C\", \"label\": \"Key-14\", \"value\": res[\"Key-14\"].toUpperCase()},\n    { \"name\": \"D\", \"label\": \"Key-13\", \"value\": res[\"Key-13\"].toUpperCase()},\n    { \"name\": \"E\", \"label\": \"Key-12\", \"value\": res[\"Key-12\"].toUpperCase()},\n    { \"name\": \"F\", \"label\": \"Key-11\", \"value\": res[\"Key-11\"].toUpperCase()},\n    { \"name\": \"G\", \"label\": \"Key-10\", \"value\": res[\"Key-10\"].toUpperCase()},\n    { \"name\": \"A\", \"label\": \"Key-9\", \"value\": res[\"Key-9\"].toUpperCase()},\n    { \"name\": \"B\", \"label\": \"Key-8\", \"value\": res[\"Key-8\"].toUpperCase()},\n    { \"name\": \"c\", \"label\": \"Key-7\", \"value\": res[\"Key-7\"].toUpperCase()},\n    { \"name\": \"d\", \"label\": \"Key-6\", \"value\": res[\"Key-6\"].toUpperCase()},\n    { \"name\": \"e\", \"label\": \"Key-5\", \"value\": res[\"Key-5\"].toUpperCase()},\n    { \"name\": \"f\", \"label\": \"Key-4\", \"value\": res[\"Key-4\"].toUpperCase()},\n    { \"name\": \"g\", \"label\": \"Key-3\", \"value\": res[\"Key-3\"].toUpperCase()},\n    { \"name\": \"a\", \"label\": \"Key-2\", \"value\": res[\"Key-2\"].toUpperCase()},\n    { \"name\": \"b\", \"label\": \"Key-1\", \"value\": res[\"Key-1\"].toUpperCase()},\n    { \"name\": \"c¹\", \"label\": \"Key0\", \"value\": res[\"Key0\"].toUpperCase()},\n    { \"name\": \"d¹\", \"label\": \"Key1\", \"value\": res[\"Key1\"].toUpperCase()},\n    { \"name\": \"e¹\", \"label\": \"Key2\", \"value\": res[\"Key2\"].toUpperCase()},\n    { \"name\": \"f¹\", \"label\": \"Key3\", \"value\": res[\"Key3\"].toUpperCase()},\n    { \"name\": \"g¹\", \"label\": \"Key4\", \"value\": res[\"Key4\"].toUpperCase()},\n    { \"name\": \"a¹\", \"label\": \"Key5\", \"value\": res[\"Key5\"].toUpperCase()},\n    { \"name\": \"b¹\", \"label\": \"Key6\", \"value\": res[\"Key6\"].toUpperCase()},\n    { \"name\": \"c²\", \"label\": \"Key7\", \"value\": res[\"Key7\"].toUpperCase()},\n    { \"name\": \"d²\", \"label\": \"Key8\", \"value\": res[\"Key8\"].toUpperCase()},\n    { \"name\": \"e²\", \"label\": \"Key9\", \"value\": res[\"Key9\"].toUpperCase()},\n    { \"name\": \"f²\", \"label\": \"Key10\", \"value\": res[\"Key10\"].toUpperCase()},\n    { \"name\": \"g²\", \"label\": \"Key11\", \"value\": res[\"Key11\"].toUpperCase()},\n    { \"name\": \"a²\", \"label\": \"Key12\", \"value\": res[\"Key12\"].toUpperCase()},\n    { \"name\": \"b²\", \"label\": \"Key13\", \"value\": res[\"Key13\"].toUpperCase()},\n    { \"name\": \"c³\", \"label\": \"Key14\", \"value\": res[\"Key14\"].toUpperCase()},\n    { \"name\": \"d³\", \"label\": \"Key15\", \"value\": res[\"Key15\"].toUpperCase()},\n    { \"name\": \"e³\", \"label\": \"Key16\", \"value\": res[\"Key16\"].toUpperCase()},\n    { \"name\": \"f³\", \"label\": \"Key17\", \"value\": res[\"Key17\"].toUpperCase()},\n    { \"name\": \"g³\", \"label\": \"Key18\", \"value\": res[\"Key18\"].toUpperCase()},\n    { \"name\": \"a³\", \"label\": \"Key19\", \"value\": res[\"Key19\"].toUpperCase()},\n    { \"name\": \"b³\", \"label\": \"Key20\", \"value\": res[\"Key20\"].toUpperCase()},\n    { \"name\": \"c⁴\", \"label\": \"Key21\", \"value\": res[\"Key21\"].toUpperCase()},\n    { \"name\": \"d⁴\", \"label\": \"Key22\", \"value\": res[\"Key22\"].toUpperCase()},\n    { \"name\": \"e⁴\", \"label\": \"Key23\", \"value\": res[\"Key23\"].toUpperCase()},\n    { \"name\": \"f⁴\", \"label\": \"Key24\", \"value\": res[\"Key24\"].toUpperCase()},\n    { \"name\": \"g⁴\", \"label\": \"Key25\", \"value\": res[\"Key25\"].toUpperCase()},\n    { \"name\": \"a⁴\", \"label\": \"Key26\", \"value\": res[\"Key26\"].toUpperCase()},\n    { \"name\": \"b⁴\", \"label\": \"Key27\", \"value\": res[\"Key27\"].toUpperCase()},\n    { \"name\": \"c⁵\", \"label\": \"Key28\", \"value\": res[\"Key28\"].toUpperCase()}]\n  })\n}\n\nfunction hasDuplicateValues(dataArray) {\n  const values = dataArray\n    .filter(item => item.value !== undefined && item.value !== null && item.value !== '')\n    .map(item => item.value);\n  const uniqueValues = new Set(values);\n  return uniqueValues.size !== values.length;\n}\n\nfunction resetKeyToDefault(){\n  sendData(\"config_operate\",{ \"operate\": \"set\", \"name\": \"keyMap\", \"value\":{ 'Key-14': '', 'Key-13': '', 'Key-12': '', 'Key-11': '', 'Key-10': '', 'Key-9': '', 'Key-8': '', 'Key-7': '', 'Key-6': '', 'Key-5': '', 'Key-4': '', 'Key-3': '', 'Key-2': '', 'Key-1': '', 'Key0': 'y', 'Key1': 'u', 'Key2': 'i', 'Key3': 'o', 'Key4': 'p', 'Key5': 'h', 'Key6': 'j', 'Key7': 'k', 'Key8': 'l', 'Key9': ';', 'Key10': 'n', 'Key11': 'm', 'Key12': ',', 'Key13': '.', 'Key14': '/', 'Key15': '', 'Key16': '', 'Key17': '', 'Key18': '', 'Key19': '', 'Key20': '', 'Key21': '', 'Key22': '', 'Key23': '', 'Key24': '', 'Key25': '', 'Key26': '', 'Key27': '', 'Key28': ''}}).then(()=>{\n    get_customize_key()\n    message.success(t('setting.clearAll'))\n  })\n}\n\nfunction resetKey(){\n  sendData(\"config_operate\",{ \"operate\": \"set\", \"name\": \"keyMap\", \"value\":{ 'Key-14': '', 'Key-13': '', 'Key-12': '', 'Key-11': '', 'Key-10': '', 'Key-9': '', 'Key-8': '', 'Key-7': '', 'Key-6': '', 'Key-5': '', 'Key-4': '', 'Key-3': '', 'Key-2': '', 'Key-1': '', 'Key0': '', 'Key1': '', 'Key2': '', 'Key3': '', 'Key4': '', 'Key5': '', 'Key6': '', 'Key7': '', 'Key8': '', 'Key9': '', 'Key10': '', 'Key11': '', 'Key12': '', 'Key13': '', 'Key14': '', 'Key15': '', 'Key16': '', 'Key17': '', 'Key18': '', 'Key19': '', 'Key20': '', 'Key21': '', 'Key22': '', 'Key23': '', 'Key24': '', 'Key25': '', 'Key26': '', 'Key27': '', 'Key28': ''}}).then(()=>{\n    get_customize_key()\n    message.success(t('setting.clearAll'))\n  })\n}\n\nonMounted(() => {\n  get_customize_key()\n})\nonUnmounted(() => {\n  hotkeys.unbind()\n})\n</script>\n\n<style scoped>\n#headText {\n  margin-top: 30px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  flex-wrap: wrap;\n}\n#father {\n  display: flex;\n  align-items: center;\n  flex-wrap: wrap;\n}\n\n:deep(.n-slider-rail__fill) {\n  --n-fill-color-hover: rgb(242, 232, 196) !important;\n  background-color: rgb(242, 232, 196) !important;\n}\n\n:deep(.n-radio) {\n  --n-box-shadow-active: inset 0 0 0 1px rgb(242, 232, 196) !important;\n  --n-box-shadow-focus: inset 0 0 0 1px rgb(242, 232, 196), 0 0 0 2px rgba(242, 232, 196, 0.3) !important;\n  --n-box-shadow-hover: inset 0 0 0 1px rgb(242, 232, 196) !important;\n  --n-dot-color-active: rgb(242, 232, 196) !important;\n}\n\n\n:deep(.n-input){\n  --n-border-hover: 1px solid rgb(242,232,196)!important;\n  --n-border-focus: 1px solid rgb(242,232,196)!important;\n  --n-caret-color: rgb(242,232,196)!important;\n  --n-color-focus: rgba(242,232,196,0.1)!important;\n  --n-text-color: rgb(242,232,196) !important;\n}\n</style>"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/shortcutKeys.vue",
    "content": "<template>\n  <div id=\"father\">\n    <n-highlight style=\"margin-bottom: 5px; color: #DDF2C4;\" :text=\"headText\" :patterns=\"patterns\" :highlight-style=\"{\n      padding: '0 6px',\n      margin: '0 6px',\n      borderRadius: themeVars.borderRadius,\n      display: 'inline-block',\n      color: 'black',\n      background: '#F2C9C4',\n      transition: `all .3s ${themeVars.cubicBezierEaseInOut}`,\n    }\" />\n    <div style=\"flex-basis: 100%;\" />\n    <n-button type=\"primary\" color=\"#f58f98\" style=\"margin-top: 20px;\" ghost @click=\"resetKeyToDefault()\">\n        {{ t(\"shortcutKeys.title\") }}\n    </n-button>\n    <n-divider style=\"color: #F2C9C4;\">{{ t(\"shortcutKeys.divider1\") }}</n-divider>\n    <div v-for=\"shortcut in musicShortcut\" style=\"margin-right: auto;\">\n      <n-input-group style=\"margin-top: 20px\">\n        <n-button type=\"primary\" text style=\"width: 100px;\" color=\"#DDF2C4\">\n          {{ shortcut.name }}\n        </n-button>\n        <n-input v-model:value=\"shortcutKey['music_key'][shortcut.label]\" readonly @blur=\"handleBlur()\" placeholder=\"\"\n          @focus=\"handleFocus('music_key', shortcut.label)\" />\n      </n-input-group>\n    </div>\n    <n-divider style=\"color: #F2C9C4;\">{{ t(\"shortcutKeys.divider2\") }}</n-divider>\n    <div v-for=\"shortcut in followShortcut\" style=\"margin-right: auto;\">\n      <n-input-group style=\"margin-top: 20px\">\n        <n-button type=\"primary\" text style=\"width: 100px;\" color=\"#DDF2C4\">\n          {{ shortcut.name }}\n        </n-button>\n        <n-input v-model:value=\"shortcutKey['follow_key'][shortcut.label]\" readonly @blur=\"handleBlur()\" placeholder=\"\"\n          @focus=\"handleFocus('follow_key', shortcut.label)\" />\n      </n-input-group>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useThemeVars } from \"naive-ui\";\nimport { sendData } from \"@renderer/utils/fetchUtils\";\nimport { useMessage } from 'naive-ui'\nimport { onMounted, onUnmounted, ref } from 'vue'\nimport hotkeys from 'hotkeys-js';\nimport configStore, { CONFIG_TYPE } from '@renderer/utils/configStore'\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\nconst themeVars = useThemeVars();\nconst message = useMessage()\nconst headText = t(\"shortcutKeys.head_text\");\nconst patterns = [t(\"shortcutKeys.patterns1\"),t(\"shortcutKeys.patterns2\"),t(\"shortcutKeys.patterns3\")];\n\nconst musicShortcut=[{ name: t(\"shortcutKeys.button_title.start\"), label: \"start\",},{ name: t(\"shortcutKeys.button_title.resume\"), label: \"resume\",},{ name: t(\"shortcutKeys.button_title.pause\"), label: \"pause\",},{ name: t(\"shortcutKeys.button_title.stop\"), label: \"stop\",},{ name: t(\"shortcutKeys.button_title.add_duration\"), label: \"add_duration\"},{ name: t(\"shortcutKeys.button_title.reduce_duration\"), label: \"reduce_duration\"},{ name: t(\"shortcutKeys.button_title.add_delay\"), label: \"add_delay\"},{ name: t(\"shortcutKeys.button_title.reduce_delay\"), label: \"reduce_delay\"},{ name: t(\"shortcutKeys.button_title.add_speed\"), label: \"add_speed\"},{ name: t(\"shortcutKeys.button_title.reduce_speed\"), label: \"reduce_speed\"},{ name: t(\"shortcutKeys.button_title.next\"), label: \"next\",}]\nconst followShortcut=[{ name: t(\"shortcutKeys.button_title.repeat\"), label: \"repeat\"},{ name: t(\"shortcutKeys.button_title.repeat_next\"), label: \"repeat_next\"},{ name: t(\"shortcutKeys.button_title.exit\"), label: \"exit\"},{ name: t(\"shortcutKeys.button_title.resize\"), label: \"resize\"}]\nconst shortcutKey=ref({ follow_key:{ tap_key: \"\", string: \"\", repeat: \"\", repeat_next: \"\", resize: \"\", exit: \"\"}, music_key:{ next: \"\", pause: \"\", resume: \"\", start: \"\", stop: \"\", add_duration:\"\", reduce_duration: \"\", add_delay: \"\", reduce_delay:\"\", add_speed:\"\", reduce_speed:\"\", string: \"\",}})\nconst keyMapStruct={ \"ScrollLock\": \"scroll_lock\", \"Escape\": \"esc\", \"PageUp\": \"page_up\", \"PageDown\": \"page_down\", \"ArrowUp\": \"up\", \"ArrowDown\": \"down\", \"ArrowLeft\": \"left\", \"ArrowRight\": \"right\", \"ControlRight\": \"ctrl_r\", \"AltRight\": \"alt_gr\", \"ControlLeft\": \"ctrl_l\", \"AltLeft\": \"alt_l\", \"ShiftLeft\": \"shift\", \"Enter\": \"enter\", \"Backspace\": \"backspace\", \"CapsLock\": \"caps_lock\"}\n\n\nfunction handleBlur() {\n  hotkeys.unbind()\n}\n\nfunction handleFocus(type, label) {\n  hotkeys('*', function (e) {\n    console.log(\"e\", e)\n\n    let demoTranKey\n    if (e.code in keyMapStruct) {\n      demoTranKey = keyMapStruct[e.code].toUpperCase();\n    } else if (e.code === \"\" && e.key === \"Shift\") {\n      demoTranKey = \"shift_r\".toUpperCase()\n    } else {\n      demoTranKey = e.key.toUpperCase()\n    }\n\n    let tempStruct = JSON.parse(JSON.stringify(shortcutKey.value));\n    tempStruct[type][label] = demoTranKey\n    if (!checkDuplicates(tempStruct)) {\n      message.error(t(\"setting.repeat\"))\n      return\n    } else {\n      shortcutKey.value[type][label] = demoTranKey\n      configStore.setItem(CONFIG_TYPE.SHORTCUT_KEY, tempStruct)\n      setShortcutKeys()\n      message.success(t(\"setting.ok\"))\n    }\n  })\n}\n\nfunction setShortcutKeys() {\n  const shortcutKeyValues = shortcutKey.value;\n  const follow = shortcutKeyValues.follow_key;\n  const music = shortcutKeyValues.music_key;\n  const followString = (follow.repeat + follow.repeat_next + follow.resize);\n  const musicString = (music.next + music.pause + music.resume + music.start + music.stop + music.add_duration + music.reduce_duration + music.add_delay + music.reduce_delay + music.add_speed + music.reduce_speed);\n  const followKey = {\n    tap_key: \"yuiophjkl;nm,./\",\n    repeat: follow.repeat.toLowerCase(),\n    repeat_next: follow.repeat_next.toLowerCase(),\n    resize: follow.resize.toLowerCase(),\n    exit: follow.exit.toLowerCase(),\n    // 使用计算后的字符串\n    string: followString.toLowerCase()\n  };\n  const musicKey = {\n    next: music.next.toLowerCase(),\n    pause: music.pause.toLowerCase(),\n    resume: music.resume.toLowerCase(),\n    start: music.start.toLowerCase(),\n    stop: music.stop.toLowerCase(),\n    string: musicString.toLowerCase(),\n    add_duration: music.add_duration.toLowerCase(),\n    reduce_duration: music.reduce_duration.toLowerCase(),\n    add_delay: music.add_delay.toLowerCase(),\n    reduce_delay: music.reduce_delay.toLowerCase(),\n    add_speed: music.add_speed.toLowerCase(),\n    reduce_speed: music.reduce_speed.toLowerCase(),\n  };\n  sendData(\"config_operate\", {\n    \"operate\": \"set\",\n    \"name\": \"shortcutStruct\",\n    \"value\": {\n      \"follow_key\": followKey,\n      \"music_key\": musicKey\n    }\n  })\n}\nfunction getShortcutKeys() {\n  return new Promise(resolve => {\n    sendData(\"config_operate\", {\n      \"operate\": \"get\",\n      \"name\": \"shortcutStruct\"\n    }).then(res => {\n      const follow = res.follow_key;\n      const music = res.music_key;\n      const followKey = {\n        tap_key: follow.tap_key.toUpperCase(),\n        repeat: follow.repeat.toUpperCase(),\n        repeat_next: follow.repeat_next.toUpperCase(),\n        resize: follow.resize.toUpperCase(),\n        exit: follow.exit.toUpperCase(),\n        string: follow.string.toUpperCase()\n      };\n      const musicKey = {\n        next: music.next.toUpperCase(),\n        pause: music.pause.toUpperCase(),\n        resume: music.resume.toUpperCase(),\n        start: music.start.toUpperCase(),\n        stop: music.stop.toUpperCase(),\n        add_duration: music.add_duration.toUpperCase(),\n        reduce_duration: music.reduce_duration.toUpperCase(),\n        add_delay: music.add_delay.toUpperCase(),\n        reduce_delay: music.reduce_delay.toUpperCase(),\n        add_speed: music.add_speed.toUpperCase(),\n        reduce_speed: music.reduce_speed.toUpperCase(),\n        string: music.string.toUpperCase()\n      };\n      shortcutKey.value.follow_key = followKey\n      shortcutKey.value.music_key = musicKey\n      resolve(true)\n    })\n  })\n}\n\nfunction checkDuplicates(shortcutObj) {\n  const keys: any = [];\n  for (const group in shortcutObj) {\n    if (shortcutObj.hasOwnProperty(group)) {\n      for (const key in shortcutObj[group]) {\n        if (shortcutObj[group].hasOwnProperty(key) && key !== \"string\" && key !== \"tap_key\") {\n          keys.push(shortcutObj[group][key]);\n        }\n      }\n    }\n  }\n  const uniqueKeys = new Set(keys);\n  return uniqueKeys.size === keys.length;\n}\n// 默认快捷方式\nconst defShortcutKey = {\"follow_key\":{\"tap_key\":\"yuiophjkl;nm,./\",\"string\":\"-=q\",\"repeat\":\"-\",\"repeat_next\":'=',\"resize\":\"q\",\"exit\":\"esc\"},\"music_key\":{\"string\":\"f2f5f6f7f8updownleftrightpage_uppage_down\",\"next\":\"f2\",\"start\":\"f5\",\"resume\":\"f6\",\"pause\":\"f7\",\"stop\":\"f8\",\"add_duration\":\"up\",\"reduce_duration\":\"down\",\"add_delay\":\"right\",\"reduce_delay\":\"left\",\"add_speed\":\"page_up\",\"reduce_speed\":\"page_down\",}}\n// 重置快捷方式\nfunction resetKeyToDefault(){\n  sendData(\"config_operate\", {\"operate\":\"set\",\"name\":\"shortcutStruct\",\"value\": defShortcutKey\n}).then(()=>{\n    getShortcutKeys().then(() => {\n      const tempStruct = JSON.parse(JSON.stringify(shortcutKey.value));\n      configStore.setItem(CONFIG_TYPE.SHORTCUT_KEY, tempStruct)\n    })\n    message.success(t(\"setting.clearAll\"))\n  })\n}\n\nonMounted(() => {\n  if(configStore.getItem(CONFIG_TYPE.SHORTCUT_KEY)){\n    shortcutKey.value = configStore.getItem(CONFIG_TYPE.SHORTCUT_KEY)\n    setShortcutKeys()\n  }else{\n    getShortcutKeys()\n  }\n})\nonUnmounted(() => {\n  hotkeys.unbind()\n})\n</script>\n\n<style scoped>\n#father {\n  margin-top: 30px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  flex-wrap: wrap;\n}\n\n:deep(.n-slider-rail__fill) {\n  --n-fill-color-hover: rgb(242, 232, 196) !important;\n  background-color: rgb(242, 232, 196) !important;\n}\n\n:deep(.n-radio) {\n  --n-box-shadow-active: inset 0 0 0 1px rgb(242, 232, 196) !important;\n  --n-box-shadow-focus: inset 0 0 0 1px rgb(242, 232, 196), 0 0 0 2px rgba(242, 232, 196, 0.3) !important;\n  --n-box-shadow-hover: inset 0 0 0 1px rgb(242, 232, 196) !important;\n  --n-dot-color-active: rgb(242, 232, 196) !important;\n}\n\n:deep(.n-input) {\n  --n-border-hover: 1px solid rgb(242, 232, 196) !important;\n  --n-border-focus: 1px solid rgb(242, 232, 196) !important;\n  --n-color-focus: rgba(242, 232, 196, 0.1) !important;\n  --n-text-color: rgb(242,232,196) !important;\n}\n</style>\n"
  },
  {
    "path": "sky-music-web/src/renderer/src/views/tutorial.vue",
    "content": "<template>\n  <n-flex align=\"center\">\n    <n-gradient-text :size=\"20\" type=\"success\" style=\"width: 100%; color: #f2e8c4\">\n      {{ t('tutorial.now', { music:nowPlayMusic }) }}\n    </n-gradient-text>\n    <n-button type=\"primary\" ghost @click=\"followTutorial\" color=\"#F2C9C4\">\n      {{ t('tutorial.follow') }}\n    </n-button>\n    <n-button type=\"primary\" ghost :loading=\"processFlag\" @click=\"transfer\" color=\"#F2E8C4\">{{ t('tutorial.save') }}</n-button>\n  </n-flex>\n  <n-card  style=\"margin-left: -22px; width: 640px;\" :bordered=\"false\">\n    <n-tabs\n      type=\"bar\"\n      animated\n      size=\"small\"\n      @update:value=\"handleUpdateValue\"\n      @before-leave=\"handleBeforeLeave\"\n    >\n      <n-tab-pane name=\"systemMusic\" :tab=\"t('tab.systemMusic')\">\n        <n-data-table\n          :columns=\"musicSystemColumns\"\n          :data=\"music.systemMusic\"\n          :bordered=\"false\"\n          :min-row-height=\"48\"\n          :max-height=\"490\"\n          :virtual-scroll=\"music.systemMusic?.length > 7\"\n          :row-props=\"MusicSelect\"\n          row-class-name=\"td_css\"\n          style=\"\n            --n-td-color: rgba(57, 57, 62, 0);\n            --n-th-color-hover: rgba(57, 57, 62, 0);\n            --n-th-color: rgba(57, 57, 62, 0);\n            --n-td-color-hover: rgba(0, 0, 0, 0.2);\n          \"/>\n      </n-tab-pane>\n      <n-tab-pane name=\"myImport\" :tab=\"t('tab.myImport')\">\n        <n-data-table\n          :columns=\"musicColumns\"\n          :data=\"music.myImport\"\n          :bordered=\"false\"\n          :min-row-height=\"48\"\n          :max-height=\"490\"\n          :virtual-scroll=\"music.myImport?.length > 7\"\n          :row-props=\"MusicSelect\"\n          row-class-name=\"td_css\"\n          style=\"\n            --n-td-color: rgba(57, 57, 62, 0);\n            --n-th-color-hover: rgba(57, 57, 62, 0);\n            --n-th-color: rgba(57, 57, 62, 0);\n            --n-td-color-hover: rgba(0, 0, 0, 0.2);\n          \"/>\n      </n-tab-pane>\n      <n-tab-pane name=\"myTranslate\" :tab=\"t('tab.myTranslate')\">\n        <n-data-table\n          :columns=\"musicColumns\"\n          :data=\"music.myTranslate\"\n          :bordered=\"false\"\n          :min-row-height=\"48\"\n          :max-height=\"490\"\n          :virtual-scroll=\"music.myTranslate?.length > 7\"\n          :row-props=\"MusicSelect\"\n          row-class-name=\"td_css\"\n          style=\"\n            --n-td-color: rgba(57, 57, 62, 0);\n            --n-th-color-hover: rgba(57, 57, 62, 0);\n            --n-th-color: rgba(57, 57, 62, 0);\n            --n-td-color-hover: rgba(0, 0, 0, 0.2);\n          \"/>\n      </n-tab-pane>\n      <n-tab-pane name=\"myFavorite\" :tab=\"t('tab.myFavorite')\">\n        <n-data-table\n          :columns=\"favoritColumns\"\n          :data=\"music.myFavorite\"\n          :bordered=\"false\"\n          :min-row-height=\"48\"\n          :max-height=\"490\"\n          :virtual-scroll=\"music.myFavorite?.length > 7\"\n          :row-props=\"MusicSelect\"\n          row-class-name=\"td_css\"\n          style=\"\n            --n-td-color: rgba(57, 57, 62, 0);\n            --n-th-color-hover: rgba(57, 57, 62, 0);\n            --n-th-color: rgba(57, 57, 62, 0);\n            --n-td-color-hover: rgba(0, 0, 0, 0.2);\n          \"/>\n      </n-tab-pane>\n      <template #suffix>\n        <n-input\n          v-model:value=\"searchText\"\n          round\n          :placeholder=\"t('tab.search')\"\n          style=\"top: -4px; width: 25vh; margin-left: 5px\"\n        >\n          <template #suffix>\n            <n-icon :component=\"Search\" />\n          </template>\n        </n-input>\n      </template>\n    </n-tabs>\n  </n-card>\n</template>\n\n<script lang=\"ts\" setup>\nimport { getList, sendData } from \"@renderer/utils/fetchUtils\";\nimport { RowData } from \"naive-ui/es/data-table/src/interface\";\nimport { h, reactive, ref, watch } from \"vue\";\nimport { useMessage, NButton } from \"naive-ui\";\nimport { Search } from \"@vicons/ionicons5\";\nimport { debounce } from \"lodash-es\";\nimport { useI18n } from \"vue-i18n\";\nconst { t } = useI18n();\nconst message = useMessage();\n\nconst music: any = reactive({\n  // 音乐列表\n  systemMusic: [], // 原版音乐\n  myImport: [], // 导入的音乐\n  myTranslate: [], // 扒谱的音乐\n  myFavorite: [],\n});\nconst nowPlayMusic = ref(t('tutorial.no_music')); // 当前选中歌曲\nconst nowSelectMusicTruth = ref('') // 当前选中歌曲真实名称\nlet nowType = \"systemMusic\";\nconst searchText = ref(\"\");\nconst musicColumns = [\n  {\n    title: t(\"columns.name\"),\n    key: \"name\",\n    className: \"th_css\",\n    resizable: true,\n  },\n  {\n    title: t(\"columns.total_duration\"),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n]; // 音乐列\n\nfunction timeToSeconds(timeString) {\n    var splitTime = timeString.split(':');\n\n    // 如果是 HH:MM:SS 格式\n    if (splitTime.length === 3) {\n        var hours = parseInt(splitTime[0], 10);\n        var minutes = parseInt(splitTime[1], 10);\n        var seconds = parseInt(splitTime[2], 10);\n        return hours * 3600 + minutes * 60 + seconds;\n    }\n\n    // 如果是 MM:SS 格式\n    if (splitTime.length === 2) {\n        var minutes = parseInt(splitTime[0], 10);\n        var seconds = parseInt(splitTime[1], 10);\n        return minutes * 60 + seconds;\n    }\n\n    return 0; // 如果格式不正确，返回0\n}\n\n// 进程标记\nconst processFlag = ref(false)\n\n/**\n * 发送扒谱转换请求\n */\n async function transfer() {\n  if (nowPlayMusic.value === t(\"tutorial.no_music\")) {\n    message.warning(t(\"tutorial.chose_music\"))\n    return\n  }\n\n  try {\n    await sendData('config_operate', {\n      fileName: nowSelectMusicTruth.value,\n      type: nowType,\n      operate: 'convert_sheet'\n    })\n    message.success(t(\"tutorial.save_desktop\"))\n  } catch (error) {\n    console.error(t(\"tutorial.error_console\"), error)\n    message.error(t(\"tutorial.error\"))\n  }\n}\n\n\nconst musicSystemColumns = [\n  {\n    title: t(\"columns.name\"),\n    key: 'name',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },\n  {\n    title: t(\"columns.total_duration\"),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n  {\n    title: t(\"columns.operation\"),\n    key: 'operation',\n    width: 60,\n    className: 'th_css',\n    render(row) {\n      return h(\n        NButton,\n        {\n          size: 'medium',\n          text: true,\n          onClick: () => {\n            heartClick(row.truthName, true)\n            window.api.sync_sheet_2_el()\n          }\n        },\n        {\n          default: () => {\n            return music.myFavorite.filter((res) => {\n              return res.name.replaceAll('.mp3').includes(row.name)\n            }).length == 0\n              ? '❤'\n              : null\n          }\n        }\n      )\n    }\n  }\n]\n\nconst favoritColumns = [\n  {\n    title: t(\"columns.name\"),\n    key: 'name',\n    resizable: true,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    }\n  },\n  {\n    title: t(\"columns.total_duration\"),\n    key: 'total_duration',\n    width: 80,\n    className: 'th_css',\n    ellipsis: {\n      tooltip: true\n    },\n    sorter: (row1, row2) => timeToSeconds(row1.total_duration) - timeToSeconds(row2.total_duration)\n  },\n  {\n    title: t(\"columns.operation\"),\n    key: 'operation',\n    width: 60,\n    className: 'th_css',\n    render(row) {\n      return h(\n        NButton,\n        {\n          size: 'medium',\n          text: true,\n          onClick: () => {\n            heartClick(row.truthName, false)\n            window.api.sync_sheet_2_el()\n          }\n        },\n        {\n          default: () => {\n            return '💔'\n          }\n        }\n      )\n    }\n  }\n]\n\n// 收藏点击处理\nfunction heartClick(name, state) {\n  if (state) {\n    sendData('config_operate', {\n      fileName: name,\n      type: nowType,\n      operate: 'favorite_music'\n    }).then(() => {\n      handleUpdateValue('myFavorite')\n      handleUpdateValue(nowType)\n      message.success(t(\"tab.love_success\"))\n    })\n  } else {\n    sendData('config_operate', {\n      fileName: name,\n      type: 'myFavorite',\n      operate: \"drop_file\"\n    }).then(() => {\n      handleUpdateValue('myFavorite')\n      message.success(t(\"tab.remove_success\"))\n    })\n  }\n}\n\nconst MusicSelect = (row: RowData) => {\n  return {\n    onClick: () => {\n      nowPlayMusic.value = row.name;\n      nowSelectMusicTruth.value = row.truthName;\n    },\n  };\n};\n\nfunction handleUpdateValue(value: string) {\n  searchText.value = \"\";\n  getListData(value);\n}\n\nfunction handleBeforeLeave(name: string) {\n  nowType = name;\n  return true;\n}\n\nconst fetchListData = debounce(() => {\n  getListData('myFavorite');\n  getListData('systemMusic');\n  getListData('myImport');\n  getListData('myTranslate');\n}, 200);\nwatch(searchText, fetchListData)\n\nfunction followTutorial() {\n  if (nowPlayMusic.value === t(\"tutorial.no_music\")) {\n    message.error(t(\"messeage.choose_plz\"));\n    return;\n  } else {\n    sendData(\"follow\", {\n      fileName: nowSelectMusicTruth.value,\n      type: nowType,\n      operate: \"setSheet\",\n    }).then(() => {\n      sendData(\"follow\", {\n        operate: \"openFollow\",\n      });\n    });\n  }\n}\nhandleUpdateValue(\"myFavorite\");\nhandleUpdateValue(\"systemMusic\");\n\nfunction getListData(value) {\n  getList(value, searchText.value).then((_res) => {\n    eval(\"music.\" + value + \"=_res\");\n  });\n}\n</script>\n\n<style scoped>\n:deep(.n-tabs-bar) {\n  --n-bar-color: rgb(242, 232, 196) !important;\n}\n:deep(.n-tabs) {\n  --n-tab-text-color-active: rgb(242, 232, 196) !important;\n  --n-tab-text-color-hover: rgb(242, 232, 196) !important;\n  --n-tab-text-color: rgb(221, 242, 196) !important;\n}\n.n-input {\n  background-color: rgba(24, 24, 28, 0) !important;\n  border: 1px solid rgba(242, 232, 196, 0.5);\n}\n:deep(.n-input){\n  --n-border-hover: 1px solid rgb(242,232,196)!important;\n  --n-border-focus: 1px solid rgb(242,232,196)!important;\n  --n-caret-color: rgb(242,232,196)!important;\n  --n-color-focus: rgba(242,232,196,0.1)!important;\n  --n-text-color: rgb(242,232,196) !important;\n}\n:deep(.td_css td) {\n  color: rgb(242, 232, 196) !important;\n}\n:deep(.th_css) {\n  color: rgb(221, 242, 196) !important;\n}\n</style>\n"
  },
  {
    "path": "sky-music-web/tsconfig.json",
    "content": "{\n  \"files\": [],\n  \"references\": [{ \"path\": \"./tsconfig.node.json\" }, { \"path\": \"./tsconfig.web.json\" }]\n}\n"
  },
  {
    "path": "sky-music-web/tsconfig.node.json",
    "content": "{\n  \"extends\": \"@electron-toolkit/tsconfig/tsconfig.node.json\",\n  \"include\": [\"electron.vite.config.*\", \"src/main/**/*\", \"src/preload/**/*\"],\n  \"compilerOptions\": {\n    \"composite\": true,\n    \"types\": [\"electron-vite/node\"]\n  }\n}\n"
  },
  {
    "path": "sky-music-web/tsconfig.web.json",
    "content": "{\n  \"extends\": \"@electron-toolkit/tsconfig/tsconfig.web.json\",\n  \"include\": [\n    \"src/renderer/src/env.d.ts\",\n    \"src/renderer/src/**/*\",\n    \"src/renderer/src/**/*.vue\",\n    \"src/preload/*.d.ts\"\n  ],\n  \"compilerOptions\": {\n    \"composite\": true,\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"@renderer/*\": [\n        \"src/renderer/src/*\"\n      ]\n    },\n    \"noUnusedLocals\":false\n  }\n}\n"
  },
  {
    "path": "template-resources/myFavorite/.keep",
    "content": ""
  },
  {
    "path": "template-resources/myImport/.keep",
    "content": ""
  },
  {
    "path": "template-resources/myTranslate/.keep",
    "content": ""
  },
  {
    "path": "template-resources/systemTools/drawTool/.keep",
    "content": ""
  },
  {
    "path": "template-resources/systemTools/modelData/demoScheenshot/.keep",
    "content": ""
  },
  {
    "path": "template-resources/systemTools/scriptTemplate/.keep",
    "content": ""
  },
  {
    "path": "template-resources/translateMID/.keep",
    "content": ""
  },
  {
    "path": "template-resources/translateOriginalMusic/.keep",
    "content": ""
  }
]