diff --git a/.gitignore b/.gitignore index 81ffac5..4748f1a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ backups/ web/node_modules/ web/.next/ web/next-env.d.ts +web/tsconfig.tsbuildinfo diff --git a/docs/ARQUITETURA.md b/docs/ARQUITETURA.md index 4b69237..d76cd4c 100644 --- a/docs/ARQUITETURA.md +++ b/docs/ARQUITETURA.md @@ -1,41 +1,35 @@ -# Bot de Pontos v2 — Documento de Arquitetura +# Bot de Pontos — Documento de Arquitetura -> Status: **Sprints 0 a 6 e evoluções implementadas; backend compila e passa nos testes, painel passa na checagem de tipos** (ver `README.md` na raiz do projeto e a seção 16) -> Base: projeto `Modelo` (versão final em `Modelo/Fase2/Sprint4`) -> Stack: **Go 1.25 (backend) · Next.js 15 (web) · PostgreSQL 17 · Docker Compose** +> Estado: **implementado** — backend compila e passa nos testes; painel passa na checagem de tipos (seção 16) +> Stack: **Go 1.25 (backend) · Next.js 15 (painel) · PostgreSQL 17 · Docker Compose** + +Este documento descreve o sistema como ele é hoje. Os números das seções são citados nos comentários do código; ao editar, mantenha a numeração. --- -## 1. Objetivo +## 1. Visão geral -Reconstruir o Bot de Pontos com uma arquitetura que: +O Bot de Pontos lembra cada usuário, pelo Telegram, da hora de **voltar do almoço** e da hora de **encerrar a jornada**. Para isso, consulta os pontos do dia na **PontoMais**, calcula o retorno (`entrada2`) e a saída (`saida2`) previstos e envia o aviso alguns minutos antes de cada horário. -- separe **backend** (Go) e **interface web** (Next.js) por um contrato de API explícito; -- troque o SQLite por **PostgreSQL**, permitindo vários processos e containers escrevendo com segurança; -- rode inteiramente em **containers Docker**; -- corrija as inconsistências conhecidas do Modelo e deixe pontos de extensão para novas regras. +- O usuário comum usa o **Telegram**: cadastro, consulta ao vivo e liga/pausa os lembretes. +- Os administradores usam um **painel web** para aprovar usuários, configurar credenciais e jornadas, acompanhar lembretes e auditoria, manter feriados e a janela de consulta e gerenciar as contas do painel. +- Nada é registrado na PontoMais: o sistema só lê os pontos. -O domínio continua o mesmo: consultar os pontos do dia na PontoMais, calcular `entrada2` e `saida2` e lembrar o usuário pelo Telegram. +## 2. Características principais -O Modelo **nunca rodou em produção**, então não há dados a migrar: a v2 começa com o banco vazio e não precisa ser compatível com o SQLite do Modelo. - -## 2. O que muda em relação ao Modelo - -| Tema | Modelo | v2 | -| --- | --- | --- | -| Web | HTML renderizado pelo Go (`webassets/`) | Next.js (App Router) consumindo API REST do Go | -| API | Não existe (rotas devolvem HTML) | API REST JSON versionada (`/api/v1`) | -| Banco | SQLite WAL, arquivo compartilhado | PostgreSQL 17, container próprio | -| Concorrência do despacho | `UPDATE ... WHERE status='scheduled'` | `SELECT ... FOR UPDATE SKIP LOCKED` + lock de líder | -| Ciclos | Reconciliação 15 min e despacho 5 min, **no mesmo loop** (um bloqueia o outro) | Reconciliação 15 min e despacho **2 min**, em **goroutines independentes** | -| Consultas à PontoMais | O dia inteiro, todo dia útil, todos os usuários a cada 15 min | Só na **janela 11:30–19:00**, com **frequência adaptativa por usuário** (15 min, 60 min ou nenhuma); ~11 consultas/usuário num dia típico (ver 9.12) | -| Datas | `TEXT` | `timestamptz` / `date` | -| Executáveis | `bot`, `admin`, `web` | uma imagem Go com subcomandos `api`, `worker`, `admin`, `migrate` (e `healthcheck`, `version`) | -| Contas web | Uma conta | N contas com papéis (`owner`, `admin`, `viewer`) | -| Fuso por usuário | Campo existe, mas é ignorado | Aplicado em todos os cálculos | -| Regras de jornada | Por usuário, mas com o texto "8h00" fixo | Por usuário, com mensagens formatadas a partir da configuração | -| Ativação | Telegram e web com validações diferentes | Um único caso de uso para as duas interfaces | -| Deploy | LXC + systemd, ou Docker | Docker Compose | +| Tema | Como funciona | +| --- | --- | +| Interfaces | Bot do Telegram (*long polling*) e painel Next.js que consome a API REST do Go (`/api/v1`) | +| Banco | PostgreSQL 17 em container próprio; instantes em `timestamptz`, dias em `date` | +| Processos | Uma imagem Go com os subcomandos `api`, `worker`, `migrate`, `admin`, `healthcheck` e `version` | +| Ciclos | Reconciliação a cada 15 min e despacho a cada 2 min, em goroutines independentes (8.2) | +| Consultas à PontoMais | Só na **janela 11:30–19:00**, com **frequência adaptativa por usuário**; ~11 consultas/usuário num dia típico (9.12) | +| Despacho | `SELECT ... FOR UPDATE SKIP LOCKED` e worker único por *advisory lock*; no máximo uma mensagem por lembrete (6.3) | +| Fuso | Cada usuário tem o seu; todos os cálculos usam esse fuso | +| Jornada | Por usuário (almoço, jornada, antecedências, janela opcional); mensagens formatadas a partir dela | +| Ativação | Um único caso de uso para Telegram e painel; exige credencial validada | +| Contas do painel | Várias contas com papéis `owner`, `admin` e `viewer`, inclusive leitura restrita a um usuário (9.6) | +| Implantação | Docker Compose numa máquina Debian, atrás do Nginx Proxy Manager da rede (11) | ## 3. Visão de containers @@ -110,7 +104,7 @@ backend/ │ ├── adapters/ │ │ ├── postgres/ # repositório (SQL escrito à mão com pgx) e migrations │ │ ├── pontomais/ # cliente HTTP + cache de token em memória -│ │ ├── telegram/ # cliente próprio da Bot API (portado do Modelo) +│ │ ├── telegram/ # cliente próprio da Bot API │ │ ├── feriados/ # cliente feriadosapi.com (endpoint por cidade) │ │ └── crypto/ # AES-GCM, Argon2id, tokens │ ├── httpapi/ # API REST: router, handlers JSON, DTOs @@ -148,12 +142,12 @@ Mesmo que alguém suba duas réplicas do `worker` por engano, o processo pega um | Driver e pool | `jackc/pgx/v5` (`pgxpool`) | | Queries | SQL escrito à mão com `pgx` (ver decisão 27) | | Migrations | `pressly/goose` (migrations em SQL embutidas no binário) | -| HTTP | `net/http` com o roteador nativo do Go 1.22+ (como no Modelo), sem framework | +| HTTP | `net/http` com o roteador nativo do Go, sem framework | | Logs | `log/slog` em JSON | | Validação | validação manual nos DTOs (sem framework) | -| Telegram | cliente próprio, portado do Modelo (ver decisão 27) | +| Telegram | cliente próprio, sem biblioteca externa (ver decisão 27) | | Criptografia e terminal | `golang.org/x/crypto` (Argon2id), `golang.org/x/term` (senha sem eco na CLI) | -| Testes de integração | previstos com `testcontainers-go` e Postgres real; **ainda não existem** (ver 13) | +| Testes de integração | não há; o plano é `testcontainers-go` com Postgres real (13) | ## 5. Frontend Next.js @@ -195,18 +189,18 @@ web/ - **Server Components** buscam dados chamando `http://api:8080/api/v1/...` e repassam o cookie de sessão recebido. - **Mutações** usam `fetch('/api/v1/...')` no cliente (`lib/client-api.ts`), sem *Server Actions*. O `rewrite` do Next encaminha essas chamadas para o Go **na mesma origem**, então não há CORS e o cookie funciona direto. -- Os **tipos** ficam em `web/lib/types.ts`, escritos à mão a partir do `openapi.yaml` e de `httpapi/dto.go`. A geração automática (`openapi-typescript`) pode ser adotada depois (decisão 27). +- Os **tipos** ficam em `web/lib/types.ts`, escritos à mão a partir do `openapi.yaml` e de `httpapi/dto.go` (decisão 27). - **UI:** CSS próprio (`app/globals.css`), com tema claro/escuro e layout responsivo; filtros por query string nas tabelas (decisão 27). ### 5.4 Autenticação -A autenticação continua **no Go**, porque a lógica já existe e fica centralizada: +A autenticação fica **no Go**, centralizada: 1. `POST /api/v1/auth/login` valida a senha com Argon2id, aplica o bloqueio por tentativas e cria a sessão no Postgres, guardando só o hash do token. 2. O Go responde com o cookie `bp_session` (`HttpOnly`, `Secure`, `SameSite=Strict`, `Path=/`). 3. **CSRF:** é usado *double submit*. O cookie `bp_csrf` (legível pelo JS) precisa ser repetido no header `X-CSRF-Token` em toda requisição mutável. Além disso, o Go confere o header `Origin`. 4. O `middleware.ts` do Next só verifica se o cookie existe, para redirecionar. **Quem autoriza de verdade é sempre o Go.** -5. Os timeouts continuam os do Modelo: sessão absoluta de 8h e 30 min de inatividade. +5. Sessão absoluta de 8h e 30 min de inatividade (`BP_SESSION_DURATION`, `BP_SESSION_IDLE`). Após 5 senhas erradas seguidas, a conta fica bloqueada por 15 min. ## 6. Banco de dados (PostgreSQL) @@ -216,11 +210,11 @@ A autenticação continua **no Go**, porque a lógica já existe e fica centrali - Instantes em `timestamptz` (gravados em UTC); dia de referência em `date`. - Estados em tipos `enum` do Postgres. - `created_at` e `updated_at`, com trigger para atualizar `updated_at`. -- Migrations só para a frente, numeradas e em SQL. +- Migrations numeradas, em SQL (`goose`), embutidas no binário e aplicadas pelo serviço `migrate`. -### 6.2 Esquema atual +### 6.2 Esquema -Resumo do resultado das migrations `00001` a `00003` (`backend/db/migrations/`). Triggers de `updated_at`, índices secundários e permissões ficam nos arquivos SQL. +Resumo do esquema resultante das migrations em `backend/db/migrations/`. Triggers de `updated_at`, índices secundários e permissões ficam nos arquivos SQL. ```sql CREATE TYPE user_status AS ENUM ('pending', 'active', 'disabled'); @@ -244,7 +238,7 @@ CREATE TABLE users ( updated_at timestamptz NOT NULL DEFAULT now() ); --- Regras de jornada separadas do cadastro (permite histórico/versão no futuro) +-- Regras de jornada do usuário CREATE TABLE work_schedules ( user_id bigint PRIMARY KEY REFERENCES users(id), lunch_minutes int NOT NULL DEFAULT 60 CHECK (lunch_minutes BETWEEN 15 AND 180), @@ -310,7 +304,7 @@ CREATE TABLE web_accounts ( CREATE TABLE web_sessions ( id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, - account_id bigint NOT NULL REFERENCES web_accounts(id) ON DELETE CASCADE, -- 00003 + account_id bigint NOT NULL REFERENCES web_accounts(id) ON DELETE CASCADE, token_hash bytea NOT NULL UNIQUE, csrf_token_hash bytea NOT NULL, expires_at timestamptz NOT NULL, @@ -321,10 +315,10 @@ CREATE TABLE web_sessions ( created_at timestamptz NOT NULL DEFAULT now() ); -CREATE TABLE holidays ( -- cache persistente da API de feriados +CREATE TABLE holidays ( -- feriados da API e manuais day date PRIMARY KEY, name text NOT NULL, - source text NOT NULL CHECK (source IN ('feriadosapi', 'feriados.dev', 'manual')), -- 00002; feriados.dev = legado + source text NOT NULL CHECK (source IN ('feriadosapi', 'feriados.dev', 'manual')), -- feriados.dev: só registros antigos created_at timestamptz NOT NULL DEFAULT now() ); @@ -348,7 +342,7 @@ CREATE INDEX user_days_next_check_idx ON user_days (next_check_at) WHERE next_ch CREATE TABLE app_settings ( key text PRIMARY KEY, -- ex.: 'query_window_start' value jsonb NOT NULL, -- ex.: "11:30" - updated_by_account bigint REFERENCES web_accounts(id) ON DELETE SET NULL, -- 00003 + updated_by_account bigint REFERENCES web_accounts(id) ON DELETE SET NULL, updated_at timestamptz NOT NULL DEFAULT now() ); @@ -364,8 +358,8 @@ CREATE TABLE audit_logs ( occurred_at timestamptz NOT NULL DEFAULT now(), source audit_source NOT NULL, actor_user_id bigint REFERENCES users(id), - actor_account bigint REFERENCES web_accounts(id) ON DELETE SET NULL, -- 00003 - actor_account_name text, -- 00003: nome da conta no momento do evento + actor_account bigint REFERENCES web_accounts(id) ON DELETE SET NULL, + actor_account_name text, -- nome da conta no momento do evento (sobrevive à exclusão) target_user_id bigint REFERENCES users(id), event_type text NOT NULL, success boolean NOT NULL, @@ -375,12 +369,12 @@ CREATE INDEX audit_logs_time_idx ON audit_logs (occurred_at DESC); CREATE INDEX audit_logs_target_idx ON audit_logs (target_user_id, occurred_at DESC); ``` -Diferenças importantes em relação ao Modelo: +Notas sobre o esquema: -- A **credencial** e a **jornada** saem de `users` e ganham tabelas próprias. Isso deixa o cadastro mais limpo e permite rotacionar a chave de criptografia (`key_version`). +- **Credencial** e **jornada** ficam em tabelas próprias, separadas do cadastro. A senha da PontoMais é cifrada com AES-256-GCM, e `key_version` permite trocar a chave (`botpontos admin rotate-key`). - A **antecedência** pode ser diferente para cada lembrete (`entrada2_lead_minutes` / `saida2_lead_minutes`). -- A tabela `holidays` guarda feriados confirmados e também **feriados manuais** cadastrados pelo painel. A ordem de consulta está na seção 9.9. -- `audit_logs.details` passa a ser `jsonb`, o que permite filtrar no painel. +- A tabela `holidays` guarda os feriados vindos da API e os **feriados manuais** cadastrados pelo painel. A ordem de consulta está na seção 9.9. +- `audit_logs.details` é `jsonb`, sem segredos. - `notifications.predicted_at` guarda o horário previsto do ponto, para a mensagem sempre informar a hora certa (9.3). - O banco tem dois usuários: `botpontos` (dono, usado pelas migrations e pelo backup) e `botpontos_app` (API e worker, só `SELECT/INSERT/UPDATE/DELETE`), criado por `postgres/init/01-create-app-role.sh`. @@ -407,7 +401,7 @@ FROM due WHERE n.id = due.id RETURNING n.*; ``` -As duas etapas rodam a cada **2 min** (ver 8.2), sempre nessa ordem, então nada com mais de 10 min de atraso chega a ser reservado. Na etapa 2, a tolerância é conferida de novo no Go, logo antes do envio, para cobrir o tempo entre a reserva e a chamada ao Telegram. Depois do `COMMIT`, o worker envia cada mensagem e marca o resultado (`sent` ou `failed`). Um job de limpeza marca como `failed` toda linha que esteja em `sending` há mais de **5 minutos** (`BP_SENDING_TIMEOUT`), que é o caso de *crash* no meio do envio. **Ela não volta para `scheduled`**, para manter a garantia do Modelo de "no máximo uma mensagem". +As duas etapas rodam a cada **2 min** (ver 8.2), sempre nessa ordem, então nada com mais de 10 min de atraso chega a ser reservado. Na etapa 2, a tolerância é conferida de novo no Go, logo antes do envio, para cobrir o tempo entre a reserva e a chamada ao Telegram. Depois do `COMMIT`, o worker envia cada mensagem e marca o resultado (`sent` ou `failed`). Um job de limpeza marca como `failed` toda linha que esteja em `sending` há mais de **5 minutos** (`BP_SENDING_TIMEOUT`), que é o caso de *crash* no meio do envio. **Ela não volta para `scheduled`**, para garantir "no máximo uma mensagem" por lembrete. ### 6.4 Pool e conexões @@ -449,7 +443,7 @@ Todas as rotas ficam sob `/api/v1`, usam JSON e exigem sessão, exceto `auth/log | GET/POST | `/accounts` | owner | Lista e cria contas web | | PATCH | `/accounts/{id}` | owner | Papel, desativação e usuário ligado (`user_id`) | | DELETE | `/accounts/{id}` | owner | Exclui a conta (não a própria nem o último owner ativo); auditado em `web_account_deleted` | -| POST | `/accounts/{id}/reset-password` | owner | Resolve a pendência "sem redefinição de senha" | +| POST | `/accounts/{id}/reset-password` | owner | Define nova senha e encerra as sessões da conta | As rotas marcadas como `viewer` têm restrições extras para a conta de leitura ligada a um usuário (tabela em 9.6). Erros seguem o formato `application/problem+json` (RFC 9457): @@ -491,7 +485,7 @@ Os usuários são processados com concorrência limitada (*worker pool* de 4, `B **Regras de implementação:** -- Cada ciclo roda na **sua própria goroutine**, com ticker próprio. No Modelo (`scheduler/scheduler.go`), reconciliação e despacho dividem o mesmo `select`, então uma reconciliação lenta segura todos os envios. +- Cada ciclo roda na **sua própria goroutine**, com ticker próprio, então uma reconciliação lenta não atrasa os envios. - A reconciliação tem **prazo total** (*deadline*) de 5 min por ciclo (`BP_RECONCILIATION_DEADLINE`) e timeout de 10 s por chamada à PontoMais (`BP_PONTOMAIS_TIMEOUT`). Usuários que não terminarem dentro do prazo ficam para o próximo ciclo. - Se um ciclo ainda estiver rodando quando o próximo tick chegar, o tick é ignorado e não se acumula. - Os ticks são alinhados ao relógio (ex.: :00, :02, :04...) para o comportamento ser previsível nos logs. @@ -510,28 +504,26 @@ Os usuários são processados com concorrência limitada (*worker pool* de 4, `B ### 8.3 Fluxo de um comando do Telegram -`Update → bot.Router → autorização → app.CasoDeUso → resposta formatada`. O mesmo caso de uso atende o handler HTTP, e é isso que elimina a divergência de ativação entre Telegram e web que existe no Modelo. +`Update → bot.Router → autorização → app.CasoDeUso → resposta formatada`. O mesmo caso de uso atende o handler HTTP, então Telegram e painel aplicam as mesmas regras (ex.: ativação só com credencial validada). O bot só responde em conversa privada; mensagens de grupos são ignoradas. ### 8.4 Comandos do Telegram -São os mesmos comandos do Modelo, com as correções da seção 9.2. - **Usuário** -| Comando | Quem pode | Comportamento na v2 | +| Comando | Quem pode | Comportamento | | --- | --- | --- | | `/start`, `/iniciar` | qualquer chat | Chat desconhecido recebe orientação para usar `/cadastrar`; usuário conhecido recebe a ajuda do seu papel | | `/cadastrar` | qualquer chat | Cria o cadastro `pending` (idempotente por `chat_id`) e avisa os admins | | `/ajuda` | cadastrado | Lista os comandos do papel | | `/status` | cadastrado | Cadastro, credencial (configurada/validada, sem dados), lembretes ligados ou pausados e motivo da pausa (manual, 3 falhas na API), a situação do dia (ex.: "hoje: nenhum ponto até 11:45, consultas encerradas") e a janela de consulta que vale para o usuário (indicando se é a global ou personalizada) | | `/entrada2` | ativo + credencial | Consulta ao vivo e informa o retorno previsto (≥ 2 pontos), no fuso do usuário. Funciona a qualquer hora, fora da janela também; se encontrar pontos num dia `no_points`/`not_working`, retoma o dia (9.12) | -| `/saida2` | ativo + credencial | Consulta ao vivo e informa a saída prevista (≥ 3 pontos). O texto usa a jornada configurada (ex.: "Para completar 6h00"), não um "8h00" fixo | +| `/saida2` | ativo + credencial | Consulta ao vivo e informa a saída prevista (≥ 3 pontos). O texto usa a jornada configurada do usuário (ex.: "Para completar 6h00") | | `/ativarponto` | ativo + credencial validada | Liga os lembretes, zera o contador de falhas e, se o dia estiver `no_points`/`not_working`, **retoma as consultas de hoje** (9.12) | | `/desativarponto` | ativo | Pausa os lembretes e cancela os `scheduled` do dia | **Admin do Telegram** (`is_bot_admin = true` e status `active`) -| Comando | Comportamento na v2 | +| Comando | Comportamento | | --- | --- | | `/usuarios` | Lista usuários com ID, status, credencial e lembretes | | `/ativarusuario ` | Usa o mesmo caso de uso `ActivateUser` do painel: **recusa se o usuário não tiver credencial validada** e orienta a configurá-la pelo painel | @@ -542,30 +534,27 @@ São os mesmos comandos do Modelo, com as correções da seção 9.2. ## 9. Regras de negócio -### 9.1 Mantidas do Modelo +### 9.1 Cálculo dos horários -- Quatro pontos normais: `entrada1`, `saida1`, `entrada2`, `saida2`. +- Quatro pontos normais por dia: `entrada1`, `saida1`, `entrada2`, `saida2`, na ordem em que aparecem na PontoMais. - `entrada2 = saida1 + almoço` e `saida2 = entrada2 + (jornada − (saida1 − entrada1))`. +- O lembrete sai `antecedência` minutos antes do horário previsto (`entrada2_lead_minutes` / `saida2_lead_minutes`, 5 min por padrão). - No máximo um lembrete por `(usuário, dia, tipo)`. -- Mais de 4 pontos conta como hora extra e fica fora do escopo. +- Mais de 4 pontos conta como hora extra e fica fora do escopo (9.7). - Notificação `failed` não é reenviada **automaticamente** (o reenvio manual está na seção 9.5). -- Nada é registrado na PontoMais. -### 9.2 Corrigidas +### 9.2 Regras gerais -| Problema no Modelo | Correção na v2 | +| Regra | Como é aplicada | | --- | --- | -| Fuso do usuário ignorado | O cálculo do dia e dos horários usa `users.timezone` | -| Texto "8h00" fixo em `/saida2` | A mensagem formata `daily_work_minutes` | -| Ativação diferente entre Telegram e web | Um caso de uso `ActivateUser`; regra única: **exige credencial validada** | -| Sem redefinição de senha web | `POST /accounts/{id}/reset-password` + revogação das sessões | -| Uma só conta web | Várias contas com papéis | -| Retorno atrasado do almoço pausa os lembretes do usuário | Ver o detalhe abaixo | -| Reconciliação lenta bloqueia o despacho (mesmo loop) | Goroutines independentes e despacho a cada 2 min (ver 8.2) | +| Fuso do usuário | O dia de referência e todos os horários são calculados em `users.timezone` | +| Jornada nas mensagens | O texto usa `daily_work_minutes` do usuário (ex.: "jornada de 6h00") | +| Ativação | Um caso de uso `ActivateUser` para Telegram e painel; **exige credencial validada** | +| Atraso no almoço | Um lembrete calculado para um horário que já passou segue a regra de 9.3; **o usuário nunca é pausado por atraso** | +| Ciclos | Reconciliação e despacho independentes; uma reconciliação lenta não segura os envios (8.2) | +| Contas do painel | Várias contas com papéis; redefinir a senha encerra as sessões da conta (9.6) | -**Detalhe do último item.** No Modelo (`scheduler/reconciliation.go`), com 2 pontos, se o horário do lembrete já passou (`scheduledAt.Before(now)`), o usuário tem os lembretes do dia cancelados **e as notificações desativadas**. Isso acontece sempre que alguém fica mais tempo no almoço do que o previsto menos a antecedência e a reconciliação roda nesse intervalo. Na v2 vale a regra de lembrete atrasado da seção 9.3, e **o usuário nunca é pausado por atraso**. - -### 9.3 Lembrete atrasado (decidido) +### 9.3 Lembrete atrasado **Regra:** se o lembrete atrasar **até 10 min** em relação ao `scheduled_at`, ele é enviado. **Acima de 10 min, não é enviado**: fica com status `expired` e é registrado na auditoria (`event_type = 'notification_expired'`, com o atraso em minutos em `details`). O usuário **não** é pausado. @@ -585,18 +574,18 @@ A regra vale nos dois pontos em que o atraso pode surgir: - O atraso é medido em relação ao `scheduled_at` (horário planejado do aviso), não ao horário previsto do ponto. Com 5 min de antecedência, o limite significa que o aviso pode chegar até 5 min **depois** do horário previsto de voltar ou sair. - Por isso, **toda mensagem informa o horário previsto**, por exemplo "Seu retorno do almoço está previsto para 13:02". Se o aviso chegar atrasado, o usuário ainda sabe a hora exata. Quando já passou do horário previsto, o texto muda para "Seu retorno estava previsto para 13:02". -- Se o ponto seguinte já tiver sido batido (ex.: `entrada2` registrada), a reconciliação cancela o lembrete antes do despacho, como no Modelo. +- Se o ponto seguinte já tiver sido batido (ex.: `entrada2` registrada), a reconciliação cancela o lembrete antes do despacho. - O painel mostra `expired` como um status próprio, separado de `failed`, para diferenciar "chegou tarde demais" de "erro no envio". -### 9.4 Falha na PontoMais (decidido) +### 9.4 Falha na PontoMais -**Regra:** os lembretes do usuário só são pausados depois de **3 falhas seguidas** na consulta à PontoMais. No Modelo, a pausa acontece na primeira falha. +**Regra:** os lembretes do usuário só são pausados depois de **3 falhas seguidas** na consulta à PontoMais. O limite fica na variável `BP_API_FAILURE_THRESHOLD`, com 3 de padrão. **O que conta como uma falha:** -- Conta **uma falha por ciclo de reconciliação**, por usuário. Dentro do mesmo ciclo o cliente faz **1 nova tentativa rápida** (após ~3 s) e, no caso de 401/403, refaz o login uma vez, como no Modelo. Só se tudo isso falhar o ciclo conta como falha. +- Conta **uma falha por ciclo de reconciliação**, por usuário. Dentro do mesmo ciclo o cliente faz **1 nova tentativa rápida** (após ~3 s) e, no caso de 401/403, refaz o login uma vez. Só se tudo isso falhar o ciclo conta como falha. - Contam: timeout, erro de rede, HTTP 5xx, 401/403 que persiste após o novo login e resposta impossível de interpretar. - **Não** contam: histórico com pontos inválidos ou fora de ordem. A API respondeu, então é um problema de dado, que só é auditado. @@ -615,7 +604,7 @@ O limite fica na variável `BP_API_FAILURE_THRESHOLD`, com 3 de padrão. | Falha 1 e 2 | Incrementa `consecutive_failures`, grava `last_error` e `last_failure_at`, audita (`point_api_failure`). Usuário não é avisado. | | Falha 3 | `notifications_enabled = false`, audita (`notifications_paused_api_failure`), avisa o usuário pelo Telegram para conferir a credencial e depois usar `/ativarponto`, e avisa o(s) admin(s). | | Consulta com sucesso | Zera `consecutive_failures`. | -| Lembretes já agendados | São **mantidos** durante as falhas e após a pausa, porque foram calculados com dados válidos (mesmo comportamento do Modelo). | +| Lembretes já agendados | São **mantidos** durante as falhas e após a pausa, porque foram calculados com dados válidos. | | `/ativarponto` ou reativação pelo painel | Zera o contador. | **Queda geral da PontoMais:** @@ -635,9 +624,9 @@ Se **todos** os usuários consultados num ciclo falharem, o problema é tratado **Efeito colateral a considerar:** enquanto as falhas duram (até ~30 min), pontos novos não são detectados. Por exemplo, um `saida1` batido nesse intervalo só gera o lembrete de `entrada2` quando a API voltar. Pela regra 9.3, ele pode virar `expired`. -### 9.5 Reenvio manual de lembrete com falha (decidido) +### 9.5 Reenvio manual de lembrete com falha -Um lembrete `failed` pode ser reenviado **manualmente** pelo painel, num botão com confirmação. O reenvio automático continua não existindo. +Um lembrete `failed` pode ser reenviado **manualmente** pelo painel, num botão com confirmação. Não existe reenvio automático. | Regra | Detalhe | | --- | --- | @@ -650,7 +639,7 @@ Um lembrete `failed` pode ser reenviado **manualmente** pelo painel, num botão | Resultado | `sent` ou `failed` de novo. Pode ser repetido enquanto as pré-condições valerem. | | Auditoria | `notification_resent`, com a conta web que acionou e o resultado. | -### 9.6 Papéis do painel (decidido) +### 9.6 Papéis do painel O painel é para administradores e contas de leitura. **O usuário comum usa o Telegram**; se precisar ver os próprios dados no painel, o owner cria para ele uma conta de leitura ligada ao seu usuário (abaixo). @@ -665,11 +654,11 @@ O painel é para administradores e contas de leitura. **O usuário comum usa o T | Definir o admin do bot no Telegram | | ✓ | ✓ | | Criar/desativar/excluir contas web, alterar papéis e vínculo com usuário, redefinir senhas | | | ✓ | -- **Conta de leitura ligada a um usuário** (`viewer` com `web_accounts.user_id`): fica restrita ao próprio usuário. Vê Início (avisos do sistema e os próprios lembretes de hoje, sem links), Usuários (só a própria ficha), Lembretes (só os próprios, somente leitura) e Feriados (somente leitura). Pode alterar jornada, credencial PontoMais, testar a API e ligar/pausar os próprios lembretes. Não vê Auditoria, Configurações nem Contas e não ativa, desativa nem promove usuários. A regra é aplicada na API (`authUser`, `authUnrestricted`, `isRestricted`), não só no menu. Um usuário só pode estar ligado a uma conta. Leitura **sem** vínculo continua vendo tudo, sem editar. +- **Conta de leitura ligada a um usuário** (`viewer` com `web_accounts.user_id`): fica restrita ao próprio usuário. Vê Início (avisos do sistema e os próprios lembretes de hoje, sem links), Usuários (só a própria ficha), Lembretes (só os próprios, somente leitura) e Feriados (somente leitura). Pode alterar jornada, credencial PontoMais, testar a API e ligar/pausar os próprios lembretes. Não vê Auditoria, Configurações nem Contas e não ativa, desativa nem promove usuários. A regra é aplicada na API (`authUser`, `authUnrestricted`, `isRestricted`), não só no menu. Um usuário só pode estar ligado a uma conta. Leitura **sem** vínculo vê tudo (menos Contas), sem editar. - A primeira conta `owner` é criada pela CLI (`botpontos admin create-owner`). - Precisa existir sempre pelo menos um `owner` ativo. A API recusa rebaixar, desativar ou excluir o último. - Ninguém pode desativar nem excluir a própria conta (a API responde `409`). -- **Excluir conta** (`DELETE /accounts/{id}`, resposta `204`) apaga a linha de `web_accounts`. A migration `00003` faz as sessões irem junto (`ON DELETE CASCADE`) e deixa `audit_logs.actor_account` e `app_settings.updated_by_account` como `NULL`; o nome da conta fica em `audit_logs.actor_account_name`, gravado em cada evento, então a auditoria continua mostrando quem fez. +- **Excluir conta** (`DELETE /accounts/{id}`, resposta `204`) apaga a linha de `web_accounts`. As sessões vão junto (`ON DELETE CASCADE`), e `audit_logs.actor_account` e `app_settings.updated_by_account` ficam `NULL`. Como o nome da conta é gravado em `audit_logs.actor_account_name` em cada evento, a auditoria continua mostrando quem fez. Desativar é a alternativa reversível. - O vínculo entre conta web e usuário do Telegram (`web_accounts.user_id`) é **opcional**; o owner define e troca em Contas. O admin do Telegram (`is_bot_admin`) e as contas do painel são independentes. #### Conta de leitura restrita (como a API aplica) @@ -693,16 +682,15 @@ Vínculo: - `POST /accounts` e `PATCH /accounts/{id}` aceitam `user_id`. No `PATCH`, campo ausente mantém o vínculo, `null` remove e um número troca. - O usuário precisa existir e não pode estar ligado a outra conta (`422` no campo `user_id`). A troca é auditada em `web_account_changed`, com o usuário no alvo. - O papel e o vínculo são lidos da conta a cada requisição, então valem na hora, sem novo login. -- Não há migration: usa `web_accounts.user_id`, que já existia. -- Leitura **sem** vínculo não é restrita: mantém o comportamento anterior (vê tudo, não edita). +- Leitura **sem** vínculo não é restrita: vê tudo (menos Contas) e não edita. No painel, `web/lib/access.ts` repete a regra só para esconder menu e botões; a segurança está na API. -### 9.7 Fora do escopo (decidido) +### 9.7 Fora do escopo - **Hora extra:** com mais de 4 pontos, nenhum lembrete é criado e não há cálculo de saldo ou banco de horas. -- **Lembretes adicionais** (ex.: `entrada1` não detectada, almoço não iniciado): não entram por enquanto. O `notification_type` é um enum, então novos tipos podem ser adicionados depois por migration. -- **Acesso do usuário comum ao painel.** +- **Lembretes adicionais** (ex.: `entrada1` não detectada, almoço não iniciado). O `notification_type` é um enum; novos tipos exigiriam uma migration (14). +- **Acesso do usuário comum ao painel**, exceto pela conta de leitura ligada a ele, criada pelo owner (9.6). - **Registro de ponto na PontoMais.** ### 9.8 Validação da jornada @@ -727,19 +715,19 @@ A cada ciclo, o worker decide se o dia é útil nesta ordem: 1. **Fim de semana** (no fuso do usuário) não é dia útil. 2. **Tabela `holidays`:** se a data estiver lá (vinda da API ou cadastrada manualmente), não é dia útil. -3. **Sincronização anual:** no primeiro uso de cada ano (e uma vez por dia enquanto não der certo), o worker baixa os feriados da feriadosapi.com (endpoint por cidade) para a cidade configurada (`BP_HOLIDAY_LOCATION`, padrão `3106200` (código IBGE)) e grava em `holidays`. -4. **Fallback:** se o ano ainda não foi sincronizado e a API falhar, segunda a sexta contam como dias úteis (como no Modelo). Os admins são **avisados uma vez por dia** enquanto isso durar, e o evento é auditado (`holiday_sync_failed`). +3. **Sincronização anual:** no primeiro uso de cada ano (e uma vez por dia enquanto não der certo), o worker baixa os feriados da feriadosapi.com para a cidade configurada (`BP_HOLIDAY_LOCATION`, código IBGE; padrão `3106200`, Belo Horizonte) e grava em `holidays`. +4. **Fallback:** se o ano ainda não foi sincronizado e a API falhar, segunda a sexta contam como dias úteis. Os admins são **avisados uma vez por dia** enquanto isso durar, e o evento é auditado (`holiday_sync_failed`). A sincronização nunca apaga feriados manuais nem sobrescreve uma data que já esteja na tabela. **API usada (feriadosapi.com):** - Chamada: `GET {BP_HOLIDAY_API_BASE_URL}/feriados/cidade/{ibge}?ano=AAAA`, com `Authorization: Bearer `. Padrão da base: `https://feriadosapi.com/api/v1`; chave em `secrets/holiday_api_key`. -- `BP_HOLIDAY_LOCATION` é o **código IBGE** da cidade (Belo Horizonte: `3106200`). Um valor não numérico, como o antigo `MG-belo-horizonte`, faz a sincronização falhar com mensagem explicativa e o fallback de segunda a sexta entra em vigor. +- `BP_HOLIDAY_LOCATION` é o **código IBGE** da cidade (Belo Horizonte: `3106200`). Um valor não numérico faz a sincronização falhar com mensagem explicativa, e o fallback de segunda a sexta entra em vigor. - A resposta traz os feriados **nacionais e municipais** da cidade. O cliente lê `feriados[].data` (formato `dd/mm/aaaa`, convertido para `AAAA-MM-DD`) e `feriados[].nome`; ignora datas de outro ano ou ilegíveis e falha se nenhuma data válida vier. - Carnaval e outros pontos facultativos que a API não lista devem ser cadastrados como feriado manual. -- Quantas chamadas: uma por ano, na primeira verificação de dia útil sem feriados do ano no banco (`HasSyncedHolidays` considera qualquer origem diferente de `manual`, inclusive a `feriados.dev` legada). Em falha, no máximo uma tentativa por dia por processo. O botão **Sincronizar** do painel chama a API a cada clique. -- Origem gravada em `holidays.source`: `feriadosapi`. Linhas antigas `feriados.dev` continuam válidas (migration `00002`, que também libera o novo valor no `CHECK`). +- Quantas chamadas: uma por ano, na primeira verificação de dia útil sem feriados do ano no banco (`HasSyncedHolidays` considera qualquer origem diferente de `manual`). Em falha, no máximo uma tentativa por dia por processo. O botão **Sincronizar** do painel chama a API a cada clique. +- Origem gravada em `holidays.source`: `feriadosapi` (ou `manual` para os cadastrados no painel). ### 9.10 Retenção de dados @@ -794,15 +782,15 @@ Em vez de consultar todos os usuários em todo ciclo, cada usuário tem **sua pr | Situação do dia | Pontos | Próxima consulta | Por quê | | --- | --- | --- | --- | | `awaiting` | 0 (antes da confirmação) | próximo tick (15 min) | Fazer as duas verificações (11:30 e 11:45) | -| `no_points` | 0 (após a confirmação) | **a cada 60 min** até 15:00 (12:45, 13:45, 14:45) | **Ajuste A:** não abandonar o dia cedo demais | +| `no_points` | 0 (após a confirmação) | **a cada 60 min** até 15:00 (12:45, 13:45, 14:45) | Não abandonar o dia cedo demais | | `working` | 1 ou 2 | próximo tick (15 min) | Detectar a saída e a volta do almoço sem atraso | -| `working` | 3 | **a cada 60 min**, mais **1 consulta de confirmação** antes do lembrete de `saida2` | **Ajuste C:** à tarde, só interessa saber se a pessoa saiu antes | +| `working` | 3 | **a cada 60 min**, mais **1 consulta de confirmação** antes do lembrete de `saida2` | À tarde, só interessa saber se a pessoa saiu antes | | `finished` | 4 | nenhuma (até amanhã) | Dia fechado | | `not_working` | 0 até 15:00 | nenhuma (até amanhã) | Dia sem trabalho confirmado | Uma consulta que **falha** não muda a situação. O usuário volta a ser consultado no próximo tick, e a falha conta conforme 9.4. -#### Ajuste A: dia sem pontos +#### Dia sem pontos ```text 11:30 0 pontos → awaiting (1ª verificação, não decide nada) @@ -816,10 +804,10 @@ Uma consulta que **falha** não muda a situação. O usuário volta a ser consul - **Só resposta bem-sucedida conta** como "0 pontos". Se a API falhar, a situação não avança. - Se um ponto aparecer em qualquer reverificação, o dia vira `working` e volta para consultas de 15 em 15 min. - **Ajuda quando:** o cache da PontoMais (`last_cached`) demora a mostrar o ponto; a pessoa começa a trabalhar mais tarde (consulta médica); um ajuste de ponto é aprovado durante o dia. -- **Limite honesto:** se a pessoa **esqueceu de bater a entrada** e não houve ajuste, o primeiro ponto que aparece é a saída para o almoço, mas o sistema o interpreta como `entrada1`. A ordem dos pontos fica errada e o bot não tem como calcular os lembretes corretamente. Isso continua fora do alcance da aplicação, como no Modelo. +- **Limite honesto:** se a pessoa **esqueceu de bater a entrada** e não houve ajuste, o primeiro ponto que aparece é a saída para o almoço, mas o sistema o interpreta como `entrada1`. A ordem dos pontos fica errada e o bot não tem como calcular os lembretes corretamente. Isso está fora do alcance da aplicação. - O usuário **não recebe mensagem** sobre `no_points`/`not_working`, para não gerar aviso diário em férias e folgas. A situação aparece no `/status`, no painel e na auditoria (`day_no_points`, `day_not_worked`). -#### Ajuste C: tarde com 3 pontos +#### Tarde com 3 pontos Com `entrada2` detectada e o lembrete de `saida2` agendado para o horário **T**, as consultas só servem para descobrir se a pessoa saiu **antes** do previsto (4º ponto) e então cancelar o lembrete: @@ -862,9 +850,9 @@ Com `entrada2` detectada e o lembrete de `saida2` agendado para o horário **T** | Cenário | Consultas/usuário | Total/dia | | --- | --- | --- | -| Dia inteiro (Modelo) | 96 | ~1.920 | +| Sem janela (a cada 15 min o dia todo) | 96 | ~1.920 | | Só a janela 11:30–19:00 | até 31 | ~620 | -| Janela + frequência adaptativa (A + C), dia típico | ~11 | **~220** | +| Janela + frequência adaptativa, dia típico | ~11 | **~220** | | Usuário de férias/folga | 6 (11:30, 11:45, 12:45, 13:45, 14:45) → depois 0 | — | ### 9.13 Configurações globais pelo painel @@ -887,7 +875,7 @@ Os quatro horários de 9.12 (início, confirmação, fim das reverificações e | `confirmação ≥ início + 15 min` | Garante as duas verificações (9.12) | | `fim − início ≥ 4 h` | Uma janela curta demais deixaria de detectar retorno do almoço e saída | -**Pré-visualização:** antes de salvar, a tela mostra o efeito estimado. Por exemplo: quantas consultas por dia a nova janela gera e quantos usuários, nos últimos 30 dias, bateram `saida1` antes do novo início e teriam lembretes atrasados ou `expired`. O horário de `saida1` é deduzido dos lembretes de `entrada2` (`scheduled_at − almoço + antecedência`), já que a v2 não guarda os pontos. A pré-visualização também informa **quantos usuários têm janela personalizada** e, portanto, não serão afetados. +**Pré-visualização:** antes de salvar, a tela mostra o efeito estimado. Por exemplo: quantas consultas por dia a nova janela gera e quantos usuários, nos últimos 30 dias, bateram `saida1` antes do novo início e teriam lembretes atrasados ou `expired`. O horário de `saida1` é deduzido dos lembretes de `entrada2` (`scheduled_at − almoço + antecedência`), já que o sistema não guarda os pontos. A pré-visualização também informa **quantos usuários têm janela personalizada** e, portanto, não serão afetados. **Quando passa a valer:** o worker lê `app_settings` no começo de cada ciclo, então a mudança vale **a partir do próximo ciclo**, sem reiniciar nada. Dias já marcados como `not_working` hoje continuam assim (podem ser retomados como em 9.12); os `next_check_at` já calculados são recalculados no próximo tick. @@ -973,13 +961,13 @@ A `api` tem saída para a internet porque a validação de credenciais na PontoM - `pg_dump -Fc` diário, com retenção de 14 dias, num volume montado. - Restauração documentada com `pg_restore` num container temporário. -- **A chave de criptografia precisa ter backup separado.** Sem ela, as senhas da PontoMais não podem ser recuperadas, como já acontece no Modelo. +- **A chave de criptografia precisa ter backup separado.** Sem ela, as senhas da PontoMais não podem ser recuperadas. ### 11.4 Proxy reverso: Nginx Proxy Manager existente -A rede onde o projeto vai rodar já tem um **Nginx Proxy Manager (NPM)**. Ele faz o papel de proxy HTTPS, então o projeto **não** inclui Caddy nem Traefik. +A rede onde o projeto roda já tem um **Nginx Proxy Manager (NPM)**. Ele faz o papel de proxy HTTPS, então o projeto **não** inclui Caddy nem Traefik. -**Topologia (decidida):** o NPM roda em **outra máquina da mesma rede**. +**Topologia:** o NPM roda em **outra máquina da mesma rede**. ```text Navegador ──HTTPS──► NPM (outra máquina) ──HTTP :3000──► servidor Docker: web ──► api ──► postgres @@ -1023,9 +1011,9 @@ Ativação: `systemctl daemon-reload && systemctl enable --now botpontos-firewal | Websockets Support | pode ficar desligado (o painel não usa) | | SSL Certificate | **Custom certificate**: o certificado interno da rede, emitido pela CA interna para o nome do painel (ver abaixo) | | Force SSL / HTTP/2 / HSTS | ligados | -| Access List | restringir à rede local (ex.: `192.168.18.0/24`), substituindo o filtro de CIDR que o Modelo fazia no Go | +| Access List | restringir à rede local (ex.: `192.168.18.0/24`) | -**Certificado interno (decidido)** +**Certificado interno** O HTTPS do painel usa um **certificado emitido pela CA interna da rede**, carregado no NPM como *Custom Certificate*. Não há Let's Encrypt nem domínio público. @@ -1044,7 +1032,7 @@ O HTTPS do painel usa um **certificado emitido pela CA interna da rede**, carreg ### 11.5 Host: máquina física com Docker -O ambiente de produção (até o momento) é uma **máquina física dedicada, separada do Proxmox**, rodando Docker. Por não ter snapshots nem alta disponibilidade de hypervisor, alguns cuidados ficam por conta do host: +O ambiente de produção é uma **máquina física dedicada, separada do Proxmox**, rodando Docker. Por não ter snapshots nem alta disponibilidade de hypervisor, alguns cuidados ficam por conta do host: | Tema | Requisito | | --- | --- | @@ -1064,8 +1052,8 @@ O ambiente de produção (até o momento) é uma **máquina física dedicada, se - Logs JSON (`slog`) com `request_id`, `user_id` e `job`. - Healthchecks do Compose: `api` em `:8080/api/v1/health/live`, `worker` em `:8081/health/live` (ambos com `botpontos healthcheck`) e `web` em `/healthz`. O `/health/ready` da API e do worker também faz ping no Postgres. - O worker registra `liderança obtida; worker ativo` e `bot do Telegram iniciado` ao assumir; uma segunda instância registra `outra instância do worker está ativa; aguardando`. -- **Métricas preparadas, não expostas.** O pacote `internal/metrics` define uma interface (`Recorder`) chamada pelos jobs e pelo cliente da PontoMais: lembretes por tipo e status, falhas e latência da PontoMais, duração da reconciliação, consultas evitadas pela janela (9.12). Na primeira versão a implementação é *no-op* (não faz nada) ou só alimenta os contadores do dashboard do painel. **Não existe endpoint `/metrics`.** -- Para ativar o Prometheus no futuro: trocar a implementação do `Recorder` por uma baseada em `prometheus/client_golang` e expor `/metrics` só na rede interna. Nenhum job precisa mudar. +- **Métricas preparadas, não expostas.** O pacote `internal/metrics` define uma interface (`Recorder`) chamada pelos jobs e pelo cliente da PontoMais: lembretes por tipo e status, falhas e latência da PontoMais, duração da reconciliação, consultas evitadas pela janela (9.12). A implementação atual é *no-op* (não faz nada); os contadores do dashboard vêm de consultas ao banco. **Não existe endpoint `/metrics`.** +- Para ativar o Prometheus: trocar a implementação do `Recorder` por uma baseada em `prometheus/client_golang` e expor `/metrics` só na rede interna. Nenhum job precisa mudar. ## 13. Testes @@ -1079,35 +1067,35 @@ O ambiente de produção (até o momento) é uma **máquina física dedicada, se Os comandos para rodar os testes em containers estão no `README.md` ("Desenvolvimento e testes"). -## 14. Plano de sprints sugerido +## 14. Pontos de extensão -| Sprint | Entrega | +O que a arquitetura já prevê, sem implementação hoje: + +| Extensão | Onde entra | | --- | --- | -| 0 — Fundação ✓ | Monorepo (`backend/`, `web/`), Compose com Postgres, migrations, `migrate`/`api`/`worker` com health. Sem CI (projeto sem repositório remoto); testes rodam num container Go | -| 1 — Núcleo de domínio ✓ | `rules` e casos de uso portados do Modelo com as correções (fuso, mensagens); adapters PontoMais e crypto | -| 2 — Bot Telegram ✓ | Cadastro, `/status`, `/entrada2`, `/saida2`, ativação unificada | -| 3 — Lembretes ✓ | Reconciliação na janela 11:30–19:00 com frequência adaptativa (`user_days.next_check_at`), despacho a cada 2 min com `SKIP LOCKED`, advisory lock, tolerância de 10 min (`expired`) | -| 4 — API + Auth ✓ | Login, sessões, CSRF, papéis, endpoints de usuários/notificações/auditoria, `openapi.yaml` | -| 5 — Painel Next ✓ | Login, dashboard, usuários (incluindo janela personalizada), notificações, auditoria, configurações globais | -| 6 — Operação ✓ | Feriados (API + manual), contas web, backup/restore, Proxy Host no NPM, hardening | -| Evoluções ✓ | Feriados pela feriadosapi.com (migration `00002`); conta de leitura restrita a um usuário (9.6); exclusão de contas web (migration `00003`); porta do painel configurável (`BP_WEB_PORT`); `go.sum` e `package-lock.json` versionados | +| Novos tipos de lembrete (ex.: `entrada1` não detectada) | Novo valor no enum `notification_type` (migration) e regra em `rules`/`app` | +| Outro sistema de ponto | Novo adapter que implemente o port `PointsProvider` (`app/service.go`) | +| Métricas Prometheus | Implementação do `Recorder` com `/metrics` na rede interna (12) | +| Outras configurações globais no painel | Novas chaves em `app_settings` (9.13), sem mudar a estrutura | +| Tipos TypeScript gerados | `openapi-typescript` a partir do `openapi.yaml` (decisão 27) | +| Testes de integração e web | Seção 13 | ## 15. Decisões registradas (ADR resumido) | # | Decisão | Motivo | | --- | --- | --- | -| 1 | PostgreSQL no lugar do SQLite | Vários containers escrevendo; `SKIP LOCKED`; crescimento futuro | +| 1 | PostgreSQL | Vários containers escrevendo com segurança; `SKIP LOCKED`; crescimento futuro | | 2 | Next.js como BFF, auth no Go | Uma fonte de verdade de autorização; sem CORS; API não exposta | | 3 | Binário Go único com subcomandos | Uma imagem, mesmo código, deploy simples | | 4 | Hexagonal com ports explícitos | Regras testáveis sem rede; adapters trocáveis (ex.: outro sistema de ponto) | -| 5 | `openapi.yaml` como contrato | Evita divergência entre Go e Next. Por enquanto os tipos do TypeScript são escritos à mão a partir dele (decisão 27) | +| 5 | `openapi.yaml` como contrato | Evita divergência entre Go e Next; os tipos do TypeScript são escritos à mão a partir dele (decisão 27) | | 6 | Worker único com advisory lock | O Telegram em long polling não aceita dois consumidores | -| 7 | "No máximo uma vez" para lembretes | Preferível perder um lembrete a enviar em duplicidade (mantido do Modelo) | +| 7 | "No máximo uma vez" para lembretes | Preferível perder um lembrete a enviar em duplicidade | | 8 | Despacho a cada 2 min, tolerância de 10 min | Aviso útil sem mensagens tardias demais; acima de 10 min vira `expired` e só é auditado | | 9 | Pausa após 3 falhas seguidas na PontoMais (1 por ciclo de 15 min) | Evita pausar por instabilidade momentânea; pausa em ~30 min se o problema persistir | | 10 | Todos falhando no ciclo = queda da API: só avisa o admin | Uma queda do fornecedor não deve pausar todos os usuários | | 11 | Reenvio manual de `failed` pelo painel, só no mesmo dia | Recupera falhas do Telegram sem abrir mão do "no máximo uma vez" automático | -| 12 | Painel só para administradores, com papéis `owner`/`admin`/`viewer` | O usuário comum já tem o que precisa no Telegram | +| 12 | Painel para administradores, com papéis `owner`/`admin`/`viewer` | O usuário comum já tem o que precisa no Telegram; quem precisar ver os próprios dados recebe uma conta restrita (decisão 31) | | 13 | Jornada exige `almoço − antecedência ≥ intervalo de reconciliação` | Garante que o lembrete de `entrada2` seja agendado a tempo | | 14 | Feriados: tabela local → API → fallback seg–sex com aviso | A automação continua funcionando, com a falha visível aos admins | | 15 | Retenção: auditoria 1 ano, notificações 90 dias, sessões 7 dias | Mantém o banco pequeno sem perder histórico útil | @@ -1117,22 +1105,22 @@ Os comandos para rodar os testes em containers estão no `README.md` ("Desenvolv | 19 | HTTPS com certificado da CA interna no NPM (`botpontos.lan`) | Painel só na rede local; sem exposição pública nem Let's Encrypt | | 20 | Consultas só na janela global 11:30–19:00 | Reduz ~70–80% das chamadas à PontoMais sem atrasar os lembretes comuns | | 21 | Sem ponto às 11:30 e 11:45 → reverificação de hora em hora até 15:00 → dia não trabalhado | Evita consultas inúteis em férias sem abandonar cedo quem atrasou ou teve ajuste de ponto | -| 22 | Ferramentas: roteador nativo do Go, `goose`, `go-telegram/bot`, `api` com saída para a PontoMais | Menos dependências; validação de credencial na hora. O `go-telegram/bot` foi substituído por cliente próprio (decisão 27) | +| 22 | Roteador nativo do Go, `goose` e `api` com saída para a internet | Menos dependências; validação de credencial, reenvio e sincronização de feriados na hora, sem passar pelo `worker` | | 23 | Métricas preparadas por interface, sem expor `/metrics` | Não há Prometheus na rede hoje; ativar depois não exige refatoração | | 24 | Horários da janela editáveis no painel (`app_settings`), com validação e pré-visualização | Ajuste sem redeploy; a validação evita configurações que quebrariam os lembretes | | 25 | Frequência adaptativa: 15 min até o 3º ponto, depois 60 min + 1 consulta de confirmação antes do lembrete de saída | ~11 consultas/usuário/dia em vez de ~31, mantendo o cancelamento quando a pessoa sai antes | | 26 | Janela global com exceção completa e opcional por usuário | Atende horários diferentes sem complicar o caso comum; selo, `/status` e auditoria deixam a exceção visível | -| 27 | Sem geradores de código nesta fase: SQL à mão com `pgx` (no lugar de `sqlc`), cliente Telegram próprio (no lugar de `go-telegram/bot`), tipos TypeScript à mão e CSS próprio (no lugar de Tailwind/shadcn) | O código foi escrito numa máquina onde não é permitido rodar ferramentas; tudo o que exigiria gerar código ou acertar a API de uma biblioteca sem compilar foi evitado. Podem ser adotados depois sem mudar a arquitetura | -| 28 | `app` usa o repositório Postgres concreto; os ports ficam só para integrações externas | Menos código de interface sem compilador; regras puras continuam testadas em `rules` | +| 27 | Sem geradores de código nem frameworks de UI: SQL à mão com `pgx`, cliente Telegram próprio, tipos TypeScript à mão e CSS próprio | Menos dependências e nenhuma etapa de geração no build. `sqlc`, `openapi-typescript` ou uma biblioteca de UI podem ser adotados sem mudar a arquitetura | +| 28 | `app` usa o repositório Postgres concreto; os ports ficam só para integrações externas | Menos código de interface; as regras puras são testadas em `rules` | | 29 | Em queda da PontoMais já registrada, falhas de ciclos com um único usuário consultado também não contam | Com a frequência adaptativa, muitos ciclos consultam só um usuário; sem isso, alguém poderia ser pausado durante uma queda conhecida | -| 30 | Feriados pela feriadosapi.com, por código IBGE da cidade | Traz feriados nacionais e municipais numa chamada por ano; a feriados.dev deixou de ser usada (linhas antigas continuam válidas) | +| 30 | Feriados pela feriadosapi.com, por código IBGE da cidade | Traz feriados nacionais e municipais numa chamada por ano | | 31 | Conta `viewer` ligada a um usuário fica restrita aos dados dele, com a regra na API | Permite ao usuário acompanhar e ajustar só o que é dele sem abrir o painel inteiro; o menu do Next só esconde o que a API já recusa | | 32 | Excluir conta web apaga a linha e preserva o nome na auditoria (`actor_account_name`) | Remove contas sem uso sem perder o histórico de quem fez cada ação; desativar continua sendo a opção reversível | -| 33 | Versões das dependências fixadas em `go.sum` e `package-lock.json`; sem `go mod tidy` com Go 1.25 | Builds reproduzíveis; versões novas das bibliotecas exigem Go 1.26 | +| 33 | Versões das dependências fixadas em `go.sum` e `package-lock.json`; sem `go mod tidy` com Go 1.25 | Builds reproduzíveis; versões mais novas das bibliotecas exigem Go 1.26 | ## 16. Estado da implementação e pendências -**Implementado:** tudo o que as seções 4 a 14 descrevem (Sprints 0 a 6 e evoluções), com os desvios das decisões 27 e 28. +**Implementado:** tudo o que as seções 3 a 13 descrevem. A seção 14 lista o que é só previsto. **Verificado:** o backend compila e passa em `go vet` e `go test`; o painel passa em `tsc --noEmit`. As dependências estão fixadas em `backend/go.sum` e `web/package-lock.json`. diff --git a/web/tsconfig.tsbuildinfo b/web/tsconfig.tsbuildinfo deleted file mode 100644 index db7babb..0000000 --- a/web/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.es2023.d.ts","./node_modules/typescript/lib/lib.es2024.d.ts","./node_modules/typescript/lib/lib.esnext.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.es2023.array.d.ts","./node_modules/typescript/lib/lib.es2023.collection.d.ts","./node_modules/typescript/lib/lib.es2023.intl.d.ts","./node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2024.collection.d.ts","./node_modules/typescript/lib/lib.es2024.object.d.ts","./node_modules/typescript/lib/lib.es2024.promise.d.ts","./node_modules/typescript/lib/lib.es2024.regexp.d.ts","./node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2024.string.d.ts","./node_modules/typescript/lib/lib.esnext.array.d.ts","./node_modules/typescript/lib/lib.esnext.collection.d.ts","./node_modules/typescript/lib/lib.esnext.intl.d.ts","./node_modules/typescript/lib/lib.esnext.disposable.d.ts","./node_modules/typescript/lib/lib.esnext.promise.d.ts","./node_modules/typescript/lib/lib.esnext.decorators.d.ts","./node_modules/typescript/lib/lib.esnext.iterator.d.ts","./node_modules/typescript/lib/lib.esnext.float16.d.ts","./node_modules/typescript/lib/lib.esnext.error.d.ts","./node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./node_modules/next/dist/server/after/builtin-request-context.d.ts","./node_modules/next/dist/compiled/webpack/webpack.d.ts","./node_modules/next/dist/server/config.d.ts","./node_modules/next/dist/lib/load-custom-routes.d.ts","./node_modules/next/dist/shared/lib/image-config.d.ts","./node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","./node_modules/next/dist/server/get-page-files.d.ts","./node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/compatibility/index.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/web-globals/abortcontroller.d.ts","./node_modules/@types/node/web-globals/domexception.d.ts","./node_modules/@types/node/web-globals/events.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/web-globals/fetch.d.ts","./node_modules/@types/node/web-globals/navigator.d.ts","./node_modules/@types/node/web-globals/storage.d.ts","./node_modules/@types/node/web-globals/streams.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/inspector.generated.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/sqlite.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/react/global.d.ts","./node_modules/csstype/index.d.ts","./node_modules/@types/react/index.d.ts","./node_modules/@types/react/canary.d.ts","./node_modules/@types/react/experimental.d.ts","./node_modules/@types/react-dom/index.d.ts","./node_modules/@types/react-dom/client.d.ts","./node_modules/@types/react-dom/canary.d.ts","./node_modules/@types/react-dom/experimental.d.ts","./node_modules/next/dist/lib/fallback.d.ts","./node_modules/next/dist/server/base-http/index.d.ts","./node_modules/next/dist/server/api-utils/index.d.ts","./node_modules/next/dist/server/node-environment-baseline.d.ts","./node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","./node_modules/next/dist/server/node-environment-extensions/random.d.ts","./node_modules/next/dist/server/node-environment-extensions/date.d.ts","./node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","./node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","./node_modules/next/dist/server/node-environment.d.ts","./node_modules/next/dist/server/require-hook.d.ts","./node_modules/next/dist/server/node-polyfill-crypto.d.ts","./node_modules/next/dist/lib/page-types.d.ts","./node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","./node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","./node_modules/next/dist/build/analysis/get-page-static-info.d.ts","./node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","./node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","./node_modules/next/dist/server/lib/cache-control.d.ts","./node_modules/next/dist/server/lib/cache-handlers/types.d.ts","./node_modules/next/dist/server/route-kind.d.ts","./node_modules/next/dist/server/route-definitions/route-definition.d.ts","./node_modules/next/dist/lib/setup-exception-listeners.d.ts","./node_modules/next/dist/lib/worker.d.ts","./node_modules/next/dist/lib/constants.d.ts","./node_modules/next/dist/client/components/app-router-headers.d.ts","./node_modules/next/dist/build/rendering-mode.d.ts","./node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","./node_modules/next/dist/server/lib/experimental/ppr.d.ts","./node_modules/next/dist/build/webpack/plugins/app-build-manifest-plugin.d.ts","./node_modules/next/dist/build/page-extensions-type.d.ts","./node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","./node_modules/next/dist/server/instrumentation/types.d.ts","./node_modules/next/dist/lib/coalesced-function.d.ts","./node_modules/next/dist/server/response-cache/index.d.ts","./node_modules/next/dist/shared/lib/deep-readonly.d.ts","./node_modules/next/dist/server/lib/incremental-cache/index.d.ts","./node_modules/next/dist/server/body-streams.d.ts","./node_modules/next/dist/server/route-matches/route-match.d.ts","./node_modules/@types/react/jsx-runtime.d.ts","./node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","./node_modules/next/dist/server/request-meta.d.ts","./node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","./node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","./node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","./node_modules/next/dist/shared/lib/mitt.d.ts","./node_modules/next/dist/client/with-router.d.ts","./node_modules/next/dist/client/router.d.ts","./node_modules/next/dist/client/route-loader.d.ts","./node_modules/next/dist/client/page-loader.d.ts","./node_modules/next/dist/shared/lib/bloom-filter.d.ts","./node_modules/next/dist/shared/lib/router/router.d.ts","./node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","./node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","./node_modules/next/dist/shared/lib/constants.d.ts","./node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","./node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","./node_modules/next/dist/server/lib/app-dir-module.d.ts","./node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","./node_modules/next/dist/server/web/spec-extension/cookies.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","./node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","./node_modules/next/dist/server/app-render/cache-signal.d.ts","./node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","./node_modules/next/dist/server/request/fallback-params.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","./node_modules/next/dist/server/lib/lazy-result.d.ts","./node_modules/next/dist/server/lib/implicit-tags.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","./node_modules/next/dist/server/app-render/app-render.d.ts","./node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/amp-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","./node_modules/next/dist/client/components/error-boundary.d.ts","./node_modules/next/dist/client/components/layout-router.d.ts","./node_modules/next/dist/client/components/render-from-template-context.d.ts","./node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","./node_modules/next/dist/client/components/client-page.d.ts","./node_modules/next/dist/client/components/client-segment.d.ts","./node_modules/next/dist/server/request/search-params.d.ts","./node_modules/next/dist/client/components/hooks-server-context.d.ts","./node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","./node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","./node_modules/next/dist/lib/metadata/types/extra-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","./node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","./node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","./node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","./node_modules/next/dist/lib/metadata/types/resolvers.d.ts","./node_modules/next/dist/lib/metadata/types/icons.d.ts","./node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","./node_modules/next/dist/lib/metadata/metadata.d.ts","./node_modules/next/dist/lib/framework/boundary-components.d.ts","./node_modules/next/dist/server/app-render/rsc/preloads.d.ts","./node_modules/next/dist/server/app-render/rsc/postpone.d.ts","./node_modules/next/dist/server/app-render/rsc/taint.d.ts","./node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","./node_modules/next/dist/server/app-render/collect-segment-data.d.ts","./node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","./node_modules/next/dist/server/app-render/entry-base.d.ts","./node_modules/next/dist/build/templates/app-page.d.ts","./node_modules/@types/react/jsx-dev-runtime.d.ts","./node_modules/@types/react/compiler-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","./node_modules/@types/react-dom/static.d.ts","./node_modules/@types/react-dom/server.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.d.ts","./node_modules/next/dist/server/lib/i18n-provider.d.ts","./node_modules/next/dist/server/web/next-url.d.ts","./node_modules/next/dist/server/web/spec-extension/response.d.ts","./node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","./node_modules/next/dist/server/web/types.d.ts","./node_modules/next/dist/server/web/adapter.d.ts","./node_modules/next/dist/server/use-cache/cache-life.d.ts","./node_modules/next/dist/server/app-render/types.d.ts","./node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","./node_modules/next/dist/client/flight-data-helpers.d.ts","./node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","./node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","./node_modules/next/dist/build/templates/pages.d.ts","./node_modules/next/dist/server/route-modules/pages/module.d.ts","./node_modules/next/dist/server/render.d.ts","./node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","./node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","./node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","./node_modules/next/dist/server/route-matchers/route-matcher.d.ts","./node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","./node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","./node_modules/next/dist/server/normalizers/normalizer.d.ts","./node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/suffix.d.ts","./node_modules/next/dist/server/normalizers/request/rsc.d.ts","./node_modules/next/dist/server/normalizers/request/prefetch-rsc.d.ts","./node_modules/next/dist/server/normalizers/request/next-data.d.ts","./node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","./node_modules/next/dist/build/static-paths/types.d.ts","./node_modules/next/dist/server/base-server.d.ts","./node_modules/next/dist/server/after/after.d.ts","./node_modules/next/dist/server/after/after-context.d.ts","./node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","./node_modules/next/dist/server/request/params.d.ts","./node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","./node_modules/next/dist/server/lib/router-utils/types.d.ts","./node_modules/next/dist/trace/types.d.ts","./node_modules/next/dist/trace/trace.d.ts","./node_modules/next/dist/trace/shared.d.ts","./node_modules/next/dist/trace/index.d.ts","./node_modules/next/dist/build/load-jsconfig.d.ts","./node_modules/@next/env/dist/index.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","./node_modules/next/dist/telemetry/storage.d.ts","./node_modules/next/dist/build/build-context.d.ts","./node_modules/next/dist/build/webpack-config.d.ts","./node_modules/next/dist/build/swc/generated-native.d.ts","./node_modules/next/dist/build/swc/types.d.ts","./node_modules/next/dist/server/dev/parse-version-info.d.ts","./node_modules/next/dist/next-devtools/shared/types.d.ts","./node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","./node_modules/next/dist/server/lib/parse-stack.d.ts","./node_modules/next/dist/next-devtools/server/shared.d.ts","./node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","./node_modules/next/dist/server/dev/hot-reloader-types.d.ts","./node_modules/next/dist/server/lib/types.d.ts","./node_modules/next/dist/server/lib/lru-cache.d.ts","./node_modules/next/dist/server/lib/dev-bundler-service.d.ts","./node_modules/next/dist/server/base-http/node.d.ts","./node_modules/next/dist/server/lib/render-server.d.ts","./node_modules/next/dist/server/lib/router-server.d.ts","./node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","./node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","./node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","./node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","./node_modules/next/dist/server/route-modules/route-module.d.ts","./node_modules/next/dist/server/load-components.d.ts","./node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","./node_modules/next/dist/server/async-storage/work-store.d.ts","./node_modules/next/dist/server/web/http.d.ts","./node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","./node_modules/next/dist/client/components/redirect-status-code.d.ts","./node_modules/next/dist/client/components/redirect-error.d.ts","./node_modules/next/dist/build/templates/app-route.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","./node_modules/next/dist/build/segment-config/app/app-segments.d.ts","./node_modules/next/dist/build/utils.d.ts","./node_modules/next/dist/build/turborepo-access-trace/types.d.ts","./node_modules/next/dist/build/turborepo-access-trace/result.d.ts","./node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","./node_modules/next/dist/build/turborepo-access-trace/index.d.ts","./node_modules/next/dist/export/routes/types.d.ts","./node_modules/next/dist/export/types.d.ts","./node_modules/next/dist/export/worker.d.ts","./node_modules/next/dist/build/worker.d.ts","./node_modules/next/dist/build/index.d.ts","./node_modules/next/dist/server/lib/route-cache-key.d.ts","./node_modules/next/dist/server/response-cache/types.d.ts","./node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","./node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","./node_modules/next/dist/server/render-result.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","./node_modules/next/dist/server/lib/async-callback-set.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","./node_modules/@img/colour/index.d.ts","./node_modules/sharp/dist/index.d.mts","./node_modules/next/dist/server/image-optimizer.d.ts","./node_modules/next/dist/server/next-server.d.ts","./node_modules/next/dist/server/dev/static-paths-worker.d.ts","./node_modules/next/dist/server/dev/next-dev-server.d.ts","./node_modules/next/dist/server/next.d.ts","./node_modules/next/dist/types.d.ts","./node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/utils.d.ts","./node_modules/next/dist/cli/next-test.d.ts","./node_modules/next/dist/server/config-shared.d.ts","./node_modules/next/dist/server/web/spec-extension/request.d.ts","./node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","./node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","./node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","./node_modules/next/dist/server/web/spec-extension/image-response.d.ts","./node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/types.d.ts","./node_modules/next/dist/server/after/index.d.ts","./node_modules/next/dist/server/request/root-params.d.ts","./node_modules/next/dist/server/request/connection.d.ts","./node_modules/next/server.d.ts","./middleware.ts","./node_modules/next/dist/styled-jsx/types/css.d.ts","./node_modules/next/dist/styled-jsx/types/macro.d.ts","./node_modules/next/dist/styled-jsx/types/style.d.ts","./node_modules/next/dist/styled-jsx/types/global.d.ts","./node_modules/next/dist/styled-jsx/types/index.d.ts","./node_modules/next/dist/shared/lib/amp.d.ts","./node_modules/next/amp.d.ts","./node_modules/next/dist/pages/_app.d.ts","./node_modules/next/app.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","./node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","./node_modules/next/dist/server/use-cache/cache-tag.d.ts","./node_modules/next/cache.d.ts","./node_modules/next/dist/shared/lib/runtime-config.external.d.ts","./node_modules/next/config.d.ts","./node_modules/next/dist/pages/_document.d.ts","./node_modules/next/document.d.ts","./node_modules/next/dist/shared/lib/dynamic.d.ts","./node_modules/next/dynamic.d.ts","./node_modules/next/dist/pages/_error.d.ts","./node_modules/next/error.d.ts","./node_modules/next/dist/shared/lib/head.d.ts","./node_modules/next/head.d.ts","./node_modules/next/dist/server/request/cookies.d.ts","./node_modules/next/dist/server/request/headers.d.ts","./node_modules/next/dist/server/request/draft-mode.d.ts","./node_modules/next/headers.d.ts","./node_modules/next/dist/shared/lib/get-img-props.d.ts","./node_modules/next/dist/client/image-component.d.ts","./node_modules/next/dist/shared/lib/image-external.d.ts","./node_modules/next/image.d.ts","./node_modules/next/dist/client/link.d.ts","./node_modules/next/link.d.ts","./node_modules/next/dist/client/components/redirect.d.ts","./node_modules/next/dist/client/components/not-found.d.ts","./node_modules/next/dist/client/components/forbidden.d.ts","./node_modules/next/dist/client/components/unauthorized.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.d.ts","./node_modules/next/dist/client/components/navigation.react-server.d.ts","./node_modules/next/dist/client/components/unrecognized-action-error.d.ts","./node_modules/next/dist/client/components/navigation.d.ts","./node_modules/next/navigation.d.ts","./node_modules/next/router.d.ts","./node_modules/next/dist/client/script.d.ts","./node_modules/next/script.d.ts","./node_modules/next/types/global.d.ts","./node_modules/next/types/compiled.d.ts","./node_modules/next/types.d.ts","./node_modules/next/index.d.ts","./next.config.ts","./app/healthz/route.ts","./lib/types.ts","./lib/access.ts","./lib/client-api.ts","./lib/format.ts","./lib/server-api.ts","./app/layout.tsx","./components/logoutbutton.tsx","./app/(painel)/layout.tsx","./app/(painel)/page.tsx","./app/(painel)/auditoria/page.tsx","./components/windowfields.tsx","./app/(painel)/configuracoes/form.tsx","./app/(painel)/configuracoes/page.tsx","./components/actionbutton.tsx","./app/(painel)/contas/forms.tsx","./app/(painel)/contas/page.tsx","./app/(painel)/feriados/form.tsx","./app/(painel)/feriados/page.tsx","./app/(painel)/notificacoes/page.tsx","./app/(painel)/usuarios/page.tsx","./app/(painel)/usuarios/[id]/forms.tsx","./app/(painel)/usuarios/[id]/page.tsx","./app/login/page.tsx"],"fileIdsList":[[95,144,161,162,485,495,505,506,508,509],[95,144,161,162,197,495,505,507,515],[95,144,161,162,495,505,506,509,516],[95,144,161,162,197,495,505,507,518],[95,144,161,162,505,508,509,519],[95,144,161,162,197,495,507],[95,144,161,162,485,505,508,509,518,521],[95,144,161,162,197,485,505,506,509,511],[95,144,161,162,485,505,508,509,518],[95,144,161,162,485,505,506,508,509],[95,144,161,162,197,495,505,507,508,515],[95,144,161,162,485,505,506,508,509,518,525],[95,144,161,162],[95,144,161,162,197,502],[95,144,161,162,197,507],[95,144,161,162,507],[95,144,161,162,505],[95,144,161,162,479,495,505],[95,144,161,162,450],[95,144,161,162,502],[95,141,142,144,161,162],[95,143,144,161,162],[144,161,162],[95,144,149,161,162,179],[95,144,145,150,155,161,162,164,176,187],[95,144,145,146,155,161,162,164],[90,91,92,95,144,161,162],[95,144,147,161,162,188],[95,144,148,149,156,161,162,165],[95,144,149,161,162,176,184],[95,144,150,152,155,161,162,164],[95,143,144,151,161,162],[95,144,152,153,161,162],[95,144,154,155,161,162],[95,143,144,155,161,162],[95,144,155,156,157,161,162,176,187],[95,144,155,156,157,161,162,171,176,179],[95,136,144,152,155,158,161,162,164,176,187],[95,144,155,156,158,159,161,162,164,176,184,187],[95,144,158,160,161,162,176,184,187],[93,94,95,96,97,98,99,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193],[95,144,155,161,162],[95,144,161,162,163,187],[95,144,152,155,161,162,164,176],[95,144,161,162,165],[95,144,161,162,166],[95,143,144,161,162,167],[95,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193],[95,144,161,162,169],[95,144,161,162,170],[95,144,155,161,162,171,172],[95,144,161,162,171,173,188,190],[95,144,156,161,162],[95,144,155,161,162,176,177,179],[95,144,161,162,178,179],[95,144,161,162,176,177],[95,144,161,162,179],[95,144,161,162,180],[95,141,144,161,162,176,181,187],[95,144,155,161,162,182,183],[95,144,161,162,182,183],[95,144,149,161,162,164,176,184],[95,144,161,162,185],[95,144,161,162,164,186],[95,144,158,161,162,170,187],[95,144,149,161,162,188],[95,144,161,162,176,189],[95,144,161,162,163,190],[95,144,161,162,191],[95,136,144,161,162],[95,136,144,155,157,161,162,167,176,179,187,189,190,192],[95,144,161,162,176,193],[95,144,161,162,197,200,201,203],[95,144,161,162,197],[95,144,161,162,197,198,199,200,201,202,434,446,455],[95,144,161,162,197,198,199,203,434,446,455],[95,144,161,162,197,201,203,319],[95,144,161,162,197,201,203],[95,144,161,162,197,199,200,203,434,446,455],[95,144,161,162,197,198,200,203,434,446,455],[95,144,161,162,195,196],[95,144,161,162,457],[95,144,161,162,459],[95,144,161,162,461,462,463,464],[95,144,161,162,466],[86,95,144,161,162,216,217,218,220,438],[86,95,144,161,162,206,366,368,370,371,373,438],[86,95,144,161,162,206,222,227,228,229,230,231,416,438],[95,144,161,162,438],[95,144,161,162,217,285,360,397,406],[86,95,144,161,162],[95,144,161,162,204,360],[95,144,161,162,375],[95,144,161,162,206,374,438],[95,144,158,161,162,267,285,314,500],[95,144,158,161,162,279,294,359,406],[95,144,158,161,162,336],[95,144,161,162,410],[95,144,161,162,409,410,411],[95,144,161,162,409],[86,89,95,144,158,161,162,204,213,214,217,221,222,228,232,233,234,329,354,407,434,438],[86,95,144,161,162,219,254,264,366,367,372,438,500],[95,144,161,162,219,500],[95,144,161,162,234,264,265,438,500],[95,144,161,162,500],[86,95,144,161,162,219,220,500],[95,144,161,162,369,500],[95,144,161,162,214,408,415],[95,144,161,162,170,243,360],[95,144,161,162,243,360],[95,144,161,162,197,243],[95,144,161,162,197,286],[95,144,161,162,282,334,360,492,493],[95,144,161,162,403,486,487,488,489,491],[95,144,161,162,402],[95,144,161,162,402,403],[95,144,161,162,229,330,331,332],[95,144,161,162,330,333,334],[95,144,161,162,490],[95,144,161,162,330,334],[87,95,144,161,162,197,480],[95,144,161,162,187,197],[95,144,161,162,197,219,252],[95,144,161,162,197,219],[95,144,161,162,250,255],[95,144,161,162,197,251,436],[95,144,158,161,162,194,197,198,199,200,203,434,444,445,455],[95,144,158,161,162,418],[95,144,158,161,162,205,222,330,339,355,397,412,413,421,438,500],[95,144,161,162,213,414],[95,144,161,162,434],[85,95,144,161,162],[95,144,161,162,197,267,281,293,303,305,359],[95,144,161,162,170,267,281,302,303,304,359,499],[95,144,161,162,296,297,298,299,300,301],[95,144,161,162,298],[95,144,161,162,302],[95,144,161,162,243,381,382,384],[95,144,161,162,197,376,377,378,383],[95,144,161,162,381,383],[95,144,161,162,379],[95,144,161,162,380],[95,144,161,162,197,243,251,436],[95,144,161,162,197,243,435,436],[95,144,161,162,197,243,436],[95,144,161,162,355,356],[95,144,161,162,356],[95,144,158,161,162,205,436],[95,144,161,162,290],[95,143,144,161,162,289],[95,144,161,162,205,235,238,239,245,275,278,279,280,322,330,359,422],[95,144,161,162,235,311,330,334],[95,144,161,162,279,359],[95,144,161,162,197,279,287,288,290,291,292,293,294,295,306,307,308,309,310,312,313,359,360,500],[95,144,161,162,274],[95,144,158,161,162,170,205,206,235,236,239,240,246,322,328,329,334,355,397,421,434,438,500],[95,144,161,162,359],[95,143,144,161,162,205,217,239,240,277,329,357,358],[95,144,161,162,279],[95,143,144,161,162,238,269,270,271,272,273,274,275,276,278,359,360,421],[95,144,158,161,162,205,206,269,270,439],[95,144,161,162,205,217,240,329,330,355,359],[95,144,158,161,162,206,438],[95,144,158,161,162,176,205,206,245],[83,95,144,158,161,162,170,187,204,205,206,219,222,235,236,238,239,240,245,246,323,330,339,340,342,345,347,350,351,352,353,354,360,361,397,417,422,438],[95,144,158,161,162,176],[86,87,88,95,144,161,162,219,222,230,232,245,264,417,434,436,437,500],[95,144,158,161,162,176,187,225,373,375,376,377,378,384,500],[95,144,161,162,170,187,204,225,238,240,245,327,330,340,345,354,355,360,366,388,389,397,423,430,431],[95,144,161,162,213,214,232,240,329,354,438],[87,95,144,158,161,162,187,222,238,245,428,438],[95,144,161,162,266],[95,144,158,161,162,386,387,394],[95,144,161,162,245,438],[95,144,161,162,275,277],[95,144,161,162,238,239,417,436],[95,144,158,161,162,170,245,345,355,362,366,388,389,430,433],[95,144,161,162,224,225,417],[95,144,158,161,162,213,214,366,390],[86,95,144,161,162,361,392,417,438],[95,144,158,161,162,187,438],[95,144,158,161,162,219,237,361,362,371,385,391,393,417,438],[89,95,144,161,162,235,239,396,434,436],[83,95,144,158,161,162,170,187,213,214,221,222,236,238,240,242,245,246,327,330,340,342,355,360,389,397,417,422,423,424,426,429,436],[95,144,158,161,162,176,214,245,394,430,432],[95,144,161,162,208,209,210,211,212],[95,144,161,162,323,346],[95,144,161,162,348],[95,144,161,162,346],[95,144,161,162,348,349],[95,144,158,161,162,205,222,228,229,421],[85,87,95,144,158,161,162,170,206,235,239,244,245,246,338,397,422,434,436],[95,144,158,161,162,170,187,205,229,238,241,242,244],[95,144,161,162,270],[95,144,161,162,271],[95,144,161,162,272],[95,144,161,162,360],[95,144,161,162,224,418,419],[95,144,158,161,162,222,224,418,422],[95,144,161,162,223,419],[95,144,161,162,420],[95,144,161,162,224,225],[95,144,161,162,224,247],[95,144,161,162,224],[95,144,161,162,242,323,344],[95,144,161,162,343],[95,144,161,162,225,242,360],[95,144,161,162,242,341],[95,144,161,162,225,360],[95,144,161,162,322],[95,144,161,162,205,222,230,238,239,245,262,267,275,281,284,315,318,321,330,396,417,422],[95,144,161,162,256,259,260,261,282,283,334],[95,144,161,162,197,200,203,243,316,317],[95,144,161,162,197,200,203,243,316,317,320],[95,144,161,162,405],[95,144,161,162,217,239,279,290,294,330,359,396,398,399,400,401,403,404,407,417,438,439],[95,144,161,162,334],[95,144,161,162,338],[95,144,158,161,162,245,248,335,337,339,396,422,434,436],[95,144,161,162,256,257,258,259,260,261,282,283,334,435],[89,95,144,158,161,162,170,187,205,224,225,236,238,239,240,246,394,395,397,417,418,434,438],[95,144,161,162,240,327,439,440],[95,144,158,161,162,323,438],[95,144,158,161,162],[95,144,161,162,269,279],[95,144,161,162,268],[83,95,144,161,162,439],[95,144,161,162,269,324,438],[95,144,158,161,162,205,241,325,326,438,439,440],[95,144,161,162,197,330,331,333],[95,144,161,162,263],[87,95,144,161,162,197],[95,144,161,162,197,360],[89,95,144,161,162,197,239,246,434,436],[87,95,144,161,162,480,481],[95,144,161,162,197,255],[85,95,144,161,162,170,187,197,249,251,253,254,436],[95,144,161,162,205,219,360],[95,144,161,162,360,425],[95,144,161,162,330],[85,95,144,156,158,161,162,170,197,255,264,368,434,435],[95,144,161,162,197,198,199,200,203,434,446],[95,144,161,162,197,452,453,454,455],[95,144,149,161,162],[95,144,161,162,363,364,365],[95,144,161,162,363],[85,95,144,158,160,161,162,170,194,197,198,199,200,203,204,206,236,302,433,436,438,446,455],[95,144,161,162,468],[95,144,161,162,470],[95,144,161,162,472],[95,144,161,162,474],[95,144,161,162,476,477,478],[95,144,161,162,482],[95,144,161,162,450,456,458,460,465,467,469,471,473,475,479,483,485,495,496,498,499,500,501],[95,144,161,162,484],[95,144,161,162,494],[95,144,161,162,251],[95,144,161,162,497],[95,143,144,161,162,293,325,327,360,439,440,441,442,443,446,447,448,449],[95,144,161,162,194],[95,144,161,162,176,194,427],[95,108,112,144,161,162,187],[95,108,144,161,162,176,187],[95,103,144,161,162],[95,105,108,144,161,162,184,187],[95,144,161,162,164,184],[95,103,144,161,162,194],[95,105,108,144,161,162,164,187],[95,100,101,104,107,144,155,161,162,176,187],[95,108,115,144,161,162],[95,100,106,144,161,162],[95,108,129,130,144,161,162],[95,104,108,144,161,162,179,187,194],[95,129,144,161,162,194],[95,102,103,144,161,162,194],[95,108,144,161,162],[95,102,103,104,105,106,107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,130,131,132,133,134,135,144,161,162],[95,108,123,144,161,162],[95,108,115,116,144,161,162],[95,106,108,116,117,144,161,162],[95,107,144,161,162],[95,100,103,108,144,161,162],[95,108,112,116,117,144,161,162],[95,112,144,161,162],[95,106,108,111,144,161,162,187],[95,100,105,108,115,144,161,162],[95,144,161,162,176],[95,103,108,129,144,161,162,192,194]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"2ab096661c711e4a81cc464fa1e6feb929a54f5340b46b0a07ac6bbf857471f0","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"73f78680d4c08509933daf80947902f6ff41b6230f94dd002ae372620adb0f60","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5239f5c01bcfa9cd32f37c496cf19c61d69d37e48be9de612b541aac915805b","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"829b9e6028b29e6a8b1c01ddb713efe59da04d857089298fa79acbdb3cfcfdef","impliedFormat":1},{"version":"24f8562308dd8ba6013120557fa7b44950b619610b2c6cb8784c79f11e3c4f90","impliedFormat":1},{"version":"5f90b8c733a1bda63e42160b15a2301051e83a6f9d5332a59d16eb12f463270d","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"631eff75b0e35d1b1b31081d55209abc43e16b49426546ab5a9b40bdd40b1f60","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"913be43dad2a40e500104700aa26cfb5c51a976114bedf19624de43fdae7474f","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"78dbea00e90d2df8ea3dbef0cc379d95b8be9b71cd6bde4c28728f306811803b","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e1e46d0a9837ee058c100501080c920fa98081ea3956af0374308ba6f22a33e","impliedFormat":1},{"version":"272ca407e0c9068bdc5152552d876e68037ceae3de62e529306403e973dec8e1","impliedFormat":1},{"version":"fa7834c715d5357e4540cee40ce96c3250ddb67a7b879a6b7fa0e86d6696f121","impliedFormat":1},{"version":"22dfb07a7ab15b66ac043829056fe70124844636ae719551812ac631ba04985b","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"0cb167c371eaa8c869f8a7656a7296f2e4fae43b4d8b803a680236b24794e5f9","impliedFormat":1},{"version":"0a839dba0287cc0481ad4beedd48a1c64acf1e212ae865d1315f7007ca215161","impliedFormat":1},{"version":"38dc4655376cd1a4bd6bb3763d92949233e33d38d3dd3cbea7bbf218175a38ef","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"208a6a0bfb227bdf8fb964799d0a206c75cf03ccd72e63bf5495c9331354c6d6","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"48a679952eefe4cb776d5a0e1ccba2d3eb53b57448bbb7abc1fcebcbd5440188","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2d14da6ecb49bf828d83948765ec2d3a579d476bbb9645e749610baa6ec880ca","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"0aef708fb4c7a6b915e8305cbfac40cd207b032dbaabe9a01889a5fff3254681","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"ad9bdafb4e7abf14cc53ce7970486a84c87831e62891e5dfe798ddcd55e84701","affectsGlobalScope":true,"impliedFormat":1},{"version":"45479f65af737a3e5c26d8772bd8ab1aa8bebbd09c1a808c2b3faddb9b84afbb","impliedFormat":1},{"version":"71d3ae6a5e73ca4130762560425e00984ebaff64d5353a3333d1bb7eb86ef336","impliedFormat":1},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"045c1b395851aa71ef76393398466330fe1eeebc113c8085eefc6d84abea3a88","impliedFormat":1},{"version":"865a2612f5ec073dd48d454307ccabb04c48f8b96fda9940c5ebfe6b4b451f51","impliedFormat":1},{"version":"2e07abf27aa06353d46f4448c0bbac73431f6065eef7113128a5cd804d0c384d","impliedFormat":1},{"version":"dfb24c6874a941ebd8947c97efb27c6b40f4a48218ce7433d1d088d1245b6d58","impliedFormat":1},{"version":"bc03c3c352f689e38c0ddd50c39b1e65d59273991bfc8858a9e3c0ebb79c023b","impliedFormat":1},{"version":"ed91c87062f8720dfb894f41e364d0c189eb3fa40501f93cf36691e06f5d3261","impliedFormat":1},{"version":"9894dafe342b976d251aac58e616ac6df8db91fb9d98934ff9dd103e9e82578f","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"27ab780875bcbb65e09da7496f2ca36288b0c541abaa75c311450a077d54ec15","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"b6db56e4903e9c32e533b78ac85522de734b3d3a8541bf24d256058d464bf04b","impliedFormat":1},{"version":"24daa0366f837d22c94a5c0bad5bf1fd0f6b29e1fae92dc47c3072c3fdb2fbd5","impliedFormat":1},{"version":"570bb5a00836ffad3e4127f6adf581bfc4535737d8ff763a4d6f4cc877e60d98","impliedFormat":1},{"version":"889c00f3d32091841268f0b994beba4dceaa5df7573be12c2c829d7c5fbc232c","impliedFormat":1},{"version":"65f43099ded6073336e697512d9b80f2d4fec3182b7b2316abf712e84104db00","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"d6e73f8010935b7b4c7487b6fb13ea197cc610f0965b759bec03a561ccf8423a","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"496bbf339f3838c41f164238543e9fe5f1f10659cb30b68903851618464b98ba","impliedFormat":1},{"version":"5178eb4415a172c287c711dc60a619e110c3fd0b7de01ed0627e51a5336aa09c","impliedFormat":1},{"version":"ca6e5264278b53345bc1ce95f42fb0a8b733a09e3d6479c6ccfca55cdc45038c","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"fb1d8e814a3eeb5101ca13515e0548e112bd1ff3fb358ece535b93e94adf5a3a","impliedFormat":1},{"version":"98b18458acb46072947aabeeeab1e410f047e0cacc972943059ca5500b0a5e95","impliedFormat":1},{"version":"361e2b13c6765d7f85bb7600b48fde782b90c7c41105b7dab1f6e7871071ba20","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"380647d8f3b7f852cca6d154a376dbf8ac620a2f12b936594504a8a852e71d2f","impliedFormat":1},{"version":"208c9af9429dd3c76f5927b971263174aaa4bc7621ddec63f163640cbd3c473c","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"f438e39833e6bd41b4b4fee9c8c3ca2bc8ac63619eaf8044edf716b698ef865e","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"899c28fff8a33a5825e1d6a9265e84dda4882822df67765820c49000209e4d62","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"b838d4c72740eb0afd284bf7575b74c624b105eff2e8c7b4aeead57e7ac320ff","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"d1c9bf292a54312888a77bb19dba5e2503ad803f5393beafd45d78d2f4fe9b48","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"0c7c947ff881c4274c0800deaa0086971e0bfe51f89a33bd3048eaa3792d4876","affectsGlobalScope":true,"impliedFormat":1},{"version":"db01d18853469bcb5601b9fc9826931cc84cc1a1944b33cad76fd6f1e3d8c544","affectsGlobalScope":true,"impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"15b36126e0089bfef173ab61329e8286ce74af5e809d8a72edcafd0cc049057f","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"002eae065e6960458bda3cf695e578b0d1e2785523476f8a9170b103c709cd4f","impliedFormat":1},{"version":"c83bb0c9c5645a46c68356c2f73fdc9de339ce77f7f45a954f560c7e0b8d5ebb","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"72d63643a657c02d3e51cd99a08b47c9b020a565c55f246907050d3c8a5e77fb","impliedFormat":1},{"version":"1d415445ea58f8033ba199703e55ff7483c52ac6742075b803bd3e7bbe9f5d61","impliedFormat":1},{"version":"d6406c629bb3efc31aedb2de809bef471e475c86c7e67f3ef9b676b5d7e0d6b2","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"8c030e515014c10a2b98f9f48408e3ba18023dfd3f56e3312c6c2f3ae1f55a16","impliedFormat":1},{"version":"dafc31e9e8751f437122eb8582b93d477e002839864410ff782504a12f2a550c","impliedFormat":1},{"version":"754498c5208ce3c5134f6eabd49b25cf5e1a042373515718953581636491f3c3","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"633d58a237f4bb25ec7d565e4ffa32cecdcee8660ac12189c4351c52557cee9e","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"13283350547389802aa35d9f2188effaeac805499169a06ef5cd77ce2a0bd63f","impliedFormat":1},{"version":"ce791f6ea807560f08065d1af6014581eeb54a05abd73294777a281b6dfd73c2","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"e17cd049a1448de4944800399daa4a64c5db8657cc9be7ef46be66e2a2cd0e7c","impliedFormat":1},{"version":"43fa6ea8714e18adc312b30450b13562949ba2f205a1972a459180fa54471018","impliedFormat":1},{"version":"6e89c2c177347d90916bad67714d0fb473f7e37fb3ce912f4ed521fe2892cd0d","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"4d4927cbee21750904af7acf940c5e3c491b4d5ebc676530211e389dd375607a","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"8a97e578a9bc40eb4f1b0ca78f476f2e9154ecbbfd5567ee72943bab37fc156a","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"f22d05663d873ee7a600faf78abb67f3f719d32266803440cf11d5db7ac0cab2","impliedFormat":1},{"version":"d93c544ad20197b3976b0716c6d5cd5994e71165985d31dcab6e1f77feb4b8f2","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"a8b1c79a833ee148251e88a2553d02ce1641d71d2921cce28e79678f3d8b96aa","impliedFormat":1},{"version":"126d4f950d2bba0bd45b3a86c76554d4126c16339e257e6d2fabf8b6bf1ce00c","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"2d3cc2211f352f46ea6b7cf2c751c141ffcdf514d6e7ae7ee20b7b6742da313f","impliedFormat":1},{"version":"c75445151ff8b77d9923191efed7203985b1a9e09eccf4b054e7be864e27923d","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"fa8a8fbf91ee2a4779496225f0312aac6635b0f21aa09cdafa4283fe32d519c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"0e8aef93d79b000deb6ec336b5645c87de167168e184e84521886f9ecc69a4b5","impliedFormat":1},{"version":"c30436b130b6218b7714314dc41d3f459590db4bdf099eecd51cb1bda32109a8","impliedFormat":1},{"version":"20fa37b636fdcc1746ea0738f733d0aed17890d1cd7cb1b2f37010222c23f13e","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"efcce61e435bbf26e26a95115cf1313a0d236937b8be3854d7975fa9b75b12e3","affectsGlobalScope":true,"impliedFormat":1},{"version":"72b0ced59987170ebaa22b5fe0fa205437809b94c6d6e9e1ffd94ca5bb9c62b2","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"de7052bfee2981443498239a90c04ea5cc07065d5b9bb61b12cb6c84313ad4ef","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"6dcf60530c25194a9ee0962230e874ff29d34c59605d8e069a49928759a17e0a","impliedFormat":1},{"version":"a3e7d932dc9c09daa99141a8e4800fc6c58c625af0d4bbb017773dc36da75426","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"4a2edd238d9104eac35b60d727f1123de5062f452b70ed8e0366cb36387dfdfd","impliedFormat":1},{"version":"ca921bf56756cb6fe957f6af693a35251b134fb932dc13f3dfff0bb7106f80b4","impliedFormat":1},{"version":"fee92c97f1aa59eb7098a0cc34ff4df7e6b11bae71526aca84359a2575f313d8","impliedFormat":1},{"version":"0bd0297484aacea217d0b76e55452862da3c5d9e33b24430e0719d1161657225","impliedFormat":1},{"version":"2ab6d334bcbf2aff3acfc4fd8c73ecd82b981d3c3aa47b3f3b89281772286904","impliedFormat":1},{"version":"d07cbc787a997d83f7bde3877fec5fb5b12ce8c1b7047eb792996ed9726b4dde","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"49179c6a23701c642bd99abe30d996919748014848b738d8e85181fc159685ff","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"45490817629431853543adcb91c0673c25af52a456479588b6486daba34f68bb","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"8514c62ce38e58457d967e9e73f128eedc1378115f712b9eef7127f7c88f82ae","impliedFormat":1},{"version":"a6ead4af7c572e1b49311ba1bc356ccf4f351a7ebccf9a9d1ea65feb33fb2089","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"a47e6d954d22dd9ebb802e7e431b560ed7c581e79fb885e44dc92ed4f60d4c07","impliedFormat":1},{"version":"f019e57d2491c159d47a107fd90219a1734bdd2e25cd8d1db3c8fae5c6b414c4","impliedFormat":1},{"version":"a23185bc5ef590c287c28a91baf280367b50ae4ea40327366ad01f6f4a8edbc5","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"6a148329edecbda07c21098639ef4254ef7869fb25a69f58e5d6a8b7b69d4236","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"f63ab283a1c8f5c79fabe7ca4ef85f9633339c4f0e822fce6a767f9d59282af2","impliedFormat":1},{"version":"a54c996c8870ef1728a2c1fa9b8eaec0bf4a8001cd2583c02dd5869289465b10","impliedFormat":1},{"version":"3754982006a3b32c502cff0867ca83584f7a43b1035989ca73603f400de13c96","impliedFormat":1},{"version":"a30ae9bb8a8fa7b90f24b8a0496702063ae4fe75deb27da731ed4a03b2eb6631","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"e9dd71cf12123419c60dab867d44fbee5c358169f99529121eaef277f5c83531","impliedFormat":1},{"version":"5b6a189ba3a0befa1f5d9cb028eb9eec2af2089c32f04ff50e2411f63d70f25d","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"e91f7b1344577a02f051b9b471f33044fef8334a76dc9e1de003d17595a5219b","impliedFormat":1},{"version":"3af3584f79c57853028ef9421ec172539e1fe01853296dc05a9d615ade4ffaf6","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"752513f35f6cff294ffe02d6027c41373adf7bfa35e593dbfd53d95c203635ee","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"1a7e2ea171726446850ec72f4d1525d547ff7e86724cc9e7eec509725752a758","impliedFormat":1},{"version":"8c901126d73f09ecdea4785e9a187d1ac4e793e07da308009db04a7283ec2f37","impliedFormat":1},{"version":"c1de754ab5f3b0f4036d6893c74a0fc984c7fcb07936086f19bbe2974406775b","impliedFormat":1},{"version":"408e2239c45d5ffea474f4b21bb8982c254b6e00055d6dcbdaeb1b879e3c3932","impliedFormat":1},{"version":"94fe3281392e1015b22f39535878610b4fa6f1388dc8d78746be3bc4e4bb8950","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"06c25ddfc2242bd06c19f66c9eae4c46d937349a267810f89783680a1d7b5259","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"0427df5c06fafc5fe126d14b9becd24160a288deff40e838bfbd92a35f8d0d00","impliedFormat":1},{"version":"90c54a02432d04e4246c87736e53a6a83084357acfeeba7a489c5422b22f5c7a","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"f1ede1eb78b9afff3224a947395f6860fc0cf6102a11a7be119bd82e306c5fdf","impliedFormat":1},{"version":"e168dbb93e622df0f3040ffaa1ebdb0b47655ff3cd32717d2def6adf706587cc","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"ec1ca97598eda26b7a5e6c8053623acbd88e43be7c4d29c77ccd57abc4c43999","impliedFormat":1},{"version":"8c848e5d0edf1dacc0ce45dcf6a17eebca9375233cd6ae954705cb4f59f8c9ef","impliedFormat":1},{"version":"201f6a42eecca012e44701fa52b8e0067785cf58b4de00fbd92575c54b748551","impliedFormat":1},{"version":"824c76aec8d8c7e65769688cbee102238c0ef421ed6686f41b2a7d8e7e78a931","impliedFormat":1},{"version":"75b868be3463d5a8cfc0d9396f0a3d973b8c297401d00bfb008a42ab16643f13","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"1a42d2ec31a1fe62fdc51591768695ed4a2dc64c01be113e7ff22890bebb5e3f","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"1d17ba45cfbe77a9c7e0df92f7d95f3eefd49ee23d1104d0548b215be56945ad","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"2467b00d963828f540f4acd7910f4c04cfe4b489550e6bb682212f65583bca5b","impliedFormat":1},{"version":"b837d41bb8d39398690458f45cc445160dad36ec0db5ba0463d114e560d49d85","impliedFormat":99},{"version":"ac47421bbc96f79b2de2475223ca0512a9ff9f3d1f6c01823ffb2ac4c49e1d64","impliedFormat":1},{"version":"23a2cd76b68dbc15605465236c82bcce7d0a7a6d7a164171eef47e4a3d9f14c3","impliedFormat":1},{"version":"f82579d87701d639ff4e3930a9b24f4ee13ca74221a9a3a792feb47f01881a9c","impliedFormat":1},{"version":"d7e5d5245a8ba34a274717d085174b2c9827722778129b0081fefd341cca8f55","impliedFormat":1},{"version":"d9d32f94056181c31f553b32ce41d0ef75004912e27450738d57efcd2409c324","impliedFormat":1},{"version":"3be035da7bee86b4c3abf392e0edaa44fc6e45092995eefe36b39118c8a84068","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f828825d077c2fa0ea606649faeb122749273a353daab23924fe674e98ba44c","impliedFormat":1},{"version":"8cc87e467cfbce715e75f7645e3f59858c940ddf1cc8a28edd0dfc581f57a319","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"d9c46395b3980848a6c4b2f44e986d27d07faee3b3b4b1f214793255b8c64f2a","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"ecbaf0da125974be39c0aac869e403f72f033a4e7fd0d8cd821a8349b4159628","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"ceec3c81b2d81f5e3b855d9367c1d4c664ab5046dff8fd56552df015b7ccbe8f","affectsGlobalScope":true,"impliedFormat":1},"2ff11d16c601af868f04f81d3493a28e6873e70a9e8425a276ae47efc839345a",{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","impliedFormat":1},{"version":"05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"407a06ba04eede4074eec470ecba2784cbb3bf4e7de56833b097dd90a2aa0651","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"5c96bad5f78466785cdad664c056e9e2802d5482ca5f862ed19ba34ffbb7b3a4","impliedFormat":1},{"version":"81d8603ac527e75cfec72bb9391228b58f161c2b33514a9d814c7f3ebd3ef466","impliedFormat":1},{"version":"5f3dc10ae646f375776b4e028d2bed039a93eebbba105694d8b910feebbe8b9c","impliedFormat":1},{"version":"bb0cd7862b72f5eba39909c9889d566e198fcaddf7207c16737d0c2246112678","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"bad68fd0401eb90fe7da408565c8aee9c7a7021c2577aec92fa1382e8876071a","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"fec01479923e169fb52bd4f668dbeef1d7a7ea6e6d491e15617b46f2cacfa37d","impliedFormat":1},{"version":"8a8fb3097ba52f0ae6530ec6ab34e43e316506eb1d9aa29420a4b1e92a81442d","impliedFormat":1},{"version":"44e09c831fefb6fe59b8e65ad8f68a7ecc0e708d152cfcbe7ba6d6080c31c61e","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"4655709c9cb3fd6db2b866cab7c418c40ed9533ce8ea4b66b5f17ec2feea46a9","impliedFormat":1},{"version":"87affad8e2243635d3a191fa72ef896842748d812e973b7510a55c6200b3c2a4","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"3eecb25bb467a948c04874d70452b14ae7edb707660aac17dc053e42f2088b00","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"5f0292a40df210ab94b9fb44c8b775c51e96777e14e073900e392b295ca1061b","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"8627ad129bcf56e82adff0ab5951627c993937aa99f5949c33240d690088b803","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"1d63055b690a582006435ddd3aa9c03aac16a696fac77ce2ed808f3e5a06efab","impliedFormat":1},"4caf1c6ba337ebe68fcf37d3704f669bf8efc739ec2a367a1bbc4c121ae9c02a","597053315ade836835602ccf4d86761d4c15bf11ae8884899de549dc9ace9a29","5c6068ebbc8e223fc1dbd01deee5bc3518231756bbe3977af86b6f8127f40774","d8a296125e4fe2b365beaeadac6e5ec95bc26bccc792bfe7aa6d1ef65f589192","05bacbd9df0d970df3e48afe1eb1ad24e9141705619c86c13fa9e39c23b14425","932b5345856fde745edf34ab65c4ede38a355dae651d006adec5f702f02cc871","49fbfcc9b207a26c36363e9cecbd5e734e75d8f70759fa34781a9b83a6a6e2e7","796d9e83d6c14dddbb6007369f2f8da923958f16ee2da0fc7ee96b6f79a47914","4777a5eed630b157df4a052780b771356b0c95ca5abac4972867e8e7bf9aa3df","dcadfbeb1248c297121419548d1a460663dda70b97103759a199575e169159bf","678b19e74555dcc937851c68143fcc01820235c403c076bec8b6a9152e37af6f","b5d2ba79f0de0afe0439ac5c262ca657a961e88f7af448308cf5b118d5d4a691","3ce26d779e2cf24a270cfa969d135b24e97f861ac10d901e608fc0a1c77852f6","7da7dd6ca3855667d0b6d18997c452564ba9510d5a4b6dce32708a37a49eb9e1","06f74367e39067cb670751936a8034c944a4b4a37d5f32a46dc0a1635cec1bd5","10387b7860d70dbdc65edce1e75e28b25821a124ecbee64c91916b38fd9138ae","55154230433921fd8a52c746b54f6e274b10dc1b38fc01ece4fa6762ad184d5e","2e06a3ced58e3a44eeaad9926ad2dc2cb88927ec28b982d7eaa7453e0f203454","cb780c47a8ac70803fbd6ccac50a2266e8d8203291883e5f5e5ebd3527f58558","1dc0ca0b567730b1b4ac82ecbfe6c66f5093c9c1bc21bffb33ab610dfb339c11","6ba801c34031bc44f70b5b01fd708dbfab32255bd15fb62281b1d5e2317abc08","776e626a7920084c523ef27d910072e4be4f98903cc4185ea74c53a7c6e7d247","f130405146b36338323d0a3f4ca72ceb077773af819e56bc7aee42444d09a841","f223e9d1f6a2406012735b5a6b009edf2f48911c46e684e4acec0e6f05a9e30a","2ed27ce755f52c0f0ec8d253d113417908197831a2fe5c75ead5796f7c8185a5"],"root":[451,[503,527]],"options":{"allowJs":false,"esModuleInterop":true,"jsx":1,"module":99,"skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[514,1],[516,2],[517,3],[519,4],[520,5],[521,6],[522,7],[512,8],[523,9],[513,10],[525,11],[526,12],[524,1],[504,13],[510,14],[527,15],[518,6],[511,16],[515,17],[506,17],[507,17],[508,13],[509,18],[505,13],[451,19],[503,20],[427,13],[368,13],[141,21],[142,21],[143,22],[95,23],[144,24],[145,25],[146,26],[90,13],[93,27],[91,13],[92,13],[147,28],[148,29],[149,30],[150,31],[151,32],[152,33],[153,33],[154,34],[155,35],[156,36],[157,37],[96,13],[94,13],[158,38],[159,39],[160,40],[194,41],[161,42],[162,13],[163,43],[164,44],[165,45],[166,46],[167,47],[168,48],[169,49],[170,50],[171,51],[172,51],[173,52],[174,13],[175,53],[176,54],[178,55],[177,56],[179,57],[180,58],[181,59],[182,60],[183,61],[184,62],[185,63],[186,64],[187,65],[188,66],[189,67],[190,68],[191,69],[97,13],[98,13],[99,13],[137,70],[138,13],[139,13],[140,57],[192,71],[193,72],[202,73],[201,74],[203,75],[200,76],[320,77],[319,78],[198,79],[317,13],[199,80],[195,13],[197,81],[316,74],[243,74],[196,13],[458,82],[460,83],[465,84],[467,85],[219,86],[372,87],[417,88],[367,89],[234,13],[230,13],[217,13],[407,90],[326,91],[218,13],[354,92],[374,93],[375,94],[315,95],[404,96],[337,97],[411,98],[412,99],[410,100],[409,13],[408,101],[373,102],[220,103],[265,13],[266,104],[233,13],[235,105],[221,106],[246,105],[340,105],[88,105],[370,107],[369,13],[416,108],[437,13],[229,13],[291,109],[292,110],[286,74],[488,13],[294,13],[295,111],[287,112],[494,113],[492,114],[487,13],[403,115],[402,13],[486,116],[288,74],[333,117],[331,118],[489,13],[493,13],[491,119],[490,13],[332,120],[481,121],[484,122],[253,123],[252,124],[251,125],[497,74],[250,126],[268,13],[442,13],[445,13],[444,74],[446,127],[84,13],[413,128],[414,129],[415,130],[237,13],[228,131],[204,13],[307,74],[86,132],[306,133],[305,134],[296,13],[297,13],[304,13],[299,13],[302,135],[298,13],[300,136],[303,137],[301,136],[216,13],[226,13],[227,105],[383,138],[384,139],[382,140],[380,141],[381,142],[377,13],[313,111],[244,111],[459,143],[468,144],[472,145],[357,146],[356,13],[83,13],[447,147],[206,148],[289,149],[290,150],[281,151],[273,13],[312,152],[274,153],[314,154],[309,155],[308,13],[310,13],[330,156],[358,157],[359,158],[276,159],[279,160],[271,161],[399,162],[205,163],[389,164],[355,165],[241,166],[438,167],[85,89],[378,13],[385,168],[432,169],[376,13],[431,170],[89,13],[429,171],[236,13],[267,172],[424,13],[222,13],[223,13],[388,173],[232,13],[323,174],[278,175],[240,176],[277,13],[387,13],[379,13],[390,177],[418,178],[391,179],[231,13],[393,180],[395,181],[394,182],[362,13],[386,166],[397,183],[430,184],[433,185],[207,13],[210,13],[208,13],[212,13],[209,13],[211,13],[213,186],[215,13],[347,187],[346,13],[352,188],[348,189],[351,190],[350,190],[353,188],[349,189],[422,191],[339,192],[245,193],[449,13],[476,194],[478,195],[275,13],[477,196],[360,157],[448,197],[293,157],[214,13],[238,198],[419,199],[420,200],[421,201],[262,202],[398,202],[247,202],[341,203],[248,203],[225,204],[224,13],[345,205],[344,206],[343,207],[342,208],[242,209],[285,210],[322,211],[284,212],[318,213],[321,214],[406,215],[405,216],[401,217],[336,218],[338,219],[335,220],[396,221],[329,13],[464,13],[328,222],[400,13],[324,223],[272,224],[270,225],[269,226],[440,227],[443,13],[439,228],[325,228],[462,13],[461,13],[463,13],[441,13],[327,229],[283,74],[457,13],[334,230],[254,13],[264,231],[239,13],[470,74],[480,232],[261,74],[474,111],[260,233],[435,234],[259,232],[87,13],[482,235],[257,74],[258,74],[249,13],[263,13],[256,236],[255,237],[361,238],[280,50],[423,50],[392,13],[426,239],[425,13],[466,13],[311,240],[282,74],[436,241],[452,74],[455,242],[456,243],[453,74],[454,13],[371,244],[366,245],[365,13],[364,246],[363,13],[434,247],[469,248],[471,249],[473,250],[475,251],[479,252],[483,253],[502,254],[485,255],[495,256],[496,257],[498,258],[450,259],[501,131],[500,13],[499,260],[428,261],[81,13],[82,13],[13,13],[14,13],[16,13],[15,13],[2,13],[17,13],[18,13],[19,13],[20,13],[21,13],[22,13],[23,13],[24,13],[3,13],[25,13],[26,13],[4,13],[27,13],[31,13],[28,13],[29,13],[30,13],[32,13],[33,13],[34,13],[5,13],[35,13],[36,13],[37,13],[38,13],[6,13],[42,13],[39,13],[40,13],[41,13],[43,13],[7,13],[44,13],[49,13],[50,13],[45,13],[46,13],[47,13],[48,13],[8,13],[54,13],[51,13],[52,13],[53,13],[55,13],[9,13],[56,13],[57,13],[58,13],[60,13],[59,13],[61,13],[62,13],[10,13],[63,13],[64,13],[65,13],[11,13],[66,13],[67,13],[68,13],[69,13],[70,13],[1,13],[71,13],[72,13],[12,13],[76,13],[74,13],[79,13],[78,13],[73,13],[77,13],[75,13],[80,13],[115,262],[125,263],[114,262],[135,264],[106,265],[105,266],[134,260],[128,267],[133,268],[108,269],[122,270],[107,271],[131,272],[103,273],[102,260],[132,274],[104,275],[109,276],[110,13],[113,276],[100,13],[136,277],[126,278],[117,279],[118,280],[120,281],[116,282],[119,283],[129,260],[111,284],[112,285],[121,286],[101,287],[124,278],[123,276],[127,13],[130,288]],"affectedFilesPendingEmit":[514,516,517,519,520,521,522,512,523,513,525,526,524,504,510,527,518,511,515,506,507,508,509,505,451,503],"version":"5.9.3"} \ No newline at end of file