.
```
## /README.md

# AI Audio&Video Translation and Dubbing Tool

**[English](./README.md)|[简体中文](./docs/README_zh.md)|[日本語](./docs/README_jp.md)|[한국어](./docs/README_kr.md)|[Tiếng Việt](./docs/README_vi.md)|[Français](./docs/README_fr.md)|[Deutsch](./docs/README_de.md)|[Español](./docs/README_es.md)|[Português](./docs/README_pt.md)|[Русский](./docs/README_rus.md)|[اللغة العربية](./docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
[](https://jq.qq.com/?_wv=1027&k=754069680)
### 📢 New Release for Win & Mac Desktop Version – Welcome to Test and Provide Feedback
## Overview
Krillin AI is an all-in-one solution for effortless video localization and enhancement. This minimalist yet powerful tool handles everything from translation, dubbing to voice cloning,formatting—seamlessly converting videos between landscape and portrait modes for optimal display across all content platforms(YouTube, TikTok, Bilibili, Douyin, WeChat Channel, RedNote, Kuaishou). With its end-to-end workflow, Krillin AI transforms raw footage into polished, platform-ready content in just a few clicks.
## Key Features:
🎯 **One-Click Start** - Launch your workflow instantly,New desktop version available—easier to use!
📥 **Video download** - yt-dlp and local file uploading supported
📜 **Precise Subtitles** - Whisper-powered high-accuracy recognition
🧠 **Smart Segmentation** - LLM-based subtitle chunking & alignment
🌍 **Professional Translation** - Paragraph-level translation for consistency
🔄 **Term Replacement** - One-click domain-specific vocabulary swap
🎙️ **Dubbing and Voice Cloning** - CosyVoice selected or cloning voices
🎬 **Video Composition** - Auto-formatting for horizontal/vertical layouts
## Showcase
The following picture demonstrates the effect after the subtitle file, which was generated through a one-click operation after importing a 46-minute local video, was inserted into the track. There was no manual adjustment involved at all. There are no missing or overlapping subtitles, the sentence segmentation is natural, and the translation quality is also quite high.

### Subtitle Translation
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### Dubbing
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### Portrait
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 Speech Recognition Support
_**All local models in the table below support automatic installation of executable files + model files. Just make your selection, and KrillinAI will handle everything else for you.**_
| Service | Supported Platforms | Model Options | Local/Cloud | Notes |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | Cross-platform | - | Cloud | Fast with excellent results |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (recommend medium+) | Local | Faster speed, no cloud service overhead |
| **WhisperKit** | macOS (Apple Silicon only) | `large-v2` | Local | Native optimization for Apple chips |
| **Alibaba Cloud ASR** | Cross-platform | - | Cloud | Bypasses China mainland network issues |
## 🚀 Large Language Model Support
✅ Compatible with all **OpenAI API-compatible** cloud/local LLM services including but not limited to:
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- Self-hosted open-source models
- Other OpenAI-format compatible API services
## 🌍 Language Support
Input language support: Chinese, English, Japanese, German, Turkish, Korean, Russian, Malay (continuously expanding)
Translation languages: 101 languages supported, including English, Chinese, Russian, Spanish, French, etc.
## Interface Preview

## 🚀 Quick Start
### Basic Steps
First, download the Release executable file that matches your device's system. Follow the instructions below to choose between the desktop or non-desktop version, then place the software in an empty folder. Running the program will generate some directories, so keeping it in an empty folder makes management easier.
[For the desktop version (release files with "desktop" in the name), refer here]
_The desktop version is newly released to address the difficulty beginners face in editing configuration files correctly. It still has some bugs and is being continuously updated._
Double-click the file to start using it. (The desktop version also requires configuration, which is done within the software.)
[For the non-desktop version (release files without "desktop" in the name), refer here]
_The non-desktop version is the original release, with more complex configuration but stable functionality. It is also suitable for server deployment, as it provides a web-based UI._
Create a `config` folder in the directory, then create a `config.toml` file inside it. Copy the contents of the `config-example.toml` file from the source code's `config` directory into your `config.toml` and fill in your configuration details.
Double-click the executable or run it in the terminal to start the service.
Open your browser and enter http://127.0.0.1:8888 to begin using it. (Replace 8888 with the port number you specified in the config file.)
### To: macOS Users
[For the desktop version, i.e., release files with "desktop" in the name, refer here]
The current packaging method for the desktop version cannot support direct double-click execution or DMG installation due to signing issues. Manual trust configuration is required as follows:
1. Open the directory containing the executable file (assuming the filename is KrillinAI_1.0.0_desktop_macOS_arm64) in Terminal
2. Execute the following commands sequentially:
```
sudo xattr -cr ./KrillinAI_1.0.0_desktop_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_desktop_macOS_arm64
./KrillinAI_1.0.0_desktop_macOS_arm64
```
[For the non-desktop version, i.e., release files without "desktop" in the name, refer here]
This software is not signed, so after completing the file configuration in the "Basic Steps," you will need to manually trust the application on macOS. Follow these steps:
1. Open the terminal and navigate to the directory where the executable file (assuming the file name is `KrillinAI_1.0.0_macOS_arm64`) is located.
2. Execute the following commands in sequence:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
This will start the service.
### Docker Deployment
This project supports Docker deployment. Please refer to the [Docker Deployment Instructions](./docs/docker.md).
### Cookie Configuration Instructions
If you encounter video download failures, please refer to the [Cookie Configuration Instructions](./docs/get_cookies.md) to configure your cookie information.
### Configuration Help
The quickest and most convenient configuration method:
* Select `openai` for both `transcription_provider` and `llm_provider`. In this way, you only need to fill in `openai.apikey` in the following three major configuration item categories, namely `openai`, `local_model`, and `aliyun`, and then you can conduct subtitle translation. (Fill in `app.proxy`, `model` and `openai.base_url` as per your own situation.)
The configuration method for using the local speech recognition model (macOS is not supported for the time being) (a choice that takes into account cost, speed, and quality):
* Fill in `fasterwhisper` for `transcription_provider` and `openai` for `llm_provider`. In this way, you only need to fill in `openai.apikey` and `local_model.faster_whisper` in the following three major configuration item categories, namely `openai` and `local_model`, and then you can conduct subtitle translation. The local model will be downloaded automatically. (The same applies to `app.proxy` and `openai.base_url` as mentioned above.)
The following usage situations require the configuration of Alibaba Cloud:
* If `llm_provider` is filled with `aliyun`, it indicates that the large model service of Alibaba Cloud will be used. Consequently, the configuration of the `aliyun.bailian` item needs to be set up.
* If `transcription_provider` is filled with `aliyun`, or if the "voice dubbing" function is enabled when starting a task, the voice service of Alibaba Cloud will be utilized. Therefore, the configuration of the `aliyun.speech` item needs to be filled in.
* If the "voice dubbing" function is enabled and local audio files are uploaded for voice timbre cloning at the same time, the OSS cloud storage service of Alibaba Cloud will also be used. Hence, the configuration of the `aliyun.oss` item needs to be filled in.
Configuration Guide: [Alibaba Cloud Configuration Instructions](./docs/aliyun.md)
## Frequently Asked Questions
Please refer to [Frequently Asked Questions](./docs/faq.md)
## Contribution Guidelines
- Do not submit unnecessary files like `.vscode`, `.idea`, etc. Please make good use of `.gitignore` to filter them.
- Do not submit `config.toml`; instead, submit `config-example.toml`.
## Star History
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /cmd/desktop/main.go
```go path="/cmd/desktop/main.go"
package main
import (
"go.uber.org/zap"
"krillin-ai/config"
"krillin-ai/internal/desktop"
"krillin-ai/internal/server"
"krillin-ai/log"
"os"
)
func main() {
log.InitLogger()
defer log.GetLogger().Sync()
config.LoadConfig()
if config.Conf.App.TranscribeProvider == "" || config.Conf.App.LlmProvider == "" {
// 确保有最基础的配置
config.Conf.App.TranscribeProvider = "openai"
config.Conf.App.LlmProvider = "openai"
err := config.SaveConfig()
if err != nil {
log.GetLogger().Error("保存配置失败", zap.Error(err))
os.Exit(1)
}
}
config.LoadConfig()
go func() {
if err := server.StartBackend(); err != nil {
log.GetLogger().Error("后端服务启动失败", zap.Error(err))
os.Exit(1)
}
}()
desktop.Show()
}
```
## /cmd/server/main.go
```go path="/cmd/server/main.go"
package main
import (
"go.uber.org/zap"
"krillin-ai/config"
"krillin-ai/internal/deps"
"krillin-ai/internal/server"
"krillin-ai/log"
"os"
)
func main() {
log.InitLogger()
defer log.GetLogger().Sync()
var err error
config.LoadConfig()
if err = config.CheckConfig(); err != nil {
log.GetLogger().Error("加载配置失败", zap.Error(err))
return
}
if err = deps.CheckDependency(); err != nil {
log.GetLogger().Error("依赖环境准备失败", zap.Error(err))
return
}
if err = server.StartBackend(); err != nil {
log.GetLogger().Error("后端服务启动失败", zap.Error(err))
os.Exit(1)
}
}
```
## /config/config-example.toml
```toml path="/config/config-example.toml"
[app]
segment_duration = 5 # 音频切分处理间隔,单位:分钟,建议值:5-10,如果视频中话语较少可以适当提高
translate_parallel_num = 5 # 并发进行模型转录和翻译的数量上限,建议值:5,如果使用了本地模型,该项自动不生效
proxy = "" # 网络代理地址,格式如http://127.0.0.1:7890,可不填
transcribe_provider = "openai" # 语音识别,当前可选值:openai,fasterwhisper,whisperkit,whisper.cpp,aliyun。(fasterwhisper不支持macOS,whisperkit只支持M芯片)
llm_provider = "openai" # LLM,当前可选值:openai,aliyun
[server]
host = "127.0.0.1"
port = 8888
# 下方的配置非必填,请结合上方的选项和文档说明进行配置
[local_model]
fasterwhisper = "large-v2" # fasterwhisper的本地模型可选值:tiny,medium,large-v2,建议medium及以上
whisperkit = "large-v2" # whisperkit的本地模型可选值:large-v2
whispercpp = "large-v2" # whisper.cpp的本地模型
[openai]
base_url = "" # OpenAI API 自定义base url,可配合转发站密钥使用,留空为默认API地址
model = "" # 指定模型名,可通过此字段结合base_url使用外部任何与OpenAI API兼容的大模型服务,留空默认为gpt-4o-mini
api_key = "sk-XXX" # OpenAI API密钥
[openai.whisper] # 由于使用whisperAPI进行语音识别时,上方可能配置使用了OpenAI格式兼容的其它厂商的模型,所以此处需要独立填入openai的配置信息
base_url = ""
api_key = ""
[aliyun] # 具体请参考文档中的“阿里云配置说明”
[aliyun.oss]
access_key_id = ""
access_key_secret = ""
bucket = ""
[aliyun.speech]
access_key_id = ""
access_key_secret = ""
app_key= ""
[aliyun.bailian]
api_key = ""
```
## /config/config.go
```go path="/config/config.go"
package config
import (
"errors"
"fmt"
"github.com/BurntSushi/toml"
"go.uber.org/zap"
"krillin-ai/log"
"net/url"
"os"
"path/filepath"
"runtime"
)
type App struct {
SegmentDuration int `toml:"segment_duration"`
TranslateParallelNum int `toml:"translate_parallel_num"`
Proxy string `toml:"proxy"`
ParsedProxy *url.URL `toml:"-"`
TranscribeProvider string `toml:"transcribe_provider"`
LlmProvider string `toml:"llm_provider"`
}
type Server struct {
Host string `toml:"host"`
Port int `toml:"port"`
}
type LocalModel struct {
Fasterwhisper string `toml:"fasterwhisper"`
Whisperkit string `toml:"whisperkit"`
Whispercpp string `toml:"whispercpp"`
}
type OpenAiWhisper struct {
BaseUrl string `toml:"base_url"`
ApiKey string `toml:"api_key"`
}
type Openai struct {
BaseUrl string `toml:"base_url"`
Model string `toml:"model"`
ApiKey string `toml:"api_key"`
Whisper OpenAiWhisper `toml:"whisper"`
}
type AliyunOss struct {
AccessKeyId string `toml:"access_key_id"`
AccessKeySecret string `toml:"access_key_secret"`
Bucket string `toml:"bucket"`
}
type AliyunSpeech struct {
AccessKeyId string `toml:"access_key_id"`
AccessKeySecret string `toml:"access_key_secret"`
AppKey string `toml:"app_key"`
}
type AliyunBailian struct {
ApiKey string `toml:"api_key"`
}
type Aliyun struct {
Oss AliyunOss `toml:"oss"`
Speech AliyunSpeech `toml:"speech"`
Bailian AliyunBailian `toml:"bailian"`
}
type Config struct {
App App `toml:"app"`
Server Server `toml:"server"`
LocalModel LocalModel `toml:"local_model"`
Openai Openai `toml:"openai"`
Aliyun Aliyun `toml:"aliyun"`
}
var Conf = Config{
App: App{
SegmentDuration: 5,
TranslateParallelNum: 5,
TranscribeProvider: "openai",
LlmProvider: "openai",
},
Server: Server{
Host: "127.0.0.1",
Port: 8888,
},
LocalModel: LocalModel{
Fasterwhisper: "large-v2",
Whisperkit: "large-v2",
Whispercpp: "large-v2",
},
}
// 检查必要的配置是否完整
func validateConfig() error {
// 检查转写服务提供商配置
switch Conf.App.TranscribeProvider {
case "openai":
if Conf.Openai.Whisper.ApiKey == "" {
return errors.New("使用OpenAI转写服务需要配置 OpenAI API Key")
}
case "fasterwhisper":
if Conf.LocalModel.Fasterwhisper != "tiny" && Conf.LocalModel.Fasterwhisper != "medium" && Conf.LocalModel.Fasterwhisper != "large-v2" {
return errors.New("检测到开启了fasterwhisper,但模型选型配置不正确,请检查配置")
}
case "whisperkit":
Conf.App.TranslateParallelNum = 1
if runtime.GOOS != "darwin" {
log.GetLogger().Error("whisperkit只支持macos", zap.String("当前系统", runtime.GOOS))
return fmt.Errorf("whisperkit只支持macos")
}
if Conf.LocalModel.Whisperkit != "large-v2" {
return errors.New("检测到开启了whisperkit,但模型选型配置不正确,请检查配置")
}
case "whispercpp":
if runtime.GOOS != "windows" { // 当前先仅支持win,模型仅支持large-v2,最小化产品
log.GetLogger().Error("whispercpp only support windows", zap.String("current os", runtime.GOOS))
return fmt.Errorf("whispercpp only support windows")
}
if Conf.LocalModel.Whispercpp != "large-v2" {
return errors.New("检测到开启了whisper.cpp,但模型选型配置不正确,请检查配置")
}
case "aliyun":
if Conf.Aliyun.Speech.AccessKeyId == "" || Conf.Aliyun.Speech.AccessKeySecret == "" || Conf.Aliyun.Speech.AppKey == "" {
return errors.New("使用阿里云语音服务需要配置相关密钥")
}
default:
return errors.New("不支持的转录提供商")
}
// 检查LLM提供商配置
switch Conf.App.LlmProvider {
case "openai":
if Conf.Openai.ApiKey == "" {
return errors.New("使用OpenAI LLM服务需要配置 OpenAI API Key")
}
case "aliyun":
if Conf.Aliyun.Bailian.ApiKey == "" {
return errors.New("使用阿里云百炼服务需要配置 API Key")
}
default:
return errors.New("不支持的LLM提供商")
}
return nil
}
func LoadConfig() {
var err error
configPath := "./config/config.toml"
if _, err = os.Stat(configPath); os.IsNotExist(err) {
return
} else {
log.GetLogger().Info("已找到配置文件,从配置文件中加载配置")
if _, err = toml.DecodeFile(configPath, &Conf); err != nil {
log.GetLogger().Error("加载配置文件失败", zap.Error(err))
return
}
}
}
// 验证配置
func CheckConfig() error {
var err error
// 解析代理地址
Conf.App.ParsedProxy, err = url.Parse(Conf.App.Proxy)
if err != nil {
return err
}
return validateConfig()
}
// SaveConfig 保存配置到文件
func SaveConfig() error {
configPath := filepath.Join("config", "config.toml")
if _, err := os.Stat(configPath); os.IsNotExist(err) {
err = os.MkdirAll(filepath.Dir(configPath), os.ModePerm)
if err != nil {
return err
}
}
data, err := toml.Marshal(Conf)
if err != nil {
return err
}
err = os.WriteFile(configPath, data, 0644)
if err != nil {
return err
}
return nil
}
```
## /docs/README_ar.md

# أداة ترجمة ودبلجة الصوت والفيديو بالذكاء الاصطناعي

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
### إصدار جديد لنظامي ويندوز وماك - مرحبًا باختباره وتقديم الملاحظات
## نظرة عامة
كريلين AI هو حل متكامل لتحسين وتوطين الفيديوهات بسهولة. هذه الأداة البسيطة لكن القوية تتعامل مع كل شيء من الترجمة والدبلجة إلى استنساخ الأصوات، وإعادة التنسيق - حيث تقوم بتحويل الفيديوهات بسلاسة بين الوضع الأفقي والعمودي لعرض مثالي على جميع منصات المحتوى (يوتيوب، تيك توك، بيلبلي، دويين، قناة وي تشات، ريد نوت، كوايشو). من خلال سير العمل الشامل، يحوّل كريلين AI اللقطات الخام إلى محتوى نهائي وجاهز للنشر ببضع نقرات فقط.
الميزات الرئيسية:
🎯 بدء بنقرة واحدة - ابدأ سير العمل فورًا، النسخة الجديدة لسطح المكتب متاحة الآن - أسهل في الاستخدام!
📥 تنزيل الفيديو - يدعم yt-dlp ورفع الملفات المحلية
📜 ترجمات دقيقة - تعتمد على Whisper للتعرف عالي الدقة
🧠 تقسيم ذكي - تجزئة المحاذاة التلقائية للترجمات بناءً على نماذج اللغات الكبيرة (LLM)
🌍 ترجمة احترافية - ترجمة على مستوى الفقرات للحفاظ على الاتساق
🔄 استبدال المصطلحات - تبديل المفردات المتخصصة بنقرة واحدة
🎙️ الدبلجة واستنساخ الأصوات - اختيار أصوات CosyVoice أو استنساخ الأصوات
🎬 تكوين الفيديو - إعادة التنسيق التلقائي للوضع الأفقي/العمودي
## عرض توضيحي
الصورة التالية توضح النتيجة بعد إدراج ملف الترجمة - الذي تم إنشاؤه بنقرة واحدة بعد استيراد فيديو محلي مدته 46 دقيقة - في المسار. لم يتم إجراء أي تعديل يدوي على الإطلاق. لا توجد ترجمات ناقصة أو متداخلة، وتقسيم الجمل طبيعي، وجودة الترجمة عالية جدًا.

### ترجمة الترجمة النصية
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### الدبلجة
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### الوضع العمودي
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 دعم التعرف على الصوت
_**جميع النماذج المحلية في الجدول أدناه تدعم التثبيت التلقائي للملفات التنفيذية + ملفات النماذج. فقط قم باختيارك، وسيتولى KrillinAI كل شيء آخر لك.**_
| Service | Supported Platforms | Model Options | Local/Cloud | Notes |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | Cross-platform | - | Cloud | Fast with excellent results |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (recommend medium+) | Local | Faster speed, no cloud service overhead |
| **WhisperKit** | macOS (Apple Silicon only) | `large-v2` | Local | Native optimization for Apple chips |
| **Alibaba Cloud ASR** | Cross-platform | - | Cloud | Bypasses China mainland network issues |
## 🚀 دعم نماذج اللغة الكبيرة
✅ متوافق مع جميع خدمات المتوافقة مع OpenAI API السحابية/المحلية بما في ذلك على سبيل المثال لا الحصر:
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- Self-hosted open-source models
- Other OpenAI-format compatible API services
## 🌍 اللغات المدعومة
لغات الإدخال: الصينية، الإنجليزية، اليابانية، الألمانية، التركية (مع إضافة المزيد من اللغات قريبًا)
لغات الترجمة: 101 لغة مدعومة، بما في ذلك الإنجليزية، الصينية، الروسية، الإسبانية، الفرنسية، وغيرها.
## معاينة الواجهة

## 🚀 بدء سريع
### الخطوات الأساسية
أولاً، قم بتنزيل ملف الإصدار التنفيذي الذي يتوافق مع نظام جهازك. اتبع التعليمات أدناه للاختيار بين نسخة سطح المكتب أو النسخة العادية، ثم ضع البرنامج في مجلد فارغ. عند تشغيل البرنامج، سيتم إنشاء بعض المجلدات تلقائياً، لذا فإن وضعه في مجلد فارغ يجعل إدارته أسهل.
[For the desktop version (release files with "desktop" in the name), refer here]
_The desktop version is newly released to address the difficulty beginners face in editing configuration files correctly. It still has some bugs and is being continuously updated._
انقر نقرًا مزدوجًا على الملف لبدء استخدامه.
[لنسخة غير سطح المكتب (ملفات الإصدار التي لا تحتوي على "desktop" في الاسم)، ارجع إلى هنا]
_تعتبر نسخة غير سطح المكتب هي الإصدار الأصلي، تتميز بإعدادات أكثر تعقيدًا ولكن بوظائف مستقرة. وهي مناسبة أيضًا للنشر على الخوادم، حيث توفر واجهة مستخدم تعمل عبر الويب._
قم بإنشاء مجلد `config` في الدليل، ثم أنشئ ملف `config.toml` بداخله. انسخ محتويات ملف `config-example.toml` من مجلد `config` في الكود المصدقي إلى ملف `config.toml` الخاص بك وقم بملء تفاصيل الإعدادات. (إذا كنت ترغب في استخدام نماذج OpenAI ولكنك لا تعرف كيفية الحصول على مفتاح، يمكنك الانضمام إلى المجموعة للحصول على وصول تجريبي مجاني.)
انقر نقرًا مزدوجًا على الملف التنفيذي أو قم بتشغيله في الطرفية لبدء الخدمة.
افتح متصفحك وأدخل http://127.0.0.1:8888 لبدء استخدامه. (استبدل 8888 برقم المنفذ الذي حددته في ملف الإعدادات.)
### إلى: مستخدمي نظام macOS
[لنسخة سطح المكتب (أي ملفات الإصدار التي تحتوي على "desktop" في الاسم)، ارجع هنا]
طريقة التغليف الحالية لنسخة سطح المكتب لا تدعم التشغيل المباشر بالنقر المزدوج أو التثبيت عبر DMG بسبب مشاكل التوقيع. يتطلب ذلك إعداد الثقة يدوياً كما يلي:
1. افتح المجلد الذي يحتوي على الملف التنفيذي (لنفترض أن اسم الملف هو KrillinAI_1.0.0_desktop_macOS_arm64) في Terminal
2. نفّذ الأوامر التالية بالتسلسل:
```
sudo xattr -cr ./KrillinAI_1.0.0_desktop_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_desktop_macOS_arm64
./KrillinAI_1.0.0_desktop_macOS_arm64
```
[للنسخة العادية (ملفات الإصدار التي لا تحتوي على "desktop" في الاسم)، راجع هنا]
هذا البرنامج غير موقّع، لذا بعد إكمال إعداد الملفات وفق "الخطوات الأساسية"، ستحتاج إلى منح الثقة يدوياً للتطبيق على نظام macOS. اتبع هذه الخطوات:
1. افتح Terminal وانتقل إلى المجلد الذي يحتوي على الملف التنفيذي (لنفترض أن اسم الملف هو KrillinAI_1.0.0_macOS_arm64).
2. نفّذ الأوامر التالية بالتسلسل:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
سيؤدي هذا إلى بدء تشغيل الخدمة.
### النشر باستخدام Docker
هذا المشروع يدعم النشر عبر يُرجى الرجوع إلى [Docker Deployment Instructions](../docs/docker.md).
### تعليمات إعداد Cookie
إذا واجهت فشلًا في تنزيل الفيديو، يُرجى الرجوع إلى تعليمات إعداد Cookie لتهيئة معلومات الـ Cookie الخاصة بك.
(ملاحظة: تم الحفاظ على نفس تنسيق الروابط والعناوين كما في النص الأصلي)
### مساعدة في الإعدادات
أسرع وأكثر طريقة ملائمة للإعداد:
* د openai لكل من transcription_provider و llm_provider. بهذه الطريقة، تحتاج فقط إلى ملء openai.apikey في الفئات الثلاث الرئيسية لبنود الإعداد التالية، وهي openai، local_model، و aliyun، ثم يمكنك إجراء ترجمة الترجمة النصية. (املأ app.proxy، model و openai.base_url حسب حالتك الخاصة.)
طريقة الإعداد لاستخدام نموذج التعرف على الكلام المحلي (غير مدعوم على macOS في الوقت الحالي) (خيار يأخذ في الاعتبار التكلفة والسرعة والجودة):
* املأ fasterwhisper لـ transcription_provider و openai لـ llm_provider. بهذه الطريقة، تحتاج فقط إلى ملء openai.apikey و local_model.faster_whisper في الفئتين الرئيسيتين لبنود الإعداد التالية، وهما openai و local_model، ثم يمكنك إجراء ترجمة الترجمة النصية. سيتم تنزيل النموذج المحلي تلقائيًا. (ينطبق نفس الأمر على app.proxy و openai.base_url كما ذكر أعلاه.)
حالات الاستخدام التي تتطلب إعدادات علي بابا السحابية
* إذا تم تعيين llm_provider إلى aliyun، فهذا يعني أنه سيتم استخدام خدمة النماذج الكبيرة من علي بابا السحابية. وبالتالي، يجب إعداد عنصر aliyun.bailian في الإعدادات.
* إذا تم تعيين transcription_provider إلى aliyun، أو إذا تم تمكين وظيفة "الدبلجة الصوتية" عند بدء المهمة، فسيتم استخدام خدمة الصوت من علي بابا السحابية. لذلك، يجب ملء عنصر aliyun.speech في الإعدادات.
* إذا تم تمكين وظيفة "الدبلجة الصوتية" وتم تحميل ملفات صوتية محلية لاستنساخ نبرة الصوت في نفس الوقت، فسيتم أيضًا استخدام خدمة التخزين السحابي OSS من علي بابا السحابية. وبالتالي، يجب ملء عنصر aliyun.oss في الإعدادات.
دليل الإعدادات: [Alibaba Cloud Configuration Instructions](../docs/aliyun.md)
## الأسئلة الشائعة
يُرجى الرجوع إلى [Frequently Asked Questions](../docs/faq.md)
## إرشادات المساهمة
- لا تقم بإرسال ملفات غير ضرورية مثل .vscode، .idea، وغيرها. يُرجى استخدام .gitignore بشكل صحيح لتصفيتها.
- لا تقم بإرسال ملف config.toml؛ بدلاً من ذلك، قم بإرسال ملف config-example.toml.
## تاريخ النجوم
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_de.md

# KI-Audio- & Video-Übersetzungs- und Synchronisationstool

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
### 📢 Neue Version für Windows & Mac Desktop – Willkommen zum Testen und Feedbackgeben
## Überblick
Krillin AI ist eine All-in-One-Lösung für mühelose Video-Lokalisierung und -Optimierung. Dieses minimalistisch gestaltete, aber leistungsstarke Tool übernimmt alles von Übersetzung, Synchronisation bis hin zu Sprachklonierung und Formatierung – es wandelt Videos nahtlos zwischen Quer- und Hochformat um, um eine optimale Darstellung auf allen Content-Plattformen zu gewährleisten (YouTube, TikTok, Bilibili, Douyin, WeChat Channel, RedNote, Kuaishou). Mit seinem End-to-End-Workflow verwandelt Krillin AI Rohmaterial in nur wenigen Klicks in aufbereitete, plattformfertige Inhalte.
## Hauptfunktionen:
🎯 **Ein-Klick-Start** - Sofortiger Workflow-Beginn, neue Desktop-Version noch benutzerfreundlicher!
📥 **Video-Download** - Unterstützt yt-dlp und lokale Datei-Uploads
📜 **Präzise Untertitel** - Hochgenaue Whisper-Erkennungstechnologie
🧠 **Intelligente Segmentierung** - LLM-basierte Unterteilungs- und Ausrichtungstechnologie
🌍 **Professionelle Übersetzung** - Absatzweise Übersetzung für konsistente Ergebnisse
🔄 **Begriffsersetzung** - Ein-Klick-Wechsel von fachspezifischem Vokabular
🎙️ **Synchronisation & Sprachklonierung** - CosyVoice-Stimmen oder individuelle Sprachklone
🎬 **Video-Zusammensetzung** - Automatische Formatierung für horizontale/vertikale Darstellungen
## Beispiel-Demo
Das folgende Bild zeigt das Ergebnis, nachdem die Untertiteldatei – generiert durch einen Ein-Klick-Vorgang nach Import eines 46-minütigen lokalen Videos – in die Spur eingefügt wurde. Es wurden keinerlei manuelle Anpassungen vorgenommen. Es gibt keine fehlenden oder überlappenden Untertitel, die Satzsegmentierung wirkt natürlich und die Übersetzungsqualität ist ebenfalls sehr hoch.

### Untertitel-Übersetzung
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### Synchronisation
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### Hochformat
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 Spracherkennungs-Unterstützung
_**Alle lokalen Modelle in der folgenden Tabelle unterstützen die automatische Installation von ausführbaren Dateien + Modelldateien. Treffen Sie einfach Ihre Auswahl und KrillinAI erledigt den Rest für Sie.**_
| Dienst | Unterstützte Plattformen | Modelloptionen | Lokal/Cloud | Hinweise |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | Plattformübergreifend | - | Cloud | Schnell mit hervorragenden Ergebnissen |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (empfohlen: medium+) | Lokal | Höhere Geschwindigkeit, kein Cloud-Service-Overhead |
| **WhisperKit** | macOS (nur Apple Silicon) | `large-v2` | Lokal | Native Optimierung für Apple-Chips |
| **Alibaba Cloud ASR** | Plattformübergreifend | - | Cloud | Umgeht Netzwerkprobleme im chinesischen Festland |
## 🚀 Unterstützung für Große Sprachmodelle
✅ Kompatibel mit allen **OpenAI-API-kompatiblen** Cloud-/Lokal-LLM-Diensten, einschließlich aber nicht beschränkt auf:
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- Selbstgehostete Open-Source-Modelle
- Andere OpenAI-Format-kompatible API-Dienste
## 🌍 Sprachunterstützung
Eingabesprachen: Chinesisch, Englisch, Japanisch, Deutsch, Türkisch (weitere Sprachen in Vorbereitung)
Übersetzungssprachen: **101** Sprachen unterstützt, darunter Englisch, Chinesisch, Russisch, Spanisch, Französisch etc.
## Interface-Vorschau

## 🚀 Schnellstart
### Grundlegende Schritte
Laden Sie zunächst die Release-Executable-Datei herunter, die zu Ihrem System passt. Folgen Sie den Anweisungen unten, um zwischen der Desktop- oder Nicht-Desktop-Version zu wählen, und platzieren Sie die Software in einem leeren Ordner. Beim Ausführen des Programms werden einige Verzeichnisse generiert, daher vereinfacht ein leerer Ordner die Verwaltung.
[Für die Desktop-Version (Release-Dateien mit "desktop" im Namen), siehe hier]
Die Desktop-Version wurde neu veröffentlicht, um Anfängern die korrekte Bearbeitung von Konfigurationsdateien zu erleichtern. Sie enthält noch einige Fehler und wird kontinuierlich aktualisiert.
Doppelklicken Sie die Datei, um sie zu starten.
[Für die Nicht-Desktop-Version (Release-Dateien ohne "desktop" im Namen), siehe hier]
Die Nicht-Desktop-Version ist das Original-Release mit komplexerer Konfiguration, aber stabiler Funktionalität. Sie eignet sich auch für Server-Deployment, da sie eine Web-basierte UI bietet.
Erstellen Sie einen config-Ordner im Verzeichnis und darin eine config.toml-Datei. Kopieren Sie den Inhalt der config-example.toml-Datei aus dem config-Verzeichnis des Quellcodes in Ihre config.toml und füllen Sie Ihre Konfigurationsdaten aus. (Falls Sie OpenAI-Modelle nutzen möchten, aber keinen Schlüssel haben, können Sie der Gruppe beitreten, um kostenlosen Testzugang zu erhalten.)
Starten Sie den Service per Doppelklick auf die Executable oder durch Terminal-Ausführung.
Öffnen Sie Ihren Browser und geben Sie http://127.0.0.1:8888 ein, um loszulegen. (Ersetzen Sie 8888 durch die im Config-File angegebene Port-Nummer.)
### An: macOS-Benutzer
[Für die Desktop-Version (Release-Dateien mit "desktop" im Namen), siehe hier]
Die aktuelle Paketierung der Desktop-Version unterstützt aufgrund von Signierungsproblemen kein direktes Ausführen per Doppelklick oder DMG-Installation. Eine manuelle Vertrauenskonfiguration ist wie folgt erforderlich:
1. Öffnen Sie das Verzeichnis mit der ausführbaren Datei (angenommen der Dateiname ist KrillinAI_1.0.0_desktop_macOS_arm64) im Terminal
2. Führen Sie folgende Befehle nacheinander aus:
```
sudo xattr -cr ./KrillinAI_1.0.0_desktop_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_desktop_macOS_arm64
./KrillinAI_1.0.0_desktop_macOS_arm64
```
[Für die Nicht-Desktop-Version (Release-Dateien ohne "desktop" im Namen), siehe hier]
Diese Software ist nicht signiert, daher müssen Sie nach Abschluss der Konfiguration gemäß den "Grundlegenden Schritten" die Anwendung manuell in macOS freigeben. Gehen Sie wie folgt vor:
1. Öffnen Sie das Terminal und navigieren Sie zum Verzeichnis der ausführbaren Datei (angenommener Dateiname: KrillinAI_1.0.0_macOS_arm64).
2. Führen Sie folgende Befehle nacheinander aus:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
Dadurch wird der Dienst gestartet.
### Dadurch wird der Dienst gestartet.
Dieses Projekt unterstützt Docker-Bereitstellung. Bitte lesen Sie die [Docker Deployment Instructions](../docs/docker.md).
### Cookie-Konfigurationsanleitung
Falls Probleme beim Herunterladen von Videos auftreten, lesen Sie bitte die [Cookie Configuration Instructions](../docs/get_cookies.md) zur Einrichtung Ihrer Cookie-Informationen.
### Konfigurationshilfe
Die schnellste und bequemste Konfigurationsmethode:
* Wählen Sie openai für sowohl transcription_provider als auch llm_provider. Auf diese Weise müssen Sie nur openai.apikey in den folgenden drei Hauptkonfigurationskategorien (openai, local_model und aliyun) ausfüllen, um Untertitelübersetzungen durchführen zu können. (Füllen Sie app.proxy, model und openai.base_url entsprechend Ihrer Situation aus.)
Die Konfigurationsmethode für die Verwendung des lokalen Spracherkennungsmodells (macOS wird vorerst nicht unterstützt) (eine kostengünstige, schnelle und qualitativ hochwertige Option):
* Tragen Sie fasterwhisper für transcription_provider und openai für llm_provider ein. Damit müssen Sie nur openai.apikey und local_model.faster_whisper in den Kategorien openai und local_model ausfüllen, um Untertitelübersetzungen durchführen zu können. Das lokale Modell wird automatisch heruntergeladen. (Gleiches gilt für app.proxy und openai.base_url wie oben erwähnt.)
Folgende Nutzungsszenarien erfordern die Konfiguration von Alibaba Cloud:
* Wenn llm_provider mit aliyun angegeben wird, wird der Large-Model-Service von Alibaba Cloud genutzt. Dementsprechend muss die Konfiguration von aliyun.bailian eingerichtet werden.
* Wenn transcription_provider mit aliyun angegeben wird oder die "Sprachsynchronisation"-Funktion bei Aufgabenstart aktiviert ist, wird der Sprachservice von Alibaba Cloud verwendet. Daher muss die Konfiguration von aliyun.speech ausgefüllt werden.
* Wenn die "Sprachsynchronisation"-Funktion aktiviert ist und gleichzeitig lokale Audiodateien für Stimmklonierung hochgeladen werden, wird auch der OSS-Cloud-Speicherservice von Alibaba Cloud genutzt. Folglich muss die Konfiguration von aliyun.oss ausgefüllt werden.
Konfigurationsanleitung:[Alibaba Cloud Configuration Instructions](../docs/aliyun.md)
## Häufig gestellte Fragen
Bitte lesen Sie die [Frequently Asked Questions](../docs/faq.md)
## Beitragsrichtlinien
- Reichen Sie keine unnötigen Dateien wie .vscode, .idea etc. ein. Nutzen Sie .gitignore entsprechend, um diese auszuschließen.
- Reichen Sie nicht config.toml ein, sondern config-example.toml.
## Sternverlauf
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_es.md

# Herramienta de Traducción y Doblaje de Audio y Video con IA

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
### 📢 Nueva Versión para Escritorio Win y Mac - Bienvenidos a Probar y Enviar Feedback
## Resumen
Krillin AI es una solución todo-en-uno para la localización y mejora de vídeos sin esfuerzo. Esta herramienta minimalista pero potente maneja todo, desde traducción, doblaje hasta clonación de voz y formato, convirtiendo vídeos entre modos horizontal y vertical de forma fluida para una visualización óptima en todas las plataformas de contenido (YouTube, TikTok, Bilibili, Douyin, WeChat Channel, RedNote, Kuaishou). Con su flujo de trabajo integral, Krillin AI transforma material sin editar en contenido pulido y listo para plataformas con solo unos clics.
## Funcionalidades Clave:
🎯 **Inicio con Un Clic** - Lanza tu flujo de trabajo al instante. ¡Nueva versión de escritorio disponible, más fácil de usar!
📥 **Descarga de Videos** - Compatible con yt-dlp y carga de archivos locales
📜 **Subtítulos Precisos** - Reconocimiento de alta precisión con tecnología Whisper
🧠 **Segmentación Inteligente** - Fragmentación y alineación de subtítulos basada en modelos de lenguaje (LLM)
🌍 **Traducción Profesional** - Traducción a nivel de párrafo para mayor coherencia
🔄 **Reemplazo de Términos** - Cambio de vocabulario específico por dominio con un clic
🎙️ **Doblaje y Clonación de Voz** - Voces seleccionadas de CosyVoice o clonación personalizada
🎬 **Composición de Video** - Formateo automático para diseños horizontales/verticales
## Ejemplo Práctico
La siguiente imagen demuestra el resultado obtenido después de insertar automáticamente en la pista de tiempo el archivo de subtítulos generado con un solo clic a partir de un vídeo local de 46 minutos. No se realizó ningún ajuste manual. Los subtítulos no presentan omisiones ni solapamientos, la segmentación de frases es natural y la calidad de traducción es notablemente alta.

### Traducción de Subtítulos
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### Doblaje
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### Formato Vertical
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 Soporte de Reconocimiento de Voz
_**Todos los modelos locales en la siguiente tabla soportan instalación automática de archivos ejecutables + archivos de modelo. Solo haz tu selección y KrillinAI se encargará de todo lo demás.**_
| Servicio | Plataformas Soportadas | Opciones de Modelo | Local/Nube | Notas |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | Multiplataforma | - | Nube | Rápido con excelentes resultados |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (recomendado medium+) | Local | Mayor velocidad, sin sobrecarga de servicios en la nube |
| **WhisperKit** | macOS (solo Apple Silicon) | `large-v2` | Local | Optimización nativa para chips Apple |
| **Alibaba Cloud ASR** | Multiplataforma | - | Nube | Evita problemas de red en China continental |
## 🚀 Soporte para Modelos de Lenguaje Grande
✅ Compatible con todos los servicios **compatibles con API OpenAI** locales/en la nube incluyendo pero no limitado a:
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- Modelos de código abierto autoalojados
- Otros servicios API compatibles con formato OpenAI
## 🌍 Idiomas Soportados
Idiomas de entrada: Chino, Inglés, Japonés, Alemán, Turco (se están añadiendo más idiomas)
Idiomas de traducción: **101** idiomas soportados, incluyendo Inglés, Chino, Ruso, Español, Francés, etc.
## Vista Previa de la Interfaz

## 🚀 Inicio Rápido
### Pasos Básicos
Primero, descarga el archivo ejecutable de la versión Release que coincida con el sistema de tu dispositivo. Sigue las instrucciones a continuación para elegir entre la versión de escritorio o la versión no-de-escritorio, luego coloca el software en una carpeta vacía. Al ejecutar el programa se generarán algunos directorios, por lo que mantenerlo en una carpeta vacía facilita su gestión.
[Para la versión de escritorio (archivos release con "desktop" en el nombre), consulta aquí]
La versión de escritorio es de reciente lanzamiento para solucionar la dificultad que tienen los principiantes al editar archivos de configuración. Aún contiene algunos errores y se actualiza continuamente.
Haz doble clic en el archivo para comenzar a usarlo.
[Para la versión no-de-escritorio (archivos release sin "desktop" en el nombre), consulta aquí]
La versión no-de-escritorio es el lanzamiento original, con configuración más compleja pero funcionalidad estable. También es adecuada para despliegue en servidores, ya que proporciona una interfaz web.
Crea una carpeta llamada config en el directorio principal, luego crea un archivo config.toml dentro de esta. Copia el contenido del archivo config-example.toml (ubicado en el directorio config del código fuente) a tu archivo config.toml y completa los detalles de configuración. (Si deseas usar modelos de OpenAI pero no sabes cómo obtener una clave, puedes unirte al grupo para obtener acceso de prueba gratuito).
Ejecuta el archivo haciendo doble clic o inicia el servicio desde la terminal con el comando correspondiente.
Abre tu navegador e ingresa http://127.0.0.1:8888 para comenzar a usarlo. (Reemplaza 8888 con el número de puerto que especificaste en el archivo de configuración).
### Para usuarios de macOS
[Para la versión de escritorio (archivos release con "desktop" en el nombre), consulta aquí]
El método actual de empaquetado para la versión de escritorio no permite la ejecución directa al hacer doble clic ni la instalación mediante DMG debido a problemas de certificación. Se requiere configuración manual de confianza como se indica a continuación:
1. Abre el directorio que contiene el archivo ejecutable (asumiendo que el nombre del archivo es KrillinAI_1.0.0_desktop_macOS_arm64) en Terminal
2. Ejecuta los siguientes comandos en secuencia:
```
sudo xattr -cr ./KrillinAI_1.0.0_desktop_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_desktop_macOS_arm64
./KrillinAI_1.0.0_desktop_macOS_arm64
```
[Para la versión no de escritorio (archivos release sin "desktop" en el nombre), consulta aquí]
Este software no está certificado, por lo que después de completar la configuración de archivos en los "Pasos Básicos", necesitarás autorizar manualmente la aplicación en macOS. Sigue estos pasos:
1. Abre la terminal y navega al directorio donde se encuentra el archivo ejecutable (asumiendo que el nombre del archivo es KrillinAI_1.0.0_macOS_arm64).
2. Ejecuta los siguientes comandos en secuencia:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
Esto iniciará el servicio.
### Implementación con Docker
Este proyecto admite implementación con Docker. Consulta las [Docker Deployment Instructions](../docs/docker.md).
### Instrucciones de Configuración de Cookies
Si experimentas fallos al descargar videos, consulta las [Cookie Configuration Instructions](../docs/get_cookies.md) para configurar tu información de cookies.
### Ayuda para Configuración
El método más rápido y conveniente para configurar:
* Select `openai` for both `transcription_provider` and `llm_provider`. In this way, you only need to fill in `openai.apikey` in the following three major configuration item categories, namely `openai`, `local_model`, and `aliyun`, and then you can conduct subtitle translation. (Fill in `app.proxy`, `model` and `openai.base_url` as per your own situation.)
El método de configuración para usar el modelo local de reconocimiento de voz (macOS no es compatible por el momento) (una opción que equilibra costo, velocidad y calidad):
* Configura fasterwhisper para transcription_provider y openai para llm_provider. De esta forma, solo necesitarás completar openai.apikey y local_model.faster_whisper en estas dos categorías principales de configuración: openai y local_model, y podrás realizar traducciones de subtítulos. El modelo local se descargará automáticamente. (Lo mismo aplica para app.proxy y openai.base_url como se mencionó anteriormente).
Los siguientes casos de uso requieren configuración con Alibaba Cloud:
* Si llm_provider se configura como aliyun, indica que se usará el servicio de modelos grandes de Alibaba Cloud. Por lo tanto, será necesario configurar el ítem aliyun.bailian.
* Si transcription_provider se configura como aliyun, o si se habilita la función de "doblaje de voz" al iniciar una tarea, se utilizará el servicio de voz de Alibaba Cloud. En consecuencia, será necesario completar la configuración del ítem aliyun.speech.
* Si se habilita la función de "doblaje de voz" y simultáneamente se suben archivos de audio locales para clonación de timbre vocal, también se usará el servicio de almacenamiento en la nube OSS de Alibaba Cloud. Por lo tanto, será necesario completar la configuración del ítem aliyun.oss.
Guía de configuración: [Alibaba Cloud Configuration Instructions](../docs/aliyun.md)
## Preguntas Frecuentes
Consulta las [Frequently Asked Questions](../docs/faq.md)
## Directrices de Contribución
- No envíes archivos innecesarios como .vscode, .idea, etc. Utiliza adecuadamente .gitignore para filtrarlos.
- No envíes config.toml; en su lugar, envía config-example.toml.
## Historial de Estrellas
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_fr.md

# Outil de Traduction et Doublage Audio/Video par IA

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
### 📢 Nouvelle Version Bureau pour Windows & Mac – Testez et Donnez Votre Avis
## Présentation
Krillin AI est une solution tout-en-un pour la localisation et l'amélioration simplifiée de vidéos. Cet outil minimaliste mais puissant gère tout : traduction, doublage, clonage vocal, et reformatage – convertissant facilement les vidéos entre formats paysage et portrait pour un affichage optimal sur toutes les plateformes (YouTube, TikTok, Bilibili, Douyin, WeChat Channel, RedNote, Kuaishou). Avec son workflow intégré, Krillin AI transforme des vidéos brutes en contenu professionnel en quelques clics.
## Fonctionnalités Clés :
🎯 **Lancement Instantané** - Démarrez votre workflow en un clic. Nouvelle version bureau plus intuitive !
📥 **Téléchargement Vidéo** - Prise en charge d'yt-dlp et des fichiers locaux
📜 **Sous-titres Précis** - Reconnaissance haute précision via Whisper
🧠 **Segmentation Intelligente** - Découpage des sous-titres par IA (LLM)
🌍 **Traduction Professionnelle** - Traduction cohérente par paragraphes
🔄 **Remplacement de Termes** - Échange de vocabulaire spécialisé en un clic
🎙️ **Doublage et Clonage Vocal** - Sélection de voix CosyVoice ou clonage
🎬 **Composition Vidéo** - Formatage automatique paysage/portrait
## Démonstration
L'image ci-dessous montre le résultat après insertion automatique des sous-titres générés pour une vidéo locale de 46 minutes (sans ajustement manuel). Aucun sous-titre manquant ou chevauchant, une segmentation naturelle et une traduction de qualité.

### Traduction de Sous-titres
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### Doublage
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### Format Portrait
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 Reconnaissance Vocale
_**Tous les modèles locaux dans le tableau ci-dessous prennent en charge l'installation automatique des fichiers exécutables + fichiers de modèle. Il vous suffit de faire votre sélection, et KrillinAI s'occupera du reste.**_
| Service | Plateformes supportées | Options de modèle | Local/Cloud | Remarques |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | Multi-plateforme | - | Cloud | Rapide avec d'excellents résultats |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (recommandé medium+) | Local | Vitesse accrue, pas de surcharge de service cloud |
| **WhisperKit** | macOS (Apple Silicon uniquement) | `large-v2` | Local | Optimisation native pour puces Apple |
| **Alibaba Cloud ASR** | Multi-plateforme | - | Cloud | Contourne les problèmes réseau en Chine continentale |
## 🚀 Prise en charge des Grands Modèles de Langage
✅ Compatible avec tous les services cloud/locaux **compatibles avec l'API OpenAI**, y compris mais sans s'y limiter :
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- Modèles open source auto-hébergés
- Autres services API compatibles avec le format OpenAI
## 🌍 Langues Prises en Charge
Langues d'entrée : Chinois, Anglais, Japonais, Allemand, Turc (autres en cours d'ajout)
Langues de traduction : 101 langues dont Anglais, Chinois, Russe, Espagnol, Français, etc.
## Aperçu de l'Interface

## 🚀 Guide de Démarrage Rapide
### Étapes de Base
Téléchargez d'abord le fichier exécutable de la version Release correspondant à votre système. Suivez les instructions ci-dessous pour choisir entre la version bureau ou standard, puis placez le logiciel dans un dossier vide. L'exécution du programme générera des répertoires supplémentaires - un dossier vide facilite la gestion.
[Pour la version bureau (fichiers avec "desktop" dans le nom)]
_La version bureau est une nouveauté conçue pour simplifier la configuration (sans éditer de fichiers). Elle contient encore quelques bugs et est mise à jour régulièrement._
Double-cliquez sur le fichier pour l'utiliser.
[Pour la version standard (fichiers sans "desktop" dans le nom), voir ici]
_La version standard est la publication originale, offrant une configuration plus complexe mais une fonctionnalité stable. Elle convient également au déploiement sur serveur grâce à son interface web._
Créez un dossier `config` dans le répertoire, puis créez un fichier `config.toml` à l'intérieur. Copiez le contenu du fichier `config-example.toml` du dossier `config` du code source dans votre `config.toml` et remplissez les détails de configuration. (Si vous souhaitez utiliser les modèles OpenAI mais ne savez pas comment obtenir une clé, vous pouvez rejoindre le groupe pour un accès d'essai gratuit.)
Double-cliquez sur l'exécutable ou exécutez-le dans le terminal pour démarrer le service.
Ouvrez votre navigateur et entrez http://127.0.0.1:8888 pour commencer à l'utiliser. (Remplacez 8888 par le numéro de port que vous avez spécifié dans le fichier config.)
### Pour les utilisateurs macOS
[Pour la version bureau (fichiers avec "desktop" dans le nom), voir ici]
La méthode actuelle d'empaquetage ne permet pas d'exécution par double-clic ni d'installation via DMG en raison de problèmes de signature. Une configuration manuelle de confiance est nécessaire :
1. Ouvrez dans le Terminal le répertoire contenant le fichier exécutable (nommé par exemple KrillinAI_1.0.0_desktop_macOS_arm64)
2. Exécutez les commandes suivantes dans l'ordre :
```
sudo xattr -cr ./KrillinAI_1.0.0_desktop_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_desktop_macOS_arm64
./KrillinAI_1.0.0_desktop_macOS_arm64
```
[Pour la version standard (fichiers sans "desktop" dans le nom), voir ici]
Ce logiciel n'est pas signé. Après avoir complété la configuration des fichiers comme décrit dans les "Étapes de base", vous devrez approuver manuellement l'application sur macOS. Procédez comme suit :
1. Ouvrez le terminal et accédez au répertoire contenant le fichier exécutable (par exemple `KrillinAI_1.0.0_macOS_arm64`)
2. Exécutez les commandes suivantes dans l'ordre :
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
Cela démarrera le service.
### Déploiement Docker
Consultez le [Docker Deployment Instructions](../docs/docker.md).
### Configuration des Cookies
En cas d'échec de téléchargement, suivez le [Cookie Configuration Instructions](../docs/get_cookies.md) .
### Aide à la Configuration
La méthode de configuration la plus rapide et pratique :
* Sélectionnez `openai` pour `transcription_provider` et `llm_provider`. Ainsi, vous n'aurez qu'à renseigner `openai.apikey` dans les trois catégories de configuration principales (`openai`, `local_model`, et `aliyun`) pour effectuer la traduction de sous-titres. (Complétez `app.proxy`, `model` et `openai.base_url` selon votre situation.)
Méthode utilisant le modèle local de reconnaissance vocale (non supporté sur macOS pour le moment) (optimisant coût, vitesse et qualité) :
* Utilisez `fasterwhisper` pour `transcription_provider` et `openai` pour `llm_provider`. Vous devrez alors renseigner `openai.apikey` et `local_model.faster_whisper` dans les catégories `openai` et `local_model`. Le modèle local sera téléchargé automatiquement. (`app.proxy` et `openai.base_url` restent configurables comme mentionné ci-dessus.)
Cas nécessitant la configuration d'Alibaba Cloud :
* Si `llm_provider` est défini sur `aliyun`, le service de grands modèles d'Alibaba Cloud sera utilisé. Configurez alors `aliyun.bailian`.
* Si `transcription_provider` est sur `aliyun` ou si la fonction "doublage vocal" est activée, le service vocal d'Alibaba Cloud sera utilisé. Configurez `aliyun.speech`.
* Si le "doublage vocal" est activé avec clonage de timbre vocal via fichiers audio locaux, le service OSS d'Alibaba Cloud sera aussi utilisé. Configurez alors `aliyun.oss`.
Guide : [Instructions de configuration Alibaba Cloud](./docs/aliyun.md)
## Foire Aux Questions
Consultez la [FAQ](../docs/faq.md) (Foire Aux Questions)
## Directives de Contribution
- Ne soumettez pas de fichiers inutiles comme `.vscode`, `.idea`, etc. Utilisez correctement le fichier `.gitignore` pour les exclure.
- Ne soumettez pas `config.toml` ; soumettez plutôt `config-example.toml`.
## Historique des Stars
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_jp.md

# AI動画翻訳・吹き替えツール(簡単デプロイ)

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
## 🚀 プロジェクト概要
クリリンAIは、動画のローカライズと品質向上を簡単に実現するオールインワンソリューションです。このシンプルでありながら強力なツールは、翻訳、吹き替え、ボイスクローニングからフォーマット調整までをカバー。縦横画面のシームレスな変換により、YouTube、TikTok、Bilibili、抖音(Douyin)、微信チャンネル、RedNote、快手(Kuaishou)など、あらゆるコンテンツプラットフォームに最適化された表示を実現します。エンドツーエンドのワークフローで、わずかなクリックだけで未編集の素材から完成度の高いプラットフォーム対応コンテンツへと仕上げます。
## 主な特徴と機能:
🎯 **ワンクリック起動**:複雑な環境設定不要、依存関係を自動インストール
📥 **動画取得**:yt-dlpダウンロードまたはローカルファイルアップロード対応
📜 **高精度認識**:Whisperベースの音声認識
🧠 **インテリジェント分割**:LLMを使用した字幕分割と調整
🔄 **用語置換**:専門分野の語彙をワンクリックで置換
🌍 **プロ翻訳**:LLMベースの段落単位翻訳で文脈一貫性を保持
🎙️ **音声クローン**:デフォルト音声またはカスタム音声クローニング
🎬 **動画合成**:縦横画面と字幕レイアウトを自動処理
## 効果デモ
下図は46分のローカル動画をインポートし、ワンクリック実行後に生成された字幕ファイルをトラックに追加した効果です。手動調整なしで、欠落・重複なく、自然な文節区切りと高品質な翻訳を実現。

### 字幕翻訳
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### 配音
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### 縦画面
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 音声認識サポート
_**以下の表に記載されているすべてのローカルモデルは、実行ファイル+モデルファイルの自動インストールに対応しています。選択するだけで、KrillinAIが残りの作業をすべて処理します。**_
| サービス | 対応プラットフォーム | モデルオプション | ローカル/クラウド | 備考 |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | クロスプラットフォーム | - | クラウド | 高速で優れた精度 |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (medium以上推奨) | ローカル | 高速処理、クラウド依存なし |
| **WhisperKit** | macOS (Apple Siliconのみ) | `large-v2` | ローカル | Appleチップ向け最適化 |
| **Alibaba Cloud ASR** | クロスプラットフォーム | - | クラウド | 中国本土のネットワーク制限回避 |
## 🚀 大規模言語モデル(LLM)サポート
✅ **OpenAI API互換**のクラウド/ローカルLLMサービスすべてに対応(以下に限定されません):
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- セルフホスト型オープンソースモデル
- その他OpenAI形式互換APIサービス
## 対応言語
入力言語対応:中国語、英語、日本語、ドイツ語、トルコ語、マレー語(随時追加中)
翻訳言語対応:英語、中国語、ロシア語、スペイン語、フランス語など101言語
## インターフェースプレビュー

## クイックスタート
### 基本手順
1. [Release](https://github.com/krillinai/KrillinAI/releases)からお使いのデバイスに合った実行ファイルをダウンロードし、空のフォルダに配置
2. フォルダ内に`config`フォルダを作成し、`config`フォルダ内に`config.toml`ファイルを作成、ソースコードの`config`ディレクトリにある`config-example.toml`ファイルの内容をコピーして貼り付け、設定情報を記入(OpenAIモデルを使いたいがキーの取得方法がわからない場合はグループに参加して無料で試用可能)
3. 実行ファイルをダブルクリック、またはターミナルで実行してサービスを起動
4. ブラウザを開き `http://127.0.0.1:8888`と入力して使用開始
### macOSユーザー向け
本ソフトウェアは署名されていないため、macOSで実行する場合、「基本手順」のファイル設定完了後、手動でアプリを信頼する必要があります。方法は以下の通り:
1. ターミナルで実行ファイル(ファイル名がKrillinAI_1.0.0_macOS_arm64と仮定)があるディレクトリを開く
2. 以下のコマンドを順に実行:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
これでサービスが起動します
### Dockerデプロイ
本プロジェクトはDockerデプロイをサポートしています。[Docker部署说明](./docker.md)を参照してください
### Cookie設定説明(オプション)
動画ダウンロードに失敗する場合
[Cookie 配置说明](./get_cookies.md) を参照してCookie情報を設定してください。
### 設定ヘルプ(必読)
最速で簡単な設定方法:
* transcription_providerとllm_providerの両方にopenaiを選択すると、openai、local_model、aliyunの3つの設定項目でopenai.apikeyのみ記入すれば字幕翻訳が可能です。(app.proxy、model、openai.base_urlは状況に応じて記入)
ローカル音声認識モデルを使用する設定方法(macOS未対応)(コスト、速度、品質を考慮した選択)
* transcription_providerにfasterwhisper、llm_providerにopenaiを記入すると、openai、local_modelの2つの設定項目でopenai.apikeyとlocal_model.faster_whisperを記入するだけで字幕翻訳が可能で、ローカルモデルは自動ダウンロードされます。(app.proxyとopenai.base_urlは同上)
以下の使用状況では、Alibaba Cloudの設定が必要です:
* llm_providerにaliyunを記入した場合、Alibaba Cloudの大規模モデルサービスを使用するため、aliyun.bailian項目の設定が必要
* transcription_providerにaliyunを記入した場合、またはタスク起動時に「吹き替え」機能を有効にした場合、Alibaba Cloudの音声サービスを使用するため、aliyun.speech項目の記入が必要
* 「吹き替え」機能を有効にし、ローカルオーディオを音声クローニング用にアップロードした場合、Alibaba CloudのOSSクラウドストレージサービスを使用するため、aliyun.oss項目の記入が必要
Alibaba Cloud設定ヘルプ:[阿里云配置说明](./aliyun.md)
## よくある質問
[よくある質問](./faq.md)をご覧ください
## コントリビューション規範
1. .vscode、.ideaなどの不要なファイルをコミットしないでください。.gitignoreを活用してフィルタリングしてください
2. config.tomlをコミットせず、代わりにconfig-example.tomlを使用してコミットしてください
## お問い合わせ
1. QQグループに参加して質問にお答えします:754069680
2. ソーシャルメディアアカウントBilibiliをフォローし、AI技術分野の高品質なコンテンツを毎日シェアしています
## Star History
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_kr.md

# AI 오디오&비디오 번역 및 더빙 도구

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
### 📢 Win & Mac 데스크톱 버전 신규 출시 – 테스트 후 피드백 제공 부탁드립니다
## 개요
크릴린 AI(Krillin AI)는 번역, 더빙, 음성 복제에서부터 화면 비율 변환까지 모든 과정을 처리하는 올인원 비디오 현지화 및 향상 솔루션입니다. 이 미니멀하면서도 강력한 도구는 유튜브, 틱톡, 빌리빌리, 더우인, 위챗 채널, 레드노트, 쿠아이쇼우 등 모든 콘텐츠 플랫폼에 최적화된 가로/세로 영상 변환을 자동으로 수행합니다. 엔드투엔드 워크플로우로 원본 영상을 클릭 몇 번만에 각 플랫폼에 맞는 완성된 콘텐츠로 변환해 줍니다.
## 주요 기능:
🎯 **원클릭 시작** - 즉시 작업 프로세스 실행
📥 **비디오 다운로드** - yt-dlp 지원 및 로컬 파일 업로드 가능
📜 **정밀 자막** - Whisper 기반 고정확도 음성 인식
🧠 **스마트 분할** - LLM 기반 자막 청크 분할 및 정렬
🌍 **전문가 수준 번역** - 문단 단위 자연스러운 번역
🔄 **용어 대체** - 분야별 전문 어휘 한 번에 변경
🎙️ ** 더빙 및 음성 복제** - CosyVoice 선택 또는 개인 음성 클로닝
🎬 **비디오 합성** - 가로/세로 레이아웃 자동 포맷팅
## 데모 영상
46분 분량의 로컬 비디오 파일을 불러온 후 원클릭 작업으로 생성된 자막 파일을 트랙에 삽입한 결과입니다. 전혀 수동 조정 없이도 자막 누락이나 겹침 현상 없이 문장 분할이 자연스럽게 이루어졌으며, 번역 품질 또한 매우 우수합니다.

### 자막 번역
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### 더빙
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
## 🔍 음성 인식 지원
_**아래 표의 모든 로컬 모델은 실행 파일 + 모델 파일의 자동 설치를 지원합니다. 원하는 모델을 선택하기만 하면 KrillinAI이 나머지 모든 작업을 처리합니다.**_
| 서비스 | 지원 플랫폼 | 모델 옵션 | 로컬/클라우드 | 참고사항 |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | 크로스 플랫폼 | - | 클라우드 | 빠른 속도와 우수한 결과 |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (medium+ 권장) | 로컬 | 더 빠른 속도, 클라우드 서비스 오버헤드 없음 |
| **WhisperKit** | macOS (Apple Silicon 전용) | `large-v2` | 로컬 | Apple 칩에 최적화 |
| **Alibaba Cloud ASR** | 크로스 플랫폼 | - | 클라우드 | 중국 본토 네트워크 문제 회피 |
## 🚀 대규모 언어 모델 지원
✅ **OpenAI API 호환** 클라우드/로컬 LLM 서비스와 완벽 호환 (다음 포함):
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- 자체 호스팅 오픈소스 모델
- 기타 OpenAI 형식 호환 API 서비스
## 🌍 언어 지원
입력 언어: 중국어, 영어, 일본어, 독일어, 터키어, 한국어 지원 (추가 언어 계속 확장 중)
번역 언어: 영어, 중국어, 러시아어, 스페인어, 프랑스어 등 101개 언어 지원
## 인터페이스 미리보기

## 🚀 빠른 시작
### 기본 단계
1. 릴리스에서 사용자 기기 시스템에 맞는 실행 파일을 다운로드 후 빈 폴더에 배치하세요.
2. 해당 폴더 내부에 config 폴더를 생성하고, config 폴더 안에 config.toml 파일을 만드세요. 소스 코드의 config 디렉토리에 있는 config-example.toml 파일 내용을 복사해 config.toml에 붙여넣은 후 설정 정보를 입력하세요.
3. 실행 파일을 더블클릭해 서비스를 시작하세요.
4. 브라우저에서 http://127.0.0.1:8888 주소로 접속하면 사용이 가능합니다(8888은 config.toml에서 설정한 포트 번호로 변경해주세요).
### macOS 사용자분들께
본 소프트웨어는 서명되지 않았으므로, "기본 단계"의 파일 구성 완료 후 macOS에서 수동으로 애플리케이션 신뢰 설정이 필요합니다. 다음 절차를 따라주세요:
1. 터미널을 열고 실행 파일(예: 파일명이 KrillinAI_1.0.0_macOS_arm64인 경우)이 위치한 디렉토리로 이동합니다.
2. 다음 명령어들을 순차적으로 실행해주세요:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
이렇게 하면 서비스가 시작됩니다.
### 도커 배포
이 프로젝트는 도커 배포를 지원합니다. 자세한 내용은 [Docker Deployment Instructions](./docs/docker.md)를 참고해주세요.
### 쿠키 설정 안내
비디오 다운로드 실패 시 [Cookie Configuration Instructions](./docs/get_cookies.md) 를 참조하여 쿠키 정보를 설정해주세요.
### 설정 가이드
가장 빠르고 편리한 설정 방법:
* transcription_provider와 llm_provider 모두 openai를 선택하세요. 이 경우 다음 3가지 주요 설정 항목 카테고리(openai, local_model, aliyun) 중 openai.apikey만 입력하면 자막 번역을 수행할 수 있습니다. (app.proxy, model, openai.base_url은 각자의 상황에 맞게 입력하세요.)
로컬 음성 인식 모델 사용 설정 방법 (현재 macOS 미지원) (비용, 속도, 품질을 고려한 선택):
* transcription_provider에는 fasterwhisper를, llm_provider에는 openai를 입력하세요. 이 경우 openai와 local_model 카테고리에서 openai.apikey와 local_model.faster_whisper만 입력하면 자막 번역이 가능합니다. 로컬 모델은 자동으로 다운로드됩니다. (위에서 언급한 app.proxy와 openai.base_url도 동일하게 적용됩니다.)
다음 사용 상황에서는 알리바바 클라우드 설정이 필요합니다:
* llm_provider에 aliyun을 입력한 경우: 알리바바 클라우드의 대형 모델 서비스를 사용하게 되므로, aliyun.bailian 항목 설정이 필요합니다.
* transcription_provider에 aliyun을 입력하거나 작업 시작 시 "보이스 더빙" 기능을 활성화한 경우: 알리바바 클라우드의 음성 서비스를 사용하게 되므로, aliyun.speech 항목 설정이 필요합니다.
* "보이스 더빙" 기능을 활성화하면서 동시에 로컬 오디오 파일을 업로드해 음색 복제를 하는 경우: 알리바바 클라우드의 OSS 클라우드 스토리지 서비스도 사용하게 되므로, aliyun.oss 항목 설정이 필요합니다.
설정 가이드: [Alibaba Cloud Configuration Instructions](./docs/aliyun.md)
## 자주 묻는 질문
자세한 내용은 [Frequently Asked Questions](./docs/faq.md)를 참조해주세요.
## 기여 가이드라인
- .vscode, .idea 등 불필요한 파일은 제출하지 마세요. .gitignore 파일을 활용해 필터링해주세요.
- config.toml 대신 config-example.toml 파일을 제출해주세요.
## 스타 히스토리
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_pt.md

# Ferramenta de Tradução e Dublagem de Áudio e Vídeo por IA

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
### 📢 Novo Lançamento para a Versão Desktop Win & Mac – Bem-vindos para Testar e Enviar Feedback
## Visão Geral
O Krillin AI é uma solução completa para localização e aprimoramento de vídeos de forma simples. Esta ferramenta minimalista, porém poderosa, cuida de tudo, desde tradução, dublagem até clonagem de voz e formatação — convertendo perfeitamente vídeos entre modos paisagem e retrato para exibição ideal em todas as plataformas de conteúdo (YouTube, TikTok, Bilibili, Douyin, WeChat Channel, RedNote, Kuaishou). Com seu fluxo de trabalho de ponta a ponta, o Krillin AI transforma gravações brutas em conteúdo refinado e pronto para as plataformas com apenas alguns cliques.
## Principais Recursos:
🎯 **Início com Um Clique** - Inicie seu fluxo de trabalho instantaneamente. Nova versão desktop disponível — mais fácil de usar!
📥 **Download de Vídeos** - Suporte a yt-dlp e upload de arquivos locais
📜 **Legendas Precisas** - Reconhecimento de alta precisão com tecnologia Whisper
🧠 **Segmentação Inteligente** - Divisão e alinhamento de legendas baseados em LLM
🌍 **Tradução Profissional** - Tradução em nível de parágrafo para consistência
🔄 **Substituição de Termos** - Troca de vocabulário específico por domínio com um clique
🎙️ **Dublagem e Clonagem de Voz** - Seleção de vozes CosyVoice ou clonagem personalizada
🎬 **Composição de Vídeo** - Formatação automática para layouts horizontais/verticais
## Demonstração
A imagem abaixo mostra o resultado após o arquivo de legenda, gerado com um único clique após a importação de um vídeo local de 46 minutos, ser inserido na timeline. Nenhum ajuste manual foi necessário. Não há legendas faltando ou sobrepostas, a segmentação das frases é natural e a qualidade da tradução também é bastante alta.

### Tradução de Legendas
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### Dublagem
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### Modo Retrato
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 Suporte a Reconhecimento de Voz
_**Todos os modelos locais na tabela abaixo suportam instalação automática de arquivos executáveis + arquivos de modelo. Basta fazer sua seleção e o KrillinAI cuidará de todo o resto para você.**_
| Serviço | Plataformas Suportadas | Opções de Modelo | Local/Nuvem | Observações |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | Multiplataforma | - | Nuvem | Rápido com excelentes resultados |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (recommend medium+) | Local | Velocidade maior, sem sobrecarga de serviço em nuvem |
| **WhisperKit** | macOS (Apple Silicon only) | `large-v2` | Local | Otimização nativa para chips Apple |
| **Alibaba Cloud ASR** | Multiplataforma | - | Nuvem | Contorna problemas de rede na China continental |
## 🚀 Suporte a Modelos de Linguagem Grande
✅ Compatível com todos os serviços **compatíveis com API OpenAI** locais/em nuvem, incluindo mas não limitado a:
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- Modelos de código aberto auto-hospedados
- Outros serviços API compatíveis com formato OpenAI
## 🌍 Idiomas Suportados
Idiomas de entrada: Chinês, Inglês, Japonês, Alemão, Turco (mais idiomas em breve)
Idiomas para tradução: 101 idiomas suportados, incluindo Inglês, Chinês, Russo, Espanhol, Francês, etc.
## Prévia da Interface

## 🚀 Início Rápido
### Passos Básicos
Primeiro, baixe o arquivo executável da versão Release compatível com o sistema do seu dispositivo. Siga as instruções abaixo para escolher entre a versão desktop ou não-desktop, depois coloque o software em uma pasta vazia. A execução do programa irá gerar alguns diretórios, portanto, mantê-lo em uma pasta vazia facilita o gerenciamento.
[Para a versão desktop (arquivos de release com "desktop" no nome), consulte aqui]
A versão desktop foi lançada recentemente para facilitar o uso por iniciantes que têm dificuldade em editar arquivos de configuração. Ela ainda contém alguns bugs e está em constante atualização.
Clique duas vezes no arquivo para começar a usar.
[Para a versão não-desktop (arquivos de release sem "desktop" no nome), consulte aqui]
A versão não-desktop é o lançamento original, com configuração mais complexa porém funcionalidade estável. Também é adequada para implantação em servidores, pois fornece uma interface baseada na web.
Crie uma pasta config no diretório e, em seguida, crie um arquivo config.toml dentro dela. Copie o conteúdo do arquivo config-example.toml (localizado na pasta config do código-fonte) para o seu config.toml e preencha com os detalhes da sua configuração. (Se desejar usar modelos da OpenAI mas não souber como obter uma chave, você pode entrar no grupo para obter acesso gratuito de teste.)
Execute o arquivo com um duplo-clique ou rode-o no terminal para iniciar o serviço.
Abra seu navegador e acesse http://127.0.0.1:8888 para começar a usar. (Substitua 8888 pelo número da porta que você definiu no arquivo de configuração.)
### Para: Usuários macOS
[Para a versão desktop, ou seja, arquivos de release com "desktop" no nome, consulte aqui]
O método atual de empacotamento da versão desktop não suporta execução por duplo-clique ou instalação via DMG devido a problemas de assinatura. É necessário configurar manualmente a confiança da seguinte forma:
1. Abra o diretório contendo o arquivo executável (supondo que o nome do arquivo seja KrillinAI_1.0.0_desktop_macOS_arm64) no Terminal
2. Execute os seguintes comandos sequencialmente:
```
sudo xattr -cr ./KrillinAI_1.0.0_desktop_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_desktop_macOS_arm64
./KrillinAI_1.0.0_desktop_macOS_arm64
```
[Para a versão não-desktop, ou seja, arquivos de release sem "desktop" no nome, consulte aqui]
Este software não está assinado, portanto após completar a configuração do arquivo nos "Passos Básicos", você precisará aprovar manualmente o aplicativo no macOS. Siga estes passos:
1. Abra o Terminal e navegue até o diretório onde está o arquivo executável (assumindo que o nome do arquivo seja KrillinAI_1.0.0_macOS_arm64)
2. Execute os seguintes comandos em sequência:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
Isso iniciará o serviço.
### Implantação com Docker
Implantação com Docker [Docker Deployment Instructions](../docs/docker.md) para mais detalhes.
### Instruções de Configuração de Cookies
Caso enfrente falhas ao baixar vídeos, consulte as [Cookie Configuration Instructions](../docs/get_cookies.md) para configurar suas informações de cookie.
### Ajuda de Configuração
O método mais rápido e conveniente de configuração:
* Selecione openai para ambos transcription_provider e llm_provider. Dessa forma, você só precisará preencher openai.apikey nas três principais categorias de configuração a seguir: openai, local_model e aliyun, e então poderá realizar tradução de legendas. (Preencha app.proxy, model e openai.base_url de acordo com sua própria situação.)
O método de configuração para usar o modelo local de reconhecimento de fala (macOS não é suportado temporariamente) - uma opção que equilibra custo, velocidade e qualidade:
* Preencha `fasterwhisper` para `transcription_provider` e `openai` para `llm_provider`. Desta forma, você só precisará preencher `openai.apikey` e `local_model.faster_whisper` nas seguintes três principais categorias de itens de configuração, ou seja, `openai` e `local_model`, e então você poderá realizar tradução de legendas. O modelo local será baixado automaticamente. (O mesmo se aplica a `app.proxy` e `openai.base_url` conforme mencionado acima.)
As seguintes situações de uso exigem a configuração da Alibaba Cloud:
* Se llm_provider for preenchido com aliyun, indica que o serviço de modelo grande da Alibaba Cloud será utilizado. Consequentemente, a configuração do item aliyun.bailian precisa ser definida.
* Se transcription_provider for preenchido com aliyun, ou se a função "dublagem de voz" for ativada ao iniciar uma tarefa, o serviço de voz da Alibaba Cloud será utilizado. Portanto, a configuração do item aliyun.speech precisa ser preenchida.
* Se a função "dublagem de voz" for ativada e arquivos de áudio locais forem enviados para clonagem de timbre de voz ao mesmo tempo, o serviço de armazenamento em nuvem OSS da Alibaba Cloud também será utilizado. Logo, a configuração do item aliyun.oss precisa ser preenchida.
Guia de Configuração: [Alibaba Cloud Configuration Instructions](../docs/aliyun.md)
## Perguntas Frequentes
Consulte [Frequently Asked Questions](../docs/faq.md)
## Diretrizes de Contribuição
- Não envie arquivos desnecessários como .vscode, .idea, etc. Por favor, utilize adequadamente o .gitignore para filtrá-los.
- Não envie o config.toml; em vez disso, envie o config-example.toml.
## Histórico de Estrelas
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_rus.md

# AI инструмент для перевода и озвучки аудио и видео

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
## Обзор
Krillin AI — это универсальное решение для простой локализации и улучшения видео. Этот минималистичный, но мощный инструмент выполняет всё: от перевода и дубляжа до клонирования голоса и адаптации формата — легко преобразует видео между горизонтальным и вертикальным режимами для идеального отображения на любых платформах (YouTube, TikTok, Bilibili, Douyin, WeChat Channel, RedNote, Kuaishou). Благодаря сквозному рабочему процессу Krillin AI превращает исходные материалы в готовый к публикации контент всего за несколько кликов.
## Ключевые возможности:
🎯 **Запуск в один клик** - мгновенное начало работы
📥 **Загрузка видео** - поддержка yt-dlp и локальных файлов
📜 **Точные субтитры** - распознавание с высокой точностью на основе Whisper
🧠 **Умное разделение** - логическая разбивка и выравнивание субтитров с помощью LLM
🌍 **Профессиональный перевод** - согласованный перевод на уровне абзацев
🔄 **Замена терминов** - смена специализированной лексики в один клик
🎙️ **Озвучка и клонирование голоса** - выбор голосов CosyVoice или создание копий
🎬 **Видеомонтаж** - автоматическое форматирование для горизонтальных и вертикальных форматов
## Пример работы
На изображении ниже показан результат автоматической вставки субтитров в видео после однокликового запуска обработки 46-минутного локального видео. Никаких ручных корректировок не производилось.

### Перевод субтитров
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### Озвучка
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### портретный режим
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 Поддержка распознавания речи
_**Все локальные модели в таблице ниже поддерживают автоматическую установку исполняемых файлов + файлов моделей. Просто сделайте свой выбор, а KrillinAI сделает всё остальное за вас.**_
| Сервис | Поддерживаемые платформы | Варианты моделей | Локально/Облако | Примечания |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | Кроссплатформенный | - | Облако | Быстрое с отличными результатами |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (recommend medium+) | Локально | Более высокая скорость, без нагрузки на облачный сервис |
| **WhisperKit** | macOS (Apple Silicon only) | `large-v2` | Локально | Нативная оптимизация для чипов Apple |
| **Alibaba Cloud ASR** | Кроссплатформенный | - | Облако | Обходит проблемы сети в материковом Китае |
## 🚀 Поддержка больших языковых моделей
✅ Совместим со всеми **совместимыми с OpenAI API** облачными/локальными LLM-сервисами, включая, но не ограничиваясь:
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- Самостоятельно размещённые open-source модели
- Другие API-сервисы, совместимые с форматом OpenAI
## 🌍 Поддерживаемые языки
Входные языки: китайский, английский, японский, немецкий, турецкий (добавляются новые языки)
Языки перевода: 101 языков, включая английский, китайский, русский, испанский, французский и др.
## Предпросмотр интерфейса

## 🚀 Быстрый старт
### Основные шаги
1. Скачайте исполняемый файл, соответствующий вашей операционной системе, из раздела релизов и поместите его в пустую папку.
2. Создайте папку config внутри этой папки, затем создайте файл config.toml в папке config. Скопируйте содержимое файла config-example.toml из директории config исходного кода в config.toml и заполните вашу конфигурационную информацию соответствующим образом.
3. Дважды щелкните на исполняемом файле, чтобы запустить сервис.
4. Откройте браузер и введите http://127.0.0.1:8888, чтобы начать использование (замените 8888 на порт, который вы указали в файле config.toml).
### Для пользователей macOS
Это программное обеспечение не подписано, поэтому после завершения настройки файлов в "Основных шагах" вам потребуется вручную подтвердить доверие к приложению в macOS. Выполните следующие действия:
1. Откройте терминал и перейдите в директорию, где находится исполняемый файл (предположим, имя файла `KrillinAI_1.0.0_macOS_arm64`).
2. Выполните следующие команды по порядку:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
Это запустит сервис.
### Инструкции по настройке Cookie
Этот проект поддерживает развертывание через Docker. Пожалуйста, обратитесь к [Docker Deployment Instructions](./docs/docker.md).
### Cookie Configuration Instructions
Если вы столкнулись с ошибками при загрузке видео, пожалуйста, обратитесь к [Cookie Configuration Instructions](./docs/get_cookies.md) для настройки информации о ваших cookie.
### Помощь по настройке
Самый быстрый и удобный способ настройки:
* Выберите openai для transcription_provider и llm_provider. Таким образом, вам нужно будет заполнить только openai.apikey в следующих трех основных категориях конфигурации, а именно openai, local_model и aliyun, и затем вы сможете выполнять перевод субтитров. (Заполните app.proxy, model и openai.base_url в соответствии с вашей ситуацией.)
Способ настройки для использования локальной модели распознавания речи (временно не поддерживается на macOS) (выбор, учитывающий стоимость, скорость и качество):
* Заполните fasterwhisper для transcription_provider и openai для llm_provider. Таким образом, вам нужно будет заполнить только openai.apikey и local_model.faster_whisper в следующих двух основных категориях конфигурации, а именно openai и local_model, и затем вы сможете выполнять перевод субтитров. Локальная модель будет загружена автоматически. (То же самое относится к app.proxy и openai.base_url, как упоминалось выше.)
Следующие ситуации использования требуют настройки Alibaba Cloud:
* Если llm_provider заполнен как aliyun, это означает, что будет использоваться сервис больших моделей Alibaba Cloud. Следовательно, необходимо настроить параметр aliyun.bailian.
* Если transcription_provider заполнен как aliyun, или если функция "озвучки" включена при запуске задачи, будет использоваться голосовой сервис Alibaba Cloud. Поэтому необходимо заполнить параметр aliyun.speech.
* Если функция "озвучки" включена и одновременно загружаются локальные аудиофайлы для клонирования тембра голоса, также будет использоваться сервис облачного хранилища OSS от Alibaba Cloud. Следовательно, необходимо заполнить параметр aliyun.oss.
Руководство по настройке: [Alibaba Cloud Configuration Instructions](./docs/aliyun.md)
## Часто задаваемые вопросы
Пожалуйста, обратитесь к [Frequently Asked Questions](./docs/faq.md)
## Рекомендации по внесению вклада
- Не отправляйте ненужные файлы, такие как .vscode, .idea и т.д. Пожалуйста, используйте .gitignore для их фильтрации.
- Не отправляйте config.toml; вместо этого отправляйте config-example.toml.
## История звезд
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_vi.md

# # Công Cụ Dịch Thuật và Lồng Tiếng AI cho Âm Thanh & Video

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://x.com/KrillinAI)
[](https://discord.gg/sKUAsHfy)
[](https://space.bilibili.com/242124650)
### 📢 Phiên Bản Mới Cho Desktop Win & Mac – Chào Đón Trải Nghiệm Và Đóng Góp Ý Kiến
## Tổng Quan
Krillin AI là giải pháp toàn diện để địa phương hóa và nâng cấp video một cách dễ dàng. Công cụ tối giản nhưng mạnh mẽ này xử lý mọi thứ từ dịch thuật, lồng tiếng đến nhân bản giọng nói, định dạng – chuyển đổi liền mạch video giữa chế độ ngang và dọc để tối ưu hiển thị trên mọi nền tảng nội dung (YouTube, TikTok, Bilibili, Douyin, Kênh WeChat, RedNote, Kuaishou). Với quy trình làm việc end-to-end, Krillin AI biến footage thô thành nội dung hoàn thiện, sẵn sàng đăng tải chỉ với vài cú nhấp chuột.
## Tính năng chính:
🎯 **Khởi động một chạm** - Bắt đầu quy trình làm việc ngay lập tức, Phiên bản desktop mới - sử dụng dễ dàng hơn!
📥 **Tải video** - Hỗ trợ yt-dlp và tải file từ máy tính
📜 **Phụ đề chính xác** - Nhận diện với độ chính xác cao nhờ Whisper
🧠 **Phân đoạn thông minh** - Chia nhỏ và căn chỉnh phụ đề dựa trên LLM
🌍 **Dịch thuật chuyên nghiệp** - Dịch theo đoạn văn để đảm bảo tính nhất quán
🔄 **Thay thế thuật ngữ** - Đổi từ vựng chuyên ngành chỉ với một cú nhấp chuột
🎙️ **Lồng tiếng & Nhân bản giọng nói** - Lựa chọn giọng CosyVoice hoặc giọng nhân bản
🎬 **Tổng hợp video** - Tự động định dạng cho bố cục ngang/dọc
## Minh họa
Bức ảnh dưới đây thể hiện kết quả sau khi file phụ đề - được tạo tự động chỉ bằng một cú nhấp chuột từ video local 46 phút - được chèn vào timeline. Toàn bộ quá trình không hề có bất kỳ chỉnh sửa thủ công nào. Phụ đề hiển thị đầy đủ không bị thiếu hay chồng chéo, cách phân đoạn câu tự nhiên, chất lượng bản dịch cũng rất cao.

### Phụ đề dịch
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### Lồng tiếng
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### Dọc
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 Hỗ trợ Nhận dạng Giọng nói
_**Tất cả mô hình cục bộ trong bảng dưới đây hỗ trợ cài đặt tự động file thực thi + file mô hình. Chỉ cần lựa chọn, KrillinAI sẽ tự động xử lý phần còn lại cho bạn.**_
| Dịch vụ | Nền tảng hỗ trợ | Tùy chọn mô hình | Cục bộ/Đám mây | Ghi chú |
|-----------------|------------------------------|-----------------------------------|-------------|----------------|
| **OpenAI Whisper** | Đa nền tảng | - | Đám mây | Tốc độ nhanh với kết quả xuất sắc |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (recommend medium+) | Cục bộ | Tốc độ nhanh hơn, không phụ thuộc dịch vụ đám mây |
| **WhisperKit** | macOS (Apple Silicon only) | `large-v2` | Cục bộ | Tối ưu hóa riêng cho chip Apple |
| **Alibaba Cloud ASR** | Đa nền tảng | - | Đám mây | Không gặp vấn đề mạng tại Trung Quốc đại lục |
## 🚀 Hỗ trợ Mô hình Ngôn ngữ Lớn
✅ Tương thích với tất cả dịch vụ LLM đám mây/cục bộ tương thích **OpenAI API** bao gồm nhưng không giới hạn:
- OpenAI
- DeepSeek
- Qwen (Tongyi Qianwen)
- Các mô hình mã nguồn mở tự triển khai
- Các dịch vụ API tương thích định dạng OpenAI khác
## 🌍 Hỗ trợ Ngôn ngữ
Ngôn ngữ đầu vào: Hỗ trợ tiếng Trung, Anh, Nhật, Đức, Thổ Nhĩ Kỳ (đang tiếp tục bổ sung thêm)
Ngôn ngữ dịch: Hỗ trợ 101 ngôn ngữ bao gồm tiếng Anh, Trung, Nga, Tây Ban Nha, Pháp,...
## Xem trước giao diện

## 🚀 Bắt đầu nhanh
### Các bước cơ bản
Đầu tiên, tải file thực thi Release phù hợp với hệ thống thiết bị của bạn. Làm theo hướng dẫn dưới đây để chọn giữa phiên bản desktop hoặc non-desktop, sau đó đặt phần mềm vào thư mục trống. Chạy chương trình sẽ tạo ra một số thư mục, vì vậy việc đặt trong thư mục trống giúp quản lý dễ dàng hơn.
[Đối với phiên bản desktop (file release có chứa "desktop" trong tên), xem hướng dẫn tại đây]
Phiên bản desktop mới được phát hành để giải quyết khó khăn cho người mới trong việc chỉnh sửa file cấu hình. Phiên bản này vẫn còn một số lỗi và đang được cập nhật liên tục.
Nhấp đúp vào file để bắt đầu sử dụng.
[Đối với phiên bản non-desktop (file release không có "desktop" trong tên), xem hướng dẫn tại đây]
Phiên bản non-desktop là bản phát hành gốc, có cấu hình phức tạp hơn nhưng chức năng ổn định. Phiên bản này cũng phù hợp để triển khai trên server, vì cung cấp giao diện web.
Tạo thư mục config trong thư mục chứa phần mềm, sau đó tạo file config.toml trong đó. Sao chép nội dung từ file config-example.toml trong thư mục config của mã nguồn vào file config.toml của bạn và điền các thông tin cấu hình. (Nếu bạn muốn sử dụng các mô hình OpenAI nhưng không biết cách lấy key, có thể tham gia nhóm để được dùng thử miễn phí.)
Nhấp đúp vào file thực thi hoặc chạy trong terminal để khởi động dịch vụ.
Mở trình duyệt và truy cập http://127.0.0.1:8888 để bắt đầu sử dụng. (Thay 8888 bằng số cổng bạn đã chỉ định trong file config.)
### Dành cho người dùng macOS
[Đối với phiên bản desktop (file bản phát hành có chứa "desktop" trong tên), làm theo hướng dẫn sau]
Do vấn đề chứng thực, phiên bản desktop hiện chưa hỗ trợ chạy trực tiếp bằng double-click hoặc cài đặt qua DMG. Cần cấu hình thủ công như sau:
1. Mở Terminal và truy cập thư mục chứa file thực thi (giả sử tên file là KrillinAI_1.0.0_desktop_macOS_arm64)
2. Thực hiện lần lượt các lệnh sau:
```
sudo xattr -cr ./KrillinAI_1.0.0_desktop_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_desktop_macOS_arm64
./KrillinAI_1.0.0_desktop_macOS_arm64
```
[Đối với phiên bản non-desktop (file bản phát hành không có "desktop" trong tên), làm theo hướng dẫn sau]
Phần mềm này chưa được chứng thực, nên sau khi hoàn thành các bước cấu hình file ở mục "Các bước cơ bản", bạn cần thủ công cấp quyền trust ứng dụng trên macOS. Thực hiện theo các bước sau:
1. Mở Terminal và điều hướng đến thư mục chứa file thực thi (giả sử tên file là KrillinAI_1.0.0_macOS_arm64)
2. Thực hiện lần lượt các lệnh sau:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
Thao tác này sẽ khởi động dịch vụ.
### Triển khai bằng Docker
Dự án này hỗ trợ triển khai qua Docker. Vui lòng tham khảo [Docker Deployment Instructions](../docs/docker.md).
### Hướng dẫn cấu hình Cookie
Nếu gặp lỗi khi tải video xuống, vui lòng tham khảo [Cookie Configuration Instructions](./docs/get_cookies.md) để thiết lập thông tin cookie của bạn.
### Hướng dẫn cấu hình
Cách cấu hình nhanh chóng và tiện lợi nhất:
* Chọn openai cho cả transcription_provider và llm_provider. Với cách này, bạn chỉ cần điền openai.apikey trong ba nhóm cấu hình chính sau: openai, local_model và aliyun là có thể thực hiện dịch phụ đề. (Điền app.proxy, model và openai.base_url theo tình hình thực tế của bạn.)
Cách cấu hình sử dụng mô hình nhận dạng giọng nói cục bộ (tạm thời chưa hỗ trợ macOS) (lựa chọn cân bằng giữa chi phí, tốc độ và chất lượng):
* Điền fasterwhisper cho transcription_provider và openai cho llm_provider. Với cách này, bạn chỉ cần điền openai.apikey và local_model.faster_whisper trong hai nhóm cấu hình openai và local_model là có thể thực hiện dịch phụ đề. Mô hình cục bộ sẽ được tải xuống tự động. (Tương tự với app.proxy và openai.base_url như đã đề cập ở trên.)
Các trường hợp sử dụng sau yêu cầu cấu hình Alibaba Cloud:
* Nếu llm_provider điền aliyun nghĩa là sẽ sử dụng dịch vụ mô hình lớn của Alibaba Cloud, do đó cần cấu hình mục aliyun.bailian.
* Nếu transcription_provider điền aliyun, hoặc khi bật chức năng "lồng tiếng" khi bắt đầu tác vụ sẽ sử dụng dịch vụ giọng nói của Alibaba Cloud, do đó cần điền cấu hình mục aliyun.speech.
* Nếu bật chức năng "lồng tiếng" đồng thời tải lên file âm thanh cục bộ để nhân bản giọng nói thì sẽ sử dụng cả dịch vụ lưu trữ đám mây OSS của Alibaba Cloud, do đó cần điền cấu hình mục aliyun.oss.
Hướng dẫn cấu hình: [Alibaba Cloud Configuration Instructions](../docs/aliyun.md)
## Câu hỏi thường gặp
Vui lòng tham khảo [Frequently Asked Questions](../docs/faq.md)
## Hướng dẫn đóng góp
- Không gửi các file không cần thiết như .vscode, .idea,... Hãy sử dụng tốt file .gitignore để lọc chúng.
- Không gửi file config.toml mà hãy gửi file config-example.toml.
## Lịch sử sao
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/README_zh.md

# 极简部署AI视频翻译配音工具

**[English](../README.md)|[简体中文](../docs/README_zh.md)|[日本語](../docs/README_jp.md)|[한국어](../docs/README_kr.md)|[Tiếng Việt](../docs/README_vi.md)|[Français](../docs/README_fr.md)|[Deutsch](../docs/README_de.md)|[Español](../docs/README_es.md)|[Português](../docs/README_pt.md)|[Русский](../docs/README_rus.md)|[اللغة العربية](../docs/README_ar.md)**
[](https://jq.qq.com/?_wv=1027&k=754069680)
[](https://space.bilibili.com/242124650)
### 📢win&mac桌面端新发布 欢迎测试反馈[文档有点落后,持续更新中]
## 项目简介
Krillin AI 是一款全能型音视频本地化与增强解决方案。这款简约而强大的工具,集音视频翻译、配音、语音克隆于一身,支持横竖屏格式输出,确保在所有主流平台(哔哩哔哩,小红书,抖音,视频号,快手,YouTube,TikTok等)都能完美呈现。通过端到端的工作流程,Krillin AI 仅需点击几次,就能将原始素材转化为精美即用的跨平台内容。
## 主要特点与功能:
🎯 **一键启动**:无需复杂的环境配置,自动安装依赖,立即投入使用,新增桌面版本,使用更便捷!
📥 **视频获取**:支持yt-dlp下载或本地文件上传
📜 **精准识别**:基于Whisper的高准确度语音识别
🧠 **智能分段**:使用LLM进行字幕分段和对齐
🔄 **术语替换**:一键替换专业领域词汇
🌍 **专业翻译**:基于LLM,段落级翻译保持语义连贯性
🎙️ **配音克隆**:提供CosyVoice精选音色或自定义音色克隆
🎬 **视频合成**:自动处理横竖版视频和字幕排版
## 效果展示
下图为46分钟的本地视频导入,一键执行后生成的字幕文件入轨后的效果,无任何手动调整。无缺失、重叠,断句自然,翻译质量也非常高。

### 字幕翻译
---
https://github.com/user-attachments/assets/bba1ac0a-fe6b-4947-b58d-ba99306d0339
|
### 配音
---
https://github.com/user-attachments/assets/0b32fad3-c3ad-4b6a-abf0-0865f0dd2385
|
### 竖屏
---
https://github.com/user-attachments/assets/c2c7b528-0ef8-4ba9-b8ac-f9f92f6d4e71
|
## 🔍 语音识别服务支持
_**下表中的本地模型全部支持自动安装可执行文件+模型文件,你只要选择,其它的KrillinAI帮你全部准备完毕。**_
| 服务源 | 支持平台 | 模型可选项 | 本地/云端 | 备注 |
|----------------|------------------------------|-----------------------------------|-------|-------------|
| **OpenAI Whisper** | 全平台 | - | 云端 | 速度快效果好 |
| **FasterWhisper** | Windows/Linux | `tiny`/`medium`/`large-v2` (推荐medium+) | 本地 | 速度更快,无云服务开销 |
| **WhisperKit** | macOS (仅限M系列芯片) | `large-v2` | 本地 | Apple芯片原生优化 |
| **阿里云ASR** | 全平台 | - | 云端 | 避免中国大陆网络问题 |
## 🚀 大模型支持
✅ 兼容所有符合 **OpenAI API规范** 的云端/本地大模型服务,包括但不限于:
- OpenAI
- DeepSeek
- 通义千问
- 本地部署的开源模型
- 其他兼容OpenAI格式的API服务
## 语言支持
输入语言支持:中文,英文,日语,德语,土耳其,韩语,俄语,马来语(持续增加中)
翻译语言支持:英文,中文,俄语,西班牙语,法语等101种语言
## 界面预览

## 🚀 快速开始
### 基本步骤
首先下载[Release](https://github.com/krillinai/KrillinAI/releases)中与你设备系统匹配的可执行文件,按照下面的教程选择桌面版还是非桌面版,然后放入空文件夹,把软件下载到一个空文件夹,因为运行之后会生成一些目录,放到空文件夹会好管理一些。
【如果是桌面版,即release文件带desktop的看此处】
_桌面版是新发布的,为了解决新手用户难以正确编辑配置文件的问题,还有不少bug,持续更新中_
1. 双击文件即可开始使用(桌面端也是需要配置的,在软件内配置)
【如果是非桌面版,即release文件不带desktop的看此处】
_非桌面版是一开始的版本,配置比较复杂,但是功能稳定,同时适合服务器部署,因为会以web的方式提供ui_
1. 在文件夹内创建`config`文件夹,然后在`config`文件夹创建`config.toml`文件,复制源代码`config`目录下的`config-example.toml`文件的内容填入`config.toml`,并对照填写你的配置信息。
2. 双击,或在终端执行可执行文件,启动服务
3. 打开浏览器,输入`http://127.0.0.1:8888`,开始使用 (8888替换成你在配置文件中填写的端口)
### To: macOS用户
【如果是桌面版,即release文件带desktop的看此处】
桌面端目前打包方式由于签名等问题,还不能够做到双击直接运行或者dmg安装,需要手动信任应用,方法如下:
1. 在终端打开可执行文件(假设文件名是KrillinAI_1.0.0_desktop_macOS_arm64)所在目录
2. 依次执行以下命令:
```
sudo xattr -cr ./KrillinAI_1.0.0_desktop_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_desktop_macOS_arm64
./KrillinAI_1.0.0_desktop_macOS_arm64
```
【如果是非桌面版,即release文件不带desktop的看此处】
本软件没有做签名,因此在macOS上运行时,在完成“基本步骤”中的文件配置后,还需要手动信任应用,方法如下:
1. 在终端打开可执行文件(假设文件名是KrillinAI_1.0.0_macOS_arm64)所在目录
2. 依次执行以下命令:
```
sudo xattr -rd com.apple.quarantine ./KrillinAI_1.0.0_macOS_arm64
sudo chmod +x ./KrillinAI_1.0.0_macOS_arm64
./KrillinAI_1.0.0_macOS_arm64
```
即可启动服务
### Docker部署
本项目支持Docker部署,请参考[Docker部署说明](./docker.md)
### Cookie配置说明(非必选)
如果你遇到视频下载失败的情况
请参考 [Cookie 配置说明](./get_cookies.md) 配置你的Cookie信息。
### 配置帮助(必看)
最快速便捷的配置方式:
* `transcription_provider`和`llm_provider`都选择`openai`,这样在下方`openai`、`local_model`、`aliyun`三个配置项大类里只需要填写`openai.apikey`就可以进行字幕翻译。(`app.proxy`、`model`和`openai.base_url`按自己情况选填)
使用本地语言识别模型(暂不支持macOS)的配置方式(兼顾成本、速度与质量的选择)
* `transcription_provider`填写`fasterwhisper`,`llm_provider`填写`openai`,这样在下方`openai`、`local_model`三个配置项大类里只需要填写`openai.apikey`和`local_model.faster_whisper`就可以进行字幕翻译,本地模型会自动下载。(`app.proxy`和`openai.base_url`同上)
以下几种使用情况,需要进行阿里云的配置:
* 如果`llm_provider`填写了`aliyun`,需要使用阿里云的大模型服务,因此需要配置`aliyun.bailian`项的配置
* 如果`transcription_provider`填写了`aliyun`,或者在启动任务时开启了“配音”功能,都需要使用阿里云的语音服务,因此需要填写`aliyun.speech`项的配置
* 如果开启了“配音”功能,同时上传了本地的音频做音色克隆,则还需要使用阿里云的OSS云存储服务,因此需要填写`aliyun.oss`项的配置
阿里云配置帮助:[阿里云配置说明](./aliyun.md)
## 常见问题
请移步[常见问题](./faq.md)
## 贡献规范
1. 不要提交无用文件,如.vscode、.idea等,请善于使用.gitignore过滤
2. 不要提交config.toml,而是使用config-example.toml提交
## 联系我们
1. 加入我们的QQ群,解答问题:754069680
2. 关注我们的社交媒体账号,[哔哩哔哩](https://space.bilibili.com/242124650),每天分享AI科技领域优质内容
## Star History
[](https://star-history.com/#krillinai/KrillinAI&Date)
## /docs/aliyun.md
## 前提条件
需要先有[阿里云](https://www.aliyun.com)账号并经过实名认证,多数服务有免费额度
## 阿里云百炼平台密钥获取
1. 登录[阿里云百炼大模型服务平台](https://bailian.console.aliyun.com/),鼠标悬停于页面右上角的个人中心图标上,在下拉菜单中单击API-KEY

2. 在左侧导航栏,选择全部API-KEY或我的API-KEY,然后创建或查看API Key
## 阿里云`access_key_id`和`access_key_secret`获取
1. 进入[阿里云AccessKey管理页面](https://ram.console.aliyun.com/profile/access-keys)
2. 点击创建AccessKey,如需要选择使用方式,选择“本地开发环境中使用”

3. 妥善保管,最好复制到本地文件保存
## 阿里云语音服务开通
1. 进入[阿里云语音服务管理页面](https://nls-portal.console.aliyun.com/applist),首次进入需开通服务
2. 点击创建项目

3. 选择功能并开通

4. “流式文本语音合成(CosyVoice大模型)”需要升级成商业版,其它服务可以用免费体验版

5. 复制app key即可

## 阿里云OSS服务开通
1. 进入[阿里云对象存储服务控制台](https://oss.console.aliyun.com/overview),首次进入需开通服务
2. 左侧选择Bucket列表,然后点击创建

3. 选择快捷创建,填写符合要求的Bucket名称并选择**上海**地域,完成创建(此处填写的名字就是配置项`aliyun.oss.bucket`的值)

4. 创建完成后进入Bucket

5. 将“阻止公共访问”开关关闭,并设置读写权限为“公共读”


## /docs/docker.md
# Docker 部署指南
## 快速开始
先准备好配置文件,设置服务器监听端口为`8888`、服务器监听地址为`0.0.0.0`
### docker run启动
```bash
docker run -d \
-p 8888:8888 \
-v /path/to/config.toml:/app/config/config.toml \
asteria798/krillinai
```
### docker-compose启动
```yaml
version: '3'
services:
krillin:
image: asteria798/krillinai
ports:
- "8888:8888"
volumes:
- /path/to/config.toml:/app/config/config.toml
```
## 持久化模型
如果使用fasterwhisper模型, KrillinAI 会自动下载模型所需文件到`/app/models`目录和`/app/bin`目录。容器删除后,这些文件会丢失。如果需要持久化模型,可以将这两个目录映射到宿主机的目录。
### docker run启动
```bash
docker run -d \
-p 8888:8888 \
-v /path/to/config.toml:/app/config/config.toml \
-v /path/to/models:/app/models \
-v /path/to/bin:/app/bin \
krillinai/krillin
```
### docker-compose启动
```yaml
version: '3'
services:
krillin:
image: krillinai/krillin
ports:
- "8888:8888"
volumes:
- /path/to/config.toml:/app/config/config.toml
- /path/to/models:/app/models
- /path/to/bin:/app/bin
```
## 注意事项
1. 如果docker容器的网络模式不为host,建议将配置文件服务器监听地址设置为`0.0.0.0`,否则可能无法访问服务。
2. 如果容器内需要访问宿主机的网络代理,请将代理地址配置项`proxy`的`127.0.0.1`设置为`host.docker.internal`,例如`http://host.docker.internal:7890`
## /docs/faq.md
### 1. 看不到`app.log`配置文件,无法知道报错内容
Windows用户请将本软件的工作目录放在非C盘的文件夹。
### 2. 非桌面版明明创建了配置文件,但还是报错“找不到配置文件”
确保配置文件名是`config.toml`,而不是`config.toml.txt`或其它。
配置完成后,本软件的工作文件夹的结构应该是这样的:
```
/── config/
│ └── config.toml
├── cookies.txt (<- 可选的cookies.txt文件)
└── krillinai.exe
```
### 3. 填写了大模型配置,但是报错“xxxxx需要配置xxxxx API Key”
模型服务和语音服务虽然可以都用openai的服务,但是也有大模型单独使用非openai的场景,因此这两块配置是分开的,除了大模型配置,请往配置下方找whisper配置填写对应的密钥等信息。
### 3. 报错内含“yt-dlp error”
视频下载器的问题,目前看来无非就是网络问题或者下载器版本问题,检查下网络代理有没有打开并且配置到配置文件的代理配置项,同时建议选择香港节点。下载器是本软件自动安装的,安装的源我会更新但毕竟不是官方源,所以可能会有落后,遇到问题尝试手动更新一下,更新方法:
在软件bin目录位置打开终端,执行
```
./yt-dlp.exe -U
```
此处`yt-dlp.exe`替换为你系统实际的ytdlp软件名称。
## /docs/get_cookies.md
# Cookie 配置说明
## 问题说明
在生成字幕的时候,可能会遇到出错的情况,例如“Sign in to confirm you are not a bot”:
这是因为:
1. 部分视频平台需要用户登录信息才能获取高质量视频
2. 您当前的代理的ip不够纯净,已被视频网站官方限制
## 解决方法
### 1. 安装浏览器扩展
根据你使用的浏览器选择安装:
- Chrome浏览器: [Get CookieTxt Locally](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc)
- Edge浏览器: [Export Cookies File](https://microsoftedge.microsoft.com/addons/detail/export-cookies-file/hbglikhfdcfhdfikmocdflffaecbnedo)
### 2. 导出Cookie文件
1. 登录需要下载视频的网站(如B站、YouTube等)
2. 点击浏览器扩展图标
3. 选择"Export Cookies"选项
4. 将导出的cookies.txt文件保存到本软件所在的目录下
5. 如果导出的文件名不是cookies.txt,请将文件名改为cookies.txt
图示:

导出后,工具的工作文件夹的结构应该是这样的:
```
/── config/
│ └── config.toml
├── tasks/
├── cookies.txt (<- 导出的cookies.txt文件)
└── krillinai.exe
```
## /docs/images/alignment.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/alignment.png
## /docs/images/aliyun_accesskey_1.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_accesskey_1.png
## /docs/images/aliyun_oss_1.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_oss_1.png
## /docs/images/aliyun_oss_2.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_oss_2.png
## /docs/images/aliyun_oss_3.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_oss_3.png
## /docs/images/aliyun_oss_4.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_oss_4.png
## /docs/images/aliyun_oss_5.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_oss_5.png
## /docs/images/aliyun_speech_1.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_speech_1.png
## /docs/images/aliyun_speech_2.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_speech_2.png
## /docs/images/aliyun_speech_3.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_speech_3.png
## /docs/images/aliyun_speech_4.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/aliyun_speech_4.png
## /docs/images/bailian_1.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/bailian_1.png
## /docs/images/export_cookies.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/export_cookies.png
## /docs/images/logo.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/logo.png
## /docs/images/ui.jpg
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/ui.jpg
## /docs/images/ui_desktop.png
Binary file available at https://raw.githubusercontent.com/krillinai/KrillinAI/refs/heads/main/docs/images/ui_desktop.png
## /go.mod
```mod path="/go.mod"
module krillin-ai
go 1.22
require (
fyne.io/fyne/v2 v2.5.4
github.com/BurntSushi/toml v1.4.0
github.com/aliyun/alibaba-cloud-sdk-go v1.63.72
github.com/aliyun/alibabacloud-oss-go-sdk-v2 v1.1.3
github.com/gin-gonic/gin v1.10.0
github.com/go-resty/resty/v2 v2.7.0
github.com/google/uuid v1.4.0
github.com/gorilla/websocket v1.5.0
github.com/samber/lo v1.38.1
github.com/sashabaranov/go-openai v1.36.0
go.uber.org/zap v1.25.0
golang.org/x/sync v0.9.0
)
require (
fyne.io/systray v1.11.0 // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fredbi/uri v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect
github.com/fyne-io/glfw-js v0.0.0-20241126112943-313d8a0fe1d0 // indirect
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/go-text/render v0.2.0 // indirect
github.com/go-text/typesetting v0.2.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rymdport/portal v0.3.0 // indirect
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/yuin/goldmark v1.7.1 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 // indirect
golang.org/x/image v0.18.0 // indirect
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/time v0.4.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
```
## /go.sum
```sum path="/go.sum"
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
fyne.io/fyne/v2 v2.5.4 h1:bg/joTgXZj2pRVOY5g3o4ZHY0ZE2w+4zs4ZKG+Xhg64=
fyne.io/fyne/v2 v2.5.4/go.mod h1:0GOXKqyvNwk3DLmsFu9v0oYM0ZcD1ysGnlHCerKoAmo=
fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.72 h1:HvFZUzEbNvfe8F2Mg0wBGv90bPhWDxgVtDHR5zoBOU0=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.72/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
github.com/aliyun/alibabacloud-oss-go-sdk-v2 v1.1.3 h1:grJyLSdRJtfxKKhCTWSeJhnOQsp2WoLNdK8XA5FE9oo=
github.com/aliyun/alibabacloud-oss-go-sdk-v2 v1.1.3/go.mod h1:FTzydeQVmR24FI0D6XWUOMKckjXehM/jgMn1xC+DA9M=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8=
github.com/fredbi/uri v1.1.0/go.mod h1:aYTUoAXBOq7BLfVJ8GnKmfcuURosB1xyHDIfWeC/iW4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe h1:A/wiwvQ0CAjPkuJytaD+SsXkPU0asQ+guQEIg1BJGX4=
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe/go.mod h1:d4clgH0/GrRwWjRzJJQXxT/h1TyuNSfF/X64zb/3Ggg=
github.com/fyne-io/glfw-js v0.0.0-20241126112943-313d8a0fe1d0 h1:/1YRWFv9bAWkoo3SuxpFfzpXH0D/bQnTjNXyF4ih7Os=
github.com/fyne-io/glfw-js v0.0.0-20241126112943-313d8a0fe1d0/go.mod h1:gsGA2dotD4v0SR6PmPCYvS9JuOeMwAtmfvDE7mbYXMY=
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 h1:hnLq+55b7Zh7/2IRzWCpiTcAvjv/P8ERF+N7+xXbZhk=
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk=
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/go-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc=
github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU=
github.com/go-text/typesetting v0.2.0 h1:fbzsgbmk04KiWtE+c3ZD4W2nmCRzBqrqQOvYlwAOdho=
github.com/go-text/typesetting v0.2.0/go.mod h1:2+owI/sxa73XA581LAzVuEBZ3WEEV2pXeDswCH/3i1I=
github.com/go-text/typesetting-utils v0.0.0-20240317173224-1986cbe96c66 h1:GUrm65PQPlhFSKjLPGOZNPNxLCybjzjYBzjfoBGaDUY=
github.com/go-text/typesetting-utils v0.0.0-20240317173224-1986cbe96c66/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20211219123610-ec9572f70e60/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 h1:Po+wkNdMmN+Zj1tDsJQy7mJlPlwGNQd9JZoPjObagf8=
github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49/go.mod h1:YiutDnxPRLk5DLUFj6Rw4pRBBURZY07GFr54NdV9mQg=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e h1:LvL4XsI70QxOGHed6yhQtAU34Kx3Qq2wwBzGFKY8zKk=
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/rymdport/portal v0.3.0 h1:QRHcwKwx3kY5JTQcsVhmhC3TGqGQb9LFghVNUy8AdB8=
github.com/rymdport/portal v0.3.0/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/sashabaranov/go-openai v1.36.0 h1:fcSrn8uGuorzPWCBp8L0aCR95Zjb/Dd+ZSML0YZy9EI=
github.com/sashabaranov/go-openai v1.36.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE=
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U=
github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE=
golang.org/x/exp v0.0.0-20221031165847-c99f073a8326/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a h1:sYbmY3FwUWCBTodZL1S3JUuOvaW6kM2o+clDzzDNBWg=
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a/go.mod h1:Ede7gF0KGoHlj822RtphAHK1jLdrcuRBZg0sF1Q+SPc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
```
## /internal/api/subtitle.go
```go path="/internal/api/subtitle.go"
package api
import (
"fmt"
"os"
"path/filepath"
"time"
)
// WordReplacement 词语替换
type WordReplacement struct {
From string `json:"from"`
To string `json:"to"`
}
// SubtitleTask 字幕任务
type SubtitleTask struct {
URL string `json:"url"` // 视频URL
Language string `json:"language"` // 界面语言
OriginLang string `json:"origin_lang"` // 源语言
TargetLang string `json:"target_lang"` // 目标语言
Bilingual int `json:"bilingual"` // 是否双语 1:是 2:否
TranslationSubtitlePos int `json:"translation_subtitle_pos"` // 翻译字幕位置 1:上方 2:下方
TTS int `json:"tts"` // 是否配音 1:是 2:否
TTSVoiceCode int `json:"tts_voice_code,omitempty"` // 配音声音代码 1:女声 2:男声
TTSVoiceCloneSrcFileURL string `json:"tts_voice_clone_src_file_url,omitempty"` // 音色克隆源文件URL
ModalFilter int `json:"modal_filter"` // 是否过滤语气词 1:是 2:否
Replace []string `json:"replace,omitempty"` // 词汇替换列表
EmbedSubtitleVideoType string `json:"embed_subtitle_video_type"` // 字幕嵌入视频类型 none:不嵌入 horizontal:横屏 vertical:竖屏 all:全部
VerticalMajorTitle string `json:"vertical_major_title,omitempty"` // 竖屏主标题
VerticalMinorTitle string `json:"vertical_minor_title,omitempty"` // 竖屏副标题
}
// SubtitleResult 字幕结果
type SubtitleResult struct {
Name string `json:"name"` // 文件名
DownloadURL string `json:"download_url"` // 下载URL
}
// TaskStatus 任务状态
type TaskStatus struct {
TaskId string `json:"task_id"` // 任务ID
ProcessPercent int `json:"process_percent"` // 处理进度百分比
Status string `json:"status"` // 任务状态
Message string `json:"message"` // 状态消息
SubtitleInfo []SubtitleResult `json:"subtitle_info"` // 字幕信息
SpeechDownloadURL string `json:"speech_download_url"` // 配音下载URL
}
// CreateSubtitleTask 创建字幕任务
func CreateSubtitleTask(task *SubtitleTask) (*TaskStatus, error) {
// 生成任务ID
taskId := generateTaskId()
// 创建任务目录
taskDir := filepath.Join("tasks", taskId)
if err := createTaskDirectory(taskDir); err != nil {
return nil, fmt.Errorf("创建任务目录失败: %v", err)
}
// 启动异步任务处理
go processTask(taskId, task)
return &TaskStatus{
TaskId: taskId,
ProcessPercent: 0,
Status: "created",
Message: "任务已创建",
}, nil
}
// GetSubtitleTaskStatus 获取任务状态
func GetSubtitleTaskStatus(taskId string) (*TaskStatus, error) {
// 获取任务状态
status, err := getTaskStatus(taskId)
if err != nil {
return nil, fmt.Errorf("获取任务状态失败: %v", err)
}
// 如果任务完成,添加下载链接
if status.ProcessPercent >= 100 {
status.SubtitleInfo = []SubtitleResult{
{
Name: "字幕.srt",
DownloadURL: fmt.Sprintf("/tasks/%s/output/subtitle.srt", taskId),
},
{
Name: "字幕.ass",
DownloadURL: fmt.Sprintf("/tasks/%s/output/subtitle.ass", taskId),
},
}
// 如果启用了配音,添加配音下载链接
if status.SpeechDownloadURL == "" {
status.SpeechDownloadURL = fmt.Sprintf("/tasks/%s/output/speech.mp3", taskId)
}
}
return status, nil
}
// 以下是辅助函数,需要在实际使用时实现
func generateTaskId() string {
// TODO: 实现任务ID生成逻辑
return "task-" + time.Now().Format("20060102150405")
}
func createTaskDirectory(taskDir string) error {
// TODO: 实现任务目录创建逻辑
return os.MkdirAll(taskDir, 0755)
}
func processTask(taskId string, task *SubtitleTask) {
// TODO: 实现任务处理逻辑
// 1. 下载视频
// 2. 提取音频
// 3. 语音识别
// 4. 翻译字幕
// 5. 生成字幕文件
// 6. 如果需要,生成配音
// 7. 如果需要,嵌入字幕到视频
// 8. 更新任务状态
}
func getTaskStatus(taskId string) (*TaskStatus, error) {
// TODO: 实现任务状态获取逻辑
return &TaskStatus{
TaskId: taskId,
ProcessPercent: 50,
Status: "processing",
Message: "正在处理中",
}, nil
}
```
The content has been capped at 50000 tokens, and files over NaN bytes have been omitted. The user could consider applying other filters to refine the result. The better and more specific the context, the better the LLM can follow instructions. If the context seems verbose, the user can refine the filter using uithub. Thank you for using https://uithub.com - Perfect LLM context for any GitHub repo.