@danhachuel/thunderbolt 0.2.81 → 0.2.82
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/MANUAL-INSTALACAO.md +1 -1
- package/README.md +2 -2
- package/app/main.py +37 -12
- package/hermes_ui/languages.py +66 -88
- package/package.json +1 -1
package/MANUAL-INSTALACAO.md
CHANGED
|
@@ -194,7 +194,7 @@ npx --yes @danhachuel/thunderbolt install
|
|
|
194
194
|
|
|
195
195
|
O Thunderbolt inclui as dez opções de idioma usadas pelo fluxo MoneyPrinterTurbo: **Inglês (en) 🇺🇸**, **Chinês Simplificado (zh) 🇨🇳**, **Alemão (de) 🇩🇪**, **Vietnamita (vi) 🇻🇳**, **Turco (tr) 🇹🇷**, **Português (pt) 🇧🇷**, **Russo (ru) 🇷🇺**, **Espanhol (es) 🇪🇸**, **Indonésio (id) 🇮🇩** e **Italiano (it) 🇮🇹**. A criação de vídeos mantém ainda os rótulos históricos para não invalidar Blueprints e tarefas antigas.
|
|
196
196
|
|
|
197
|
-
No topo da área principal, o menu nativo de idioma segue o padrão do MoneyPrinterTurbo e mostra
|
|
197
|
+
No topo da área principal, o menu nativo de idioma segue o padrão do MoneyPrinterTurbo e mostra o rótulo **Language** acima do selector. Cada opção apresenta o nome e o código, acompanhados por uma imagem SVG local da bandeira; não depende de emojis nem de siglas da fonte do sistema. A escolha fica guardada como `ui_language` em `storage/state/settings.json` e, quando existe um caminho MoneyPrinterTurbo configurado, é sincronizada com `[ui].language` no `config.toml`. O dashboard inicial e as abas da barra lateral usam o mesmo idioma seleccionado. O toolbar do Streamlit não é manipulado: o indicador de execução, **Deploy** e o menu de três pontos permanecem nativos e clicáveis. Na Criação de Vídeos e em Roteiros, o selector **Script Language** mantém o catálogo de vídeo independente, mas guarda o código curto; essa escolha é sincronizada com `[ui].video_language`.
|
|
198
198
|
|
|
199
199
|
## 4. Diagnóstico antes de iniciar
|
|
200
200
|
|
package/README.md
CHANGED
|
@@ -50,9 +50,9 @@ Os adaptadores do MoneyPrinterTurbo e de publicação nas plataformas são ligad
|
|
|
50
50
|
|
|
51
51
|
O Thunderbolt mantém os idiomas históricos da criação de vídeos e acrescenta as dez opções canónicas do MoneyPrinterTurbo: **Inglês (en) 🇺🇸**, **Chinês Simplificado (zh) 🇨🇳**, **Alemão (de) 🇩🇪**, **Vietnamita (vi) 🇻🇳**, **Turco (tr) 🇹🇷**, **Português (pt) 🇧🇷**, **Russo (ru) 🇷🇺**, **Espanhol (es) 🇪🇸**, **Indonésio (id) 🇮🇩** e **Italiano (it) 🇮🇹**. Os códigos curtos são os valores persistidos e sincronizados com `ui.video_language` no `config.toml`; a bandeira e o nome são apenas a apresentação visual.
|
|
52
52
|
|
|
53
|
-
No topo da área principal da aplicação existe o menu nativo de idioma no padrão do MoneyPrinterTurbo, sem sobrepor o toolbar do Streamlit. O selector mostra o
|
|
53
|
+
No topo da área principal da aplicação existe o menu nativo de idioma no padrão do MoneyPrinterTurbo, sem sobrepor o toolbar do Streamlit. O selector mostra o rótulo visível **Language** acima do campo, cada opção aparece como **nome do idioma + código**, e a bandeira é uma imagem SVG local real, não um emoji ou sigla dependente da fonte do sistema. Ao escolher outra opção, a preferência é guardada em `storage/state/settings.json` como `ui_language`, e a navegação lateral e o dashboard inicial actualizam-se sem alterar o idioma seleccionado para os vídeos. O indicador de execução, o botão **Deploy** e o menu principal do Streamlit permanecem totalmente nativos e clicáveis.
|
|
54
54
|
|
|
55
|
-
## Navegação da UI 0.2.
|
|
55
|
+
## Navegação da UI 0.2.82
|
|
56
56
|
|
|
57
57
|
A barra lateral mantém os níveis principais, nesta ordem: **Início**, **Niche Finder**, **Pipeline**, **Pipeline TikTok**, **Automação**, **Edição**, **AI Influencers** e **Configurações**. **Pipeline** é expansível e contém **Criação de Vídeos**, **Criação de Músicas**, **Roteiros** e **Upload**. **Automação** também é expansível e contém **Automação Youtube**. **Edição** é expansível e contém **Limpador de Metadados**, **Cortes**, **Editor Python** e **Download Mídia**, nessa ordem. **AI Influencers** é expansível e contém **Personagens**, **Redes Sociais** e **Tutorial Meta**, nessa ordem. **Niche Finder** é expansível e contém **Niche Finder Kaggle** e **Niche Finder Apify**. **Configurações** é expansível e contém **Canais Youtube**, **Blueprints Youtube**, **MCP**, **Contas Google**, **Configuração API** e **Notificações**. O Início reúne o dashboard e as filas do Pipeline, sem botões de acções rápidas.
|
|
58
58
|
|
package/app/main.py
CHANGED
|
@@ -37,7 +37,7 @@ from hermes_ui.material_sources import material_api_keys, material_source_catalo
|
|
|
37
37
|
from hermes_ui.music import list_music_files, materialize_suno_audio, request_suno_generation, store_music_file
|
|
38
38
|
from hermes_ui.media_downloader import AUDIO_FORMATS, VIDEO_CONTAINERS, VIDEO_QUALITY_OPTIONS, MediaDownloadError, build_download_options, clear_media_download_history, dependency_status, download_media, list_media_downloads, media_download_file
|
|
39
39
|
from hermes_ui.notifications import clear_notifications, list_notifications, mark_all_notifications_read, mark_notification_read, notification_event_catalog, notification_preferences, record_notification, reconcile_persisted_notifications, save_notification_preferences, unread_notification_count
|
|
40
|
-
from hermes_ui.languages import LANGUAGE_CODES, language_code, language_label, ui_text, video_language_label, video_language_options
|
|
40
|
+
from hermes_ui.languages import LANGUAGE_CODES, LANGUAGE_FLAG_DATA_URIS, language_code, language_label, ui_language_menu_label, ui_text, video_language_label, video_language_options
|
|
41
41
|
from hermes_ui.script_documents import list_script_documents, read_script_document, save_script_document, script_storage_path
|
|
42
42
|
from hermes_ui.script_generation import generate_script_document
|
|
43
43
|
from hermes_ui.voice_preview import DEFAULT_SAMPLE, load_preview_file, synthesize_preview
|
|
@@ -246,17 +246,31 @@ def save_video_language(value: str) -> str:
|
|
|
246
246
|
|
|
247
247
|
|
|
248
248
|
def render_ui_language_picker(language: str) -> None:
|
|
249
|
-
"""Render the MoneyPrinterTurbo-style
|
|
249
|
+
"""Render the native MoneyPrinterTurbo-style picker with local SVG flags."""
|
|
250
250
|
current = language_code(language)
|
|
251
|
+
current_flag_uri = LANGUAGE_FLAG_DATA_URIS[current]
|
|
252
|
+
option_flag_css = "\n".join(
|
|
253
|
+
f'''[role="listbox"][aria-label="Language"] [role="option"][aria-posinset="{position}"] [data-item-hl]::before {{ content: ""; display: inline-block; width: 1.5rem; height: 1rem; margin-right: .55rem; flex: 0 0 auto; vertical-align: middle; background: url("{LANGUAGE_FLAG_DATA_URIS[code]}") center / cover no-repeat; border-radius: 2px; box-shadow: 0 0 0 1px rgba(255,255,255,.18); }}'''
|
|
254
|
+
for position, code in enumerate(LANGUAGE_CODES, start=1)
|
|
255
|
+
)
|
|
256
|
+
st.markdown(
|
|
257
|
+
f'''<style>
|
|
258
|
+
[data-testid="stSelectbox"]:has(input[aria-label="Language"]) label {{ display: block !important; visibility: visible !important; }}
|
|
259
|
+
[data-testid="stSelectbox"]:has(input[aria-label="Language"]) input {{ background-image: url("{current_flag_uri}") !important; background-repeat: no-repeat !important; background-position: .65rem center !important; background-size: 1.5rem 1rem !important; padding-left: 2.55rem !important; }}
|
|
260
|
+
[role="listbox"][aria-label="Language"] [data-item-hl] {{ display: flex; align-items: center; }}
|
|
261
|
+
{option_flag_css}
|
|
262
|
+
</style>''',
|
|
263
|
+
unsafe_allow_html=True,
|
|
264
|
+
)
|
|
251
265
|
_spacer, language_col = st.columns([5.2, 1.5])
|
|
252
266
|
with language_col:
|
|
253
267
|
selected = st.selectbox(
|
|
254
|
-
"Language
|
|
268
|
+
"Language",
|
|
255
269
|
list(LANGUAGE_CODES),
|
|
256
270
|
index=list(LANGUAGE_CODES).index(current),
|
|
257
|
-
format_func=
|
|
271
|
+
format_func=ui_language_menu_label,
|
|
258
272
|
key="top_language_code_selector",
|
|
259
|
-
label_visibility="
|
|
273
|
+
label_visibility="visible",
|
|
260
274
|
)
|
|
261
275
|
if selected != current:
|
|
262
276
|
save_ui_language(selected)
|
|
@@ -700,16 +714,26 @@ def render_channel_edit_form(channel: dict, youtube_account_ids: list[str], yout
|
|
|
700
714
|
|
|
701
715
|
|
|
702
716
|
def render_dashboard():
|
|
717
|
+
ui_language = current_ui_language()
|
|
703
718
|
st.title("Thunderbolt")
|
|
704
|
-
st.caption("Interface local para operação e automação de conteúdo faceless")
|
|
719
|
+
st.caption(ui_text("Interface local para operação e automação de conteúdo faceless", ui_language))
|
|
705
720
|
summary = pipeline_summary()
|
|
721
|
+
active_note = f'{summary["active_channels"]} {ui_text("activos", ui_language)}'
|
|
722
|
+
cards = [
|
|
723
|
+
("Canais", summary["channels"], active_note),
|
|
724
|
+
("Tarefas", summary["total_tasks"], ui_text("total registado", ui_language)),
|
|
725
|
+
("A fazer", summary["pending"], ui_text("na pipeline", ui_language)),
|
|
726
|
+
("Em execução", summary["doing"], ui_text("a decorrer", ui_language)),
|
|
727
|
+
("Concluídos", summary["done"], ui_text("artefactos prontos", ui_language)),
|
|
728
|
+
("Falhas", summary["failed"], ui_text("requerem atenção", ui_language)),
|
|
729
|
+
]
|
|
706
730
|
cols = st.columns(6)
|
|
707
|
-
for col, (label, value, note) in zip(cols,
|
|
731
|
+
for col, (label, value, note) in zip(cols, cards):
|
|
708
732
|
with col:
|
|
709
|
-
card(label, value, note)
|
|
733
|
+
card(ui_text(label, ui_language), value, note)
|
|
710
734
|
st.divider()
|
|
711
|
-
st.subheader("Pipeline")
|
|
712
|
-
st.caption("Filas locais e dependências da cascata")
|
|
735
|
+
st.subheader(ui_text("Pipeline", ui_language))
|
|
736
|
+
st.caption(ui_text("Filas locais e dependências da cascata", ui_language))
|
|
713
737
|
queues = read_json("queues.json", {})
|
|
714
738
|
blueprint_count = len(list_blueprint_files())
|
|
715
739
|
for row_start in range(0, len(STAGES), 3):
|
|
@@ -717,9 +741,10 @@ def render_dashboard():
|
|
|
717
741
|
for col, stage in zip(queue_cols, STAGES[row_start:row_start + 3]):
|
|
718
742
|
with col:
|
|
719
743
|
if stage == "blueprint":
|
|
720
|
-
|
|
744
|
+
queue_note = f'{ui_text("na biblioteca", ui_language)} · {len(queues.get(stage, []))} {ui_text("tarefa(s) na fila", ui_language)}'
|
|
745
|
+
card(ui_text("Blueprints", ui_language), blueprint_count, queue_note)
|
|
721
746
|
else:
|
|
722
|
-
card(stage.title(), len(queues.get(stage, [])), "fila")
|
|
747
|
+
card(ui_text(stage.title(), ui_language), len(queues.get(stage, [])), ui_text("fila", ui_language))
|
|
723
748
|
|
|
724
749
|
|
|
725
750
|
def render_blueprints():
|
package/hermes_ui/languages.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import base64
|
|
5
6
|
from typing import Any
|
|
6
7
|
|
|
7
8
|
|
|
@@ -22,53 +23,38 @@ LANGUAGE_CATALOG: tuple[dict[str, str], ...] = (
|
|
|
22
23
|
LANGUAGE_BY_CODE = {item["code"]: item for item in LANGUAGE_CATALOG}
|
|
23
24
|
LANGUAGE_CODES = tuple(item["code"] for item in LANGUAGE_CATALOG)
|
|
24
25
|
|
|
25
|
-
#
|
|
26
|
+
# SVGs are embedded locally so flags render as images instead of relying on the
|
|
27
|
+
# host operating system's emoji font (which may show regional-letter siglas).
|
|
28
|
+
LANGUAGE_FLAG_SVGS: dict[str, str] = {
|
|
29
|
+
"en": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><rect width="30" height="20" fill="#fff"/><path fill="#b22234" d="M0 0h30v2H0zm0 4h30v2H0zm0 4h30v2H0zm0 4h30v2H0zm0 4h30v2H0zm0 4h30v2H0z"/><rect width="13" height="10.8" fill="#3c3b6e"/><g fill="#fff"><circle cx="2" cy="2" r=".55"/><circle cx="5" cy="2" r=".55"/><circle cx="8" cy="2" r=".55"/><circle cx="11" cy="2" r=".55"/><circle cx="3.5" cy="4.2" r=".55"/><circle cx="6.5" cy="4.2" r=".55"/><circle cx="9.5" cy="4.2" r=".55"/><circle cx="2" cy="6.4" r=".55"/><circle cx="5" cy="6.4" r=".55"/><circle cx="8" cy="6.4" r=".55"/><circle cx="11" cy="6.4" r=".55"/><circle cx="3.5" cy="8.6" r=".55"/><circle cx="6.5" cy="8.6" r=".55"/><circle cx="9.5" cy="8.6" r=".55"/></g></svg>',
|
|
30
|
+
"zh": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><rect width="30" height="20" fill="#de2910"/><path fill="#ffde00" d="m6 2 1 2.1 2.3.2-1.8 1.5.6 2.2L6 6.8 3.9 8l.6-2.2-1.8-1.5L5 4.1z"/></svg>',
|
|
31
|
+
"de": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#000" d="M0 0h30v6.67H0z"/><path fill="#d00" d="M0 6.67h30v6.66H0z"/><path fill="#ffce00" d="M0 13.33h30V20H0z"/></svg>',
|
|
32
|
+
"vi": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><rect width="30" height="20" fill="#da251d"/><path fill="#ff0" d="m15 3 1.9 5.7h6l-4.9 3.5 1.9 5.8-4.9-3.6 1.9-5.8-4.9-3.5h6z"/></svg>',
|
|
33
|
+
"tr": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><rect width="30" height="20" fill="#e30a17"/><circle cx="13" cy="10" r="5.2" fill="#fff"/><circle cx="15" cy="10" r="4.2" fill="#e30a17"/><path fill="#fff" d="m19 6.1 1.2 3.1 3.3.1-2.6 2 1 3.2-2.9-1.9-2.8 1.9 1-3.2-2.6-2 3.3-.1z"/></svg>',
|
|
34
|
+
"pt": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><rect width="30" height="20" fill="#ffdf00"/><path fill="#009c3b" d="m15 1.2 12.2 8.8L15 18.8 2.8 10z"/><circle cx="15" cy="10" r="4.1" fill="#002776"/><path fill="#fff" d="M11.4 9.4c2.2-1.1 4.7-.9 7.1.6l-.3 1.1c-2.2-1.4-4.4-1.6-6.5-.6z"/></svg>',
|
|
35
|
+
"ru": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#fff" d="M0 0h30v6.67H0z"/><path fill="#22408c" d="M0 6.67h30v6.66H0z"/><path fill="#d52b1e" d="M0 13.33h30V20H0z"/></svg>',
|
|
36
|
+
"es": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#aa151b" d="M0 0h30v4H0zM0 16h30v4H0z"/><rect y="4" width="30" height="12" fill="#f1bf00"/><path fill="#ad1519" d="M7 7h2v6H7z"/></svg>',
|
|
37
|
+
"id": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#ce1126" d="M0 0h30v10H0z"/><path fill="#fff" d="M0 10h30v10H0z"/></svg>',
|
|
38
|
+
"it": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#009246" d="M0 0h10v20H0z"/><path fill="#f1f2f1" d="M10 0h10v20H10z"/><path fill="#ce2b37" d="M20 0h10v20H20z"/></svg>',
|
|
39
|
+
}
|
|
40
|
+
LANGUAGE_FLAG_DATA_URIS = {
|
|
41
|
+
code: "data:image/svg+xml;base64," + base64.b64encode(svg.encode("utf-8")).decode("ascii")
|
|
42
|
+
for code, svg in LANGUAGE_FLAG_SVGS.items()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Legacy labels used by existing channels, scripts and tests. They remain
|
|
26
46
|
# readable while new UI selections persist only the canonical short code.
|
|
27
47
|
LEGACY_LANGUAGE_CODES = {
|
|
28
|
-
"01 – inglês": "en",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"36 – português (brasil)": "pt",
|
|
39
|
-
"36 - português (brasil)": "pt",
|
|
40
|
-
"39 – mandarim": "zh",
|
|
41
|
-
"39 - mandarim": "zh",
|
|
42
|
-
"13 – espanhol (espanha)": "es",
|
|
43
|
-
"41 - espanhol (latam)": "es",
|
|
44
|
-
"42 – vietnamita": "vi",
|
|
45
|
-
"42 - vietnamita": "vi",
|
|
46
|
-
"44 – indonésio": "id",
|
|
47
|
-
"44 - indonésio": "id",
|
|
48
|
-
"13 – espanhol (espanha)": "es",
|
|
49
|
-
"13 - espanhol (espanha)": "es",
|
|
50
|
-
"37 – cantonês": "zh",
|
|
51
|
-
"37 - cantonês": "zh",
|
|
52
|
-
"english": "en",
|
|
53
|
-
"inglês": "en",
|
|
54
|
-
"inglés": "en",
|
|
55
|
-
"zh": "zh",
|
|
56
|
-
"chinês": "zh",
|
|
57
|
-
"chinês simplificado": "zh",
|
|
58
|
-
"deutsch": "de",
|
|
59
|
-
"alemão": "de",
|
|
60
|
-
"vietnamita": "vi",
|
|
61
|
-
"turco": "tr",
|
|
62
|
-
"português": "pt",
|
|
63
|
-
"português (brasil)": "pt",
|
|
64
|
-
"portuguese": "pt",
|
|
65
|
-
"ru": "ru",
|
|
66
|
-
"russo": "ru",
|
|
67
|
-
"español": "es",
|
|
68
|
-
"espanhol": "es",
|
|
69
|
-
"indonésio": "id",
|
|
70
|
-
"bahasa indonesia": "id",
|
|
71
|
-
"italiano": "it",
|
|
48
|
+
"01 – inglês": "en", "01 - inglês": "en", "06 – alemão": "de", "06 - alemão": "de",
|
|
49
|
+
"15 – italiano": "it", "15 - italiano": "it", "29 – turco": "tr", "29 - turco": "tr",
|
|
50
|
+
"31 – russo": "ru", "31 - russo": "ru", "36 – português (brasil)": "pt", "36 - português (brasil)": "pt",
|
|
51
|
+
"39 – mandarim": "zh", "39 - mandarim": "zh", "13 – espanhol (espanha)": "es", "13 - espanhol (espanha)": "es",
|
|
52
|
+
"41 - espanhol (latam)": "es", "42 – vietnamita": "vi", "42 - vietnamita": "vi",
|
|
53
|
+
"44 – indonésio": "id", "44 - indonésio": "id", "37 – cantonês": "zh", "37 - cantonês": "zh",
|
|
54
|
+
"english": "en", "inglês": "en", "inglés": "en", "zh": "zh", "chinês": "zh", "chinês simplificado": "zh",
|
|
55
|
+
"deutsch": "de", "alemão": "de", "vietnamita": "vi", "turco": "tr", "português": "pt",
|
|
56
|
+
"português (brasil)": "pt", "portuguese": "pt", "ru": "ru", "russo": "ru", "español": "es",
|
|
57
|
+
"espanhol": "es", "indonésio": "id", "bahasa indonesia": "id", "italiano": "it",
|
|
72
58
|
}
|
|
73
59
|
|
|
74
60
|
|
|
@@ -87,13 +73,21 @@ def language_code(value: Any, default: str = "pt") -> str:
|
|
|
87
73
|
|
|
88
74
|
|
|
89
75
|
def language_label(value: Any, *, include_code: bool = True) -> str:
|
|
90
|
-
"""Return
|
|
76
|
+
"""Return a text label with the legacy emoji flag presentation."""
|
|
91
77
|
code = language_code(value)
|
|
92
78
|
item = LANGUAGE_BY_CODE[code]
|
|
93
79
|
suffix = f" ({item['code']})" if include_code else ""
|
|
94
80
|
return f"{item['name']}{suffix} {item['flag']}"
|
|
95
81
|
|
|
96
82
|
|
|
83
|
+
def ui_language_menu_label(value: Any, *, include_code: bool = True) -> str:
|
|
84
|
+
"""Return text-only UI label; the picker renders the flag as a real SVG icon."""
|
|
85
|
+
code = language_code(value)
|
|
86
|
+
item = LANGUAGE_BY_CODE[code]
|
|
87
|
+
suffix = f" ({item['code']})" if include_code else ""
|
|
88
|
+
return f"{item['name']}{suffix}"
|
|
89
|
+
|
|
90
|
+
|
|
97
91
|
def language_option_labels(*, include_code: bool = True) -> list[str]:
|
|
98
92
|
return [language_label(item["code"], include_code=include_code) for item in LANGUAGE_CATALOG]
|
|
99
93
|
|
|
@@ -102,51 +96,47 @@ def language_option_codes() -> list[str]:
|
|
|
102
96
|
return list(LANGUAGE_CODES)
|
|
103
97
|
|
|
104
98
|
|
|
99
|
+
_CORE_UI_TEXT_KEYS = (
|
|
100
|
+
"Início", "Niche Finder", "Pipeline", "Pipeline TikTok", "Automação", "Edição", "AI Influencers", "Configurações",
|
|
101
|
+
"Criação de Vídeos", "Criação de Músicas", "Roteiros", "Upload", "Prompts Master", "Contas TikTok", "Automação Youtube",
|
|
102
|
+
"Niche Finder Kaggle", "Niche Finder Apify", "Limpador de Metadados", "Cortes", "Editor Python", "Download Mídia",
|
|
103
|
+
"Personagens", "Redes Sociais", "Tutorial Meta", "Canais Youtube", "Blueprints Youtube", "MCP", "Contas Google",
|
|
104
|
+
"Configuração API", "Notificações", "Interface local para operação e automação de conteúdo faceless", "Canais", "activos",
|
|
105
|
+
"Tarefas", "total registado", "A fazer", "na pipeline", "Em execução", "a decorrer", "Concluídos", "artefactos prontos",
|
|
106
|
+
"Falhas", "requerem atenção", "Filas locais e dependências da cascata", "Niche", "Blueprints", "Brand", "Script", "Title",
|
|
107
|
+
"Thumbnail", "Video", "Edit", "fila", "na biblioteca", "tarefa(s) na fila", "Language",
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
105
111
|
UI_TRANSLATIONS: dict[str, dict[str, str]] = {
|
|
112
|
+
"pt": {key: key for key in _CORE_UI_TEXT_KEYS},
|
|
106
113
|
"en": {
|
|
107
|
-
"Início": "Home", "Niche Finder": "Niche Finder", "Pipeline": "Pipeline", "Pipeline TikTok": "TikTok Pipeline",
|
|
108
|
-
"Automação": "Automation", "Edição": "Editing", "AI Influencers": "AI Influencers", "Configurações": "Settings",
|
|
109
|
-
"Criação de Vídeos": "Video Creation", "Criação de Músicas": "Music Creation", "Roteiros": "Scripts", "Upload": "Upload",
|
|
110
|
-
"Prompts Master": "Prompt Masters", "Contas TikTok": "TikTok Accounts", "Automação Youtube": "YouTube Automation",
|
|
111
|
-
"Canais Youtube": "YouTube Channels", "Blueprints Youtube": "YouTube Blueprints", "Contas Google": "Google Accounts",
|
|
112
|
-
"Configuração API": "API Configuration", "Notificações": "Notifications", "Niche Finder Kaggle": "Niche Finder Kaggle",
|
|
113
|
-
"Niche Finder Apify": "Niche Finder Apify", "Limpador de Metadados": "Metadata Cleaner", "Cortes": "Cuts",
|
|
114
|
-
"Editor Python": "Python Editor", "Download Mídia": "Media Download", "Personagens": "Characters", "Redes Sociais": "Social Networks",
|
|
115
|
-
"Tutorial Meta": "Meta Tutorial", "Idioma da interface": "Interface language",
|
|
114
|
+
"Início": "Home", "Niche Finder": "Niche Finder", "Pipeline": "Pipeline", "Pipeline TikTok": "TikTok Pipeline", "Automação": "Automation", "Edição": "Editing", "AI Influencers": "AI Influencers", "Configurações": "Settings", "Criação de Vídeos": "Video Creation", "Criação de Músicas": "Music Creation", "Roteiros": "Scripts", "Upload": "Upload", "Prompts Master": "Prompt Masters", "Contas TikTok": "TikTok Accounts", "Automação Youtube": "YouTube Automation", "Niche Finder Kaggle": "Niche Finder Kaggle", "Niche Finder Apify": "Niche Finder Apify", "Limpador de Metadados": "Metadata Cleaner", "Cortes": "Cuts", "Editor Python": "Python Editor", "Download Mídia": "Media Download", "Personagens": "Characters", "Redes Sociais": "Social Networks", "Tutorial Meta": "Meta Tutorial", "Canais Youtube": "YouTube Channels", "Blueprints Youtube": "YouTube Blueprints", "MCP": "MCP", "Contas Google": "Google Accounts", "Configuração API": "API Configuration", "Notificações": "Notifications", "Interface local para operação e automação de conteúdo faceless": "Local interface for faceless content operation and automation", "Canais": "Channels", "activos": "active", "Tarefas": "Tasks", "total registado": "total registered", "A fazer": "To do", "na pipeline": "in pipeline", "Em execução": "Running", "a decorrer": "in progress", "Concluídos": "Completed", "artefactos prontos": "ready artifacts", "Falhas": "Failures", "requerem atenção": "need attention", "Filas locais e dependências da cascata": "Local queues and cascade dependencies", "Niche": "Niche", "Blueprints": "Blueprints", "Brand": "Brand", "Script": "Script", "Title": "Title", "Thumbnail": "Thumbnail", "Video": "Video", "Edit": "Edit", "fila": "queue", "na biblioteca": "in library", "tarefa(s) na fila": "task(s) in queue", "Language": "Language",
|
|
116
115
|
},
|
|
117
116
|
"zh": {
|
|
118
|
-
"Início": "首页", "Pipeline": "视频流程", "Pipeline TikTok": "TikTok 流程", "Automação": "自动化", "Edição": "编辑", "Configurações": "设置",
|
|
119
|
-
"Criação de Vídeos": "视频创作", "Criação de Músicas": "音乐创作", "Roteiros": "脚本", "Upload": "上传", "Contas Google": "Google 账户", "Notificações": "通知", "Idioma da interface": "界面语言",
|
|
117
|
+
"Início": "首页", "Niche Finder": "利基搜索", "Pipeline": "视频流程", "Pipeline TikTok": "TikTok 流程", "Automação": "自动化", "Edição": "编辑", "AI Influencers": "AI 影响者", "Configurações": "设置", "Criação de Vídeos": "视频创作", "Criação de Músicas": "音乐创作", "Roteiros": "脚本", "Upload": "上传", "Prompts Master": "主提示词", "Contas TikTok": "TikTok 账户", "Automação Youtube": "YouTube 自动化", "Niche Finder Kaggle": "Kaggle 利基搜索", "Niche Finder Apify": "Apify 利基搜索", "Limpador de Metadados": "元数据清理器", "Cortes": "剪辑", "Editor Python": "Python 编辑器", "Download Mídia": "媒体下载", "Personagens": "角色", "Redes Sociais": "社交网络", "Tutorial Meta": "Meta 教程", "Canais Youtube": "YouTube 频道", "Blueprints Youtube": "YouTube 蓝图", "MCP": "MCP", "Contas Google": "Google 账户", "Configuração API": "API 配置", "Notificações": "通知", "Interface local para operação e automação de conteúdo faceless": "无脸内容运营与自动化本地界面", "Canais": "频道", "activos": "活跃", "Tarefas": "任务", "total registado": "已登记总数", "A fazer": "待处理", "na pipeline": "在流程中", "Em execução": "执行中", "a decorrer": "正在进行", "Concluídos": "已完成", "artefactos prontos": "成品已就绪", "Falhas": "失败", "requerem atenção": "需要关注", "Filas locais e dependências da cascata": "本地队列和级联依赖", "Niche": "利基", "Blueprints": "蓝图", "Brand": "品牌", "Script": "脚本", "Title": "标题", "Thumbnail": "缩略图", "Video": "视频", "Edit": "编辑", "fila": "队列", "na biblioteca": "在库中", "tarefa(s) na fila": "队列中的任务", "Language": "语言",
|
|
120
118
|
},
|
|
121
119
|
"de": {
|
|
122
|
-
"Início": "Startseite", "Pipeline": "Pipeline", "Pipeline TikTok": "TikTok-Pipeline", "Automação": "Automatisierung", "Edição": "Bearbeitung", "Configurações": "Einstellungen",
|
|
123
|
-
"Criação de Vídeos": "Videoerstellung", "Criação de Músicas": "Musikerstellung", "Roteiros": "Skripte", "Upload": "Upload", "Contas Google": "Google-Konten", "Notificações": "Benachrichtigungen", "Idioma da interface": "Oberflächensprache",
|
|
120
|
+
"Início": "Startseite", "Niche Finder": "Nischenfinder", "Pipeline": "Pipeline", "Pipeline TikTok": "TikTok-Pipeline", "Automação": "Automatisierung", "Edição": "Bearbeitung", "AI Influencers": "KI-Influencer", "Configurações": "Einstellungen", "Criação de Vídeos": "Videoerstellung", "Criação de Músicas": "Musikerstellung", "Roteiros": "Skripte", "Upload": "Upload", "Prompts Master": "Prompt Masters", "Contas TikTok": "TikTok-Konten", "Automação Youtube": "YouTube-Automatisierung", "Niche Finder Kaggle": "Kaggle-Nischenfinder", "Niche Finder Apify": "Apify-Nischenfinder", "Limpador de Metadados": "Metadatenbereinigung", "Cortes": "Schnitte", "Editor Python": "Python-Editor", "Download Mídia": "Mediendownload", "Personagens": "Figuren", "Redes Sociais": "Soziale Netzwerke", "Tutorial Meta": "Meta-Tutorial", "Canais Youtube": "YouTube-Kanäle", "Blueprints Youtube": "YouTube-Blueprints", "MCP": "MCP", "Contas Google": "Google-Konten", "Configuração API": "API-Konfiguration", "Notificações": "Benachrichtigungen", "Interface local para operação e automação de conteúdo faceless": "Lokale Oberfläche für den Betrieb und die Automatisierung von Faceless-Inhalten", "Canais": "Kanäle", "activos": "aktiv", "Tarefas": "Aufgaben", "total registado": "insgesamt registriert", "A fazer": "Offen", "na pipeline": "in der Pipeline", "Em execução": "In Ausführung", "a decorrer": "in Bearbeitung", "Concluídos": "Abgeschlossen", "artefactos prontos": "fertige Artefakte", "Falhas": "Fehler", "requerem atenção": "benötigen Aufmerksamkeit", "Filas locais e dependências da cascata": "Lokale Warteschlangen und Abhängigkeiten", "Niche": "Nische", "Blueprints": "Blueprints", "Brand": "Marke", "Script": "Skript", "Title": "Titel", "Thumbnail": "Thumbnail", "Video": "Video", "Edit": "Bearbeitung", "fila": "Warteschlange", "na biblioteca": "in der Bibliothek", "tarefa(s) na fila": "Aufgabe(n) in der Warteschlange", "Language": "Sprache",
|
|
124
121
|
},
|
|
125
122
|
"vi": {
|
|
126
|
-
"Início": "Trang chủ", "Pipeline": "Quy trình", "Pipeline TikTok": "Quy trình TikTok", "Automação": "Tự động hóa", "Edição": "Chỉnh sửa", "Configurações": "Cài đặt",
|
|
127
|
-
"Criação de Vídeos": "Tạo video", "Criação de Músicas": "Tạo nhạc", "Roteiros": "Kịch bản", "Upload": "Tải lên", "Contas Google": "Tài khoản Google", "Notificações": "Thông báo", "Idioma da interface": "Ngôn ngữ giao diện",
|
|
123
|
+
"Início": "Trang chủ", "Niche Finder": "Tìm ngách", "Pipeline": "Quy trình", "Pipeline TikTok": "Quy trình TikTok", "Automação": "Tự động hóa", "Edição": "Chỉnh sửa", "AI Influencers": "Người ảnh hưởng AI", "Configurações": "Cài đặt", "Criação de Vídeos": "Tạo video", "Criação de Músicas": "Tạo nhạc", "Roteiros": "Kịch bản", "Upload": "Tải lên", "Prompts Master": "Prompt Master", "Contas TikTok": "Tài khoản TikTok", "Automação Youtube": "Tự động hóa YouTube", "Niche Finder Kaggle": "Tìm ngách Kaggle", "Niche Finder Apify": "Tìm ngách Apify", "Limpador de Metadados": "Trình dọn siêu dữ liệu", "Cortes": "Cắt", "Editor Python": "Trình soạn thảo Python", "Download Mídia": "Tải phương tiện", "Personagens": "Nhân vật", "Redes Sociais": "Mạng xã hội", "Tutorial Meta": "Hướng dẫn Meta", "Canais Youtube": "Kênh YouTube", "Blueprints Youtube": "Blueprint YouTube", "MCP": "MCP", "Contas Google": "Tài khoản Google", "Configuração API": "Cấu hình API", "Notificações": "Thông báo", "Interface local para operação e automação de conteúdo faceless": "Giao diện cục bộ để vận hành và tự động hóa nội dung faceless", "Canais": "Kênh", "activos": "đang hoạt động", "Tarefas": "Tác vụ", "total registado": "tổng số đã đăng ký", "A fazer": "Cần làm", "na pipeline": "trong quy trình", "Em execução": "Đang chạy", "a decorrer": "đang diễn ra", "Concluídos": "Đã hoàn tất", "artefactos prontos": "sản phẩm đã sẵn sàng", "Falhas": "Lỗi", "requerem atenção": "cần chú ý", "Filas locais e dependências da cascata": "Hàng đợi cục bộ và các phụ thuộc", "Niche": "Ngách", "Blueprints": "Blueprint", "Brand": "Thương hiệu", "Script": "Kịch bản", "Title": "Tiêu đề", "Thumbnail": "Ảnh thu nhỏ", "Video": "Video", "Edit": "Chỉnh sửa", "fila": "hàng đợi", "na biblioteca": "trong thư viện", "tarefa(s) na fila": "tác vụ trong hàng đợi", "Language": "Ngôn ngữ",
|
|
128
124
|
},
|
|
129
125
|
"tr": {
|
|
130
|
-
"Início": "Ana sayfa", "Pipeline": "Akış", "Pipeline TikTok": "TikTok
|
|
131
|
-
"Criação de Vídeos": "Video oluşturma", "Criação de Músicas": "Müzik oluşturma", "Roteiros": "Senaryolar", "Upload": "Yükleme", "Contas Google": "Google hesapları", "Notificações": "Bildirimler", "Idioma da interface": "Arayüz dili",
|
|
126
|
+
"Início": "Ana sayfa", "Niche Finder": "Niş Bulucu", "Pipeline": "Akış", "Pipeline TikTok": "TikTok Akışı", "Automação": "Otomasyon", "Edição": "Düzenleme", "AI Influencers": "Yapay Zekâ Etkileyicileri", "Configurações": "Ayarlar", "Criação de Vídeos": "Video Oluşturma", "Criação de Músicas": "Müzik Oluşturma", "Roteiros": "Senaryolar", "Upload": "Yükleme", "Prompts Master": "Prompt Master", "Contas TikTok": "TikTok Hesapları", "Automação Youtube": "YouTube Otomasyonu", "Niche Finder Kaggle": "Kaggle Niş Bulucu", "Niche Finder Apify": "Apify Niş Bulucu", "Limpador de Metadados": "Meta Veri Temizleyici", "Cortes": "Kesitler", "Editor Python": "Python Editörü", "Download Mídia": "Medya İndirme", "Personagens": "Karakterler", "Redes Sociais": "Sosyal Ağlar", "Tutorial Meta": "Meta Eğitimi", "Canais Youtube": "YouTube Kanalları", "Blueprints Youtube": "YouTube Blueprint'leri", "MCP": "MCP", "Contas Google": "Google Hesapları", "Configuração API": "API Yapılandırması", "Notificações": "Bildirimler", "Interface local para operação e automação de conteúdo faceless": "Faceless içerik operasyonu ve otomasyonu için yerel arayüz", "Canais": "Kanallar", "activos": "aktif", "Tarefas": "Görevler", "total registado": "kayıtlı toplam", "A fazer": "Yapılacak", "na pipeline": "akışta", "Em execução": "Çalışıyor", "a decorrer": "devam ediyor", "Concluídos": "Tamamlandı", "artefactos prontos": "hazır çıktılar", "Falhas": "Hatalar", "requerem atenção": "dikkat gerekiyor", "Filas locais e dependências da cascata": "Yerel kuyruklar ve bağımlılıklar", "Niche": "Niş", "Blueprints": "Blueprint", "Brand": "Marka", "Script": "Senaryo", "Title": "Başlık", "Thumbnail": "Küçük resim", "Video": "Video", "Edit": "Düzenle", "fila": "kuyruk", "na biblioteca": "kütüphanede", "tarefa(s) na fila": "kuyruktaki görev(ler)", "Language": "Dil",
|
|
132
127
|
},
|
|
133
128
|
"ru": {
|
|
134
|
-
"Início": "Главная", "Pipeline": "Конвейер", "Pipeline TikTok": "Конвейер TikTok", "Automação": "Автоматизация", "Edição": "Редактирование", "Configurações": "Настройки",
|
|
135
|
-
"Criação de Vídeos": "Создание видео", "Criação de Músicas": "Создание музыки", "Roteiros": "Сценарии", "Upload": "Загрузка", "Contas Google": "Аккаунты Google", "Notificações": "Уведомления", "Idioma da interface": "Язык интерфейса",
|
|
129
|
+
"Início": "Главная", "Niche Finder": "Поиск ниши", "Pipeline": "Конвейер", "Pipeline TikTok": "Конвейер TikTok", "Automação": "Автоматизация", "Edição": "Редактирование", "AI Influencers": "ИИ-инфлюенсеры", "Configurações": "Настройки", "Criação de Vídeos": "Создание видео", "Criação de Músicas": "Создание музыки", "Roteiros": "Сценарии", "Upload": "Загрузка", "Prompts Master": "Мастер-промпты", "Contas TikTok": "Аккаунты TikTok", "Automação Youtube": "Автоматизация YouTube", "Niche Finder Kaggle": "Поиск ниши Kaggle", "Niche Finder Apify": "Поиск ниши Apify", "Limpador de Metadados": "Очистка метаданных", "Cortes": "Нарезка", "Editor Python": "Редактор Python", "Download Mídia": "Загрузка медиа", "Personagens": "Персонажи", "Redes Sociais": "Социальные сети", "Tutorial Meta": "Руководство Meta", "Canais Youtube": "Каналы YouTube", "Blueprints Youtube": "Blueprint YouTube", "MCP": "MCP", "Contas Google": "Аккаунты Google", "Configuração API": "Настройка API", "Notificações": "Уведомления", "Interface local para operação e automação de conteúdo faceless": "Локальный интерфейс для работы и автоматизации faceless-контента", "Canais": "Каналы", "activos": "активны", "Tarefas": "Задачи", "total registado": "всего зарегистрировано", "A fazer": "К выполнению", "na pipeline": "в конвейере", "Em execução": "Выполняются", "a decorrer": "в процессе", "Concluídos": "Завершены", "artefactos prontos": "готовые материалы", "Falhas": "Ошибки", "requerem atenção": "требуют внимания", "Filas locais e dependências da cascata": "Локальные очереди и зависимости конвейера", "Niche": "Ниша", "Blueprints": "Blueprints", "Brand": "Бренд", "Script": "Сценарий", "Title": "Заголовок", "Thumbnail": "Миниатюра", "Video": "Видео", "Edit": "Монтаж", "fila": "очередь", "na biblioteca": "в библиотеке", "tarefa(s) na fila": "задач в очереди", "Language": "Язык",
|
|
136
130
|
},
|
|
137
131
|
"es": {
|
|
138
|
-
"Início": "Inicio", "Pipeline": "Flujo", "Pipeline TikTok": "Flujo de TikTok", "Automação": "Automatización", "Edição": "Edición", "Configurações": "Configuración",
|
|
139
|
-
"Criação de Vídeos": "Creación de vídeos", "Criação de Músicas": "Creación de música", "Roteiros": "Guiones", "Upload": "Carga", "Contas Google": "Cuentas de Google", "Notificações": "Notificaciones", "Idioma da interface": "Idioma de la interfaz",
|
|
132
|
+
"Início": "Inicio", "Niche Finder": "Buscador de nichos", "Pipeline": "Flujo", "Pipeline TikTok": "Flujo de TikTok", "Automação": "Automatización", "Edição": "Edición", "AI Influencers": "Influencers de IA", "Configurações": "Configuración", "Criação de Vídeos": "Creación de vídeos", "Criação de Músicas": "Creación de música", "Roteiros": "Guiones", "Upload": "Subir", "Prompts Master": "Prompts maestros", "Contas TikTok": "Cuentas de TikTok", "Automação Youtube": "Automatización de YouTube", "Niche Finder Kaggle": "Buscador de nichos Kaggle", "Niche Finder Apify": "Buscador de nichos Apify", "Limpador de Metadados": "Limpiador de metadatos", "Cortes": "Cortes", "Editor Python": "Editor de Python", "Download Mídia": "Descargar medios", "Personagens": "Personajes", "Redes Sociais": "Redes sociales", "Tutorial Meta": "Tutorial de Meta", "Canais Youtube": "Canales de YouTube", "Blueprints Youtube": "Blueprints de YouTube", "MCP": "MCP", "Contas Google": "Cuentas de Google", "Configuração API": "Configuración de API", "Notificações": "Notificaciones", "Interface local para operação e automação de conteúdo faceless": "Interfaz local para operar y automatizar contenido faceless", "Canais": "Canales", "activos": "activos", "Tarefas": "Tareas", "total registado": "total registrado", "A fazer": "Pendiente", "na pipeline": "en el flujo", "Em execução": "En ejecución", "a decorrer": "en curso", "Concluídos": "Completados", "artefactos prontos": "artefactos listos", "Falhas": "Fallos", "requerem atenção": "requieren atención", "Filas locais e dependências da cascata": "Colas locales y dependencias del flujo", "Niche": "Nicho", "Blueprints": "Blueprints", "Brand": "Marca", "Script": "Guion", "Title": "Título", "Thumbnail": "Miniatura", "Video": "Vídeo", "Edit": "Edición", "fila": "cola", "na biblioteca": "en la biblioteca", "tarefa(s) na fila": "tarea(s) en la cola", "Language": "Idioma",
|
|
140
133
|
},
|
|
141
134
|
"id": {
|
|
142
|
-
"Início": "Beranda", "Pipeline": "Alur", "Pipeline TikTok": "Alur TikTok", "Automação": "Otomatisasi", "Edição": "Penyuntingan", "Configurações": "Pengaturan",
|
|
143
|
-
"Criação de Vídeos": "Pembuatan video", "Criação de Músicas": "Pembuatan musik", "Roteiros": "Skrip", "Upload": "Unggah", "Contas Google": "Akun Google", "Notificações": "Notifikasi", "Idioma da interface": "Bahasa antarmuka",
|
|
135
|
+
"Início": "Beranda", "Niche Finder": "Pencari Niche", "Pipeline": "Alur", "Pipeline TikTok": "Alur TikTok", "Automação": "Otomatisasi", "Edição": "Penyuntingan", "AI Influencers": "Influencer AI", "Configurações": "Pengaturan", "Criação de Vídeos": "Pembuatan video", "Criação de Músicas": "Pembuatan musik", "Roteiros": "Skrip", "Upload": "Unggah", "Prompts Master": "Prompt Master", "Contas TikTok": "Akun TikTok", "Automação Youtube": "Otomatisasi YouTube", "Niche Finder Kaggle": "Pencari Niche Kaggle", "Niche Finder Apify": "Pencari Niche Apify", "Limpador de Metadados": "Pembersih metadata", "Cortes": "Potongan", "Editor Python": "Editor Python", "Download Mídia": "Unduh media", "Personagens": "Karakter", "Redes Sociais": "Jejaring sosial", "Tutorial Meta": "Tutorial Meta", "Canais Youtube": "Kanal YouTube", "Blueprints Youtube": "Blueprint YouTube", "MCP": "MCP", "Contas Google": "Akun Google", "Configuração API": "Konfigurasi API", "Notificações": "Notifikasi", "Interface local para operação e automação de conteúdo faceless": "Antarmuka lokal untuk operasi dan otomatisasi konten faceless", "Canais": "Kanal", "activos": "aktif", "Tarefas": "Tugas", "total registado": "total terdaftar", "A fazer": "Perlu dilakukan", "na pipeline": "dalam alur", "Em execução": "Berjalan", "a decorrer": "sedang berlangsung", "Concluídos": "Selesai", "artefactos prontos": "artefak siap", "Falhas": "Kegagalan", "requerem atenção": "perlu perhatian", "Filas locais e dependências da cascata": "Antrean lokal dan dependensi alur", "Niche": "Niche", "Blueprints": "Blueprint", "Brand": "Merek", "Script": "Skrip", "Title": "Judul", "Thumbnail": "Thumbnail", "Video": "Video", "Edit": "Edit", "fila": "antrean", "na biblioteca": "di pustaka", "tarefa(s) na fila": "tugas dalam antrean", "Language": "Bahasa",
|
|
144
136
|
},
|
|
145
137
|
"it": {
|
|
146
|
-
"Início": "Home", "Pipeline": "Pipeline", "Pipeline TikTok": "Pipeline TikTok", "Automação": "Automazione", "Edição": "Modifica", "Configurações": "Impostazioni",
|
|
147
|
-
"Criação de Vídeos": "Creazione video", "Criação de Músicas": "Creazione musicale", "Roteiros": "Script", "Upload": "Caricamento", "Contas Google": "Account Google", "Notificações": "Notifiche", "Idioma da interface": "Lingua dell'interfaccia",
|
|
138
|
+
"Início": "Home", "Niche Finder": "Trova nicchia", "Pipeline": "Pipeline", "Pipeline TikTok": "Pipeline TikTok", "Automação": "Automazione", "Edição": "Modifica", "AI Influencers": "Influencer AI", "Configurações": "Impostazioni", "Criação de Vídeos": "Creazione video", "Criação de Músicas": "Creazione musicale", "Roteiros": "Script", "Upload": "Caricamento", "Prompts Master": "Prompt Master", "Contas TikTok": "Account TikTok", "Automação Youtube": "Automazione YouTube", "Niche Finder Kaggle": "Trova nicchia Kaggle", "Niche Finder Apify": "Trova nicchia Apify", "Limpador de Metadados": "Pulizia metadati", "Cortes": "Tagli", "Editor Python": "Editor Python", "Download Mídia": "Download media", "Personagens": "Personaggi", "Redes Sociais": "Social network", "Tutorial Meta": "Tutorial Meta", "Canais Youtube": "Canali YouTube", "Blueprints Youtube": "Blueprint YouTube", "MCP": "MCP", "Contas Google": "Account Google", "Configuração API": "Configurazione API", "Notificações": "Notifiche", "Interface local para operação e automação de conteúdo faceless": "Interfaccia locale per la gestione e l'automazione di contenuti faceless", "Canais": "Canali", "activos": "attivi", "Tarefas": "Attività", "total registado": "totale registrato", "A fazer": "Da fare", "na pipeline": "nella pipeline", "Em execução": "In esecuzione", "a decorrer": "in corso", "Concluídos": "Completati", "artefactos prontos": "artefatti pronti", "Falhas": "Errori", "requerem atenção": "richiedono attenzione", "Filas locais e dependências da cascata": "Code locali e dipendenze della pipeline", "Niche": "Nicchia", "Blueprints": "Blueprint", "Brand": "Brand", "Script": "Script", "Title": "Titolo", "Thumbnail": "Miniatura", "Video": "Video", "Edit": "Modifica", "fila": "coda", "na biblioteca": "nella libreria", "tarefa(s) na fila": "attività in coda", "Language": "Lingua",
|
|
148
139
|
},
|
|
149
|
-
"pt": {},
|
|
150
140
|
}
|
|
151
141
|
|
|
152
142
|
|
|
@@ -166,11 +156,7 @@ def language_locale(value: Any) -> str:
|
|
|
166
156
|
def video_language_label(value: Any) -> str:
|
|
167
157
|
"""Format a video-language value while preserving all historical options."""
|
|
168
158
|
raw = str(value or "").strip()
|
|
169
|
-
if raw.casefold() in {
|
|
170
|
-
"music",
|
|
171
|
-
"00 – apenas música de fundo (sem falas)",
|
|
172
|
-
"00 - apenas música de fundo (sem falas)",
|
|
173
|
-
}:
|
|
159
|
+
if raw.casefold() in {"music", "00 – apenas música de fundo (sem falas)", "00 - apenas música de fundo (sem falas)"}:
|
|
174
160
|
return "🎵 Apenas Música de Fundo (Sem Falas)"
|
|
175
161
|
normalized = language_code(raw, default="")
|
|
176
162
|
if normalized in LANGUAGE_BY_CODE and (raw.casefold() in LEGACY_LANGUAGE_CODES or raw in LANGUAGE_BY_CODE):
|
|
@@ -183,15 +169,7 @@ def video_language_options() -> list[str]:
|
|
|
183
169
|
|
|
184
170
|
|
|
185
171
|
__all__ = [
|
|
186
|
-
"LANGUAGE_CATALOG",
|
|
187
|
-
"
|
|
188
|
-
"
|
|
189
|
-
"language_code",
|
|
190
|
-
"language_flag",
|
|
191
|
-
"language_label",
|
|
192
|
-
"language_locale",
|
|
193
|
-
"language_option_codes",
|
|
194
|
-
"language_option_labels",
|
|
195
|
-
"video_language_label",
|
|
196
|
-
"video_language_options",
|
|
172
|
+
"LANGUAGE_CATALOG", "LANGUAGE_BY_CODE", "LANGUAGE_CODES", "LANGUAGE_FLAG_DATA_URIS", "language_code", "language_flag",
|
|
173
|
+
"language_label", "ui_language_menu_label", "language_locale", "language_option_codes", "language_option_labels",
|
|
174
|
+
"ui_text", "video_language_label", "video_language_options",
|
|
197
175
|
]
|
package/package.json
CHANGED