Skip to content

Latest commit

 

History

History
834 lines (659 loc) · 26.1 KB

File metadata and controls

834 lines (659 loc) · 26.1 KB

🌐 If you want to read the English version of this README, click here. Si quieres leer la versión en español de este README, haz clic aquí.

SimplifAI - Extensão Chrome para Acessibilidade Web

Chrome Extension License: Apache 2.0 ISO 24495-1 Prototype

Important

Este projeto é um protótipo experimental. Não é um produto oficial do Google e não possui nenhum mecanismo de suporte. Foi criado para explorar as possibilidades dos modelos Gemini e fomentar ideias de acessibilidade através de IA generativa. Use por sua conta e risco.

SimplifAI é uma extensão Chrome que utiliza Inteligência Artificial (Google Gemini API) para simplificar conteúdo web, tornando a informação mais acessível segundo os princípios da ISO 24495-1 (Linguagem Simples).


📋 Índice


📚 Fundamentação Teórica

ISO 24495-1: Linguagem Simples

A SimplifAI baseia-se na ISO 24495-1 (Plain language - Part 1: Governing principles and guidelines), norma internacional que estabelece princípios e diretrizes para comunicação clara e acessível.

No Brasil, a linguagem simples é promovida pelo Governo Federal através do programa Linguagem Simples, que estabelece:

Princípios da Linguagem Simples (ISO 24495-1)

  1. Foco no usuário: Adaptar a linguagem ao público-alvo
  2. Clareza: Usar palavras comuns e frases curtas
  3. Estrutura lógica: Organizar informações de forma coerente
  4. Design acessível: Facilitar a leitura visual
  5. Verificação: Testar com usuários reais

Implementação na SimplifAI

A extensão aplica estes princípios através de:

  • Redução de complexidade: Textos são reduzidos em até 50%
  • Vocabulário simplificado: Substituição de termos técnicos por sinônimos comuns
  • Estrutura clara: Parágrafos curtos (2-3 frases) com hierarquia mantida
  • Explicação de siglas: Acrônimos são explicados entre parênteses
  • Voz ativa: Preferência por construções diretas

🎯 Funcionalidades

1. Onboarding Guiado (Wizard)

  • 3 etapas simples: Idioma → Configuração API → Sucesso
  • Multilíngue desde o início: Tela inicial exibe PT/ES/EN simultaneamente
  • Seleção de modelo Gemini: Escolha entre Gemini 2.5 (gratuito) e Gemini 3.0 (requer billing)
  • Validação de API key: Teste automático antes de salvar
  • Redirecionamento automático: Se tentar usar sem configurar, abre o wizard

2. Simplificação de Conteúdo com IA

  • Análise semântica profunda usando Google Gemini API
  • Suporte a múltiplos modelos: Gemini 2.5 Flash e Gemini 3.0 Flash Preview
  • Redução de até 50% do texto original mantendo significado
  • Preservação da hierarquia de títulos e seções
  • Remoção automática de conteúdo secundário e publicidade

3. Geração de Áudio (Text-to-Speech)

  • Motor TTS: Gemini 2.5 Flash Preview TTS
  • Qualidade: 24 kHz, 16-bit PCM, mono
  • Chunking inteligente: Divisão por parágrafos e frases
  • Processamento paralelo: Até 5 chunks simultâneos
  • Reprodução progressiva: Início antes da conclusão total
  • Retry automático: Tolerância a falhas de API
  • Controles: Play, pause, stop com barra de progresso

4. Descrição de Imagens com IA

  • Análise contextual usando Gemini API
  • Detecta e ignora: ícones, logos, banners, anúncios
  • Lazy loading: Suporte a imagens com carregamento diferido
  • Contexto do artigo: Descrições específicas baseadas no conteúdo
  • Validação de dimensões (>50x50px)

5. Dicionário Contextual Embutido

  • Ativação: Duplo clique ou seleção + atalho (Alt+D)
  • Prevenção de alucinações: Validação de siglas e termos técnicos
  • Popup flutuante: Posicionado próximo à seleção
  • Multi-idioma: Definições no idioma configurado
  • Contexto: Considera o artigo para termos ambíguos

6. Suporte Multilíngue Avançado

Idiomas Suportados

  • 🇺🇸 Inglês (EN)
  • 🇧🇷 Português (PT)
  • 🇪🇸 Espanhol (ES)

Capacidade de Tradução Automática

A SimplifAI pode simplificar em um idioma uma página que está em outro:

Exemplo:

  • Página original: Português (notícia do G1)
  • Idioma configurado: Inglês
  • Resultado: Texto simplificado em inglês
📄 Original (PT): "O Supremo Tribunal Federal (STF) decidiu..."
📝 Simplificado (EN): "The Supreme Federal Court decided..."

Processo:

  1. Extração do conteúdo no idioma original
  2. Prompt Gemini: "Translate to {language} and simplify..."
  3. Tradução + simplificação simultâneas
  4. Validação de qualidade

7. Recursos de Acessibilidade

Atalhos de Teclado

Atalho Função
Alt/Cmd + S Simplificar página atual
Alt/Cmd + A Gerar/pausar áudio (na página simplificada)

Modo Alto Contraste

  • Ativação: Botão na toolbar da página simplificada
  • Cores WCAG AAA: Contraste mínimo 7:1
  • Esquema: Texto branco (#FFFFFF) sobre fundo preto (#000000)
  • Persistência: Salvo em chrome.storage.sync
  • Aplicação: CSS separado (high-contrast.css)

Controle de Fonte

  • Tamanhos: 14px, 16px, 18px, 20px, 22px, 24px
  • Padrão: 18px
  • Incremento: ±2px por botão
  • Persistência: Salvo por usuário
  • Unidade: px absoluto para previsibilidade

🏗️ Arquitetura Técnica

Diagrama de Componentes

graph TB
    subgraph "Chrome Extension"
        BG[Background Service Worker]
        CS[Content Script]
        POP[Popup UI]
        
        subgraph "Content Modules"
            META[Metadata Extractor]
            CONT[Content Extractor]
            IMG[Image Processor]
            MD[Markdown Processor]
            OVL[Overlay Manager]
            ORCH[Simplification Orchestrator]
        end
        
        subgraph "Services"
            GEM[Gemini Service]
            AUD[Audio Service]
        end
        
        subgraph "Utilities"
            TRANS[Translations]
            PROM[Prompts]
            KBD[Keyboard Shortcuts]
        end
    end
    
    subgraph "External APIs"
        GEMAPI[Google Gemini API]
        TTS[Gemini TTS API]
    end
    
    subgraph "Chrome APIs"
        STORAGE[chrome.storage.sync]
        RUNTIME[chrome.runtime]
        SCRIPTING[chrome.scripting]
    end
    
    CS --> ORCH
    ORCH --> META
    ORCH --> CONT
    ORCH --> IMG
    ORCH --> MD
    ORCH --> OVL
    
    CONT --> GEM
    IMG --> GEM
    AUD --> TTS
    
    GEM --> GEMAPI
    AUD --> GEMAPI
    
    BG --> STORAGE
    CS --> STORAGE
    POP --> STORAGE
    
    BG --> RUNTIME
    CS --> RUNTIME
    
    POP --> TRANS
    ORCH --> PROM
    CS --> KBD
    
    style ORCH fill:#ff6b6b
    style GEM fill:#4ecdc4
    style AUD fill:#95e1d3
    style GEMAPI fill:#f38181
Loading

Fluxo de Onboarding (Primeira Execução)

sequenceDiagram
    participant U as Usuário
    participant BG as Background Script
    participant OB as Onboarding Page
    participant GEM as Gemini Service
    participant ST as Chrome Storage

    Note over BG: Extensão instalada
    BG->>ST: Verifica apiKey
    ST-->>BG: null (não configurado)
    BG->>OB: Abre onboarding.html
    
    Note over OB: Etapa 1: Idioma
    OB->>U: Exibe PT/ES/EN
    U->>OB: Seleciona idioma
    OB->>ST: Salva language
    
    Note over OB: Etapa 2: API Key
    OB->>U: Solicita modelo + API key
    U->>OB: Insere dados
    OB->>BG: testApiKey(key, model)
    BG->>GEM: validateApiKey(model)
    GEM-->>BG: isValid: true
    BG-->>OB: Validação OK
    OB->>ST: Salva apiKey + geminiModel
    
    Note over OB: Etapa 3: Sucesso
    OB->>U: ✅ Pronto para usar!
Loading

Fluxo de Simplificação

sequenceDiagram
    participant U as Usuário
    participant CS as Content Script
    participant ORCH as Orchestrator
    participant EXT as Extractors
    participant GEM as Gemini Service
    participant OVL as Overlay Manager

    U->>CS: Alt+S (simplificar)
    CS->>ORCH: orchestrateSimplification()
    
    ORCH->>EXT: extractMetadata()
    EXT-->>ORCH: {titulo, autor, data}
    
    ORCH->>EXT: extractMainContent()
    EXT-->>ORCH: {texto, imagens}
    
    ORCH->>GEM: simplifyText(conteúdo)
    GEM->>GEM: Prompts[idioma].textSimplification
    GEM-->>ORCH: texto simplificado
    
    loop Para cada imagem
        ORCH->>GEM: getImageDescription(img, contexto)
        GEM-->>ORCH: descrição
    end
    
    ORCH->>ORCH: renderMarkdown()
    ORCH->>OVL: showSimplifiedPage(html)
    OVL-->>U: Exibe página simplificada
Loading

Fluxo de Geração de Áudio

sequenceDiagram
    participant U as Usuário
    participant SP as Simplified Page
    participant AUD as AudioService
    participant GEM as Gemini TTS API
    participant QUEUE as AudioQueue

    U->>SP: Clica "Gerar Áudio"
    SP->>AUD: generateAudioInChunks(texto, idioma)
    
    AUD->>AUD: splitIntoLogicalChunks(400 chars)
    AUD->>QUEUE: new AudioQueue(totalChunks)
    
    par Processamento Paralelo (5 simultâneos)
        AUD->>GEM: convertTextToSpeech(chunk1)
        AUD->>GEM: convertTextToSpeech(chunk2)
        AUD->>GEM: convertTextToSpeech(chunk3)
    end
    
    GEM-->>AUD: WAV buffer (24kHz PCM)
    AUD->>QUEUE: addChunk(index, buffer)
    
    alt É o próximo chunk
        QUEUE->>QUEUE: playChunk()
        QUEUE-->>U: 🔊 Reproduz áudio
    else Não é o próximo
        QUEUE->>QUEUE: armazena em fila
    end
    
    loop Até todos chunks
        QUEUE->>QUEUE: playNextAvailableChunks()
    end
    
    QUEUE-->>U: ✅ Playback completo
Loading

Padrões Arquiteturais Implementados

1. Context Pass-through Pattern

// Contexto do artigo é passado para descrição de imagens
const pageContext = await generatePageContext(simplifiedText);
const imageDescriptions = await processImagesWithDescriptions(
    imageMap, 
    apiKey, 
    language, 
    pageContext  // ← Contexto passado
);

2. Stabilized Parallel Batched TTS

// Processamento paralelo com concorrência controlada
async generateAudioInChunks(fullText, language, progressCallback, maxConcurrency = 5) {
    const chunks = this.splitIntoLogicalChunks(fullText, 400);
    
    for (let i = 0; i < chunks.length; i += maxConcurrency) {
        const batch = chunks.slice(i, i + maxConcurrency);
        await Promise.all(batch.map(chunk => this.convertTextToSpeech(chunk)));
    }
}

3. State Guarding

// Previne execução dupla
if (window.extensionVariables.isSimplifying) {
    console.warn('Simplification already in progress');
    return;
}
window.extensionVariables.isSimplifying = true;

4. Extension Context Robustness

// Detecta contexto invalidado e orienta usuário
try {
    const result = await chrome.storage.sync.get(['language']);
} catch (error) {
    if (error.message?.includes('Extension context invalidated')) {
        alert('Extension was reloaded. Please refresh the page.');
        return;
    }
}

🌍 Capacidades Multilíngues

Arquitetura de Tradução/Simplificação

graph LR
    A[Página Original] --> B{Detecta Idioma Original}
    B --> C[Extrai Conteúdo]
    C --> D{Idioma Config ≠ Original?}
    
    D -->|Sim| E[Prompt: Translate + Simplify]
    D -->|Não| F[Prompt: Simplify Only]
    
    E --> G[Gemini API]
    F --> G
    
    G --> H[Texto Simplificado<br/>no Idioma Config]
Loading

Exemplos de Uso Multilíngue

Exemplo 1: Português → Inglês

📄 Input (PT - G1 Notícias):
"O Supremo Tribunal Federal (STF) julgou procedente a Ação Direta de 
Inconstitucionalidade (ADI) que questionava dispositivos da Lei..."

⚙️ Configuração: Idioma = English
🤖 Processo: Tradução + Simplificação
📝 Output (EN - Simplified):
"The Supreme Court ruled that parts of the law are unconstitutional. 
The case (ADI) challenged specific articles..."

Exemplo 2: Inglês → Português

📄 Input (EN - Wikipedia):
"Quantum mechanics is a fundamental theory in physics that provides 
a description of the physical properties of nature at the scale of 
atoms and subatomic particles..."

⚙️ Configuração: Idioma = Português
🤖 Processo: Tradução + Simplificação
📝 Output (PT - Simplificado):
"A mecânica quântica é uma teoria da física. Ela explica como 
funcionam átomos e partículas muito pequenas..."

Exemplo 3: Espanhol → Espanhol (Simplificação apenas)

📄 Input (ES - El País):
"El Tribunal Constitucional ha desestimado el recurso de 
inconstitucionalidad interpuesto contra diversos preceptos..."

⚙️ Configuração: Idioma = Español
🤖 Processo: Simplificação (sem tradução)
📝 Output (ES - Simplificado):
"El Tribunal Constitucional rechazó el recurso contra la ley. 
Los artículos cuestionados..."

Configuração de Prompts por Idioma

Os prompts são externalizados em src/utils/prompts.js:

const Prompts = {
    en: {
        textSimplification: `Translate to English and simplify...`,
        imageDescription: `Describe this image in short paragraph...`,
        wordDefinition: `Define the word "{word}"...`
    },
    pt: {
        textSimplification: `Traduza para Português e simplifique...`,
        imageDescription: `Descreva esta imagem em parágrafo curto...`,
        wordDefinition: `Defina a palavra "{word}"...`
    },
    es: { /* ... */ }
};

♿ Recursos de Acessibilidade

Toolbar de Acessibilidade

┌─────────────────────────────────────────────┐
│ 🎨 [H] Alto Contraste  │  A⁺ A⁻  Fonte      │
└─────────────────────────────────────────────┘

Implementação Alto Contraste

/* high-contrast.css */
.high-contrast-mode {
    background-color: #000000 !important;
    color: #FFFFFF !important;
}

.high-contrast-mode a {
    color: #FFFF00 !important; /* Amarelo para links */
}

.high-contrast-mode img {
    border: 2px solid #FFFFFF !important;
}

Contraste WCAG AAA:

  • Texto normal: 7:1 (branco sobre preto)
  • Texto grande: 4.5:1
  • Componentes UI: 3:1

Navegação por Teclado

Todos os elementos interativos são acessíveis via teclado:

  • Tab: Navegação entre elementos
  • Enter/Space: Ativação de botões
  • Esc: Fechar popups e overlays
  • Atalhos Alt+: Ações rápidas

ARIA Labels

<button 
    id="generate-audio-btn" 
    aria-label="Gerar áudio da página simplificada"
    data-i18n="simplified.generateAudio">
    🔊 Gerar Áudio
</button>

💾 Instalação e Configuração

Pré-requisitos

Instalação

  1. Clone o repositório:
git clone https://github.com/seu-usuario/SimplifAI.git
cd SimplifAI
  1. Carregue a extensão no Chrome:

    • Acesse chrome://extensions/
    • Ative "Modo do desenvolvedor" (canto superior direito)
    • Clique "Carregar sem compactação"
    • Selecione a pasta src/
  2. Configure via Wizard de Onboarding:

    • O wizard abre automaticamente na primeira instalação
    • Etapa 1: Escolha seu idioma (PT/ES/EN)
    • Etapa 2: Selecione o modelo Gemini e insira sua API Key
    • Etapa 3: Pronto! Extensão configurada

Nota: Se vocé fechar o wizard antes de configurar e tentar usar a extensão, o wizard reabrirá automaticamente.

Configuração Avançada

Modificar Concorrência TTS

// src/services/audio.js
async generateAudioInChunks(
    fullText, 
    language = 'en', 
    progressCallback = null, 
    maxConcurrency = 5  // ← Altere aqui (1-10)
) { ... }

Ajustar Tamanho de Chunk TTS

// src/services/audio.js
splitIntoLogicalChunks(
    text, 
    maxChunkSize = 2000  // ← Altere aqui (400-4000 chars)
) { ... }

📖 Guia de Uso

Simplificar uma Página

Método 1: Ícone da Extensão

  1. Navegue até a página desejada
  2. Clique no ícone SimplifAI
  3. Aguarde o processamento (5-30s)

Método 2: Menu Contextual

  1. Clique direito na página
  2. Selecione "Simplificar esta página"

Método 3: Atalho de Teclado

  1. Pressione Alt/Cmd + S

Gerar Áudio

  1. Simplifique a página primeiro
  2. Clique em "🔊 Gerar Áudio"
  3. Aguarde o processamento progressivo
  4. Use os controles:
    • ▶️ Play/Pause
    • ⏹️ Stop
    • Barra de progresso

Usar o Dicionário

Método 1: Duplo Clique

  1. Dê duplo clique na palavra

Método 2: Menu Contextual

  1. Selecione a palavra
  2. Clique direito
  3. "Definir palavra selecionada"

Ativar Alto Contraste

  1. Na página simplificada, clique no botão "🎨 Alto Contraste"
  2. Para desativar, clique novamente

Ajustar Tamanho da Fonte

  • Aumentar: Clique no botão A⁺
  • Diminuir: Clique no botão A⁻

📁 Estrutura do Projeto

SimplifAI/
├── src/
│   ├── components/              # Componentes principais
│   │   ├── background.js       # Service Worker (476 linhas)
│   │   ├── content.js          # Content Script principal (218 linhas)
│   │   ├── onboarding.html     # Wizard de primeira configuração
│   │   ├── onboarding.js       # Lógica do onboarding (330 linhas)
│   │   ├── popup.html          # Interface de configuração
│   │   ├── popup.js            # Lógica do popup (311 linhas)
│   │   ├── simplified.html     # Template da página simplificada
│   │   └── simplified-page.js  # Lógica da página simplificada (776 linhas)
│   │
│   ├── content/                 # Módulos de processamento (2,210 linhas)
│   │   ├── extractors/
│   │   │   ├── metadata-extractor.js    # Extração de metadados (207 linhas)
│   │   │   ├── content-extractor.js     # Extração de conteúdo (452 linhas)
│   │   │   ├── author-extractor.js      # Extração de autores (268 linhas)
│   │   │   ├── hero-image-extractor.js  # Imagem principal (304 linhas)
│   │   │   └── image-mapper.js          # Mapeamento de imagens (292 linhas)
│   │   ├── processors/
│   │   │   ├── image-processor.js       # Processamento de imagens (502 linhas)
│   │   │   └── markdown-processor.js    # Conversão Markdown→HTML (116 linhas)
│   │   ├── ui/
│   │   │   └── overlay-manager.js       # Gerenciador de UI (224 linhas)
│   │   └── orchestrator/
│   │       └── simplification-orchestrator.js  # Coordenador (370 linhas)
│   │
│   ├── services/                # Serviços core
│   │   ├── gemini.js           # Integração Gemini API (608 linhas)
│   │   └── audio.js            # Serviço TTS (700 linhas)
│   │
│   ├── utils/                   # Utilitários (2,640 linhas)
│   │   ├── translations.js     # Sistema i18n (340 linhas)
│   │   ├── prompts.js          # Prompts LLM (401 linhas)
│   │   ├── keyboard-shortcuts.js  # Gerenciador de atalhos (118 linhas)
│   │   ├── constants.js        # Constantes e seletores (224 linhas)
│   │   ├── error-handler.js    # Tratamento de erros (420 linhas)
│   │   ├── logger.js           # Sistema de logs (260 linhas)
│   │   ├── retry.js            # Lógica de retry (432 linhas)
│   │   └── state-manager.js    # Gerenciamento de estado (445 linhas)
│   │
│   ├── lib/                     # Bibliotecas externas
│   │   └── purify.min.js       # DOMPurify (sanitização HTML)
│   │
│   ├── styles/
│   │   ├── styles.css          # Estilos principais (~1,300 linhas)
│   │   └── high-contrast.css   # Modo alto contraste
│   │
│   ├── icons/                   # Ícones da extensão
│   │   └── icon128.png
│   │
│   └── manifest.json            # Manifesto Chrome Extension V3
│
├── README.md                    # Este arquivo
└── LICENSE                      # Licença MIT

Métricas do Código

Categoria Arquivos Linhas
Components 5 2,118
Content Modules 9 2,735
Services 2 1,308
Utilities 8 2,640
Total JavaScript 24 8,801

🛠️ Tecnologias Utilizadas

Frontend

  • JavaScript ES6+: Vanilla JS, sem frameworks
  • HTML5: Semantic markup
  • CSS3: Grid, Flexbox, Custom Properties
  • Web APIs:
    • Web Audio API (reprodução de áudio)
    • Selection API (dicionário)
    • Fetch API (requisições)

Chrome APIs (Manifest V3)

  • chrome.storage.sync: Persistência de configurações
  • chrome.runtime: Comunicação entre componentes
  • chrome.scripting: Injeção de scripts
  • chrome.contextMenus: Menu contextual
  • chrome.tabs: Gerenciamento de abas

APIs Externas

  • Google Gemini API (modelos configuráveis pelo usuário):
    • gemini-2.5-flash: Simplificação de texto e visão (Free tier disponível)
    • gemini-3-flash-preview: Modelo mais recente (requer billing account)
    • gemini-2.5-flash-preview-tts: Text-to-Speech (áudio)
  • Formatos: JSON, Base64, WAV (24 kHz PCM)

Bibliotecas

  • DOMPurify 3.0+: Sanitização de HTML (prevenir XSS)
  • Readability.js: Extração de conteúdo principal (baseado no Mozilla Readability)

Ferramentas de Desenvolvimento

  • Node.js: Validação de sintaxe (node -c)
  • Chrome DevTools: Debugging e performance
  • Git: Controle de versão

⚠️ Limitações Conhecidas

Limitações Técnicas

  1. Páginas Restritas: Não funciona em:

    • chrome:// (páginas internas do Chrome)
    • chrome-extension:// (outras extensões)
    • file:// (arquivos locais sem permissão)
  2. APIs Externas:

    • Requer conexão com internet
    • Sujeito a limites de taxa da Gemini API
    • Gemini TTS pode retornar erro 500 intermitente (retry automático)
  3. Extração de Conteúdo:

    • Alguns sites bloqueiam content scripts
    • SPAs (React, Vue) podem ter conteúdo dinâmico não capturado
    • Paywalls não são contornados

Limitações de Qualidade

  1. Simplificação:

    • Textos muito técnicos podem perder nuances
    • Siglas desconhecidas podem ser preservadas
    • Tabelas complexas podem ser simplificadas em excesso
  2. TTS:

    • Pausas e entonação podem não ser naturais
    • Nomes próprios podem ser pronunciados incorretamente
    • Um único idioma de voz (Kore) para todos os idiomas
  3. Imagens:

    • Imagens decorativas podem ser incluídas
    • Contexto pode não ser suficiente para descrições precisas
    • Imagens em SVG não são processadas

Privacidade

  • Dados enviados à Gemini API:
    • Texto completo da página
    • Imagens (como Base64)
    • Palavras selecionadas (dicionário)
  • Não coletamos: Nenhum dado de uso, histórico ou analítica

🤝 Contribuindo

Contribuições são bem-vindas! Siga estas diretrizes:

Processo

  1. Fork o repositório
  2. Crie uma branch de feature (git checkout -b feature/MinhaNovaFuncionalidade)
  3. Commit suas mudanças (git commit -am 'Adiciona nova funcionalidade X')
  4. Push para a branch (git push origin feature/MinhaNovaFuncionalidade)
  5. Abra um Pull Request

Padrões de Código

  • Idioma: Código e comentários em inglês
  • JSDoc: Documente funções complexas
  • Linting: Execute node -c em arquivos modificados
  • Commits: Mensagens descritivas em português ou inglês

Áreas Prioritárias

  • Suporte a mais idiomas (FR, DE, IT, etc.)
  • Melhorias na extração de conteúdo para SPAs
  • Integração com screen readers (NVDA, JAWS)
  • Exportação de conteúdo simplificado (PDF, EPUB)
  • Cache inteligente para reduzir chamadas API

📄 Licença

Este projeto está licenciado sob a Apache License 2.0.

Copyright 2026 SimplifAI Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

📞 Suporte e Contato


🙏 Agradecimentos

  • Google Gemini pela API poderosa e acessível
  • Comunidade de Linguagem Simples do Brasil pelos padrões ISO 24495-1
  • Desenvolvedores de Acessibilidade Web pelas melhores práticas WCAG
  • Todos os contribuidores que tornam este projeto possível

Desenvolvido com ♿ para um web mais acessível

Star on GitHub