diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2dc2e3c7..b10a3a39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,7 @@
# PrivateBin version history
* **next (not yet released)**
- * ADDED: Translations for Spanish, Occitan and Norwegian
+ * ADDED: Translations for Spanish, Occitan, Norwegian and Portuguese
* ADDED: Option in configuration to change the default "PrivateBin" title of the site
* CHANGED: Cleanup of bootstrap template variants and moved icons to `img` directory
* **1.1 (2016-12-26)**
diff --git a/CREDITS.md b/CREDITS.md
index dfb2d83e..1c7ec3cc 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -35,3 +35,4 @@ Sébastien Sauvage - original idea and main developer
* Alfredo Fabián Altamirano Tena - Spanish
* Quent-in - Occitan
* idarlund - Norwegian
+* Tulio Leao - Portuguese
diff --git a/i18n/pt.json b/i18n/pt.json
new file mode 100644
index 00000000..3e418909
--- /dev/null
+++ b/i18n/pt.json
@@ -0,0 +1,151 @@
+{
+ "PrivateBin": "PrivateBin",
+ "%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bits AES. More information on the project page.":
+ "%s é um serviço minimalista e de código aberto do tipo \"pastebin\", em que o servidor tem zero conhecimento dos dados copiados. Os dados são cifrados e decifrados no navegador usando 256 bits AES. Mais informações na página do projeto.",
+ "Because ignorance is bliss":
+ "Porque a ignorância é uma benção",
+ "en": "pt",
+ "Paste does not exist, has expired or has been deleted.":
+ "A cópia não existe, expirou ou já foi excluída.",
+ "%s requires php 5.3.0 or above to work. Sorry.":
+ "%s requer php 5.3.0 ou superior para funcionar. Desculpa.",
+ "%s requires configuration section [%s] to be present in configuration file.":
+ "%s requer que a seção de configuração [% s] esteja no arquivo de configuração.",
+ "Please wait %d seconds between each post.":
+ "Por favor espere %d segundos entre cada publicação.",
+ "Paste is limited to %s of encrypted data.":
+ "A cópia está limitada a %s de dados cifrados.",
+ "Invalid data.":
+ "Dados inválidos.",
+ "You are unlucky. Try again.":
+ "Você é azarado. Tente novamente",
+ "Error saving comment. Sorry.":
+ "Erro ao salvar comentário. Desculpa.",
+ "Error saving paste. Sorry.":
+ "Erro ao salvar cópia. Desculpa.",
+ "Invalid paste ID.":
+ "ID de cópia inválido.",
+ "Paste is not of burn-after-reading type.":
+ "Cópia não é do tipo \"queime após ler\".",
+ "Wrong deletion token. Paste was not deleted.":
+ "Token de remoção inválido. A cópia não foi excluída.",
+ "Paste was properly deleted.":
+ "A cópia foi devidamente excluída.",
+ "JavaScript is required for %s to work.
Sorry for the inconvenience.":
+ "JavaScript é necessário para que %s funcione.
Pedimos desculpas pela inconveniência.",
+ "%s requires a modern browser to work.":
+ "%s requer um navegador moderno para funcionar.",
+ "Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
+ "Ainda usando Internet Explorer? Faça-se um favor, mude para um navegador moderno:",
+ "New":
+ "Novo",
+ "Send":
+ "Enviar",
+ "Clone":
+ "Clonar",
+ "Raw text":
+ "Texto sem formato",
+ "Expires":
+ "Expirar em",
+ "Burn after reading":
+ "Queime após ler",
+ "Open discussion":
+ "Discussão aberta",
+ "Password (recommended)":
+ "Senha (recomendada)",
+ "Discussion":
+ "Discussão",
+ "Toggle navigation":
+ "Mudar navegação",
+ "%d seconds": ["%d segundo", "%d segundos"],
+ "%d minutes": ["%d minuto", "%d minutos"],
+ "%d hours": ["%d hora", "%d horas"],
+ "%d days": ["%d dia", "%d dias"],
+ "%d weeks": ["%d semana", "%d semanas"],
+ "%d months": ["%d mês", "%d meses"],
+ "%d years": ["%d ano", "%d anos"],
+ "Never":
+ "Nunca",
+ "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.":
+ "Nota: Este é um serviço de teste. Dados podem ser perdidos a qualquer momento. Gatinhos morrerão se você abusar desse serviço.",
+ "This document will expire in %d seconds.":
+ ["Este documento irá expirar em um segundo.", "Este documento irá expirar em %d segundos."],
+ "This document will expire in %d minutes.":
+ ["Este documento irá expirar em um minuto.", "Este documento irá expirar em %d minutos."],
+ "This document will expire in %d hours.":
+ ["Este documento irá expirar em uma hora.", "Este documento irá expirar em %d horas."],
+ "This document will expire in %d days.":
+ ["Este documento irá expirar em um dia.", "Este documento irá expirar em %d dias."],
+ "This document will expire in %d months.":
+ ["Este documento irá expirar em um mês.", "Este documento irá expirar em %d meses."],
+ "Please enter the password for this paste:":
+ "Por favor, digite a senha para essa cópia:",
+ "Could not decrypt data (Wrong key?)":
+ "Não foi possível decifrar os dados (Chave errada?)",
+ "Could not delete the paste, it was not stored in burn after reading mode.":
+ "Não foi possível excluir a cópia, ela não foi salva no modo de \"queime após ler\".",
+ "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.":
+ "APENAS PARA SEUS OLHOS. Não feche essa janela, essa mensagem não pode ser exibida novamente.",
+ "Could not decrypt comment; Wrong key?":
+ "Não foi possível decifrar o comentário; Chave errada?",
+ "Reply":
+ "Responder",
+ "Anonymous":
+ "Anônimo",
+ "Anonymous avatar (Vizhash of the IP address)":
+ "Avatar anônimo (Vizhash do endereço IP)",
+ "Add comment":
+ "Adicionar comentário",
+ "Optional nickname...":
+ "Apelido opcional...",
+ "Post comment":
+ "Publicar comentário",
+ "Sending comment...":
+ "Enviando comentário...",
+ "Comment posted.":
+ "Comentário publicado.",
+ "Could not refresh display: %s":
+ "Não foi possível atualizar a tela: %s",
+ "unknown status":
+ "Estado desconhecido",
+ "server error or not responding":
+ "Servidor em erro ou não responsivo",
+ "Could not post comment: %s":
+ "Não foi possível publicar o comentário: %s",
+ "Sending paste (Please move your mouse for more entropy)...":
+ "Enviando cópia (Por favor, mova o mouse para maior entropia)...",
+ "Sending paste...":
+ "Enviando cópia...",
+ "Your paste is %s (Hit [Ctrl]+[c] to copy)":
+ "Sua cópia é %s (Pressione [Ctrl]+[c] para copiar)",
+ "Delete data":
+ "Excluir dados",
+ "Could not create paste: %s":
+ "Não foi possível criar cópia: %s",
+ "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)":
+ "Não foi possível decifrar a cópia: chave de decriptografia ausente na URL (Você utilizou um redirecionador ou encurtador de URL que removeu parte dela?)",
+ "Format": "Formato",
+ "Plain Text": "Texto sem formato",
+ "Source Code": "Código fonte",
+ "Markdown": "Markdown",
+ "Download attachment": "Baixar anexo",
+ "Cloned file attached.": "Arquivo clonado anexado.",
+ "Attach a file": "Anexar um arquivo",
+ "Remove attachment": "Remover anexo",
+ "Your browser does not support uploading encrypted files. Please use a newer browser.":
+ "Seu navegador não permite subir arquivos cifrados. Por favor, utilize um navegador mais recente.",
+ "Invalid attachment.": "Anexo inválido.",
+ "Options": "Opções",
+ "Shorten URL": "Encurtar URL",
+ "Editor": "Editor",
+ "Preview": "Visualizar",
+ "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.":
+ "%s requer que o PATH termine em \"%s\". Por favor, atualize o PATH em seu index.php.",
+ "Decrypt":
+ "Decifrar",
+ "Enter password":
+ "Digite a senha",
+ "Loading…": "Carregando…",
+ "In case this message never disappears please have a look at this FAQ for information to troubleshoot.":
+ "Caso essa mensagem nunca desapareça, por favor veja este FAQ para saber como resolver os problemas."
+}
diff --git a/js/privatebin.js b/js/privatebin.js
index 4fd0e99b..6508bec4 100644
--- a/js/privatebin.js
+++ b/js/privatebin.js
@@ -353,7 +353,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
* @prop {string[]}
* @readonly
*/
- supportedLanguages: ['de', 'es', 'fr', 'it', 'no', 'pl', 'oc', 'ru', 'sl', 'zh'],
+ supportedLanguages: ['de', 'es', 'fr', 'it', 'no', 'pl', 'pt', 'oc', 'ru', 'sl', 'zh'],
/**
* translate a string, alias for i18n.translate()
@@ -450,7 +450,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
return (n % 10 === 1 && n % 100 !== 11 ? 0 : (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2));
case 'sl':
return (n % 100 === 1 ? 1 : (n % 100 === 2 ? 2 : (n % 100 === 3 || n % 100 === 4 ? 3 : 0)));
- // de, en, es, it, no
+ // de, en, es, it, no, pt
default:
return (n !== 1 ? 1 : 0);
}
diff --git a/lib/I18n.php b/lib/I18n.php
index 4c59ef57..d35bcf01 100644
--- a/lib/I18n.php
+++ b/lib/I18n.php
@@ -304,7 +304,7 @@ class I18n
return $n % 10 == 1 && $n % 100 != 11 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
case 'sl':
return $n % 100 == 1 ? 1 : ($n % 100 == 2 ? 2 : ($n % 100 == 3 || $n % 100 == 4 ? 3 : 0));
- // de, en, es, it, no
+ // de, en, es, it, no, pt
default:
return $n != 1 ? 1 : 0;
}
diff --git a/tpl/bootstrap.php b/tpl/bootstrap.php
index 4bf3ca1d..04f2726b 100644
--- a/tpl/bootstrap.php
+++ b/tpl/bootstrap.php
@@ -69,7 +69,7 @@ if ($MARKDOWN):
-
+
diff --git a/tpl/page.php b/tpl/page.php
index 4ae0b6a7..2bdbf913 100644
--- a/tpl/page.php
+++ b/tpl/page.php
@@ -47,7 +47,7 @@ if ($MARKDOWN):
-
+