From ff481bbcd5a5e842725e749d0070126a03a40979 Mon Sep 17 00:00:00 2001
From: Ricardo <230414@epvc.pt>
Date: Thu, 11 Jun 2026 10:31:07 +0100
Subject: [PATCH] =?UTF-8?q?linguagem=20da=20aplica=C3=A7=C3=A3o?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apply_i18n.py | 401 ++++++
extract_strings.py | 36 +
extracted_strings.txt | 1193 +++++++++++++++++
index.html | 1413 ++++++++++++++++----
index.html.bak | 2971 +++++++++++++++++++++++++++++++++++++++++
to_translate.json | 168 +++
translations.py | 54 +
7 files changed, 5989 insertions(+), 247 deletions(-)
create mode 100644 apply_i18n.py
create mode 100644 extract_strings.py
create mode 100644 extracted_strings.txt
create mode 100644 index.html.bak
create mode 100644 to_translate.json
create mode 100644 translations.py
diff --git a/apply_i18n.py b/apply_i18n.py
new file mode 100644
index 0000000..c4dd4ee
--- /dev/null
+++ b/apply_i18n.py
@@ -0,0 +1,401 @@
+import re
+import json
+
+trans_dict = {
+ "Acesso": {"en": "Access", "es": "Acceso", "fr": "Accès"},
+ "Adicionar": {"en": "Add", "es": "Añadir", "fr": "Ajouter"},
+ "Agenda de Reservas": {"en": "Booking Schedule", "es": "Agenda de Reservas", "fr": "Calendrier des Réservations"},
+ "Alertas por Email": {"en": "Email Alerts", "es": "Alertas por Email", "fr": "Alertes par Email"},
+ "Alterar": {"en": "Change", "es": "Cambiar", "fr": "Modifier"},
+ "Aparência": {"en": "Appearance", "es": "Apariencia", "fr": "Apparence"},
+ "As Minhas Quotas": {"en": "My Dues", "es": "Mis Cuotas", "fr": "Mes Cotisations"},
+ "Ativar Agora": {"en": "Activate Now", "es": "Activar Ahora", "fr": "Activer Maintenant"},
+ "Atualizar Segurança": {"en": "Update Security", "es": "Actualizar Seguridad", "fr": "Mettre à jour la Sécurité"},
+ "Avisos de Cobrança": {"en": "Billing Notices", "es": "Avisos de Cobro", "fr": "Avis de Facturation"},
+ "Ações": {"en": "Actions", "es": "Acciones", "fr": "Actions"},
+ "Balanço Líquido": {"en": "Net Balance", "es": "Balance Neto", "fr": "Solde Net"},
+ "Cancelar": {"en": "Cancel", "es": "Cancelar", "fr": "Annuler"},
+ "Categoria": {"en": "Category", "es": "Categoría", "fr": "Catégorie"},
+ "Claro": {"en": "Light", "es": "Claro", "fr": "Clair"},
+ "Comércio": {"en": "Commerce", "es": "Comercio", "fr": "Commerce"},
+ "Condómino": {"en": "Resident", "es": "Residente", "fr": "Résident"},
+ "Condóminos": {"en": "Residents", "es": "Residentes", "fr": "Résidents"},
+ "Confirmar": {"en": "Confirm", "es": "Confirmar", "fr": "Confirmer"},
+ "Confirmar Nova Palavra-passe": {"en": "Confirm New Password", "es": "Confirmar Nueva Contraseña", "fr": "Confirmer le Nouveau Mot de passe"},
+ "Confirmar Reserva": {"en": "Confirm Booking", "es": "Confirmar Reserva", "fr": "Confirmer la Réservation"},
+ "Confirmação": {"en": "Confirmation", "es": "Confirmación", "fr": "Confirmation"},
+ "Consulte as suas despesas e faturas emitidas": {"en": "Check your expenses and issued invoices", "es": "Consulte sus gastos y facturas emitidas", "fr": "Consultez vos dépenses et factures émises"},
+ "Contacto": {"en": "Contact", "es": "Contacto", "fr": "Contact"},
+ "Conversas": {"en": "Conversations", "es": "Conversaciones", "fr": "Conversations"},
+ "Criar Grupo": {"en": "Create Group", "es": "Crear Grupo", "fr": "Créer un Groupe"},
+ "Criar Novo Grupo": {"en": "Create New Group", "es": "Crear Nuevo Grupo", "fr": "Créer un Nouveau Groupe"},
+ "Dados Pessoais": {"en": "Personal Data", "es": "Datos Personales", "fr": "Données Personnelles"},
+ "Dashboard": {"en": "Dashboard", "es": "Panel de Control", "fr": "Tableau de Bord"},
+ "Data": {"en": "Date", "es": "Fecha", "fr": "Date"},
+ "Data Emissão": {"en": "Issue Date", "es": "Fecha de Emisión", "fr": "Date d'Émission"},
+ "Data Vencimento": {"en": "Due Date", "es": "Fecha de Vencimiento", "fr": "Date d'Échéance"},
+ "Descarregar Recibo": {"en": "Download Receipt", "es": "Descargar Recibo", "fr": "Télécharger le Reçu"},
+ "Descrição": {"en": "Description", "es": "Descripción", "fr": "Description"},
+ "Detalhes da Rota": {"en": "Route Details", "es": "Detalles de la Ruta", "fr": "Détails de l'Itinéraire"},
+ "Detalhes do movimento": {"en": "Movement details", "es": "Detalles del movimiento", "fr": "Détails du mouvement"},
+ "Detalhes e Navegação": {"en": "Details and Navigation", "es": "Detalles y Navegación", "fr": "Détails et Navigation"},
+ "Diário Financeiro": {"en": "Financial Diary", "es": "Diario Financiero", "fr": "Journal Financier"},
+ "Editar": {"en": "Edit", "es": "Editar", "fr": "Modifier"},
+ "Eliminar": {"en": "Delete", "es": "Eliminar", "fr": "Supprimer"},
+ "Em Dívida": {"en": "In Debt", "es": "En Deuda", "fr": "En Dette"},
+ "Em resolução": {"en": "In Resolution", "es": "En resolución", "fr": "En résolution"},
+ "Email": {"en": "Email", "es": "Correo", "fr": "Email"},
+ "Emita faturas ou avise condóminos individualmente": {"en": "Issue invoices or notify residents individually", "es": "Emita facturas o avise a los residentes individualmente", "fr": "Émettez des factures ou informez les résidents individuellement"},
+ "Emitir Fatura": {"en": "Issue Invoice", "es": "Emitir Factura", "fr": "Émettre une Facture"},
+ "Emitir Nova Fatura": {"en": "Issue New Invoice", "es": "Emitir Nueva Factura", "fr": "Émettre une Nouvelle Facture"},
+ "Endereço de email": {"en": "Email Address", "es": "Dirección de correo", "fr": "Adresse e-mail"},
+ "Enviar por Email": {"en": "Send by Email", "es": "Enviar por Correo", "fr": "Envoyer par Email"},
+ "Escuro": {"en": "Dark", "es": "Oscuro", "fr": "Sombre"},
+ "Espaço": {"en": "Space", "es": "Espacio", "fr": "Espace"},
+ "Espaços Comuns": {"en": "Common Spaces", "es": "Espacios Comunes", "fr": "Espaces Communs"},
+ "Estado": {"en": "Status", "es": "Estado", "fr": "Statut"},
+ "Estado Quotas": {"en": "Dues Status", "es": "Estado de Cuotas", "fr": "Statut des Cotisations"},
+ "Ex: 14:00 - 16:00": {"en": "E.g.: 14:00 - 16:00", "es": "Ej: 14:00 - 16:00", "fr": "Ex : 14:00 - 16:00"},
+ "Ex: 1º Esq": {"en": "E.g.: 1st Left", "es": "Ej: 1º Izq", "fr": "Ex : 1er Gauche"},
+ "Ex: Hall de entrada": {"en": "E.g.: Entrance Hall", "es": "Ej: Hall de entrada", "fr": "Ex : Hall d'entrée"},
+ "Ex: Limpeza, Elevadores, Quotas...": {"en": "E.g.: Cleaning, Elevators, Dues...", "es": "Ej: Limpieza, Ascensores, Cuotas...", "fr": "Ex : Nettoyage, Ascenseurs, Cotisations..."},
+ "Ex: Lâmpada fundida": {"en": "E.g.: Blown bulb", "es": "Ej: Bombilla fundida", "fr": "Ex : Ampoule grillée"},
+ "Explore e encontre rotas no condomínio": {"en": "Explore and find routes in the condo", "es": "Explore y encuentre rutas en el condominio", "fr": "Explorez et trouvez des itinéraires dans la copropriété"},
+ "Fatura": {"en": "Invoice", "es": "Factura", "fr": "Facture"},
+ "Faturar na Hora": {"en": "Invoice Now", "es": "Facturar al Instante", "fr": "Facturer Maintenant"},
+ "Faturação": {"en": "Billing", "es": "Facturación", "fr": "Facturation"},
+ "Fazer Reserva": {"en": "Make Booking", "es": "Hacer Reserva", "fr": "Faire une Réservation"},
+ "Finanças": {"en": "Finances", "es": "Finanzas", "fr": "Finances"},
+ "Fração": {"en": "Unit", "es": "Fracción", "fr": "Unité"},
+ "Fórum do Condomínio": {"en": "Condo Forum", "es": "Foro del Condominio", "fr": "Forum de la Copropriété"},
+ "Geral": {"en": "General", "es": "General", "fr": "Général"},
+ "Gestão de Condóminos": {"en": "Residents Management", "es": "Gestión de Residentes", "fr": "Gestion des Résidents"},
+ "Gestão de pedidos e reparações": {"en": "Requests and repairs management", "es": "Gestión de solicitudes y reparaciones", "fr": "Gestion des demandes et réparations"},
+ "Ginásio": {"en": "Gym", "es": "Gimnasio", "fr": "Salle de Sport"},
+ "Ginásio Privado": {"en": "Private Gym", "es": "Gimnasio Privado", "fr": "Salle de Sport Privée"},
+ "Grupo": {"en": "Group", "es": "Grupo", "fr": "Groupe"},
+ "Grupo partilhado": {"en": "Shared group", "es": "Grupo compartido", "fr": "Groupe partagé"},
+ "Guardar Alterações": {"en": "Save Changes", "es": "Guardar Cambios", "fr": "Enregistrer les Modifications"},
+ "Guardar Condómino": {"en": "Save Resident", "es": "Guardar Residente", "fr": "Enregistrer le Résident"},
+ "Histórico de Reservas": {"en": "Booking History", "es": "Historial de Reservas", "fr": "Historique des Réservations"},
+ "Horário": {"en": "Schedule", "es": "Horario", "fr": "Horaire"},
+ "Horário: 08:00 - 22:00": {"en": "Hours: 08:00 - 22:00", "es": "Horario: 08:00 - 22:00", "fr": "Horaires : 08:00 - 22:00"},
+ "Idioma da Aplicação": {"en": "App Language", "es": "Idioma de la Aplicación", "fr": "Langue de l'Application"},
+ "Lazer": {"en": "Leisure", "es": "Ocio", "fr": "Loisirs"},
+ "Limpar": {"en": "Clear", "es": "Limpiar", "fr": "Effacer"},
+ "Lista completa de agendamentos em todos os espaços de lazer": {"en": "Complete list of bookings in all leisure spaces", "es": "Lista completa de reservas en todos los espacios de ocio", "fr": "Liste complète des réservations dans tous les espaces de loisirs"},
+ "Localização": {"en": "Location", "es": "Ubicación", "fr": "Emplacement"},
+ "Manutenção": {"en": "Maintenance", "es": "Mantenimiento", "fr": "Maintenance"},
+ "Manutenção e Ocorrências": {"en": "Maintenance and Issues", "es": "Mantenimiento e Incidencias", "fr": "Maintenance et Incidents"},
+ "Manutenções Ativas": {"en": "Active Maintenance", "es": "Mantenimientos Activos", "fr": "Maintenances Actives"},
+ "Mapa": {"en": "Map", "es": "Mapa", "fr": "Carte"},
+ "Marcar como lida": {"en": "Mark as read", "es": "Marcar como leída", "fr": "Marquer comme lu"},
+ "Mensagens": {"en": "Messages", "es": "Mensajes", "fr": "Messages"},
+ "Meu Perfil": {"en": "My Profile", "es": "Mi Perfil", "fr": "Mon Profil"},
+ "Min. 8 caracteres": {"en": "Min. 8 characters", "es": "Mín. 8 caracteres", "fr": "Min. 8 caractères"},
+ "Minhas Contas": {"en": "My Accounts", "es": "Mis Cuentas", "fr": "Mes Comptes"},
+ "Minhas Faturas": {"en": "My Invoices", "es": "Mis Facturas", "fr": "Mes Factures"},
+ "Morador": {"en": "Resident", "es": "Residente", "fr": "Résident"},
+ "Mudar Permissões": {"en": "Change Permissions", "es": "Cambiar Permisos", "fr": "Modifier les Permissions"},
+ "MyCondominium": {"en": "MyCondominium", "es": "MyCondominium", "fr": "MyCondominium"},
+ "Navegação Inteligente": {"en": "Smart Navigation", "es": "Navegación Inteligente", "fr": "Navigation Intelligente"},
+ "Nome Completo": {"en": "Full Name", "es": "Nombre Completo", "fr": "Nom Complet"},
+ "Nome do Grupo": {"en": "Group Name", "es": "Nombre del Grupo", "fr": "Nom du Groupe"},
+ "Nome do proprietário": {"en": "Owner Name", "es": "Nombre del propietario", "fr": "Nom du propriétaire"},
+ "Nome do residente": {"en": "Resident Name", "es": "Nombre del residente", "fr": "Nom du résident"},
+ "Notificar": {"en": "Notify", "es": "Notificar", "fr": "Notifier"},
+ "Notificações": {"en": "Notifications", "es": "Notificaciones", "fr": "Notifications"},
+ "Notificações Push no Navegador": {"en": "Browser Push Notifications", "es": "Notificaciones Push en el Navegador", "fr": "Notifications Push du Navigateur"},
+ "Nova Palavra-passe": {"en": "New Password", "es": "Nueva Contraseña", "fr": "Nouveau Mot de passe"},
+ "Nova Reserva": {"en": "New Booking", "es": "Nueva Reserva", "fr": "Nouvelle Réservation"},
+ "Novo Registo": {"en": "New Registration", "es": "Nuevo Registro", "fr": "Nouvel Enregistrement"},
+ "Nível de Acesso": {"en": "Access Level", "es": "Nivel de Acceso", "fr": "Niveau d'Accès"},
+ "Pagamentos": {"en": "Payments", "es": "Pagos", "fr": "Paiements"},
+ "Pagamentos Concluídos": {"en": "Completed Payments", "es": "Pagos Completados", "fr": "Paiements Terminés"},
+ "Pagar": {"en": "Pay", "es": "Pagar", "fr": "Payer"},
+ "Pago": {"en": "Paid", "es": "Pagado", "fr": "Payé"},
+ "Palavra-passe": {"en": "Password", "es": "Contraseña", "fr": "Mot de passe"},
+ "Palavra-passe Atual": {"en": "Current Password", "es": "Contraseña Actual", "fr": "Mot de passe Actuel"},
+ "Parque Jogos": {"en": "Playground", "es": "Parque de Juegos", "fr": "Aire de Jeux"},
+ "Parque de Jogos": {"en": "Playground", "es": "Parque de Juegos", "fr": "Aire de Jeux"},
+ "Permissões": {"en": "Permissions", "es": "Permisos", "fr": "Permissions"},
+ "Portal de Gestão": {"en": "Management Portal", "es": "Portal de Gestión", "fr": "Portail de Gestion"},
+ "Preferências": {"en": "Preferences", "es": "Preferencias", "fr": "Préférences"},
+ "Preferências da Aplicação": {"en": "App Preferences", "es": "Preferencias de la Aplicación", "fr": "Préférences de l'Application"},
+ "Prioridade": {"en": "Priority", "es": "Prioridad", "fr": "Priorité"},
+ "Proprietário": {"en": "Owner", "es": "Propietario", "fr": "Propriétaire"},
+ "Próximas Reservas": {"en": "Upcoming Bookings", "es": "Próximas Reservas", "fr": "Prochaines Réservations"},
+ "Quadro de Avisos": {"en": "Notice Board", "es": "Tablón de Anuncios", "fr": "Tableau d'Affichage"},
+ "Quotas em Atraso": {"en": "Overdue Dues", "es": "Cuotas Atrasadas", "fr": "Cotisations en Retard"},
+ "RIO TEJO": {"en": "RIO TEJO", "es": "RIO TEJO", "fr": "RIO TEJO"},
+ "Recarregar Página": {"en": "Reload Page", "es": "Recargar Página", "fr": "Recharger la Page"},
+ "Recibo": {"en": "Receipt", "es": "Recibo", "fr": "Reçu"},
+ "Registar Movimento": {"en": "Register Movement", "es": "Registrar Movimiento", "fr": "Enregistrer le Mouvement"},
+ "Registar Movimento Financeiro": {"en": "Register Financial Movement", "es": "Registrar Movimiento Financiero", "fr": "Enregistrer le Mouvement Financier"},
+ "Relatórios Semanais Automáticos": {"en": "Automated Weekly Reports", "es": "Informes Semanales Automáticos", "fr": "Rapports Hebdomadaires Automatiques"},
+ "Reportar": {"en": "Report", "es": "Reportar", "fr": "Signaler"},
+ "Reportar Ocorrência": {"en": "Report Issue", "es": "Reportar Incidencia", "fr": "Signaler un Incident"},
+ "Reportar Problema": {"en": "Report Problem", "es": "Reportar Problema", "fr": "Signaler un Problème"},
+ "Reservado para (Condómino)": {"en": "Booked for (Resident)", "es": "Reservado para (Residente)", "fr": "Réservé pour (Résident)"},
+ "Reservar Agora": {"en": "Book Now", "es": "Reservar Ahora", "fr": "Réserver Maintenant"},
+ "Reservas (Mês)": {"en": "Bookings (Month)", "es": "Reservas (Mes)", "fr": "Réservations (Mois)"},
+ "Residencial": {"en": "Residential", "es": "Residencial", "fr": "Résidentiel"},
+ "Resolver": {"en": "Resolve", "es": "Resolver", "fr": "Résoudre"},
+ "Resolver Problemas": {"en": "Solve Problems", "es": "Resolver Problemas", "fr": "Résoudre des Problèmes"},
+ "Restaurar Base de Dados": {"en": "Restore Database", "es": "Restaurar Base de Datos", "fr": "Restaurer la Base de Données"},
+ "Saldo Disponível": {"en": "Available Balance", "es": "Saldo Disponible", "fr": "Solde Disponible"},
+ "Salão de Festas": {"en": "Party Room", "es": "Salón de Fiestas", "fr": "Salle de Fêtes"},
+ "Segurança": {"en": "Security", "es": "Seguridad", "fr": "Sécurité"},
+ "Selecionar Moradores": {"en": "Select Residents", "es": "Seleccionar Residentes", "fr": "Sélectionner des Résidents"},
+ "Sem novas notificações": {"en": "No new notifications", "es": "No hay nuevas notificaciones", "fr": "Aucune nouvelle notification"},
+ "Sem reservas": {"en": "No bookings", "es": "Sin reservas", "fr": "Aucune réservation"},
+ "Sem valores pendentes": {"en": "No pending values", "es": "Sin valores pendientes", "fr": "Aucune valeur en attente"},
+ "Senha de acesso": {"en": "Access Password", "es": "Contraseña de acceso", "fr": "Mot de passe d'accès"},
+ "Serviços": {"en": "Services", "es": "Servicios", "fr": "Services"},
+ "Sistema": {"en": "System", "es": "Sistema", "fr": "Système"},
+ "Telefone": {"en": "Phone", "es": "Teléfono", "fr": "Téléphone"},
+ "Telemóvel": {"en": "Mobile", "es": "Móvil", "fr": "Portable"},
+ "Terminar Sessão": {"en": "Log Out", "es": "Cerrar Sesión", "fr": "Se Déconnecter"},
+ "Tipo": {"en": "Type", "es": "Tipo", "fr": "Type"},
+ "Total Pago": {"en": "Total Paid", "es": "Total Pagado", "fr": "Total Payé"},
+ "Total Pendente": {"en": "Total Pending", "es": "Total Pendiente", "fr": "Total en Attente"},
+ "Total agendado": {"en": "Total Scheduled", "es": "Total Agendado", "fr": "Total Programmé"},
+ "Título do Problema": {"en": "Problem Title", "es": "Título del Problema", "fr": "Titre du Problème"},
+ "VIA CENTRAL": {"en": "VIA CENTRAL", "es": "VIA CENTRAL", "fr": "VIA CENTRAL"},
+ "Valor": {"en": "Amount", "es": "Valor", "fr": "Montant"},
+ "Valor (€)": {"en": "Amount (€)", "es": "Valor (€)", "fr": "Montant (€)"},
+ "Valor Pendente (€)": {"en": "Pending Amount (€)", "es": "Valor Pendiente (€)", "fr": "Montant en Attente (€)"},
+ "Vencimento": {"en": "Due Date", "es": "Vencimiento", "fr": "Échéance"},
+ "Ver todas as Reservas": {"en": "See all Bookings", "es": "Ver todas las Reservas", "fr": "Voir toutes les Réservations"},
+ "Em Progresso": {"en": "In Progress", "es": "En Progreso", "fr": "En Cours"},
+ "Receita": {"en": "Income", "es": "Ingreso", "fr": "Revenu"},
+ "Despesa": {"en": "Expense", "es": "Gasto", "fr": "Dépense"},
+ "Em Validação": {"en": "Validating", "es": "En Validación", "fr": "En Validation"},
+ "Alta": {"en": "High", "es": "Alta", "fr": "Élevée"},
+ "Baixa": {"en": "Low", "es": "Baja", "fr": "Basse"},
+ "Novo": {"en": "New", "es": "Nuevo", "fr": "Nouveau"},
+ "Resolvido": {"en": "Resolved", "es": "Resuelto", "fr": "Résolu"},
+ "Pendente": {"en": "Pending", "es": "Pendiente", "fr": "En Attente"},
+ "Confirmado": {"en": "Confirmed", "es": "Confirmado", "fr": "Confirmé"},
+ "Média": {"en": "Medium", "es": "Media", "fr": "Moyenne"},
+ "Atrasado": {"en": "Overdue", "es": "Atrasado", "fr": "En Retard"},
+ "Ana Silva": {"en": "Ana Silva", "es": "Ana Silva", "fr": "Ana Silva"},
+ "Carlos Santos": {"en": "Carlos Santos", "es": "Carlos Santos", "fr": "Carlos Santos"},
+ "Maria Pereira": {"en": "Maria Pereira", "es": "Maria Pereira", "fr": "Maria Pereira"},
+ "João Ferreira": {"en": "João Ferreira", "es": "João Ferreira", "fr": "João Ferreira"},
+ "Sofia Costa": {"en": "Sofia Costa", "es": "Sofia Costa", "fr": "Sofia Costa"},
+ "Administração": {"en": "Administration", "es": "Administración", "fr": "Administration"},
+ "Utilizador": {"en": "User", "es": "Usuario", "fr": "Utilisateur"},
+ "Pesquisar condómino por nome ou fração...": {"en": "Search resident by name or unit...", "es": "Buscar residente por nombre o fracción...", "fr": "Rechercher un résident par nom ou unité..."},
+ "Pesquisar transação...": {"en": "Search transaction...", "es": "Buscar transacción...", "fr": "Rechercher una transacción..."},
+ "Pesquisar na lista...": {"en": "Search in list...", "es": "Buscar en la lista...", "fr": "Rechercher dans la liste..."},
+ "Pesquisar fatura...": {"en": "Search invoice...", "es": "Buscar factura...", "fr": "Rechercher une facture..."},
+ "Escreva a sua mensagem...": {"en": "Write your message...", "es": "Escriba su mensaje...", "fr": "Écrivez votre message..."},
+ "Pesquisar reserva...": {"en": "Search booking...", "es": "Buscar reserva...", "fr": "Rechercher une réservation..."},
+ "vs. mês passado": {"en": "vs. last month", "es": "vs. mes pasado", "fr": "vs. mois dernier"},
+ "Algo correu mal (Erro na Aplicação)": {"en": "Something went wrong (App Error)", "es": "Algo salió mal (Error de Aplicación)", "fr": "Un problème est survenu (Erreur d'Application)"},
+ "Email ou Palavra-passe incorreta": {"en": "Incorrect Email or Password", "es": "Correo o Contraseña incorrecta", "fr": "E-mail ou Mot de passe incorrect"},
+ "A entrar...": {"en": "Logging in...", "es": "Entrando...", "fr": "Connexion en cours..."},
+ "Entrar": {"en": "Log In", "es": "Entrar", "fr": "Se Connecter"},
+ "Nenhuma ocorrência encontrada.": {"en": "No issues found.", "es": "Ninguna incidencia encontrada.", "fr": "Aucun incident trouvé."},
+ "Nenhuma transação financeira encontrada.": {"en": "No financial transactions found.", "es": "Ninguna transacción financiera encontrada.", "fr": "Aucune transaction financière trouvée."},
+ "Nenhum condómino encontrado.": {"en": "No resident found.", "es": "Ningún residente encontrado.", "fr": "Aucun résident trouvé."},
+ "Nenhuma fatura encontrada.": {"en": "No invoice found.", "es": "Ninguna factura encontrada.", "fr": "Aucune facture trouvée."},
+ "Nenhuma reserva encontrada.": {"en": "No booking found.", "es": "Ninguna reserva encontrada.", "fr": "Aucune réservation trouvée."},
+ "Tem a certeza que deseja terminar sessão?": {"en": "Are you sure you want to log out?", "es": "¿Está seguro que desea cerrar sesión?", "fr": "Êtes-vous sûr de vouloir vous déconnecter ?"},
+ "Permissões de utilizador atualizadas": {"en": "User permissions updated", "es": "Permisos de usuario actualizados", "fr": "Permissions utilisateur mises à jour"},
+ "Erro ao atualizar permissão.": {"en": "Error updating permission.", "es": "Error al actualizar permiso.", "fr": "Erreur lors de la mise à jour de la permission."},
+ "Morador atualizado com sucesso": {"en": "Resident updated successfully", "es": "Residente actualizado con éxito", "fr": "Résident mis à jour avec succès"},
+ "Morador adicionado com sucesso": {"en": "Resident added successfully", "es": "Residente añadido con éxito", "fr": "Résident ajouté avec succès"},
+ "Erro ao guardar morador": {"en": "Error saving resident", "es": "Error al guardar residente", "fr": "Erreur lors de l'enregistrement du résident"},
+ "Ocorrência resolvida com sucesso": {"en": "Issue resolved successfully", "es": "Incidencia resuelta con éxito", "fr": "Incident résolu avec succès"},
+ "Ocorrência atualizada": {"en": "Issue updated", "es": "Incidencia actualizada", "fr": "Incident mis à jour"},
+ "Transação adicionada com sucesso": {"en": "Transaction added successfully", "es": "Transacción añadida con éxito", "fr": "Transaction ajoutée avec succès"},
+ "Erro ao guardar transação": {"en": "Error saving transaction", "es": "Error al guardar transacción", "fr": "Erreur lors de l'enregistrement de la transaction"},
+ "Fatura emitida com sucesso": {"en": "Invoice issued successfully", "es": "Factura emitida con éxito", "fr": "Facture émise avec succès"},
+ "Erro ao emitir fatura": {"en": "Error issuing invoice", "es": "Error al emitir factura", "fr": "Erreur lors de l'émission de la facture"},
+ "Fatura atualizada para Paga": {"en": "Invoice updated to Paid", "es": "Factura actualizada a Pagada", "fr": "Facture mise à jour sur Payée"},
+ "Erro ao atualizar fatura": {"en": "Error updating invoice", "es": "Error al actualizar factura", "fr": "Erreur lors de la mise à jour de la facture"},
+ "Reserva efetuada com sucesso": {"en": "Booking made successfully", "es": "Reserva efectuada con éxito", "fr": "Réservation effectuée avec succès"},
+ "Reserva atualizada com sucesso": {"en": "Booking updated successfully", "es": "Reserva actualizada con éxito", "fr": "Réservation mise à jour avec succès"},
+ "Erro ao fazer reserva": {"en": "Error making booking", "es": "Error al hacer reserva", "fr": "Erreur lors de la réservation"}
+}
+
+def make_key(s):
+ return re.sub(r'[^a-zA-Z0-9]+', '_', s.lower()).strip('_')
+
+translations = {'pt': {}, 'en': {}, 'es': {}, 'fr': {}}
+for pt_str, translations_langs in trans_dict.items():
+ key = make_key(pt_str)
+ translations['pt'][key] = pt_str
+ translations['en'][key] = translations_langs.get('en', pt_str)
+ translations['es'][key] = translations_langs.get('es', pt_str)
+ translations['fr'][key] = translations_langs.get('fr', pt_str)
+
+js_dict_str = "const translations = " + json.dumps(translations, indent=4, ensure_ascii=False) + ";"
+
+context_block = """
+ const LanguageContext = React.createContext();
+
+ const LanguageProvider = ({ children }) => {
+ const [language, setLanguage] = useState(() => {
+ const cookieMatch = document.cookie.match(/googtrans=\\/pt\\/([a-z]{2})/);
+ if (cookieMatch) return cookieMatch[1];
+ return 'pt';
+ });
+
+ const t = (key) => {
+ return translations[language]?.[key] || translations['pt']?.[key] || key;
+ };
+
+ const changeLanguage = (lang) => {
+ setLanguage(lang);
+ document.cookie = `googtrans=/pt/${lang}; path=/;`;
+ const domain = window.location.hostname;
+ if(domain !== 'localhost' && domain !== '127.0.0.1' && domain !== '') {
+ document.cookie = `googtrans=/pt/${lang}; domain=${domain}; path=/;`;
+ document.cookie = `googtrans=/pt/${lang}; domain=.${domain}; path=/;`;
+ }
+ };
+
+ return (
+