Ver Fonte

Add Portuguese (Brazil) localization and language picker support.

AhtashamShahzad1 há 1 mês atrás
pai
commit
606af0654e

+ 1 - 0
Info.plist

@@ -16,6 +16,7 @@
 		<string>de</string>
 		<string>sv</string>
 		<string>ko</string>
+		<string>pt-BR</string>
 		<string>zh-Hans</string>
 		<string>zh-Hant</string>
 	</array>

+ 2 - 0
meetings_app.xcodeproj/project.pbxproj

@@ -102,8 +102,10 @@
 				de,
 				sv,
 				ko,
+				"pt-BR",
 				"zh-Hans",
 				"zh-Hant",
+				"pt-BR",
 			);
 			mainGroup = 13AF5D992F83DE22001BE867;
 			minimizedProjectReferenceProxies = 1;

+ 3 - 1
meetings_app/Localization/AppLanguageManager.swift

@@ -8,7 +8,7 @@ enum AppLanguageManager {
     private static let defaultsKey = "settings.appLanguageCode"
 
     /// UI languages shown in Settings → Language (order preserved).
-    private static let supportedLanguageCodes = ["en", "fr", "fr-CA", "de", "sv", "ko", "zh-Hans", "zh-Hant"]
+    private static let supportedLanguageCodes = ["en", "fr", "fr-CA", "de", "sv", "ko", "pt-BR", "zh-Hans", "zh-Hant"]
 
     /// `nil` follows the system language; otherwise uses the selected `.lproj` code.
     static var selectedLanguageCode: String? {
@@ -67,6 +67,8 @@ enum AppLanguageManager {
             return "Svenska"
         case "ko":
             return "한국어"
+        case "pt-BR":
+            return "Português (Brasil)"
         case "zh-Hans":
             return "简体中文"
         case "zh-Hant":

+ 4 - 0
meetings_app/pt-BR.lproj/InfoPlist.strings

@@ -0,0 +1,4 @@
+"CFBundleDisplayName" = "Assistente de IA do Meet do Google";
+"CFBundleName" = "Assistente de IA do Meet do Google";
+"NSMicrophoneUsageDescription" = "Com o seu consentimento, o aplicativo gravará o áudio da reunião neste Mac e o mostrará no Assistente de IA após a reunião.";
+"NSSpeechRecognitionUsageDescription" = "Este aplicativo converte o áudio de suas reuniões salvas em transcrições de texto para o Assistente de IA.";

+ 452 - 0
meetings_app/pt-BR.lproj/Localizable.strings

@@ -0,0 +1,452 @@
+/* AppBrand.name ("Meetings") intencionalmente omitido — o nome do aplicativo permanece inalterado no código. */
+"AI Companion for Meet" = "Assistente de IA do Meet do Google";
+
+/* MARK: - Common */
+"OK" = "OK";
+"Cancel" = "Cancelar";
+"Continue" = "Continuar";
+"Apply" = "Aplicar";
+"Reset" = "Redefinir";
+"Save" = "Salvar";
+"Copy" = "Copiar";
+"Copied" = "Copiado";
+"Close" = "Fechar";
+"Join" = "Participar";
+"None" = "Nenhum";
+"Link" = "Link";
+"Stop" = "Parar";
+"Address" = "Endereço";
+"Title" = "Título";
+"Notes" = "Anotações";
+"Start" = "Iniciar";
+"Premium" = "Premium";
+"Popular" = "Popular";
+"Browser" = "Navegador";
+"Meeting" = "Reunião";
+"Error" = "Erro";
+"Success" = "Sucesso";
+
+/* MARK: - Status bar */
+"Meetings status menu" = "Menu de status de reuniões";
+"Open App" = "Abrir aplicativo";
+"Join Meetings" = "Participar de reuniões";
+"Schedule" = "Agendar";
+"Calendar" = "Calendário";
+"Widgets" = "Widgets";
+"AI Companion" = "Assistente de IA";
+"Settings" = "Configurações";
+"Top meetings" = "Reuniões no topo";
+"No upcoming meetings" = "Nenhuma reunião próxima";
+"Sign Out" = "Sair";
+"Sign In" = "Entrar";
+"Quit" = "Sair";
+
+/* MARK: - Launch splash */
+"Preparing your meetings workspace" = "Preparando seu espaço de trabalho de reuniões";
+"CONNECTING SERVICES" = "CONECTANDO SERVIÇOS";
+"READY" = "PRONTO";
+"Plan smart, achieve more" = "Planeje de forma inteligente, alcance mais";
+
+/* MARK: - Widgets */
+"Add Widget to Desktop" = "Adicionar widget à área de trabalho";
+"Choose a size and add your Google Meet widget." = "Escolha um tamanho e adicione seu widget do Meet do Google.";
+"Tip: Right-click a desktop widget to remove it." = "Dica: clique com o botão direito em um widget da área de trabalho para removê-lo.";
+"Removed %@ widget from desktop." = "Widget %@ removido da área de trabalho.";
+"Added %@ widget from desktop." = "Widget %@ adicionado da área de trabalho.";
+"Widgets are Premium only. Upgrade to add widgets." = "Widgets são exclusivos para Premium. Faça upgrade para adicionar widgets.";
+"Remove Widget" = "Remover widget";
+"Small" = "Pequeno";
+"Medium" = "Médio";
+"Quick actions" = "Ações rápidas";
+"Open Meet" = "Abrir o Meet do Google";
+"Upcoming meetings" = "Próximas reuniões";
+"Sign in to see upcoming meetings" = "Faça login para ver as próximas reuniões";
+"Sign in with Google" = "Fazer login com o Google";
+"Google Meet" = "Meet do Google";
+"Open and join quickly" = "Abrir e participar rapidamente";
+"Refresh" = "Atualizar";
+
+/* MARK: - Sidebar & navigation */
+"Planning" = "Planejamento";
+"Additional" = "Adicional";
+"Get Premium" = "Obter Premium";
+"Manage Subscription" = "Gerenciar assinatura";
+"App for Google Meet" = "Aplicativo para o Meet do Google";
+
+/* MARK: - Join meetings */
+"New Instant Meet" = "Nova reunião instantânea";
+"Start instant Meet in more section with\nGoogle Meet meet." = "Inicie uma reunião instantânea na seção Mais\ncom o Meet do Google.";
+"Join with Link" = "Participar com link";
+"Code or meet.google.com/…" = "Código ou meet.google.com/…";
+"Join with ID" = "Participar com ID";
+"Join with URL" = "Participar com URL";
+"Meeting URL" = "URL da reunião";
+"Enter meeting URL..." = "Digite a URL da reunião...";
+"Quick Join Meeting" = "Participar rapidamente da reunião";
+"Invalid Meet link" = "Link do Meet do Google inválido";
+"Enter a valid Google Meet link or meeting code (for example nkd-grps-duv, meet.google.com/nkd-grps-duv, or https://meet.google.com/nkd-grps-duv)." = "Digite um link válido do Meet do Google ou código de reunião (por exemplo, nkd-grps-duv, meet.google.com/nkd-grps-duv ou https://meet.google.com/nkd-grps-duv).";
+"Instant Meeting" = "Reunião instantânea";
+"Connect Google to start Instant Meeting" = "Conecte-se ao Google para iniciar uma reunião instantânea";
+"To auto-stop recording when the meeting ends, connect your Google account first." = "Para parar automaticamente a gravação quando a reunião terminar, conecte sua conta do Google primeiro.";
+"Could not create Instant Meeting" = "Não foi possível criar a reunião instantânea";
+"Free trial used. Upgrade to continue." = "Teste gratuito usado. Faça upgrade para continuar.";
+
+/* MARK: - Browse web */
+"Browse the web" = "Navegar na web";
+"Enter a web address (for example meet.google.com)." = "Digite um endereço da web (por exemplo, meet.google.com).";
+"Invalid address" = "Endereço inválido";
+"Enter a valid http or https URL." = "Digite uma URL http ou https válida.";
+"Browse" = "Navegar";
+"Quick links" = "Links rápidos";
+"Zoom help" = "Ajuda do Zoom";
+"https://example.com or example.com" = "https://example.com ou example.com";
+"Enter a valid web address, for example https://example.com" = "Digite um endereço da web válido, por exemplo, https://example.com";
+"Address not allowed" = "Endereço não permitido";
+"This URL is not permitted with the current in-app browser policy (whitelist)." = "Esta URL não é permitida pela política atual do navegador no aplicativo (lista de permissões).";
+"Unable to load page" = "Não foi possível carregar a página";
+"Could not load this page in the in-app browser.\n\n%@" = "Não foi possível carregar esta página no navegador do aplicativo.\n\n%@";
+"Page stopped loading" = "O carregamento da página foi interrompido";
+"Unable to open browser" = "Não foi possível abrir o navegador";
+"Unable to Open Safari" = "Não foi possível abrir o Safari";
+
+/* MARK: - Schedule & calendar */
+"All" = "Todos";
+"Today" = "Hoje";
+"This week" = "Esta semana";
+"This month" = "Este mês";
+"Previous week" = "Semana anterior";
+"Previous month" = "Mês anterior";
+"Custom range" = "Intervalo personalizado";
+"No meetings match the selected filters." = "Nenhuma reunião corresponde aos filtros selecionados.";
+"Adjust the date range and tap Apply." = "Ajuste o intervalo de datas e toque em Aplicar.";
+"Premium required. Get Premium now to unlock Calendar." = "Premium necessário. Obtenha o Premium agora para desbloquear o Calendário.";
+"Premium required. Click to open paywall." = "Premium necessário. Clique para abrir a página de pagamento.";
+"Get Premium to see events" = "Obtenha o Premium para ver eventos";
+"Connect Google" = "Conectar-se ao Google";
+"Sign in with Google first to schedule a meeting from Calendar." = "Faça login com o Google primeiro para agendar uma reunião a partir do Calendário.";
+"Select date" = "Selecionar data";
+"Choose a date to schedule your meeting." = "Escolha uma data para agendar sua reunião.";
+"Google schedule" = "Agenda do Google";
+"To show scheduled meetings, connect your Google account. You’ll need a Google OAuth client ID (Desktop) and a redirect URI matching the app’s callback scheme." = "Para mostrar reuniões agendadas, conecte sua conta do Google. Você precisará de um ID de cliente OAuth do Google (Desktop) e um URI de redirecionamento correspondente ao esquema de retorno de chamada do aplicativo.";
+"Actions" = "Ações";
+"Schedule meeting" = "Agendar reunião";
+"Team sync" = "Sincronização da equipe";
+"Duration (min)" = "Duração (min)";
+"Refresh saved meetings" = "Atualizar reuniões salvas";
+
+/* MARK: - Settings */
+"Manage appearance, account, and app options." = "Gerencie aparência, conta e opções do aplicativo.";
+"Appearance" = "Aparência";
+"Account" = "Conta";
+"App" = "Aplicativo";
+"Notifications" = "Notificações";
+"Help & Legal" = "Ajuda e Legal";
+"Dark Mode" = "Modo escuro";
+"Language" = "Idioma";
+"System Language" = "Idioma do sistema";
+"Rate Us" = "Avalie-nos";
+"Share App" = "Compartilhar aplicativo";
+"Upgrade" = "Upgrade";
+"Privacy Policy" = "Política de privacidade";
+"Support" = "Suporte";
+"Terms of Services" = "Termos de serviço";
+"AI Language 1" = "Idioma da IA 1";
+"AI Language 2" = "Idioma da IA 2";
+"Google account connected" = "Conta do Google conectada";
+"Google account not connected" = "Conta do Google não conectada";
+"Signed in" = "Conectado";
+"Sign in to sync your meetings and calendar." = "Faça login para sincronizar suas reuniões e calendário.";
+"Log out" = "Sair";
+"Check out %@ for managing and joining meetings." = "Experimente %@ para gerenciar e participar de reuniões.";
+"Meetings App" = "Aplicativo de Reuniões";
+
+/* MARK: - Recording consent */
+"Record this meeting locally?" = "Gravar esta reunião localmente?";
+"With your consent, the app will record meeting audio on this Mac and show it in AI Companion after the meeting." = "Com o seu consentimento, o aplicativo gravará o áudio da reunião neste Mac e o mostrará no Assistente de IA após a reunião.";
+"Allow and Continue" = "Permitir e continuar";
+"Continue Without Recording" = "Continuar sem gravar";
+"Transcription Languages" = "Idiomas de transcrição";
+"Preferred Language 1" = "Idioma preferido 1";
+"Preferred Language 2" = "Idioma preferido 2";
+"Microphone permission denied" = "Permissão do microfone negada";
+"Microphone permission required" = "Permissão do microfone necessária";
+"Enable microphone access in System Settings to record meetings locally." = "Ative o acesso ao microfone nas Configurações do Sistema para gravar reuniões localmente.";
+"Could not start recording" = "Não foi possível iniciar a gravação";
+"Recording will start when the meeting starts" = "A gravação começará quando a reunião começar";
+"Meeting recording started (meeting + microphone)" = "Gravação da reunião iniciada (reunião + microfone)";
+"System audio unavailable. Recording microphone only." = "Áudio do sistema indisponível. Gravando apenas o microfone.";
+"Meeting recording started (microphone only)" = "Gravação da reunião iniciada (apenas microfone)";
+"Meeting recording saved" = "Gravação da reunião salva";
+
+/* MARK: - AI Companion */
+"Get notes from your previous meetings" = "Obtenha anotações de suas reuniões anteriores";
+"Connect your Google account to see your AI Companion meeting history." = "Conecte sua conta do Google para ver seu histórico de reuniões do Assistente de IA.";
+"No previous meetings yet for %@. End a meeting to save it here and generate notes." = "Ainda não há reuniões anteriores para %@. Encerre uma reunião para salvá-la aqui e gerar anotações.";
+"this account" = "esta conta";
+"Previous meetings" = "Reuniões anteriores";
+"Recording in progress: %@" = "Gravação em andamento: %@";
+"Started: %@" = "Iniciada: %@";
+"Stop Recording" = "Parar gravação";
+"Date: %@" = "Data: %@";
+"Saved time: %@" = "Salva em: %@";
+"Get Notes" = "Obter anotações";
+"Premium required. Click to unlock AI Companion notes." = "Premium necessário. Clique para desbloquear as anotações do Assistente de IA.";
+"Play Audio" = "Reproduzir áudio";
+"Pause Audio" = "Pausar áudio";
+"Stopped" = "Parado";
+"Speaking..." = "Falando...";
+"Paused" = "Pausado";
+"Playing..." = "Reproduzindo...";
+"Not playing" = "Não está reproduzindo";
+"Checking audio..." = "Verificando áudio...";
+"Audio file missing" = "Arquivo de áudio ausente";
+"Could not play recording" = "Não foi possível reproduzir a gravação";
+"Failed: %@" = "Falhou: %@";
+"Failed to play audio" = "Falha ao reproduzir áudio";
+"decode error" = "erro de decodificação";
+"Loading..." = "Carregando...";
+"Buffering..." = "Em buffer...";
+"Finished" = "Concluído";
+"Transcript not requested" = "Transcrição não solicitada";
+"Transcript processing..." = "Processando transcrição...";
+"Transcript ready" = "Transcrição pronta";
+"Transcript unavailable (tap to retry)" = "Transcrição indisponível (toque para tentar novamente)";
+"Notes not requested" = "Anotações não solicitadas";
+"Preparing notes, please wait..." = "Preparando anotações, aguarde...";
+"Notes ready" = "Anotações prontas";
+"Notes unavailable (tap to retry)" = "Anotações indisponíveis (toque para tentar novamente)";
+"Transcript unavailable" = "Transcrição indisponível";
+"Notes unavailable" = "Anotações indisponíveis";
+"Could not find recording details for this meeting." = "Não foi possível encontrar detalhes da gravação para esta reunião.";
+"Transcript - %@" = "Transcrição - %@";
+"Notes - %@" = "Anotações - %@";
+"Meeting Notes" = "Anotações da reunião";
+"Transcript processing..." = "Processando transcrição...";
+
+/* MARK: - Paywall & StoreKit */
+"Meetings Pro" = "Reuniões Pro";
+"PREMIUM EXPERIENCE" = "EXPERIÊNCIA PREMIUM";
+"Elevate your meetings workflow" = "Eleve seu fluxo de trabalho de reuniões";
+"Unlock automation, premium meeting tools, and priority support for every session." = "Desbloqueie automação, ferramentas premium para reuniões e suporte prioritário para cada sessão.";
+"Manage meetings" = "Gerenciar reuniões";
+"Smart scheduling" = "Agendamento inteligente";
+"Faster workflow" = "Fluxo de trabalho mais rápido";
+"Reminder notifications" = "Notificações de lembrete";
+"Monthly" = "Mensal";
+"Bi Yearly" = "Semestral";
+"Yearly" = "Anual";
+"Most Popular" = "Mais popular";
+"%@ • Most Popular" = "%@ • Mais popular";
+"3 days free trial" = "3 dias de teste gratuito";
+"Cancel anytime" = "Cancele quando quiser";
+"No lock-in" = "Sem fidelidade";
+"Instant access" = "Acesso instantâneo";
+"Unlock all tools" = "Desbloqueie todas as ferramentas";
+"Secure billing" = "Pagamento seguro";
+"Handled by Apple" = "Processado pela Apple";
+"Secured by Apple. Cancel anytime." = "Protegido pela Apple. Cancele quando quiser.";
+"Restore Purchase" = "Restaurar compra";
+"Continue with free plan" = "Continuar com o plano gratuito";
+"Already Premium" = "Já é Premium";
+"You are already premium. Do you want to continue with this purchase?" = "Você já é Premium. Deseja continuar com esta compra?";
+"Current plan: %@. Choose a different package to switch." = "Plano atual: %@. Escolha um pacote diferente para mudar.";
+"Premium is active on this Apple ID." = "O Premium está ativo neste ID Apple.";
+"Free for %@, then %@" = "Grátis por %@, depois %@";
+"Billed via App Store" = "Cobrado via App Store";
+"%@  •  %@" = "%@  •  %@";
+"Save 0%" = "Economize 0%";
+"Save %@%%" = "Economize %@%%";
+"month" = "mês";
+"year" = "ano";
+"%@ free trial" = "Teste gratuito de %@";
+"Processing..." = "Processando...";
+"Premium Active" = "Premium ativo";
+"Continue with 3 day trail" = "Continuar com o teste de 3 dias";
+"Please Wait" = "Aguarde";
+"A purchase is already being processed." = "Uma compra já está sendo processada.";
+"This Apple ID already has premium access." = "Este ID Apple já tem acesso Premium.";
+"Purchase Complete" = "Compra concluída";
+"Premium has been unlocked successfully." = "O Premium foi desbloqueado com sucesso.";
+"Purchase Pending" = "Compra pendente";
+"Your purchase is pending approval. You can continue once it completes." = "Sua compra está aguardando aprovação. Você pode continuar assim que ela for concluída.";
+"Product Not Available" = "Produto indisponível";
+"Unable to load this product. Check your StoreKit configuration and product IDs." = "Não foi possível carregar este produto. Verifique sua configuração do StoreKit e os IDs do produto.";
+"Already Purchased" = "Já comprado";
+"This plan is already active on your Apple ID." = "Este plano já está ativo no seu ID Apple.";
+"Purchase Failed" = "Falha na compra";
+"Restore Purchases" = "Restaurar compras";
+"Purchases restored successfully." = "Compras restauradas com sucesso.";
+"No previous premium purchase was found for this Apple ID." = "Nenhuma compra Premium anterior foi encontrada para este ID Apple.";
+"Restore failed: %@" = "Falha na restauração: %@";
+"Unable to Open Subscriptions" = "Não foi possível abrir assinaturas";
+"The subscriptions URL is invalid." = "A URL de assinaturas é inválida.";
+"%@ tapped." = "%@ tocado.";
+
+/* MARK: - Auth */
+"Google Sign-In" = "Entrar com o Google";
+
+/* MARK: - Speech / transcript errors */
+"Speech recognition permission denied. Enable it in System Settings and try again." = "Permissão de reconhecimento de fala negada. Ative-a nas Configurações do Sistema e tente novamente.";
+"Speech recognition is restricted on this Mac." = "O reconhecimento de fala está restrito neste Mac.";
+"Speech recognition authorization is unavailable." = "A autorização de reconhecimento de fala está indisponível.";
+"Speech recognizer is unavailable for the current locale." = "O reconhecedor de fala está indisponível para a localidade atual.";
+"Speech recognizer is unavailable for %@." = "O reconhecedor de fala está indisponível para %@.";
+"No audio was available to transcribe." = "Nenhum áudio estava disponível para transcrição.";
+
+/* MARK: - StoreKit transaction errors */
+"Unable to load products: %@" = "Não foi possível carregar produtos: %@";
+"Product ID not found in StoreKit response. Requested: %@. Loaded IDs: %@" = "ID do produto não encontrado na resposta do StoreKit. Solicitado: %@. IDs carregados: %@";
+"Purchase verification failed." = "Falha na verificação da compra.";
+"Unknown purchase state." = "Estado de compra desconhecido.";
+"none" = "nenhum";
+
+/* MARK: - Paywall pricing copy */
+"%@ one-time purchase" = "Compra única de %@";
+"%@/month" = "%@/mês";
+"%@/6 months" = "%@/6 meses";
+"%@/year (3 days free trial)" = "%@/ano (3 dias de teste gratuito)";
+"day" = "dia";
+"week" = "semana";
+"period" = "período";
+"1 %@" = "1 %@";
+"%d %@s" = "%d %@";
+
+/* MARK: - Toasts & quick feedback */
+"Meeting added successfully." = "Reunião adicionada com sucesso.";
+"An issue occurred. Please try again." = "Ocorreu um problema. Tente novamente.";
+"Failed to load transcript." = "Falha ao carregar a transcrição.";
+"Failed to generate notes." = "Falha ao gerar anotações.";
+
+/* MARK: - Browser alerts */
+"Try Again" = "Tentar novamente";
+"The in-app browser closed this page unexpectedly. You can try loading it again in this same window." = "O navegador do aplicativo fechou esta página inesperadamente. Você pode tentar carregá-la novamente nesta mesma janela.";
+
+/* MARK: - Schedule & calendar errors */
+"Couldn't load schedule." = "Não foi possível carregar a agenda.";
+"Couldn't refresh schedule." = "Não foi possível atualizar a agenda.";
+"Couldn't connect Google account." = "Não foi possível conectar a conta do Google.";
+"Couldn't logout Google account." = "Não foi possível sair da conta do Google.";
+"Couldn't load schedule" = "Não foi possível carregar a agenda";
+"Couldn't determine Meet meeting code from URL." = "Não foi possível determinar o código de reunião do Meet do Google a partir da URL.";
+"Refreshing…" = "Atualizando…";
+"Connect Google to see meetings" = "Conecte-se ao Google para ver reuniões";
+"Connect to load schedule" = "Conecte-se para carregar a agenda";
+"Loading…" = "Carregando…";
+"Loading schedule…" = "Carregando agenda…";
+"Start date must be on or before end date." = "A data de início deve ser anterior ou igual à data de término.";
+"Invalid custom date range" = "Intervalo de datas personalizado inválido";
+"No meetings" = "Nenhuma reunião";
+"No meetings for selected filters" = "Nenhuma reunião para os filtros selecionados";
+"No meetings on %@" = "Nenhuma reunião em %@";
+"1 meeting on %@" = "1 reunião em %@";
+"%d meetings on %@" = "%d reuniões em %@";
+"All day" = "Dia todo";
+"Duration: all day" = "Duração: dia todo";
+"Duration: %dh %dm" = "Duração: %dh %dm";
+"Duration: %dh" = "Duração: %dh";
+"Duration: %dm" = "Duração: %dm";
+"%@ - %@" = "%@ - %@";
+"Scheduled Meeting" = "Reunião agendada";
+
+/* MARK: - Create meeting popover */
+"Please enter a title." = "Digite um título.";
+"Duration must be a positive number of minutes." = "A duração deve ser um número positivo de minutos.";
+"Invalid start time." = "Horário de início inválido.";
+
+/* MARK: - Reminders & notifications */
+"Reminders" = "Lembretes";
+"1 Day Before" = "1 dia antes";
+"12 Hours Before" = "12 horas antes";
+"1 Hour Before" = "1 hora antes";
+"Starts in 1 day" = "Começa em 1 dia";
+"Starts in 12 hours" = "Começa em 12 horas";
+"Starts in 1 hour" = "Começa em 1 hora";
+
+/* MARK: - Google OAuth errors */
+"Missing Google OAuth Client ID." = "ID do cliente OAuth do Google ausente.";
+"Missing Google OAuth Client Secret." = "Segredo do cliente OAuth do Google ausente.";
+"Invalid OAuth callback URL." = "URL de retorno de chamada OAuth inválida.";
+"Google did not return an authorization code." = "O Google não retornou um código de autorização.";
+"Token exchange failed: %@" = "Falha na troca de token: %@";
+"Could not open browser for Google sign-in." = "Não foi possível abrir o navegador para entrar com o Google.";
+"Google sign-in timed out." = "Tempo limite para entrar com o Google excedido.";
+"No stored Google tokens found." = "Nenhum token do Google armazenado encontrado.";
+
+/* MARK: - AI Companion / transcript errors */
+"Recording not found." = "Gravação não encontrada.";
+"Local meeting audio is missing." = "Áudio da reunião local ausente.";
+"Generated transcript was empty." = "A transcrição gerada estava vazia.";
+"(No transcript entries found.)" = "(Nenhuma entrada de transcrição encontrada.)";
+"No conference record found for this meeting." = "Nenhum registro de conferência encontrado para esta reunião.";
+"No transcript found for this meeting." = "Nenhuma transcrição encontrada para esta reunião.";
+"Unable to create audio composition tracks." = "Não foi possível criar faixas de composição de áudio.";
+"Unable to create audio export session." = "Não foi possível criar a sessão de exportação de áudio.";
+"Audio mix export failed." = "Falha na exportação da mixagem de áudio.";
+"No display available for system audio capture." = "Nenhuma tela disponível para captura de áudio do sistema.";
+"Cannot add audio writer input." = "Não foi possível adicionar a entrada do gravador de áudio.";
+
+/* MARK: - Google API errors */
+"Google Meet returned an invalid response." = "O Meet do Google retornou uma resposta inválida.";
+"Google Meet API error (%d): %@" = "Erro da API do Meet do Google (%d): %@";
+"Failed to parse Google Meet response: %@" = "Falha ao analisar a resposta do Meet do Google: %@";
+"Google Calendar returned an invalid response." = "O Calendário do Google retornou uma resposta inválida.";
+"Google Calendar API error (%d): %@" = "Erro da API do Calendário do Google (%d): %@";
+"Failed to parse Google Calendar events: %@" = "Falha ao analisar os eventos do Calendário do Google: %@";
+
+/* MARK: - OpenAI errors */
+"OpenAI API key is missing. Set OPENAI_API_KEY in the environment or app key vault." = "Chave da API OpenAI ausente. Defina OPENAI_API_KEY no ambiente ou no cofre de chaves do aplicativo.";
+"Notes generation returned an invalid response." = "A geração de anotações retornou uma resposta inválida.";
+"Notes generation failed (%d): %@" = "Falha na geração de anotações (%d): %@";
+"Notes generation returned empty text." = "A geração de anotações retornou texto vazio.";
+"OpenAI transcription returned an invalid response." = "A transcrição da OpenAI retornou uma resposta inválida.";
+"OpenAI transcription failed (%d): %@" = "Falha na transcrição da OpenAI (%d): %@";
+"OpenAI transcription returned no text." = "A transcrição da OpenAI não retornou texto.";
+
+/* MARK: - Browse & in-app browser */
+"Open sites in the in-app browser (back, forward, reload, address bar). OAuth and “Continue in browser” flows stay inside the app." = "Abra sites no navegador do aplicativo (voltar, avançar, recarregar, barra de endereço). Os fluxos OAuth e “Continuar no navegador” permanecem dentro do aplicativo.";
+"Open in app browser" = "Abrir no navegador do aplicativo";
+"Meet help" = "Ajuda do Meet do Google";
+"Go" = "Ir";
+"Back" = "Voltar";
+"Forward" = "Avançar";
+"Reload" = "Recarregar";
+
+/* MARK: - Schedule & calendar labels */
+"Google Calendar" = "Calendário do Google";
+"Untitled meeting" = "Reunião sem título";
+"Created event missing start/end." = "Evento criado sem início/fim.";
+"Created event missing Meet/HTML link." = "Evento criado sem link do Meet do Google/HTML.";
+
+/* MARK: - Google account */
+"Google account" = "Conta do Google";
+"%@, Google account" = "%@, conta do Google";
+"Google User" = "Usuário do Google";
+
+/* MARK: - Zoom join (unused section) */
+"Meeting ID" = "ID da reunião";
+"Enter meeting ID..." = "Digite o ID da reunião...";
+"Meeting Passcode" = "Código de acesso da reunião";
+"Enter meeting passcode..." = "Digite o código de acesso da reunião...";
+
+/* MARK: - Paywall (alternate benefits) */
+"Virtual backgrounds" = "Planos de fundo virtuais";
+"Tools for productivity" = "Ferramentas de produtividade";
+"24/7 support" = "Suporte 24/7";
+
+/* MARK: - Transcription speakers */
+"You" = "Você";
+
+/* MARK: - Keychain errors */
+"Failed to read OAuth tokens from Keychain." = "Falha ao ler tokens OAuth do Keychain.";
+"Keychain returned an invalid token payload." = "O Keychain retornou uma carga de token inválida.";
+"Failed to update OAuth tokens in Keychain." = "Falha ao atualizar tokens OAuth no Keychain.";
+"Failed to save OAuth tokens to Keychain." = "Falha ao salvar tokens OAuth no Keychain.";
+"Failed to delete OAuth tokens from Keychain." = "Falha ao excluir tokens OAuth do Keychain.";
+"Unable to allocate audio buffer." = "Não foi possível alocar o buffer de áudio.";
+"Invalid revoke response." = "Resposta de revogação inválida.";
+"Token revoke failed with status %d." = "Falha na revogação do token com status %d.";
+
+/* MARK: - Error alert diagnostics */
+"Keychain: %d (%@)" = "Keychain: %d (%@)";
+"OSStatus: %d" = "OSStatus: %d";
+"Item: service=%@, account=%@" = "Item: serviço=%@, conta=%@";

+ 17 - 0
meetings_app/pt-BR.lproj/Main.strings

@@ -0,0 +1,17 @@
+/* Class = "NSMenuItem"; title = "AI Companion for Meet"; ObjectID = "1Xt-HY-uBw"; */
+"1Xt-HY-uBw.title" = "Assistente de IA do Meet do Google";
+
+/* Class = "NSMenu"; title = "AI Companion for Meet"; ObjectID = "uQy-DD-JDr"; */
+"uQy-DD-JDr.title" = "Assistente de IA do Meet do Google";
+
+/* Class = "NSMenuItem"; title = "About AI Companion for Meet"; ObjectID = "5kV-Vb-QxS"; */
+"5kV-Vb-QxS.title" = "Sobre o Assistente de IA do Meet do Google";
+
+/* Class = "NSMenuItem"; title = "Hide AI Companion for Meet"; ObjectID = "Olw-nP-bQN"; */
+"Olw-nP-bQN.title" = "Ocultar Assistente de IA do Meet do Google";
+
+/* Class = "NSMenuItem"; title = "Quit AI Companion for Meet"; ObjectID = "4sb-4s-VLi"; */
+"4sb-4s-VLi.title" = "Sair do Assistente de IA do Meet do Google";
+
+/* Class = "NSMenuItem"; title = "AI Companion for Meet Help"; ObjectID = "FKE-Sm-Kum"; */
+"FKE-Sm-Kum.title" = "Ajuda do Assistente de IA do Meet do Google";