pg-backup-sdk 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +363 -57
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,60 +1,73 @@
|
|
|
1
1
|
# pg-backup-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
SDK open source em **Node.js + TypeScript** para criar backups automáticos de bancos **PostgreSQL** usando `pg_dump`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
O pacote pode ser usado de duas formas:
|
|
6
|
+
|
|
7
|
+
1. **Como CLI** no terminal.
|
|
8
|
+
2. **Como módulo/SDK** importado dentro de outro projeto Node.js.
|
|
9
|
+
|
|
10
|
+
Ele lista os bancos PostgreSQL, cria uma pasta separada para cada banco e salva os arquivos `.dump` no formato custom do PostgreSQL.
|
|
11
|
+
|
|
12
|
+
---
|
|
6
13
|
|
|
7
14
|
## Recursos
|
|
8
15
|
|
|
9
16
|
* Backup automático com CRON
|
|
10
17
|
* Backup manual via CLI
|
|
18
|
+
* Uso como módulo/SDK em outro projeto
|
|
11
19
|
* Uma pasta separada por banco
|
|
12
20
|
* Retenção automática de backups antigos
|
|
13
21
|
* Ignora bancos internos por padrão
|
|
14
22
|
* Permite filtrar bancos específicos
|
|
15
23
|
* Usa `pg_dump --format custom`
|
|
16
|
-
*
|
|
24
|
+
* Compatível com Node.js, Docker e systemd
|
|
25
|
+
* Escrito em TypeScript
|
|
26
|
+
* Pronto para projetos open source
|
|
17
27
|
|
|
18
|
-
|
|
28
|
+
---
|
|
19
29
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
## Instalação
|
|
31
|
+
|
|
32
|
+
### Instalar em um projeto
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install pg-backup-sdk
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Instalar globalmente como CLI
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install -g pg-backup-sdk
|
|
28
42
|
```
|
|
29
43
|
|
|
44
|
+
---
|
|
45
|
+
|
|
30
46
|
## Requisitos
|
|
31
47
|
|
|
32
48
|
* Node.js 20+
|
|
33
49
|
* PostgreSQL client instalado na máquina
|
|
34
50
|
* Binário `pg_dump` disponível no PATH ou configurado no `.env`
|
|
35
51
|
|
|
36
|
-
Ubuntu/Debian
|
|
52
|
+
### Ubuntu/Debian
|
|
37
53
|
|
|
38
54
|
```bash
|
|
39
55
|
sudo apt install postgresql-client
|
|
40
56
|
```
|
|
41
57
|
|
|
42
|
-
Windows
|
|
58
|
+
### Windows
|
|
59
|
+
|
|
60
|
+
Configure o caminho do `pg_dump` no `.env`:
|
|
43
61
|
|
|
44
62
|
```env
|
|
45
63
|
PG_DUMP_BIN=C:\Program Files\PostgreSQL\16\bin\pg_dump.exe
|
|
46
64
|
```
|
|
47
65
|
|
|
48
|
-
|
|
66
|
+
---
|
|
49
67
|
|
|
50
|
-
|
|
51
|
-
git clone https://github.com/guio11221/pg-backup-sdk.git
|
|
52
|
-
cd pg-backup-sdk
|
|
53
|
-
npm install
|
|
54
|
-
cp .env.example .env
|
|
55
|
-
```
|
|
68
|
+
## Configuração
|
|
56
69
|
|
|
57
|
-
|
|
70
|
+
Crie um arquivo `.env` na raiz do projeto:
|
|
58
71
|
|
|
59
72
|
```env
|
|
60
73
|
PG_HOST=localhost
|
|
@@ -62,100 +75,354 @@ PG_PORT=5432
|
|
|
62
75
|
PG_USER=postgres
|
|
63
76
|
PG_PASSWORD=postgres
|
|
64
77
|
PG_ADMIN_DATABASE=postgres
|
|
78
|
+
|
|
65
79
|
BACKUP_DIR=./backups
|
|
66
80
|
BACKUP_CRON=0 2 * * *
|
|
67
81
|
BACKUP_RETENTION_DAYS=7
|
|
82
|
+
|
|
68
83
|
PG_DUMP_BIN=pg_dump
|
|
84
|
+
|
|
69
85
|
IGNORE_DATABASES=postgres,template0,template1
|
|
70
86
|
ONLY_DATABASES=
|
|
71
87
|
```
|
|
72
88
|
|
|
73
|
-
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Variáveis de ambiente
|
|
92
|
+
|
|
93
|
+
| Variável | Descrição | Padrão |
|
|
94
|
+
| ----------------------- | ---------------------------------------------- | ------------------------------ |
|
|
95
|
+
| `PG_HOST` | Host do PostgreSQL | obrigatório |
|
|
96
|
+
| `PG_PORT` | Porta do PostgreSQL | `5432` |
|
|
97
|
+
| `PG_USER` | Usuário PostgreSQL | obrigatório |
|
|
98
|
+
| `PG_PASSWORD` | Senha do PostgreSQL | obrigatório |
|
|
99
|
+
| `PG_ADMIN_DATABASE` | Banco usado para listar os databases | `postgres` |
|
|
100
|
+
| `BACKUP_DIR` | Pasta raiz onde os backups serão salvos | `./backups` |
|
|
101
|
+
| `BACKUP_CRON` | Expressão CRON usada pelo scheduler | `0 2 * * *` |
|
|
102
|
+
| `BACKUP_RETENTION_DAYS` | Quantidade de dias para manter backups antigos | `7` |
|
|
103
|
+
| `PG_DUMP_BIN` | Caminho do binário `pg_dump` | `pg_dump` |
|
|
104
|
+
| `IGNORE_DATABASES` | Bancos ignorados separados por vírgula | `postgres,template0,template1` |
|
|
105
|
+
| `ONLY_DATABASES` | Bancos permitidos separados por vírgula | vazio |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Como funciona a retenção
|
|
110
|
+
|
|
111
|
+
Exemplo:
|
|
112
|
+
|
|
113
|
+
```env
|
|
114
|
+
BACKUP_CRON=0 2 * * *
|
|
115
|
+
BACKUP_RETENTION_DAYS=7
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Isso significa:
|
|
119
|
+
|
|
120
|
+
* executa backup todos os dias às `02:00`;
|
|
121
|
+
* mantém os backups dos últimos `7` dias;
|
|
122
|
+
* backups mais antigos são removidos automaticamente.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Exemplos de CRON
|
|
127
|
+
|
|
128
|
+
### Todo dia às 02:00
|
|
129
|
+
|
|
130
|
+
```env
|
|
131
|
+
BACKUP_CRON=0 2 * * *
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Todo dia à meia-noite
|
|
135
|
+
|
|
136
|
+
```env
|
|
137
|
+
BACKUP_CRON=0 0 * * *
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Todo domingo às 03:00
|
|
141
|
+
|
|
142
|
+
```env
|
|
143
|
+
BACKUP_CRON=0 3 * * 0
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### A cada 1 minuto, apenas para teste
|
|
147
|
+
|
|
148
|
+
```env
|
|
149
|
+
BACKUP_CRON=* * * * *
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
# Uso como CLI
|
|
155
|
+
|
|
156
|
+
Depois de instalar globalmente:
|
|
74
157
|
|
|
75
158
|
```bash
|
|
76
|
-
npm
|
|
159
|
+
npm install -g pg-backup-sdk
|
|
77
160
|
```
|
|
78
161
|
|
|
79
|
-
|
|
162
|
+
## Executar backup manual
|
|
80
163
|
|
|
81
164
|
```bash
|
|
82
|
-
|
|
165
|
+
pg-backup-sdk --now
|
|
83
166
|
```
|
|
84
167
|
|
|
85
168
|
## Rodar scheduler
|
|
86
169
|
|
|
87
170
|
```bash
|
|
88
|
-
|
|
171
|
+
pg-backup-sdk
|
|
89
172
|
```
|
|
90
173
|
|
|
91
|
-
|
|
174
|
+
O scheduler ficará rodando e executará os backups conforme o valor de `BACKUP_CRON`.
|
|
92
175
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
# Uso como módulo/SDK
|
|
179
|
+
|
|
180
|
+
Você também pode importar o `pg-backup-sdk` dentro de outro projeto Node.js ou TypeScript.
|
|
181
|
+
|
|
182
|
+
## Backup manual dentro do código
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { runBackupJob } from 'pg-backup-sdk';
|
|
186
|
+
|
|
187
|
+
async function main(): Promise<void> {
|
|
188
|
+
await runBackupJob();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
main().catch((error) => {
|
|
192
|
+
console.error('Erro ao executar backup:', error);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
});
|
|
96
195
|
```
|
|
97
196
|
|
|
98
|
-
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Iniciar scheduler dentro de outro projeto
|
|
99
200
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
| `PG_HOST` | Host do PostgreSQL | obrigatório |
|
|
103
|
-
| `PG_PORT` | Porta do PostgreSQL | `5432` |
|
|
104
|
-
| `PG_USER` | Usuário PostgreSQL | obrigatório |
|
|
105
|
-
| `PG_PASSWORD` | Senha PostgreSQL | obrigatório |
|
|
106
|
-
| `PG_ADMIN_DATABASE` | Banco usado para listar databases | `postgres` |
|
|
107
|
-
| `BACKUP_DIR` | Pasta raiz dos backups | `./backups` |
|
|
108
|
-
| `BACKUP_CRON` | Expressão CRON do scheduler | `0 2 * * *` |
|
|
109
|
-
| `BACKUP_RETENTION_DAYS` | Dias de retenção | `7` |
|
|
110
|
-
| `PG_DUMP_BIN` | Caminho do binário pg_dump | `pg_dump` |
|
|
111
|
-
| `IGNORE_DATABASES` | Bancos ignorados separados por vírgula | `postgres,template0,template1` |
|
|
112
|
-
| `ONLY_DATABASES` | Bancos permitidos separados por vírgula | vazio |
|
|
201
|
+
```ts
|
|
202
|
+
import { startBackupScheduler } from 'pg-backup-sdk';
|
|
113
203
|
|
|
114
|
-
|
|
204
|
+
startBackupScheduler();
|
|
205
|
+
```
|
|
115
206
|
|
|
116
|
-
|
|
207
|
+
Esse código inicia o agendador de backups usando a expressão definida em:
|
|
208
|
+
|
|
209
|
+
```env
|
|
210
|
+
BACKUP_CRON=0 2 * * *
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Exemplo usando Express
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
import express from 'express';
|
|
219
|
+
import { runBackupJob, startBackupScheduler } from 'pg-backup-sdk';
|
|
220
|
+
|
|
221
|
+
const app = express();
|
|
222
|
+
|
|
223
|
+
app.use(express.json());
|
|
224
|
+
|
|
225
|
+
startBackupScheduler();
|
|
226
|
+
|
|
227
|
+
app.post('/admin/backups/run', async (req, res) => {
|
|
228
|
+
try {
|
|
229
|
+
await runBackupJob();
|
|
230
|
+
|
|
231
|
+
return res.status(200).json({
|
|
232
|
+
success: true,
|
|
233
|
+
message: 'Backup executado com sucesso'
|
|
234
|
+
});
|
|
235
|
+
} catch (error) {
|
|
236
|
+
return res.status(500).json({
|
|
237
|
+
success: false,
|
|
238
|
+
message: 'Erro ao executar backup',
|
|
239
|
+
error: error instanceof Error ? error.message : 'Erro desconhecido'
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
app.listen(3000, () => {
|
|
245
|
+
console.log('Servidor rodando na porta 3000');
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Exemplo usando NestJS
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
import { Injectable, OnModuleInit } from '@nestjs/common';
|
|
255
|
+
import { runBackupJob, startBackupScheduler } from 'pg-backup-sdk';
|
|
256
|
+
|
|
257
|
+
@Injectable()
|
|
258
|
+
export class BackupService implements OnModuleInit {
|
|
259
|
+
onModuleInit(): void {
|
|
260
|
+
startBackupScheduler();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async runManualBackup(): Promise<void> {
|
|
264
|
+
await runBackupJob();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Controller:
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
import { Controller, Post } from '@nestjs/common';
|
|
273
|
+
import { BackupService } from './backup.service';
|
|
274
|
+
|
|
275
|
+
@Controller('admin/backups')
|
|
276
|
+
export class BackupController {
|
|
277
|
+
constructor(private readonly backupService: BackupService) {}
|
|
278
|
+
|
|
279
|
+
@Post('run')
|
|
280
|
+
async runBackup() {
|
|
281
|
+
await this.backupService.runManualBackup();
|
|
282
|
+
|
|
283
|
+
return {
|
|
284
|
+
success: true,
|
|
285
|
+
message: 'Backup executado com sucesso'
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Exemplo usando Fastify
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
import Fastify from 'fastify';
|
|
297
|
+
import { runBackupJob, startBackupScheduler } from 'pg-backup-sdk';
|
|
298
|
+
|
|
299
|
+
const app = Fastify();
|
|
300
|
+
|
|
301
|
+
startBackupScheduler();
|
|
302
|
+
|
|
303
|
+
app.post('/admin/backups/run', async () => {
|
|
304
|
+
await runBackupJob();
|
|
305
|
+
|
|
306
|
+
return {
|
|
307
|
+
success: true,
|
|
308
|
+
message: 'Backup executado com sucesso'
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
await app.listen({
|
|
313
|
+
port: 3000,
|
|
314
|
+
host: '0.0.0.0'
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Estrutura de backups gerada
|
|
321
|
+
|
|
322
|
+
```txt
|
|
323
|
+
backups/
|
|
324
|
+
├─ financeiro/
|
|
325
|
+
│ └─ financeiro_2026-06-25_02-00-00.dump
|
|
326
|
+
├─ pmgestao/
|
|
327
|
+
│ └─ pmgestao_2026-06-25_02-00-00.dump
|
|
328
|
+
└─ sistema_escolar/
|
|
329
|
+
└─ sistema_escolar_2026-06-25_02-00-00.dump
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Cada banco recebe sua própria pasta.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Filtros de bancos
|
|
337
|
+
|
|
338
|
+
### Backup de todos os bancos, exceto internos
|
|
117
339
|
|
|
118
340
|
```env
|
|
119
341
|
IGNORE_DATABASES=postgres,template0,template1
|
|
120
342
|
ONLY_DATABASES=
|
|
121
343
|
```
|
|
122
344
|
|
|
123
|
-
Backup apenas de
|
|
345
|
+
### Backup apenas de bancos específicos
|
|
124
346
|
|
|
125
347
|
```env
|
|
126
348
|
ONLY_DATABASES=sistema_escolar,financeiro,pmgestao
|
|
127
349
|
```
|
|
128
350
|
|
|
129
|
-
Ignorar banco de teste
|
|
351
|
+
### Ignorar banco de teste
|
|
130
352
|
|
|
131
353
|
```env
|
|
132
354
|
IGNORE_DATABASES=postgres,template0,template1,test_db
|
|
133
355
|
```
|
|
134
356
|
|
|
357
|
+
Quando `ONLY_DATABASES` estiver preenchido, apenas os bancos listados serão considerados para backup.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
135
361
|
## Restaurar backup
|
|
136
362
|
|
|
137
|
-
|
|
363
|
+
Como os arquivos são gerados no formato custom do PostgreSQL, use `pg_restore`.
|
|
364
|
+
|
|
365
|
+
### Criar novo banco e restaurar
|
|
138
366
|
|
|
139
367
|
```bash
|
|
140
368
|
createdb -U postgres nome_banco_restaurado
|
|
141
369
|
pg_restore -U postgres -d nome_banco_restaurado ./backups/pmgestao/pmgestao_2026-06-25_02-00-00.dump
|
|
142
370
|
```
|
|
143
371
|
|
|
144
|
-
Restaurar limpando objetos existentes
|
|
372
|
+
### Restaurar limpando objetos existentes
|
|
145
373
|
|
|
146
374
|
```bash
|
|
147
375
|
pg_restore -U postgres --clean --if-exists -d nome_banco ./backups/pmgestao/pmgestao_2026-06-25_02-00-00.dump
|
|
148
376
|
```
|
|
149
377
|
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Desenvolvimento local
|
|
381
|
+
|
|
382
|
+
Clone o repositório:
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
git clone https://github.com/guio11221/pg-backup-sdk.git
|
|
386
|
+
cd pg-backup-sdk
|
|
387
|
+
npm install
|
|
388
|
+
cp .env.example .env
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Rodar em desenvolvimento:
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
npm run dev
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Executar backup manual em desenvolvimento:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
npm run backup
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Build de produção:
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
npm run build
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Rodar build:
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
npm start
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
150
417
|
## Docker
|
|
151
418
|
|
|
152
|
-
Build
|
|
419
|
+
### Build
|
|
153
420
|
|
|
154
421
|
```bash
|
|
155
422
|
docker build -t pg-backup-sdk .
|
|
156
423
|
```
|
|
157
424
|
|
|
158
|
-
Run
|
|
425
|
+
### Run
|
|
159
426
|
|
|
160
427
|
```bash
|
|
161
428
|
docker run --rm \
|
|
@@ -164,13 +431,15 @@ docker run --rm \
|
|
|
164
431
|
pg-backup-sdk
|
|
165
432
|
```
|
|
166
433
|
|
|
167
|
-
|
|
434
|
+
### Docker Compose
|
|
168
435
|
|
|
169
436
|
```bash
|
|
170
437
|
cp docker-compose.example.yml docker-compose.yml
|
|
171
438
|
docker compose up -d
|
|
172
439
|
```
|
|
173
440
|
|
|
441
|
+
---
|
|
442
|
+
|
|
174
443
|
## systemd
|
|
175
444
|
|
|
176
445
|
Copie o projeto para `/opt/pg-backup-sdk`.
|
|
@@ -190,23 +459,60 @@ Logs:
|
|
|
190
459
|
journalctl -u pg-backup-sdk -f
|
|
191
460
|
```
|
|
192
461
|
|
|
193
|
-
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Publicar no npm
|
|
465
|
+
|
|
466
|
+
Atualize a versão:
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
npm version patch
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Publique:
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
npm publish
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
Verificar versão publicada:
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
npm view pg-backup-sdk version
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Ver todas as versões:
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
npm view pg-backup-sdk versions
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## Publicar no GitHub
|
|
194
493
|
|
|
195
494
|
```bash
|
|
196
495
|
git init
|
|
197
496
|
git add .
|
|
198
|
-
git commit -m "Initial open source PostgreSQL backup
|
|
497
|
+
git commit -m "Initial open source PostgreSQL backup SDK"
|
|
199
498
|
git branch -M main
|
|
200
499
|
git remote add origin https://github.com/guio11221/pg-backup-sdk.git
|
|
201
500
|
git push -u origin main
|
|
202
501
|
```
|
|
203
502
|
|
|
503
|
+
---
|
|
504
|
+
|
|
204
505
|
## Segurança
|
|
205
506
|
|
|
206
507
|
* Não suba o arquivo `.env` para o GitHub.
|
|
207
|
-
* Use usuário PostgreSQL com permissões adequadas para backup.
|
|
508
|
+
* Use um usuário PostgreSQL com permissões adequadas para backup.
|
|
509
|
+
* Evite usar o superusuário `postgres` em produção.
|
|
208
510
|
* Salve backups em disco seguro.
|
|
209
511
|
* Para produção, considere copiar os backups para outro servidor, S3, NAS ou storage externo.
|
|
512
|
+
* Proteja rotas manuais de backup com autenticação e autorização.
|
|
513
|
+
* Não exponha endpoints de backup publicamente sem proteção.
|
|
514
|
+
|
|
515
|
+
---
|
|
210
516
|
|
|
211
517
|
## Licença
|
|
212
518
|
|