diff --git a/composer.json b/composer.json index 7a9af45f37..c68685a388 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "The Kirby core", "license": "proprietary", "type": "kirby-cms", - "version": "4.0.2", + "version": "4.0.3", "keywords": [ "kirby", "cms", diff --git a/composer.lock b/composer.lock index b56f37c3e3..98243ed038 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b3bdc15cebd0ff800fa453afa8a4751c", + "content-hash": "977754e23aeb4791a5c4f60c6e18ddc6", "packages": [ { "name": "christian-riesen/base32", @@ -1125,5 +1125,5 @@ "platform-overrides": { "php": "8.1.0" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/i18n/translations/de.json b/i18n/translations/de.json index 5648868aa6..f5c205ac00 100644 --- a/i18n/translations/de.json +++ b/i18n/translations/de.json @@ -98,7 +98,7 @@ "error.file.changeName.empty": "Bitte gib einen Namen an", "error.file.changeName.permission": "Du darfst den Dateinamen von \"{filename}\" nicht ändern", "error.file.changeTemplate.invalid": "Die Vorlage für die Datei \"{id}\" kann nicht zu \"{template}\" geändert werden (gültig: \"{blueprints}\")", - "error.file.changeTemplate.permission": "Du kannst die Voralge für die Datei \"{id}\" nicht ändern", + "error.file.changeTemplate.permission": "Du kannst die Vorlage für die Datei \"{id}\" nicht ändern", "error.file.duplicate": "Eine Datei mit dem Dateinamen \"{filename}\" besteht bereits", "error.file.extension.forbidden": "Verbotene Dateiendung \"{extension}\"", diff --git a/i18n/translations/it.json b/i18n/translations/it.json index ca3113d400..004cee65a2 100644 --- a/i18n/translations/it.json +++ b/i18n/translations/it.json @@ -535,7 +535,7 @@ "page.changeStatus.select": "Seleziona un nuovo stato", "page.changeTemplate": "Cambia template", "page.changeTemplate.notice": "Changing the page's template will remove content for fields that don't match in type. Use with caution.", - "page.create": "Create as {status}", + "page.create": "Crea come \"{status}\"", "page.delete.confirm": "Sei sicuro di voler eliminare questa pagina?", "page.delete.confirm.subpages": "Questa pagina ha sottopagine.
Anche tutte le sottopagine verranno eliminate.", "page.delete.confirm.title": "Inserisci il titolo della pagina per confermare", diff --git a/i18n/translations/pt_BR.json b/i18n/translations/pt_BR.json index 609b7c8653..e9ca866aec 100644 --- a/i18n/translations/pt_BR.json +++ b/i18n/translations/pt_BR.json @@ -3,7 +3,7 @@ "account.delete": "Deletar sua conta", "account.delete.confirm": "Deseja realmente deletar sua conta? Você sairá do site imediatamente. Sua conta não poderá ser recuperada. ", - "activate": "Activate", + "activate": "Ativar", "add": "Adicionar", "alpha": "Alpha", "author": "Autor", @@ -12,17 +12,17 @@ "cancel": "Cancelar", "change": "Alterar", "close": "Fechar", - "changes": "Changes", + "changes": "Alterações", "confirm": "Salvar", "collapse": "Colapsar", "collapse.all": "Colapsar todos", - "color": "Color", - "coordinates": "Coordinates", + "color": "Cor", + "coordinates": "Coordenadas", "copy": "Copiar", "copy.all": "Copiar todos", - "copy.success": "{count} copied!", + "copy.success": "{count} copiados!", "create": "Criar", - "custom": "Custom", + "custom": "Personalizado", "date": "Data", "date.select": "Selecione uma data", @@ -41,20 +41,20 @@ "delete": "Deletar", "delete.all": "Deletar todos", - "dialog.fields.empty": "This dialog has no fields", + "dialog.fields.empty": "Esta caixa de diálogo não tem campos", "dialog.files.empty": "Nenhum arquivo para selecionar", "dialog.pages.empty": "Nenhuma página para selecionar", - "dialog.text.empty": "This dialog does not define any text", + "dialog.text.empty": "Esta caixa de diálogo não define nenhum texto", "dialog.users.empty": "Nenhum usuário para selecionar", "dimensions": "Dimensões", - "disable": "Disable", + "disable": "Desativar", "disabled": "Desativado", "discard": "Descartar", - "drawer.fields.empty": "This drawer has no fields", + "drawer.fields.empty": "Esta janela não tem campos", - "domain": "Domain", + "domain": "Domínio", "download": "Baixar", "duplicate": "Duplicar", @@ -63,13 +63,13 @@ "email": "Email", "email.placeholder": "mail@exemplo.com", - "enter": "Enter", - "entries": "Entries", - "entry": "Entry", + "enter": "Insira", + "entries": "Registos", + "entry": "Registo", "environment": "Ambiente", - "error": "Error", + "error": "Erro", "error.access.code": "Código inválido", "error.access.login": "Código de acesso inválido", "error.access.panel": "Você não tem permissão para acessar o painel", @@ -86,19 +86,19 @@ "error.blocks.max.singular": "Você não deve adicionar mais do que um bloco", "error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos", "error.blocks.min.singular": "Você deve adicionar pelo menos um bloco", - "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + "error.blocks.validation": "Há um erro no campo \"{field}\" no bloco {index} a usar o tipo de bloco \"{fieldset}\"", - "error.cache.type.invalid": "Invalid cache type \"{type}\"", + "error.cache.type.invalid": "Tipo de cache \"{type}\" inválido", "error.email.preset.notFound": "Pré-configuração de email \"{name}\" não foi encontrada", "error.field.converter.invalid": "Conversor \"{converter}\" inválido", - "error.field.type.missing": "Field \"{ name }\": The field type \"{ type }\" does not exist", + "error.field.type.missing": "Campo \"{name}\": O tipo de campo \"{type}\" não existe", "error.file.changeName.empty": "O nome não deve ficar em branco", "error.file.changeName.permission": "Você não tem permissão para alterar o nome de \"{filename}\"", - "error.file.changeTemplate.invalid": "The template for the file \"{id}\" cannot be changed to \"{template}\" (valid: \"{blueprints}\")", - "error.file.changeTemplate.permission": "You are not allowed to change the template for the file \"{id}\"", + "error.file.changeTemplate.invalid": "O template para o ficheiro \"{id}\" não pode ser alterado para \"{template}\" (válido: \"{blueprints}\")", + "error.file.changeTemplate.permission": "Não tem permissão para alterar o template do ficheiro \"{id}\"", "error.file.duplicate": "Um arquivo com o nome \"{filename}\" já existe", "error.file.extension.forbidden": "Extensão \"{extension}\" não permitida", @@ -114,7 +114,7 @@ "error.file.minheight": "A altura da imagem deve ser pelo menos {height} pixels", "error.file.minsize": "O arquivo é pequeno demais", "error.file.minwidth": "A largura da imagem deve ser pelo menos {width} pixels", - "error.file.name.unique": "The filename must be unique", + "error.file.name.unique": "O nome do ficheiro deve ser único", "error.file.name.missing": "O nome do arquivo não pode ficar em branco", "error.file.notFound": "Arquivo \"{filename}\" não encontrado", "error.file.orientation": "A orientação da imagem deve ser “{orientation}”", @@ -130,23 +130,23 @@ "error.language.name": "Por favor entre um nome válido para o idioma", "error.language.notFound": "O idioma não foi encontrado", - "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.block": "Há um erro no campo \"{field}\" no bloco {blockIndex} a usar o tipo de bloco \"{fieldset}\" no layout {layoutIndex}", "error.layout.validation.settings": "Há um erro na configuração do layout {index}", - "error.license.domain": "The domain for the license is missing", + "error.license.domain": "O domínio da licença está em falta", "error.license.email": "Digite um endereço de email válido", - "error.license.format": "Please enter a valid license code", + "error.license.format": "Por favor insira um código de licença válido", "error.license.verification": "A licensa não pôde ser verificada", "error.login.totp.confirm.invalid": "Código inválido", - "error.login.totp.confirm.missing": "Please enter the current code", + "error.login.totp.confirm.missing": "Por favor insira o código atual", - "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + "error.object.validation": "Há um erro no campo \"{label}\":\n{message}", "error.offline": "O painel está offline no momento", "error.page.changeSlug.permission": "Você não tem permissão para alterar o anexo de URL de \"{slug}\"", - "error.page.changeSlug.reserved": "The path of top-level pages must not start with \"{path}\"", + "error.page.changeSlug.reserved": "O caminho das páginas de nível superior não deve começar com \"{path}\"", "error.page.changeStatus.incomplete": "A página possui erros e não pode ser salva", "error.page.changeStatus.permission": "O estado desta página não pode ser alterado", "error.page.changeStatus.toDraft.invalid": "A página \"{slug}\" não pode ser convertida para rascunho", @@ -162,12 +162,12 @@ "error.page.draft.duplicate": "Uma página rascunho com um anexo de URL \"{slug}\" já existe", "error.page.duplicate": "Uma página com o anexo de URL \"{slug}\" já existe", "error.page.duplicate.permission": "Você não tem permissão para duplicar “{slug}”", - "error.page.move.ancestor": "The page cannot be moved into itself", - "error.page.move.directory": "The page directory cannot be moved", - "error.page.move.duplicate": "A sub page with the URL appendix \"{slug}\" already exists", - "error.page.move.notFound": "The moved page could not be found", - "error.page.move.permission": "You are not allowed to move \"{slug}\"", - "error.page.move.template": "The \"{template}\" template is not accepted as a subpage of \"{parent}\"", + "error.page.move.ancestor": "A página não pode ser movida para dentro dela mesma", + "error.page.move.directory": "A pasta da página não pode ser movida", + "error.page.move.duplicate": "Uma subpágina com o segmento de URL \"{slug}\" já existe", + "error.page.move.notFound": "A página movida não foi encontrada", + "error.page.move.permission": "Não tem permissão para mover \"{slug}\"", + "error.page.move.template": "O template \"{template}\" não é aceite como subpágina de \"{parent}\"", "error.page.notFound": "Página \"{slug}\" não encontrada", "error.page.num.invalid": "Digite um número de ordenação válido. Este número não pode ser negativo.", "error.page.slug.invalid": "Por favor entre um anexo de URL válido ", @@ -194,11 +194,11 @@ "error.site.changeTitle.permission": "Você não tem permissão para alterar o título do site", "error.site.update.permission": "Você não tem permissão para atualizar o site", - "error.structure.validation": "There's an error on the \"{field}\" field in row {index}", + "error.structure.validation": "Existe um erro no campo \"{field}\" na linha {index}", "error.template.default.notFound": "O tema padrão não existe", - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + "error.unexpected": "Ocorreu um erro inesperado! Ative o modo de debug para obter mais informações: https://getkirby.com/docs/reference/system/options/debug", "error.user.changeEmail.permission": "Você não tem permissão para alterar o email do usuário \"{name}\"", "error.user.changeLanguage.permission": "Você não tem permissão para alterar o idioma do usuário \"{name}\"", @@ -216,7 +216,7 @@ "error.user.email.invalid": "Digite um endereço de email válido", "error.user.language.invalid": "Digite um idioma válido", "error.user.notFound": "Usuário \"{name}\" não encontrado", - "error.user.password.excessive": "Please enter a valid password. Passwords must not be longer than 1000 characters.", + "error.user.password.excessive": "Por favor insira uma palavra-passe válida. As palavras-passe não devem ter mais do que 1000 caracteres.", "error.user.password.invalid": "Digite uma senha válida. Sua senha deve ter pelo menos 8 caracteres.", "error.user.password.notSame": "As senhas não combinam", "error.user.password.undefined": "O usuário não possui uma senha", @@ -228,10 +228,10 @@ "error.validation.accepted": "Por favor, confirme", "error.validation.alpha": "Por favor, use apenas caracteres entre a-z", "error.validation.alphanum": "Por favor, use apenas caracteres entre a-z ou 0-9", - "error.validation.anchor": "Please enter a correct link anchor", + "error.validation.anchor": "Por favor insira uma âncora de link correta", "error.validation.between": "Digite um valor entre \"{min}\" e \"{max}\"", "error.validation.boolean": "Por favor, confirme ou rejeite", - "error.validation.color": "Please enter a valid color in the {format} format", + "error.validation.color": "Por favor, insira uma cor válida no formato {format}", "error.validation.contains": "Digite um valor que contenha \"{needle}\"", "error.validation.date": "Escolha uma data válida", "error.validation.date.after": "Por favor entre uma data depois de {date}", @@ -246,7 +246,7 @@ "error.validation.integer": "Digite um número inteiro válido", "error.validation.ip": "Digite um endereço de IP válido", "error.validation.less": "Digite um valor menor que {max}", - "error.validation.linkType": "The link type is not allowed", + "error.validation.linkType": "O tipo de link não é permitido", "error.validation.match": "O valor não combina com o padrão esperado", "error.validation.max": "Digite um valor igual ou menor que {max}", "error.validation.maxlength": "Digite um valor curto. (no máximo {max} caracteres)", @@ -263,18 +263,18 @@ "error.validation.same": "Por favor, digite \"{other}\"", "error.validation.size": "O tamanho do valor deve ser \"{size}\"", "error.validation.startswith": "O valor deve começar com \"{start}\"", - "error.validation.tel": "Please enter an unformatted phone number", + "error.validation.tel": "Por favor, insira um número de telefone não formatado", "error.validation.time": "Digite um horário válido", "error.validation.time.after": "Por favor entre um horário depois de {time}", "error.validation.time.before": "Por favor entre um horário antes de {time}", "error.validation.time.between": "Por favor entre um horário entre {min} e {max}", - "error.validation.uuid": "Please enter a valid UUID", + "error.validation.uuid": "Por favor, insira um UUID válido", "error.validation.url": "Digite uma URL válida", "expand": "Expandir", "expand.all": "Expandir todos", - "field.invalid": "The field is invalid", + "field.invalid": "O campo é inválido", "field.required": "Este campo é obrigatório ", "field.blocks.changeType": "Mudar tipo", "field.blocks.code.name": "Código", @@ -284,9 +284,9 @@ "field.blocks.delete.confirm.all": "Deseja realmente deletar todos os blocos?", "field.blocks.delete.confirm.selected": "Deseja realmente deletar os blocos selecionados?", "field.blocks.empty": "Nenhum bloco", - "field.blocks.fieldsets.empty": "No fieldsets yet", + "field.blocks.fieldsets.empty": "Ainda não há tipos de blocos", "field.blocks.fieldsets.label": "Por favor selecione um tipo de bloco …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to import layouts/blocks from your clipboard Only those allowed in the current field will get inserted.", + "field.blocks.fieldsets.paste": "Pressione {{ shortcut }} para importar layouts/blocks da sua área de transferência Só serão inseridos aqueles permitidos no campo atual.", "field.blocks.gallery.name": "Galeria", "field.blocks.gallery.images.empty": "Nenhuma imagem", "field.blocks.gallery.images.label": "Imagens", @@ -299,8 +299,8 @@ "field.blocks.image.crop": "Cortar", "field.blocks.image.link": "Link", "field.blocks.image.location": "Localização ", - "field.blocks.image.location.internal": "This website", - "field.blocks.image.location.external": "External source", + "field.blocks.image.location.internal": "Este website", + "field.blocks.image.location.external": "Fonte externa", "field.blocks.image.name": "Imagem", "field.blocks.image.placeholder": "Selecionar uma imagem", "field.blocks.image.ratio": "Proporção ", @@ -325,43 +325,43 @@ "field.files.empty": "Nenhum arquivo selecionado", - "field.layout.change": "Change layout", + "field.layout.change": "Alterar layout", "field.layout.delete": "Deletar layout", "field.layout.delete.confirm": "Deseja realmente deletar este layout?", - "field.layout.delete.confirm.all": "Do you really want to delete all layouts?", + "field.layout.delete.confirm.all": "Tem a certeza que pretende remover todos os layouts?", "field.layout.empty": "Nenhuma linha", "field.layout.select": "Selecionar um layout", - "field.object.empty": "No information yet", + "field.object.empty": "Nenhuma informação ainda", "field.pages.empty": "Nenhuma página selecionada", "field.structure.delete.confirm": "Deseja realmente deletar esta linha?", - "field.structure.delete.confirm.all": "Do you really want to delete all entries?", + "field.structure.delete.confirm.all": "Tem a certeza que pretende eliminar todos os registos?", "field.structure.empty": "Nenhum registro", "field.users.empty": "Nenhum usuário selecionado", - "fields.empty": "No fields yet", + "fields.empty": "Nenhum campo ainda", - "file": "File", + "file": "Ficheiro", "file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em /site/blueprints/files/{blueprint}.yml", "file.changeTemplate": "Alterar tema", - "file.changeTemplate.notice": "Changing the file's template will remove content for fields that don't match in type. If the new template defines certain rules, e.g. image dimensions, those will also be applied irreversibly. Use with caution.", + "file.changeTemplate.notice": "Alterar o template do ficheiro irá remover o conteúdo dos campos que não correspondem ao mesmo tipo. Se o novo template definir certas regras, por exemplo dimensões de imagem, estas também serão aplicadas irreversivelmente. Use com cuidado.", "file.delete.confirm": "Deseja realmente deletar
{filename}?", - "file.focus.placeholder": "Set focal point", - "file.focus.reset": "Remove focal point", - "file.focus.title": "Focus", + "file.focus.placeholder": "Definir ponto de foco", + "file.focus.reset": "Remover ponto de foco", + "file.focus.title": "Foco", "file.sort": "Mudar posição", "files": "Arquivos", "files.empty": "Nenhum arquivo", - "filter": "Filter", + "filter": "Filtro", "hide": "Ocultar", "hour": "Hora", - "hue": "Hue", + "hue": "Tonalidade", "import": "Importar", "info": "Info", "insert": "Inserir", @@ -396,16 +396,16 @@ "language.locale": "String de localização do PHP", "language.locale.warning": "Você está usando uma configuração de local customizada. Por favor modifique a configuração no arquivo do idioma em /site/languages", "language.name": "Nome", - "language.secondary": "Secondary language", - "language.settings": "Language settings", + "language.secondary": "Idioma secundário", + "language.settings": "Configurações de idioma", "language.updated": "Idioma atualizado", - "language.variables": "Language variables", - "language.variables.empty": "No translations yet", + "language.variables": "Variáveis de idioma", + "language.variables.empty": "Nenhuma tradução ainda", - "language.variable.delete.confirm": "Do you really want to delete the variable for {key}?", - "language.variable.key": "Key", - "language.variable.notFound": "The variable could not be found", - "language.variable.value": "Value", + "language.variable.delete.confirm": "Tem a certeza que pretende eliminar a variável {key}?", + "language.variable.key": "Chave", + "language.variable.notFound": "A variável não foi encontrada", + "language.variable.value": "Valor", "languages": "Idiomas", "languages.default": "Idioma padrão", @@ -414,31 +414,31 @@ "languages.secondary.empty": "Nenhum idioma secundário", "license": "Licen\u00e7a do Kirby ", - "license.activate": "Activate it now", - "license.activate.label": "Please activate your license", - "license.activate.domain": "Your license will be activated for {host}.", - "license.activate.local": "You are about to activate your Kirby license for your local domain {host}. If this site will be deployed to a public domain, please activate it there instead. If {host} is the domain you want to use your license for, please continue.", - "license.activated": "Activated", + "license.activate": "Ativar agora", + "license.activate.label": "Por favor, ative a sua licença", + "license.activate.domain": "A sua licença será irá ser ativada para {host}.", + "license.activate.local": "Está prestes a ativar a sua licença Kirby no domínio local {host}. Se este site vai ser alojado num domínio público, por favor ative-o lá. Se o domínio {host} é o o que deseja para usar a sua licença, por favor continue.", + "license.activated": "Ativado", "license.buy": "Comprar licença", "license.code": "Código", - "license.code.help": "You received your license code after the purchase via email. Please copy and paste it here.", + "license.code.help": "Recebeu o seu código de licença por e-mail após a compra. Por favor, copie e cole aqui.", "license.code.label": "Por favor, digite o código da sua licença", - "license.status.active.info": "Includes new major versions until {date}", - "license.status.active.label": "Valid license", - "license.status.demo.info": "This is a demo installation", - "license.status.demo.label": "Demo", - "license.status.inactive.info": "Renew license to update to new major versions", - "license.status.inactive.label": "No new major versions", - "license.status.legacy.bubble": "Ready to renew your license?", - "license.status.legacy.info": "Your license does not cover this version", - "license.status.legacy.label": "Please renew your license", - "license.status.missing.bubble": "Ready to launch your site?", - "license.status.missing.info": "No valid license", - "license.status.missing.label": "Please activate your license", - "license.manage": "Manage your licenses", - "license.purchased": "Purchased", + "license.status.active.info": "Inclui novas versões principais até {date}", + "license.status.active.label": "Licença válida", + "license.status.demo.info": "Esta é uma instalação de demonstração", + "license.status.demo.label": "Demonstração", + "license.status.inactive.info": "Renove a licença para atualizar para novas versões principais", + "license.status.inactive.label": "Nenhuma versão principal nova", + "license.status.legacy.bubble": "Pronto para renovar a sua licença?", + "license.status.legacy.info": "A sua licença não abrange esta versão", + "license.status.legacy.label": "Por favor, renove a sua licença", + "license.status.missing.bubble": "Pronto para lançar o seu site?", + "license.status.missing.info": "Nenhuma licença válida", + "license.status.missing.label": "Por favor, ative a sua licença", + "license.manage": "Gerir as suas licenças", + "license.purchased": "Compradas", "license.success": "Obrigado por apoiar o Kirby", - "license.unregistered.label": "Unregistered", + "license.unregistered.label": "Não registadas", "link": "Link", "link.text": "Texto do link", @@ -447,10 +447,10 @@ "lock.unsaved": "Mudanças não salvas", "lock.unsaved.empty": "Não há mais mudanças não salvas", - "lock.isLocked": "Unsaved changes by {email}", + "lock.isLocked": "Alterações não guardadas de {email}", "lock.unlock": "Destrancar", - "lock.unlock.submit": "Unlock and overwrite unsaved changes by {email}", - "lock.isUnlocked": "Was unlocked by another user", + "lock.unlock.submit": "Desbloqueie e substitua alterações não guardadas de {email}", + "lock.isUnlocked": "Foi desbloqueado por outro utilizador", "login": "Entrar", "login.code.label.login": "Código de acesso", @@ -458,7 +458,7 @@ "login.code.placeholder.email": "000 0000", "login.code.placeholder.totp": "000000", "login.code.text.email": "Se seu endereço de email está registrado, o código requisitado será mandado por email.", - "login.code.text.totp": "Please enter the one‑time code from your authenticator app.", + "login.code.text.totp": "Por favor, insira o código único da sua aplicação de autenticação.", "login.email.login.body": "Oi, {user.nameOrEmail},\n\nVocê recentemente pediu um código de acesso ao painel administrativo do site {site}.\nO seguinte código será válido por {timeout} minutos:\n\n{code}\n\nSe você não pediu este código de acesso, por favor ignore esta mensagem, ou contate seu Administrador de Sistemas se você tiver dúvidas.\nPor questões de segurança, por favor NÃO compartilhe esta mensagem.", "login.email.login.subject": "Seu código de acesso", "login.email.password-reset.body": "Oi, {user.nameOrEmail},\n\nVocê recentemente pediu um código de redefinição de senha, para o painel administrativo do site {site}.\nO seguinte código de redefinição de senha será válido por {timeout} minutos:\n\n{code}\n\nSe você não pediu este código, por favor ignore esta mensagem, ou contate seu Administrador de Sistemas se você tiver dúvidas.\nPor questões de segurança, por favor NÃO compartilhe esta mensagem.", @@ -469,24 +469,24 @@ "login.toggleText.code.email-password": "Entrar com senha", "login.toggleText.password-reset.email": "Esqueceu sua senha?", "login.toggleText.password-reset.email-password": "← Voltar à entrada", - "login.totp.enable.option": "Set up one‑time codes", - "login.totp.enable.intro": "Authenticator apps can generate one‑time codes that are used as a second factor when signing into your account.", - "login.totp.enable.qr.label": "1. Scan this QR code", - "login.totp.enable.qr.help": "Unable to scan? Add the setup key {secret} manually to your authenticator app.", - "login.totp.enable.confirm.headline": "2. Confirm with generated code", - "login.totp.enable.confirm.text": "Your app generates a new one‑time code every 30 seconds. Enter the current code to complete the setup:", - "login.totp.enable.confirm.label": "Current code", - "login.totp.enable.confirm.help": "After this setup, we will ask you for a one‑time code every time you log in.", - "login.totp.enable.success": "One‑time codes enabled", - "login.totp.disable.option": "Disable one‑time codes", - "login.totp.disable.label": "Enter your password to disable one‑time codes", - "login.totp.disable.help": "In the future, a different second factor like a login code sent via email will be requested when you log in. You can always set up one‑time codes again later.", - "login.totp.disable.admin": "

This will disable one‑time codes for {user}.

In the future, a different second factor like a login code sent via email will be requested when they log in. {user} can set up one‑time codes again after their next login.

", - "login.totp.disable.success": "One‑time codes disabled", + "login.totp.enable.option": "Configurar códigos únicos", + "login.totp.enable.intro": "As aplicações de autenticação podem gerar códigos únicos que são utilizados como um segundo fator ao iniciar a sessão na sua conta.", + "login.totp.enable.qr.label": "1. Leia este código QR", + "login.totp.enable.qr.help": "Não consegue ler o código? Adicione a chave de configuração {secret} manualmente à sua aplicação de autenticação.", + "login.totp.enable.confirm.headline": "2. Confirme com o código gerado", + "login.totp.enable.confirm.text": "A sua aplicação gera um novo código único a cada 30 segundos. Insira o código atual para concluir a configuração:", + "login.totp.enable.confirm.label": "Código atual", + "login.totp.enable.confirm.help": "Após esta configuração, iremos solicitar um código único sempre que iniciar a sessão.", + "login.totp.enable.success": "Códigos únicos ativados", + "login.totp.disable.option": "Desativar códigos únicos", + "login.totp.disable.label": "Insira a sua palavra-passe para desativar códigos únicos", + "login.totp.disable.help": "No futuro, um segundo fator diferente, como um código de início de sessão enviado por e-mail, será solicitado quando iniciar a sessão. Poderá configurar códigos únicos novamente mais tarde.", + "login.totp.disable.admin": "Isto irá desactivar os códigos únicos para {user}. No futuro, um segundo fator diferente, como um código de início de sessão enviado por e-mail, será solicitado quando eles iniciarem a sessão. {user} poderá configurar códigos únicos novamente após o próximo início de sessão.", + "login.totp.disable.success": "Códigos únicos desativados", "logout": "Sair", - "merge": "Merge", + "merge": "Unir", "menu": "Menu", "meridiem": "AM/PM", "mime": "Tipo de mídia", @@ -507,19 +507,19 @@ "months.september": "Setembro", "more": "Mais", - "move": "Move", + "move": "Mover", "name": "Nome", "next": "Próximo", - "night": "Night", + "night": "Noite", "no": "não", "off": "não", "on": "sim", "open": "Abrir", "open.newWindow": "Abrir em nova janela", - "option": "Option", + "option": "Opção", "options": "Opções", "options.none": "Nenhuma opção", - "options.all": "Show all {count} options", + "options.all": "Mostrar todas as {count} opções", "orientation": "Orientação", "orientation.landscape": "Paisagem", @@ -534,15 +534,15 @@ "page.changeStatus.position": "Selecione uma posição", "page.changeStatus.select": "Selecione um novo estado", "page.changeTemplate": "Alterar tema", - "page.changeTemplate.notice": "Changing the page's template will remove content for fields that don't match in type. Use with caution.", - "page.create": "Create as {status}", + "page.changeTemplate.notice": "Alterar o template da página irá remover o conteúdo dos campos que não correspondem ao mesmo tipo. Use com cuidado.", + "page.create": "Criar como {status}", "page.delete.confirm": "Deseja realmente deletar {title}?", "page.delete.confirm.subpages": "Esta página possui subpáginas.
Todas as subpáginas serão excluídas também.", "page.delete.confirm.title": "Digite o título da página para confirmar", "page.duplicate.appendix": "Copiar", "page.duplicate.files": "Copiar arquivos", "page.duplicate.pages": "Copiar páginas", - "page.move": "Move page", + "page.move": "Mover página", "page.sort": "Mudar posição", "page.status": "Estado", "page.status.draft": "Rascunho", @@ -563,7 +563,7 @@ "password": "Senha", "paste": "Colar", "paste.after": "Colar após", - "paste.success": "{count} pasted!", + "paste.success": "{count} colados!", "pixel": "Pixel", "plugin": "Plugin", "plugins": "Plugins", @@ -571,9 +571,9 @@ "preview": "Visualizar", "remove": "Remover", "rename": "Renomear", - "renew": "Renew", + "renew": "Renovar", "replace": "Substituir", - "replace.with": "Replace with", + "replace.with": "Substituir por", "retry": "Tentar novamente", "revert": "Descartar", "revert.confirm": "Deseja realmente deletar todas as mudanças não salvas?", @@ -590,13 +590,13 @@ "save": "Salvar", "search": "Buscar", "search.min": "Digite {min} caracteres para fazer uma busca", - "search.all": "Show all {count} results", + "search.all": "Mostrar todos os {count} resultados", "search.results.none": "Nenhum resultado", - "section.invalid": "The section is invalid", + "section.invalid": "A secção é inválida", "section.required": "Esta seção é obrigatória", - "security": "Security", + "security": "Segurança", "select": "Selecionar", "server": "Servidor", "settings": "Configurações", @@ -605,40 +605,40 @@ "size": "Tamanho", "slug": "Anexo de URL", "sort": "Ordenar", - "sort.drag": "Drag to sort …", - "split": "Split", + "sort.drag": "Arraste para ordenar ...", + "split": "Dividir", - "stats.empty": "No reports", + "stats.empty": "Nenhum relatório", "status": "Estado", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", - "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", - "system.issues.eol.php": "Your installed PHP release { release } has reached end-of-life and will not receive further security updates", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", - "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", - "system.updateStatus": "Update status", - "system.updateStatus.error": "Could not check for updates", - "system.updateStatus.not-vulnerable": "No known vulnerabilities", - "system.updateStatus.security-update": "Free security update { version } available", - "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", - "system.updateStatus.unreleased": "Unreleased version", - "system.updateStatus.up-to-date": "Up to date", - "system.updateStatus.update": "Free update { version } available", - "system.updateStatus.upgrade": "Upgrade { version } available", - - "tel": "Phone", - "tel.placeholder": "+49123456789", + "system.issues.content": "A pasta \"content\" parece não estar protegida", + "system.issues.eol.kirby": "A versão instalada do Kirby chegou ao fim da sua vida útil e não irá receber mais atualizações de segurança", + "system.issues.eol.plugin": "A versão instalada do plugin {plugin} chegou ao fim da sua vida útil e não irá receber mais atualizações de segurança", + "system.issues.eol.php": "A versão instalada {release} de PHP chegou ao fim da sua vida útil e não irá receber mais atualizações de segurança", + "system.issues.debug": "O modo debug deve ser desativado em produção", + "system.issues.git": "A pasta \".git\" parece não estar protegida", + "system.issues.https": "Nós recomendamos HTTPS para todos os seus sites", + "system.issues.kirby": "A pasta \"kirby\" parece não estar protegida", + "system.issues.site": "A pasta \"site\" parece não estar protegida", + "system.issues.vulnerability.kirby": "A sua instalação poderá ser afetada pela seguinte vulnerabilidade ({ severity } gravidade): { description }", + "system.issues.vulnerability.plugin": "A sua instalação poderá ser afetada pela seguinte vulnerabilidade no plugin { plugin } ({ severity } gravidade): { description }", + "system.updateStatus": "Atualizar estado", + "system.updateStatus.error": "Não foi possível verificar se havia atualizações", + "system.updateStatus.not-vulnerable": "Nenhuma vulnerabilidade conhecida", + "system.updateStatus.security-update": "Atualização de segurança gratuita { version } disponível", + "system.updateStatus.security-upgrade": "Atualização { version } com correções de segurança disponível", + "system.updateStatus.unreleased": "Versão não lançada", + "system.updateStatus.up-to-date": "Atualizado", + "system.updateStatus.update": "Atualização gratuita { version } disponível", + "system.updateStatus.upgrade": "Atualização { version } disponível", + + "tel": "Telefone", + "tel.placeholder": "+351 123456789", "template": "Tema", "title": "Título", "today": "Hoje", - "toolbar.button.clear": "Clear formatting", + "toolbar.button.clear": "Limpar formatação", "toolbar.button.code": "Código", "toolbar.button.bold": "Negrito", "toolbar.button.email": "Email", @@ -656,8 +656,8 @@ "toolbar.button.link": "Link", "toolbar.button.paragraph": "Parágrafo", "toolbar.button.strike": "Riscado", - "toolbar.button.sub": "Subscript", - "toolbar.button.sup": "Superscript", + "toolbar.button.sub": "Subscrito", + "toolbar.button.sup": "Sobrescrito", "toolbar.button.ol": "Lista ordenada", "toolbar.button.underline": "Sublinhado", "toolbar.button.ul": "Lista não-ordenada", @@ -667,7 +667,7 @@ "translation.name": "Português do Brasil", "translation.locale": "pt_BR", - "type": "Type", + "type": "Tipo", "upload": "Enviar", "upload.error.cantMove": "O arquivo carregado não pôde ser movido", @@ -704,9 +704,9 @@ "users": "Usuários", "version": "Vers\u00e3o do Kirby", - "version.current": "Current version", - "version.latest": "Latest version", - "versionInformation": "Version information", + "version.current": "Versão atual", + "version.latest": "Versão mais recente", + "versionInformation": "Informação da versão", "view.account": "Sua conta", "view.installation": "Instala\u00e7\u00e3o", diff --git a/i18n/translations/pt_PT.json b/i18n/translations/pt_PT.json index 74944f8daa..c39fdcad31 100644 --- a/i18n/translations/pt_PT.json +++ b/i18n/translations/pt_PT.json @@ -1,28 +1,28 @@ { - "account.changeName": "Mudar seu nome", - "account.delete": "Deletar sua conta", - "account.delete.confirm": "Deseja realmente deletar sua conta? Você sairá do site imediatamente. Sua conta não poderá ser recuperada. ", + "account.changeName": "Altere o seu nome", + "account.delete": "Elimine a sua conta", + "account.delete.confirm": "Tem a certeza que pretende eliminar a sua conta? A sessão será terminada imediatamente. A sua conta não poderá ser recuperada. ", - "activate": "Activate", + "activate": "Ativar", "add": "Adicionar", "alpha": "Alpha", "author": "Autor", - "avatar": "Foto do perfil", + "avatar": "Foto de perfil", "back": "Voltar", "cancel": "Cancelar", "change": "Alterar", "close": "Fechar", - "changes": "Changes", - "confirm": "Salvar", + "changes": "Alterações", + "confirm": "Ok", "collapse": "Colapsar", "collapse.all": "Colapsar todos", - "color": "Color", - "coordinates": "Coordinates", + "color": "Cor", + "coordinates": "Coordenadas", "copy": "Copiar", "copy.all": "Copiar todos", - "copy.success": "{count} copied!", + "copy.success": "{count} copiados!", "create": "Criar", - "custom": "Custom", + "custom": "Personalizado", "date": "Data", "date.select": "Selecione uma data", @@ -38,23 +38,23 @@ "debugging": "Depuração ", - "delete": "Excluir", - "delete.all": "Deletar todos", + "delete": "Eliminar", + "delete.all": "Eliminar todos", - "dialog.fields.empty": "This dialog has no fields", - "dialog.files.empty": "Sem arquivos para selecionar", + "dialog.fields.empty": "Esta caixa de diálogo não tem campos", + "dialog.files.empty": "Sem ficheiros para selecionar", "dialog.pages.empty": "Sem páginas para selecionar", - "dialog.text.empty": "This dialog does not define any text", + "dialog.text.empty": "Esta caixa de diálogo não define nenhum texto", "dialog.users.empty": "Sem utilizadores para selecionar", "dimensions": "Dimensões", - "disable": "Disable", - "disabled": "Inativo", + "disable": "Desativar", + "disabled": "Desativado", "discard": "Descartar", - "drawer.fields.empty": "This drawer has no fields", + "drawer.fields.empty": "Esta janela não tem campos", - "domain": "Domain", + "domain": "Domínio", "download": "Descarregar", "duplicate": "Duplicar", @@ -64,231 +64,231 @@ "email.placeholder": "mail@exemplo.pt", "enter": "Enter", - "entries": "Entries", - "entry": "Entry", + "entries": "Registos", + "entry": "Registo", "environment": "Ambiente", - "error": "Error", + "error": "Erro", "error.access.code": "Código inválido", - "error.access.login": "Login inválido", + "error.access.login": "Dados de acesso inválidos", "error.access.panel": "Não tem permissões para aceder ao painel", - "error.access.view": "Não tem permissões para aceder a esta área do Painel", + "error.access.view": "Não tem permissões para aceder a esta área do painel", - "error.avatar.create.fail": "A foto de perfil não foi enviada", - "error.avatar.delete.fail": "A foto do perfil não foi excluída", + "error.avatar.create.fail": "Não foi possível enviar a foto de perfil", + "error.avatar.delete.fail": "Não foi possível eliminar a foto de perfil", "error.avatar.dimensions.invalid": "Por favor, use uma foto de perfil com largura e altura menores que 3000 pixels", - "error.avatar.mime.forbidden": "A foto de perfil deve ser um arquivo JPEG ou PNG", + "error.avatar.mime.forbidden": "A foto de perfil deve ser um ficheiro JPEG ou PNG", - "error.blueprint.notFound": "O blueprint \"{name}\" não pode ser carregado", + "error.blueprint.notFound": "Não foi possível carregar o blueprint \"{name}\"", - "error.blocks.max.plural": "Você não deve adicionar mais do que {max} blocos", - "error.blocks.max.singular": "Você não deve adicionar mais do que um bloco", - "error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos", - "error.blocks.min.singular": "Você deve adicionar pelo menos um bloco", - "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + "error.blocks.max.plural": "Não pode adicionar mais do que {max} blocos", + "error.blocks.max.singular": "Não pode adicionar mais do que um bloco", + "error.blocks.min.plural": "Tem de adicionar pelo menos {min} blocos", + "error.blocks.min.singular": "Tem de adicionar pelo menos um bloco", + "error.blocks.validation": "Há um erro no campo \"{field}\" no bloco {index} a usar o tipo de bloco \"{fieldset}\"", - "error.cache.type.invalid": "Invalid cache type \"{type}\"", + "error.cache.type.invalid": "Tipo de cache \"{type}\" inválido", - "error.email.preset.notFound": "Preset de email \"{name}\" não encontrado", + "error.email.preset.notFound": "A predefinição de email \"{name}\" não foi encontrada", "error.field.converter.invalid": "Conversor \"{converter}\" inválido", - "error.field.type.missing": "Field \"{ name }\": The field type \"{ type }\" does not exist", + "error.field.type.missing": "Campo \"{name}\": O tipo de campo \"{type}\" não existe", "error.file.changeName.empty": "O nome não pode ficar em branco", "error.file.changeName.permission": "Não tem permissões para alterar o nome de \"{filename}\"", - "error.file.changeTemplate.invalid": "The template for the file \"{id}\" cannot be changed to \"{template}\" (valid: \"{blueprints}\")", - "error.file.changeTemplate.permission": "You are not allowed to change the template for the file \"{id}\"", + "error.file.changeTemplate.invalid": "O template para o ficheiro \"{id}\" não pode ser alterado para \"{template}\" (válido: \"{blueprints}\")", + "error.file.changeTemplate.permission": "Não tem permissão para alterar o template do ficheiro \"{id}\"", - "error.file.duplicate": "Um arquivo com o nome \"{filename}\" já existe", - "error.file.extension.forbidden": "Extensão \"{extension}\" não permitida", + "error.file.duplicate": "Um ficheiro com o nome \"{filename}\" já existe", + "error.file.extension.forbidden": "A extensão \"{extension}\" não é permitida", "error.file.extension.invalid": "Extensão inválida: {extension}", - "error.file.extension.missing": "Extensão de \"{filename}\" em falta", + "error.file.extension.missing": "As extensões de \"{filename}\" estão em falta", "error.file.maxheight": "A altura da imagem não deve exceder {height} pixels", - "error.file.maxsize": "O arquivo é muito grande", + "error.file.maxsize": "O ficheiro é demasiado grande", "error.file.maxwidth": "A largura da imagem não deve exceder {width} pixels", - "error.file.mime.differs": "O arquivo enviado precisa ser do tipo \"{mime}\"", - "error.file.mime.forbidden": "Tipo de mídia \"{mime}\" não permitido", + "error.file.mime.differs": "O ficheiro enviado precisa de ser do tipo \"{mime}\"", + "error.file.mime.forbidden": "O tipo de mídia \"{mime}\" não é permitido", "error.file.mime.invalid": "Tipo de mídia inválido: {mime}", - "error.file.mime.missing": "Tipo de mídia de \"{filename}\" não detectado", - "error.file.minheight": "A altura da imagem deve ser pelo menos {height} pixels", - "error.file.minsize": "O ficheiro é muito pequeno", - "error.file.minwidth": "A largura da imagem deve ser pelo menos {width} pixels", - "error.file.name.unique": "The filename must be unique", - "error.file.name.missing": "O nome do arquivo não pode ficar em branco", - "error.file.notFound": "Arquivo \"{filename}\" não encontrado", + "error.file.mime.missing": "Não foi possível detectar o tipo de mídia de \"{filename}\"", + "error.file.minheight": "A altura da imagem deve ter pelo menos {height} pixels", + "error.file.minsize": "O ficheiro é demasiado pequeno", + "error.file.minwidth": "A largura da imagem deve ter pelo menos {width} pixels", + "error.file.name.unique": "O nome do ficheiro deve ser único", + "error.file.name.missing": "O nome do ficheiro não pode ficar em branco", + "error.file.notFound": "Não foi possível encontrar o ficheiro \"{filename}\"", "error.file.orientation": "A orientação da imagem deve ser \"{orientation}\"", - "error.file.type.forbidden": "Não tem permissões para enviar arquivos {type}", - "error.file.type.invalid": "Tipo inválido de arquivo: {type}", - "error.file.undefined": "Arquivo n\u00e3o encontrado", + "error.file.type.forbidden": "Não tem permissões para enviar ficheiros {type}", + "error.file.type.invalid": "Tipo de ficheiro inválido: {type}", + "error.file.undefined": "Não foi possível encontrar o ficheiro", - "error.form.incomplete": "Por favor, corrija os erros do formulário…", - "error.form.notSaved": "O formulário não foi guardado", + "error.form.incomplete": "Por favor, corrija todos os erros do formulário…", + "error.form.notSaved": "Não foi possível guardar o formulário", - "error.language.code": "Insira um código de idioma válido", + "error.language.code": "Por favor, insira um código válido para o idioma", "error.language.duplicate": "O idioma já existe", - "error.language.name": "Insira um nome válido para o idioma", - "error.language.notFound": "O idioma não foi encontrado", + "error.language.name": "Por favor, insira um nome válido para o idioma", + "error.language.notFound": "Não foi possível encontrar o idoma", - "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.block": "Há um erro no campo \"{field}\" no bloco {blockIndex} a usar o tipo de bloco \"{fieldset}\" no layout {layoutIndex}", "error.layout.validation.settings": "Há um erro na configuração do layout {index}", - "error.license.domain": "The domain for the license is missing", - "error.license.email": "Digite um endereço de email válido", - "error.license.format": "Please enter a valid license code", + "error.license.domain": "O domínio da licença está em falta", + "error.license.email": "Por favor, insira um endereço de email válido", + "error.license.format": "Por favor, insira um código de licença válido", "error.license.verification": "Não foi possível verificar a licença", "error.login.totp.confirm.invalid": "Código inválido", - "error.login.totp.confirm.missing": "Please enter the current code", + "error.login.totp.confirm.missing": "Por favor, insira o código atual", - "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + "error.object.validation": "Há um erro no campo \"{label}\":\n{message}", - "error.offline": "O painel está offline no momento", + "error.offline": "O painel encontra-se offline de momento", - "error.page.changeSlug.permission": "Não tem permissões para alterar a URL de \"{slug}\"", - "error.page.changeSlug.reserved": "The path of top-level pages must not start with \"{path}\"", - "error.page.changeStatus.incomplete": "A página possui erros e não pode ser guardada", + "error.page.changeSlug.permission": "Não tem permissões para alterar o URL de \"{slug}\"", + "error.page.changeSlug.reserved": "O caminho das páginas de nível superior não deve começar com \"{path}\"", + "error.page.changeStatus.incomplete": "A página tem erros e não pode ser publicada", "error.page.changeStatus.permission": "O estado desta página não pode ser alterado", "error.page.changeStatus.toDraft.invalid": "A página \"{slug}\" não pode ser convertida para rascunho", - "error.page.changeTemplate.invalid": "O tema da página \"{slug}\" não pode ser alterado", - "error.page.changeTemplate.permission": "Não tem permissões para alterar o tema de \"{slug}\"", + "error.page.changeTemplate.invalid": "O template da página \"{slug}\" não pode ser alterado", + "error.page.changeTemplate.permission": "Não tem permissões para alterar o template de \"{slug}\"", "error.page.changeTitle.empty": "O título não pode ficar em branco", "error.page.changeTitle.permission": "Não tem permissões para alterar o título de \"{slug}\"", "error.page.create.permission": "Não tem permissões para criar \"{slug}\"", - "error.page.delete": "A página \"{slug}\" não pode ser excluída", - "error.page.delete.confirm": "Por favor, digite o título da página para confirmar", - "error.page.delete.hasChildren": "A página possui subpáginas e não pode ser excluída", - "error.page.delete.permission": "Não tem permissões para excluir \"{slug}\"", - "error.page.draft.duplicate": "Um rascunho de página com a URL \"{slug}\" já existe", - "error.page.duplicate": "Uma página com a URL \"{slug}\" já existe", - "error.page.duplicate.permission": "Não tem permissão para duplicar \"{slug}\"", - "error.page.move.ancestor": "The page cannot be moved into itself", - "error.page.move.directory": "The page directory cannot be moved", - "error.page.move.duplicate": "A sub page with the URL appendix \"{slug}\" already exists", - "error.page.move.notFound": "The moved page could not be found", - "error.page.move.permission": "You are not allowed to move \"{slug}\"", - "error.page.move.template": "The \"{template}\" template is not accepted as a subpage of \"{parent}\"", - "error.page.notFound": "Página\"{slug}\" não encontrada", - "error.page.num.invalid": "Digite um número de ordenação válido. Este número não pode ser negativo.", - "error.page.slug.invalid": "Por favor entre um anexo de URL válido ", - "error.page.slug.maxlength": "O slug não pode conter mais do que \"{length}\" caracteres", - "error.page.sort.permission": "A página \"{slug}\" não pode ser ordenada", + "error.page.delete": "A página \"{slug}\" não pode ser eliminada", + "error.page.delete.confirm": "Por favor, insira o título da página para confirmar", + "error.page.delete.hasChildren": "A página tem subpáginas e não pode ser eliminada", + "error.page.delete.permission": "Não tem permissões para eliminar \"{slug}\"", + "error.page.draft.duplicate": "Uma página de rascunho com o URL \"{slug}\" já existe", + "error.page.duplicate": "Uma página com o URL \"{slug}\" já existe", + "error.page.duplicate.permission": "Não tem permissões para duplicar \"{slug}\"", + "error.page.move.ancestor": "A página não pode ser movida para dentro dela mesma", + "error.page.move.directory": "A pasta da página não pode ser movida", + "error.page.move.duplicate": "Já existe uma subpágina com o URL \"{slug}\"", + "error.page.move.notFound": "A página movida não foi encontrada", + "error.page.move.permission": "Não tem permissões para mover \"{slug}\"", + "error.page.move.template": "O template \"{template}\" não é aceite como subpágina de \"{parent}\"", + "error.page.notFound": "Não foi possível encontrar a página \"{slug}\"", + "error.page.num.invalid": "Por favor, insira um número de ordenação válido. Este número não pode ser negativo.", + "error.page.slug.invalid": "Por favor, insira um caminho de URL válido ", + "error.page.slug.maxlength": "O URL não pode conter mais do que \"{length}\" caracteres", + "error.page.sort.permission": "Não é possível ordenar a página \"{slug}\"", "error.page.status.invalid": "Por favor, defina um estado de página válido", - "error.page.undefined": "P\u00e1gina n\u00e3o encontrada", + "error.page.undefined": "Não foi possível encontrar a página", "error.page.update.permission": "Não tem permissões para atualizar \"{slug}\"", - "error.section.files.max.plural": "Não pode adicionar mais do que {max} arquivos à seção \"{section}\"", - "error.section.files.max.singular": "Não pode adicionar mais do que um arquivo à seção \"{section}\"", - "error.section.files.min.plural": "A secção \"{section}\" requer no mínimo {min} arquivos", - "error.section.files.min.singular": "A secção \"{section}\" requer no mínimo um arquivo", + "error.section.files.max.plural": "Não pode adicionar mais do que {max} ficheiros à secção \"{section}\"", + "error.section.files.max.singular": "Não pode adicionar mais do que um ficheiro à secção \"{section}\"", + "error.section.files.min.plural": "A secção \"{section}\" requer no mínimo {min} ficheiros", + "error.section.files.min.singular": "A secção \"{section}\" requer no mínimo um ficheiro", - "error.section.pages.max.plural": "Não pode adicionar mais do que {max} página à seção \"{section}\"", - "error.section.pages.max.singular": "Não pode adicionar mais do que uma página à seção \"{section}\"", + "error.section.pages.max.plural": "Não pode adicionar mais do que {max} páginas à secção \"{section}\"", + "error.section.pages.max.singular": "Não pode adicionar mais do que uma página à secção \"{section}\"", "error.section.pages.min.plural": "A secção \"{section}\" requer no mínimo {min} páginas", "error.section.pages.min.singular": "A secção \"{section}\" requer no mínimo uma página", - "error.section.notLoaded": "A seção \"{name}\" não pôde ser carregada", - "error.section.type.invalid": "O tipo da seção \"{type}\" não é válido", + "error.section.notLoaded": "Não foi possível carregar a secção \"{name}\"", + "error.section.type.invalid": "O tipo de secção \"{type}\" não é válido", "error.site.changeTitle.empty": "O título não pode ficar em branco", "error.site.changeTitle.permission": "Não tem permissões para alterar o título do site", "error.site.update.permission": "Não tem permissões para atualizar o site", - "error.structure.validation": "There's an error on the \"{field}\" field in row {index}", + "error.structure.validation": "Existe um erro no campo \"{field}\" na linha {index}", - "error.template.default.notFound": "O tema padrão não existe", + "error.template.default.notFound": "O template \"default\" não existe", - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + "error.unexpected": "Ocorreu um erro inesperado! Ative o modo de debug para obter mais informações: https://getkirby.com/docs/reference/system/options/debug", "error.user.changeEmail.permission": "Não tem permissões para alterar o email do utilizador \"{name}\"", "error.user.changeLanguage.permission": "Não tem permissões para alterar o idioma do utilizador \"{name}\"", "error.user.changeName.permission": "Não tem permissões para alterar o nome do utilizador \"{name}\"", "error.user.changePassword.permission": "Não tem permissões para alterar a palavra-passe do utilizador \"{name}\"", - "error.user.changeRole.lastAdmin": "A função do último administrador não pode ser alterado", + "error.user.changeRole.lastAdmin": "A função do último administrador não pode ser alterada", "error.user.changeRole.permission": "Não tem permissões para alterar a função do utilizador \"{name}\"", "error.user.changeRole.toAdmin": "Não tem permissões para promover utilizadores à função de administrador", "error.user.create.permission": "Não tem permissões para criar este utilizador", - "error.user.delete": "O utilizador \"{name}\" não pode ser excluído", - "error.user.delete.lastAdmin": "O último administrador não pode ser excluído", - "error.user.delete.lastUser": "O último utilizador não pode ser excluído", - "error.user.delete.permission": "Não tem permissões para excluir o utilizador \"{name}\"", - "error.user.duplicate": "Um utilizador com o email \"{email}\" já existe", - "error.user.email.invalid": "Digite um endereço de email válido", - "error.user.language.invalid": "Digite um idioma válido", - "error.user.notFound": "Utilizador \"{name}\" não encontrado", - "error.user.password.excessive": "Please enter a valid password. Passwords must not be longer than 1000 characters.", - "error.user.password.invalid": "Digite uma palavra-passe válida. A sua palavra-passe deve ter pelo menos 8 caracteres.", - "error.user.password.notSame": "As palavras-passe não combinam", - "error.user.password.undefined": "O utilizador não possui uma palavra-passe", - "error.user.password.wrong": "Senha errada", - "error.user.role.invalid": "Digite uma função válida", - "error.user.undefined": "Usuário não encontrado", + "error.user.delete": "Não é possível eliminar o utilizador \"{name}\"", + "error.user.delete.lastAdmin": "Não é possível eliminar o último administrador", + "error.user.delete.lastUser": "Não é possível eliminar o último utilizador", + "error.user.delete.permission": "Não tem permissões para eliminar o utilizador \"{name}\"", + "error.user.duplicate": "Já existe um utilizador com o email \"{email}\"", + "error.user.email.invalid": "Por favor, insira um endereço de email válido", + "error.user.language.invalid": "Por favor, insira um idioma válido", + "error.user.notFound": "Não foi possível encontrar o utilizador \"{name}\"", + "error.user.password.excessive": "Por favor, insira uma palavra-passe válida. As palavras-passe não devem ter mais do que 1000 caracteres.", + "error.user.password.invalid": "Por favor, insira uma palavra-passe válida. As palavras-passe devem ter pelo menos 8 caracteres.", + "error.user.password.notSame": "As palavras-passe não coincidem", + "error.user.password.undefined": "O utilizador não tem uma palavra-passe", + "error.user.password.wrong": "Palavra-passe errada", + "error.user.role.invalid": "Por favor, insira uma função válida", + "error.user.undefined": "Não foi possível encontrar o utilizador", "error.user.update.permission": "Não tem permissões para atualizar o utilizador \"{name}\"", "error.validation.accepted": "Por favor, confirme", - "error.validation.alpha": "Por favor, use apenas caracteres entre a-z", - "error.validation.alphanum": "Por favor, use apenas caracteres entre a-z ou 0-9", - "error.validation.anchor": "Please enter a correct link anchor", - "error.validation.between": "Digite um valor entre \"{min}\" e \"{max}\"", + "error.validation.alpha": "Por favor, insira apenas caracteres entre a-z", + "error.validation.alphanum": "Por favor, insira apenas caracteres entre a-z ou 0-9", + "error.validation.anchor": "Por favor, insira uma âncora de link correta", + "error.validation.between": "Por favor, insira um valor entre \"{min}\" e \"{max}\"", "error.validation.boolean": "Por favor, confirme ou rejeite", - "error.validation.color": "Please enter a valid color in the {format} format", - "error.validation.contains": "Digite um valor que contenha \"{needle}\"", - "error.validation.date": "Escolha uma data válida", - "error.validation.date.after": "Escolha uma data posterior a {date}", - "error.validation.date.before": "Escolha uma data anterior a {date}", - "error.validation.date.between": "Escolha uma data compreendida entre {min} e {max}", - "error.validation.denied": "Por favor, cancele", - "error.validation.different": "O valor deve ser diferente de \"{other}\"", - "error.validation.email": "Digite um endereço de email válido", - "error.validation.endswith": "O valor deve terminar com \"{end}\"", - "error.validation.filename": "Digite um nome de arquivo válido", - "error.validation.in": "Digite um destes valores: ({in})", - "error.validation.integer": "Digite um número inteiro válido", - "error.validation.ip": "Digite um endereço de IP válido", - "error.validation.less": "Digite um valor menor que {max}", - "error.validation.linkType": "The link type is not allowed", - "error.validation.match": "O valor não combina com o padrão esperado", - "error.validation.max": "Digite um valor igual ou menor que {max}", - "error.validation.maxlength": "Digite um valor curto. (no máximo {max} caracteres)", - "error.validation.maxwords": "Digite menos que {max} palavra(s)", - "error.validation.min": "Digite um valor igual ou maior que {min}", - "error.validation.minlength": "Digite um valor maior. (no mínimo {min} caracteres)", - "error.validation.minwords": "Digite ao menos {min} palavra(s)", - "error.validation.more": "Digite um valor maior que {min}", - "error.validation.notcontains": "Digite um valor que não contenha \"{needle}\"", - "error.validation.notin": "Não digite nenhum destes valores: ({notIn})", - "error.validation.option": "Escolha uma opção válida", - "error.validation.num": "Digite um número válido", - "error.validation.required": "Digite algo", - "error.validation.same": "Por favor, digite \"{other}\"", - "error.validation.size": "O tamanho do valor deve ser \"{size}\"", - "error.validation.startswith": "O valor deve começar com \"{start}\"", - "error.validation.tel": "Please enter an unformatted phone number", - "error.validation.time": "Digite uma hora válida", - "error.validation.time.after": "Por favor entre um horário depois de {time}", - "error.validation.time.before": "Por favor entre um horário antes de {time}", - "error.validation.time.between": "Por favor entre um horário entre {min} e {max}", - "error.validation.uuid": "Please enter a valid UUID", - "error.validation.url": "Digite uma URL válida", + "error.validation.color": "Por favor, insira uma cor válida no formato {format}", + "error.validation.contains": "Por favor, insira um valor que contenha \"{needle}\"", + "error.validation.date": "Por favor, insira uma data válida", + "error.validation.date.after": "Por favor, insira uma data posterior a {date}", + "error.validation.date.before": "Por favor, insira uma data anterior a {date}", + "error.validation.date.between": "Por favor, insira uma data entre {min} e {max}", + "error.validation.denied": "Por favor, rejeite", + "error.validation.different": "O valor tem de ser diferente de \"{other}\"", + "error.validation.email": "Por favor, insira um endereço de email válido", + "error.validation.endswith": "O valor tem de terminar com \"{end}\"", + "error.validation.filename": "Por favor, insira um nome de ficheiro válido", + "error.validation.in": "Por favor, insira um dos seguintes valores: ({in})", + "error.validation.integer": "Por favor, insira um número inteiro válido", + "error.validation.ip": "Por favor, insira um endereço de IP válido", + "error.validation.less": "Por favor, insira um valor menor que {max}", + "error.validation.linkType": "O tipo de link não é permitido", + "error.validation.match": "O valor não corresponde ao padrão esperado", + "error.validation.max": "Por favor, insira um valor igual ou menor que {max}", + "error.validation.maxlength": "Por favor, insira um valor mais curto. (máximo {max} caracteres)", + "error.validation.maxwords": "Por favor, não insira mais que {max} palavra(s)", + "error.validation.min": "Por favor, insira um valor igual ou maior que {min}", + "error.validation.minlength": "Por favor, insira um valor mais longo. (mínimo {min} caracteres)", + "error.validation.minwords": "Por favor, insira pelo menos {min} palavra(s)", + "error.validation.more": "Por favor, insira um valor maior que {min}", + "error.validation.notcontains": "Por favor, insira um valor que não contenha \"{needle}\"", + "error.validation.notin": "Por favor, não insira nenhum destes valores: ({notIn})", + "error.validation.option": "Por favor, selecione uma opção válida", + "error.validation.num": "Por favor, insira um número válido", + "error.validation.required": "Por favor, insira algo", + "error.validation.same": "Por favor, insira \"{other}\"", + "error.validation.size": "O tamanho do valor tem de ser \"{size}\"", + "error.validation.startswith": "O valor tem de começar com \"{start}\"", + "error.validation.tel": "Por favor, insira um número de telefone não formatado", + "error.validation.time": "Por favor, insira uma hora válida", + "error.validation.time.after": "Por favor, insira uma hora posterior a {time}", + "error.validation.time.before": "Por favor, insira uma hora anterior a {time}", + "error.validation.time.between": "Por favor, insira uma hora entre {min} e {max}", + "error.validation.uuid": "Por favor, insira um UUID válido", + "error.validation.url": "Por favor, insira um URL válido", "expand": "Expandir", "expand.all": "Expandir todos", - "field.invalid": "The field is invalid", - "field.required": "Este campo é necessário", - "field.blocks.changeType": "Mudar tipo", + "field.invalid": "O campo é inválido", + "field.required": "O campo é obrigatório", + "field.blocks.changeType": "Alterar tipo", "field.blocks.code.name": "Código", "field.blocks.code.language": "Idioma", - "field.blocks.code.placeholder": "Seu código …", - "field.blocks.delete.confirm": "Deseja realmente deletar este bloco?", - "field.blocks.delete.confirm.all": "Deseja realmente deletar todos os blocos?", - "field.blocks.delete.confirm.selected": "Deseja realmente deletar os blocos selecionados?", - "field.blocks.empty": "Nenhum bloco", - "field.blocks.fieldsets.empty": "No fieldsets yet", - "field.blocks.fieldsets.label": "Por favor selecione um tipo de bloco …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to import layouts/blocks from your clipboard Only those allowed in the current field will get inserted.", + "field.blocks.code.placeholder": "O seu código …", + "field.blocks.delete.confirm": "Tem a certeza que pretende eliminar este bloco?", + "field.blocks.delete.confirm.all": "Tem a certeza que pretende eliminar todos os blocos?", + "field.blocks.delete.confirm.selected": "Tem a certeza que pretende eliminar os blocos selecionados?", + "field.blocks.empty": "Nenhum bloco ainda", + "field.blocks.fieldsets.empty": "Nenhum tipo de bloco ainda", + "field.blocks.fieldsets.label": "Por favor, selecione um tipo de bloco …", + "field.blocks.fieldsets.paste": "Pressione {{ shortcut }} para importar layouts/blocks da sua área de transferência Só serão inseridos aqueles permitidos no campo atual.", "field.blocks.gallery.name": "Galeria", - "field.blocks.gallery.images.empty": "Nenhuma imagem", + "field.blocks.gallery.images.empty": "Nenhuma imagem ainda", "field.blocks.gallery.images.label": "Imagens", "field.blocks.heading.level": "Nível ", "field.blocks.heading.name": "Título ", @@ -299,8 +299,8 @@ "field.blocks.image.crop": "Cortar", "field.blocks.image.link": "Link", "field.blocks.image.location": "Localização ", - "field.blocks.image.location.internal": "This website", - "field.blocks.image.location.external": "External source", + "field.blocks.image.location.internal": "Este website", + "field.blocks.image.location.external": "Fonte externa", "field.blocks.image.name": "Imagem", "field.blocks.image.placeholder": "Selecionar uma imagem", "field.blocks.image.ratio": "Proporção ", @@ -319,49 +319,49 @@ "field.blocks.text.placeholder": "Texto …", "field.blocks.video.caption": "Legenda", "field.blocks.video.name": "Vídeo ", - "field.blocks.video.placeholder": "Entre uma URL de vídeo ", + "field.blocks.video.placeholder": "Insira um URL de vídeo ", "field.blocks.video.url.label": "URL-Vídeo", "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - "field.files.empty": "Nenhum arquivo selecionado", + "field.files.empty": "Nenhum ficheiro selecionado ainda", - "field.layout.change": "Change layout", - "field.layout.delete": "Deletar layout", - "field.layout.delete.confirm": "Deseja realmente deletar este layout?", - "field.layout.delete.confirm.all": "Do you really want to delete all layouts?", - "field.layout.empty": "Nenhuma linha", + "field.layout.change": "Alterar layout", + "field.layout.delete": "Eliminar layout", + "field.layout.delete.confirm": "Tem a certeza que pretende eliminar este layout?", + "field.layout.delete.confirm.all": "Tem a certeza que pretende eliminar todos os layouts?", + "field.layout.empty": "Nenhuma linha ainda", "field.layout.select": "Selecionar um layout", - "field.object.empty": "No information yet", + "field.object.empty": "Nenhuma informação ainda", - "field.pages.empty": "Nenhuma página selecionada", + "field.pages.empty": "Nenhuma página selecionada ainda", - "field.structure.delete.confirm": "Deseja realmente excluir este registro?", - "field.structure.delete.confirm.all": "Do you really want to delete all entries?", - "field.structure.empty": "Nenhum registro", + "field.structure.delete.confirm": "Tem a certeza que pretende eliminar esta linha?", + "field.structure.delete.confirm.all": "Tem a certeza que pretende eliminar todos os registos?", + "field.structure.empty": "Nenhum registo ainda", - "field.users.empty": "Nenhum utilizador selecionado", + "field.users.empty": "Nenhum utilizador selecionado ainda", - "fields.empty": "No fields yet", + "fields.empty": "Nenhum campo ainda", - "file": "File", - "file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em /site/blueprints/files/{blueprint}.yml", - "file.changeTemplate": "Alterar tema", - "file.changeTemplate.notice": "Changing the file's template will remove content for fields that don't match in type. If the new template defines certain rules, e.g. image dimensions, those will also be applied irreversibly. Use with caution.", - "file.delete.confirm": "Deseja realmente excluir
{filename}?", - "file.focus.placeholder": "Set focal point", - "file.focus.reset": "Remove focal point", - "file.focus.title": "Focus", - "file.sort": "Mudar posição", + "file": "Ficheiro", + "file.blueprint": "Este ficheiro ainda não tem blueprint. Pode configurar o blueprint em /site/blueprints/files/{blueprint}.yml", + "file.changeTemplate": "Alterar template", + "file.changeTemplate.notice": "Alterar o template do ficheiro irá remover o conteúdo dos campos que não correspondem ao mesmo tipo. Se o novo template definir certas regras, por exemplo dimensões de imagem, estas também serão aplicadas irreversivelmente. Use com cuidado.", + "file.delete.confirm": "Tem a certeza que pretende eliminar
{filename}?", + "file.focus.placeholder": "Definir ponto de foco", + "file.focus.reset": "Remover ponto de foco", + "file.focus.title": "Foco", + "file.sort": "Alterar posição", - "files": "Arquivos", - "files.empty": "Nenhum arquivo", + "files": "Ficheiros", + "files.empty": "Nenhum ficheiro ainda", - "filter": "Filter", + "filter": "Filtro", "hide": "Ocultar", "hour": "Hora", - "hue": "Hue", + "hue": "Tonalidade", "import": "Importar", "info": "Info", "insert": "Inserir", @@ -370,126 +370,126 @@ "install": "Instalar", "installation": "Instalação", - "installation.completed": "Painel instalado com sucesso", - "installation.disabled": "Por padrão, o instalador do painel está desabilitado em servidores públicos. Por favor, execute o instalador numa máquina local ou habilite a opção panel.install.", - "installation.issues.accounts": "A pasta /site/accounts não existe ou não possui permissão de escrita", - "installation.issues.content": "A pasta /content não existe ou não possui permissão de escrita", + "installation.completed": "O painel foi instalado com sucesso", + "installation.disabled": "A instalação do painel está desativada em servidores públicos por defeito. Execute a instalação numa máquina local ou ative-a com a opção panel.install.", + "installation.issues.accounts": "A pasta /site/accounts não existe ou não tem permissão de escrita", + "installation.issues.content": "A pasta /content não existe ou não tem permissão de escrita", "installation.issues.curl": "A extensão CURL é necessária", - "installation.issues.headline": "O painel não pôde ser instalado", + "installation.issues.headline": "Não foi possível instalar o painel", "installation.issues.mbstring": "A extensão MB String é necessária", - "installation.issues.media": "A pasta /media não existe ou não possui permissão de escrita", - "installation.issues.php": "Certifique-se que você está usando o PHP 8+", + "installation.issues.media": "A pasta /media não existe ou não tem permissão de escrita", + "installation.issues.php": "Certifique-se que está a usar o PHP 8+", "installation.issues.server": "O Kirby necessita do Apache, Nginx ou Caddy", - "installation.issues.sessions": "A pasta /site/sessions não existe ou não possui permissão de escrita", + "installation.issues.sessions": "A pasta /site/sessions não existe ou não tem permissão de escrita", "language": "Idioma", "language.code": "Código", - "language.convert": "Tornar padrão", - "language.convert.confirm": "

Deseja realmente converter {name} para o idioma padrão? Esta ação não poderá ser revertida.

Se {name} tiver conteúdo não traduzido, partes do seu site poderão ficar sem conteúdo.

", - "language.create": "Adicionar novo idioma", - "language.default": "Idioma padrão", - "language.delete.confirm": "Deseja realmente excluir o idioma {name} incluíndo todas as traduções? Esta ação não poderá ser revertida!", - "language.deleted": "Idioma excluído", + "language.convert": "Definir como por defeito", + "language.convert.confirm": "

Tem a certeza que pretende converter {name} para o idioma por defeito? Esta ação não pode ser revertida.

Se {name} tiver conteúdo não traduzido, partes do site podem ficar sem conteúdo.

", + "language.create": "Adicionar um novo idioma", + "language.default": "Idioma por defeito", + "language.delete.confirm": "Tem a certeza que pretende eliminar o idioma {name} incluindo todas as traduções? Esta ação não pode ser revertida!", + "language.deleted": "O idioma foi eliminado", "language.direction": "Direção de leitura", "language.direction.ltr": "Esquerda para direita", "language.direction.rtl": "Direita para esquerda", "language.locale": "String de localização do PHP", "language.locale.warning": "Está a usar configurações de localização personalizadas. Corrija as mesmas no ficheiro /site/languages", "language.name": "Nome", - "language.secondary": "Secondary language", - "language.settings": "Language settings", - "language.updated": "Idioma atualizado", - "language.variables": "Language variables", - "language.variables.empty": "No translations yet", + "language.secondary": "Idioma secundário", + "language.settings": "Configurações de idioma", + "language.updated": "O idioma foi atualizado", + "language.variables": "Variáveis de idioma", + "language.variables.empty": "Nenhuma tradução ainda", - "language.variable.delete.confirm": "Do you really want to delete the variable for {key}?", - "language.variable.key": "Key", - "language.variable.notFound": "The variable could not be found", - "language.variable.value": "Value", + "language.variable.delete.confirm": "Tem a certeza que pretende eliminar a variável {key}?", + "language.variable.key": "Chave", + "language.variable.notFound": "Não foi possível encontrar a variável", + "language.variable.value": "Valor", "languages": "Idiomas", "languages.default": "Idioma padrão", - "languages.empty": "Nenhum idioma", + "languages.empty": "Nenhum idioma ainda", "languages.secondary": "Idiomas secundários", - "languages.secondary.empty": "Nenhum idioma secundário", - - "license": "Licen\u00e7a do Kirby ", - "license.activate": "Activate it now", - "license.activate.label": "Please activate your license", - "license.activate.domain": "Your license will be activated for {host}.", - "license.activate.local": "You are about to activate your Kirby license for your local domain {host}. If this site will be deployed to a public domain, please activate it there instead. If {host} is the domain you want to use your license for, please continue.", - "license.activated": "Activated", - "license.buy": "Comprar uma licença", + "languages.secondary.empty": "Nenhum idioma secundário ainda", + + "license": "Licença ", + "license.activate": "Ativar agora", + "license.activate.label": "Por favor, ative a sua licença", + "license.activate.domain": "A sua licença será ativada para {host}.", + "license.activate.local": "Está prestes a ativar a sua licença Kirby no domínio local {host}. Se este site vai ser alojado num domínio público, por favor ative-o lá. Se o domínio {host} é o o que deseja para usar a sua licença, por favor continue.", + "license.activated": "Ativado", + "license.buy": "Compre uma licença", "license.code": "Código", - "license.code.help": "You received your license code after the purchase via email. Please copy and paste it here.", - "license.code.label": "Por favor, digite o código da sua licença", - "license.status.active.info": "Includes new major versions until {date}", - "license.status.active.label": "Valid license", - "license.status.demo.info": "This is a demo installation", - "license.status.demo.label": "Demo", - "license.status.inactive.info": "Renew license to update to new major versions", - "license.status.inactive.label": "No new major versions", - "license.status.legacy.bubble": "Ready to renew your license?", - "license.status.legacy.info": "Your license does not cover this version", - "license.status.legacy.label": "Please renew your license", - "license.status.missing.bubble": "Ready to launch your site?", - "license.status.missing.info": "No valid license", - "license.status.missing.label": "Please activate your license", - "license.manage": "Manage your licenses", - "license.purchased": "Purchased", + "license.code.help": "Recebeu o seu código de licença por email após a compra. Por favor, copie e cole aqui.", + "license.code.label": "Por favor, insira o código da sua licença", + "license.status.active.info": "Inclui novas versões principais até {date}", + "license.status.active.label": "Licença válida", + "license.status.demo.info": "Esta é uma instalação de demonstração", + "license.status.demo.label": "Demonstração", + "license.status.inactive.info": "Renove a licença para atualizar para novas versões principais", + "license.status.inactive.label": "Nenhuma versão principal nova", + "license.status.legacy.bubble": "Pronto para renovar a sua licença?", + "license.status.legacy.info": "A sua licença não abrange esta versão", + "license.status.legacy.label": "Por favor, renove a sua licença", + "license.status.missing.bubble": "Pronto para lançar o seu site?", + "license.status.missing.info": "Sem licença válida", + "license.status.missing.label": "Por favor, ative a sua licença", + "license.manage": "Gerir as suas licenças", + "license.purchased": "Comprada", "license.success": "Obrigado por apoiar o Kirby", - "license.unregistered.label": "Unregistered", + "license.unregistered.label": "Não registada", "link": "Link", "link.text": "Texto do link", "loading": "A carregar", - "lock.unsaved": "Alterações por guardar", - "lock.unsaved.empty": "Não existem alterações por guardar", - "lock.isLocked": "Unsaved changes by {email}", + "lock.unsaved": "Alterações não guardadas", + "lock.unsaved.empty": "Não existem mais alterações não guardadas", + "lock.isLocked": "Alterações não guardadas de {email}", "lock.unlock": "Desbloquear", - "lock.unlock.submit": "Unlock and overwrite unsaved changes by {email}", - "lock.isUnlocked": "Was unlocked by another user", + "lock.unlock.submit": "Desbloqueie e substitua alterações não guardadas de {email}", + "lock.isUnlocked": "Foi desbloqueado por outro utilizador", "login": "Entrar", - "login.code.label.login": "Código de acesso", - "login.code.label.password-reset": "Código de redefinição de senha", + "login.code.label.login": "Código de início de sessão", + "login.code.label.password-reset": "Código de redefinição de palavra-passe", "login.code.placeholder.email": "000 0000", "login.code.placeholder.totp": "000000", - "login.code.text.email": "Se seu endereço de email está registrado, o código requisitado será mandado por email.", - "login.code.text.totp": "Please enter the one‑time code from your authenticator app.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Seu código de acesso", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Seu código de redefinição de senha", - "login.remember": "Manter-me conectado", - "login.reset": "Redefinir senha", - "login.toggleText.code.email": "Entrar com email", - "login.toggleText.code.email-password": "Entrar com senha", - "login.toggleText.password-reset.email": "Esqueceu sua senha?", - "login.toggleText.password-reset.email-password": "← Voltar à entrada", - "login.totp.enable.option": "Set up one‑time codes", - "login.totp.enable.intro": "Authenticator apps can generate one‑time codes that are used as a second factor when signing into your account.", - "login.totp.enable.qr.label": "1. Scan this QR code", - "login.totp.enable.qr.help": "Unable to scan? Add the setup key {secret} manually to your authenticator app.", - "login.totp.enable.confirm.headline": "2. Confirm with generated code", - "login.totp.enable.confirm.text": "Your app generates a new one‑time code every 30 seconds. Enter the current code to complete the setup:", - "login.totp.enable.confirm.label": "Current code", - "login.totp.enable.confirm.help": "After this setup, we will ask you for a one‑time code every time you log in.", - "login.totp.enable.success": "One‑time codes enabled", - "login.totp.disable.option": "Disable one‑time codes", - "login.totp.disable.label": "Enter your password to disable one‑time codes", - "login.totp.disable.help": "In the future, a different second factor like a login code sent via email will be requested when you log in. You can always set up one‑time codes again later.", - "login.totp.disable.admin": "

This will disable one‑time codes for {user}.

In the future, a different second factor like a login code sent via email will be requested when they log in. {user} can set up one‑time codes again after their next login.

", - "login.totp.disable.success": "One‑time codes disabled", + "login.code.text.email": "Se o seu endereço de email está registado, o código solicitado foi enviado por email.", + "login.code.text.totp": "Por favor, insira o código de segurança da sua aplicação de autenticação.", + "login.email.login.body": "Olá {user.nameOrEmail},\n\nRecentemente solicitou um código de início de sessão para o Painel de {site}.\nO seguinte código de início de sessão será válido por {timeout} minutos:\n\n{code}\n\nSe não solicitou um código de início de sessão, por favor ignore este e-mail ou entre em contacto com o administrador se tiver dúvidas.\nPor motivos de segurança, por favor NÃO reencaminhe este e-mail.", + "login.email.login.subject": "O seu código de início de sessão", + "login.email.password-reset.body": "Olá {user.nameOrEmail},\n\nRecentemente solicitou um código de redefinição de palavra-passe para o Painel de {site}.\nO seguinte código de redefinição de palavra-passe será válido por {timeout} minutos:\n\n{code}\n\nSe não solicitou um código de redefinição de palavra-passe, por favor ignore este e-mail ou entre em contacto com o administrador se tiver dúvidas.\nPor motivos de segurança, por favor NÃO reencaminhe este e-mail.", + "login.email.password-reset.subject": "O seu código de redefinição de palavra-passe", + "login.remember": "Manter sessão iniciada", + "login.reset": "Redefinir palavra-passe", + "login.toggleText.code.email": "Iniciar sessão com email", + "login.toggleText.code.email-password": "Iniciar sessão com palavra-passe", + "login.toggleText.password-reset.email": "Esqueceu-se da sua palavra-passe?", + "login.toggleText.password-reset.email-password": "← Voltar à página de início de sessão", + "login.totp.enable.option": "Configurar códigos de segurança", + "login.totp.enable.intro": "As aplicações de autenticação podem gerar códigos de segurança que são usados como um segundo fator ao iniciar a sessão na sua conta.", + "login.totp.enable.qr.label": "1. Leia este código QR", + "login.totp.enable.qr.help": "Não consegue ler o código? Adicione a chave de configuração {secret} manualmente à sua aplicação de autenticação.", + "login.totp.enable.confirm.headline": "2. Confirme com o código gerado", + "login.totp.enable.confirm.text": "A sua aplicação gera um novo código de segurança a cada 30 segundos. Insira o código atual para concluir a configuração:", + "login.totp.enable.confirm.label": "Código atual", + "login.totp.enable.confirm.help": "Após esta configuração, iremos solicitar um código de segurança sempre que iniciar a sessão.", + "login.totp.enable.success": "Códigos de segurança ativados", + "login.totp.disable.option": "Desativar códigos de segurança", + "login.totp.disable.label": "Insira a sua palavra-passe para desativar códigos de segurança", + "login.totp.disable.help": "No futuro, um segundo fator diferente, como um código de início de sessão enviado por e-mail, será solicitado quando iniciar a sessão. Poderá configurar códigos únicos novamente mais tarde.", + "login.totp.disable.admin": "

Isto irá desactivar os códigos de segurança para {user}.

No futuro, um segundo fator diferente, como um código de início de sessão enviado por e-mail, será solicitado quando eles iniciarem a sessão. {user} poderá configurar códigos de segurança novamente após o próximo início de sessão.

", + "login.totp.disable.success": "Códigos de segurança desativados", "logout": "Sair", - "merge": "Merge", + "merge": "Unir", "menu": "Menu", "meridiem": "AM/PM", - "mime": "Tipo de mídia", + "mime": "Tipo de Mídia", "minutes": "Minutos", "month": "Mês", @@ -507,19 +507,19 @@ "months.september": "Setembro", "more": "Mais", - "move": "Move", + "move": "Mover", "name": "Nome", "next": "Próximo", - "night": "Night", + "night": "Noite", "no": "não", "off": "off", "on": "on", "open": "Abrir", - "open.newWindow": "Abrir em nova janela", - "option": "Option", + "open.newWindow": "Abrir numa nova janela", + "option": "Opção", "options": "Opções", "options.none": "Sem opções", - "options.all": "Show all {count} options", + "options.all": "Mostrar todas as {count} opções", "orientation": "Orientação", "orientation.landscape": "Paisagem", @@ -527,33 +527,33 @@ "orientation.square": "Quadrado", "page": "Página", - "page.blueprint": "Esta página não tem planta. Você pode definir sua planta em /site/blueprints/pages/{blueprint}.yml", + "page.blueprint": "Esta página não tem blueprint ainda. Pode configurar o blueprint em /site/blueprints/pages/{blueprint}.yml", "page.changeSlug": "Alterar URL", "page.changeSlug.fromTitle": "Criar a partir do t\u00edtulo", "page.changeStatus": "Alterar estado", "page.changeStatus.position": "Selecione uma posição", "page.changeStatus.select": "Selecione um novo estado", - "page.changeTemplate": "Alterar tema", - "page.changeTemplate.notice": "Changing the page's template will remove content for fields that don't match in type. Use with caution.", - "page.create": "Create as {status}", - "page.delete.confirm": "Deseja realmente excluir {title}?", - "page.delete.confirm.subpages": "Esta página possui subpáginas.
Todas as subpáginas serão excluídas também.", - "page.delete.confirm.title": "Digite o título da página para confirmar", + "page.changeTemplate": "Alterar template", + "page.changeTemplate.notice": "Alterar o template da página irá remover o conteúdo dos campos que não correspondem ao mesmo tipo. Use com cuidado.", + "page.create": "Criar como {status}", + "page.delete.confirm": "Tem a certeza que pretende eliminar {title}?", + "page.delete.confirm.subpages": "Esta página tem subpáginas.
Todas as subpáginas serão eliminadas também.", + "page.delete.confirm.title": "Por favor, insira o título da página para confirmar", "page.duplicate.appendix": "Copiar", - "page.duplicate.files": "Copiar arquivos", + "page.duplicate.files": "Copiar ficheiros", "page.duplicate.pages": "Copiar páginas", - "page.move": "Move page", - "page.sort": "Mudar posição", + "page.move": "Mover página", + "page.sort": "Alterar posição", "page.status": "Estado", "page.status.draft": "Rascunho", - "page.status.draft.description": "A página está em modo de rascunho e é visível somente para editores", + "page.status.draft.description": "A página está em modo de rascunho e é visível apenas para editores com sessão iniciada ou através de um link secreto", "page.status.listed": "Pública", "page.status.listed.description": "A página é pública para todos", - "page.status.unlisted": "Não listadas", - "page.status.unlisted.description": "Esta página é acessível somente através da URL", + "page.status.unlisted": "Não listada", + "page.status.unlisted.description": "Esta página é acessível apenas através de URL", "pages": "Páginas", - "pages.empty": "Nenhuma página", + "pages.empty": "Nenhuma página ainda", "pages.status.draft": "Rascunhos", "pages.status.listed": "Publicadas", "pages.status.unlisted": "Não listadas", @@ -563,82 +563,82 @@ "password": "Palavra-passe", "paste": "Colar", "paste.after": "Colar após", - "paste.success": "{count} pasted!", + "paste.success": "{count} colados!", "pixel": "Pixel", "plugin": "Plugin", "plugins": "Plugins", "prev": "Anterior", - "preview": "Visualizar", + "preview": "Pré-visualizar", "remove": "Remover", - "rename": "Renomear", - "renew": "Renew", + "rename": "Alterar nome", + "renew": "Renovar", "replace": "Substituir", - "replace.with": "Replace with", + "replace.with": "Substituir por", "retry": "Tentar novamente", - "revert": "Descartar", - "revert.confirm": "Tem a certeza que pretende eliminar todas as alterações por guardar?", + "revert": "Reverter", + "revert.confirm": "Tem a certeza que pretende eliminar todas as alterações não guardadas?", "role": "Função", - "role.admin.description": "O administrador tem todas as permissões.", + "role.admin.description": "O administrador tem todas as permissões", "role.admin.title": "Administrador", "role.all": "Todos", "role.empty": "Não há utilizadores com esta função", "role.description.placeholder": "Sem descrição", - "role.nobody.description": "Esta é uma função de salvaguarda sem permissões.", + "role.nobody.description": "Esta é uma função de recurso sem permissões", "role.nobody.title": "Ninguém", - "save": "Salvar", - "search": "Buscar", - "search.min": "Introduza {min} caracteres para pesquisar", - "search.all": "Show all {count} results", + "save": "Guardar", + "search": "Pesquisar", + "search.min": "Insira {min} caracteres para pesquisar", + "search.all": "Mostrar todos os {count} resultados", "search.results.none": "Sem resultados", - "section.invalid": "The section is invalid", - "section.required": "Esta seção é necessária", + "section.invalid": "A secção é inválida", + "section.required": "A secção é obrigatória", - "security": "Security", + "security": "Segurança", "select": "Selecionar", "server": "Servidor", "settings": "Configurações", "show": "Mostrar", - "site.blueprint": "Este site não tem planta. Você pode definir sua planta em /site/blueprints/site.yml", + "site.blueprint": "O site não tem blueprint ainda. Pode configurar o blueprint em /site/blueprints/site.yml", "size": "Tamanho", "slug": "URL", "sort": "Ordenar", - "sort.drag": "Drag to sort …", - "split": "Split", + "sort.drag": "Arraste para ordenar ...", + "split": "Dividir", - "stats.empty": "No reports", + "stats.empty": "Sem relatórios", "status": "Estado", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", - "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", - "system.issues.eol.php": "Your installed PHP release { release } has reached end-of-life and will not receive further security updates", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", - "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", - "system.updateStatus": "Update status", - "system.updateStatus.error": "Could not check for updates", - "system.updateStatus.not-vulnerable": "No known vulnerabilities", - "system.updateStatus.security-update": "Free security update { version } available", - "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", - "system.updateStatus.unreleased": "Unreleased version", - "system.updateStatus.up-to-date": "Up to date", - "system.updateStatus.update": "Free update { version } available", - "system.updateStatus.upgrade": "Upgrade { version } available", - - "tel": "Phone", - "tel.placeholder": "+49123456789", - "template": "Tema", + "system.issues.content": "A pasta content parece não estar protegida", + "system.issues.eol.kirby": "A versão instalada do Kirby chegou ao fim da sua vida útil e não irá receber mais atualizações de segurança", + "system.issues.eol.plugin": "A versão instalada do plugin { plugin } chegou ao fim da sua vida útil e não irá receber mais atualizações de segurança", + "system.issues.eol.php": "A versão instalada { release } de PHP chegou ao fim da sua vida útil e não irá receber mais atualizações de segurança", + "system.issues.debug": "O modo debug deve ser desativado em produção", + "system.issues.git": "A pasta .git parece não estar protegida", + "system.issues.https": "Nós recomendamos HTTPS para todos os seus sites", + "system.issues.kirby": "A pasta kirby parece não estar protegida", + "system.issues.site": "A pasta site parece não estar protegida", + "system.issues.vulnerability.kirby": "A sua instalação poderá ser afetada pela seguinte vulnerabilidade ({ severity } gravidade): { description }", + "system.issues.vulnerability.plugin": "A sua instalação poderá ser afetada pela seguinte vulnerabilidade no plugin { plugin } ({ severity } gravidade): { description }", + "system.updateStatus": "Atualizar estado", + "system.updateStatus.error": "Não foi possível verificar se havia atualizações", + "system.updateStatus.not-vulnerable": "Nenhuma vulnerabilidade conhecida", + "system.updateStatus.security-update": "Atualização de segurança gratuita { version } disponível", + "system.updateStatus.security-upgrade": "Atualização { version } com correções de segurança disponível", + "system.updateStatus.unreleased": "Versão não lançada", + "system.updateStatus.up-to-date": "Atualizado", + "system.updateStatus.update": "Atualização gratuita { version } disponível", + "system.updateStatus.upgrade": "Atualização { version } disponível", + + "tel": "Telefone", + "tel.placeholder": "+351912345678", + "template": "Template", "title": "Título", "today": "Hoje", - "toolbar.button.clear": "Clear formatting", + "toolbar.button.clear": "Limpar formatação", "toolbar.button.code": "Código", "toolbar.button.bold": "Negrito", "toolbar.button.email": "Email", @@ -651,35 +651,35 @@ "toolbar.button.heading.6": "Título 6", "toolbar.button.italic": "Itálico", "toolbar.button.file": "Ficheiro", - "toolbar.button.file.select": "Selecione o arquivo", - "toolbar.button.file.upload": "Carregue o arquivo", + "toolbar.button.file.select": "Selecione um ficheiro", + "toolbar.button.file.upload": "Envie um ficheiro", "toolbar.button.link": "Link", "toolbar.button.paragraph": "Parágrafo", - "toolbar.button.strike": "Riscado", - "toolbar.button.sub": "Subscript", - "toolbar.button.sup": "Superscript", + "toolbar.button.strike": "Rasurado", + "toolbar.button.sub": "Subscrito", + "toolbar.button.sup": "Sobrescrito", "toolbar.button.ol": "Lista ordenada", "toolbar.button.underline": "Sublinhado", "toolbar.button.ul": "Lista não-ordenada", - "translation.author": "Kirby Team", + "translation.author": "Equipa Kirby", "translation.direction": "ltr", - "translation.name": "Português (Europeu)", + "translation.name": "Português (Portugal)", "translation.locale": "pt_PT", - "type": "Type", + "type": "Tipo", "upload": "Enviar", - "upload.error.cantMove": "Não foi possível mover o arquivo carregado", - "upload.error.cantWrite": "Não foi possível guardar o arquivo no sistema de ficheiros.", - "upload.error.default": "Não foi possível carregar o arquivo", - "upload.error.extension": "A extensão do arquivo não permite o carregamento", - "upload.error.formSize": "O arquivo excede o tamanho MAX_FILE_SIZE", - "upload.error.iniPostSize": "O arquivo excede o tamanho post_max_size", - "upload.error.iniSize": "O arquivo carregado excede a definição upload_max_filesize do php.ini", - "upload.error.noFile": "Nenhum arquivo carregado", - "upload.error.noFiles": "Nenhuns arquivos carregados", - "upload.error.partial": "O arquivo foi parcialmente carregado", + "upload.error.cantMove": "Não foi possível mover o ficheiro enviado", + "upload.error.cantWrite": "Não foi possível guardar o ficheiro em disco", + "upload.error.default": "Não foi possível enviar o ficheiro", + "upload.error.extension": "O envio do ficheiro foi interrompido devido à extensão", + "upload.error.formSize": "O ficheiro enviado excede a diretiva MAX_FILE_SIZE especificada no formulário", + "upload.error.iniPostSize": "O ficheiro enviado excede a diretiva post_max_size do php.ini", + "upload.error.iniSize": "O ficheiro enviado excede a diretiva upload_max_filesize do php.ini", + "upload.error.noFile": "Nenhum ficheiro foi enviado", + "upload.error.noFiles": "Nenhum ficheiro foi enviado", + "upload.error.partial": "O ficheiro foi enviado apenas parcialmente", "upload.error.tmpDir": "Pasta temporária em falta", "upload.errors": "Erro", "upload.progress": "A enviar…", @@ -688,30 +688,30 @@ "url.placeholder": "https://exemplo.pt", "user": "Utilizador", - "user.blueprint": "Você pode definir seções e campos de formulário adicionais para este papel de usuário em /site/blueprints/users/{blueprint}.yml", + "user.blueprint": "Pode definir secções adicionais e campos de formulário para esta função de utilizador em /site/blueprints/users/{blueprint}.yml", "user.changeEmail": "Alterar email", "user.changeLanguage": "Alterar idioma", - "user.changeName": "Renomear este utilizador", + "user.changeName": "Alterar o nome deste utilizador", "user.changePassword": "Alterar palavra-passe", "user.changePassword.new": "Nova palavra-passe", "user.changePassword.new.confirm": "Confirme a nova palavra-passe…", - "user.changeRole": "Alterar Função", + "user.changeRole": "Alterar função", "user.changeRole.select": "Selecione uma nova função", - "user.create": "Adicionar novo utilizador", - "user.delete": "Excluir este utilizador", - "user.delete.confirm": "Deseja realmente excluir
{email}?", + "user.create": "Adicionar um novo utilizador", + "user.delete": "Eliminar este utilizador", + "user.delete.confirm": "Tem a certeza que pretende eliminar
{email}?", "users": "Utilizadores", - "version": "Vers\u00e3o do Kirby", - "version.current": "Current version", - "version.latest": "Latest version", - "versionInformation": "Version information", + "version": "Versão", + "version.current": "Versão atual", + "version.latest": "Versão mais recente", + "versionInformation": "Informação da versão", "view.account": "A sua conta", "view.installation": "Instala\u00e7\u00e3o", "view.languages": "Idiomas", - "view.resetPassword": "Redefinir senha", + "view.resetPassword": "Redefinir palavra-passe", "view.site": "Site", "view.system": "Sistema", "view.users": "Utilizadores", diff --git a/i18n/translations/tr.json b/i18n/translations/tr.json index e8ca25d6ca..949711647c 100644 --- a/i18n/translations/tr.json +++ b/i18n/translations/tr.json @@ -135,7 +135,7 @@ "error.license.domain": "Lisans için alan adı eksik", "error.license.email": "Lütfen geçerli bir e-posta adresi girin", - "error.license.format": "Please enter a valid license code", + "error.license.format": "Lütfen geçerli bir lisans anahtarı girin", "error.license.verification": "Lisans doğrulanamadı", "error.login.totp.confirm.invalid": "Geçersiz kod", @@ -425,7 +425,7 @@ "license.code.label": "Lütfen lisans kodunu giriniz", "license.status.active.info": "{date} tarihine kadar yeni ana sürümleri içerir", "license.status.active.label": "Geçerli lisans", - "license.status.demo.info": "This is a demo installation", + "license.status.demo.info": "Bu bir demo kurulumudur", "license.status.demo.label": "Demo", "license.status.inactive.info": "Yeni ana sürümlere güncellemek için lisansı yenileyin", "license.status.inactive.label": "Yeni ana sürüm yok", diff --git a/src/Cms/App.php b/src/Cms/App.php index e394af48d7..bb4c474003 100644 --- a/src/Cms/App.php +++ b/src/Cms/App.php @@ -437,8 +437,6 @@ public function contentToken(mixed $model, string $value): string /** * Calls a page controller by name * and with the given arguments - * - * @internal */ public function controller( string $name, diff --git a/src/Cms/License.php b/src/Cms/License.php index efd2e3d395..1716a6a061 100644 --- a/src/Cms/License.php +++ b/src/Cms/License.php @@ -391,7 +391,7 @@ public function request(string $path, array $data): array */ public function save(): bool { - if ($this->status() !== LicenseStatus::Active) { + if ($this->status()->activatable() !== true) { throw new InvalidArgumentException([ 'key' => 'license.verification' ]); diff --git a/src/Cms/LicenseStatus.php b/src/Cms/LicenseStatus.php index 51ae5da237..705099f034 100644 --- a/src/Cms/LicenseStatus.php +++ b/src/Cms/LicenseStatus.php @@ -43,6 +43,22 @@ enum LicenseStatus: string */ case Missing = 'missing'; + /** + * Checks if the license can be saved when it + * was entered in the activation dialog; + * renewable licenses are accepted as well + * to allow renewal from the Panel + */ + public function activatable(): bool + { + return match ($this) { + static::Active, + static::Inactive, + static::Legacy => true, + default => false + }; + } + /** * Returns the dialog according to the status */ @@ -95,7 +111,7 @@ public function label(): string public function renewable(): bool { return match ($this) { - static::Demo => false, + static::Demo, static::Active => false, default => true }; diff --git a/src/Http/Environment.php b/src/Http/Environment.php index 8eccc13df7..c3c3648981 100644 --- a/src/Http/Environment.php +++ b/src/Http/Environment.php @@ -753,6 +753,10 @@ public function isLocal(): bool return true; } + if (Str::endsWith($host, '.ddev.site') === true) { + return true; + } + // collect all possible visitor ips $ips = [ $this->get('REMOTE_ADDR'), diff --git a/src/Http/Url.php b/src/Http/Url.php index 622f350e93..93600409da 100644 --- a/src/Http/Url.php +++ b/src/Http/Url.php @@ -186,7 +186,7 @@ public static function short( $uri->slash = false; $url = $base ? $uri->base() : $uri->toString(); - $url = str_replace('www.', '', $url); + $url = str_replace('www.', '', $url ?? ''); return Str::short($url, $length, $rep); } diff --git a/tests/Cms/System/LicenseTest.php b/tests/Cms/System/LicenseTest.php index 66a43186f3..34b1a6a90a 100644 --- a/tests/Cms/System/LicenseTest.php +++ b/tests/Cms/System/LicenseTest.php @@ -402,7 +402,7 @@ public function testRenewal() /** * @covers ::save */ - public function testSaveWhenNotActive() + public function testSaveWhenNotActivatable() { $license = new License(); diff --git a/tests/Http/EnvironmentTest.php b/tests/Http/EnvironmentTest.php index dc9dabd9a8..d81f3f9d57 100644 --- a/tests/Http/EnvironmentTest.php +++ b/tests/Http/EnvironmentTest.php @@ -1050,6 +1050,7 @@ public function providerForServerNames() ['localhost', true], ['mydomain.local', true], ['mydomain.test', true], + ['mydomain.ddev.site', true], ['mydomain.com', false], ['mydomain.dev', false], ]; diff --git a/tests/Option/OptionsApiTest.php b/tests/Option/OptionsApiTest.php index 3396a83f90..a3b17d5158 100644 --- a/tests/Option/OptionsApiTest.php +++ b/tests/Option/OptionsApiTest.php @@ -16,7 +16,7 @@ class OptionsApiTest extends TestCase */ public function testConstruct() { - $options = new OptionsApi($url = 'https://api.getkirby.com'); + $options = new OptionsApi($url = 'https://api.example.com'); $this->assertSame($url, $options->url); $this->assertNull($options->query); $this->assertNull($options->text); @@ -28,7 +28,7 @@ public function testConstruct() */ public function testDefaults() { - $options = new OptionsApi($url = 'https://api.getkirby.com'); + $options = new OptionsApi($url = 'https://api.example.com'); $this->assertSame($url, $options->url); $this->assertNull($options->text); $this->assertNull($options->value); @@ -46,7 +46,7 @@ public function testDefaults() public function testFactory() { $options = OptionsApi::factory([ - 'url' => $url = 'https://api.getkirby.com', + 'url' => $url = 'https://api.example.com', 'query' => $query = 'Companies', 'text' => $text = '{{ item.name }}', 'value' => $value = '{{ item.id }}', @@ -57,7 +57,7 @@ public function testFactory() $this->assertSame($text, $options->text); $this->assertSame($value, $options->value); - $options = OptionsApi::factory($url = 'https://api.getkirby.com'); + $options = OptionsApi::factory($url = 'https://api.example.com'); $this->assertSame($url, $options->url); $this->assertNull($options->query); $this->assertNull($options->text); @@ -67,12 +67,12 @@ public function testFactory() /** * @covers ::load */ - public function testLoadNotFound() + public function testLoadNoJson() { $model = new Page(['slug' => 'test']); - $options = new OptionsApi(url: 'https://api.getkirby.com'); + $options = new OptionsApi(url: 'https://example.com'); $this->expectException(NotFoundException::class); - $this->expectExceptionMessage('Options could not be loaded from API: https://api.getkirby.com'); + $this->expectExceptionMessage('Options could not be loaded from API: https://example.com'); $options->resolve($model); } @@ -81,10 +81,10 @@ public function testLoadNotFound() */ public function testPolyfill() { - $api = 'https//api.getkirby.com'; + $api = 'https://api.example.com'; $this->assertSame(['url' => $api], OptionsApi::polyfill($api)); - $api = ['url' => 'https//api.getkirby.com']; + $api = ['url' => 'https://api.example.com']; $this->assertSame($api, OptionsApi::polyfill($api)); $api = ['fetch' => 'Companies']; diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 7824d8f7ea..a72151c77c 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -45,34 +45,35 @@ class ClassLoader /** @var \Closure(string):void */ private static $includeFile; - /** @var string|null */ + /** @var ?string */ private $vendorDir; // PSR-4 /** - * @var array> + * @var array[] + * @psalm-var array> */ private $prefixLengthsPsr4 = array(); /** - * @var array> + * @var array[] + * @psalm-var array> */ private $prefixDirsPsr4 = array(); /** - * @var list + * @var array[] + * @psalm-var array */ private $fallbackDirsPsr4 = array(); // PSR-0 /** - * List of PSR-0 prefixes - * - * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) - * - * @var array>> + * @var array[] + * @psalm-var array> */ private $prefixesPsr0 = array(); /** - * @var list + * @var array[] + * @psalm-var array */ private $fallbackDirsPsr0 = array(); @@ -80,7 +81,8 @@ class ClassLoader private $useIncludePath = false; /** - * @var array + * @var string[] + * @psalm-var array */ private $classMap = array(); @@ -88,20 +90,21 @@ class ClassLoader private $classMapAuthoritative = false; /** - * @var array + * @var bool[] + * @psalm-var array */ private $missingClasses = array(); - /** @var string|null */ + /** @var ?string */ private $apcuPrefix; /** - * @var array + * @var self[] */ private static $registeredLoaders = array(); /** - * @param string|null $vendorDir + * @param ?string $vendorDir */ public function __construct($vendorDir = null) { @@ -110,7 +113,7 @@ public function __construct($vendorDir = null) } /** - * @return array> + * @return string[] */ public function getPrefixes() { @@ -122,7 +125,8 @@ public function getPrefixes() } /** - * @return array> + * @return array[] + * @psalm-return array> */ public function getPrefixesPsr4() { @@ -130,7 +134,8 @@ public function getPrefixesPsr4() } /** - * @return list + * @return array[] + * @psalm-return array */ public function getFallbackDirs() { @@ -138,7 +143,8 @@ public function getFallbackDirs() } /** - * @return list + * @return array[] + * @psalm-return array */ public function getFallbackDirsPsr4() { @@ -146,7 +152,8 @@ public function getFallbackDirsPsr4() } /** - * @return array Array of classname => path + * @return string[] Array of classname => path + * @psalm-return array */ public function getClassMap() { @@ -154,7 +161,8 @@ public function getClassMap() } /** - * @param array $classMap Class to filename map + * @param string[] $classMap Class to filename map + * @psalm-param array $classMap * * @return void */ @@ -171,25 +179,24 @@ public function addClassMap(array $classMap) * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories * * @return void */ public function add($prefix, $paths, $prepend = false) { - $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - $paths, + (array) $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - $paths + (array) $paths ); } @@ -198,19 +205,19 @@ public function add($prefix, $paths, $prepend = false) $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = $paths; + $this->prefixesPsr0[$first][$prefix] = (array) $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - $paths, + (array) $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - $paths + (array) $paths ); } } @@ -219,9 +226,9 @@ public function add($prefix, $paths, $prepend = false) * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException * @@ -229,18 +236,17 @@ public function add($prefix, $paths, $prepend = false) */ public function addPsr4($prefix, $paths, $prepend = false) { - $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - $paths, + (array) $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - $paths + (array) $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -250,18 +256,18 @@ public function addPsr4($prefix, $paths, $prepend = false) throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = $paths; + $this->prefixDirsPsr4[$prefix] = (array) $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - $paths, + (array) $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - $paths + (array) $paths ); } } @@ -270,8 +276,8 @@ public function addPsr4($prefix, $paths, $prepend = false) * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 base directories * * @return void */ @@ -288,8 +294,8 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException * @@ -475,9 +481,9 @@ public function findFile($class) } /** - * Returns the currently registered loaders keyed by their corresponding vendor directories. + * Returns the currently registered loaders indexed by their corresponding vendor directories. * - * @return array + * @return self[] */ public static function getRegisteredLoaders() { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index d388ecb261..c2e384899d 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,8 +1,8 @@ array( 'name' => 'getkirby/cms', - 'pretty_version' => '4.0.2', - 'version' => '4.0.2.0', + 'pretty_version' => '4.0.3', + 'version' => '4.0.3.0', 'reference' => NULL, 'type' => 'kirby-cms', 'install_path' => __DIR__ . '/../../', @@ -47,8 +47,8 @@ 'dev_requirement' => false, ), 'getkirby/cms' => array( - 'pretty_version' => '4.0.2', - 'version' => '4.0.2.0', + 'pretty_version' => '4.0.3', + 'version' => '4.0.3.0', 'reference' => NULL, 'type' => 'kirby-cms', 'install_path' => __DIR__ . '/../../',