From cf084265fc07650bd86f010c61a62b077e2395f1 Mon Sep 17 00:00:00 2001
From: LordGrey <48840279+Lord-Grey@users.noreply.github.com>
Date: Sat, 1 May 2021 18:05:45 +0200
Subject: [PATCH] =?UTF-8?q?New=20languages=20-=20Portuguese=20(Std/Brazil)?=
=?UTF-8?q?=20&=20Norwegian=20(Bokm=C3=A5l)=20(#1236)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Update jquery.i18n to 1.07, add extended plurals support
* Add additional languages - Portuguese, Portuguese (Brazil), Norwegian (Bokmål)
---
assets/webconfig/i18n/en.json | 2 +
assets/webconfig/i18n/nb.json | 85 ++
assets/webconfig/i18n/pt-br.json | 970 ++++++++++++++++++
assets/webconfig/i18n/pt.json | 77 ++
assets/webconfig/index.html | 13 +-
.../lib/jquery.i18n/CLDRPluralRuleParser.js | 607 +++++++++++
.../jquery.i18n/jquery.i18n.emitter.bidi.js | 95 ++
.../{ => jquery.i18n}/jquery.i18n.emitter.js | 64 +-
.../jquery.i18n.fallbacks.js | 5 +-
.../js/lib/{ => jquery.i18n}/jquery.i18n.js | 145 +--
.../{ => jquery.i18n}/jquery.i18n.language.js | 135 ++-
.../jquery.i18n.messagestore.js | 68 +-
.../{ => jquery.i18n}/jquery.i18n.parser.js | 51 +-
.../js/lib/jquery.i18n/languages/bs.js | 22 +
.../js/lib/jquery.i18n/languages/dsb.js | 22 +
.../js/lib/jquery.i18n/languages/fi.js | 49 +
.../js/lib/jquery.i18n/languages/ga.js | 38 +
.../js/lib/jquery.i18n/languages/he.js | 31 +
.../js/lib/jquery.i18n/languages/hsb.js | 21 +
.../js/lib/jquery.i18n/languages/hu.js | 26 +
.../js/lib/jquery.i18n/languages/hy.js | 25 +
.../js/lib/jquery.i18n/languages/la.js | 54 +
.../js/lib/jquery.i18n/languages/ml.js | 98 ++
.../js/lib/jquery.i18n/languages/os.js | 75 ++
.../js/lib/jquery.i18n/languages/ru.js | 29 +
.../js/lib/jquery.i18n/languages/sl.js | 26 +
.../js/lib/jquery.i18n/languages/uk.js | 39 +
assets/webconfig/js/settings.js | 7 +-
28 files changed, 2650 insertions(+), 229 deletions(-)
create mode 100644 assets/webconfig/i18n/nb.json
create mode 100644 assets/webconfig/i18n/pt-br.json
create mode 100644 assets/webconfig/i18n/pt.json
create mode 100644 assets/webconfig/js/lib/jquery.i18n/CLDRPluralRuleParser.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/jquery.i18n.emitter.bidi.js
rename assets/webconfig/js/lib/{ => jquery.i18n}/jquery.i18n.emitter.js (78%)
rename assets/webconfig/js/lib/{ => jquery.i18n}/jquery.i18n.fallbacks.js (98%)
rename assets/webconfig/js/lib/{ => jquery.i18n}/jquery.i18n.js (66%)
rename assets/webconfig/js/lib/{ => jquery.i18n}/jquery.i18n.language.js (74%)
rename assets/webconfig/js/lib/{ => jquery.i18n}/jquery.i18n.messagestore.js (80%)
rename assets/webconfig/js/lib/{ => jquery.i18n}/jquery.i18n.parser.js (84%)
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/bs.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/dsb.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/fi.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/ga.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/he.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/hsb.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/hu.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/hy.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/la.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/ml.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/os.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/ru.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/sl.js
create mode 100644 assets/webconfig/js/lib/jquery.i18n/languages/uk.js
diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json
index 27f5b4b7..eb452bb5 100644
--- a/assets/webconfig/i18n/en.json
+++ b/assets/webconfig/i18n/en.json
@@ -759,8 +759,10 @@
"general_speech_es": "Spanish",
"general_speech_fr": "French",
"general_speech_it": "Italian",
+ "general_speech_nb": "Norwegian (Bokmål)",
"general_speech_nl": "Dutch",
"general_speech_pl": "Polish",
+ "general_speech_pt": "Portuguese",
"general_speech_ro": "Romanian",
"general_speech_ru": "Russian",
"general_speech_sv": "Swedish",
diff --git a/assets/webconfig/i18n/nb.json b/assets/webconfig/i18n/nb.json
new file mode 100644
index 00000000..4f39ae1f
--- /dev/null
+++ b/assets/webconfig/i18n/nb.json
@@ -0,0 +1,85 @@
+{
+ "conf_general_impexp_expbtn": "Eksporter",
+ "conf_general_impexp_impbtn": "Importer",
+ "conf_general_label_title": "Generelle innstillinger",
+ "conf_helptable_option": "Valg",
+ "conf_leds_layout_advanced": "Avanserte innstillinger",
+ "conf_leds_layout_cl_bottom": "Bunn",
+ "conf_leds_layout_cl_left": "Venstre",
+ "conf_leds_layout_cl_right": "Høyre",
+ "conf_leds_layout_cl_top": "Topp",
+ "conf_leds_nav_label_ledlayout": "LED-oppsett",
+ "conf_leds_optgroup_network": "Nettverk",
+ "dashboard_alert_message_confedit": "Dine Hyperion konfigureringer er blitt endre. For å bruke de, restart Hyperion",
+ "dashboard_alert_message_confedit_t": "Konfigurering endret",
+ "dashboard_alert_message_confsave_success": "Dine Hyperionkonfigureringer er vellykket endret. Dine endringer er nå aktive.",
+ "dashboard_alert_message_confsave_success_t": "Konfigurasjon lagret",
+ "dashboard_componentbox_label_comp": "Komponent",
+ "dashboard_componentbox_label_status": "Status",
+ "dashboard_componentbox_label_title": "Komponentstatus",
+ "dashboard_infobox_label_currenthyp": "Din Hyperion versjon:",
+ "dashboard_infobox_label_disableh": "Deaktiver forekomst: $1",
+ "dashboard_infobox_label_instance": "Forekomst:",
+ "dashboard_infobox_label_latesthyp": "Siste Hyperion versjon:",
+ "dashboard_infobox_label_platform": "Plattform:",
+ "dashboard_infobox_label_ports": "Porter (flat|proto):",
+ "dashboard_infobox_label_smartacc": "Smart Adgang",
+ "dashboard_infobox_label_statush": "Hyperion status:",
+ "dashboard_infobox_label_title": "Informasjon",
+ "dashboard_infobox_message_updatesuccess": "Du kjører siste versjon av Hyperion.",
+ "dashboard_infobox_message_updatewarning": "En nyere versjon av Hyperion er tilgjengelig! ($1)",
+ "dashboard_label_intro": "Dashbordet gir en enkel oversikt over statusen til Hyperion og viser siste nyheter fra Hyperion Bloggen",
+ "dashboard_newsbox_label_title": "Hyperion-Blogg",
+ "dashboard_newsbox_noconn": "Kan ikke koble Hyperion Serveren for å motta siste inlegg, fungerer internettilkoblingen?",
+ "dashboard_newsbox_readmore": "Les mer",
+ "dashboard_newsbox_visitblog": "Besøk Hyperion-Bloggen",
+ "general_access_advanced": "Avansert",
+ "general_access_default": "Standard",
+ "general_access_expert": "Ekspert",
+ "general_btn_back": "Tilbake",
+ "general_btn_cancel": "Avbryt",
+ "general_btn_continue": "Fortsett",
+ "general_btn_iswitch": "Bytt",
+ "general_btn_next": "Neste",
+ "general_btn_off": "Av",
+ "general_btn_ok": "OK",
+ "general_btn_on": "På",
+ "general_btn_restarthyperion": "Start Hyperion på nytt",
+ "general_btn_save": "Lagre",
+ "general_btn_saveandreload": "Lagre og last inn på nytt",
+ "general_btn_yes": "Ja",
+ "general_col_blue": "blå",
+ "general_col_green": "grønn",
+ "general_col_red": "rød",
+ "general_comp_BLACKBORDER": "Blackbar gjennkjennelse",
+ "general_comp_SMOOTHING": "Utjevning",
+ "general_country_de": "Tyskland",
+ "general_country_es": "Spania",
+ "general_country_fr": "Frankrike",
+ "general_country_it": "Italia",
+ "general_country_nl": "Nederland",
+ "general_country_uk": "Storbritania",
+ "general_country_us": "USA",
+ "general_speech_de": "Tysk",
+ "general_speech_en": "Engelsk",
+ "general_speech_es": "Spansk",
+ "general_speech_it": "Italiensk",
+ "general_webui_title": "Hyperion - Webkonfigurasjon",
+ "main_ledsim_btn_togglelednumber": "Antall LED",
+ "main_ledsim_btn_toggleleds": "Vis LED",
+ "main_ledsim_btn_togglelivevideo": "Direktevideo",
+ "main_ledsim_title": "LED-visualisering",
+ "main_menu_about_token": "Om Hyperion",
+ "main_menu_colors_conf_token": "Bildebehandling",
+ "main_menu_configuration_token": "Konfigureringer",
+ "main_menu_dashboard_token": "Dashbord",
+ "main_menu_effect_conf_token": "Effekter",
+ "main_menu_effectsconfigurator_token": "Effekt konfigurerer",
+ "main_menu_general_conf_token": "Generell",
+ "main_menu_logging_token": "Logg",
+ "main_menu_network_conf_token": "Nettverkstjenester",
+ "main_menu_remotecontrol_token": "Fjern-kontroll",
+ "main_menu_support_token": "Støtte",
+ "main_menu_system_token": "System",
+ "main_menu_update_token": "Oppdater"
+}
\ No newline at end of file
diff --git a/assets/webconfig/i18n/pt-br.json b/assets/webconfig/i18n/pt-br.json
new file mode 100644
index 00000000..53456fa4
--- /dev/null
+++ b/assets/webconfig/i18n/pt-br.json
@@ -0,0 +1,970 @@
+{
+ "InfoDialog_access_text": "Dependendo do nível de configuração, você pode ajustar mais opções ou obter acesso a mais recursos. Recomendado é o nível \"Padrão\".",
+ "InfoDialog_access_title": "Nível de configurações",
+ "InfoDialog_changePassword_success": "Senha salva com sucesso!",
+ "InfoDialog_changePassword_title": "Alterar a senha",
+ "InfoDialog_iswitch_text": "Se você executar o Hyperion mais de uma vez em sua rede local, poderá alternar entre as configurações da web. Selecione a instância do Hyperion abaixo e mude!",
+ "InfoDialog_iswitch_title": "Switcher Hyperion",
+ "InfoDialog_lang_text": "Se não gostar do resultado da detecção automática de idioma, você pode sobrescrevê-lo aqui.",
+ "InfoDialog_lang_title": "Configuração de idioma",
+ "InfoDialog_nowrite_foottext": "O WebUI será desbloqueado automaticamente depois que você resolver o problema!",
+ "InfoDialog_nowrite_text": "O Hyperion não pode gravar em seu arquivo de configuração carregado atualmente. Repare as permissões do arquivo para continuar.",
+ "InfoDialog_nowrite_title": "erro de permissão de gravação!",
+ "about_3rd_party_licenses": "Licenças de terceiros",
+ "about_3rd_party_licenses_error": "Tivemos problemas para coletar informações de licenças de terceiros na web. Por favor, siga este link para o recurso GitHub.",
+ "about_build": "Build",
+ "about_builddate": "Data da Build",
+ "about_contribute": "Desenvolva ainda mais o Hyperion conosco!",
+ "about_credits": "Créditos a todos esses desenvolvedores!",
+ "about_resources": "$1 bibliotecas",
+ "about_translations": "Traduções",
+ "about_version": "Versão",
+ "conf_colors_blackborder_intro": "Ignore as barras pretas onde quer que estejam. Cada modo usa outro algoritmo de detecção que é ajustado para situações especiais. Aumente o limite se não funcionar para você.",
+ "conf_colors_color_intro": "Crie um ou mais perfis de calibração, ajuste cada cor, brilho, linearização e muito mais.",
+ "conf_colors_smoothing_intro": "A suavização nivela as alterações de cor / brilho para reduzir a distração irritante.",
+ "conf_effect_bgeff_intro": "Defina a cor/efeito de fundo, que é exibida quando o Hyperion esta \"ocioso\". Sempre começa com o canal prioritário 255.",
+ "conf_effect_fgeff_intro": "Defina um efeito ou cor de inicialização, que será mostrado durante a inicialização do Hyperion pelo tempo determinado.",
+ "conf_effect_path_intro": "Carregue efeitos a partir dos caminhos definidos. Adicionalmente, você pode desabilitar efeitos individuais pelo nome, para escondê-los da lista de efeitos.",
+ "conf_general_createInst_btn": "Criar Instância",
+ "conf_general_impexp_expbtn": "Exportar",
+ "conf_general_impexp_impbtn": "Importar",
+ "conf_general_impexp_l1": "Importe uma configuração selecionando abaixo um arquivo de configuração e clicando em \"Importar\".",
+ "conf_general_impexp_l2": "Exporte um arquivo de configuração clicando em \"Exportar\". Seu navegador irá iniciar um download.",
+ "conf_general_impexp_title": "Configurações de Importação/Exportação",
+ "conf_general_inst_actionhead": "Ação",
+ "conf_general_inst_delreq_h": "Excluir instância de hardware de LED",
+ "conf_general_inst_delreq_t": "Tem certeza de que deseja excluir a instância \"$1\"? Todas as configurações serão excluídas também.",
+ "conf_general_inst_desc": "Use múltiplos dispositivos de LED ao mesmo tempo. Cada instância é executada independente uma da outra, o que permite diferentes layouts de LED e configurações de calibração. As instâncias em execução estão disponíveis na barra de ícones superior",
+ "conf_general_inst_name_title": "Nome da nova instância",
+ "conf_general_inst_namehead": "Nome da instância",
+ "conf_general_inst_renreq_t": "Insira um novo nome para sua instância no campo abaixo.",
+ "conf_general_inst_title": "Gerenciamento de instância de hardware LED",
+ "conf_general_intro": "Configurações básicas do Hyperion e da WebUI que não se encaixam em outra categoria.",
+ "conf_general_label_title": "Configurações gerais",
+ "conf_grabber_fg_intro": "A captura da plataforma é a captura do seu sistema local como fonte de entrada em que o Hyperion está instalado.",
+ "conf_grabber_v4l_intro": "Captura USB é um dispositivo (de captura) conectado via USB que é usado para inserir imagens de origem para processamento.",
+ "conf_helptable_expl": "Explicação",
+ "conf_helptable_option": "Opção",
+ "conf_leds_config_error": "Erro na configuração do layout LED / LED",
+ "conf_leds_config_warning": "Verifique sua configuração de layout de LED / LED",
+ "conf_leds_contr_label_contrtype": "Tipo de controlador:",
+ "conf_leds_device_info_log": "Caso seus LEDs não funcionem, verifique aqui se há erros:",
+ "conf_leds_device_intro": "Hyperion suporta vários controladores para transmitir sinal para o seu dispositivo. Selecione o contolador de LED da lista e configure. Nós escolhemos as melhores configurações padrão para cada dispositivo.",
+ "conf_leds_error_hwled_gt_layout": "A contagem de LEDs do hardware ($1) é maior do que os LEDs configurados via layout ($2), $3 {{plural:$1|LED|LEDs}} permanecerá preto se você continuar.",
+ "conf_leds_error_hwled_lt_layout": "A contagem de LEDs do hardware ($1) é menor do que os LEDs configurados por layout ($2). O número de LEDs configurados no layout não deve exceder os LEDs disponíveis",
+ "conf_leds_layout_advanced": "Configurações Avançadas",
+ "conf_leds_layout_blacklist_num_title": "Número de LEDs",
+ "conf_leds_layout_blacklist_rule_title": "Regra da lista negra",
+ "conf_leds_layout_blacklist_rules_title": "Regras da lista negra",
+ "conf_leds_layout_blacklist_start_title": "LED de início",
+ "conf_leds_layout_blacklistleds_title": "LEDs da lista negra",
+ "conf_leds_layout_btn_checklist": "Mostrar checklist",
+ "conf_leds_layout_button_savelay": "Salvar layout",
+ "conf_leds_layout_button_updsim": "Atualizar pre-visualização",
+ "conf_leds_layout_checkp1": "O led preto é sempre o seu primeiro led, o primeiro led é o ponto onde o fio de sinal(dados) começa.",
+ "conf_leds_layout_checkp2": "O layout é sempre em relação a frente da sua TV, nunca da traseira.",
+ "conf_leds_layout_checkp3": "Certifique-se que a direção está certa. Os LEDs cinzas representam os LEDs 2 e 3 para visualizar a direção dos dados.",
+ "conf_leds_layout_checkp4": "Espaço sem LED: Para criar um espaço, primeiro defina a quantidade de leds que estão no Topo / Base / Esquerda / Direita e depois defina o comprimento do espaço para remover a quantidade desejada de leds. Modifique a posição da lacuna até que corresponda.\n",
+ "conf_leds_layout_cl_bottom": "Base",
+ "conf_leds_layout_cl_bottomleft": "Base Esquerda (Canto)",
+ "conf_leds_layout_cl_bottomright": "Base Direita (Canto)",
+ "conf_leds_layout_cl_cornergap": "Espaçamento Canto",
+ "conf_leds_layout_cl_edgegap": "Espaçamento Borda",
+ "conf_leds_layout_cl_gaglength": "Comprimento da lacuna",
+ "conf_leds_layout_cl_gappos": "Posição da lacuna",
+ "conf_leds_layout_cl_hleddepth": "Profundidade de LED horizontal",
+ "conf_leds_layout_cl_inppos": "Posição entrada do sinal",
+ "conf_leds_layout_cl_left": "Esquerda",
+ "conf_leds_layout_cl_leftbottom": "Esquerda 50% - 100% Base",
+ "conf_leds_layout_cl_leftmiddle": "Esquerda 25% - 75% Meio",
+ "conf_leds_layout_cl_lefttop": "Esquerda 0% - 50% Topo",
+ "conf_leds_layout_cl_overlap": "Sobreposição",
+ "conf_leds_layout_cl_reversdir": "Inverter direção",
+ "conf_leds_layout_cl_right": "Direita",
+ "conf_leds_layout_cl_rightbottom": "Direita 50% - 100% Base",
+ "conf_leds_layout_cl_rightmiddle": "Direita 25% - 75% Meio",
+ "conf_leds_layout_cl_righttop": "Direita 0% - 50% Topo",
+ "conf_leds_layout_cl_top": "Topo",
+ "conf_leds_layout_cl_topleft": "Topo Esquerdo (Canto)",
+ "conf_leds_layout_cl_topright": "Topo Direito (Canto)",
+ "conf_leds_layout_cl_vleddepth": "Profundidade de LED vertical",
+ "conf_leds_layout_frame": "Layout Clássico (MOLDURA LED)",
+ "conf_leds_layout_generatedconf": "Configuração de LED gerado / atual",
+ "conf_leds_layout_intro": "Você tambem precisa do layout dos leds, que refere a posição dos leds. O layout clássico que é usado geralmente é a moldura de tv, mas também suportamos a criação de matriz de leds (paredes de leds). A vista desse layout é sempre da FRENTE da tv.",
+ "conf_leds_layout_ma_cabling": "Cabeamento",
+ "conf_leds_layout_ma_horiz": "Horizontal",
+ "conf_leds_layout_ma_optbottomleft": "Base esquerda",
+ "conf_leds_layout_ma_optbottomright": "Base direita",
+ "conf_leds_layout_ma_opthoriz": "Horizontal",
+ "conf_leds_layout_ma_optparallel": "Paralelo",
+ "conf_leds_layout_ma_optsnake": "Cobra",
+ "conf_leds_layout_ma_opttopleft": "Topo Esquerdo",
+ "conf_leds_layout_ma_opttopright": "Topo Direito",
+ "conf_leds_layout_ma_optvert": "Vertical",
+ "conf_leds_layout_ma_order": "Ordem",
+ "conf_leds_layout_ma_position": "Entrada",
+ "conf_leds_layout_ma_vert": "Vertical",
+ "conf_leds_layout_matrix": "Layout matriz (PAREDE DE LED)",
+ "conf_leds_layout_pbl": "Ponto Base Esquerda",
+ "conf_leds_layout_pbr": "Ponto Base Direita",
+ "conf_leds_layout_peview": "Prévia do layout do LED",
+ "conf_leds_layout_preview_l1": "Esse é o seu primeiro LED (entrada/início)",
+ "conf_leds_layout_preview_l2": "Isso mostra a direção do efeito (segundo/terceiro led)",
+ "conf_leds_layout_preview_ledpower": "Máx. consumo de energia: $1 A",
+ "conf_leds_layout_preview_originCL": "Criado de: Layout Clássico (PAREDE DE LED)",
+ "conf_leds_layout_preview_originMA": "Criado de: Layout Matriz (PAREDE DE LED)",
+ "conf_leds_layout_preview_originTEXT": "Criado a partir de: Textfield",
+ "conf_leds_layout_preview_totalleds": "Total de LEDs: $1",
+ "conf_leds_layout_ptl": "Ponto Topo Esquerdo",
+ "conf_leds_layout_ptlh": "Horizontal",
+ "conf_leds_layout_ptln": "Pontos Triplos",
+ "conf_leds_layout_ptlv": "Vertical",
+ "conf_leds_layout_ptr": "Ponto Topo Direito",
+ "conf_leds_layout_textf1": "Este campo de texto mostra por padrão seu layout carregado atual e será sobrescrito se você gerar um novo com as opções acima. Opcional, você pode realizar outras edições.",
+ "conf_leds_nav_label_ledcontroller": "Controlador LED",
+ "conf_leds_nav_label_ledlayout": "Posicionamento LED",
+ "conf_leds_note_layout_overwrite": "Nota: Sobrescrever cria um layout padrão para {{plural:$1| $1 LED | todos os $1 LEDs}} fornecidos pela contagem de LED do hardware",
+ "conf_leds_optgroup_RPiGPIO": "RPi CPIO",
+ "conf_leds_optgroup_RPiPWM": "RPi PWM",
+ "conf_leds_optgroup_RPiSPI": "RPi SPI",
+ "conf_leds_optgroup_network": "Rede",
+ "conf_leds_optgroup_other": "Outro",
+ "conf_leds_optgroup_usb": "USB/Serial",
+ "conf_logging_btn_autoscroll": "Rolagem automática",
+ "conf_logging_btn_pbupload": "Faça upload de um relatório para solicitações de suporte",
+ "conf_logging_contpolicy": "Política de Privacidade do Relatório",
+ "conf_logging_label_intro": "Área para verificar as mensagens de log, você verá mais ou menos informações dependendo do nível de log definido.",
+ "conf_logging_lastreports": "Relatórios anteriores",
+ "conf_logging_logoutput": "Saída de log",
+ "conf_logging_nomessage": "Nenhuma mensagem de log disponível.",
+ "conf_logging_report": "Relatório",
+ "conf_logging_uplfailed": "Falha no envio! Por favor, cheque sua conexão com a internet!",
+ "conf_logging_uploading": "Prepare os dados ...",
+ "conf_logging_uplpolicy": "Ao clicar nesse botão você aceita",
+ "conf_logging_yourlink": "Link para o seu relatório",
+ "conf_network_bobl_intro": "Receptor para Boblight",
+ "conf_network_createToken_btn": "Criar Token",
+ "conf_network_fbs_intro": "Receptor Google Flatbuffers. Usado para transmissão rápida de imagens.",
+ "conf_network_forw_intro": "Encaminhe todas as entradas para uma segunda instância do Hyperion que pode ser conduzida com outro controlador de led",
+ "conf_network_json_intro": "O JSON-RPC-Port de todas as instâncias do Hyperion, usado para controle remoto.",
+ "conf_network_net_intro": "Configurações relacionadas à rede que são aplicadas a todos os serviços de rede.",
+ "conf_network_proto_intro": "A porta PROTO de todas as instâncias do Hyperion, usada para fluxos de imagem (HyperionScreenCap, Kodi Addon, Android Hyperion Grabber, ...)",
+ "conf_network_tok_cidhead": "Descrição",
+ "conf_network_tok_comment_title": "Descrição do Token",
+ "conf_network_tok_desc": "Os tokens concedem a outros aplicativos acesso à API do Hyperion, um aplicativo pode solicitar um token onde você precisa aceitá-lo ou você mesmo pode criá-lo abaixo. Esses tokens são necessários apenas quando a \"Autorização de API\" está ativada nas configurações de rede.",
+ "conf_network_tok_diaMsg": "Aqui está seu novo token, que pode ser usado para conceder a um aplicativo acesso à API do Hyperion. Por razões de segurança, você não pode visualizá-lo novamente, então use / anote.",
+ "conf_network_tok_diaTitle": "Novo Token Criado!",
+ "conf_network_tok_grantMsg": "Um aplicativo solicitou um token para obter acesso à API Hyperion. Você quer conceder acesso? Por favor, verifique as informações fornecidas!",
+ "conf_network_tok_grantT": "Token de solicitações de aplicativos",
+ "conf_network_tok_intro": "Aqui você pode criar e excluir tokens para autenticação de API. Os tokens criados serão exibidos apenas uma vez.",
+ "conf_network_tok_lastuse": "Último uso",
+ "conf_network_tok_title": "Gestão de Token",
+ "conf_webconfig_label_intro": "Definições de configuração da Web. Edite com sabedoria.",
+ "dashboard_active_instance": "Instância selecionada",
+ "dashboard_alert_message_confedit": "Sua configuração do Hyperion foi modificada. Para aplicar, reinicie o Hyperion.",
+ "dashboard_alert_message_confedit_t": "Configuração modificada",
+ "dashboard_alert_message_confsave_success": "Sua configuração do Hyperion foi salva com sucesso. Suas mudanças estão ativas.",
+ "dashboard_alert_message_confsave_success_t": "Configuração salva",
+ "dashboard_alert_message_disabled": "Essa instância está atualmente desabilitada! Para usá-la novamente, habilite-a na dashboard.",
+ "dashboard_alert_message_disabled_t": "Instância de hardware LED desabilitada",
+ "dashboard_componentbox_label_comp": "Componente",
+ "dashboard_componentbox_label_status": "Estado",
+ "dashboard_componentbox_label_title": "Estado dos componentes:",
+ "dashboard_infobox_label_currenthyp": "Sua versão do Hyperion:",
+ "dashboard_infobox_label_disableh": "Desabilitar instância: $1",
+ "dashboard_infobox_label_enableh": "Habilitar instância: $1",
+ "dashboard_infobox_label_instance": "Instância:",
+ "dashboard_infobox_label_latesthyp": "Última versão do Hyperion:",
+ "dashboard_infobox_label_platform": "Plataforma:",
+ "dashboard_infobox_label_ports": "Portas (flat/proto):",
+ "dashboard_infobox_label_smartacc": "Acesso inteligente",
+ "dashboard_infobox_label_statush": "Estado do Hyperion:",
+ "dashboard_infobox_label_title": "Informação",
+ "dashboard_infobox_label_watchedversionbranch": "Branch da versão assistida:",
+ "dashboard_infobox_message_updatesuccess": "Você está rodando a versão mais recente do Hyperion.",
+ "dashboard_infobox_message_updatewarning": "Uma nova versão do Hyperion está disponível! ($1)",
+ "dashboard_label_intro": "O dashboard dá uma visão geral sobre o estado do Hyperion e exibe as notícias mais recentes do blog do Hyperion.",
+ "dashboard_message_default_password": "A senha padrão para o WebUi está definida. É altamente recomendável mudar isso.",
+ "dashboard_message_default_password_t": "A senha padrão do WebUI está definida",
+ "dashboard_message_do_not_show_again": "Não mostrar esta mensagem novamente",
+ "dashboard_message_global_setting": "As configurações nesta página não dependem de uma instância específica. As alterações serão armazenadas globalmente para todas as instâncias.",
+ "dashboard_message_global_setting_t": "Configuração independente de instância",
+ "dashboard_newsbox_label_title": "Blog do Hyperion",
+ "dashboard_newsbox_noconn": "Não é possível conectar-se ao servidor do Hyperion para pegar os últimos posts. Sua conexão com a internet está funcionando?",
+ "dashboard_newsbox_readmore": "Leia mais",
+ "dashboard_newsbox_visitblog": "Visite o Blog do Hyperion",
+ "edt_append_degree": "°",
+ "edt_append_hz": "hz",
+ "edt_append_leds": "LEDS",
+ "edt_append_ms": "ms",
+ "edt_append_ns": "ns",
+ "edt_append_percent": "%",
+ "edt_append_percent_h": "% hori",
+ "edt_append_percent_v": "% vert",
+ "edt_append_pixel": "Pixel",
+ "edt_append_s": "s",
+ "edt_append_sdegree": "s/grau",
+ "edt_conf_bb_blurRemoveCnt_expl": "Número de pixels que são removidos da borda detectada para eliminar o desfoque.",
+ "edt_conf_bb_blurRemoveCnt_title": "Desfocar Pixel",
+ "edt_conf_bb_borderFrameCnt_expl": "Número de quadros antes que uma borda detectada consistente seja definida.",
+ "edt_conf_bb_borderFrameCnt_title": "Molduras de borda",
+ "edt_conf_bb_heading_title": "Detector Barras Pretas",
+ "edt_conf_bb_maxInconsistentCnt_expl": "Número de quadros inconsistentes que são ignorados antes que uma nova borda tenha a chance de comprovar a consistência.",
+ "edt_conf_bb_maxInconsistentCnt_title": "Frames inconsistentes",
+ "edt_conf_bb_mode_expl": "Algoritmo para processamento. (veja Wiki)",
+ "edt_conf_bb_mode_title": "Modo",
+ "edt_conf_bb_threshold_expl": "Se a detecção não funcionar, aumente o limite para ajustar o preto 'acinzentado'",
+ "edt_conf_bb_threshold_title": "Limite",
+ "edt_conf_bb_unknownFrameCnt_expl": "Número de quadros sem nenhuma detecção antes de a borda ser definida como 0.",
+ "edt_conf_bb_unknownFrameCnt_title": "Quadros desconhecidos",
+ "edt_conf_bge_heading_title": "Efeito / cor de fundo",
+ "edt_conf_bobls_heading_title": "Servidor Boblight",
+ "edt_conf_color_backlightColored_expl": "Adicione um pouco de cor à sua luz de fundo.",
+ "edt_conf_color_backlightColored_title": "Luz de fundo colorida",
+ "edt_conf_color_backlightThreshold_expl": "A quantidade mínima de brilho (luz de fundo). Desativado durante efeitos, cores e no status \"Desligado\"",
+ "edt_conf_color_backlightThreshold_title": "Limite de luz de fundo",
+ "edt_conf_color_black_expl": "O valor de preto calibrado.",
+ "edt_conf_color_black_title": "Preto",
+ "edt_conf_color_blue_expl": "O valor de azul calibrado.",
+ "edt_conf_color_blue_title": "Azul",
+ "edt_conf_color_brightnessComp_expl": "Compensa as diferenças de brilho entre o azul, verde vermelho, amarelo magenta ciano e branco. 100 significa compensação total, 0 sem compensação",
+ "edt_conf_color_brightnessComp_title": "Compensação de brilho",
+ "edt_conf_color_brightness_expl": "definir o brilho geral dos LEDs",
+ "edt_conf_color_brightness_title": "Brilho",
+ "edt_conf_color_channelAdjustment_header_expl": "Crie perfis de cores que podem ser atribuídos a um componente específico. Ajuste a cor, gama, brilho, compensação e muito mais.",
+ "edt_conf_color_channelAdjustment_header_itemtitle": "Perfil",
+ "edt_conf_color_channelAdjustment_header_title": "Ajustes de canal de cor",
+ "edt_conf_color_cyan_expl": "O valor de ciano calibrado.",
+ "edt_conf_color_cyan_title": "Ciano",
+ "edt_conf_color_gammaBlue_expl": "A gama de azul. 1.0 é neutro. Acima de 1.0 ele reduz o azul, abaixo de 1.0 ele adiciona o azul.",
+ "edt_conf_color_gammaBlue_title": "Gama Azul",
+ "edt_conf_color_gammaGreen_expl": "A gama de verde. 1.0 é neutro. Acima de 1.0 ele reduz o verde, abaixo de 1.0 ele adiciona verde.",
+ "edt_conf_color_gammaGreen_title": "Gama Verde",
+ "edt_conf_color_gammaRed_expl": "A gama de vermelho. 1.0 é neutro. Acima de 1,0, reduz o vermelho, abaixo de 1,0, ele adiciona vermelho.",
+ "edt_conf_color_gammaRed_title": "Gama Vermelho",
+ "edt_conf_color_green_expl": "O valor verde calibrado.",
+ "edt_conf_color_green_title": "Verde",
+ "edt_conf_color_heading_title": "Calibração de Cor",
+ "edt_conf_color_id_expl": "Nome dado pelo usuário",
+ "edt_conf_color_id_title": "ID",
+ "edt_conf_color_imageToLedMappingType_expl": "Substitui a atribuição da área de led do seu layout de led se não for \"multicolor\"",
+ "edt_conf_color_imageToLedMappingType_title": "Atribuição de área de led",
+ "edt_conf_color_leds_expl": "Atribua este ajuste a todos os LEDs (*) ou apenas a alguns (0-24).",
+ "edt_conf_color_leds_title": "Índice de LED",
+ "edt_conf_color_magenta_expl": "O valor de magenta calibrado.",
+ "edt_conf_color_magenta_title": "Magenta",
+ "edt_conf_color_red_expl": "O valor de vermelho calibrado.",
+ "edt_conf_color_red_title": "Vermelho",
+ "edt_conf_color_white_expl": "O valor de branco calibrado.",
+ "edt_conf_color_white_title": "Branco",
+ "edt_conf_color_yellow_expl": "O valor de amarelo calibrado.",
+ "edt_conf_color_yellow_title": "Amarelo",
+ "edt_conf_effp_disable_expl": "Adicione nomes de efeitos aqui para desabilitá-los / ocultá-los de todas as listas de efeitos.",
+ "edt_conf_effp_disable_itemtitle": "Efeito",
+ "edt_conf_effp_disable_title": "Efeitos Desativados",
+ "edt_conf_effp_heading_title": "Caminhos do efeito",
+ "edt_conf_effp_paths_expl": "Você pode definir mais pastas que contêm efeitos. O configurador de efeitos sempre salvará dentro da primeira pasta.",
+ "edt_conf_effp_paths_itemtitle": "Caminho",
+ "edt_conf_effp_paths_title": "Caminho (s) do efeito",
+ "edt_conf_enum_NO_CHANGE": "Automático",
+ "edt_conf_enum_NTSC": "NTSC",
+ "edt_conf_enum_PAL": "PAL",
+ "edt_conf_enum_SECAM": "SECAM",
+ "edt_conf_enum_automatic": "Automatico",
+ "edt_conf_enum_bbclassic": "Clássico",
+ "edt_conf_enum_bbdefault": "Padrão",
+ "edt_conf_enum_bbletterbox": "Letterbox",
+ "edt_conf_enum_bbosd": "OSD",
+ "edt_conf_enum_bgr": "BGR",
+ "edt_conf_enum_bottom_up": "Debaixo para cima",
+ "edt_conf_enum_brg": "BRG",
+ "edt_conf_enum_color": "Cor",
+ "edt_conf_enum_custom": "Personalizado",
+ "edt_conf_enum_decay": "Decaimento",
+ "edt_conf_enum_dl_error": "Erro",
+ "edt_conf_enum_dl_informational": "Informativo",
+ "edt_conf_enum_dl_nodebug": "Sem saída de depuração",
+ "edt_conf_enum_dl_statechange": "Mudança de estado",
+ "edt_conf_enum_dl_verbose": "Modo Texto",
+ "edt_conf_enum_dl_verbose1": "Modo de texto 1",
+ "edt_conf_enum_dl_verbose2": "Modo de texto 2",
+ "edt_conf_enum_dl_verbose3": "Moto de texto 3",
+ "edt_conf_enum_effect": "Efeito",
+ "edt_conf_enum_gbr": "GBR",
+ "edt_conf_enum_grb": "GRB",
+ "edt_conf_enum_hsv": "HSV",
+ "edt_conf_enum_left_right": "Da esquerda para a direita",
+ "edt_conf_enum_linear": "Linear",
+ "edt_conf_enum_logdebug": "Debug",
+ "edt_conf_enum_logsilent": "Silêncioso",
+ "edt_conf_enum_logverbose": "Modo Texto",
+ "edt_conf_enum_logwarn": "Aviso",
+ "edt_conf_enum_multicolor_mean": "Multicolorido",
+ "edt_conf_enum_please_select": "Selecione por favor",
+ "edt_conf_enum_rbg": "RBG",
+ "edt_conf_enum_rgb": "RGB",
+ "edt_conf_enum_right_left": "Da direita para a esquerda",
+ "edt_conf_enum_top_down": "De cima para baixo",
+ "edt_conf_enum_transeffect_smooth": "Suavização",
+ "edt_conf_enum_transeffect_sudden": "De repente",
+ "edt_conf_enum_unicolor_mean": "Unicolor",
+ "edt_conf_fbs_heading_title": "Servidor Flatbuffers",
+ "edt_conf_fbs_timeout_expl": "Se nenhum dado for recebido para o período determinado, o componente será desabilitado (soft).",
+ "edt_conf_fbs_timeout_title": "Tempo esgotado",
+ "edt_conf_fg_display_expl": "Selecione qual área de trabalho deve ser capturada (configuração de vários monitores)",
+ "edt_conf_fg_display_title": "Exibição",
+ "edt_conf_fg_frequency_Hz_expl": "Com que rapidez novas fotos são capturadas",
+ "edt_conf_fg_frequency_Hz_title": "Frequência de captura Hz",
+ "edt_conf_fg_heading_title": "Captura de plataforma",
+ "edt_conf_fg_height_expl": "Reduza a imagem a essa altura, pois a imagem bruta precisa de muito tempo de CPU.",
+ "edt_conf_fg_height_title": "Altura",
+ "edt_conf_fg_pixelDecimation_expl": "Reduza o tamanho da imagem (fator) com base no tamanho original. Um fator de 1 significa nenhuma mudança",
+ "edt_conf_fg_pixelDecimation_title": "Decimação de imagem",
+ "edt_conf_fg_type_expl": "Tipo de captura de plataforma, o padrão é 'automático'",
+ "edt_conf_fg_type_title": "Tipo",
+ "edt_conf_fg_width_expl": "Reduza a imagem para essa largura, pois a imagem bruta precisa de muito tempo de CPU.",
+ "edt_conf_fg_width_title": "Largura",
+ "edt_conf_fge_color_expl": "Se o tipo for \"Cor\", defina uma cor de sua escolha aqui.",
+ "edt_conf_fge_color_title": "Cor",
+ "edt_conf_fge_duration_ms_expl": "Duração do efeito / cor durante a inicialização do Hyperion.",
+ "edt_conf_fge_duration_ms_title": "Duração",
+ "edt_conf_fge_effect_expl": "Se o tipo for \"Efeito\", selecione um efeito de sua escolha (incluindo efeitos criados pelo você).",
+ "edt_conf_fge_effect_title": "Efeito",
+ "edt_conf_fge_heading_title": "Efeito / cor de Boot",
+ "edt_conf_fge_type_expl": "Escolha entre uma cor ou efeito.",
+ "edt_conf_fge_type_title": "Tipo",
+ "edt_conf_fw_flat_expl": "Um alvo flatbuffer por linha. Contém IP: PORTA (Exemplo: 127.0.0.1:19401)",
+ "edt_conf_fw_flat_itemtitle": "alvo flatbuffer",
+ "edt_conf_fw_flat_title": "Lista de alvos flatbuffer",
+ "edt_conf_fw_heading_title": "Despachante",
+ "edt_conf_fw_json_expl": "Um alvo json por linha. Contém IP: PORT (Exemplo: 127.0.0.1:19446)",
+ "edt_conf_fw_json_itemtitle": "Alvo Json",
+ "edt_conf_fw_json_title": "Lista de alvos json",
+ "edt_conf_gen_configVersion_title": "Versão de Configuração",
+ "edt_conf_gen_heading_title": "Configurações Gerais",
+ "edt_conf_gen_name_expl": "Um nome definido pelo usuário que é usado para detectar o Hyperion. (Útil com mais de uma instância do Hyperion)",
+ "edt_conf_gen_name_title": "Nome da configuração",
+ "edt_conf_gen_showOptHelp_expl": "Mostre todas as explicações disponíveis em cada seção. Altamente recomendado para iniciantes!",
+ "edt_conf_gen_showOptHelp_title": "Mostrar explicações",
+ "edt_conf_gen_watchedVersionBranch_expl": "Seleciona qual versão do Branch deve ser usada para pesquisar novas versões do Hyperion.",
+ "edt_conf_gen_watchedVersionBranch_title": "Branch da versão assistida",
+ "edt_conf_general_enable_expl": "Se marcado, o componente é habilitado.",
+ "edt_conf_general_enable_title": "Ativar",
+ "edt_conf_general_port_expl": "A porta está em uso.",
+ "edt_conf_general_port_title": "Porta",
+ "edt_conf_general_priority_expl": "A prioridade deste componente",
+ "edt_conf_general_priority_title": "Canal prioritário",
+ "edt_conf_instC_systemEnable_expl": "Ativa a captura da plataforma para esta instância de hardware",
+ "edt_conf_instC_systemEnable_title": "Habilitar captura de plataforma",
+ "edt_conf_instC_v4lEnable_expl": "Ativa a captura USB para esta instância de hardware",
+ "edt_conf_instC_v4lEnable_title": "Ativa captura USB",
+ "edt_conf_instCapture_heading_title": "Captura de Instância",
+ "edt_conf_js_heading_title": "Servidor JSON",
+ "edt_conf_log_heading_title": "Registro",
+ "edt_conf_log_level_expl": "Dependendo do nível de log, você verá menos ou mais mensagens em seu log.",
+ "edt_conf_log_level_title": "Log-Level",
+ "edt_conf_net_apiAuth_expl": "Force todos os aplicativos que usam a API Hyperion para se autenticar no Hyperion (Exceção, consulte \"Autenticação API local\"). Maior segurança, pois você controla o acesso e o revoga a qualquer momento.",
+ "edt_conf_net_apiAuth_title": "Autenticação API",
+ "edt_conf_net_heading_title": "Rede",
+ "edt_conf_net_internetAccessAPI_expl": "Permita o acesso ao Hyperion API / Interface Web da Internet, desative para maior segurança.",
+ "edt_conf_net_internetAccessAPI_title": "Acesso à Internet API",
+ "edt_conf_net_ipWhitelist_expl": "Você pode colocar endereços IP na lista de permissões, em vez de permitir que todas as conexões da Internet se conectem à API / interface da Web do Hyperion.",
+ "edt_conf_net_ipWhitelist_title": "IPs na lista branca",
+ "edt_conf_net_ip_itemtitle": "IP",
+ "edt_conf_net_localAdminAuth_expl": "Quando ativado, o acesso de administração de sua rede local precisa de uma senha.",
+ "edt_conf_net_localAdminAuth_title": "Autenticação de API de administrador local",
+ "edt_conf_net_localApiAuth_expl": "Quando habilitado, as conexões de sua rede doméstica precisam se autenticar no Hyperion com um token.",
+ "edt_conf_net_localApiAuth_title": "Autenticação de API local",
+ "edt_conf_net_restirctedInternetAccessAPI_expl": "Você pode restringir o acesso à API através da Internet a determinados IPs.",
+ "edt_conf_net_restirctedInternetAccessAPI_title": "Restringir aos IPs",
+ "edt_conf_pbs_heading_title": "Servidor de buffers de protocolo",
+ "edt_conf_pbs_timeout_expl": "Se nenhum dado for recebido para o período determinado, o componente será desabilitado (soft).",
+ "edt_conf_pbs_timeout_title": "Tempo Esgotado",
+ "edt_conf_smooth_continuousOutput_expl": "Atualize os LEDs mesmo que não haja alteração na imagem.",
+ "edt_conf_smooth_continuousOutput_title": "Saída contínua",
+ "edt_conf_smooth_decay_expl": "A velocidade da decadência. 1 é linear, valores maiores têm efeito mais forte.",
+ "edt_conf_smooth_decay_title": "Poder de decomposição",
+ "edt_conf_smooth_dithering_expl": "Melhore a precisão das cores em altas velocidades de saída, alternando entre cores adjacentes.",
+ "edt_conf_smooth_dithering_title": "Tremulação",
+ "edt_conf_smooth_heading_title": "Suavização",
+ "edt_conf_smooth_interpolationRate_expl": "Velocidade do cálculo de quadros intermediários suavizados.",
+ "edt_conf_smooth_interpolationRate_title": "Taxa de interpolação",
+ "edt_conf_smooth_outputRate_expl": "A velocidade de saída para o controlador led.",
+ "edt_conf_smooth_outputRate_title": "Taxa de saída",
+ "edt_conf_smooth_time_ms_expl": "Por quanto tempo a suavização deve reunir imagens?",
+ "edt_conf_smooth_time_ms_title": "Tempo",
+ "edt_conf_smooth_type_expl": "Tipo de Suavização.",
+ "edt_conf_smooth_type_title": "Tipo",
+ "edt_conf_smooth_updateDelay_expl": "Atrase a saída caso a luz ambiente seja mais rápida do que a TV.",
+ "edt_conf_smooth_updateDelay_title": "Atraso de atualização",
+ "edt_conf_smooth_updateFrequency_expl": "A velocidade de saída para o controlador led.",
+ "edt_conf_smooth_updateFrequency_title": "Frequência de atualização",
+ "edt_conf_v4l2_blueSignalThreshold_expl": "Escurece os valores de azul baixos (reconhecidos como pretos)",
+ "edt_conf_v4l2_blueSignalThreshold_title": "Limite do sinal azul",
+ "edt_conf_v4l2_cecDetection_expl": "Se ativada, a captura USB será temporariamente desativada quando o evento de espera CEC for recebido do barramento HDMI.",
+ "edt_conf_v4l2_cecDetection_title": "Detecção CEC",
+ "edt_conf_v4l2_cropBottom_expl": "Contagem de pixels na parte inferior que são removidos da imagem.",
+ "edt_conf_v4l2_cropBottom_title": "Cortar base",
+ "edt_conf_v4l2_cropLeft_expl": "Contagem de pixels no lado esquerdo que são removidos da imagem.",
+ "edt_conf_v4l2_cropLeft_title": "Cortar à esquerda",
+ "edt_conf_v4l2_cropRight_expl": "Contagem de pixels no lado direito que são removidos da imagem.",
+ "edt_conf_v4l2_cropRight_title": "Cortar à direita",
+ "edt_conf_v4l2_cropTop_expl": "Contagem de pixels na parte superior que são removidos da imagem.",
+ "edt_conf_v4l2_cropTop_title": "Cortar topo",
+ "edt_conf_v4l2_device_expl": "O caminho para a interface de captura USB. Defina como 'Automático' para detecção automática. Exemplo: '/ dev / video0'",
+ "edt_conf_v4l2_device_title": "Dispositivo",
+ "edt_conf_v4l2_framerate_expl": "Os quadros por segundo suportados do dispositivo ativo",
+ "edt_conf_v4l2_framerate_title": "Quadros por segundo",
+ "edt_conf_v4l2_greenSignalThreshold_expl": "Escurece valores verdes baixos (reconhecidos como pretos)",
+ "edt_conf_v4l2_greenSignalThreshold_title": "Limite do sinal verde",
+ "edt_conf_v4l2_heading_title": "Captura USB",
+ "edt_conf_v4l2_input_expl": "Selecione a entrada de vídeo do seu dispositivo. 'Automático' mantém o valor escolhido pela interface v4l2.",
+ "edt_conf_v4l2_input_title": "Entrada",
+ "edt_conf_v4l2_redSignalThreshold_expl": "Escurece valores baixos de vermelho (reconhecido como preto)",
+ "edt_conf_v4l2_redSignalThreshold_title": "Limite de sinal vermelho",
+ "edt_conf_v4l2_resolution_expl": "Uma lista de resoluções suportadas do dispositivo ativo",
+ "edt_conf_v4l2_resolution_title": "Resolução do dispositivo",
+ "edt_conf_v4l2_sDHOffsetMax_expl": "Área de detecção de sinal horizontal máxima (0.0-1.0)",
+ "edt_conf_v4l2_sDHOffsetMax_title": "HMax de detecção de sinal",
+ "edt_conf_v4l2_sDHOffsetMin_expl": "Área de detecção de sinal horizontal mínima (0.0-1.0)",
+ "edt_conf_v4l2_sDHOffsetMin_title": "HMin de detecção de sinal",
+ "edt_conf_v4l2_sDVOffsetMax_expl": "Signal detection area vertical maximum (0.0-1.0)",
+ "edt_conf_v4l2_sDVOffsetMax_title": "Detecção de Sinal VMax",
+ "edt_conf_v4l2_sDVOffsetMin_expl": "Mínimo vertical da área de detecção de sinal (0.0-1.0)",
+ "edt_conf_v4l2_sDVOffsetMin_title": "VMin de detecção de sinal",
+ "edt_conf_v4l2_signalDetection_expl": "Se ativada, a captura de USB será temporariamente desativada quando nenhum sinal for encontrado. Isso acontecerá quando a imagem cair abaixo do valor limite por um período de 4 segundos.",
+ "edt_conf_v4l2_signalDetection_title": "Detecção de sinal",
+ "edt_conf_v4l2_sizeDecimation_expl": "O fator de dizimação do tamanho. 1 significa sem dizimação (manter o tamanho original)",
+ "edt_conf_v4l2_sizeDecimation_title": "Decimação de tamanho",
+ "edt_conf_v4l2_standard_expl": "Selecione o padrão de vídeo para sua região. 'Automático' mantém o valor escolhido pela interface v4l2.",
+ "edt_conf_v4l2_standard_title": "Padrão de vídeo",
+ "edt_conf_webc_crtPath_expl": "Caminho para o arquivo de certificação (o formato deve ser PEM)",
+ "edt_conf_webc_crtPath_title": "Caminho do certificado",
+ "edt_conf_webc_docroot_expl": "Caminho raiz da interface da web local (apenas para desenvolvedor webui)",
+ "edt_conf_webc_docroot_title": "Raiz do Documento",
+ "edt_conf_webc_heading_title": "Configuração da Web",
+ "edt_conf_webc_keyPassPhrase_expl": "Opcional: a chave pode ser protegida com uma senha",
+ "edt_conf_webc_keyPassPhrase_title": "Senha chave",
+ "edt_conf_webc_keyPath_expl": "Caminho para o arquivo de chave (formato PEM, criptografado com RSA)",
+ "edt_conf_webc_keyPath_title": "Caminho da chave privada",
+ "edt_conf_webc_sslport_expl": "Porta do HTTPS-Webservidor",
+ "edt_conf_webc_sslport_title": "Porta HTTPS",
+ "edt_dev_auth_key_title": "Token de autenticação",
+ "edt_dev_auth_key_title_info": "Token de autenticação necessário para acessar o dispositivo",
+ "edt_dev_enum_sub_min_cool_adjust": "Subtrair branco frio",
+ "edt_dev_enum_sub_min_warm_adjust": "Subtrair o branco quente",
+ "edt_dev_enum_subtract_minimum": "Subtrair mínimo",
+ "edt_dev_enum_white_off": "Branco apagado",
+ "edt_dev_general_colorOrder_title": "Ordem de bytes RGB",
+ "edt_dev_general_colorOrder_title_info": "A ordem de cores do dispositivo",
+ "edt_dev_general_hardwareLedCount_title": "Contagem de LED de hardware",
+ "edt_dev_general_hardwareLedCount_title_info": "O número de LEDs físicos disponíveis para o dispositivo fornecido",
+ "edt_dev_general_heading_title": "Configurações Gerais",
+ "edt_dev_general_name_title": "Nome da configuração",
+ "edt_dev_general_rewriteTime_title": "Tempo de atualização",
+ "edt_dev_spec_FCledToOn_title": "LED Fadecandy ligado",
+ "edt_dev_spec_FCmanualControl_title": "Controle manual do LED fadecandy",
+ "edt_dev_spec_FCsetConfig_title": "Definir configuração de fadecandy",
+ "edt_dev_spec_LBap102Mode_title": "Modo LightBerry APA102",
+ "edt_dev_spec_PBFiFo_title": "Pi-Blaster FiFo",
+ "edt_dev_spec_baudrate_title": "Taxa de transmissão",
+ "edt_dev_spec_blackLightsTimeout_title": "Tempo limite de detecção de sinal em preto",
+ "edt_dev_spec_brightnessFactor_title": "Fator de brilho",
+ "edt_dev_spec_brightnessMax_title": "Brilho máximo",
+ "edt_dev_spec_brightnessMin_title": "Brilho mínimo",
+ "edt_dev_spec_brightnessOverwrite_title": "Sobrescrever brilho",
+ "edt_dev_spec_brightnessThreshold_title": "Signal detection brightness minimum",
+ "edt_dev_spec_brightness_title": "Brilho",
+ "edt_dev_spec_chanperfixture_title": "Canais por luminária",
+ "edt_dev_spec_cid_title": "CID",
+ "edt_dev_spec_clientKey_title": "Chavecliente:",
+ "edt_dev_spec_colorComponent_title": "Componente de cor",
+ "edt_dev_spec_debugLevel_title": "Nível de Depuração",
+ "edt_dev_spec_debugStreamer_title": "Streamer Debug",
+ "edt_dev_spec_delayAfterConnect_title": "Atrasar após conectar",
+ "edt_dev_spec_devices_discovered_none": "Nenhum dispositivo foi descoberto",
+ "edt_dev_spec_devices_discovered_title": "Dispositivos descobertos",
+ "edt_dev_spec_devices_discovered_title_info": "Selecione o seu dispositivo LED descoberto",
+ "edt_dev_spec_devices_discovered_title_info_custom": "Selecione o seu dispositivo LED descoberto ou configure um personalizado",
+ "edt_dev_spec_devices_discovery_inprogress": "Descoberta em andamento",
+ "edt_dev_spec_dithering_title": "Tremulação",
+ "edt_dev_spec_dmaNumber_title": "Canal DMA",
+ "edt_dev_spec_gamma_title": "Gama",
+ "edt_dev_spec_globalBrightnessControlMaxLevel_title": "Nível máximo atual",
+ "edt_dev_spec_globalBrightnessControlThreshold_title": "Limiar de corrente adaptável",
+ "edt_dev_spec_gpioBcm_title": "Pino GPIO",
+ "edt_dev_spec_gpioMap_title": "Mapeamento GPIO",
+ "edt_dev_spec_gpioNumber_title": "Número GPIO",
+ "edt_dev_spec_groupId_title": "ID do Grupo",
+ "edt_dev_spec_header_title": "Configurações Específicas",
+ "edt_dev_spec_interpolation_title": "Interpolação",
+ "edt_dev_spec_intervall_title": "Intervalo",
+ "edt_dev_spec_invert_title": "Inverter sinal",
+ "edt_dev_spec_latchtime_title": "Tempo UIDLatch",
+ "edt_dev_spec_latchtime_title_info": "O tempo de travamento é o período de tempo que um dispositivo requer até que a próxima atualização possa ser processada. Durante esse período, todas as atualizações feitas são ignoradas.",
+ "edt_dev_spec_ledIndex_title": "Índice de LED",
+ "edt_dev_spec_ledType_title": "Tipo de LED",
+ "edt_dev_spec_lightid_itemtitle": "ID",
+ "edt_dev_spec_lightid_title": "ID (s) de luz",
+ "edt_dev_spec_lights_itemtitle": "Luz",
+ "edt_dev_spec_lights_name": "Nome",
+ "edt_dev_spec_lights_title": "Luz(es)",
+ "edt_dev_spec_maxPacket_title": "Pacote máximo",
+ "edt_dev_spec_maximumLedCount_title": "Contagem máxima de LED",
+ "edt_dev_spec_multicastGroup_title": "Grupo multicast",
+ "edt_dev_spec_networkDeviceName_title": "Nome do dispositivo de rede",
+ "edt_dev_spec_networkDevicePort_title": "Porta",
+ "edt_dev_spec_numberOfLeds_title": "Número de LEDs",
+ "edt_dev_spec_orbIds_title": "ID(s) Orb",
+ "edt_dev_spec_order_left_right_title": "2.",
+ "edt_dev_spec_order_top_down_title": "1.",
+ "edt_dev_spec_outputPath_title": "Caminho de saída",
+ "edt_dev_spec_panel_start_position": "Painel inicial [0-max panels]",
+ "edt_dev_spec_panelorganisation_title": "Seqüência de numeração do painel",
+ "edt_dev_spec_pid_title": "PID",
+ "edt_dev_spec_port_title": "Porta",
+ "edt_dev_spec_printTimeStamp_title": "Adicionar carimbo de data / hora",
+ "edt_dev_spec_pwmChannel_title": "Canal PWM",
+ "edt_dev_spec_restoreOriginalState_title": "Restaurar o estado das luzes",
+ "edt_dev_spec_restoreOriginalState_title_info": "Restaura o estado original do dispositivo quando o dispositivo é desativado",
+ "edt_dev_spec_serial_title": "Número Serial",
+ "edt_dev_spec_spipath_title": "Dispositivo SPI",
+ "edt_dev_spec_sslHSTimeoutMax_title": "Tempo limite máximo do aperto de mão do Streamer",
+ "edt_dev_spec_sslHSTimeoutMin_title": "Tempo limite mínimo de handshake do Streamer",
+ "edt_dev_spec_sslReadTimeout_title": "Tempo limite de leitura do streamer",
+ "edt_dev_spec_switchOffOnBlack_title": "Desligue no preto",
+ "edt_dev_spec_switchOffOnbelowMinBrightness_title": "Desligar, abaixo do mínimo",
+ "edt_dev_spec_syncOverwrite_title": "Desactivar a sincronização",
+ "edt_dev_spec_targetIpHost_title": "Nome do host / endereço IP de destino",
+ "edt_dev_spec_targetIpHost_title_info": "O nome de host ou endereço IP do dispositivo",
+ "edt_dev_spec_targetIp_title": "Endereço IP de destino",
+ "edt_dev_spec_transeffect_title": "Efeito de transição",
+ "edt_dev_spec_transistionTimeExtra_title": "Tempo extra escuridão",
+ "edt_dev_spec_transistionTime_title": "Período de transição",
+ "edt_dev_spec_uid_title": "UID",
+ "edt_dev_spec_universe_title": "Universal",
+ "edt_dev_spec_useEntertainmentAPI_title": "Usar api Entretenimento HUE",
+ "edt_dev_spec_useOrbSmoothing_title": "Usar suavização Orb",
+ "edt_dev_spec_useRgbwProtocol_title": "Use protocolo RGBW",
+ "edt_dev_spec_username_title": "Nome de usuário",
+ "edt_dev_spec_verbose_title": "Registrar todos os comandos Hue",
+ "edt_dev_spec_vid_title": "VID",
+ "edt_dev_spec_whiteLedAlgor_title": "Algoritmo de LED branco",
+ "edt_dev_spec_whitepoint_title": "Ponto branco",
+ "edt_eff_alarmcolor": "Cor do Alarme",
+ "edt_eff_backgroundColor": "Cor de fundo",
+ "edt_eff_basecolorchange": "Mudança de cor base",
+ "edt_eff_basecolorchangerate": "Taxa de mudança da Cor Base",
+ "edt_eff_basecolorrangeleft": "Cor base faixa esquerda",
+ "edt_eff_basecolorrangeright": "Cor base faixa direita",
+ "edt_eff_blobcount": "Contagem de bolhas",
+ "edt_eff_brightness": "Brilho",
+ "edt_eff_candle_header": "Vela",
+ "edt_eff_candle_header_desc": "Velas cintilantes",
+ "edt_eff_centerx": "Centro do eixo X",
+ "edt_eff_centery": "Centro do Eixo Y",
+ "edt_eff_collision_header": "colisão de cores",
+ "edt_eff_collision_header_desc": "Dois projéteis coloridos são enviados de posições aleatórias e colidem um com o outro",
+ "edt_eff_color": "Cor",
+ "edt_eff_colorHour": "Cor hora",
+ "edt_eff_colorMarker": "Cor do marcador",
+ "edt_eff_colorMinute": "Cor minuto",
+ "edt_eff_colorSecond": "Cor segundo",
+ "edt_eff_colorcount": "Comprimento de cor",
+ "edt_eff_colorend": "Cor Final",
+ "edt_eff_colorendtime": "Hora de segurar a cor inicial",
+ "edt_eff_colorevel": "Nível de Cor",
+ "edt_eff_colorone": "Cor primária",
+ "edt_eff_colorrandom": "Cor aleatória",
+ "edt_eff_colorshift": "Mudança de cor",
+ "edt_eff_colorstart": "Início de cor",
+ "edt_eff_colorstarttime": "Hora de manter a cor final",
+ "edt_eff_colortwo": "Cor secundária",
+ "edt_eff_count": "Contagem",
+ "edt_eff_countries": "Países",
+ "edt_eff_customColor": "Cor customizada",
+ "edt_eff_enableSecondSwirl": "Segundo Redemoinho",
+ "edt_eff_enableshutdown": "Desligamento real",
+ "edt_eff_enum_all": "Todos",
+ "edt_eff_enum_all-together": "Todos juntos",
+ "edt_eff_enum_list": "Lista de LED",
+ "edt_eff_explodeRadius": "Alcance de Detonação ",
+ "edt_eff_fade_header": "Esmaecer",
+ "edt_eff_fade_header_desc": "Esmaece entre as cores",
+ "edt_eff_fadefactor": "Fator de esmaecer",
+ "edt_eff_fadeintime": "Fade in time",
+ "edt_eff_fadeouttime": "Fade out time",
+ "edt_eff_flag_header": "Bandeiras",
+ "edt_eff_flag_header_desc": "Deixe seus LEDs brilharem com as cores do seu país. Você pode selecionar mais de um sinalizador e eles serão alterados com base no intervalo de tempo.",
+ "edt_eff_fps": "Quadros por segundo",
+ "edt_eff_frequency": "Frequência",
+ "edt_eff_gif_header": "GIF's",
+ "edt_eff_gif_header_desc": "Este efeito reproduz arquivos .gif, fornece um vídeo simples como um loop como efeito.",
+ "edt_eff_height": "Altura",
+ "edt_eff_huechange": "Mudança de cor",
+ "edt_eff_image": "Arquivo de imagem",
+ "edt_eff_interval": "intervalo",
+ "edt_eff_knightrider_header": "Knight Rider",
+ "edt_eff_knightrider_header_desc": "K.I.T.T está de volta! O scanner frontal do conhecido carro, desta vez não apenas em vermelho.",
+ "edt_eff_ledlist": "Lista de Leds",
+ "edt_eff_ledtest_header": "Teste de Led",
+ "edt_eff_ledtest_header_desc": "Saída rotativa: Vermelho, Verde, Azul, Branco, Preto",
+ "edt_eff_length": "Comprimento",
+ "edt_eff_lightclock_header": "Relogio de luz",
+ "edt_eff_lightclock_header_desc": "Um verdadeiro relógioem forma de luz! Ajuste as cores de horas, minutos, segundos. Um marcador opcional de 3/6/9/12 horas também está disponível. Caso o relógio esteja errado, você precisa verificar o relógio do seu sistema.",
+ "edt_eff_maintain_end_color": "Manter cor final",
+ "edt_eff_margin": "Margem",
+ "edt_eff_markerDepth": "Profundidade do marcador",
+ "edt_eff_markerEnable": "Mostrar Marcador",
+ "edt_eff_markerWidth": "Largura do marcador",
+ "edt_eff_max_len": "Comprimento máximo",
+ "edt_eff_min_len": "Comprimento mínimo",
+ "edt_eff_moodblobs_header": "Bolhas de Humor",
+ "edt_eff_moodblobs_header_desc": "Relaxe à noite com bolhas que se movem lentamente e mudam de cor.",
+ "edt_eff_offset": "Desvio",
+ "edt_eff_pacman_header": "Pac-Man",
+ "edt_eff_pacman_header_desc": "Pequeno com fome e amarelo. Quem vai sobreviver?",
+ "edt_eff_plasma_header": "Plasma",
+ "edt_eff_plasma_header_desc": "Distorção de cor em diferentes direções",
+ "edt_eff_police_header": "Polícia",
+ "edt_eff_police_header_desc": "Luzes como um carro de polícia em ação",
+ "edt_eff_postcolor": "Cor da postagem",
+ "edt_eff_rainbowmood_header": "Modo Arco-íris",
+ "edt_eff_rainbowmood_header_desc": "Todos os LEDs humor do arco-íris",
+ "edt_eff_randomCenter": "Centro aleatório",
+ "edt_eff_random_header": "Aleatório",
+ "edt_eff_random_header_desc": "Pixel Ponto, ponto, ponto ...",
+ "edt_eff_repeat": "Repetir",
+ "edt_eff_repeatcount": "Contagem de Repetição",
+ "edt_eff_reverseRandomTime": "Inverte a cada",
+ "edt_eff_reversedirection": "Reverter direção",
+ "edt_eff_rotationtime": "Tempo de rotação",
+ "edt_eff_saturation": "Saturação",
+ "edt_eff_showseconds": "Mostrar segundos",
+ "edt_eff_sleeptime": "Tempo de descanso",
+ "edt_eff_smooth_custom": "Habilitar suavização",
+ "edt_eff_smooth_time_ms": "Tempo de suavização",
+ "edt_eff_smooth_updateFrequency": "Freqüência de atualização de suavização",
+ "edt_eff_snake_header": "Cobra",
+ "edt_eff_snake_header_desc": "Onde tem algo para comer?",
+ "edt_eff_sparks_header": "Faíscas",
+ "edt_eff_sparks_header_desc": "Star-Sparking, escolha entre uma cor estática ou aleatória. Você também pode ajustar o brilho, a saturação e a velocidade.",
+ "edt_eff_speed": "Velocidade",
+ "edt_eff_swirl_header": "Redemoinho de cor",
+ "edt_eff_swirl_header_desc": "Um redemoinho com cores personalizadas. As cores são distribuídas uniformemente em 360 °, e as mudanças entre as cores serão calculadas. Além disso, você pode adicionar um segundo redemoinho no topo, esteja ciente de que precisa de transparência parcial! Dica: A repetição da mesma cor resulta em uma área de cor \"mais alta\" e uma área de mudança de cor reduzida.",
+ "edt_eff_systemshutdown_header": "Desligamento do sistema",
+ "edt_eff_systemshutdown_header_desc": "Uma curta animação com provavelmente um desligamento real do sistema",
+ "edt_eff_traces_header": "Traços de cor",
+ "edt_eff_traces_header_desc": "Requer redesenho",
+ "edt_eff_trails_header": "Estrelas cadentes",
+ "edt_eff_trails_header_desc": "Estrelas coloridas que caem de cima para baixo",
+ "edt_eff_waves_header": "Ondas",
+ "edt_eff_waves_header_desc": "Ondas de cor! Escolha suas cores, tempo de rotação, direção reversa e muito mais.",
+ "edt_eff_whichleds": "Quais LEDs",
+ "edt_eff_whitelevel": "Nível de Branco",
+ "edt_eff_x-mas_header": "Natal",
+ "edt_eff_x-mas_header_desc": "Toque de natal",
+ "edt_msg_button_add_row_title": "Adicionar $1",
+ "edt_msg_button_collapse": "Colapsar",
+ "edt_msg_button_delete_all": "Todos",
+ "edt_msg_button_delete_all_title": "Deletar Tudo",
+ "edt_msg_button_delete_last": "Último $1",
+ "edt_msg_button_delete_last_title": "Deletar Último $1",
+ "edt_msg_button_delete_row_title": "Deletar $1",
+ "edt_msg_button_delete_row_title_short": "Deletar",
+ "edt_msg_button_expand": "Expandir",
+ "edt_msg_button_move_down_title": "Mover para baixo",
+ "edt_msg_button_move_up_title": "Mover para cima",
+ "edt_msg_error_additionalItems": "Nenhum item adicional permitido nesta matriz",
+ "edt_msg_error_additional_properties": "Nenhuma propriedade adicional permitida, mas a propriedade $1 está definida",
+ "edt_msg_error_anyOf": "O valor deve ser validado em pelo menos um dos esquemas fornecidos",
+ "edt_msg_error_dependency": "Deve ter propriedade $1",
+ "edt_msg_error_disallow": "O valor não deve ser do tipo $1",
+ "edt_msg_error_disallow_union": "O valor não deve ser um dos tipos não permitidos fornecidos",
+ "edt_msg_error_enum": "O valor deve ser um dos valores enumerados",
+ "edt_msg_error_maxItems": "O valor deve ter no máximo $1 itens",
+ "edt_msg_error_maxLength": "O valor deve ter no máximo $1 caracteres",
+ "edt_msg_error_maxProperties": "O objeto deve ter no máximo $1 propriedades",
+ "edt_msg_error_maximum_excl": "O valor deve ser inferior a $1",
+ "edt_msg_error_maximum_incl": "O valor deve ser no máximo $1",
+ "edt_msg_error_minItems": "O valor deve ter pelo menos $1 itens",
+ "edt_msg_error_minLength": "O valor deve ter pelo menos $1 caracteres",
+ "edt_msg_error_minProperties": "O objeto deve ter pelo menos $1 propriedades",
+ "edt_msg_error_minimum_excl": "O valor deve ser maior que $1",
+ "edt_msg_error_minimum_incl": "O valor deve ser pelo menos $1",
+ "edt_msg_error_multipleOf": "O valor deve ser um múltiplo de $1",
+ "edt_msg_error_not": "O valor não deve ser validado no esquema fornecido",
+ "edt_msg_error_notempty": "Valor requerido",
+ "edt_msg_error_notset": "A propriedade deve ser definida",
+ "edt_msg_error_oneOf": "O valor deve ser validado em relação a exatamente um dos esquemas fornecidos. Atualmente é validado em $1 dos esquemas.",
+ "edt_msg_error_pattern": "O valor deve corresponder ao padrão",
+ "edt_msg_error_required": "O objeto está sem a propriedade necessária '$1'",
+ "edt_msg_error_type": "O valor deve ser do tipo $1",
+ "edt_msg_error_type_union": "O valor deve ser um dos tipos fornecidos",
+ "edt_msg_error_uniqueItems": "A matriz deve ter itens exclusivos",
+ "effectsconfigurator_button_conttest": "Teste Contínuo",
+ "effectsconfigurator_button_deleffect": "Deletar Efeito",
+ "effectsconfigurator_button_editeffect": "Carregar Efgeito",
+ "effectsconfigurator_button_saveeffect": "Salvar Efeito",
+ "effectsconfigurator_button_starttest": "Iniciar Teste",
+ "effectsconfigurator_button_stoptest": "Parar Teste",
+ "effectsconfigurator_editdeleff": "Deletar/Carregar Efeito",
+ "effectsconfigurator_label_chooseeff": "Escolha Modelo",
+ "effectsconfigurator_label_effectname": "Nome do Efeito",
+ "effectsconfigurator_label_intro": "Crie novos efeitos a partir dos efeitos básicos ajustados ao seu gosto. Dependendo do efeito, existem opções como cor, velocidade, direção e muito mais disponíveis.",
+ "general_access_advanced": "Avançado",
+ "general_access_default": "Padrão",
+ "general_access_expert": "Especialista",
+ "general_btn_back": "Voltar",
+ "general_btn_cancel": "Cancelar",
+ "general_btn_continue": "Continuar",
+ "general_btn_delete": "Deletar",
+ "general_btn_denyAccess": "Negar Acesso",
+ "general_btn_grantAccess": "Permitir acesso",
+ "general_btn_iswitch": "Trocar",
+ "general_btn_next": "Próximo",
+ "general_btn_off": "Desligado",
+ "general_btn_ok": "Ok",
+ "general_btn_on": "Ligado",
+ "general_btn_overwrite": "Sobrescrever",
+ "general_btn_rename": "Renomear",
+ "general_btn_restarthyperion": "Reiniciar Hyperion",
+ "general_btn_save": "Salvar",
+ "general_btn_saveandreload": "Salvar e recarregar",
+ "general_btn_saverestart": "Salvar e reiniciar",
+ "general_btn_start": "Iniciar",
+ "general_btn_stop": "Parar",
+ "general_btn_yes": "Sim",
+ "general_button_savesettings": "Salvar configurações",
+ "general_chars_needed": "mais caracteres necessários",
+ "general_col_blue": "azul",
+ "general_col_green": "verde",
+ "general_col_red": "vermelho",
+ "general_comp_BLACKBORDER": "Detecção de bordas",
+ "general_comp_BOBLIGHTSERVER": "Servidor Boblight",
+ "general_comp_FLATBUFSERVER": "Servidor Flatbuffers",
+ "general_comp_FORWARDER": "Encaminhador",
+ "general_comp_GRABBER": "Plataforma de Captura",
+ "general_comp_LEDDEVICE": "Dispositivo LED",
+ "general_comp_PROTOSERVER": "Protocolo do Servidor de Buffer",
+ "general_comp_SMOOTHING": "Suavização",
+ "general_comp_V4L": "Captura USB",
+ "general_country_cn": "China",
+ "general_country_de": "Alemanha",
+ "general_country_es": "Espanha",
+ "general_country_fr": "França",
+ "general_country_it": "Itália",
+ "general_country_nl": "Holanda",
+ "general_country_ru": "Rússia",
+ "general_country_uk": "Reino Unido",
+ "general_country_us": "Estados Unidos",
+ "general_speech_cs": "Tcheco",
+ "general_speech_de": "Alemanha",
+ "general_speech_en": "Inglês",
+ "general_speech_es": "Espanhol",
+ "general_speech_fr": "Francês",
+ "general_speech_it": "Italiano",
+ "general_speech_nl": "Holandês",
+ "general_speech_pl": "Polonês",
+ "general_speech_pt": "Português",
+ "general_speech_ro": "Romeno",
+ "general_speech_ru": "Russo",
+ "general_speech_sv": "Sueco",
+ "general_speech_tr": "Turco",
+ "general_speech_vi": "Vietnamita",
+ "general_speech_zh-CN": "Chinês (simplificado)",
+ "general_webui_title": "Hyperion - Configuração Web",
+ "general_wiki_moreto": "Mais informações para \"$1\" na nossa Wiki",
+ "infoDialog_checklist_title": "Checklist!",
+ "infoDialog_effconf_created_text": "O efeito \"$1\" foi criado com sucesso!",
+ "infoDialog_effconf_deleted_text": "O efeito \"$1\" foi excluído com sucesso!",
+ "infoDialog_general_error_title": "Erro",
+ "infoDialog_general_success_title": "Sucesso",
+ "infoDialog_general_warning_title": "Aviso",
+ "infoDialog_import_comperror_text": "Triste! Seu navegador não suporta importação. Por favor, tente novamente com outro navegador.",
+ "infoDialog_import_confirm_text": "Tem certeza de que deseja importar \"$1\"? Este processo não pode ser revertido!",
+ "infoDialog_import_confirm_title": "Confirmar importação",
+ "infoDialog_import_hyperror_text": "O arquivo de configuração selecionado \"$1\" não pode ser importado. Não é compatível com Hyperion 2.0 e superior!",
+ "infoDialog_import_jsonerror_text": "O arquivo de configuração selecionado \"$1\" não é um arquivo .json ou está corrompido. Mensagem de erro: ($2)",
+ "infoDialog_wizrgb_text": "Sua ordem de bytes RGB já está bem ajustada.",
+ "infoDialog_writeconf_error_text": "Falha ao salvar sua configuração.",
+ "infoDialog_writeimage_error_text": "O arquivo selecionado \"$1\" não é um arquivo de imagem ou está corrompido! Selecione outro arquivo de imagem.",
+ "info_404": "A página que você solicitou não está disponível!",
+ "info_conlost_label_autorecon": "Nós nos reconectamos novamente após o Hyperion estar disponível.",
+ "info_conlost_label_autorefresh": "Esta página será atualizada automaticamente.",
+ "info_conlost_label_reason": "Razões possíveis:",
+ "info_conlost_label_reason1": "- Conexão WLAN ruim",
+ "info_conlost_label_reason2": "- Você realizou uma atualização",
+ "info_conlost_label_reason3": "- Hyperion não está aberto",
+ "info_conlost_label_reload": "Reconexão automática interrompida - limite excedido, atualize a página ou clique aqui.",
+ "info_conlost_label_title": "Conexão perdida com o serviço Hyperion!",
+ "info_restart_contus": "Se você ainda está por aqui depois de 20 segundos e não tem ideia do porque, abra um novo tópico em nosso fórum de suporte...",
+ "info_restart_contusa": "... com seus últimos passos. Obrigado!",
+ "info_restart_rightback": "Hyperion estará de volta logo!",
+ "info_restart_title": "Reiniciando atualmente ...",
+ "main_ledsim_btn_togglelednumber": "Números dos LEDs",
+ "main_ledsim_btn_toggleleds": "Mostrar LEDs",
+ "main_ledsim_btn_togglelivevideo": "Video em tempo real",
+ "main_ledsim_text": "Visualização em tempo real das cores dos LEDs e, opcionalmente, stream de vídeo do dispositivo de captura.",
+ "main_ledsim_title": "Visualização LED",
+ "main_menu_about_token": "Sobre o Hyperion",
+ "main_menu_colors_conf_token": "Processamento de Imagem",
+ "main_menu_configuration_token": "Configuração",
+ "main_menu_dashboard_token": "Dashboard",
+ "main_menu_effect_conf_token": "Efeitos",
+ "main_menu_effectsconfigurator_token": "Configurador de efeitos",
+ "main_menu_general_conf_token": "Geral",
+ "main_menu_grabber_conf_token": "Hardware de Captura",
+ "main_menu_input_selection_token": "Seleção de",
+ "main_menu_leds_conf_token": "Hardware LED",
+ "main_menu_logging_token": "Log",
+ "main_menu_network_conf_token": "Serviços de Rede",
+ "main_menu_remotecontrol_token": "Controle Remoto",
+ "main_menu_support_token": "Suporte",
+ "main_menu_system_token": "Sistema",
+ "main_menu_update_token": "Atualizar",
+ "main_menu_webconfig_token": "Configuração web",
+ "remote_adjustment_intro": "Modificar cor",
+ "remote_adjustment_label": "Ajuste de cor",
+ "remote_color_button_reset": "Resetar Cor/Efeito",
+ "remote_color_intro": "Defina um efeito ou cor. Também são listados os efeitos criados por você mesmo (se disponíveis). $1",
+ "remote_color_label": "Cores/Efeitos",
+ "remote_color_label_color": "Cor:",
+ "remote_components_intro": "Habilite e desabilite os componentes do Hyperion durante o tempo de execução. $1",
+ "remote_components_label": "Controle de componentes",
+ "remote_effects_label_effects": "Efeito:",
+ "remote_effects_label_picture": "Foto:",
+ "remote_input_clearall": "Limpar todos os efeitos / cores",
+ "remote_input_duration": "Duração:",
+ "remote_input_intro": "O Hyperion usa um sistema de prioridade para selecionar uma fonte. Tudo que você define tem uma prioridade (Efeito / Cor / Captura de plataforma / Captura USB e fontes de rede). Por padrão, o Hyperion seleciona as fontes de acordo com a prioridade (o número mais baixo reflete a fonte ativa atual). Agora você tem a oportunidade de selecionar as fontes por conta própria. $1",
+ "remote_input_ip": "IP:",
+ "remote_input_label": "Seleção de Fonte",
+ "remote_input_label_autoselect": "Seleção Automática",
+ "remote_input_origin": "Origem",
+ "remote_input_owner": "Tipo",
+ "remote_input_priority": "Prioridade",
+ "remote_input_setsource_btn": "Selecione a fonte",
+ "remote_input_sourceactiv_btn": "Fonte ativa",
+ "remote_input_status": "Estado/Ação",
+ "remote_losthint": "Nota: Todas as configurações são redefinidas ao resetar.",
+ "remote_maptype_intro": "Normalmente, o layout de led define qual LED cobre uma área específica da imagem, você pode alterá-lo aqui: $1.",
+ "remote_maptype_label": "Tipo de mapeamento",
+ "remote_maptype_label_multicolor_mean": "Multicolorido",
+ "remote_maptype_label_unicolor_mean": "Unicolorido",
+ "remote_optgroup_syseffets": "Effeitos do Sistema",
+ "remote_optgroup_templates_custom": "Modelos do usuário",
+ "remote_optgroup_templates_system": "Modelos do sistema",
+ "remote_optgroup_usreffets": "Effeitos do Usuário",
+ "remote_videoMode_2D": "2D",
+ "remote_videoMode_3DSBS": "3DSBS",
+ "remote_videoMode_3DTAB": "3DTAB",
+ "remote_videoMode_intro": "Alterne entre os diferentes modos de vídeo para desfrutar de filmes 3D! São suportados todos os dispositivos de captura. $1",
+ "remote_videoMode_label": "Modo vídeo",
+ "support_label_affinstr1": "Clique no link apropriado de seu país",
+ "support_label_affinstr2": "Tudo o que você compra (não importa o que), nós recebemos uma pequena taxa com base no seu faturamento",
+ "support_label_affinstr3": "Você SEMPRE paga o mesmo preço, não há absolutamente nenhuma diferença. Experimente!",
+ "support_label_btctext": "Endereço:",
+ "support_label_donate": "Doe ou use nossos links de afiliados",
+ "support_label_donationpp": "Doação:",
+ "support_label_fbtext": "Compartilhe nossa página do Hyperion no Facebook e receba um aviso quando novas atualizações forem lançadas",
+ "support_label_forumtext": "Demonstrações, discussões, ajuda e muito mais",
+ "support_label_forumtitle": "Fórum",
+ "support_label_ggtext": "Circule-nos no Google +!",
+ "support_label_ghtext": "Visite-nos no GitHub",
+ "support_label_igtext": "Visite-nos no Instagram para ver as últimas fotos do Hyperion!",
+ "support_label_intro": "Hyperion é um software gratuito sem fins lucrativos. Uma pequena equipe está trabalhando nisso e é por isso que precisamos do seu apoio constante.",
+ "support_label_spreadtheword": "Divulgue",
+ "support_label_title": "Ajude Hyperion",
+ "support_label_twtext": "Compartilhe e siga no Twitter, esteja sempre atualizado com as últimas postagens sobre o desenvolvimento do Hyperion",
+ "support_label_webpagetext": "Site do Hyperion",
+ "support_label_webpagetitle": "Site",
+ "support_label_webrestitle": "Recursos de informação e ajuda",
+ "support_label_wikitext": "A fonte de A a Z para quase tudo relacionado ao Hyperion",
+ "support_label_wikititle": "Documentação",
+ "support_label_yttext": "Entediado das fotos? Confira nosso canal no YouTube!",
+ "update_button_changelog": "Log de mudanças completo",
+ "update_button_install": "Instalar",
+ "update_error_getting_versions": "Tivemos problemas para determinar a versão mais recente disponível.",
+ "update_label_description": "Descrição:",
+ "update_label_intro": "Visão geral sobre todas as versões disponíveis do Hyperion. Além disso, você pode atualizar ou fazer downgrade de sua versão do Hyperion sempre que quiser. Ordenado do mais recente ao mais antigo",
+ "update_label_type": "Tipo:",
+ "update_no_updates_for_branch": "Nenhuma atualização para o canal da versão selecionada.",
+ "update_versreminder": "Sua versão: $1",
+ "wiz_atmoorb_desc2": "Agora escolha quais Orbs devem ser adicionados. A posição atribui a lâmpada a uma posição específica na sua \"imagem\". Lâmpadas desativadas não serão adicionadas. Para identificar lâmpadas individuais, pressione o botão à direita.",
+ "wiz_atmoorb_intro1": "Este assistente configura o Hyperion para AtmoOrbs. Os recursos são a detecção automática AtmoOrb, definindo cada luz para uma posição específica em sua imagem ou desativá-lo e otimizar as configurações do Hyperion automaticamente! Resumindo: você só precisa de alguns cliques e pronto!",
+ "wiz_atmoorb_title": "Assistente AtmoOrb",
+ "wiz_cc_adjustgamma": "Gama: O que você precisa fazer é ajustar os níveis de gama de cada canal até ter a mesma quantidade percebida de cada canal. Dica: Neutro é 1.0! Por exemplo, se o seu cinza for um pouco avermelhado, isso significa que você deve aumentar o gama do vermelho para reduzir a quantidade de vermelho (quanto mais gama, menor a quantidade de cor).",
+ "wiz_cc_adjustit": "Ajuste seu \"$1\", até que esteja tudo bem com ele. Atenção: quanto mais você se afasta do valor padrão, o espectro de cores será limitado (também para todas as cores intermediárias). Dependendo do espectro de cores da TV / LED, os resultados podem variar.",
+ "wiz_cc_backlight": "Além disso, você pode definir uma luz de fundo para separar as \"cores ruins\" em áreas quase escuras ou se você não gostar de alternar entre cores e desligadas durante a exibição. Além disso, você pode definir se deve haver alguma cor ou apenas branco. Isso é desativado durante o estado \"Desligado\", \"Cor\" e \"Efeito\".",
+ "wiz_cc_btn_stop": "Parar o vídeo",
+ "wiz_cc_btn_switchpic": "Mudar de imagem",
+ "wiz_cc_chooseid": "Defina um nome para este perfil de cor.",
+ "wiz_cc_intro1": "Este assistente irá guiá-lo através da calibração do led. Se você estiver usando o Kodi, as fotos e vídeos de calibração podem ser enviados diretamente para ele. Pré-requisito: você precisa habilitar \"Permitir controle remoto de aplicativos em outros sistemas\" no Kodi. Como alternativa, você pode fazer o download desses arquivos por conta própria e exibi-los quando o assistente solicitar que você ajuste a configuração.",
+ "wiz_cc_kodicon": "Kodi encontrado, prossiga com o suporte Kodi.",
+ "wiz_cc_kodidiscon": "Kodi não encontrado, prossiga sem o suporte Kodi (verifique se o controle remoto por outros sistemas está ativado).",
+ "wiz_cc_kodidisconlink": "Baixar fotos do link:",
+ "wiz_cc_kodimsg_start": "Sucesso do teste - hora de continuar!",
+ "wiz_cc_kodishould": "Kodi deve mostrar a seguinte imagem: $1",
+ "wiz_cc_kwebs": "Servidor da web Kodi (nome do host ou IP)",
+ "wiz_cc_lettvshow": "Deixe sua TV mostrar a seguinte imagem: $1",
+ "wiz_cc_lettvshowm": "Verifique isso com as seguintes fotos: $1",
+ "wiz_cc_link": "Clique aqui!",
+ "wiz_cc_morethanone": "Você tem mais de um perfil, escolha o perfil que deseja calibrar.",
+ "wiz_cc_summary": "Uma conclusão de suas configurações. Durante a reprodução do vídeo, você pode alterar ou testar os valores novamente. Quando terminar, clique em salvar.",
+ "wiz_cc_testintro": "É hora de um teste real!",
+ "wiz_cc_testintrok": "Pressione o botão abaixo para iniciar um vídeo de teste.",
+ "wiz_cc_testintrowok": "Confira o seguinte link para baixar vídeos de teste:",
+ "wiz_cc_title": "Assistente de calibração de cores",
+ "wiz_cololight_desc2": "Agora escolha quais Cololights devem ser adicionados. Para identificar luzes individuais, pressione o botão à direita.",
+ "wiz_cololight_intro1": "Este assistente configura o Hyperion para o sistema Cololight. Os recursos são a detecção automática Cololight e ajuste as configurações do Hyperion automaticamente! Resumindo: Tudo o que você precisa é de alguns cliques e pronto! Nota: No caso do Cololight Strip, pode ser necessário corrigir manualmente a contagem e o layout dos LEDs.",
+ "wiz_cololight_noprops": "Não é possível obter propriedades do dispositivo - Definir contagem de LED de hardware manualmente",
+ "wiz_cololight_title": "Assistente Cololight",
+ "wiz_guideyou": "O $1 irá guiá-lo através das configurações. Basta apertar o botão!",
+ "wiz_hue_blinkblue": "Deixe ID $1 acender em azul",
+ "wiz_hue_clientkey": "Chave do Cliente:",
+ "wiz_hue_create_user": "Criar novo Usuário",
+ "wiz_hue_desc1": "Ele procura automaticamente por um Hue-Bridge, caso não encontre um, você precisa fornecer o endereço IP e apertar o botão recarregar à direita. Agora você precisa de um ID de usuário, se você não tiver um, crie um novo.",
+ "wiz_hue_desc2": "Agora escolha quais lâmpadas devem ser adicionadas. A posição atribui a lâmpada a uma posição específica na sua \"imagem\". Lâmpadas desativadas não serão adicionadas. Para identificar lâmpadas individuais, pressione o botão à direita.",
+ "wiz_hue_e_clientkey_needed": "Uma chave de cliente que corresponda ao nome de usuário é necessária para usar a API de entretenimento. Insira um existente ou use o botão abaixo para criar um novo.",
+ "wiz_hue_e_create_user": "Criar novo usuário e chave de cliente",
+ "wiz_hue_e_desc1": "Ele procura automaticamente por uma hue bridge, caso não encontre uma, você precisa fornecer o endereço IP e apertar o botão recarregar à direita. Agora você precisa de um ID de usuário e a chave do cliente, se você não tiver os dois, crie um novo.",
+ "wiz_hue_e_desc2": "Agora escolha o seu grupo de entretenimento, que tem todas as suas luzes dentro para usar com o Hyperion.",
+ "wiz_hue_e_desc3": "Agora você pode escolher em que posição a respectiva lâmpada deve estar \"na imagem\". Uma pré-seleção da posição foi feita com base nas posições configuradas das luzes no grupo de entretenimento. Esta é apenas uma recomendação e pode ser personalizada conforme desejado. Você pode, portanto, destacá-los brevemente clicando com o botão direito para melhorar a seleção.",
+ "wiz_hue_e_intro1": "Este assistente configura o Hyperion para o conhecido sistema Philips Hue Entertainment. Os recursos são: detecção automática do Hue Bridge, criação de chaves do usuário e do cliente, seleção do grupo de entretenimento, configuração das luzes do grupo em uma posição específica na imagem e otimização das configurações do Hyperion automaticamente! Resumindo: você só precisa de alguns cliques e pronto!",
+ "wiz_hue_e_noapisupport": "O assistente desativou o suporte à API de entretenimento e continuará no modo clássico.",
+ "wiz_hue_e_noapisupport_hint": "A opção \" Usar Hue Entertainment API \" foi desmarcada.",
+ "wiz_hue_e_noegrpids": "Nenhum grupo de entretenimento definido nesta ponte Hue.",
+ "wiz_hue_e_nogrpids": "Esta ponte Hue não tem grupos definidos, crie pelo menos um antes com os Aplicativos Hue.",
+ "wiz_hue_e_title": "Assistente de Entretenimento Philips Hue",
+ "wiz_hue_e_use_group": "Use o grupo",
+ "wiz_hue_e_use_groupid": "Use o ID de grupo $1",
+ "wiz_hue_failure_connection": "Tempo limite: Por favor, pressione o botão bridge dentro do período de 30 segundos",
+ "wiz_hue_failure_ip": "Nenhuma ponte encontrada, digite um endereço IP válido",
+ "wiz_hue_failure_user": "Usuário não encontrado, crie um novo com o botão abaixo ou insira um ID de usuário válido e pressione o símbolo \"recarregar\".",
+ "wiz_hue_intro1": "Este assistente configura o Hyperion para o conhecido sistema Philips Hue. Os recursos são a detecção automática do Hue Bridge, a criação do usuário, defina cada luz HUE para uma posição específica em sua imagem ou desative-a e ajuste as configurações do Hyperion automaticamente! Resumindo: você só precisa de alguns cliques e pronto!",
+ "wiz_hue_ip": "Hue Bridge IP:",
+ "wiz_hue_noids": "Este Hue Bridge não tem lâmpadas / listras, por favor, emparelhe-os antes com os Aplicativos Hue",
+ "wiz_hue_press_link": "Pressione o botão de link na Hue Bridge.",
+ "wiz_hue_searchb": "Procurando Bridge...",
+ "wiz_hue_title": "Assistente Philips Hue",
+ "wiz_hue_username": "ID de Usuário:",
+ "wiz_identify": "Identificar",
+ "wiz_identify_light": "identificar $1",
+ "wiz_ids_disabled": "Desativado",
+ "wiz_ids_entire": "Foto Inteira",
+ "wiz_noLights": "Nenhum $1 encontrado! Conecte as luzes à rede ou configure-as manualmente.",
+ "wiz_pos": "Posição/Estado",
+ "wiz_rgb_expl": "O ponto colorido muda a cada x segundos de cor (vermelho, verde), ao mesmo tempo que seus LEDs mudam de cor também. Responda às perguntas na parte inferior para verificar / corrigir a ordem dos bytes.",
+ "wiz_rgb_intro1": "Este assistente irá guiá-lo através do processo de localização da ordem correta de cores para seus leds. Clique em continuar para começar.",
+ "wiz_rgb_intro2": "Quando você precisa deste assistente? Exemplo: você define a cor vermelha, mas obtém verde ou azul. Você também pode usá-lo para a primeira configuração.",
+ "wiz_rgb_q": "Qual cor seus LEDs mostram, quando o ponto de cor acima mostra ...",
+ "wiz_rgb_qgend": "...verde?",
+ "wiz_rgb_qrend": "...vermelho?",
+ "wiz_rgb_switchevery": "Mudar de cor a cada ...",
+ "wiz_rgb_title": "Assistente de ordem de bytes RGB",
+ "wiz_wizavail": "Assistente disponível",
+ "wiz_yeelight_desc2": "Agora escolha quais lâmpadas devem ser adicionadas. A posição atribui a lâmpada a uma posição específica na sua \"imagem\". Lâmpadas desativadas não serão adicionadas. Para identificar lâmpadas individuais, pressione o botão à direita.",
+ "wiz_yeelight_intro1": "Este assistente configura o Hyperion para o sistema Yeelight. Os recursos são a detecção automática dos Yeelighs, definindo cada luz em uma posição específica na imagem ou desabilitá-la e ajustar as configurações do Hyperion automaticamente! Resumindo: você só precisa de alguns cliques e pronto!",
+ "wiz_yeelight_title": "Assistente Yeelight",
+ "wiz_yeelight_unsupported": "Não suportado"
+}
diff --git a/assets/webconfig/i18n/pt.json b/assets/webconfig/i18n/pt.json
new file mode 100644
index 00000000..10cd7f6d
--- /dev/null
+++ b/assets/webconfig/i18n/pt.json
@@ -0,0 +1,77 @@
+{
+ "dashboard_alert_message_confedit_t": "Configuração modificada",
+ "dashboard_alert_message_confsave_success_t": "Configuração gravada",
+ "dashboard_componentbox_label_comp": "Componente",
+ "dashboard_componentbox_label_status": "Estado",
+ "dashboard_componentbox_label_title": "Estado dos componentes",
+ "dashboard_infobox_label_currenthyp": "A tua versão do Hyperion:",
+ "dashboard_infobox_label_disableh": "Desabilitar instância: $1",
+ "dashboard_infobox_label_enableh": "Habilitar instância: $1",
+ "dashboard_infobox_label_instance": "Instância",
+ "dashboard_infobox_label_latesthyp": "Última versão do Hyperion:",
+ "dashboard_infobox_label_platform": "Plataforma:",
+ "dashboard_infobox_label_ports": "Portos (flat| proto):",
+ "dashboard_infobox_label_smartacc": "Acesso Inteligente",
+ "dashboard_infobox_label_statush": "Hyperion estado:",
+ "dashboard_infobox_label_title": "Informação",
+ "dashboard_infobox_message_updatesuccess": "Está a executar última versão do Hyperion.",
+ "dashboard_infobox_message_updatewarning": "Uma versão mais recente do Hyperion está disponível! ($1)",
+ "dashboard_label_intro": "O painel fornece uma visão geral rápida sobre o estado do Hyperion e mostra as últimas notícias do Blog do Hyperion.",
+ "dashboard_newsbox_label_title": "Hyperion-Blog",
+ "dashboard_newsbox_noconn": "Não é possível conectar ao servidor Hyperion para recuperar os últimos posts, a sua conexão à Internet funciona?",
+ "dashboard_newsbox_readmore": "Ler mais",
+ "dashboard_newsbox_visitblog": "Visite o Hyperion-Blog",
+ "general_access_advanced": "Avançado",
+ "general_access_default": "Por omissão",
+ "general_access_expert": "Especialista",
+ "general_btn_back": "Voltar",
+ "general_btn_cancel": "Cancelar",
+ "general_btn_continue": "Continuar",
+ "general_btn_iswitch": "Interruptor",
+ "general_btn_next": "Seguinte",
+ "general_btn_off": "Desligar",
+ "general_btn_ok": "OK",
+ "general_btn_on": "Ligar",
+ "general_btn_restarthyperion": "Reiniciar o Hyperion",
+ "general_btn_save": "Garvar",
+ "general_btn_saveandreload": "Gravar e recarregar",
+ "general_btn_yes": "Sim",
+ "general_button_savesettings": "Gravar configurações",
+ "general_col_blue": "azul",
+ "general_col_green": "verde",
+ "general_col_red": "vermelho",
+ "general_comp_BLACKBORDER": "Detecção de barras",
+ "general_comp_BOBLIGHTSERVER": "Boblight Server",
+ "general_comp_FLATBUFSERVER": "Servidor Flatbuffers",
+ "general_comp_FORWARDER": "Forwarder",
+ "general_comp_GRABBER": "Plataforma de Captura",
+ "general_comp_LEDDEVICE": "Dispositivo LED",
+ "general_comp_PROTOSERVER": "Servidor de buffers de protocolo",
+ "general_comp_SMOOTHING": "Smoothing",
+ "general_comp_V4L": "Captura USB",
+ "general_country_de": "Alemanha",
+ "general_country_es": "Espanha",
+ "general_country_fr": "França",
+ "general_country_it": "Itália",
+ "general_country_nl": "Holanda",
+ "general_country_uk": "Reino Unido",
+ "general_country_us": "Estados Unidos da América",
+ "general_speech_cs": "Tcheco",
+ "general_speech_de": "Alemão",
+ "general_speech_en": "Inglês",
+ "general_speech_es": "Espanhol",
+ "general_speech_it": "Italiano",
+ "general_speech_pt": "Português",
+ "general_webui_title": "Hyperion - Configuração Web",
+ "general_wiki_moreto": "Mais informação a \"$1\" na nossa Wiki",
+ "main_menu_colors_conf_token": "Processamento de imagem",
+ "main_menu_configuration_token": "Configuração",
+ "main_menu_dashboard_token": "Painel",
+ "main_menu_effect_conf_token": "Efeitos",
+ "main_menu_general_conf_token": "Geral",
+ "main_menu_grabber_conf_token": "Hardware de captura",
+ "main_menu_leds_conf_token": "LED Hardware",
+ "main_menu_network_conf_token": "Serviços de rede",
+ "main_menu_remotecontrol_token": "Controlo remoto",
+ "main_menu_support_token": "Suporte"
+}
diff --git a/assets/webconfig/index.html b/assets/webconfig/index.html
index 5f73d80c..e8154e01 100644
--- a/assets/webconfig/index.html
+++ b/assets/webconfig/index.html
@@ -44,12 +44,13 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/assets/webconfig/js/lib/jquery.i18n/CLDRPluralRuleParser.js b/assets/webconfig/js/lib/jquery.i18n/CLDRPluralRuleParser.js
new file mode 100644
index 00000000..f76459e5
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/CLDRPluralRuleParser.js
@@ -0,0 +1,607 @@
+/**
+ * cldrpluralparser.js
+ * A parser engine for CLDR plural rules.
+ *
+ * Copyright 2012-2014 Santhosh Thottingal and other contributors
+ * Released under the MIT license
+ * http://opensource.org/licenses/MIT
+ *
+ * @source https://github.com/santhoshtr/CLDRPluralRuleParser
+ * @author Santhosh Thottingal
+ * @author Timo Tijhof
+ * @author Amir Aharoni
+ */
+
+/**
+ * Evaluates a plural rule in CLDR syntax for a number
+ * @param {string} rule
+ * @param {integer} number
+ * @return {boolean} true if evaluation passed, false if evaluation failed.
+ */
+
+// UMD returnExports https://github.com/umdjs/umd/blob/master/returnExports.js
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(factory);
+ } else if (typeof exports === 'object') {
+ // Node. Does not work with strict CommonJS, but
+ // only CommonJS-like environments that support module.exports,
+ // like Node.
+ module.exports = factory();
+ } else {
+ // Browser globals (root is window)
+ root.pluralRuleParser = factory();
+ }
+}(this, function() {
+
+function pluralRuleParser(rule, number) {
+ 'use strict';
+
+ /*
+ Syntax: see http://unicode.org/reports/tr35/#Language_Plural_Rules
+ -----------------------------------------------------------------
+ condition = and_condition ('or' and_condition)*
+ ('@integer' samples)?
+ ('@decimal' samples)?
+ and_condition = relation ('and' relation)*
+ relation = is_relation | in_relation | within_relation
+ is_relation = expr 'is' ('not')? value
+ in_relation = expr (('not')? 'in' | '=' | '!=') range_list
+ within_relation = expr ('not')? 'within' range_list
+ expr = operand (('mod' | '%') value)?
+ operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
+ range_list = (range | value) (',' range_list)*
+ value = digit+
+ digit = 0|1|2|3|4|5|6|7|8|9
+ range = value'..'value
+ samples = sampleRange (',' sampleRange)* (',' ('…'|'...'))?
+ sampleRange = decimalValue '~' decimalValue
+ decimalValue = value ('.' value)?
+ */
+
+ // We don't evaluate the samples section of the rule. Ignore it.
+ rule = rule.split('@')[0].replace(/^\s*/, '').replace(/\s*$/, '');
+
+ if (!rule.length) {
+ // Empty rule or 'other' rule.
+ return true;
+ }
+
+ // Indicates the current position in the rule as we parse through it.
+ // Shared among all parsing functions below.
+ var pos = 0,
+ operand,
+ expression,
+ relation,
+ result,
+ whitespace = makeRegexParser(/^\s+/),
+ value = makeRegexParser(/^\d+/),
+ _n_ = makeStringParser('n'),
+ _i_ = makeStringParser('i'),
+ _f_ = makeStringParser('f'),
+ _t_ = makeStringParser('t'),
+ _v_ = makeStringParser('v'),
+ _w_ = makeStringParser('w'),
+ _is_ = makeStringParser('is'),
+ _isnot_ = makeStringParser('is not'),
+ _isnot_sign_ = makeStringParser('!='),
+ _equal_ = makeStringParser('='),
+ _mod_ = makeStringParser('mod'),
+ _percent_ = makeStringParser('%'),
+ _not_ = makeStringParser('not'),
+ _in_ = makeStringParser('in'),
+ _within_ = makeStringParser('within'),
+ _range_ = makeStringParser('..'),
+ _comma_ = makeStringParser(','),
+ _or_ = makeStringParser('or'),
+ _and_ = makeStringParser('and');
+
+ function debug() {
+ // console.log.apply(console, arguments);
+ }
+
+ debug('pluralRuleParser', rule, number);
+
+ // Try parsers until one works, if none work return null
+ function choice(parserSyntax) {
+ return function() {
+ var i, result;
+
+ for (i = 0; i < parserSyntax.length; i++) {
+ result = parserSyntax[i]();
+
+ if (result !== null) {
+ return result;
+ }
+ }
+
+ return null;
+ };
+ }
+
+ // Try several parserSyntax-es in a row.
+ // All must succeed; otherwise, return null.
+ // This is the only eager one.
+ function sequence(parserSyntax) {
+ var i, parserRes,
+ originalPos = pos,
+ result = [];
+
+ for (i = 0; i < parserSyntax.length; i++) {
+ parserRes = parserSyntax[i]();
+
+ if (parserRes === null) {
+ pos = originalPos;
+
+ return null;
+ }
+
+ result.push(parserRes);
+ }
+
+ return result;
+ }
+
+ // Run the same parser over and over until it fails.
+ // Must succeed a minimum of n times; otherwise, return null.
+ function nOrMore(n, p) {
+ return function() {
+ var originalPos = pos,
+ result = [],
+ parsed = p();
+
+ while (parsed !== null) {
+ result.push(parsed);
+ parsed = p();
+ }
+
+ if (result.length < n) {
+ pos = originalPos;
+
+ return null;
+ }
+
+ return result;
+ };
+ }
+
+ // Helpers - just make parserSyntax out of simpler JS builtin types
+ function makeStringParser(s) {
+ var len = s.length;
+
+ return function() {
+ var result = null;
+
+ if (rule.substr(pos, len) === s) {
+ result = s;
+ pos += len;
+ }
+
+ return result;
+ };
+ }
+
+ function makeRegexParser(regex) {
+ return function() {
+ var matches = rule.substr(pos).match(regex);
+
+ if (matches === null) {
+ return null;
+ }
+
+ pos += matches[0].length;
+
+ return matches[0];
+ };
+ }
+
+ /**
+ * Integer digits of n.
+ */
+ function i() {
+ var result = _i_();
+
+ if (result === null) {
+ debug(' -- failed i', parseInt(number, 10));
+
+ return result;
+ }
+
+ result = parseInt(number, 10);
+ debug(' -- passed i ', result);
+
+ return result;
+ }
+
+ /**
+ * Absolute value of the source number (integer and decimals).
+ */
+ function n() {
+ var result = _n_();
+
+ if (result === null) {
+ debug(' -- failed n ', number);
+
+ return result;
+ }
+
+ result = parseFloat(number, 10);
+ debug(' -- passed n ', result);
+
+ return result;
+ }
+
+ /**
+ * Visible fractional digits in n, with trailing zeros.
+ */
+ function f() {
+ var result = _f_();
+
+ if (result === null) {
+ debug(' -- failed f ', number);
+
+ return result;
+ }
+
+ result = (number + '.').split('.')[1] || 0;
+ debug(' -- passed f ', result);
+
+ return result;
+ }
+
+ /**
+ * Visible fractional digits in n, without trailing zeros.
+ */
+ function t() {
+ var result = _t_();
+
+ if (result === null) {
+ debug(' -- failed t ', number);
+
+ return result;
+ }
+
+ result = (number + '.').split('.')[1].replace(/0$/, '') || 0;
+ debug(' -- passed t ', result);
+
+ return result;
+ }
+
+ /**
+ * Number of visible fraction digits in n, with trailing zeros.
+ */
+ function v() {
+ var result = _v_();
+
+ if (result === null) {
+ debug(' -- failed v ', number);
+
+ return result;
+ }
+
+ result = (number + '.').split('.')[1].length || 0;
+ debug(' -- passed v ', result);
+
+ return result;
+ }
+
+ /**
+ * Number of visible fraction digits in n, without trailing zeros.
+ */
+ function w() {
+ var result = _w_();
+
+ if (result === null) {
+ debug(' -- failed w ', number);
+
+ return result;
+ }
+
+ result = (number + '.').split('.')[1].replace(/0$/, '').length || 0;
+ debug(' -- passed w ', result);
+
+ return result;
+ }
+
+ // operand = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
+ operand = choice([n, i, f, t, v, w]);
+
+ // expr = operand (('mod' | '%') value)?
+ expression = choice([mod, operand]);
+
+ function mod() {
+ var result = sequence(
+ [operand, whitespace, choice([_mod_, _percent_]), whitespace, value]
+ );
+
+ if (result === null) {
+ debug(' -- failed mod');
+
+ return null;
+ }
+
+ debug(' -- passed ' + parseInt(result[0], 10) + ' ' + result[2] + ' ' + parseInt(result[4], 10));
+
+ return parseFloat(result[0]) % parseInt(result[4], 10);
+ }
+
+ function not() {
+ var result = sequence([whitespace, _not_]);
+
+ if (result === null) {
+ debug(' -- failed not');
+
+ return null;
+ }
+
+ return result[1];
+ }
+
+ // is_relation = expr 'is' ('not')? value
+ function is() {
+ var result = sequence([expression, whitespace, choice([_is_]), whitespace, value]);
+
+ if (result !== null) {
+ debug(' -- passed is : ' + result[0] + ' == ' + parseInt(result[4], 10));
+
+ return result[0] === parseInt(result[4], 10);
+ }
+
+ debug(' -- failed is');
+
+ return null;
+ }
+
+ // is_relation = expr 'is' ('not')? value
+ function isnot() {
+ var result = sequence(
+ [expression, whitespace, choice([_isnot_, _isnot_sign_]), whitespace, value]
+ );
+
+ if (result !== null) {
+ debug(' -- passed isnot: ' + result[0] + ' != ' + parseInt(result[4], 10));
+
+ return result[0] !== parseInt(result[4], 10);
+ }
+
+ debug(' -- failed isnot');
+
+ return null;
+ }
+
+ function not_in() {
+ var i, range_list,
+ result = sequence([expression, whitespace, _isnot_sign_, whitespace, rangeList]);
+
+ if (result !== null) {
+ debug(' -- passed not_in: ' + result[0] + ' != ' + result[4]);
+ range_list = result[4];
+
+ for (i = 0; i < range_list.length; i++) {
+ if (parseInt(range_list[i], 10) === parseInt(result[0], 10)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ debug(' -- failed not_in');
+
+ return null;
+ }
+
+ // range_list = (range | value) (',' range_list)*
+ function rangeList() {
+ var result = sequence([choice([range, value]), nOrMore(0, rangeTail)]),
+ resultList = [];
+
+ if (result !== null) {
+ resultList = resultList.concat(result[0]);
+
+ if (result[1][0]) {
+ resultList = resultList.concat(result[1][0]);
+ }
+
+ return resultList;
+ }
+
+ debug(' -- failed rangeList');
+
+ return null;
+ }
+
+ function rangeTail() {
+ // ',' range_list
+ var result = sequence([_comma_, rangeList]);
+
+ if (result !== null) {
+ return result[1];
+ }
+
+ debug(' -- failed rangeTail');
+
+ return null;
+ }
+
+ // range = value'..'value
+ function range() {
+ var i, array, left, right,
+ result = sequence([value, _range_, value]);
+
+ if (result !== null) {
+ debug(' -- passed range');
+
+ array = [];
+ left = parseInt(result[0], 10);
+ right = parseInt(result[2], 10);
+
+ for (i = left; i <= right; i++) {
+ array.push(i);
+ }
+
+ return array;
+ }
+
+ debug(' -- failed range');
+
+ return null;
+ }
+
+ function _in() {
+ var result, range_list, i;
+
+ // in_relation = expr ('not')? 'in' range_list
+ result = sequence(
+ [expression, nOrMore(0, not), whitespace, choice([_in_, _equal_]), whitespace, rangeList]
+ );
+
+ if (result !== null) {
+ debug(' -- passed _in:' + result);
+
+ range_list = result[5];
+
+ for (i = 0; i < range_list.length; i++) {
+ if (parseInt(range_list[i], 10) === parseFloat(result[0])) {
+ return (result[1][0] !== 'not');
+ }
+ }
+
+ return (result[1][0] === 'not');
+ }
+
+ debug(' -- failed _in ');
+
+ return null;
+ }
+
+ /**
+ * The difference between "in" and "within" is that
+ * "in" only includes integers in the specified range,
+ * while "within" includes all values.
+ */
+ function within() {
+ var range_list, result;
+
+ // within_relation = expr ('not')? 'within' range_list
+ result = sequence(
+ [expression, nOrMore(0, not), whitespace, _within_, whitespace, rangeList]
+ );
+
+ if (result !== null) {
+ debug(' -- passed within');
+
+ range_list = result[5];
+
+ if ((result[0] >= parseInt(range_list[0], 10)) &&
+ (result[0] < parseInt(range_list[range_list.length - 1], 10))) {
+
+ return (result[1][0] !== 'not');
+ }
+
+ return (result[1][0] === 'not');
+ }
+
+ debug(' -- failed within ');
+
+ return null;
+ }
+
+ // relation = is_relation | in_relation | within_relation
+ relation = choice([is, not_in, isnot, _in, within]);
+
+ // and_condition = relation ('and' relation)*
+ function and() {
+ var i,
+ result = sequence([relation, nOrMore(0, andTail)]);
+
+ if (result) {
+ if (!result[0]) {
+ return false;
+ }
+
+ for (i = 0; i < result[1].length; i++) {
+ if (!result[1][i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ debug(' -- failed and');
+
+ return null;
+ }
+
+ // ('and' relation)*
+ function andTail() {
+ var result = sequence([whitespace, _and_, whitespace, relation]);
+
+ if (result !== null) {
+ debug(' -- passed andTail' + result);
+
+ return result[3];
+ }
+
+ debug(' -- failed andTail');
+
+ return null;
+
+ }
+ // ('or' and_condition)*
+ function orTail() {
+ var result = sequence([whitespace, _or_, whitespace, and]);
+
+ if (result !== null) {
+ debug(' -- passed orTail: ' + result[3]);
+
+ return result[3];
+ }
+
+ debug(' -- failed orTail');
+
+ return null;
+ }
+
+ // condition = and_condition ('or' and_condition)*
+ function condition() {
+ var i,
+ result = sequence([and, nOrMore(0, orTail)]);
+
+ if (result) {
+ for (i = 0; i < result[1].length; i++) {
+ if (result[1][i]) {
+ return true;
+ }
+ }
+
+ return result[0];
+ }
+
+ return false;
+ }
+
+ result = condition();
+
+ /**
+ * For success, the pos must have gotten to the end of the rule
+ * and returned a non-null.
+ * n.b. This is part of language infrastructure,
+ * so we do not throw an internationalizable message.
+ */
+ if (result === null) {
+ throw new Error('Parse error at position ' + pos.toString() + ' for rule: ' + rule);
+ }
+
+ if (pos !== rule.length) {
+ debug('Warning: Rule not parsed completely. Parser stopped at ' + rule.substr(0, pos) + ' for rule: ' + rule);
+ }
+
+ return result;
+}
+
+return pluralRuleParser;
+
+}));
diff --git a/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.emitter.bidi.js b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.emitter.bidi.js
new file mode 100644
index 00000000..531f1365
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.emitter.bidi.js
@@ -0,0 +1,95 @@
+/*!
+ * BIDI embedding support for jQuery.i18n
+ *
+ * Copyright (C) 2015, David Chan
+ *
+ * This code is dual licensed GPLv2 or later and MIT. You don't have to do
+ * anything special to choose one license or the other and you don't have to
+ * notify anyone which license you are using. You are free to use this code
+ * in commercial projects as long as the copyright header is left intact.
+ * See files GPL-LICENSE and MIT-LICENSE for details.
+ *
+ * @licence GNU General Public Licence 2.0 or later
+ * @licence MIT License
+ */
+
+( function ( $ ) {
+ 'use strict';
+ var strongDirRegExp;
+
+ /**
+ * Matches the first strong directionality codepoint:
+ * - in group 1 if it is LTR
+ * - in group 2 if it is RTL
+ * Does not match if there is no strong directionality codepoint.
+ *
+ * Generated by UnicodeJS (see tools/strongDir) from the UCD; see
+ * https://phabricator.wikimedia.org/diffusion/GUJS/ .
+ */
+ // eslint-disable-next-line no-misleading-character-class
+ strongDirRegExp = new RegExp(
+ '(?:' +
+ '(' +
+ '[\u0041-\u005a\u0061-\u007a\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u02bb-\u02c1\u02d0\u02d1\u02e0-\u02e4\u02ee\u0370-\u0373\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0482\u048a-\u052f\u0531-\u0556\u0559-\u055f\u0561-\u0587\u0589\u0903-\u0939\u093b\u093d-\u0940\u0949-\u094c\u094e-\u0950\u0958-\u0961\u0964-\u0980\u0982\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd-\u09c0\u09c7\u09c8\u09cb\u09cc\u09ce\u09d7\u09dc\u09dd\u09df-\u09e1\u09e6-\u09f1\u09f4-\u09fa\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3e-\u0a40\u0a59-\u0a5c\u0a5e\u0a66-\u0a6f\u0a72-\u0a74\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd-\u0ac0\u0ac9\u0acb\u0acc\u0ad0\u0ae0\u0ae1\u0ae6-\u0af0\u0af9\u0b02\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b3e\u0b40\u0b47\u0b48\u0b4b\u0b4c\u0b57\u0b5c\u0b5d\u0b5f-\u0b61\u0b66-\u0b77\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe\u0bbf\u0bc1\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcc\u0bd0\u0bd7\u0be6-\u0bf2\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c41-\u0c44\u0c58-\u0c5a\u0c60\u0c61\u0c66-\u0c6f\u0c7f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd-\u0cc4\u0cc6-\u0cc8\u0cca\u0ccb\u0cd5\u0cd6\u0cde\u0ce0\u0ce1\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d40\u0d46-\u0d48\u0d4a-\u0d4c\u0d4e\u0d57\u0d5f-\u0d61\u0d66-\u0d75\u0d79-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dcf-\u0dd1\u0dd8-\u0ddf\u0de6-\u0def\u0df2-\u0df4\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e4f-\u0e5b\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0ed0-\u0ed9\u0edc-\u0edf\u0f00-\u0f17\u0f1a-\u0f34\u0f36\u0f38\u0f3e-\u0f47\u0f49-\u0f6c\u0f7f\u0f85\u0f88-\u0f8c\u0fbe-\u0fc5\u0fc7-\u0fcc\u0fce-\u0fda\u1000-\u102c\u1031\u1038\u103b\u103c\u103f-\u1057\u105a-\u105d\u1061-\u1070\u1075-\u1081\u1083\u1084\u1087-\u108c\u108e-\u109c\u109e-\u10c5\u10c7\u10cd\u10d0-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1360-\u137c\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u167f\u1681-\u169a\u16a0-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1735\u1736\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17b6\u17be-\u17c5\u17c7\u17c8\u17d4-\u17da\u17dc\u17e0-\u17e9\u1810-\u1819\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1923-\u1926\u1929-\u192b\u1930\u1931\u1933-\u1938\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19da\u1a00-\u1a16\u1a19\u1a1a\u1a1e-\u1a55\u1a57\u1a61\u1a63\u1a64\u1a6d-\u1a72\u1a80-\u1a89\u1a90-\u1a99\u1aa0-\u1aad\u1b04-\u1b33\u1b35\u1b3b\u1b3d-\u1b41\u1b43-\u1b4b\u1b50-\u1b6a\u1b74-\u1b7c\u1b82-\u1ba1\u1ba6\u1ba7\u1baa\u1bae-\u1be5\u1be7\u1bea-\u1bec\u1bee\u1bf2\u1bf3\u1bfc-\u1c2b\u1c34\u1c35\u1c3b-\u1c49\u1c4d-\u1c7f\u1cc0-\u1cc7\u1cd3\u1ce1\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200e\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u214f\u2160-\u2188\u2336-\u237a\u2395\u249c-\u24e9\u26ac\u2800-\u28ff\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d70\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u302e\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u3190-\u31ba\u31f0-\u321c\u3220-\u324f\u3260-\u327b\u327f-\u32b0\u32c0-\u32cb\u32d0-\u32fe\u3300-\u3376\u337b-\u33dd\u33e0-\u33fe\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua60c\ua610-\ua62b\ua640-\ua66e\ua680-\ua69d\ua6a0-\ua6ef\ua6f2-\ua6f7\ua722-\ua787\ua789-\ua7ad\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua824\ua827\ua830-\ua837\ua840-\ua873\ua880-\ua8c3\ua8ce-\ua8d9\ua8f2-\ua8fd\ua900-\ua925\ua92e-\ua946\ua952\ua953\ua95f-\ua97c\ua983-\ua9b2\ua9b4\ua9b5\ua9ba\ua9bb\ua9bd-\ua9cd\ua9cf-\ua9d9\ua9de-\ua9e4\ua9e6-\ua9fe\uaa00-\uaa28\uaa2f\uaa30\uaa33\uaa34\uaa40-\uaa42\uaa44-\uaa4b\uaa4d\uaa50-\uaa59\uaa5c-\uaa7b\uaa7d-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaaeb\uaaee-\uaaf5\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab65\uab70-\uabe4\uabe6\uabe7\uabe9-\uabec\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\ue000-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]|\ud800[\udc00-\udc0b]|\ud800[\udc0d-\udc26]|\ud800[\udc28-\udc3a]|\ud800\udc3c|\ud800\udc3d|\ud800[\udc3f-\udc4d]|\ud800[\udc50-\udc5d]|\ud800[\udc80-\udcfa]|\ud800\udd00|\ud800\udd02|\ud800[\udd07-\udd33]|\ud800[\udd37-\udd3f]|\ud800[\uddd0-\uddfc]|\ud800[\ude80-\ude9c]|\ud800[\udea0-\uded0]|\ud800[\udf00-\udf23]|\ud800[\udf30-\udf4a]|\ud800[\udf50-\udf75]|\ud800[\udf80-\udf9d]|\ud800[\udf9f-\udfc3]|\ud800[\udfc8-\udfd5]|\ud801[\udc00-\udc9d]|\ud801[\udca0-\udca9]|\ud801[\udd00-\udd27]|\ud801[\udd30-\udd63]|\ud801\udd6f|\ud801[\ude00-\udf36]|\ud801[\udf40-\udf55]|\ud801[\udf60-\udf67]|\ud804\udc00|\ud804[\udc02-\udc37]|\ud804[\udc47-\udc4d]|\ud804[\udc66-\udc6f]|\ud804[\udc82-\udcb2]|\ud804\udcb7|\ud804\udcb8|\ud804[\udcbb-\udcc1]|\ud804[\udcd0-\udce8]|\ud804[\udcf0-\udcf9]|\ud804[\udd03-\udd26]|\ud804\udd2c|\ud804[\udd36-\udd43]|\ud804[\udd50-\udd72]|\ud804[\udd74-\udd76]|\ud804[\udd82-\uddb5]|\ud804[\uddbf-\uddc9]|\ud804\uddcd|\ud804[\uddd0-\udddf]|\ud804[\udde1-\uddf4]|\ud804[\ude00-\ude11]|\ud804[\ude13-\ude2e]|\ud804\ude32|\ud804\ude33|\ud804\ude35|\ud804[\ude38-\ude3d]|\ud804[\ude80-\ude86]|\ud804\ude88|\ud804[\ude8a-\ude8d]|\ud804[\ude8f-\ude9d]|\ud804[\ude9f-\udea9]|\ud804[\udeb0-\udede]|\ud804[\udee0-\udee2]|\ud804[\udef0-\udef9]|\ud804\udf02|\ud804\udf03|\ud804[\udf05-\udf0c]|\ud804\udf0f|\ud804\udf10|\ud804[\udf13-\udf28]|\ud804[\udf2a-\udf30]|\ud804\udf32|\ud804\udf33|\ud804[\udf35-\udf39]|\ud804[\udf3d-\udf3f]|\ud804[\udf41-\udf44]|\ud804\udf47|\ud804\udf48|\ud804[\udf4b-\udf4d]|\ud804\udf50|\ud804\udf57|\ud804[\udf5d-\udf63]|\ud805[\udc80-\udcb2]|\ud805\udcb9|\ud805[\udcbb-\udcbe]|\ud805\udcc1|\ud805[\udcc4-\udcc7]|\ud805[\udcd0-\udcd9]|\ud805[\udd80-\uddb1]|\ud805[\uddb8-\uddbb]|\ud805\uddbe|\ud805[\uddc1-\udddb]|\ud805[\ude00-\ude32]|\ud805\ude3b|\ud805\ude3c|\ud805\ude3e|\ud805[\ude41-\ude44]|\ud805[\ude50-\ude59]|\ud805[\ude80-\udeaa]|\ud805\udeac|\ud805\udeae|\ud805\udeaf|\ud805\udeb6|\ud805[\udec0-\udec9]|\ud805[\udf00-\udf19]|\ud805\udf20|\ud805\udf21|\ud805\udf26|\ud805[\udf30-\udf3f]|\ud806[\udca0-\udcf2]|\ud806\udcff|\ud806[\udec0-\udef8]|\ud808[\udc00-\udf99]|\ud809[\udc00-\udc6e]|\ud809[\udc70-\udc74]|\ud809[\udc80-\udd43]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud811[\udc00-\ude46]|\ud81a[\udc00-\ude38]|\ud81a[\ude40-\ude5e]|\ud81a[\ude60-\ude69]|\ud81a\ude6e|\ud81a\ude6f|\ud81a[\uded0-\udeed]|\ud81a\udef5|\ud81a[\udf00-\udf2f]|\ud81a[\udf37-\udf45]|\ud81a[\udf50-\udf59]|\ud81a[\udf5b-\udf61]|\ud81a[\udf63-\udf77]|\ud81a[\udf7d-\udf8f]|\ud81b[\udf00-\udf44]|\ud81b[\udf50-\udf7e]|\ud81b[\udf93-\udf9f]|\ud82c\udc00|\ud82c\udc01|\ud82f[\udc00-\udc6a]|\ud82f[\udc70-\udc7c]|\ud82f[\udc80-\udc88]|\ud82f[\udc90-\udc99]|\ud82f\udc9c|\ud82f\udc9f|\ud834[\udc00-\udcf5]|\ud834[\udd00-\udd26]|\ud834[\udd29-\udd66]|\ud834[\udd6a-\udd72]|\ud834\udd83|\ud834\udd84|\ud834[\udd8c-\udda9]|\ud834[\uddae-\udde8]|\ud834[\udf60-\udf71]|\ud835[\udc00-\udc54]|\ud835[\udc56-\udc9c]|\ud835\udc9e|\ud835\udc9f|\ud835\udca2|\ud835\udca5|\ud835\udca6|\ud835[\udca9-\udcac]|\ud835[\udcae-\udcb9]|\ud835\udcbb|\ud835[\udcbd-\udcc3]|\ud835[\udcc5-\udd05]|\ud835[\udd07-\udd0a]|\ud835[\udd0d-\udd14]|\ud835[\udd16-\udd1c]|\ud835[\udd1e-\udd39]|\ud835[\udd3b-\udd3e]|\ud835[\udd40-\udd44]|\ud835\udd46|\ud835[\udd4a-\udd50]|\ud835[\udd52-\udea5]|\ud835[\udea8-\udeda]|\ud835[\udedc-\udf14]|\ud835[\udf16-\udf4e]|\ud835[\udf50-\udf88]|\ud835[\udf8a-\udfc2]|\ud835[\udfc4-\udfcb]|\ud836[\udc00-\uddff]|\ud836[\ude37-\ude3a]|\ud836[\ude6d-\ude74]|\ud836[\ude76-\ude83]|\ud836[\ude85-\ude8b]|\ud83c[\udd10-\udd2e]|\ud83c[\udd30-\udd69]|\ud83c[\udd70-\udd9a]|\ud83c[\udde6-\ude02]|\ud83c[\ude10-\ude3a]|\ud83c[\ude40-\ude48]|\ud83c\ude50|\ud83c\ude51|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6]|\ud869[\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34]|\ud86d[\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud86e[\udc20-\udfff]|[\ud86f-\ud872][\udc00-\udfff]|\ud873[\udc00-\udea1]|\ud87e[\udc00-\ude1d]|[\udb80-\udbbe][\udc00-\udfff]|\udbbf[\udc00-\udffd]|[\udbc0-\udbfe][\udc00-\udfff]|\udbff[\udc00-\udffd]' +
+ ')|(' +
+ '[\u0590\u05be\u05c0\u05c3\u05c6\u05c8-\u05ff\u07c0-\u07ea\u07f4\u07f5\u07fa-\u0815\u081a\u0824\u0828\u082e-\u0858\u085c-\u089f\u200f\ufb1d\ufb1f-\ufb28\ufb2a-\ufb4f\u0608\u060b\u060d\u061b-\u064a\u066d-\u066f\u0671-\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u0710\u0712-\u072f\u074b-\u07a5\u07b1-\u07bf\u08a0-\u08e2\ufb50-\ufd3d\ufd40-\ufdcf\ufdf0-\ufdfc\ufdfe\ufdff\ufe70-\ufefe]|\ud802[\udc00-\udd1e]|\ud802[\udd20-\ude00]|\ud802\ude04|\ud802[\ude07-\ude0b]|\ud802[\ude10-\ude37]|\ud802[\ude3b-\ude3e]|\ud802[\ude40-\udee4]|\ud802[\udee7-\udf38]|\ud802[\udf40-\udfff]|\ud803[\udc00-\ude5f]|\ud803[\ude7f-\udfff]|\ud83a[\udc00-\udccf]|\ud83a[\udcd7-\udfff]|\ud83b[\udc00-\uddff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\ude00-\udeef]|\ud83b[\udef2-\udeff]' +
+ ')' +
+ ')'
+ );
+
+ /**
+ * Gets directionality of the first strongly directional codepoint
+ *
+ * This is the rule the BIDI algorithm uses to determine the directionality of
+ * paragraphs ( http://unicode.org/reports/tr9/#The_Paragraph_Level ) and
+ * FSI isolates ( http://unicode.org/reports/tr9/#Explicit_Directional_Isolates ).
+ *
+ * TODO: Does not handle BIDI control characters inside the text.
+ * TODO: Does not handle unallocated characters.
+ *
+ * @param {string} text The text from which to extract initial directionality.
+ * @return {string} Directionality (either 'ltr' or 'rtl')
+ */
+ function strongDirFromContent( text ) {
+ var m = text.match( strongDirRegExp );
+ if ( !m ) {
+ return null;
+ }
+ if ( m[ 2 ] === undefined ) {
+ return 'ltr';
+ }
+ return 'rtl';
+ }
+
+ $.extend( $.i18n.parser.emitter, {
+ /**
+ * Wraps argument with unicode control characters for directionality safety
+ *
+ * This solves the problem where directionality-neutral characters at the edge of
+ * the argument string get interpreted with the wrong directionality from the
+ * enclosing context, giving renderings that look corrupted like "(Ben_(WMF".
+ *
+ * The wrapping is LRE...PDF or RLE...PDF, depending on the detected
+ * directionality of the argument string, using the BIDI algorithm's own "First
+ * strong directional codepoint" rule. Essentially, this works round the fact that
+ * there is no embedding equivalent of U+2068 FSI (isolation with heuristic
+ * direction inference). The latter is cleaner but still not widely supported.
+ *
+ * @param {string[]} nodes The text nodes from which to take the first item.
+ * @return {string} Wrapped String of content as needed.
+ */
+ bidi: function ( nodes ) {
+ var dir = strongDirFromContent( nodes[ 0 ] );
+ if ( dir === 'ltr' ) {
+ // Wrap in LEFT-TO-RIGHT EMBEDDING ... POP DIRECTIONAL FORMATTING
+ return '\u202A' + nodes[ 0 ] + '\u202C';
+ }
+ if ( dir === 'rtl' ) {
+ // Wrap in RIGHT-TO-LEFT EMBEDDING ... POP DIRECTIONAL FORMATTING
+ return '\u202B' + nodes[ 0 ] + '\u202C';
+ }
+ // No strong directionality: do not wrap
+ return nodes[ 0 ];
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n.emitter.js b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.emitter.js
similarity index 78%
rename from assets/webconfig/js/lib/jquery.i18n.emitter.js
rename to assets/webconfig/js/lib/jquery.i18n/jquery.i18n.emitter.js
index b26f147d..330e50c5 100644
--- a/assets/webconfig/js/lib/jquery.i18n.emitter.js
+++ b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.emitter.js
@@ -1,4 +1,4 @@
-/**
+/*!
* jQuery Internationalization library
*
* Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
@@ -17,7 +17,7 @@
'use strict';
var MessageParserEmitter = function () {
- this.language = $.i18n.languages[String.locale] || $.i18n.languages['default'];
+ this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ];
};
MessageParserEmitter.prototype = {
@@ -38,36 +38,36 @@
messageParserEmitter = this;
switch ( typeof node ) {
- case 'string':
- case 'number':
- ret = node;
- break;
- case 'object':
+ case 'string':
+ case 'number':
+ ret = node;
+ break;
+ case 'object':
// node is an array of nodes
- subnodes = $.map( node.slice( 1 ), function ( n ) {
- return messageParserEmitter.emit( n, replacements );
- } );
+ subnodes = $.map( node.slice( 1 ), function ( n ) {
+ return messageParserEmitter.emit( n, replacements );
+ } );
- operation = node[0].toLowerCase();
+ operation = node[ 0 ].toLowerCase();
- if ( typeof messageParserEmitter[operation] === 'function' ) {
- ret = messageParserEmitter[operation]( subnodes, replacements );
- } else {
- throw new Error( 'unknown operation "' + operation + '"' );
- }
+ if ( typeof messageParserEmitter[ operation ] === 'function' ) {
+ ret = messageParserEmitter[ operation ]( subnodes, replacements );
+ } else {
+ throw new Error( 'unknown operation "' + operation + '"' );
+ }
- break;
- case 'undefined':
+ break;
+ case 'undefined':
// Parsing the empty string (as an entire expression, or as a
// paramExpression in a template) results in undefined
// Perhaps a more clever parser can detect this, and return the
// empty string? Or is that useful information?
// The logical thing is probably to return the empty string here
// when we encounter undefined.
- ret = '';
- break;
- default:
- throw new Error( 'unexpected type in AST: ' + typeof node );
+ ret = '';
+ break;
+ default:
+ throw new Error( 'unexpected type in AST: ' + typeof node );
}
return ret;
@@ -80,7 +80,7 @@
* in our children and pass them upwards
*
* @param {Array} nodes Mixed, some single nodes, some arrays of nodes.
- * @return String
+ * @return {string}
*/
concat: function ( nodes ) {
var result = '';
@@ -106,11 +106,11 @@
* @return {string} replacement
*/
replace: function ( nodes, replacements ) {
- var index = parseInt( nodes[0], 10 );
+ var index = parseInt( nodes[ 0 ], 10 );
if ( index < replacements.length ) {
// replacement is not a string, don't touch!
- return replacements[index];
+ return replacements[ index ];
} else {
// index not found, fallback to displaying variable
return '$' + ( index + 1 );
@@ -124,11 +124,11 @@
* convertNumber.
*
* @param {Array} nodes List [ {String|Number}, {String}, {String} ... ]
- * @return {String} selected pluralized form according to current
+ * @return {string} selected pluralized form according to current
* language.
*/
plural: function ( nodes ) {
- var count = parseFloat( this.language.convertNumber( nodes[0], 10 ) ),
+ var count = parseFloat( this.language.convertNumber( nodes[ 0 ], 10 ) ),
forms = nodes.slice( 1 );
return forms.length ? this.language.convertPlural( count, forms ) : '';
@@ -139,10 +139,10 @@
* {{gender:gender|masculine|feminine|neutral}}.
*
* @param {Array} nodes List [ {String}, {String}, {String} , {String} ]
- * @return {String} selected gender form according to current language
+ * @return {string} selected gender form according to current language
*/
gender: function ( nodes ) {
- var gender = nodes[0],
+ var gender = nodes[ 0 ],
forms = nodes.slice( 1 );
return this.language.gender( gender, forms );
@@ -153,12 +153,12 @@
* putting {{grammar:form|word}} in a message
*
* @param {Array} nodes List [{Grammar case eg: genitive}, {String word}]
- * @return {String} selected grammatical form according to current
+ * @return {string} selected grammatical form according to current
* language.
*/
grammar: function ( nodes ) {
- var form = nodes[0],
- word = nodes[1];
+ var form = nodes[ 0 ],
+ word = nodes[ 1 ];
return word && form && this.language.convertGrammar( word, form );
}
diff --git a/assets/webconfig/js/lib/jquery.i18n.fallbacks.js b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.fallbacks.js
similarity index 98%
rename from assets/webconfig/js/lib/jquery.i18n.fallbacks.js
rename to assets/webconfig/js/lib/jquery.i18n/jquery.i18n.fallbacks.js
index e5bcbc19..74b16f22 100644
--- a/assets/webconfig/js/lib/jquery.i18n.fallbacks.js
+++ b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.fallbacks.js
@@ -1,4 +1,4 @@
-/**
+/*!
* jQuery Internationalization library
*
* Copyright (C) 2012 Santhosh Thottingal
@@ -11,7 +11,7 @@
* @licence GNU General Public Licence 2.0 or later
* @licence MIT License
*/
-( function ( $, undefined ) {
+( function ( $ ) {
'use strict';
$.i18n = $.i18n || {};
@@ -45,7 +45,6 @@
'crh-cyrl': [ 'ru' ],
csb: [ 'pl' ],
cv: [ 'ru' ],
- 'de-DE': [ 'de' ],
'de-at': [ 'de' ],
'de-ch': [ 'de' ],
'de-formal': [ 'de' ],
diff --git a/assets/webconfig/js/lib/jquery.i18n.js b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.js
similarity index 66%
rename from assets/webconfig/js/lib/jquery.i18n.js
rename to assets/webconfig/js/lib/jquery.i18n/jquery.i18n.js
index 32d9b10d..d6c0bae6 100644
--- a/assets/webconfig/js/lib/jquery.i18n.js
+++ b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.js
@@ -1,4 +1,4 @@
-/**
+/*!
* jQuery Internationalization library
*
* Copyright (C) 2012 Santhosh Thottingal
@@ -16,7 +16,7 @@
( function ( $ ) {
'use strict';
- var nav, I18N,
+ var I18N,
slice = Array.prototype.slice;
/**
* @constructor
@@ -30,61 +30,52 @@
this.locale = this.options.locale;
this.messageStore = this.options.messageStore;
this.languages = {};
-
- this.init();
};
I18N.prototype = {
/**
- * Initialize by loading locales and setting up
- * String.prototype.toLocaleString and String.locale.
+ * Localize a given messageKey to a locale.
+ * @param {string} messageKey
+ * @return {string} Localized message
*/
- init: function () {
- var i18n = this;
+ localize: function ( messageKey ) {
+ var localeParts, localePartIndex, locale, fallbackIndex,
+ tryingLocale, message;
- // Set locale of String environment
- String.locale = i18n.locale;
+ locale = this.locale;
+ fallbackIndex = 0;
- // Override String.localeString method
- String.prototype.toLocaleString = function () {
- var localeParts, localePartIndex, value, locale, fallbackIndex,
- tryingLocale, message;
+ while ( locale ) {
+ // Iterate through locales starting at most-specific until
+ // localization is found. As in fi-Latn-FI, fi-Latn and fi.
+ localeParts = locale.split( '-' );
+ localePartIndex = localeParts.length;
- value = this.valueOf();
- locale = i18n.locale;
- fallbackIndex = 0;
+ do {
+ tryingLocale = localeParts.slice( 0, localePartIndex ).join( '-' );
+ message = this.messageStore.get( tryingLocale, messageKey );
- while ( locale ) {
- // Iterate through locales starting at most-specific until
- // localization is found. As in fi-Latn-FI, fi-Latn and fi.
- localeParts = locale.split( '-' );
- localePartIndex = localeParts.length;
-
- do {
- tryingLocale = localeParts.slice( 0, localePartIndex ).join( '-' );
- message = i18n.messageStore.get( tryingLocale, value );
-
- if ( message ) {
- return message;
- }
-
- localePartIndex--;
- } while ( localePartIndex );
-
- if ( locale === 'en' ) {
- break;
+ if ( message ) {
+ return message;
}
- locale = ( $.i18n.fallbacks[i18n.locale] && $.i18n.fallbacks[i18n.locale][fallbackIndex] ) ||
- i18n.options.fallbackLocale;
- $.i18n.log( 'Trying fallback locale for ' + i18n.locale + ': ' + locale );
+ localePartIndex--;
+ } while ( localePartIndex );
- fallbackIndex++;
+ if ( locale === this.options.fallbackLocale ) {
+ break;
}
- // key not found
- return '';
- };
+ locale = ( $.i18n.fallbacks[ this.locale ] &&
+ $.i18n.fallbacks[ this.locale ][ fallbackIndex ] ) ||
+ this.options.fallbackLocale;
+ $.i18n.log( 'Trying fallback locale for ' + this.locale + ': ' + locale + ' (' + messageKey + ')' );
+
+ fallbackIndex++;
+ }
+
+ // key not found
+ return '';
},
/*
@@ -132,26 +123,28 @@
* If the data argument is null/undefined/false,
* all cached messages for the i18n instance will get reset.
*
- * @param {String|Object} source
- * @param {String} locale Language tag
- * @returns {jQuery.Promise}
+ * @param {string|Object} source
+ * @param {string} locale Language tag
+ * @return {jQuery.Promise}
*/
load: function ( source, locale ) {
var fallbackLocales, locIndex, fallbackLocale, sourceMap = {};
if ( !source && !locale ) {
- source = 'i18n';
+ source = 'i18n/' + $.i18n().locale + '.json';
locale = $.i18n().locale;
}
- if ( typeof source === 'string' &&
- source.split( '.' ).pop() !== 'json'
+ if ( typeof source === 'string' &&
+ // source extension should be json, but can have query params after that.
+ source.split( '?' )[ 0 ].split( '.' ).pop() !== 'json'
) {
- // Load specified locale then check for fallbacks when directory is specified in load()
- sourceMap[locale] = source + '/' + locale + '.json';
- fallbackLocales = ( $.i18n.fallbacks[locale] || [] )
+ // Load specified locale then check for fallbacks when directory is
+ // specified in load()
+ sourceMap[ locale ] = source + '/' + locale + '.json';
+ fallbackLocales = ( $.i18n.fallbacks[ locale ] || [] )
.concat( this.options.fallbackLocale );
- for ( locIndex in fallbackLocales ) {
- fallbackLocale = fallbackLocales[locIndex];
- sourceMap[fallbackLocale] = source + '/' + fallbackLocale + '.json';
+ for ( locIndex = 0; locIndex < fallbackLocales.length; locIndex++ ) {
+ fallbackLocale = fallbackLocales[ locIndex ];
+ sourceMap[ fallbackLocale ] = source + '/' + fallbackLocale + '.json';
}
return this.load( sourceMap );
} else {
@@ -168,11 +161,11 @@
* @return {string}
*/
parse: function ( key, parameters ) {
- var message = key.toLocaleString();
+ var message = this.localize( key );
// FIXME: This changes the state of the I18N object,
// should probably not change the 'this.parser' but just
// pass it to the parser.
- this.parser.language = $.i18n.languages[$.i18n().locale] || $.i18n.languages['default'];
+ this.parser.language = $.i18n.languages[ $.i18n().locale ] || $.i18n.languages[ 'default' ];
if ( message === '' ) {
message = key;
}
@@ -202,7 +195,7 @@
// NOTE: It should only change language for this one call.
// Then cache instances of I18N somewhere.
if ( options && options.locale && i18n && i18n.locale !== options.locale ) {
- String.locale = i18n.locale = options.locale;
+ i18n.locale = options.locale;
}
if ( !i18n ) {
@@ -231,28 +224,38 @@
i18n = new I18N();
$.data( document, 'i18n', i18n );
}
- String.locale = i18n.locale;
+
return this.each( function () {
var $this = $( this ),
- messageKey = $this.data( 'i18n' );
+ messageKey = $this.data( 'i18n' ),
+ lBracket, rBracket, type, key;
if ( messageKey ) {
- $this.text( i18n.parse( messageKey ) );
+ lBracket = messageKey.indexOf( '[' );
+ rBracket = messageKey.indexOf( ']' );
+ if ( lBracket !== -1 && rBracket !== -1 && lBracket < rBracket ) {
+ type = messageKey.slice( lBracket + 1, rBracket );
+ key = messageKey.slice( rBracket + 1 );
+ if ( type === 'html' ) {
+ $this.html( i18n.parse( key ) );
+ } else {
+ $this.attr( type, i18n.parse( key ) );
+ }
+ } else {
+ $this.text( i18n.parse( messageKey ) );
+ }
} else {
$this.find( '[data-i18n]' ).i18n();
}
} );
};
- String.locale = String.locale || $( 'html' ).attr( 'lang' );
-
- if ( !String.locale ) {
- if ( typeof window.navigator !== 'undefined' ) {
- nav = window.navigator;
- String.locale = nav.language || nav.userLanguage || '';
- } else {
- String.locale = '';
+ function getDefaultLocale() {
+ var locale = $( 'html' ).attr( 'lang' );
+ if ( !locale ) {
+ locale = navigator.language || navigator.userLanguage || '';
}
+ return locale;
}
$.i18n.languages = {};
@@ -262,7 +265,7 @@
parse: function ( message, parameters ) {
return message.replace( /\$(\d+)/g, function ( str, match ) {
var index = parseInt( match, 10 ) - 1;
- return parameters[index] !== undefined ? parameters[index] : '$' + match;
+ return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
} );
},
emitter: {}
@@ -276,7 +279,7 @@
};
/* Static members */
I18N.defaults = {
- locale: String.locale,
+ locale: getDefaultLocale(),
fallbackLocale: 'en',
parser: $.i18n.parser,
messageStore: $.i18n.messageStore
diff --git a/assets/webconfig/js/lib/jquery.i18n.language.js b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.language.js
similarity index 74%
rename from assets/webconfig/js/lib/jquery.i18n.language.js
rename to assets/webconfig/js/lib/jquery.i18n/jquery.i18n.language.js
index be413924..f905aa8f 100644
--- a/assets/webconfig/js/lib/jquery.i18n.language.js
+++ b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.language.js
@@ -1,7 +1,8 @@
-/*global pluralRuleParser */
+/* global pluralRuleParser */
( function ( $ ) {
'use strict';
+ // jscs:disable
var language = {
// CLDR plural rules generated using
// libs/CLDRPluralRuleParser/tools/PluralXML2JSON.html
@@ -19,6 +20,16 @@
few: 'n % 100 = 3..10',
many: 'n % 100 = 11..99'
},
+ ars: {
+ zero: 'n = 0',
+ one: 'n = 1',
+ two: 'n = 2',
+ few: 'n % 100 = 3..10',
+ many: 'n % 100 = 11..99'
+ },
+ as: {
+ one: 'i = 0 or n = 1'
+ },
be: {
one: 'n % 10 = 1 and n % 100 != 11',
few: 'n % 10 = 2..4 and n % 100 != 12..14',
@@ -55,6 +66,11 @@
da: {
one: 'n = 1 or t != 0 and i = 0,1'
},
+ dsb: {
+ one: 'v = 0 and i % 100 = 1 or f % 100 = 1',
+ two: 'v = 0 and i % 100 = 2 or f % 100 = 2',
+ few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4'
+ },
fa: {
one: 'i = 0 or n = 1'
},
@@ -62,7 +78,7 @@
one: 'i = 0,1'
},
fil: {
- one: 'i = 0..1 and v = 0'
+ one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9'
},
fr: {
one: 'i = 0,1'
@@ -85,9 +101,10 @@
one: 'n = 0..1'
},
gv: {
- one: 'n % 10 = 1',
- two: 'n % 10 = 2',
- few: 'n % 100 = 0,20,40,60'
+ one: 'v = 0 and i % 10 = 1',
+ two: 'v = 0 and i % 10 = 2',
+ few: 'v = 0 and i % 100 = 0,20,40,60,80',
+ many: 'v != 0'
},
he: {
one: 'i = 1 and v = 0',
@@ -101,6 +118,11 @@
one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
},
+ hsb: {
+ one: 'v = 0 and i % 100 = 1 or f % 100 = 1',
+ two: 'v = 0 and i % 100 = 2 or f % 100 = 2',
+ few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4'
+ },
hy: {
one: 'i = 0,1'
},
@@ -175,20 +197,20 @@
few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
many: 'v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14'
},
+ prg: {
+ zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19',
+ one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1'
+ },
pt: {
- one: 'i = 1 and v = 0 or i = 0 and t = 1'
+ one: 'i = 0..1'
},
- // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
- pt_PT: {
- one: 'n = 1 and v = 0'
- },
- // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
ro: {
one: 'i = 1 and v = 0',
few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
},
ru: {
one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
+ few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
},
se: {
@@ -244,7 +266,7 @@
one: 'n = 0..1'
},
tl: {
- one: 'i = 0..1 and v = 0'
+ one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9'
},
tzm: {
one: 'n = 0..1 or n = 11..99'
@@ -261,21 +283,22 @@
one: 'i = 0 or n = 1'
}
},
+ // jscs:enable
/**
* Plural form transformations, needed for some languages.
*
- * @param count
- * integer Non-localized quantifier
- * @param forms
- * array List of plural forms
- * @return string Correct form for quantifier in this language
+ * @param {integer} count
+ * Non-localized quantifier
+ * @param {Array} forms
+ * List of plural forms
+ * @return {string} Correct form for quantifier in this language
*/
convertPlural: function ( count, forms ) {
var pluralRules,
pluralFormIndex,
index,
- explicitPluralPattern = new RegExp( '\\d+=', 'i' ),
+ explicitPluralPattern = /\d+=/i,
formCount,
form;
@@ -285,13 +308,13 @@
// Handle for Explicit 0= & 1= values
for ( index = 0; index < forms.length; index++ ) {
- form = forms[index];
+ form = forms[ index ];
if ( explicitPluralPattern.test( form ) ) {
- formCount = parseInt( form.substring( 0, form.indexOf( '=' ) ), 10 );
+ formCount = parseInt( form.slice( 0, form.indexOf( '=' ) ), 10 );
if ( formCount === count ) {
- return ( form.substr( form.indexOf( '=' ) + 1 ) );
+ return ( form.slice( form.indexOf( '=' ) + 1 ) );
}
- forms[index] = undefined;
+ forms[ index ] = undefined;
}
}
@@ -301,25 +324,25 @@
}
} );
- pluralRules = this.pluralRules[$.i18n().locale];
+ pluralRules = this.pluralRules[ $.i18n().locale ];
if ( !pluralRules ) {
// default fallback.
- return ( count === 1 ) ? forms[0] : forms[1];
+ return ( count === 1 ) ? forms[ 0 ] : forms[ 1 ];
}
pluralFormIndex = this.getPluralForm( count, pluralRules );
pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 );
- return forms[pluralFormIndex];
+ return forms[ pluralFormIndex ];
},
/**
* For the number, get the plural for index
*
- * @param number
- * @param pluralRules
- * @return plural form index
+ * @param {integer} number
+ * @param {Object} pluralRules
+ * @return {integer} plural form index
*/
getPluralForm: function ( number, pluralRules ) {
var i,
@@ -327,8 +350,8 @@
pluralFormIndex = 0;
for ( i = 0; i < pluralForms.length; i++ ) {
- if ( pluralRules[pluralForms[i]] ) {
- if ( pluralRuleParser( pluralRules[pluralForms[i]], number ) ) {
+ if ( pluralRules[ pluralForms[ i ] ] ) {
+ if ( pluralRuleParser( pluralRules[ pluralForms[ i ] ], number ) ) {
return pluralFormIndex;
}
@@ -344,6 +367,7 @@
*
* @param {number} num Value to be converted
* @param {boolean} integer Convert the return value to an integer
+ * @return {string} The number converted into a String.
*/
convertNumber: function ( num, integer ) {
var tmp, item, i,
@@ -360,28 +384,28 @@
// Check if the restore to Latin number flag is set:
if ( integer ) {
- if ( parseFloat( num ) === num ) {
+ if ( parseFloat( num, 10 ) === num ) {
return num;
}
tmp = [];
for ( item in transformTable ) {
- tmp[transformTable[item]] = item;
+ tmp[ transformTable[ item ] ] = item;
}
transformTable = tmp;
}
for ( i = 0; i < numberString.length; i++ ) {
- if ( transformTable[numberString[i]] ) {
- convertedNumber += transformTable[numberString[i]];
+ if ( transformTable[ numberString[ i ] ] ) {
+ convertedNumber += transformTable[ numberString[ i ] ];
} else {
- convertedNumber += numberString[i];
+ convertedNumber += numberString[ i ];
}
}
- return integer ? parseFloat( convertedNumber ) : convertedNumber;
+ return integer ? parseFloat( convertedNumber, 10 ) : convertedNumber;
},
/**
@@ -390,11 +414,12 @@
* Override this method for languages that need special grammar rules
* applied dynamically.
*
- * @param word {String}
- * @param form {String}
- * @return {String}
+ * @param {string} word
+ * @param {string} form
+ * @return {string}
*/
- convertGrammar: function ( word, form ) { /*jshint unused: false */
+ // eslint-disable-next-line no-unused-vars
+ convertGrammar: function ( word, form ) {
return word;
},
@@ -405,12 +430,12 @@
*
* These details may be overriden per language.
*
- * @param gender
- * string male, female, or anything else for neutral.
- * @param forms
- * array List of gender forms
+ * @param {string} gender
+ * male, female, or anything else for neutral.
+ * @param {Array} forms
+ * List of gender forms
*
- * @return string
+ * @return {string}
*/
gender: function ( gender, forms ) {
if ( !forms || forms.length === 0 ) {
@@ -418,25 +443,26 @@
}
while ( forms.length < 2 ) {
- forms.push( forms[forms.length - 1] );
+ forms.push( forms[ forms.length - 1 ] );
}
if ( gender === 'male' ) {
- return forms[0];
+ return forms[ 0 ];
}
if ( gender === 'female' ) {
- return forms[1];
+ return forms[ 1 ];
}
- return ( forms.length === 3 ) ? forms[2] : forms[0];
+ return ( forms.length === 3 ) ? forms[ 2 ] : forms[ 0 ];
},
/**
* Get the digit transform table for the given language
* See http://cldr.unicode.org/translation/numbering-systems
- * @param language
- * @returns {Array|boolean} List of digits in the passed language or false
+ *
+ * @param {string} language
+ * @return {Array|boolean} List of digits in the passed language or false
* representation, or boolean false if there is no information.
*/
digitTransformTable: function ( language ) {
@@ -448,6 +474,7 @@
lo: '໐໑໒໓໔໕໖໗໘໙',
or: '୦୧୨୩୪୫୬୭୮୯',
kh: '០១២៣៤៥៦៧៨៩',
+ nqo: '߀߁߂߃߄߅߆߇߈߉', // Note that the digits go right to left
pa: '੦੧੨੩੪੫੬੭੮੯',
gu: '૦૧૨૩૪૫૬૭૮૯',
hi: '०१२३४५६७८९',
@@ -458,15 +485,15 @@
bo: '༠༡༢༣༤༥༦༧༨༩' // FIXME use iso 639 codes
};
- if ( !tables[language] ) {
+ if ( !tables[ language ] ) {
return false;
}
- return tables[language].split( '' );
+ return tables[ language ].split( '' );
}
};
$.extend( $.i18n.languages, {
- 'default': language
+ default: language
} );
}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n.messagestore.js b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.messagestore.js
similarity index 80%
rename from assets/webconfig/js/lib/jquery.i18n.messagestore.js
rename to assets/webconfig/js/lib/jquery.i18n/jquery.i18n.messagestore.js
index 759295ce..ba81ce52 100644
--- a/assets/webconfig/js/lib/jquery.i18n.messagestore.js
+++ b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.messagestore.js
@@ -1,4 +1,4 @@
-/**
+/*!
* jQuery Internationalization library - Message Store
*
* Copyright (C) 2012 Santhosh Thottingal
@@ -12,7 +12,7 @@
* @licence MIT License
*/
-( function ( $, window, undefined ) {
+( function ( $ ) {
'use strict';
var MessageStore = function () {
@@ -20,6 +20,20 @@
this.sources = {};
};
+ function jsonMessageLoader( url ) {
+ var deferred = $.Deferred();
+
+ $.getJSON( url )
+ .done( deferred.resolve )
+ .fail( function ( jqxhr, settings, exception ) {
+ $.i18n.log( 'Error in loading messages from ' + url + ' Exception: ' + exception );
+ // Ignore 404 exception, because we are handling fallabacks explicitly
+ deferred.resolve();
+ } );
+
+ return deferred.promise();
+ }
+
/**
* See https://github.com/wikimedia/jquery.i18n/wiki/Specification#wiki-Message_File_Loading
*/
@@ -41,25 +55,22 @@
* null/undefined/false,
* all cached messages for the i18n instance will get reset.
*
- * @param {String|Object} source
- * @param {String} locale Language tag
+ * @param {string|Object} source
+ * @param {string} locale Language tag
* @return {jQuery.Promise}
*/
load: function ( source, locale ) {
var key = null,
- deferred = null,
deferreds = [],
messageStore = this;
if ( typeof source === 'string' ) {
// This is a URL to the messages file.
$.i18n.log( 'Loading messages from: ' + source );
- deferred = jsonMessageLoader( source )
- .done( function ( localization ) {
- messageStore.set( locale, localization );
+ return jsonMessageLoader( source )
+ .then( function ( localization ) {
+ return messageStore.load( localization, locale );
} );
-
- return deferred.promise();
}
if ( locale ) {
@@ -74,7 +85,7 @@
locale = key;
// No {locale} given, assume data is a group of languages,
// call this function again for each language.
- deferreds.push( messageStore.load( source[key], locale ) );
+ deferreds.push( messageStore.load( source[ key ], locale ) );
}
}
return $.when.apply( $, deferreds );
@@ -85,41 +96,28 @@
/**
* Set messages to the given locale.
* If locale exists, add messages to the locale.
- * @param locale
- * @param messages
+ *
+ * @param {string} locale
+ * @param {Object} messages
*/
set: function ( locale, messages ) {
- if ( !this.messages[locale] ) {
- this.messages[locale] = messages;
+ if ( !this.messages[ locale ] ) {
+ this.messages[ locale ] = messages;
} else {
- this.messages[locale] = $.extend( this.messages[locale], messages );
+ this.messages[ locale ] = $.extend( this.messages[ locale ], messages );
}
},
/**
*
- * @param locale
- * @param messageKey
- * @returns {Boolean}
+ * @param {string} locale
+ * @param {string} messageKey
+ * @return {boolean}
*/
get: function ( locale, messageKey ) {
- return this.messages[locale] && this.messages[locale][messageKey];
+ return this.messages[ locale ] && this.messages[ locale ][ messageKey ];
}
};
- function jsonMessageLoader( url ) {
- var deferred = $.Deferred();
-
- $.getJSON( url )
- .done( deferred.resolve )
- .fail( function ( jqxhr, settings, exception ) {
- $.i18n.log( 'Error in loading messages from ' + url + ' Exception: ' + exception );
- // Ignore 404 exception, because we are handling fallabacks explicitly
- deferred.resolve();
- } );
-
- return deferred.promise();
- }
-
$.extend( $.i18n.messageStore, new MessageStore() );
-}( jQuery, window ) );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n.parser.js b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.parser.js
similarity index 84%
rename from assets/webconfig/js/lib/jquery.i18n.parser.js
rename to assets/webconfig/js/lib/jquery.i18n/jquery.i18n.parser.js
index 3dea2842..8c47e55f 100644
--- a/assets/webconfig/js/lib/jquery.i18n.parser.js
+++ b/assets/webconfig/js/lib/jquery.i18n/jquery.i18n.parser.js
@@ -1,4 +1,4 @@
-/**
+/*!
* jQuery Internationalization library
*
* Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
@@ -18,7 +18,7 @@
var MessageParser = function ( options ) {
this.options = $.extend( {}, $.i18n.parser.defaults, options );
- this.language = $.i18n.languages[String.locale] || $.i18n.languages['default'];
+ this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ];
this.emitter = $.i18n.parser.emitter;
};
@@ -30,7 +30,7 @@
return message.replace( /\$(\d+)/g, function ( str, match ) {
var index = parseInt( match, 10 ) - 1;
- return parameters[index] !== undefined ? parameters[index] : '$' + match;
+ return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
} );
},
@@ -39,8 +39,8 @@
return this.simpleParse( message, replacements );
}
- this.emitter.language = $.i18n.languages[$.i18n().locale] ||
- $.i18n.languages['default'];
+ this.emitter.language = $.i18n.languages[ $.i18n().locale ] ||
+ $.i18n.languages[ 'default' ];
return this.emitter.emit( this.ast( message ), replacements );
},
@@ -58,7 +58,7 @@
var i, result;
for ( i = 0; i < parserSyntax.length; i++ ) {
- result = parserSyntax[i]();
+ result = parserSyntax[ i ]();
if ( result !== null ) {
return result;
@@ -78,7 +78,7 @@
result = [];
for ( i = 0; i < parserSyntax.length; i++ ) {
- res = parserSyntax[i]();
+ res = parserSyntax[ i ]();
if ( res === null ) {
pos = originalPos;
@@ -123,7 +123,7 @@
return function () {
var result = null;
- if ( message.substr( pos, len ) === s ) {
+ if ( message.slice( pos, pos + len ) === s ) {
result = s;
pos += len;
}
@@ -134,15 +134,15 @@
function makeRegexParser( regex ) {
return function () {
- var matches = message.substr( pos ).match( regex );
+ var matches = message.slice( pos ).match( regex );
if ( matches === null ) {
return null;
}
- pos += matches[0].length;
+ pos += matches[ 0 ].length;
- return matches[0];
+ return matches[ 0 ];
};
}
@@ -152,9 +152,9 @@
anyCharacter = makeRegexParser( /^./ );
dollar = makeStringParser( '$' );
digits = makeRegexParser( /^\d+/ );
- regularLiteral = makeRegexParser( /^[^{}\[\]$\\]/ );
- regularLiteralWithoutBar = makeRegexParser( /^[^{}\[\]$\\|]/ );
- regularLiteralWithoutSpace = makeRegexParser( /^[^{}\[\]$\s]/ );
+ regularLiteral = makeRegexParser( /^[^{}[\]$\\]/ );
+ regularLiteralWithoutBar = makeRegexParser( /^[^{}[\]$\\|]/ );
+ regularLiteralWithoutSpace = makeRegexParser( /^[^{}[\]$\s]/ );
// There is a general pattern:
// parse a thing;
@@ -189,7 +189,7 @@
function escapedLiteral() {
var result = sequence( [ backslash, anyCharacter ] );
- return result === null ? null : result[1];
+ return result === null ? null : result[ 1 ];
}
choice( [ escapedLiteral, regularLiteralWithoutSpace ] );
@@ -203,13 +203,13 @@
return null;
}
- return [ 'REPLACE', parseInt( result[1], 10 ) - 1 ];
+ return [ 'REPLACE', parseInt( result[ 1 ], 10 ) - 1 ];
}
templateName = transform(
// see $wgLegalTitleChars
// not allowing : due to the need to catch "PLURAL:$1"
- makeRegexParser( /^[ !"$&'()*,.\/0-9;=?@A-Z\^_`a-z~\x80-\xFF+\-]+/ ),
+ makeRegexParser( /^[ !"$&'()*,./0-9;=?@A-Z^_`a-z~\x80-\xFF+-]+/ ),
function ( result ) {
return result.toString();
@@ -224,23 +224,23 @@
return null;
}
- expr = result[1];
+ expr = result[ 1 ];
// use a "CONCAT" operator if there are multiple nodes,
// otherwise return the first node, raw.
- return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[0];
+ return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[ 0 ];
}
function templateWithReplacement() {
var result = sequence( [ templateName, colon, replacement ] );
- return result === null ? null : [ result[0], result[2] ];
+ return result === null ? null : [ result[ 0 ], result[ 2 ] ];
}
function templateWithOutReplacement() {
var result = sequence( [ templateName, colon, paramExpression ] );
- return result === null ? null : [ result[0], result[2] ];
+ return result === null ? null : [ result[ 0 ], result[ 2 ] ];
}
templateContents = choice( [
@@ -254,7 +254,7 @@
nOrMore( 0, templateParam )
] );
- return res === null ? null : res[0].concat( res[1] );
+ return res === null ? null : res[ 0 ].concat( res[ 1 ] );
},
function () {
var res = sequence( [ templateName, nOrMore( 0, templateParam ) ] );
@@ -263,7 +263,7 @@
return null;
}
- return [ res[0] ].concat( res[1] );
+ return [ res[ 0 ] ].concat( res[ 1 ] );
}
] );
@@ -273,7 +273,7 @@
function template() {
var result = sequence( [ openTemplate, templateContents, closeTemplate ] );
- return result === null ? null : result[1];
+ return result === null ? null : result[ 1 ];
}
expression = choice( [ template, replacement, literal ] );
@@ -294,7 +294,8 @@
/*
* For success, the pos must have gotten to the end of the input
* and returned a non-null.
- * n.b. This is part of language infrastructure, so we do not throw an internationalizable message.
+ * n.b. This is part of language infrastructure, so we do not throw an
+ * internationalizable message.
*/
if ( result === null || pos !== message.length ) {
throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + message );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/bs.js b/assets/webconfig/js/lib/jquery.i18n/languages/bs.js
new file mode 100644
index 00000000..41862ace
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/bs.js
@@ -0,0 +1,22 @@
+/**
+ * Bosnian (bosanski) language functions
+ */
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.bs = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ switch ( form ) {
+ case 'instrumental': // instrumental
+ word = 's ' + word;
+ break;
+ case 'lokativ': // locative
+ word = 'o ' + word;
+ break;
+ }
+
+ return word;
+ }
+ } );
+
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/dsb.js b/assets/webconfig/js/lib/jquery.i18n/languages/dsb.js
new file mode 100644
index 00000000..a1d33ac2
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/dsb.js
@@ -0,0 +1,22 @@
+/**
+ * Lower Sorbian (Dolnoserbski) language functions
+ */
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.dsb = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ switch ( form ) {
+ case 'instrumental': // instrumental
+ word = 'z ' + word;
+ break;
+ case 'lokatiw': // lokatiw
+ word = 'wo ' + word;
+ break;
+ }
+
+ return word;
+ }
+ } );
+
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/fi.js b/assets/webconfig/js/lib/jquery.i18n/languages/fi.js
new file mode 100644
index 00000000..34526016
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/fi.js
@@ -0,0 +1,49 @@
+/**
+ * Finnish (Suomi) language functions
+ *
+ * @author Santhosh Thottingal
+ */
+
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.fi = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ // vowel harmony flag
+ var aou = word.match( /[aou][^äöy]*$/i ),
+ origWord = word;
+ if ( word.match( /wiki$/i ) ) {
+ aou = false;
+ }
+
+ // append i after final consonant
+ if ( word.match( /[bcdfghjklmnpqrstvwxz]$/i ) ) {
+ word += 'i';
+ }
+
+ switch ( form ) {
+ case 'genitive':
+ word += 'n';
+ break;
+ case 'elative':
+ word += ( aou ? 'sta' : 'stä' );
+ break;
+ case 'partitive':
+ word += ( aou ? 'a' : 'ä' );
+ break;
+ case 'illative':
+ // Double the last letter and add 'n'
+ word += word.slice( -1 ) + 'n';
+ break;
+ case 'inessive':
+ word += ( aou ? 'ssa' : 'ssä' );
+ break;
+ default:
+ word = origWord;
+ break;
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/ga.js b/assets/webconfig/js/lib/jquery.i18n/languages/ga.js
new file mode 100644
index 00000000..843673a1
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/ga.js
@@ -0,0 +1,38 @@
+/**
+ * Irish (Gaeilge) language functions
+ */
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.ga = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ if ( form === 'ainmlae' ) {
+ switch ( word ) {
+ case 'an Domhnach':
+ word = 'Dé Domhnaigh';
+ break;
+ case 'an Luan':
+ word = 'Dé Luain';
+ break;
+ case 'an Mháirt':
+ word = 'Dé Mháirt';
+ break;
+ case 'an Chéadaoin':
+ word = 'Dé Chéadaoin';
+ break;
+ case 'an Déardaoin':
+ word = 'Déardaoin';
+ break;
+ case 'an Aoine':
+ word = 'Dé hAoine';
+ break;
+ case 'an Satharn':
+ word = 'Dé Sathairn';
+ break;
+ }
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/he.js b/assets/webconfig/js/lib/jquery.i18n/languages/he.js
new file mode 100644
index 00000000..b5934291
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/he.js
@@ -0,0 +1,31 @@
+/**
+ * Hebrew (עברית) language functions
+ */
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.he = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ switch ( form ) {
+ case 'prefixed':
+ case 'תחילית': // the same word in Hebrew
+ // Duplicate prefixed "Waw", but only if it's not already double
+ if ( word.slice( 0, 1 ) === 'ו' && word.slice( 0, 2 ) !== 'וו' ) {
+ word = 'ו' + word;
+ }
+
+ // Remove the "He" if prefixed
+ if ( word.slice( 0, 1 ) === 'ה' ) {
+ word = word.slice( 1 );
+ }
+
+ // Add a hyphen (maqaf) before numbers and non-Hebrew letters
+ if ( word.slice( 0, 1 ) < 'א' || word.slice( 0, 1 ) > 'ת' ) {
+ word = '־' + word;
+ }
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/hsb.js b/assets/webconfig/js/lib/jquery.i18n/languages/hsb.js
new file mode 100644
index 00000000..2beb8dee
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/hsb.js
@@ -0,0 +1,21 @@
+/**
+ * Upper Sorbian (Hornjoserbsce) language functions
+ */
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.hsb = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ switch ( form ) {
+ case 'instrumental': // instrumental
+ word = 'z ' + word;
+ break;
+ case 'lokatiw': // lokatiw
+ word = 'wo ' + word;
+ break;
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/hu.js b/assets/webconfig/js/lib/jquery.i18n/languages/hu.js
new file mode 100644
index 00000000..ec52f4c4
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/hu.js
@@ -0,0 +1,26 @@
+/**
+ * Hungarian language functions
+ *
+ * @author Santhosh Thottingal
+ */
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.hu = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ switch ( form ) {
+ case 'rol':
+ word += 'ról';
+ break;
+ case 'ba':
+ word += 'ba';
+ break;
+ case 'k':
+ word += 'k';
+ break;
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/hy.js b/assets/webconfig/js/lib/jquery.i18n/languages/hy.js
new file mode 100644
index 00000000..5ecf7ba5
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/hy.js
@@ -0,0 +1,25 @@
+/**
+ * Armenian (Հայերեն) language functions
+ */
+
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.hy = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ if ( form === 'genitive' ) { // սեռական հոլով
+ if ( word.slice( -1 ) === 'ա' ) {
+ word = word.slice( 0, -1 ) + 'այի';
+ } else if ( word.slice( -1 ) === 'ո' ) {
+ word = word.slice( 0, -1 ) + 'ոյի';
+ } else if ( word.slice( -4 ) === 'գիրք' ) {
+ word = word.slice( 0, -4 ) + 'գրքի';
+ } else {
+ word = word + 'ի';
+ }
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/la.js b/assets/webconfig/js/lib/jquery.i18n/languages/la.js
new file mode 100644
index 00000000..1a6c92bd
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/la.js
@@ -0,0 +1,54 @@
+/**
+ * Latin (lingua Latina) language functions
+ *
+ * @author Santhosh Thottingal
+ */
+
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.la = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ switch ( form ) {
+ case 'genitive':
+ // only a few declensions, and even for those mostly the singular only
+ word = word.replace( /u[ms]$/i, 'i' ); // 2nd declension singular
+ word = word.replace( /ommunia$/i, 'ommunium' ); // 3rd declension neuter plural (partly)
+ word = word.replace( /a$/i, 'ae' ); // 1st declension singular
+ word = word.replace( /libri$/i, 'librorum' ); // 2nd declension plural (partly)
+ word = word.replace( /nuntii$/i, 'nuntiorum' ); // 2nd declension plural (partly)
+ word = word.replace( /tio$/i, 'tionis' ); // 3rd declension singular (partly)
+ word = word.replace( /ns$/i, 'ntis' );
+ word = word.replace( /as$/i, 'atis' );
+ word = word.replace( /es$/i, 'ei' ); // 5th declension singular
+ break;
+ case 'accusative':
+ // only a few declensions, and even for those mostly the singular only
+ word = word.replace( /u[ms]$/i, 'um' ); // 2nd declension singular
+ word = word.replace( /ommunia$/i, 'am' ); // 3rd declension neuter plural (partly)
+ word = word.replace( /a$/i, 'ommunia' ); // 1st declension singular
+ word = word.replace( /libri$/i, 'libros' ); // 2nd declension plural (partly)
+ word = word.replace( /nuntii$/i, 'nuntios' );// 2nd declension plural (partly)
+ word = word.replace( /tio$/i, 'tionem' ); // 3rd declension singular (partly)
+ word = word.replace( /ns$/i, 'ntem' );
+ word = word.replace( /as$/i, 'atem' );
+ word = word.replace( /es$/i, 'em' ); // 5th declension singular
+ break;
+ case 'ablative':
+ // only a few declensions, and even for those mostly the singular only
+ word = word.replace( /u[ms]$/i, 'o' ); // 2nd declension singular
+ word = word.replace( /ommunia$/i, 'ommunibus' ); // 3rd declension neuter plural (partly)
+ word = word.replace( /a$/i, 'a' ); // 1st declension singular
+ word = word.replace( /libri$/i, 'libris' ); // 2nd declension plural (partly)
+ word = word.replace( /nuntii$/i, 'nuntiis' ); // 2nd declension plural (partly)
+ word = word.replace( /tio$/i, 'tione' ); // 3rd declension singular (partly)
+ word = word.replace( /ns$/i, 'nte' );
+ word = word.replace( /as$/i, 'ate' );
+ word = word.replace( /es$/i, 'e' ); // 5th declension singular
+ break;
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/ml.js b/assets/webconfig/js/lib/jquery.i18n/languages/ml.js
new file mode 100644
index 00000000..d9c82cfb
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/ml.js
@@ -0,0 +1,98 @@
+/**
+ * Malayalam language functions
+ *
+ * @author Santhosh Thottingal
+ */
+
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.ml = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ form = form.toLowerCase();
+ switch ( form ) {
+ case 'ഉദ്ദേശിക':
+ case 'dative':
+ if ( word.slice( -1 ) === 'ു' ||
+ word.slice( -1 ) === 'ൂ' ||
+ word.slice( -1 ) === 'ൗ' ||
+ word.slice( -1 ) === 'ൌ'
+ ) {
+ word += 'വിന്';
+ } else if ( word.slice( -1 ) === 'ം' ) {
+ word = word.slice( 0, -1 ) + 'ത്തിന്';
+ } else if ( word.slice( -1 ) === 'ൻ' ) {
+ // Atomic chillu n. അവൻ -> അവന്
+ word = word.slice( 0, -1 ) + 'ന്';
+ } else if ( word.slice( -3 ) === 'ന്\u200d' ) {
+ // chillu n. അവൻ -> അവന്
+ word = word.slice( 0, -1 );
+ } else if ( word.slice( -1 ) === 'ൾ' || word.slice( -3 ) === 'ള്\u200d' ) {
+ word += 'ക്ക്';
+ } else if ( word.slice( -1 ) === 'ർ' || word.slice( -3 ) === 'ര്\u200d' ) {
+ word += 'ക്ക്';
+ } else if ( word.slice( -1 ) === 'ൽ' ) {
+ // Atomic chillu ൽ , ഫയൽ -> ഫയലിന്
+ word = word.slice( 0, -1 ) + 'ലിന്';
+ } else if ( word.slice( -3 ) === 'ല്\u200d' ) {
+ // chillu ല്\u200d , ഫയല്\u200d -> ഫയലിന്
+ word = word.slice( 0, -2 ) + 'ിന്';
+ } else if ( word.slice( -2 ) === 'ു്' ) {
+ word = word.slice( 0, -2 ) + 'ിന്';
+ } else if ( word.slice( -1 ) === '്' ) {
+ word = word.slice( 0, -1 ) + 'ിന്';
+ } else {
+ // കാവ്യ -> കാവ്യയ്ക്ക്, ഹരി -> ഹരിയ്ക്ക്, മല -> മലയ്ക്ക്
+ word += 'യ്ക്ക്';
+ }
+
+ break;
+ case 'സംബന്ധിക':
+ case 'genitive':
+ if ( word.slice( -1 ) === 'ം' ) {
+ word = word.slice( 0, -1 ) + 'ത്തിന്റെ';
+ } else if ( word.slice( -2 ) === 'ു്' ) {
+ word = word.slice( 0, -2 ) + 'ിന്റെ';
+ } else if ( word.slice( -1 ) === '്' ) {
+ word = word.slice( 0, -1 ) + 'ിന്റെ';
+ } else if ( word.slice( -1 ) === 'ു' ||
+ word.slice( -1 ) === 'ൂ' ||
+ word.slice( -1 ) === 'ൗ' ||
+ word.slice( -1 ) === 'ൌ'
+ ) {
+ word += 'വിന്റെ';
+ } else if ( word.slice( -1 ) === 'ൻ' ) {
+ // Atomic chillu n. അവൻ -> അവന്റെ
+ word = word.slice( 0, -1 ) + 'ന്റെ';
+ } else if ( word.slice( -3 ) === 'ന്\u200d' ) {
+ // chillu n. അവൻ -> അവന്റെ
+ word = word.slice( 0, -1 ) + 'റെ';
+ } else if ( word.slice( -3 ) === 'ള്\u200d' ) {
+ // chillu n. അവൾ -> അവളുടെ
+ word = word.slice( 0, -2 ) + 'ുടെ';
+ } else if ( word.slice( -1 ) === 'ൾ' ) {
+ // Atomic chillu n. അവള്\u200d -> അവളുടെ
+ word = word.slice( 0, -1 ) + 'ളുടെ';
+ } else if ( word.slice( -1 ) === 'ൽ' ) {
+ // Atomic l. മുയല്\u200d -> മുയലിന്റെ
+ word = word.slice( 0, -1 ) + 'ലിന്റെ';
+ } else if ( word.slice( -3 ) === 'ല്\u200d' ) {
+ // chillu l. മുയല്\u200d -> അവളുടെ
+ word = word.slice( 0, -2 ) + 'ിന്റെ';
+ } else if ( word.slice( -3 ) === 'ര്\u200d' ) {
+ // chillu r. അവര്\u200d -> അവരുടെ
+ word = word.slice( 0, -2 ) + 'ുടെ';
+ } else if ( word.slice( -1 ) === 'ർ' ) {
+ // Atomic chillu r. അവർ -> അവരുടെ
+ word = word.slice( 0, -1 ) + 'രുടെ';
+ } else {
+ word += 'യുടെ';
+ }
+
+ break;
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/os.js b/assets/webconfig/js/lib/jquery.i18n/languages/os.js
new file mode 100644
index 00000000..e788db94
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/os.js
@@ -0,0 +1,75 @@
+/**
+ * Ossetian (Ирон) language functions
+ *
+ * @author Santhosh Thottingal
+ */
+
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.os = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ var endAllative, jot, hyphen, ending;
+
+ // Ending for allative case
+ endAllative = 'мæ';
+ // Variable for 'j' beetwen vowels
+ jot = '';
+ // Variable for "-" for not Ossetic words
+ hyphen = '';
+ // Variable for ending
+ ending = '';
+
+ if ( word.match( /тæ$/i ) ) {
+ // Checking if the $word is in plural form
+ word = word.slice( 0, -1 );
+ endAllative = 'æм';
+ } else if ( word.match( /[аæеёиоыэюя]$/i ) ) {
+ // Works if word is in singular form.
+ // Checking if word ends on one of the vowels: е, ё, и, о, ы, э, ю,
+ // я.
+ jot = 'й';
+ } else if ( word.match( /у$/i ) ) {
+ // Checking if word ends on 'у'. 'У' can be either consonant 'W' or
+ // vowel 'U' in cyrillic Ossetic.
+ // Examples: {{grammar:genitive|аунеу}} = аунеуы,
+ // {{grammar:genitive|лæппу}} = лæппуйы.
+ if ( !word.slice( -2, -1 ).match( /[аæеёиоыэюя]$/i ) ) {
+ jot = 'й';
+ }
+ } else if ( !word.match( /[бвгджзйклмнопрстфхцчшщьъ]$/i ) ) {
+ hyphen = '-';
+ }
+
+ switch ( form ) {
+ case 'genitive':
+ ending = hyphen + jot + 'ы';
+ break;
+ case 'dative':
+ ending = hyphen + jot + 'æн';
+ break;
+ case 'allative':
+ ending = hyphen + endAllative;
+ break;
+ case 'ablative':
+ if ( jot === 'й' ) {
+ ending = hyphen + jot + 'æ';
+ } else {
+ ending = hyphen + jot + 'æй';
+ }
+ break;
+ case 'superessive':
+ ending = hyphen + jot + 'ыл';
+ break;
+ case 'equative':
+ ending = hyphen + jot + 'ау';
+ break;
+ case 'comitative':
+ ending = hyphen + 'имæ';
+ break;
+ }
+
+ return word + ending;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/ru.js b/assets/webconfig/js/lib/jquery.i18n/languages/ru.js
new file mode 100644
index 00000000..60fefffa
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/ru.js
@@ -0,0 +1,29 @@
+/**
+ * Russian (Русский) language functions
+ */
+
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.ru = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ if ( form === 'genitive' ) { // родительный падеж
+ if ( word.slice( -1 ) === 'ь' ) {
+ word = word.slice( 0, -1 ) + 'я';
+ } else if ( word.slice( -2 ) === 'ия' ) {
+ word = word.slice( 0, -2 ) + 'ии';
+ } else if ( word.slice( -2 ) === 'ка' ) {
+ word = word.slice( 0, -2 ) + 'ки';
+ } else if ( word.slice( -2 ) === 'ти' ) {
+ word = word.slice( 0, -2 ) + 'тей';
+ } else if ( word.slice( -2 ) === 'ды' ) {
+ word = word.slice( 0, -2 ) + 'дов';
+ } else if ( word.slice( -3 ) === 'ник' ) {
+ word = word.slice( 0, -3 ) + 'ника';
+ }
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/sl.js b/assets/webconfig/js/lib/jquery.i18n/languages/sl.js
new file mode 100644
index 00000000..0e14ed5f
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/sl.js
@@ -0,0 +1,26 @@
+/**
+ * Slovenian (Slovenščina) language functions
+ */
+
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.sl = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ switch ( form ) {
+ // locative
+ case 'mestnik':
+ word = 'o ' + word;
+
+ break;
+ // instrumental
+ case 'orodnik':
+ word = 'z ' + word;
+
+ break;
+ }
+
+ return word;
+ }
+ } );
+}( jQuery ) );
diff --git a/assets/webconfig/js/lib/jquery.i18n/languages/uk.js b/assets/webconfig/js/lib/jquery.i18n/languages/uk.js
new file mode 100644
index 00000000..f5292cf8
--- /dev/null
+++ b/assets/webconfig/js/lib/jquery.i18n/languages/uk.js
@@ -0,0 +1,39 @@
+/**
+ * Ukrainian (Українська) language functions
+ */
+
+( function ( $ ) {
+ 'use strict';
+
+ $.i18n.languages.uk = $.extend( {}, $.i18n.languages[ 'default' ], {
+ convertGrammar: function ( word, form ) {
+ switch ( form ) {
+ case 'genitive': // родовий відмінок
+ if ( word.slice( -1 ) === 'ь' ) {
+ word = word.slice( 0, -1 ) + 'я';
+ } else if ( word.slice( -2 ) === 'ія' ) {
+ word = word.slice( 0, -2 ) + 'ії';
+ } else if ( word.slice( -2 ) === 'ка' ) {
+ word = word.slice( 0, -2 ) + 'ки';
+ } else if ( word.slice( -2 ) === 'ти' ) {
+ word = word.slice( 0, -2 ) + 'тей';
+ } else if ( word.slice( -2 ) === 'ды' ) {
+ word = word.slice( 0, -2 ) + 'дов';
+ } else if ( word.slice( -3 ) === 'ник' ) {
+ word = word.slice( 0, -3 ) + 'ника';
+ }
+
+ break;
+ case 'accusative': // знахідний відмінок
+ if ( word.slice( -2 ) === 'ія' ) {
+ word = word.slice( 0, -2 ) + 'ію';
+ }
+
+ break;
+ }
+
+ return word;
+ }
+ } );
+
+}( jQuery ) );
diff --git a/assets/webconfig/js/settings.js b/assets/webconfig/js/settings.js
index 961ecc36..bca0cc65 100644
--- a/assets/webconfig/js/settings.js
+++ b/assets/webconfig/js/settings.js
@@ -1,8 +1,9 @@
var storedAccess;
var storedLang;
-var availLang = ['cs','de','en','es','fr','it','nl','pl','ro','sv','vi','ru','tr','zh-CN'];
-var availLangText = ['Čeština', 'Deutsch', 'English', 'Español', 'Français', 'Italiano', 'Nederlands', 'Polski', 'Română', 'Svenska', 'Tiếng Việt', 'русский', 'Türkçe', '汉语'];
-var availAccess = ['default','advanced','expert'];
+var availLang = ['cs', 'de', 'en', 'es', 'fr', 'it', 'nl', 'nb', 'pl', 'pt', 'ro', 'sv', 'vi', 'ru', 'tr', 'zh-CN'];
+var availLangText = ['Čeština', 'Deutsch', 'English', 'Español', 'Français', 'Italiano', 'Nederlands', 'Norsk Bokmål', 'Polski', 'Português', 'Română', 'Svenska', 'Tiếng Việt', 'русский', 'Türkçe', '汉语'];
+var availAccess = ['default', 'advanced', 'expert'];
+
//$.i18n.debug = true;
//Change Password