free-short-video 6.4.1 → 6.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -2
- package/core/api/agnes_chat.py +10 -6
- package/core/api/agnes_image.py +13 -7
- package/core/api/agnes_models.py +2 -2
- package/core/api/agnes_video.py +16 -9
- package/core/api/rate_limiter.py +11 -5
- package/core/config.py +107 -17
- package/package.json +1 -1
- package/static/assets/ar-DD2gvMKw.js +1 -0
- package/static/assets/bn-DPcCDLpk.js +1 -0
- package/static/assets/de-DFxaRKtY.js +1 -0
- package/static/assets/es-DoMCctKF.js +1 -0
- package/static/assets/fa-BzEKx0PN.js +1 -0
- package/static/assets/fr-C0bWeTQ6.js +1 -0
- package/static/assets/hi-C_hrAd50.js +1 -0
- package/static/assets/id-BlECjGv5.js +1 -0
- package/static/assets/index-BNSSpVol.css +1 -0
- package/static/assets/index-DD5NtUvj.js +45 -0
- package/static/assets/it-BCF04BbE.js +1 -0
- package/static/assets/ja--ICvVBr-.js +1 -0
- package/static/assets/ko-DAjiyyWl.js +1 -0
- package/static/assets/ms-DamV6gQc.js +1 -0
- package/static/assets/nl-BOMKQzmH.js +1 -0
- package/static/assets/pt-CC05NXdy.js +1 -0
- package/static/assets/ru-DPWcNyU1.js +1 -0
- package/static/assets/th-9kl-UM3z.js +1 -0
- package/static/assets/tl-4mRVYM2I.js +1 -0
- package/static/assets/tr-dfD9cPiH.js +1 -0
- package/static/assets/ur-L0V50o2j.js +1 -0
- package/static/assets/vi-ChKtUMhj.js +1 -0
- package/static/index.html +2 -2
- package/web/routes/config_routes.py +126 -1
- package/static/assets/ar-Co0g8IHi.js +0 -1
- package/static/assets/bn-CEnXv-Ci.js +0 -1
- package/static/assets/de-DFCb-VQb.js +0 -1
- package/static/assets/es-BB_h_gjW.js +0 -1
- package/static/assets/fa-1AsF74IR.js +0 -1
- package/static/assets/fr-D46wN4E5.js +0 -1
- package/static/assets/hi-c8b3jY49.js +0 -1
- package/static/assets/id-BHQhGk9v.js +0 -1
- package/static/assets/index-B9DuV3Tq.css +0 -1
- package/static/assets/index-Cg4TCtV5.js +0 -45
- package/static/assets/it-WSb6hkMy.js +0 -1
- package/static/assets/ja-CnXP4P5V.js +0 -1
- package/static/assets/ko-DHM410FB.js +0 -1
- package/static/assets/ms-BbdBN1mH.js +0 -1
- package/static/assets/nl-ClA4sipR.js +0 -1
- package/static/assets/pt-5buuwYmD.js +0 -1
- package/static/assets/ru-BeoxxbcJ.js +0 -1
- package/static/assets/th-D0e7n9S1.js +0 -1
- package/static/assets/tl-Ci8Qz9u5.js +0 -1
- package/static/assets/tr-BJqJ4N-5.js +0 -1
- package/static/assets/ur-BFgi64hX.js +0 -1
- package/static/assets/vi-DkyI43Z4.js +0 -1
package/README.md
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
|
-
# What's New in v6.4.
|
|
3
|
+
# What's New in v6.4.2
|
|
4
4
|
|
|
5
5
|
## What's New
|
|
6
6
|
|
|
7
|
+
### Features & Improvements
|
|
8
|
+
|
|
9
|
+
* **Per-Key domain binding** — each API Key saved in the projects config can now carry its own access domain (`com` / `cn` / `cn_bak`), so keys issued on the global site and keys issued on the domestic site can coexist and be routed to the correct endpoint automatically. Keys can from the environment still use the global domain.
|
|
10
|
+
|
|
11
|
+
* **One-click "Auto-detect domains" button** — in the API Key config panel, trigger a probe that tests each key across the candidate domains and fills in the matching domain automatically, instead of guessing it by hand.
|
|
12
|
+
|
|
13
|
+
* **Restored China fallback domain** **`apihub.agnes-ai.cn`** — this endpoint accepts both domestic and global keys, giving users a migration path when their key domain changes. It is not listed in the official docs and may be removed later, so we recommend choosing the domain that matches your key.
|
|
14
|
+
|
|
7
15
|
### Bug Fixes
|
|
8
16
|
|
|
9
|
-
* **Fixed
|
|
17
|
+
* **Fixed multi-key authentication failures across domains** — after the Chinese domain migration, global-site keys could fail authentication against the strict domestic endpoint; domain is now resolved per key with the restored fallback, so mixed global/domestic keys authenticate successfully.
|
|
18
|
+
|
|
19
|
+
* **Domain mismatch hints in the config UI** — keys without a bound domain now show a clear "domain not set" hint, prompting users to pick or auto-detect the matching domain on their next visit.
|
|
10
20
|
|
|
11
21
|
|
|
12
22
|
---
|
package/core/api/agnes_chat.py
CHANGED
|
@@ -16,7 +16,6 @@ import requests
|
|
|
16
16
|
|
|
17
17
|
from core.api.error_collector import collect_error, collect_error_from_exception
|
|
18
18
|
from core.api.rate_limiter import get_rate_limiter, request_with_key_rotation
|
|
19
|
-
from core.config import get_agnes_base_url
|
|
20
19
|
|
|
21
20
|
logger = logging.getLogger(__name__)
|
|
22
21
|
|
|
@@ -69,13 +68,18 @@ class AgnesChatAPI:
|
|
|
69
68
|
# 向后兼容:旧调用方可能读取 self.headers
|
|
70
69
|
self.headers = dict(self._base_headers)
|
|
71
70
|
|
|
72
|
-
def _auth_headers(self) -> dict:
|
|
73
|
-
"""每次请求前生成带当前 Key 的 headers
|
|
71
|
+
def _auth_headers(self, key: str | None = None) -> dict:
|
|
72
|
+
"""每次请求前生成带当前 Key 的 headers 副本。
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
key: 显式指定 Key(供按 Key 绑定域名路由时与 URL 保持一致)。
|
|
76
|
+
省略时从 KeyRing 轮转取当前 Key。
|
|
77
|
+
"""
|
|
74
78
|
from core.api.key_manager import get_key_ring
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
k = key or get_key_ring().next()
|
|
77
81
|
h = dict(self._base_headers)
|
|
78
|
-
h["Authorization"] = f"Bearer {
|
|
82
|
+
h["Authorization"] = f"Bearer {k}"
|
|
79
83
|
return h
|
|
80
84
|
|
|
81
85
|
def _image_to_b64_uri(self, path: str) -> str:
|
|
@@ -128,7 +132,7 @@ class AgnesChatAPI:
|
|
|
128
132
|
get_rate_limiter().acquire()
|
|
129
133
|
resp = request_with_key_rotation(
|
|
130
134
|
requests.post,
|
|
131
|
-
|
|
135
|
+
"/chat/completions",
|
|
132
136
|
max_retries=_MAX_RETRIES,
|
|
133
137
|
retry_base_delay=_RETRY_BASE_DELAY,
|
|
134
138
|
json=payload,
|
package/core/api/agnes_image.py
CHANGED
|
@@ -12,7 +12,7 @@ import requests
|
|
|
12
12
|
from core.api.error_collector import collect_error, collect_error_from_exception
|
|
13
13
|
from core.api.key_manager import get_key_ring
|
|
14
14
|
from core.api.rate_limiter import get_rate_limiter
|
|
15
|
-
from core.config import
|
|
15
|
+
from core.config import get_base_url_for_key
|
|
16
16
|
from utils.image import download_image
|
|
17
17
|
from utils.image_normalizer import normalize_reference_path
|
|
18
18
|
|
|
@@ -77,11 +77,16 @@ class AgnesImageAPI:
|
|
|
77
77
|
# 向后兼容:旧调用方可能读取 self.headers
|
|
78
78
|
self.headers = dict(self._base_headers)
|
|
79
79
|
|
|
80
|
-
def _auth_headers(self) -> dict:
|
|
81
|
-
"""每次请求前生成带当前 Key 的 headers
|
|
82
|
-
|
|
80
|
+
def _auth_headers(self, key: str | None = None) -> dict:
|
|
81
|
+
"""每次请求前生成带当前 Key 的 headers 副本。
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
key: 显式指定 Key(供按 Key 绑定域名路由时与 URL 保持一致)。
|
|
85
|
+
省略时从 KeyRing 轮转取当前 Key。
|
|
86
|
+
"""
|
|
87
|
+
k = key or get_key_ring().next()
|
|
83
88
|
h = dict(self._base_headers)
|
|
84
|
-
h["Authorization"] = f"Bearer {
|
|
89
|
+
h["Authorization"] = f"Bearer {k}"
|
|
85
90
|
return h
|
|
86
91
|
|
|
87
92
|
async def _path_to_b64(self, path: str) -> str:
|
|
@@ -156,10 +161,11 @@ class AgnesImageAPI:
|
|
|
156
161
|
await get_rate_limiter().acquire_async()
|
|
157
162
|
# 动态超时:第一次 120s,后续逐步增加(图像生成较慢,放宽读超时)
|
|
158
163
|
read_timeout = _READ_TIMEOUT_BASE_SECONDS * (attempt + 1)
|
|
164
|
+
key = ring.next()
|
|
159
165
|
resp = await asyncio.to_thread(
|
|
160
166
|
requests.post,
|
|
161
|
-
f"{
|
|
162
|
-
headers=self._auth_headers(),
|
|
167
|
+
f"{get_base_url_for_key(key)}/images/generations",
|
|
168
|
+
headers=self._auth_headers(key),
|
|
163
169
|
json=payload,
|
|
164
170
|
timeout=(30, read_timeout),
|
|
165
171
|
)
|
package/core/api/agnes_models.py
CHANGED
|
@@ -12,7 +12,7 @@ from core.config import (
|
|
|
12
12
|
DEFAULT_IMAGE_MODEL,
|
|
13
13
|
DEFAULT_TEXT_MODEL,
|
|
14
14
|
DEFAULT_VIDEO_MODEL,
|
|
15
|
-
|
|
15
|
+
get_base_url_for_key,
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
logger = logging.getLogger(__name__)
|
|
@@ -52,7 +52,7 @@ def fetch_available_models(api_key: str) -> dict:
|
|
|
52
52
|
接口失败(网络/鉴权/非 200)时返回硬编码兜底列表。
|
|
53
53
|
"""
|
|
54
54
|
try:
|
|
55
|
-
endpoint = f"{
|
|
55
|
+
endpoint = f"{get_base_url_for_key(api_key)}/models?all=true"
|
|
56
56
|
resp = requests.get(
|
|
57
57
|
endpoint,
|
|
58
58
|
headers={"Authorization": f"Bearer {api_key}"},
|
package/core/api/agnes_video.py
CHANGED
|
@@ -17,7 +17,7 @@ from core.api.rate_limiter import get_rate_limiter, get_video_submit_limiter
|
|
|
17
17
|
from core.config import (
|
|
18
18
|
VIDEO_ASPECT_RATIOS,
|
|
19
19
|
get_agnes_api_root,
|
|
20
|
-
|
|
20
|
+
get_base_url_for_key,
|
|
21
21
|
is_v25_video_model,
|
|
22
22
|
)
|
|
23
23
|
from utils.image_normalizer import normalize_reference_path
|
|
@@ -118,11 +118,16 @@ class AgnesVideoAPI:
|
|
|
118
118
|
# 向后兼容:旧调用方可能读取 self.headers
|
|
119
119
|
self.headers = dict(self._base_headers)
|
|
120
120
|
|
|
121
|
-
def _auth_headers(self) -> dict:
|
|
122
|
-
"""每次请求前生成带当前 Key 的 headers
|
|
123
|
-
|
|
121
|
+
def _auth_headers(self, key: str | None = None) -> dict:
|
|
122
|
+
"""每次请求前生成带当前 Key 的 headers 副本。
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
key: 显式指定 Key(供按 Key 绑定域名路由时与 URL 保持一致)。
|
|
126
|
+
省略时从 KeyRing 轮转取当前 Key。
|
|
127
|
+
"""
|
|
128
|
+
k = key or get_key_ring().next()
|
|
124
129
|
h = dict(self._base_headers)
|
|
125
|
-
h["Authorization"] = f"Bearer {
|
|
130
|
+
h["Authorization"] = f"Bearer {k}"
|
|
126
131
|
return h
|
|
127
132
|
|
|
128
133
|
def _path_to_b64(self, path: str) -> str:
|
|
@@ -202,10 +207,11 @@ class AgnesVideoAPI:
|
|
|
202
207
|
}
|
|
203
208
|
logger.info(f"[AgnesVideo] Uploading image to hosted URL (attempt {attempt + 1}/{retries})...")
|
|
204
209
|
await get_rate_limiter().acquire_async(self.shutdown_event)
|
|
210
|
+
key = ring.next()
|
|
205
211
|
resp = await asyncio.to_thread(
|
|
206
212
|
requests.post,
|
|
207
|
-
f"{
|
|
208
|
-
headers=self._auth_headers(),
|
|
213
|
+
f"{get_base_url_for_key(key)}/images/generations",
|
|
214
|
+
headers=self._auth_headers(key),
|
|
209
215
|
json=payload,
|
|
210
216
|
timeout=(30, 120),
|
|
211
217
|
)
|
|
@@ -405,11 +411,12 @@ class AgnesVideoAPI:
|
|
|
405
411
|
# 2.3 异步原生,停止可打断)
|
|
406
412
|
await get_video_submit_limiter().acquire_async(self.shutdown_event)
|
|
407
413
|
# M2: 缩短读超时从 180s 到 60s,使 stop() 更快生效
|
|
414
|
+
key = ring.next()
|
|
408
415
|
resp = await asyncio.wait_for(
|
|
409
416
|
asyncio.to_thread(
|
|
410
417
|
requests.post,
|
|
411
|
-
f"{
|
|
412
|
-
headers=self._auth_headers(),
|
|
418
|
+
f"{get_base_url_for_key(key)}/videos",
|
|
419
|
+
headers=self._auth_headers(key),
|
|
413
420
|
json=payload,
|
|
414
421
|
timeout=(15, 60),
|
|
415
422
|
),
|
package/core/api/rate_limiter.py
CHANGED
|
@@ -269,7 +269,7 @@ def reset_rate_limiter() -> None:
|
|
|
269
269
|
|
|
270
270
|
def request_with_key_rotation(
|
|
271
271
|
requester,
|
|
272
|
-
|
|
272
|
+
endpoint: str,
|
|
273
273
|
*,
|
|
274
274
|
max_retries: int = 3,
|
|
275
275
|
retry_base_delay: float = 20.0,
|
|
@@ -279,7 +279,8 @@ def request_with_key_rotation(
|
|
|
279
279
|
"""429 换 Key 立即重试;全 Key 429 或 5xx/超时/连接错误才指数退避。
|
|
280
280
|
|
|
281
281
|
规则:
|
|
282
|
-
1. 每请求前 key_ring.next()(round-robin,均匀分摊),生成带当前 Key 的 headers
|
|
282
|
+
1. 每请求前 key_ring.next()(round-robin,均匀分摊),生成带当前 Key 的 headers,
|
|
283
|
+
并按该 Key 绑定域名构造 URL(``get_base_url_for_key``,未绑定回退全局域名)
|
|
283
284
|
2. 429 且 has_multiple() -> key_ring.rotate() 立即重试(不 sleep、不计入退避)
|
|
284
285
|
—— Key 级隔离限速,换 Key 后配额是满的
|
|
285
286
|
3. 所有 Key 均 429(rotation 计数达到 len(keys) × 退避上限)-> 指数退避
|
|
@@ -287,7 +288,8 @@ def request_with_key_rotation(
|
|
|
287
288
|
|
|
288
289
|
Args:
|
|
289
290
|
requester: 可调用 (url, headers, **kw) -> requests.Response。
|
|
290
|
-
|
|
291
|
+
endpoint: API 接口相对路径(如 "/chat/completions")。完整 URL 依当前 Key
|
|
292
|
+
绑定域名经 ``get_base_url_for_key`` 动态拼接。
|
|
291
293
|
max_retries: 退避重试上限。
|
|
292
294
|
retry_base_delay: 指数退避基数(秒),delay = 基数 × (retries + 1)。
|
|
293
295
|
key_ring: KeyRing 实例;None 时取全局单例。
|
|
@@ -302,6 +304,8 @@ def request_with_key_rotation(
|
|
|
302
304
|
"""
|
|
303
305
|
import requests
|
|
304
306
|
|
|
307
|
+
from core.config import get_base_url_for_key
|
|
308
|
+
|
|
305
309
|
ring = key_ring or get_key_ring()
|
|
306
310
|
base_headers = requester_kwargs.pop("headers", None) or {}
|
|
307
311
|
retries = 0
|
|
@@ -309,8 +313,10 @@ def request_with_key_rotation(
|
|
|
309
313
|
max_rotations = len(ring) * max_retries
|
|
310
314
|
while True:
|
|
311
315
|
# 每请求前轮转 Key:round-robin 均匀分摊;429 换 Key(rotate 推进计数)后
|
|
312
|
-
# 下次 next() 自然取到下一个 Key
|
|
313
|
-
|
|
316
|
+
# 下次 next() 自然取到下一个 Key。URL 按该 Key 绑定域名动态拼接。
|
|
317
|
+
key = ring.next()
|
|
318
|
+
headers = {**base_headers, "Authorization": f"Bearer {key}"}
|
|
319
|
+
url = f"{get_base_url_for_key(key)}{endpoint}"
|
|
314
320
|
try:
|
|
315
321
|
resp = requester(url, headers=headers, **requester_kwargs)
|
|
316
322
|
except (requests.ConnectionError, requests.Timeout) as e:
|
package/core/config.py
CHANGED
|
@@ -18,7 +18,7 @@ CONFIG_FILE = os.path.join(CONFIG_DIR, "config.json")
|
|
|
18
18
|
# ═══════════════════════════════════════════════════
|
|
19
19
|
# 应用版本号(v6.1 新增:发版时同步更新,见 docs/dev/release_process.md)
|
|
20
20
|
# ═══════════════════════════════════════════════════
|
|
21
|
-
APP_VERSION = "6.4.
|
|
21
|
+
APP_VERSION = "6.4.2"
|
|
22
22
|
|
|
23
23
|
# 未配置 API Key 时的统一报错文案(含免费获取与在线体验兜底,全站路由共用)
|
|
24
24
|
API_KEY_MISSING_MSG = (
|
|
@@ -334,7 +334,7 @@ def get_api_keys() -> list:
|
|
|
334
334
|
"""返回所有可用 API Key(去重、去空),合并顺序:
|
|
335
335
|
|
|
336
336
|
1. 环境变量 / .env:AGNES_API_KEY, AGNES_API_KEY_2 ... _N(环境变量覆盖 .env)
|
|
337
|
-
2. 配置文件:api_keys
|
|
337
|
+
2. 配置文件:api_keys 列表(新字段,条目可为字符串或 {key, domain})或旧 api_key 单个字段
|
|
338
338
|
|
|
339
339
|
两来源合并后去重(同 Key 只保留一次,env 位置优先)。因此:
|
|
340
340
|
- Web UI 保存的多 Key(config)与 env Key 可并存;
|
|
@@ -345,22 +345,86 @@ def get_api_keys() -> list:
|
|
|
345
345
|
cfg_keys = config.get("api_keys", []) or []
|
|
346
346
|
if not cfg_keys and config.get("api_key"):
|
|
347
347
|
cfg_keys = [config["api_key"]]
|
|
348
|
-
cfg_keys = [k for k in cfg_keys if k]
|
|
348
|
+
cfg_keys = [_extract_key(k) for k in cfg_keys if _extract_key(k)]
|
|
349
349
|
return _dedup(env_keys + cfg_keys)
|
|
350
350
|
|
|
351
351
|
|
|
352
|
+
def _extract_key(entry) -> str:
|
|
353
|
+
"""从 api_keys 条目中提取 Key 明文(兼容字符串或 {key, domain} 字典)。"""
|
|
354
|
+
if isinstance(entry, dict):
|
|
355
|
+
return str(entry.get("key") or "").strip()
|
|
356
|
+
return str(entry or "").strip()
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def _key_domain_from_config(config: dict, key: str) -> str:
|
|
360
|
+
"""从已加载的 config dict 中查找某 Key 绑定的域名(未绑定返回空串)。"""
|
|
361
|
+
entries = config.get("api_keys", []) or []
|
|
362
|
+
if isinstance(entries, dict):
|
|
363
|
+
entries = [entries]
|
|
364
|
+
for e in entries:
|
|
365
|
+
if isinstance(e, dict) and _extract_key(e) == key:
|
|
366
|
+
return str(e.get("domain") or "").strip()
|
|
367
|
+
return ""
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def get_api_key_domains() -> dict:
|
|
371
|
+
"""返回 config 中每个 Key 绑定的域名(key -> domain,env key 不在内)。
|
|
372
|
+
|
|
373
|
+
Returns:
|
|
374
|
+
{"sk-...": "com"|"cn"|"cn_bak"|"", ...}
|
|
375
|
+
未绑定的 Key 值为空串。
|
|
376
|
+
"""
|
|
377
|
+
config = load_config()
|
|
378
|
+
out: dict = {}
|
|
379
|
+
entries = config.get("api_keys", []) or []
|
|
380
|
+
if isinstance(entries, dict):
|
|
381
|
+
entries = [entries]
|
|
382
|
+
for e in entries:
|
|
383
|
+
k = _extract_key(e)
|
|
384
|
+
if not k or k in out:
|
|
385
|
+
continue
|
|
386
|
+
d = ""
|
|
387
|
+
if isinstance(e, dict):
|
|
388
|
+
d = str(e.get("domain") or "").strip()
|
|
389
|
+
out[k] = d
|
|
390
|
+
return out
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def set_api_key_domains(mapping: dict) -> None:
|
|
394
|
+
"""按 key -> domain 写入 config api_keys 的域名绑定(仅 config 来源 key)。
|
|
395
|
+
|
|
396
|
+
未提及的 config key 保留其现有 domain;无效域名(不在 AGNES_DOMAIN_MAP)视为空。
|
|
397
|
+
不涉及 env key(env key 无法落盘,始终走全局默认域名)。
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
mapping: {key 明文: 域名},domain 为空串表示清除绑定(回退全局域名)。
|
|
401
|
+
"""
|
|
402
|
+
config = load_config()
|
|
403
|
+
curr = get_api_key_domains()
|
|
404
|
+
for k, d in mapping.items():
|
|
405
|
+
k = _extract_key(k)
|
|
406
|
+
d = str(d or "").strip()
|
|
407
|
+
if k:
|
|
408
|
+
curr[k] = d if d in AGNES_DOMAIN_MAP else ""
|
|
409
|
+
config["api_keys"] = [{"key": k, "domain": curr[k]} for k in curr]
|
|
410
|
+
config.pop("api_key", None)
|
|
411
|
+
save_config(config)
|
|
412
|
+
|
|
413
|
+
|
|
352
414
|
def set_api_keys(keys: list) -> None:
|
|
353
415
|
"""持久化多 Key 到配置文件 ``api_keys`` 字段(原子写 + 0o600 权限)。
|
|
354
416
|
|
|
355
417
|
keys 为空数组时:移除配置中的 api_keys 字段,使采集回退到 env(.env/环境变量)。
|
|
418
|
+
已存在的 Key 会保留其域名绑定(仅对仍在 keys 中的 Key)。
|
|
356
419
|
|
|
357
420
|
写入后必须在调用侧重建 KeyRing 与限速器(reset_key_ring / reset_rate_limiter),
|
|
358
421
|
否则旧配置(单桶 + 旧 KeyRing)继续生效。
|
|
359
422
|
"""
|
|
360
423
|
config = load_config()
|
|
361
|
-
|
|
424
|
+
current = get_api_key_domains()
|
|
425
|
+
cleaned = _dedup([_extract_key(k) for k in keys])
|
|
362
426
|
if cleaned:
|
|
363
|
-
config["api_keys"] = cleaned
|
|
427
|
+
config["api_keys"] = [{"key": k, "domain": current.get(k, "")} for k in cleaned]
|
|
364
428
|
config.pop("api_key", None)
|
|
365
429
|
else:
|
|
366
430
|
config.pop("api_keys", None)
|
|
@@ -373,7 +437,7 @@ def _collect_config_keys() -> list:
|
|
|
373
437
|
cfg_keys = config.get("api_keys", []) or []
|
|
374
438
|
if not cfg_keys and config.get("api_key"):
|
|
375
439
|
cfg_keys = [config["api_key"]]
|
|
376
|
-
return _dedup([k for k in cfg_keys if k])
|
|
440
|
+
return _dedup([_extract_key(k) for k in cfg_keys if _extract_key(k)])
|
|
377
441
|
|
|
378
442
|
|
|
379
443
|
def get_api_keys_with_sources() -> list:
|
|
@@ -410,18 +474,18 @@ def remove_api_key_single(key: str) -> tuple:
|
|
|
410
474
|
"""
|
|
411
475
|
config = load_config()
|
|
412
476
|
changed = False
|
|
413
|
-
# 1. 从 api_keys
|
|
414
|
-
|
|
415
|
-
if key in
|
|
416
|
-
|
|
477
|
+
# 1. 从 api_keys 列表移除(保留其余条目的 domain 绑定)
|
|
478
|
+
raw_cfg = config.get("api_keys", []) or []
|
|
479
|
+
if any(_extract_key(e) == key for e in raw_cfg):
|
|
480
|
+
kept = [e for e in raw_cfg if _extract_key(e) != key]
|
|
417
481
|
changed = True
|
|
418
482
|
# 2. 命中旧 api_key 字段
|
|
419
483
|
if config.get("api_key") == key:
|
|
420
484
|
config.pop("api_key", None)
|
|
421
485
|
changed = True
|
|
422
486
|
if changed:
|
|
423
|
-
if
|
|
424
|
-
config["api_keys"] =
|
|
487
|
+
if kept:
|
|
488
|
+
config["api_keys"] = kept
|
|
425
489
|
else:
|
|
426
490
|
config.pop("api_keys", None)
|
|
427
491
|
save_config(config)
|
|
@@ -967,11 +1031,18 @@ def get_video_model_capabilities() -> dict:
|
|
|
967
1031
|
|
|
968
1032
|
# 可用域名映射
|
|
969
1033
|
# 注:Agnes 官方域名划分(来源:AgnesAI-Labs skills 的 model_catalog 参考值):
|
|
970
|
-
# - com 国际站(主):apihub.agnes-ai.com
|
|
971
|
-
# - cn 国内站(中国站):api.agnes-ai.cn
|
|
1034
|
+
# - com 国际站(主):apihub.agnes-ai.com(官方文档,接受国际站 key)
|
|
1035
|
+
# - cn 国内站(中国站):api.agnes-ai.cn(官方文档,仅接受国内站专属 key,国际站 key 会 401)
|
|
1036
|
+
# - cn_bak 国内站备用端点:apihub.agnes-ai.cn
|
|
1037
|
+
# ⚠️ 官方文档未提及,仅作临时备用,后续可能下线
|
|
1038
|
+
# ⚠️ 该端点接受国际站 key(在 platform.agnes-ai.com 领取的 key),
|
|
1039
|
+
# 避免切换 cn 后因国际站 key 撞上 api.agnes-ai.cn 得到 401。
|
|
1040
|
+
# ⚠️ 推荐用户选择与自身 key 匹配的域名:key 是国际站 → 用 com / cn_bak;
|
|
1041
|
+
# key 是国内站专属 → 用 cn(api.agnes-ai.cn)。长期仍应跟随官方文档域名。
|
|
972
1042
|
AGNES_DOMAIN_MAP = {
|
|
973
|
-
"com": "https://apihub.agnes-ai.com",
|
|
974
|
-
"cn": "https://api.agnes-ai.cn",
|
|
1043
|
+
"com": "https://apihub.agnes-ai.com", # 国际站(官方文档)
|
|
1044
|
+
"cn": "https://api.agnes-ai.cn", # 国内站(官方文档,需国内站专属 key)
|
|
1045
|
+
"cn_bak": "https://apihub.agnes-ai.cn", # 国内站备用(官方文档未提及,可能下线;接受国际站 key)
|
|
975
1046
|
}
|
|
976
1047
|
|
|
977
1048
|
_DEFAULT_DOMAIN = "com"
|
|
@@ -998,12 +1069,31 @@ def set_agnes_domain(domain: str):
|
|
|
998
1069
|
|
|
999
1070
|
|
|
1000
1071
|
def get_agnes_base_url() -> str:
|
|
1001
|
-
"""
|
|
1072
|
+
"""返回基于当前全局域名配置的完整 API Base URL(含 /v1 后缀)。
|
|
1073
|
+
|
|
1074
|
+
未绑定域名的 Key 与 env Key 以及模型列表等全局操作均走这里。
|
|
1075
|
+
"""
|
|
1002
1076
|
domain = get_agnes_domain()
|
|
1003
1077
|
root = AGNES_DOMAIN_MAP.get(domain, AGNES_DOMAIN_MAP[_DEFAULT_DOMAIN])
|
|
1004
1078
|
return f"{root}/v1"
|
|
1005
1079
|
|
|
1006
1080
|
|
|
1081
|
+
def get_base_url_for_key(key: str) -> str:
|
|
1082
|
+
"""返回某 Key 应使用的 API Base URL(含 /v1 后缀),按 Key 绑定域名路由。
|
|
1083
|
+
|
|
1084
|
+
- 若该 Key 在配置中绑定了有效域名(com/cn/cn_bak)→ 走该域名;
|
|
1085
|
+
- 否则(未绑定 / env key / 无效域名)→ 回退到全局 agnes_domain。
|
|
1086
|
+
|
|
1087
|
+
供各 API 客户端在选中具体 Key 后据此构造请求 URL。
|
|
1088
|
+
"""
|
|
1089
|
+
config = load_config()
|
|
1090
|
+
domain = _key_domain_from_config(config, key)
|
|
1091
|
+
if domain not in AGNES_DOMAIN_MAP:
|
|
1092
|
+
domain = config.get("agnes_domain") or _DEFAULT_DOMAIN
|
|
1093
|
+
root = AGNES_DOMAIN_MAP.get(domain, AGNES_DOMAIN_MAP[_DEFAULT_DOMAIN])
|
|
1094
|
+
return f"{root}/v1"
|
|
1095
|
+
|
|
1096
|
+
|
|
1007
1097
|
def get_agnes_api_root() -> str:
|
|
1008
1098
|
"""返回基于当前域名配置的 API Root URL(不含 /v1 后缀)。"""
|
|
1009
1099
|
domain = get_agnes_domain()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-short-video",
|
|
3
|
-
"version": "6.4.
|
|
3
|
+
"version": "6.4.2",
|
|
4
4
|
"description": "Free AI short-video generator — run the full free-short-video service locally with one command. Text-to-video, image generation, Edge-TTS narration, subtitles, and compositing, all free. Official site: https://video.lichuanyang.top",
|
|
5
5
|
"bin": {
|
|
6
6
|
"free-short-video": "bin/cli.js",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e="فيديو بالذكاء الاصطناعي، بضغطة واحدة",t="إعداد مفتاح API",o="غير مهيأ",n="مهيأ",s="أدخل مفتاح Agnes API الخاص بك (احصل عليه مجانًا من platform.agnes-ai.com)",c="مهيأ (●●●)",a="حفظ",i="مسح",r="هل أنت متأكد من مسح مفتاح API المهيأ",l="مهيأ (متغير بيئة)",p="تم تعيين مفتاح API عبر متغير البيئة AGNES_API_KEY ولا يمكن مسحه من الواجهة. أزل متغير البيئة ثم أعد المحاولة.",d="اختيار النموذج",m="اختر نماذج Agnes المستخدمة في التوليد. نماذج الصور والفيديو غير متاحة بعد؛ احتفظ بالإعدادات الافتراضية.",u="نموذج النص / المحادثة",g="نموذج الصور (غير متاح بعد)",f="نموذج الفيديو",S="Video model",b="Video model capabilities",P="Capability",y="Price",v="Modes",h="Duration",C="Resolution",R="Negative prompt",T="Ref. video",k="Paid",A="Free",M="Yes",w="No",I="Modes",H="Durations",D="Resolution",E="Negative prompt",L="Ref images",F="Ref. video",x="Negative prompt is not supported by this model",N="Aspect ratio",V="Quality",G="Up to",K="Negative prompt not supported by this model",B="short edge px",U="720P = short edge 720px; output size scales with ratio",O="تحديث القائمة",q="غير متزامن",W="تم الحفظ",_="agnes-2.5-flash قيد الإصدار التجريبي: يتطلب مفتاح API مع صلاحية تجريبية، وإلا ستفشل الاستدعاءات.",z=" (تجريبي)",Q="نص",Y="صورة",j="فيديو",J="نموذج النص لا يمكن أن يكون فارغًا",X="فشل الجلب",Z="فشل الحفظ",$="دليل العمل",ee="غير محدد",te="نشط",oe="إضافة",ne='انقر على "تصفح" على اليمين لاختيار الدليل',se="الاسم (اختياري)",ce="تفعيل",ae="إزالة",ie="الحالي",re="مساحة العمل النشطة",le="تصفح…",pe="افتراضي",de="كل المساحات",me='انقر على "تفعيل" لتبديل دليل العمل الحالي',ue="هذه مساحة اختبار الانحدار، مقفلة بواسطة متغير البيئة ولا يمكن تعديلها من الواجهة.",ge="إزالة هذا الدليل من القائمة (لن يتم حذف الملفات من القرص)",fe="مهمة جديدة",Se="قائمة المهام",be="علامة مائية للفيديو",Pe="أضف علامة Agnes Video Generator المائية لمساعدة المزيد من المبدعين على اكتشاف هذه الأداة",ye="تم تفعيل العلامة المائية",ve="تم تعطيل العلامة المائية",he="صورة وفيديو",Ce="فيديو إبداعي",Re="فيديو مقال",Te="النوع",ke="🎬 فيديو",Ae="🖼️ صورة",Me="إعدادات الفيديو البسيط",we="الإعدادات الإبداعية",Ie="إعدادات المقال",He="وصف الفيديو",De="قطة برتقالية تغفو على عتبة النافذة بعد المطر، ضوء الشمس يتسلل عبر الزجاج، الستارة تتحرك مع النسيم، 4K واقعي",Ee="وضع التوليد",Le="نص إلى فيديو",Fe="صورة إلى فيديو",xe="إطارات مفتاحية",Ne="المدة",Ve="الدقة",Ge="عمودي 9:16",Ke="أفقي 16:9",Be="مربع 1:1",Ue="صورة مرجعية",Oe="صورة الإطار الأخير",qe="اختيار صورة",We="لم يتم الاختيار",_e="إعدادات متقدمة",ze="اختياري",Qe="اتركه فارغًا لعشوائية",Ye="العناصر المطلوب استبعادها",je="اسم المهمة",Je="اختياري، يولّد تلقائيًا إذا تركت فارغًا",Xe="وصف الفكرة",Ze="روبوت يسقي زهرة صغيرة في مدينة مهجورة، 3 مشاهد: اكتشاف الشتلة، إحضار الماء، تفتح الزهرة",$e="النمط البصري",et="3 مشاهد، كل مشهد 5 ثوانٍ، جودة سينمائية",tt="أسلوب واقعي سينمائي",ot="وضع التتابع",nt="keyframes (موصى به)",st="ti2vid (انتقال)",ct="none (مستقل)",at="صورة مرجعية (اختياري)",it="اختياري. إذا قدمتها، ستستخدمها جميع المشاهد كمرساة بصرية؛ وإلا ستولّد تلقائيًا من القصة.",rt="إطارات نهاية مخصصة",lt="تفعيل",pt="توليد من المرجع (i2i)",dt="إطار نهاية واحد لكل مشهد، بالترتيب.",mt="مشهد",ut="+ إضافة إطار نهاية",gt="إعدادات الصوت",ft="إعدادات الترجمة",St="التعليق الصوتي",bt="الترجمة",Pt="الصوت",yt="السرعة",vt="عادي",ht="اختيار الصوت",Ct="ابحث عن اسم الصوت أو الأسلوب...",Rt="الحالي",Tt="تأكيد",kt="إلغاء",At="تأكيد",Mt="معاينة",wt="إيقاف",It="فشلت المعاينة، قد لا يدعم هذا الصوت هذه اللغة",Ht="قد لا يكون هذا الصوت متوافقًا مع اللغة الحالية. هل تريد استخدامه",Dt="أنثى",Et="ذكر",Lt="لا توجد أصوات مطابقة",Ft="نمط الترجمة",xt="الخط",Nt="اللون",Vt="الحجم",Gt="الموضع",Kt="أسفل",Bt="أعلى",Ut="لون الحدود",Ot="سماكة الحدود",qt="لون الخلفية",Wt="وضع النمط",_t="ثابت",zt="ذكاء اصطناعي",Qt="تفضيلات النمط",Yt="صف كيف يجب أن تتغير الموضع واللون والحجم للترجمة. سيخصص الذكاء الاصطناعي نمطًا لكل ترجمة.",jt="نص المقال",Jt="الصق مقالك أو بيانك الصحفي أو تدوينتك. مثال: مقدمة منتج من 500 كلمة أو مقال سفر — سيقسم النظام تلقائيًا إلى مشاهد",Xt="حرف",Zt="بدء التوليد",$t="جارٍ الإرسال...",eo="المهمة قيد التنفيذ...",to="جارٍ التحميل...",oo="لا توجد مهام",no="فشل التحميل",so="التقدم",co="إيقاف المهمة",ao="إرسال",io="توليد الفيديو",ro="تهيئة",lo="إعداد المشاهد",po="تحليل الصور",mo="القصة",uo="مرجع الشخصية",go="السيناريو",fo="أوامر الإطار الأخير",So="توليد الإطار الأخير",bo="توليد الفيديو",Po="الصوت",yo="الترجمة",vo="الدمج",ho="تقسيم النص",Co="أوامر المشاهد",Ro="توليد الفيديو",To="الصوت",ko="الترجمة",Ao="الدمج",Mo="اكتمل توليد الفيديو!",wo="اكتملت المهمة",Io="معرف المهمة",Ho="الدليل",Do="الفكرة",Eo="عدد المشاهد",Lo="التتابع",Fo="إعداد المشاهد",xo="مصدر معلومات المشاهد",No="يدوي",Vo="استخراج من الفكرة",Go="حدد عدد المشاهد ومدتها يدويًا",Ko="سيحلل الذكاء الاصطناعي عدد المشاهد ومدتها من الفكرة",Bo="مدة المشاهد",Uo="موحد",Oo="مستقل",qo="ثانية",Wo="الناتج",_o="فقرات",zo="مكتمل",Qo="قيد التنفيذ",Yo="فشل",jo="قيد الانتظار",Jo="في الطابور",Xo="تحليل الصور",Zo="القصة",$o="السيناريو",en="مرجع الشخصية",tn="مطالبات الإطار النهائي",on="الإطارات النهائية",nn="معلومات المهمة",sn="الفكرة",cn="نص المخطوطة",an="نص التقديم",rn="وصف المذيع",ln="نص القصيدة",pn="المطالبة",dn="العرض",mn="الارتفاع",un="عدد المشاهد",gn="عدد الفقرات",fn="وضع التسلسل",Sn="النمط",bn="وضع الصوت",Pn="الوضع",yn="المدة",vn="نقاط الإيقاف",hn="اختر نقاط التحقق للتوقف في الوضع اليدوي؛ غير المحددة تُمرَّر تلقائياً",Cn="القصة المصورة",Rn="الصور المرجعية",Tn="مقاطع الفيديو",kn="التعليق الصوتي",An="الترجمة النصية",Mn="التركيب",wn="هذا النوع من المهام لا يدعم الوضع اليدوي",In="جارٍ تغيير وضع التنفيذ...",Hn="تم تغيير وضع التنفيذ",Dn="فشل تغيير الوضع",En="التبديل إلى تلقائي",Ln="التبديل إلى يدوي",Fn="التبديل إلى الوضع التلقائي سيمسح نقاط الإيقاف وينفذ حتى النهاية. متابعة؟",xn="التبديل إلى الوضع اليدوي سيتوقف عند نقطة التحقق التالية لمراجعتك. متابعة؟",Nn="في انتظارك",Vn="المهمة متوقفة عند نقطة تحقق؛ راجع أو عدّل المخرجات ثم تابع",Gn="نقطة التحقق",Kn="تم",Bn="قيد الانتظار",Un="قيد التشغيل",On="كيفية معالجة نقطة التحقق هذه",qn="تعديل بالذكاء الاصطناعي",Wn="صف التغيير؛ سيقوم النظام بتعديل المخرجات تلقائياً",_n="تعديل بنفسي",zn="اطلع على المسارات، عدّل الملفات محلياً، ثم أكّد",Qn="وكيل خارجي",Yn="انسخ الأمر والمطالبة، استخدم وكيلاً محلياً، ثم أكّد",jn="طلب التعديل",Jn="مثال: اجعل سرد المشهد 2 أكثر عامية",Xn="بدء التعديل",Zn="الذكاء الاصطناعي يعدّل...",$n="نتيجة التعديل",es="تطبيق وتأكيد",ts="تجاهل",os="مسار المخرَج",ns="متطلبات التنسيق",ss="الأثر بعد التعديل",cs="تم التعديل، متابعة",as="الأمر",is="المطالبة",rs="تم، متابعة",ls="🔗 المزيد من أدوات الذكاء الاصطناعي المجانية",ps="نسخ",ds="لا توجد مخرجات قابلة للتعديل في نقطة التحقق هذه",ms="فشل التعديل بالذكاء الاصطناعي",us="فشل المتابعة",gs="تم التأكيد، جارٍ المتابعة",fs="فشل إعادة الإنشاء",Ss="إعادة إنشاء",bs="ستُحذف المخرجات المتأثرة وتُعاد إنشاؤها؛ غير المتأثرة تُحتفظ بها",Ps="يرجى مراجعة وتحسين مخرجات نقطة التحقق هذه في دليل المهمة {dir}. أبلغني بالنتيجة عند الانتهاء، وسأضغط «تم التعديل، متابعة» في واجهة الويب.\\\\n\\\\nالمتطلبات:\\\\n1. حافظ على تنسيق المخرجات وبنيتها\\\\n2. عدّل المحتوى الدلالي فقط\\\\n3. أبلغ عن الملفات التي تم تغييرها",ys="سيُحذف ويُعاد تشغيله",vs="مُحتفظ به، بدون إعادة تشغيل",hs="تأكيد الحذف وإعادة التشغيل",Cs="إلغاء",Rs="لا توجد مخرجات متأثرة؛ تابع مباشرة",Ts="معلمات المهمة",ks="الدقة",As="الصوت",Ms="cd {dir} && traework\\ncd {dir} && opencode\\n# or another local agent (workbuddy / CodeBuddy CLI, etc.)",ws="Awaiting you",Is="Back",Hs="Stages",Ds="Expand",Es="Collapse",Ls="Waiting",Fs="عرض",xs="التقدم",Ns="استئناف",Vs="إيقاف",Gs=" مشهد",Ks=" فقرة",Bs="بسيط",Us="إبداعي",Os="مقال",qs="صورة",Ws="إيقاف المهمة الحالية يمكن استئنافها من قائمة المهام.",_s="إيقاف هذه المهمة يمكن استئنافها لاحقًا.",zs="تم إيقاف المهمة، يمكن استئنافها من القائمة",Qs="تم إيقاف المهمة",Ys="الرجاء إدخال مفتاح API",js="الرجاء وصف الفيديو",Js="الرجاء وصف فكرتك",Xs="الرجاء إدخال نص المقال",Zs="هناك مهمة قيد التنفيذ أو في الطابور بالفعل",$s="فشل الإنشاء",ec="فشل الاستئناف",tc="فشل التحميل",oc="فشل الإيقاف",nc="جارٍ الإيقاف...",sc="تم إرسال المهمة، الرجاء الانتظار",cc="تم استئناف المهمة، الرجاء الانتظار",ac="يرجى مراقبة سجلات وحدة التحكم والانتظار بصبر.",ic="المهمة",rc="فشلت المهمة",lc="افحص سجلات وحدة التحكم، ثم استأنف من قائمة المهام.",pc="الانتقال إلى قائمة المهام",dc="انقطع الاتصال",mc="انقطع الاتصال الفوري مع الخادم. قد لا يزال الخادم يعمل في الخلفية. تحقق من الحالة في قائمة المهام.",uc="الانتقال إلى قائمة المهام",gc="انقطع الاتصال، جارٍ إعادة المحاولة...",fc="مذيع رقمي",Sc="نطاق Agnes",bc="اختر نطاق الوصول إلى Agnes API. في الصين يُنصح باستخدام .cn للحصول على اتصال أكثر استقرارًا.",Pc="دولي",yc="الصين (موصى به)",vc="الصين احتياطي (غير مذكور في الوثائق الرسمية، قد يُحذف)",hc="تم الحفظ",Cc="فشل الحفظ",Rc="فيديو شعر",Tc="إعدادات الشعر",kc="نص القصيدة",Ac="أدخل نص القصيدة كاملاً",Mc="يمكن أن تكون عدة مقاطع، مفصولة بسطر جديد أو علامات ترقيم. سيقسم الذكاء الاصطناعي إلى مشاهد حسب المعنى.",wc="أوامر المشاهد (اختياري)",Ic="التنسيق: بيت | وصف بصري (مشهد واحد في كل سطر)",Hc='اختياري. مشهد واحد في كل سطر، بتنسيق ثابت "بيت | وصف بصري". الطريقتان تعطيان نفس النتيجة: ① اتركه فارغًا، سيولده النظام؛ ② انسخ الأمر أدناه إلى أي ذكاء اصطناعي وألصق النتيجة هنا.',Dc="مثال: الربيع لا يدرك الفجر... | صباح ربيعي ضبابي، غناء العصافير",Ec="توليد المشاهد بذكاء اصطناعي آخر",Lc="عرض الأمر",Fc="يتضمن الأمر عدد المشاهد ومدتها المضبوطين أعلاه، مطابق تمامًا لأمر النظام. انسخه إلى أي ذكاء اصطناعي، أدخل قصيدتك، ودعه يولّد المشاهد، ثم ألصق النتيجة في المربع أعلاه.",xc="إدخال القصيدة ونسخ الأمر",Nc="المدة الإجمالية",Vc="0=تلقائي",Gc="تستخدم ترجمة الشعر نمطًا ثابتًا عامًا (أسفل المنتصف، نص أبيض بحدود سوداء) — يمكن التبديل فقط، دون تخصيص.",Kc="تقسيم المشاهد",Bc="توليد الفيديو",Uc="الإلقاء",Oc="الترجمة",qc="الدمج",Wc="الرجاء إدخال نص القصيدة",_c="صورة بسيطة",zc="إعدادات الصورة",Qc="وصف الصورة",Yc="بحيرة عند سفح جبال ثلجية، ضباب الصباح، انعكاس الجبال في الماء، إضاءة سينمائية، أفقي",jc="حجم الصورة",Jc="اختياري. ارفع لتوليد أشكال مختلفة؛ اتركه فارغًا لتوليد بالذكاء الاصطناعي الخالص.",Xc="توليد الصورة",Zc="اكتمل توليد الصورة!",$c="جارٍ التوليد...",ea="الرجاء إدخال وصف الصورة",ta="إعدادات المذيع الرقمي",oa="وصف المذيع",na="مذيع أخبار محترف يرتدي بدلة، يجلس في استوديو أخبار حديث...",sa="صورة مرجعية (اختياري)",ca="اختياري. ارفع لضبط مظهر المذيع؛ اتركه فارغًا لتوليد بالذكاء الاصطناعي الخالص.",aa="نص التعليق",ia="مرحبًا بكم في نشرة الأخبار التقنية اليوم. الخبر الأول: دخل توليد الفيديو بالذكاء الاصطناعي عصرًا مجانيًا...",ra="عمودي 9:16 (HD)",la="متطلبات موضع الترجمة",pa="ضع الترجمة في الثلث السفلي من الشاشة، وتجنب تغطية وجه المذيع",da="مذيع",ma="مصدر الصوت",ua="صوت ما بعد التركيب",ga="جودة الصوت قابلة للتحكم (الصوت، السرعة)، لكن مطابقة الشفاه أصعب",fa="صوت النموذج",Sa="الصوت يتحكم فيه النموذج، التأثير غير قابل للتنبؤ؛ لا توجد خيارات للصوت/السرعة",ba="توليد صورة المذيع",Pa="تقسيم النص",ya="توليد أوامر المقاطع",va="توليد فيديو المقاطع",ha="توليد الصوت",Ca="توليد الترجمة",Ra="دمج الفيديو",Ta="أمر النظام",ka="تعليمات إضافية للنموذج (مثل الأسلوب والجودة)، لا تؤثر على وصف المحتوى الرئيسي",Aa="النواتج الوسيطة",Ma="تحليل الصور",wa="القصة",Ia="مرجع الشخصية",Ha="السيناريو",Da="أوامر الإطار الأخير",Ea="إطار نهاية المشهد {index}",La="فيديو المشهد {index}",Fa="صوت التعليق",xa="الترجمة",Na="الفيديو النهائي",Va="صورة المذيع",Ga="أوامر المقطع",Ka="مقطع فيديو",Ba="فيديو الفقرة {index}",Ua="أوامر المشاهد",Oa="حذف هذا الناتج ستحذف جميع النواتج اللاحقة وسيتم إرجاع حالة المهمة.",qa="سيتم حذف الملفات التالية",Wa="سيتم إعادة تعيين الخطوات التالية",_a="تم حذف الناتج",za="فشل الحذف",Qa="انقر للمعاينة",Ya="جارٍ بدء المهمة...",ja="احصل على مفتاح API مجانًا",Ja="دليل الإعداد",Xa="جرّبه عبر الإنترنت",Za="🎯 نصائح الأوامر",$a="🧠 مقارنة النماذج",ei="📋 أمثلة أوامر الفيديو البسيط",ti="📋 أمثلة أوامر الفيديو الإبداعي",oi="📋 أمثلة فيديو المقال",ni="📋 أمثلة المذيع الرقمي",si="💡 أثناء الانتظار، شاهد ما ينشئه الآخرون بـ Agnes",ci="📈 خطط وسائل التواصل",ai="🎬 المزيد من اتجاهات الإبداع",ii="⭐ ادعم المشروع",ri="مجاني بالكامل ومفتوح المصدر، لا رسوم أبدًا. ادعم المشروع:",li="⭐ امنح نجمة",pi="ساعد المزيد من الناس على اكتشاف هذه الأداة",di="🔓 تعطيل AdBlock",mi="أوقف حظر الإعلانات على الموقع الرسمي",ui="👆 اضغط على إعلان",gi="نقرة صغيرة، دعم حقيقي",fi="شكرًا لدعمك ❤️",Si="المزيد من الموارد",bi="🏠 الصفحة الرئيسية للمشروع",Pi="🎬 تجربة مباشرة",yi="📖 دليل الاستخدام",vi="❓ الأسئلة الشائعة",hi="📋 وثائق API",Ci="🎯 حالات الاستخدام",Ri="🔗 روابط سريعة",Ti="📖 نصائح الأوامر",ki="📚 نظرة عامة على النماذج",Ai="📘 استدعاء API",Mi="-30% (بطيء)",wi="+30% (سريع)",Ii="-15% (إلقاء القصيدة أبطأ)",Hi="أفقي 16:9 (HD)",Di="عمودي 9:18",Ei="أفقي 18:9",Li="الماندرين · أنثى",Fi="خطأ في الشبكة",xi="تم النسخ ✓",Ni="توسيع",Vi="طي",Gi="تحديث",Ki="إغلاق",Bi="شعر",Ui="الكلمات المهمة بخط أحمر كبير، والسرد العادي بخط أبيض صغير في الأسفل",Oi="إضافة مفتاح",qi="الصق مفتاح API جديد (يُضاف تلقائيًا إلى المفاتيح الموجودة)",Wi="حذف",_i="حذف هذه المهمة وجميع الملفات المُنشأة؟ لا يمكن التراجع عن هذا الإجراء!",zi="تم حذف المهمة",Qi="وضع التنفيذ",Yi="⚡ تلقائي",ji="✋ يدوي",Ji="الوضع التلقائي يعمل حتى النهاية دون تدخل؛ الوضع اليدوي يتوقف عند كل نقطة تحقق للتأكيد أو التعديل، ويمكن استخدامه مع أدوات الذكاء الاصطناعي الخارجية. يمكن التبديل في أي وقت.",Xi="فشل الحذف",Zi="فشل الإزالة",$i="المفاتيح المُعدة",er="ENV",tr="CONFIG",or="من متغير البيئة؛ عدّله في بيئة التشغيل/.env",nr="المفتاح ما زال فعّالًا (موجود في env)",sr="تم تفعيل تناوب المفاتيح المتعددة",cr="إزالة هذا المفتاح",ar="هل تريد إزالة هذا المفتاح؟",ir="تمت إزالة المفتاح",rr="ارفع صورة مرجعية لكل مشهد؛ سيستخدمها الفيديو كنقطة بداية بصرية (مع تخطي توليد لوحة القصة بالذكاء الاصطناعي لذلك المشهد). المشاهد دون رفع تستخدم صورًا من الذكاء الاصطناعي.",lr="الصور المرجعية للمشاهد (اختياري)",pr="فشل الحفظ",dr="تم حفظ القطعة",mr="قارن",ur="✅ المتابعة دون تغييرات",gr="الاحتفاظ بالقطع الحالية والمتابعة",fr="بعد الحفظ، ستُعاد توليد القطع السفلية المتأثرة",Sr="تعديل القطع",br="فتح نافذة التحرير",Pr="أدخل المحتوى المعدل هنا...",yr="💾 حفظ التغييرات",vr="الرئيسية",hr="💻 التحرير عبر الإنترنت",Cr="حرّر القطع النصية في نافذة واحفظها، وقارن بالأصل في أي وقت",Rr="هذا النموذج مدفوع، يُفوتر حسب الاستخدام. تأكد من فتح حصة الدفع.",Tr=" (مدفوع)",kr="لا توجد قطع نصية قابلة للتحرير في نقطة التحقق هذه",Ar="الأصل",Mr="جارٍ استئناف التنفيذ...",wr="تغيير اللغة",Ir="✅ تأكيد ومتابعة",Hr="انقر على «تأكيد ومتابعة» بالأعلى لتطبيق التغييرات",Dr="يحتاج إلى استئناف",Er="استئناف المهمة",Lr="المهمة لا تعمل",Fr="انقر على «استئناف المهمة» أعلى اليمين",xr="يمكن تحرير القطع النصية فقط عبر الإنترنت",Nr="Generation failures are often caused by transient factors. Please retry first (resumes from the failed step).",Vr="Retry Task",Gr="Retried {n} time(s)",Kr="Still failing after multiple retries? Report the issue",Br="Still failing after {n} retries. Please report with diagnostic info.",Ur="This looks like a deterministic issue caused by parameters or content. Retrying may not help.",Or="Diagnostic Info",qr="Copy Diagnostic Info",Wr="Copied. Please paste it into the GitHub Issue.",_r="Check the FAQ first",zr="Open an Issue on GitHub",Qr="Please review before submitting (your prompt text is not included)",Yr="Prefilled content was too long and shortened. Please paste the full diagnostic info.",jr="Generating diagnostic info…",Jr="Copy failed, please try again",Xr="## Diagnostic Info (Agnes Video Generator)",Zr="App Version",$r="Task ID",el="Task Type",tl="Generation Mode",ol="Failed Step",nl="Retry Count",sl="Key Configs",cl="Environment",al="unknown",il="### Error Message",rl="#### التتبع الكامل",ll="### Reproduction Steps",pl="<!-- Please fill in: operations and related config -->",dl="### Expected Behavior",ml="<!-- Please fill in -->",ul="…(content was too long and truncated, please paste the full diagnostic info)",gl="[Bug] {taskType} task failed at {failedStep}",fl="[Bug] {taskType} generation failed",Sl="#### Model call error {n}",bl="Time",Pl="Model",yl="API",vl="Error Type",hl="Status Code",Cl="Error Message",Rl="الخصوصية",Tl="إيقاف الإحصائيات المجهولة",kl="عند التفعيل، لا يتم تحميل أي نصوص تحليلات (Google Analytics 4) ولا يتم إرسال أي بيانات.",Al="عند تشغيل التحليلات، يتم إرسال ما يلي بشكل مجهول",Ml="أحداث المهام: إنشاء، إكمال، فشل، إيقاف، حذف",wl="نوع المهمة ووضع التوليد (مثل: فيديو بسيط/t2v، فيديو إبداعي)",Il="إجراءات الواجهة والإعدادات: تبديل نوع المهمة، اختيار النماذج، حفظ/مسح مفاتيح API، النطاق، تبديل العلامة المائية (يتم تسجيل الإجراء فقط، وليس المفتاح نفسه)",Hl="ملخص أخطاء الواجهة الأمامية: رسالة الخطأ (مقتطعة إلى 500 حرف)",Dl="لن يتم رفع ما يلي أبدًا بغض النظر عن حالة المفتاح",El="المحتوى الإبداعي مثل المطالبات والمخطوطات والنصوص الشعرية؛ مفاتيح API؛ الصور المرجعية. يتم استبدال جميع حقول المحتوى بعلامة <redacted> قبل الإرسال، ويتم اقتطاع النصوص الطويلة تلقائيًا، ولا يدخل شيء إلى نظام التحليلات.",Ll="الإحصائيات مفعّلة",Fl="الإحصائيات متوقفة",xl={subtitle:e,apiKeyTitle:t,apiKeyNotConfigured:o,apiKeyConfigured:n,apiKeyPlaceholder:s,apiKeyMasked:c,save:a,clear:i,clearConfirm:r,apiKeyFromEnv:l,clearEnvHint:p,modelTitle:d,modelHint:m,modelTextLabel:u,modelImageLabel:g,modelVideoLabel:f,vmModelSelect:S,vmDiffTitle:b,vmColCapability:P,vmColPrice:y,vmColMode:v,vmColDuration:h,vmColResolution:C,vmColNegative:R,vmColRefVideo:T,vmTagPaid:k,vmTagFree:A,vmYes:M,vmNo:w,vmModelModesLabel:I,vmModelDurationsLabel:H,vmModelResLabel:D,vmModelNegativeLabel:E,vmModelRefImagesLabel:L,vmModelRefVideoLabel:F,vmModelNegativeUnsupported:x,vmRatioLabel:N,vmSizeLabel:V,vmRefImagesHint:G,vmNegativeDisabledPlaceholder:K,vmRatioHint:B,vm720pHint:U,modelSync:O,modelSyncIdle:q,modelSaved:W,modelBetaHint:_,modelBetaTag:z,modelTagText:Q,modelTagImage:Y,modelTagVideo:j,modelTextRequired:J,modelSyncFailed:X,modelSaveFailed:Z,workspaceTitle:$,workspaceNone:ee,workspaceActive:te,workspaceAdd:oe,workspacePathPlaceholder:ne,workspaceNamePlaceholder:se,workspaceActivate:ce,workspaceRemove:ae,workspaceActiveBadge:ie,workspaceCurrentActive:re,workspaceBrowse:le,workspaceDefault:pe,workspaceListTitle:de,workspaceListHint:me,workspaceRegressionHint:ue,workspaceRemoveConfirm:ge,tabCreate:fe,tabList:Se,watermarkTitle:be,watermarkPromo:Pe,watermarkEnabled:ye,watermarkDisabled:ve,ttSimple:he,ttCreative:Ce,ttManuscript:Re,subModeLabel:Te,subModeVideo:ke,subModeImage:Ae,simpleSettings:Me,creativeSettings:we,manuscriptSettings:Ie,promptLabel:He,promptPlaceholder:De,genMode:Ee,modeT2v:Le,modeI2v:Fe,modeKeyframesSimple:xe,duration:Ne,resolution:Ve,resPortrait:Ge,resLandscape:Ke,resSquare:Be,refImageSimple:Ue,endFrameImage:Oe,chooseImage:qe,notSelected:We,advancedSettings:_e,optional:ze,seedPlaceholder:Qe,negativePlaceholder:Ye,taskName:je,taskNamePlaceholder:Je,ideaLabel:Xe,ideaPlaceholder:Ze,visualStyle:$e,requirementDefault:et,styleDefault:tt,chainingMode:ot,modeKeyframes:nt,modeTi2vid:st,modeNone:ct,referenceImage:at,refDescription:it,customEndFrames:rt,enableCustomEndFrames:lt,genEndFramesFromRef:pt,endFrameDesc:dt,scene_:mt,addEndFrame:ut,audioConfig:gt,subtitleConfig:ft,enableNarration:St,enableSubtitle:bt,voiceRole:Pt,speechRate:yt,rateNormal:vt,selectVoice:ht,searchVoice:Ct,currentSelection:Rt,confirmSelection:Tt,cancel:kt,confirm:At,previewPlay:Mt,previewStop:wt,previewFailed:It,voiceCompatWarning:Ht,voiceGenderFemale:Dt,voiceGenderMale:Et,voiceEmpty:Lt,subtitleStyle:Ft,subFont:xt,subColor:Nt,subSize:Vt,subPosition:Gt,posBottom:Kt,posTop:Bt,subStrokeColor:Ut,subStrokeWidth:Ot,subBgColor:qt,subStyleMode:Wt,subStyleFixed:_t,subStyleLLM:zt,subStyleHints:Qt,subStyleHintsHint:Yt,manuscriptText:jt,manuscriptPlaceholder:Jt,charCount:Xt,startGenerate:Zt,submitting:$t,taskRunning:eo,loading:to,noTasks:oo,loadFailed:no,progress:so,stopTask:co,sStepSubmit:ao,sStepVideoGen:io,cStepInit:ro,cStepSceneConfig:lo,cStepImageAnalysis:po,cStepStory:mo,cStepCharacterRef:uo,cStepScript:go,cStepEndFramePrompts:fo,cStepEndFrameGen:So,cStepVideoGen:bo,cStepAudio:Po,cStepSubtitle:yo,cStepConcat:vo,mStepSplit:ho,mStepScenePrompts:Co,mStepVideoGen:Ro,mStepAudio:To,mStepSubtitle:ko,mStepConcat:Ao,videoComplete:Mo,taskComplete:wo,taskId:Io,dir:Ho,idea_:Do,sceneCount:Eo,chainingMode_:Lo,sceneConfig:Fo,durationSource:xo,sourceManual:No,sourcePrompt:Vo,sourceManualHint:Go,sourcePromptHint:Ko,durationMode:Bo,uniformDuration:Uo,independentDuration:Oo,seconds:qo,artifact:Wo,paragraphCount:_o,statusCompleted:zo,statusRunning:Qo,statusFailed:Yo,statusPending:jo,statusQueued:Jo,cpImageAnalysis:Xo,cpStory:Zo,cpScript:$o,cpCharacterRef:en,cpEndFramePrompts:tn,cpEndFrameGen:on,taskInfo:nn,tiIdea:sn,tiManuscript:cn,tiScript:an,tiAnchorPrompt:rn,tiPoem:ln,tiPrompt:pn,tiWidth:dn,tiHeight:mn,tiScenes:un,tiParagraphs:gn,tiChaining:fn,tiStyle:Sn,tiAudioSource:bn,tiMode:Pn,tiDuration:yn,pausePoints:vn,pausePointsHint:hn,cpScenes:Cn,cpReferences:Rn,cpVideos:Tn,cpAudio:kn,cpSubtitle:An,cpFinal:Mn,manualUnsupported:wn,modeSwitching:In,modeSwitched:Hn,failSwitchMode:Dn,switchToAuto:En,switchToManual:Ln,switchToAutoConfirm:Fn,switchToManualConfirm:xn,awaitingUser:Nn,awaitingUserTip:Vn,checkpointTitle:Gn,cpDone:Kn,cpPending:Bn,cpRunning:Un,howToHandle:On,handleAi:qn,handleAiDesc:Wn,handleSelf:_n,handleSelfDesc:zn,handleAgent:Qn,handleAgentDesc:Yn,aiModifyRequest:jn,aiModifyRequestPlaceholder:Jn,aiModifyStart:Xn,aiModifyApplying:Zn,aiModifyResult:$n,applyAndContinue:es,discard:ts,selfEditPath:os,selfEditSchemaHint:ns,selfEditAffected:ss,selfEditDone:cs,agentCommand:as,agentPrompt:is,agentDone:rs,agentMoreTools:ls,copy:ps,noEditableArtifact:ds,aiModifyFailed:ms,failContinue:us,continued:gs,failRegen:fs,regenCurrent:Ss,selfEditAffectedHint:bs,agentPromptTemplate:Ps,impactTitle:ys,impactRetained:vs,impactConfirm:hs,impactCancel:Cs,noAffected:Rs,paramUpdates:Ts,paramResolution:ks,paramVoice:As,agentCommandLines:Ms,statusAwaitingUser:ws,progressBack:Is,ppStages:Hs,ppExpand:Ds,ppCollapse:Es,ppWaiting:Ls,btnView:Fs,btnViewProgress:xs,btnResume:Ns,btnStop:Vs,sceneUnit:Gs,paraUnit:Ks,typeSimple:Bs,typeCreative:Us,typeManuscript:Os,typeImage:qs,stopConfirm:Ws,stopConfirmById:_s,stopped:zs,stoppedById:Qs,enterApiKey:Ys,enterPrompt:js,enterIdea:Js,enterText:Xs,taskRunningWarn:Zs,failCreate:$s,failResume:ec,failLoad:tc,failStop:oc,stopping:nc,submitted:sc,resumed:cc,watchLog:ac,task_:ic,genFailed:rc,genFailedMsg:lc,gotoResume:pc,connLost:dc,connLostMsg:mc,gotoList:uc,reconnecting:gc,ttAnchor:fc,domainTitle:Sc,domainHint:bc,domainComLabel:Pc,domainCnLabel:yc,domainCnBakLabel:vc,domainSaved:hc,domainSaveFailed:Cc,ttPoetry:Rc,poetrySettings:Tc,poemLabel:kc,poemPlaceholder:Ac,poemHint:Mc,scenePromptsOptional:wc,scenePromptsPlaceholder:Ic,scenePromptsHint:Hc,scenePromptsExample:Dc,scenePromptTool:Ec,showPrompt:Lc,scenePromptToolHint:Fc,copyPromptWithPoem:xc,totalDuration:Nc,sceneCountAuto:Vc,poetrySubtitleFixed:Gc,pStepBuildScenes:Kc,pStepVideoGen:Bc,pStepAudio:Uc,pStepSubtitle:Oc,pStepConcat:qc,enterPoem:Wc,ttImage:_c,imageSettings:zc,imagePrompt:Qc,imagePromptPlaceholder:Yc,imageSize:jc,refImageHint:Jc,imgGenerate:Xc,imgComplete:Zc,generating:$c,enterImagePrompt:ea,anchorSettings:ta,anchorPrompt:oa,anchorPromptPlaceholder:na,anchorRefImage:sa,anchorRefImageHint:ca,scriptText:aa,scriptTextPlaceholder:ia,resPortraitHD:ra,subPositionHints:la,subPositionHintsPlaceholder:pa,typeAnchor:da,audioSource:ma,audioPostStitch:ua,audioPostStitchDesc:ga,audioModel:fa,audioModelDesc:Sa,aStepGenerateAnchor:ba,aStepSplit:Pa,aStepClipPrompts:ya,aStepClipGen:va,aStepAudio:ha,aStepSubtitle:Ca,aStepConcat:Ra,systemPrompt:Ta,systemPromptPlaceholder:ka,artTitle:Aa,artImageAnalysis:Ma,artStory:wa,artCharacterRef:Ia,artScript:Ha,artEndFramePrompts:Da,artEndFrame:Ea,artVideo:La,artAudio:Fa,artSubtitle:xa,artFinalVideo:Na,artAnchorImage:Va,artClipPrompts:Ga,artClip:Ka,artParaVideo:Ba,artScenePrompts:Ua,deleteArtifactConfirm:Oa,willDelete:qa,willResetSteps:Wa,artifactDeleted:_a,artifactDeleteFailed:za,clickToPreview:Qa,taskStarting:Ya,apiKeyGetLink:ja,apiKeyGuideLink:Ja,apiKeyDemoLink:Xa,formTipTips:Za,formTipModels:$a,exampleLinkSimple:ei,exampleLinkCreative:ti,exampleLinkManuscript:oi,exampleLinkAnchor:ni,waitTip:si,doneTipTiktok:ci,doneTipMore:ai,adSupportTitle:ii,adSupportDesc:ri,adStar:li,adStarDesc:pi,adAdblock:di,adAdblockDesc:mi,adClick:ui,adClickDesc:gi,adThanks:fi,moreResources:Si,projectHome:bi,onlineDemo:Pi,usageGuide:yi,faqTitle:vi,apiDocs:hi,appScenarios:Ci,quickLinks:Ri,promptTips:Ti,modelOverview:ki,apiCall:Ai,rateSlow:Mi,rateFast:wi,ratePoem:Ii,resLandscapeHD:Hi,resPortraitTall:Di,resLandscapeWide:Ei,voiceDefaultDesc:Li,networkError:Fi,copied:xi,expand:Ni,collapse:Vi,refresh:Gi,close:Ki,typePoetry:Bi,subStyleHintsPlaceholder:Ui,addKey:Oi,apiKeyAppendPlaceholder:qi,deleteTask:Wi,deleteTaskConfirm:_i,deletedTask:zi,execMode:Qi,execAuto:Yi,execManual:ji,execModeHint:Ji,failDelete:Xi,failRemoveKey:Zi,keyCountLabel:$i,keySrcEnv:er,keySrcConfig:tr,keySrcEnvHint:or,keyStillActive:nr,multiKeyActive:sr,removeKeyBtn:cr,removeKeyConfirm:ar,removedKey:ir,sceneRefDesc:rr,sceneReferenceImages:lr,artifactSaveFailed:pr,artifactSaved:dr,compare:mr,continueNoChange:ur,continueNoChangeHint:gr,editArtifactHint:fr,editModalTitle:Sr,editOpen:br,editPlaceholder:Pr,editSave:yr,goHome:vr,handleEdit:hr,handleEditDesc:Cr,modelPaidHint:Rr,modelPaidTag:Tr,noEditableText:kr,originalContent:Ar,resuming:Mr,langSwitch:wr,continueConfirm:Ir,continueToApply:Hr,statusNeedsResume:Dr,resumeTaskBtn:Er,taskNotRunning:Lr,taskNotRunningHint:Fr,editTextOnly:xr,fbRetryHint:Nr,fbRetryBtn:Vr,fbRetriedN:Gr,fbCollapsedHint:Kr,fbExpandedHint:Br,fbDeterministicHint:Ur,fbDiagTitle:Or,fbCopy:qr,fbCopied:Wr,fbFaq:_r,fbGithub:zr,fbPrivacyHint:Qr,fbUrlTooLong:Yr,fbDiagLoading:jr,fbCopyFailed:Jr,fbRepTitle:Xr,fbRepAppVersion:Zr,fbRepTaskId:$r,fbRepTaskType:el,fbRepMode:tl,fbRepFailedStep:ol,fbRepRetryCount:nl,fbRepConfigs:sl,fbRepEnv:cl,fbRepUnknown:al,fbRepErrorTitle:il,fbRepTraceback:rl,fbRepReproSteps:ll,fbRepReproHint:pl,fbRepExpected:dl,fbRepExpectedHint:ml,fbRepTruncated:ul,fbRepIssueTitleStep:gl,fbRepIssueTitleNoStep:fl,fbRepErrHeading:Sl,fbRepErrTime:bl,fbRepErrModel:Pl,fbRepErrApi:yl,fbRepErrType:vl,fbRepErrStatusCode:hl,fbRepErrInfo:Cl,privacyTitle:Rl,gaOptOutLabel:Tl,gaOptOutHint:kl,gaReportTitle:Al,gaReportItem1:Ml,gaReportItem2:wl,gaReportItem3:Il,gaReportItem4:Hl,gaNeverUploadTitle:Dl,gaNeverUploadText:El,gaStatOn:Ll,gaStatOff:Fl};export{ha as aStepAudio,va as aStepClipGen,ya as aStepClipPrompts,Ra as aStepConcat,ba as aStepGenerateAnchor,Pa as aStepSplit,Ca as aStepSubtitle,di as adAdblock,mi as adAdblockDesc,ui as adClick,gi as adClickDesc,li as adStar,pi as adStarDesc,ri as adSupportDesc,ii as adSupportTitle,fi as adThanks,ut as addEndFrame,Oi as addKey,_e as advancedSettings,as as agentCommand,Ms as agentCommandLines,rs as agentDone,ls as agentMoreTools,is as agentPrompt,Ps as agentPromptTemplate,Zn as aiModifyApplying,ms as aiModifyFailed,jn as aiModifyRequest,Jn as aiModifyRequestPlaceholder,$n as aiModifyResult,Xn as aiModifyStart,oa as anchorPrompt,na as anchorPromptPlaceholder,sa as anchorRefImage,ca as anchorRefImageHint,ta as anchorSettings,Ai as apiCall,hi as apiDocs,qi as apiKeyAppendPlaceholder,n as apiKeyConfigured,Xa as apiKeyDemoLink,l as apiKeyFromEnv,ja as apiKeyGetLink,Ja as apiKeyGuideLink,c as apiKeyMasked,o as apiKeyNotConfigured,s as apiKeyPlaceholder,t as apiKeyTitle,Ci as appScenarios,es as applyAndContinue,Va as artAnchorImage,Fa as artAudio,Ia as artCharacterRef,Ka as artClip,Ga as artClipPrompts,Ea as artEndFrame,Da as artEndFramePrompts,Na as artFinalVideo,Ma as artImageAnalysis,Ba as artParaVideo,Ua as artScenePrompts,Ha as artScript,wa as artStory,xa as artSubtitle,Aa as artTitle,La as artVideo,Wo as artifact,za as artifactDeleteFailed,_a as artifactDeleted,pr as artifactSaveFailed,dr as artifactSaved,gt as audioConfig,fa as audioModel,Sa as audioModelDesc,ua as audioPostStitch,ga as audioPostStitchDesc,ma as audioSource,Nn as awaitingUser,Vn as awaitingUserTip,Ns as btnResume,Vs as btnStop,Fs as btnView,xs as btnViewProgress,Po as cStepAudio,uo as cStepCharacterRef,vo as cStepConcat,So as cStepEndFrameGen,fo as cStepEndFramePrompts,po as cStepImageAnalysis,ro as cStepInit,lo as cStepSceneConfig,go as cStepScript,mo as cStepStory,yo as cStepSubtitle,bo as cStepVideoGen,kt as cancel,ot as chainingMode,Lo as chainingMode_,Xt as charCount,Gn as checkpointTitle,qe as chooseImage,i as clear,r as clearConfirm,p as clearEnvHint,Qa as clickToPreview,Ki as close,Vi as collapse,mr as compare,At as confirm,Tt as confirmSelection,dc as connLost,mc as connLostMsg,Ir as continueConfirm,ur as continueNoChange,gr as continueNoChangeHint,Hr as continueToApply,gs as continued,xi as copied,ps as copy,xc as copyPromptWithPoem,kn as cpAudio,en as cpCharacterRef,Kn as cpDone,on as cpEndFrameGen,tn as cpEndFramePrompts,Mn as cpFinal,Xo as cpImageAnalysis,Bn as cpPending,Rn as cpReferences,Un as cpRunning,Cn as cpScenes,$o as cpScript,Zo as cpStory,An as cpSubtitle,Tn as cpVideos,we as creativeSettings,Rt as currentSelection,rt as customEndFrames,xl as default,Oa as deleteArtifactConfirm,Wi as deleteTask,_i as deleteTaskConfirm,zi as deletedTask,Ho as dir,ts as discard,vc as domainCnBakLabel,yc as domainCnLabel,Pc as domainComLabel,bc as domainHint,Cc as domainSaveFailed,hc as domainSaved,Sc as domainTitle,ai as doneTipMore,ci as doneTipTiktok,Ne as duration,Bo as durationMode,xo as durationSource,fr as editArtifactHint,Sr as editModalTitle,br as editOpen,Pr as editPlaceholder,yr as editSave,xr as editTextOnly,lt as enableCustomEndFrames,St as enableNarration,bt as enableSubtitle,dt as endFrameDesc,Oe as endFrameImage,Ys as enterApiKey,Js as enterIdea,ea as enterImagePrompt,Wc as enterPoem,js as enterPrompt,Xs as enterText,ni as exampleLinkAnchor,ti as exampleLinkCreative,oi as exampleLinkManuscript,ei as exampleLinkSimple,Yi as execAuto,ji as execManual,Qi as execMode,Ji as execModeHint,Ni as expand,us as failContinue,$s as failCreate,Xi as failDelete,tc as failLoad,fs as failRegen,Zi as failRemoveKey,ec as failResume,oc as failStop,Dn as failSwitchMode,vi as faqTitle,Kr as fbCollapsedHint,Wr as fbCopied,qr as fbCopy,Jr as fbCopyFailed,Ur as fbDeterministicHint,jr as fbDiagLoading,Or as fbDiagTitle,Br as fbExpandedHint,_r as fbFaq,zr as fbGithub,Qr as fbPrivacyHint,Zr as fbRepAppVersion,sl as fbRepConfigs,cl as fbRepEnv,yl as fbRepErrApi,Sl as fbRepErrHeading,Cl as fbRepErrInfo,Pl as fbRepErrModel,hl as fbRepErrStatusCode,bl as fbRepErrTime,vl as fbRepErrType,il as fbRepErrorTitle,dl as fbRepExpected,ml as fbRepExpectedHint,ol as fbRepFailedStep,fl as fbRepIssueTitleNoStep,gl as fbRepIssueTitleStep,tl as fbRepMode,pl as fbRepReproHint,ll as fbRepReproSteps,nl as fbRepRetryCount,$r as fbRepTaskId,el as fbRepTaskType,Xr as fbRepTitle,rl as fbRepTraceback,ul as fbRepTruncated,al as fbRepUnknown,Gr as fbRetriedN,Vr as fbRetryBtn,Nr as fbRetryHint,Yr as fbUrlTooLong,$a as formTipModels,Za as formTipTips,El as gaNeverUploadText,Dl as gaNeverUploadTitle,kl as gaOptOutHint,Tl as gaOptOutLabel,Ml as gaReportItem1,wl as gaReportItem2,Il as gaReportItem3,Hl as gaReportItem4,Al as gaReportTitle,Fl as gaStatOff,Ll as gaStatOn,pt as genEndFramesFromRef,rc as genFailed,lc as genFailedMsg,Ee as genMode,$c as generating,vr as goHome,uc as gotoList,pc as gotoResume,Qn as handleAgent,Yn as handleAgentDesc,qn as handleAi,Wn as handleAiDesc,hr as handleEdit,Cr as handleEditDesc,_n as handleSelf,zn as handleSelfDesc,On as howToHandle,Xe as ideaLabel,Ze as ideaPlaceholder,Do as idea_,Qc as imagePrompt,Yc as imagePromptPlaceholder,zc as imageSettings,jc as imageSize,Zc as imgComplete,Xc as imgGenerate,Cs as impactCancel,hs as impactConfirm,vs as impactRetained,ys as impactTitle,Oo as independentDuration,$i as keyCountLabel,tr as keySrcConfig,er as keySrcEnv,or as keySrcEnvHint,nr as keyStillActive,wr as langSwitch,no as loadFailed,to as loading,To as mStepAudio,Ao as mStepConcat,Co as mStepScenePrompts,ho as mStepSplit,ko as mStepSubtitle,Ro as mStepVideoGen,wn as manualUnsupported,Jt as manuscriptPlaceholder,Ie as manuscriptSettings,jt as manuscriptText,Fe as modeI2v,nt as modeKeyframes,xe as modeKeyframesSimple,ct as modeNone,Hn as modeSwitched,In as modeSwitching,Le as modeT2v,st as modeTi2vid,_ as modelBetaHint,z as modelBetaTag,m as modelHint,g as modelImageLabel,ki as modelOverview,Rr as modelPaidHint,Tr as modelPaidTag,Z as modelSaveFailed,W as modelSaved,O as modelSync,X as modelSyncFailed,q as modelSyncIdle,Y as modelTagImage,Q as modelTagText,j as modelTagVideo,u as modelTextLabel,J as modelTextRequired,d as modelTitle,f as modelVideoLabel,Si as moreResources,sr as multiKeyActive,Ye as negativePlaceholder,Fi as networkError,Rs as noAffected,ds as noEditableArtifact,kr as noEditableText,oo as noTasks,We as notSelected,Pi as onlineDemo,ze as optional,Ar as originalContent,Uc as pStepAudio,Kc as pStepBuildScenes,qc as pStepConcat,Oc as pStepSubtitle,Bc as pStepVideoGen,Ks as paraUnit,_o as paragraphCount,ks as paramResolution,Ts as paramUpdates,As as paramVoice,vn as pausePoints,hn as pausePointsHint,Mc as poemHint,kc as poemLabel,Ac as poemPlaceholder,Tc as poetrySettings,Gc as poetrySubtitleFixed,Kt as posBottom,Bt as posTop,Es as ppCollapse,Ds as ppExpand,Hs as ppStages,Ls as ppWaiting,It as previewFailed,Mt as previewPlay,wt as previewStop,Rl as privacyTitle,so as progress,Is as progressBack,bi as projectHome,He as promptLabel,De as promptPlaceholder,Ti as promptTips,Ri as quickLinks,wi as rateFast,vt as rateNormal,Ii as ratePoem,Mi as rateSlow,gc as reconnecting,it as refDescription,Jc as refImageHint,Ue as refImageSimple,at as referenceImage,Gi as refresh,Ss as regenCurrent,cr as removeKeyBtn,ar as removeKeyConfirm,ir as removedKey,et as requirementDefault,Ke as resLandscape,Hi as resLandscapeHD,Ei as resLandscapeWide,Ge as resPortrait,ra as resPortraitHD,Di as resPortraitTall,Be as resSquare,Ve as resolution,Er as resumeTaskBtn,cc as resumed,Mr as resuming,ao as sStepSubmit,io as sStepVideoGen,a as save,Fo as sceneConfig,Eo as sceneCount,Vc as sceneCountAuto,Ec as scenePromptTool,Fc as scenePromptToolHint,Dc as scenePromptsExample,Hc as scenePromptsHint,wc as scenePromptsOptional,Ic as scenePromptsPlaceholder,rr as sceneRefDesc,lr as sceneReferenceImages,Gs as sceneUnit,mt as scene_,aa as scriptText,ia as scriptTextPlaceholder,Ct as searchVoice,qo as seconds,Qe as seedPlaceholder,ht as selectVoice,ss as selfEditAffected,bs as selfEditAffectedHint,cs as selfEditDone,os as selfEditPath,ns as selfEditSchemaHint,Lc as showPrompt,Me as simpleSettings,No as sourceManual,Go as sourceManualHint,Vo as sourcePrompt,Ko as sourcePromptHint,yt as speechRate,Zt as startGenerate,ws as statusAwaitingUser,zo as statusCompleted,Yo as statusFailed,Dr as statusNeedsResume,jo as statusPending,Jo as statusQueued,Qo as statusRunning,Ws as stopConfirm,_s as stopConfirmById,co as stopTask,zs as stopped,Qs as stoppedById,nc as stopping,tt as styleDefault,qt as subBgColor,Nt as subColor,xt as subFont,Ae as subModeImage,Te as subModeLabel,ke as subModeVideo,Gt as subPosition,la as subPositionHints,pa as subPositionHintsPlaceholder,Vt as subSize,Ut as subStrokeColor,Ot as subStrokeWidth,_t as subStyleFixed,Qt as subStyleHints,Yt as subStyleHintsHint,Ui as subStyleHintsPlaceholder,zt as subStyleLLM,Wt as subStyleMode,sc as submitted,$t as submitting,e as subtitle,ft as subtitleConfig,Ft as subtitleStyle,En as switchToAuto,Fn as switchToAutoConfirm,Ln as switchToManual,xn as switchToManualConfirm,Ta as systemPrompt,ka as systemPromptPlaceholder,fe as tabCreate,Se as tabList,wo as taskComplete,Io as taskId,nn as taskInfo,je as taskName,Je as taskNamePlaceholder,Lr as taskNotRunning,Fr as taskNotRunningHint,eo as taskRunning,Zs as taskRunningWarn,Ya as taskStarting,ic as task_,rn as tiAnchorPrompt,bn as tiAudioSource,fn as tiChaining,yn as tiDuration,mn as tiHeight,sn as tiIdea,cn as tiManuscript,Pn as tiMode,gn as tiParagraphs,ln as tiPoem,pn as tiPrompt,un as tiScenes,an as tiScript,Sn as tiStyle,dn as tiWidth,Nc as totalDuration,fc as ttAnchor,Ce as ttCreative,_c as ttImage,Re as ttManuscript,Rc as ttPoetry,he as ttSimple,da as typeAnchor,Us as typeCreative,qs as typeImage,Os as typeManuscript,Bi as typePoetry,Bs as typeSimple,Uo as uniformDuration,yi as usageGuide,Mo as videoComplete,$e as visualStyle,U as vm720pHint,P as vmColCapability,h as vmColDuration,v as vmColMode,R as vmColNegative,y as vmColPrice,T as vmColRefVideo,C as vmColResolution,b as vmDiffTitle,H as vmModelDurationsLabel,I as vmModelModesLabel,E as vmModelNegativeLabel,x as vmModelNegativeUnsupported,L as vmModelRefImagesLabel,F as vmModelRefVideoLabel,D as vmModelResLabel,S as vmModelSelect,K as vmNegativeDisabledPlaceholder,w as vmNo,B as vmRatioHint,N as vmRatioLabel,G as vmRefImagesHint,V as vmSizeLabel,A as vmTagFree,k as vmTagPaid,M as vmYes,Ht as voiceCompatWarning,Li as voiceDefaultDesc,Lt as voiceEmpty,Dt as voiceGenderFemale,Et as voiceGenderMale,Pt as voiceRole,si as waitTip,ac as watchLog,ve as watermarkDisabled,ye as watermarkEnabled,Pe as watermarkPromo,be as watermarkTitle,qa as willDelete,Wa as willResetSteps,ce as workspaceActivate,te as workspaceActive,ie as workspaceActiveBadge,oe as workspaceAdd,le as workspaceBrowse,re as workspaceCurrentActive,pe as workspaceDefault,me as workspaceListHint,de as workspaceListTitle,se as workspaceNamePlaceholder,ee as workspaceNone,ne as workspacePathPlaceholder,ue as workspaceRegressionHint,ae as workspaceRemove,ge as workspaceRemoveConfirm,$ as workspaceTitle};
|