From 9ca548a62de8fe04523fd9bc9eb63759f80d2ffa Mon Sep 17 00:00:00 2001 From: Matheus Ricardo Brunelli Date: Thu, 5 Oct 2023 11:46:34 +0000 Subject: [PATCH] deploy: 37b67136609f8d7906194f196215991975b03855 --- 404.html | 8 +++---- aprenda-a-criar-snippets-no-vscode/index.html | 10 ++++----- aprenda-a-testar-pt1/index.html | 10 ++++----- aprenda-a-testar-pt2/index.html | 10 ++++----- archive/index.html | 10 ++++----- ...c2115.b328678d.js => 12fc2115.de73d99a.js} | 2 +- assets/js/2c46ef68.44f7a85e.js | 1 + assets/js/3234bd47.cd43694f.js | 1 + assets/js/378ebcfd.25503ea2.js | 1 + assets/js/3fe1affd.90cdc07b.js | 1 + ...76adc.82c15e01.js => 44176adc.f0e6558e.js} | 2 +- assets/js/6ae2e228.171f296a.js | 1 + assets/js/6ae2e228.b733cf1a.js | 1 - assets/js/814f3328.1391f7a7.js | 1 - assets/js/814f3328.3433abcc.js | 1 + ...d8f45.b9adc77d.js => 816d8f45.3a123ab7.js} | 2 +- ...84eec.f5dfab6a.js => a5f84eec.5b0a9bf9.js} | 2 +- assets/js/a7023ddc.af52f977.js | 1 + assets/js/a7023ddc.eb9f6974.js | 1 - ...0d8f5.27176f2d.js => ae80d8f5.8e669ca3.js} | 2 +- assets/js/b2f554cd.450bf15b.js | 1 - assets/js/b2f554cd.58e375fe.js | 1 + ...b4cc7.45e9d7da.js => d81b4cc7.1eeaa3e6.js} | 2 +- assets/js/main.38da634c.js | 2 ++ ...CENSE.txt => main.38da634c.js.LICENSE.txt} | 0 assets/js/main.56ada70d.js | 2 -- assets/js/runtime~main.21caba00.js | 1 - assets/js/runtime~main.392caf8c.js | 1 + atom.xml | 20 +++++++++++++++++- .../index.html" | 10 ++++----- .../index.html | 10 ++++----- criando-atalhos-para-o-git/index.html | 10 ++++----- .../index.html | 10 ++++----- en/404.html | 8 +++---- .../index.html | 10 ++++----- en/aprenda-a-testar-pt1/index.html | 10 ++++----- en/aprenda-a-testar-pt2/index.html | 10 ++++----- en/archive/index.html | 10 ++++----- en/assets/js/2c46ef68.be6839a2.js | 1 + en/assets/js/378ebcfd.6727b4d6.js | 1 + ...2e361.4964adb3.js => 5232e361.f2d19c79.js} | 2 +- en/assets/js/547263ca.4718f7fc.js | 1 + ...49b6f.ef2fa283.js => 59049b6f.29d62e1d.js} | 2 +- en/assets/js/6ae2e228.7d35a4ec.js | 1 - en/assets/js/6ae2e228.fb691229.js | 1 + en/assets/js/79cd14f8.618f3b79.js | 1 - en/assets/js/79cd14f8.cf99df66.js | 1 + ...e3e9a.d07a8e10.js => 80ce3e9a.b70e3d5c.js} | 2 +- en/assets/js/814f3328.2e0d4a65.js | 1 + en/assets/js/814f3328.e5b936cc.js | 1 - ...91fce.c91eaa39.js => 99391fce.917bad29.js} | 2 +- en/assets/js/9c96fb51.25ebc2d1.js | 1 + en/assets/js/9fffc702.2b93336d.js | 1 + en/assets/js/9fffc702.3ce35276.js | 1 - ...03efb.6191ac20.js => c1a03efb.489a07dd.js} | 2 +- ...b4cc7.2d4cea2c.js => d81b4cc7.c8382878.js} | 2 +- en/assets/js/main.458346e8.js | 2 ++ ...CENSE.txt => main.458346e8.js.LICENSE.txt} | 0 en/assets/js/main.f8e4fa24.js | 2 -- en/assets/js/runtime~main.1fa83d2c.js | 1 - en/assets/js/runtime~main.a6b056f7.js | 1 + en/atom.xml | 20 +++++++++++++++++- .../index.html" | 10 ++++----- .../index.html | 10 ++++----- en/criando-atalhos-para-o-git/index.html | 10 ++++----- .../index.html | 10 ++++----- en/img/peace.jpg | Bin 0 -> 112380 bytes en/index.html | 10 ++++----- .../index.html | 18 ++++++++++++++++ .../index.html" | 10 ++++----- en/rss.xml | 16 +++++++++++++- en/sitemap.xml | 2 +- en/tags/a-importancia-da-educacao/index.html | 10 ++++----- en/tags/aliases/index.html | 10 ++++----- en/tags/aprendizado/index.html | 10 ++++----- en/tags/carreira/index.html | 12 +++++------ en/tags/cobertura/index.html | 10 ++++----- en/tags/dicas/index.html | 12 +++++------ en/tags/educacao/index.html | 10 ++++----- en/tags/entrevista/index.html | 10 ++++----- en/tags/every/index.html | 10 ++++----- en/tags/git/index.html | 10 ++++----- en/tags/index.html | 10 ++++----- en/tags/javascript/index.html | 10 ++++----- en/tags/negociar/index.html | 18 ++++++++++++++++ en/tags/prazos/index.html | 18 ++++++++++++++++ en/tags/produtividade/index.html | 10 ++++----- en/tags/qualidade/index.html | 12 +++++------ en/tags/snippets/index.html | 10 ++++----- en/tags/tdd/index.html | 10 ++++----- en/tags/teste-unitario/index.html | 10 ++++----- en/tags/teste/index.html | 10 ++++----- en/tags/testes-automatizados/index.html | 10 ++++----- en/tags/testes/index.html | 12 +++++------ en/tags/validador/index.html | 10 ++++----- en/tags/vitest/index.html | 10 ++++----- en/tags/vscode/index.html | 10 ++++----- img/peace.jpg | Bin 0 -> 112380 bytes index.html | 10 ++++----- .../index.html | 18 ++++++++++++++++ .../index.html" | 10 ++++----- rss.xml | 16 +++++++++++++- sitemap.xml | 2 +- tags/a-importancia-da-educacao/index.html | 10 ++++----- tags/aliases/index.html | 10 ++++----- tags/aprendizado/index.html | 10 ++++----- tags/carreira/index.html | 12 +++++------ tags/cobertura/index.html | 10 ++++----- tags/dicas/index.html | 12 +++++------ tags/educacao/index.html | 10 ++++----- tags/entrevista/index.html | 10 ++++----- tags/every/index.html | 10 ++++----- tags/git/index.html | 10 ++++----- tags/index.html | 10 ++++----- tags/javascript/index.html | 10 ++++----- tags/negociar/index.html | 18 ++++++++++++++++ tags/prazos/index.html | 18 ++++++++++++++++ tags/produtividade/index.html | 10 ++++----- tags/qualidade/index.html | 12 +++++------ tags/snippets/index.html | 10 ++++----- tags/tdd/index.html | 10 ++++----- tags/teste-unitario/index.html | 10 ++++----- tags/teste/index.html | 10 ++++----- tags/testes-automatizados/index.html | 10 ++++----- tags/testes/index.html | 12 +++++------ tags/validador/index.html | 10 ++++----- tags/vitest/index.html | 10 ++++----- tags/vscode/index.html | 10 ++++----- 128 files changed, 558 insertions(+), 378 deletions(-) rename assets/js/{12fc2115.b328678d.js => 12fc2115.de73d99a.js} (78%) create mode 100644 assets/js/2c46ef68.44f7a85e.js create mode 100644 assets/js/3234bd47.cd43694f.js create mode 100644 assets/js/378ebcfd.25503ea2.js create mode 100644 assets/js/3fe1affd.90cdc07b.js rename assets/js/{44176adc.82c15e01.js => 44176adc.f0e6558e.js} (83%) create mode 100644 assets/js/6ae2e228.171f296a.js delete mode 100644 assets/js/6ae2e228.b733cf1a.js delete mode 100644 assets/js/814f3328.1391f7a7.js create mode 100644 assets/js/814f3328.3433abcc.js rename assets/js/{816d8f45.b9adc77d.js => 816d8f45.3a123ab7.js} (79%) rename assets/js/{a5f84eec.f5dfab6a.js => a5f84eec.5b0a9bf9.js} (82%) create mode 100644 assets/js/a7023ddc.af52f977.js delete mode 100644 assets/js/a7023ddc.eb9f6974.js rename assets/js/{ae80d8f5.27176f2d.js => ae80d8f5.8e669ca3.js} (81%) delete mode 100644 assets/js/b2f554cd.450bf15b.js create mode 100644 assets/js/b2f554cd.58e375fe.js rename assets/js/{d81b4cc7.45e9d7da.js => d81b4cc7.1eeaa3e6.js} (75%) create mode 100644 assets/js/main.38da634c.js rename assets/js/{main.56ada70d.js.LICENSE.txt => main.38da634c.js.LICENSE.txt} (100%) delete mode 100644 assets/js/main.56ada70d.js delete mode 100644 assets/js/runtime~main.21caba00.js create mode 100644 assets/js/runtime~main.392caf8c.js create mode 100644 en/assets/js/2c46ef68.be6839a2.js create mode 100644 en/assets/js/378ebcfd.6727b4d6.js rename en/assets/js/{5232e361.4964adb3.js => 5232e361.f2d19c79.js} (75%) create mode 100644 en/assets/js/547263ca.4718f7fc.js rename en/assets/js/{59049b6f.ef2fa283.js => 59049b6f.29d62e1d.js} (79%) delete mode 100644 en/assets/js/6ae2e228.7d35a4ec.js create mode 100644 en/assets/js/6ae2e228.fb691229.js delete mode 100644 en/assets/js/79cd14f8.618f3b79.js create mode 100644 en/assets/js/79cd14f8.cf99df66.js rename en/assets/js/{80ce3e9a.d07a8e10.js => 80ce3e9a.b70e3d5c.js} (78%) create mode 100644 en/assets/js/814f3328.2e0d4a65.js delete mode 100644 en/assets/js/814f3328.e5b936cc.js rename en/assets/js/{99391fce.c91eaa39.js => 99391fce.917bad29.js} (76%) create mode 100644 en/assets/js/9c96fb51.25ebc2d1.js create mode 100644 en/assets/js/9fffc702.2b93336d.js delete mode 100644 en/assets/js/9fffc702.3ce35276.js rename en/assets/js/{c1a03efb.6191ac20.js => c1a03efb.489a07dd.js} (83%) rename en/assets/js/{d81b4cc7.2d4cea2c.js => d81b4cc7.c8382878.js} (75%) create mode 100644 en/assets/js/main.458346e8.js rename en/assets/js/{main.f8e4fa24.js.LICENSE.txt => main.458346e8.js.LICENSE.txt} (100%) delete mode 100644 en/assets/js/main.f8e4fa24.js delete mode 100644 en/assets/js/runtime~main.1fa83d2c.js create mode 100644 en/assets/js/runtime~main.a6b056f7.js create mode 100644 en/img/peace.jpg create mode 100644 en/nao-espere-um-ambiente-favoravel-para-fazer-algo-com-qualidade/index.html create mode 100644 en/tags/negociar/index.html create mode 100644 en/tags/prazos/index.html create mode 100644 img/peace.jpg create mode 100644 nao-espere-um-ambiente-favoravel-para-fazer-algo-com-qualidade/index.html create mode 100644 tags/negociar/index.html create mode 100644 tags/prazos/index.html diff --git a/404.html b/404.html index 336dbd8..bd58277 100644 --- a/404.html +++ b/404.html @@ -6,13 +6,13 @@ Página não encontrada | Blog Matheus Brunelli - - + +
Pular para o conteúdo principal

Página não encontrada

Não foi possível encontrar o que você está procurando.

Entre em contato com o proprietário do site que lhe trouxe para cá e lhe informe que o link está quebrado.

- - + + \ No newline at end of file diff --git a/aprenda-a-criar-snippets-no-vscode/index.html b/aprenda-a-criar-snippets-no-vscode/index.html index 6088b05..dbd6309 100644 --- a/aprenda-a-criar-snippets-no-vscode/index.html +++ b/aprenda-a-criar-snippets-no-vscode/index.html @@ -6,14 +6,14 @@ Aprenda a criar snippets no VS Code | Blog Matheus Brunelli - - + +
-
Pular para o conteúdo principal

Aprenda a criar snippets no VS Code

· Leitura de 3 minutos
Matheus R. Brunelli

Salve galera, tudo bem?

Hoje quero compartilhar com vocês algo bem bacana, que é criar seus próprios snippets no VS Code.

O que é um Snippet?

Um atalho

Nada mais é que um atalho para a criação de um trecho de código. Pense em um código simples como esse:

Lógica de um loop no Javascript
for (const item of items) {
console.log(item);
}

Esse tipo de código tende a se repetir muito durante nosso desenvolvimento rotineiro. Com isso, pode ficar chato escrever a mesma sintaxe toda vez.

Produtividade

É ai que a mágica acontece! Que tal digitiar apenas newfor e o VS Code criá-lo para você? Sim é possível!

Vamos começar

Primeiro passo

Vamos criar o arquivo principal para nossos snippets.

Com seu VS Code aberto, digite Ctrl+Shift+P e digite snippets na barra que apareceu, selecione a opção Preferences: Configure User Snippets e depois New Global Snippet File.

Abrirá uma caixinha para você digitar o nome do seu arquivo de snippets. Você pode colocar qualquer nome, eu vou colocar my-snippets.

Segundo passo

Vai abrir um arquivo mais ou menos assim:

my-snippets.code-snippets
{
// Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
// "Print to console": {
// "scope": "javascript,typescript",
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
}

Apague tudo e monte essa estrutura:

my-snippets.code-snippets
{
"newfor": {
"scope": "",
"prefix": "",
"body": [],
"description": ""
}
}

Significado de cada atributo

  • newfor: é o nome do nosso snippet
  • scope: em quais tipos de arquivos seu snippet executará
  • prefix: atalho para seu snippet
  • body: linhas que seu snippet irá gerar
  • description: descrição do que seu snippet irá gerar (não obrigatório)

Terceiro passo

Agora que sabemos o que cada campo significa, vamos preenche-los com nosso código:

my-snippets.code-snippets
{
"newfor": {
"scope": "javascript, typescript",
"prefix": "newfor",
"body": ["for (const item of items) {", "console.log(item)", "}"],
"description": "cria um loop com for"
}
}

Quarto passo

Pronto, salve o seu arquivo de snippet, vá para um arquivo .js ou .ts e faça o teste. Digite newfor e aperte Ctrl+ Space bar.

Deverá aparecer o nome do seu snippet no autocomplete, dessa forma: +

Aprenda a criar snippets no VS Code

· Leitura de 3 minutos
Matheus R. Brunelli

Salve galera, tudo bem?

Hoje quero compartilhar com vocês algo bem bacana, que é criar seus próprios snippets no VS Code.

O que é um Snippet?

Um atalho

Nada mais é que um atalho para a criação de um trecho de código. Pense em um código simples como esse:

Lógica de um loop no Javascript
for (const item of items) {
console.log(item);
}

Esse tipo de código tende a se repetir muito durante nosso desenvolvimento rotineiro. Com isso, pode ficar chato escrever a mesma sintaxe toda vez.

Produtividade

É ai que a mágica acontece! Que tal digitiar apenas newfor e o VS Code criá-lo para você? Sim é possível!

Vamos começar

Primeiro passo

Vamos criar o arquivo principal para nossos snippets.

Com seu VS Code aberto, digite Ctrl+Shift+P e digite snippets na barra que apareceu, selecione a opção Preferences: Configure User Snippets e depois New Global Snippet File.

Abrirá uma caixinha para você digitar o nome do seu arquivo de snippets. Você pode colocar qualquer nome, eu vou colocar my-snippets.

Segundo passo

Vai abrir um arquivo mais ou menos assim:

my-snippets.code-snippets
{
// Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
// "Print to console": {
// "scope": "javascript,typescript",
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
}

Apague tudo e monte essa estrutura:

my-snippets.code-snippets
{
"newfor": {
"scope": "",
"prefix": "",
"body": [],
"description": ""
}
}

Significado de cada atributo

  • newfor: é o nome do nosso snippet
  • scope: em quais tipos de arquivos seu snippet executará
  • prefix: atalho para seu snippet
  • body: linhas que seu snippet irá gerar
  • description: descrição do que seu snippet irá gerar (não obrigatório)

Terceiro passo

Agora que sabemos o que cada campo significa, vamos preenche-los com nosso código:

my-snippets.code-snippets
{
"newfor": {
"scope": "javascript, typescript",
"prefix": "newfor",
"body": ["for (const item of items) {", "console.log(item)", "}"],
"description": "cria um loop com for"
}
}

Quarto passo

Pronto, salve o seu arquivo de snippet, vá para um arquivo .js ou .ts e faça o teste. Digite newfor e aperte Ctrl+ Space bar.

Deverá aparecer o nome do seu snippet no autocomplete, dessa forma:

Só apertar Enter que seu código será gerado. Legal né?

Conclusão

Caso você tenha chegado até aqui e não tenha funcionado, volte desde o começo e tente novamente com calma, você deve ter deixado algo passar. É bem simples.

Espero que tenha gostado! Se foi útil para você, compartilhe com seus amigos e colegas de trabalho!

Até a próxima!

- - + + \ No newline at end of file diff --git a/aprenda-a-testar-pt1/index.html b/aprenda-a-testar-pt1/index.html index 4a24513..bcac91a 100644 --- a/aprenda-a-testar-pt1/index.html +++ b/aprenda-a-testar-pt1/index.html @@ -6,13 +6,13 @@ Aprenda a escrever testes - Parte 1 | Blog Matheus Brunelli - - + +
-

Aprenda a escrever testes - Parte 1

· Leitura de 4 minutos
Matheus R. Brunelli

Para que servem os testes? Como faço para escrever um teste? Esse tema ainda pode ser muito confuso para quem está começando a programar, e até para quem já possuí mais tempo de estrada.

Afinal, para que servem os testes?

Antes de responder essa pergunta, vamos entender de que testes estamos falando. A primeira coisa que me vem a mente quando alguém me pede para testar a aplicação é: executar a aplicação e fazer alguma ação e ver se o resultado esperado foi alcançado.

Esse conceito está correto, e de fato isso é "testar a aplicação". Entretanto uma aplicação irá conter muitos recursos, que se forem testadas de forma manual, levará muito tempo e desgastará quem está testando. Também haverá possibilidades de erros humanos durante esse processo.

Testes automatizados

Para isso existem os testes automatizados, que é uma forma de executar um script que irá testar todas as ações da aplicação, de forma automática, simulando a interação humana e observando se o resultado esperado foi alcaçado.

Os benefícios dessa prática são muitos, visto que, se o teste é automatizado, posso executá-lo e assim esperar para ver se todas as funcionalidades do sistema ainda estão ok e se comportando como deveriam. Dessa forma é possível simular toda a interação humana em todos os módulos do sistema, e em poucos segundos.

Requisitos para escrever um teste

Primeiramente devemos entender as regras de negócio da aplicação, e saber como devem se comportar em diferentes situações.

Vamos supor que nosso sistema recebe dois números e retorna a soma desses números para o usuário. Para escrever um teste em cima dessa funcionalidade, deveremos prover dois números de entrada e observar se o valor retornado é a soma dos dois números fornecidos. Se o resultado de fato for a soma dos dois números fornecidos, então o teste passará, do contrário ele reprovará.

Exemplo 1

calculadora.ts
export class Calculadora {
somar(numero1: number, numero2: number) {
return numero1 + numero2;
}
}
calculadora.test.ts
import { Calculadora } from "./calculadora";

test("Deve somar 10 + 10 e retornar 20", () => {
const calculadora = new Calculadora();
const resultado = calculadora.somar(10, 10);

expect(resultado).toBe(20); // true, logo o teste passará.
});

Exemplo 2

Agora, se eu alterar a regra de negócios do método somar, e fazê-lo retornar a multiplicação ao invés da soma, nosso teste irá reprovar, pois ele espera que o resultado seja 20 e não 100.

calculadora.ts
export class Calculadora {
somar(numero1: number, numero2: number) {
return numero1 * numero2;
}
}
calculadora.test.ts
import { Calculadora } from "./calculadora";

test("Deve somar 10 + 10 e retornar 20", () => {
const calculadora = new Calculadora();
const resultado = calculadora.somar(10, 10);

console.log(resultado); // 100

expect(resultado).toBe(20); // 100 != 20, logo é false, o teste reprovará.
});

O que eu devo testar?

Posso testar as regras de negócio de uma classe (unidade), a integração de um serviço com o banco de dados (integração) e o comportamento geral do sistema (de ponta a ponta).

Logo temos testes de unidade, testes de integração e testes de ponta a ponta.

Para que haja uma excelente cobertura, devemos utilizar todos esses tipos de testes. Alguns desenvolvedores optam por utilizar apenas um desses tipos de testes, o que pode resultar em uma ou várias lacunas na cobertura do sistema.

Resumo

  • Testar é executar uma ação no sistema e observar se o resultado obtivo é de fato esperado.
  • Testes automatizados excluem a necessidade de testes humanos e manuais.
  • Os tipos de testes são: unidade, integração e de ponta a ponta.
  • Testar garante que o comportamento do sistema será preservado. Em caso de quebra, os testes avisarão onde ocorreu a quebra.
  • Se um sistema não possuí testes automatizados, não há como o desenvolvedor saber se a alteração que ele fez quebrou o sistema. Ele terá que testar manualmente, e em muitos dos casos poderão ocorrer falhas humanas e o sistema poderá ir para produção com defeito (em muitos casos isso pode significar prejuízo financeiro para a empresa, e até falência da mesma).

Repositório com o código

https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-1

- - +

Aprenda a escrever testes - Parte 1

· Leitura de 4 minutos
Matheus R. Brunelli

Para que servem os testes? Como faço para escrever um teste? Esse tema ainda pode ser muito confuso para quem está começando a programar, e até para quem já possuí mais tempo de estrada.

Afinal, para que servem os testes?

Antes de responder essa pergunta, vamos entender de que testes estamos falando. A primeira coisa que me vem a mente quando alguém me pede para testar a aplicação é: executar a aplicação e fazer alguma ação e ver se o resultado esperado foi alcançado.

Esse conceito está correto, e de fato isso é "testar a aplicação". Entretanto uma aplicação irá conter muitos recursos, que se forem testadas de forma manual, levará muito tempo e desgastará quem está testando. Também haverá possibilidades de erros humanos durante esse processo.

Testes automatizados

Para isso existem os testes automatizados, que é uma forma de executar um script que irá testar todas as ações da aplicação, de forma automática, simulando a interação humana e observando se o resultado esperado foi alcaçado.

Os benefícios dessa prática são muitos, visto que, se o teste é automatizado, posso executá-lo e assim esperar para ver se todas as funcionalidades do sistema ainda estão ok e se comportando como deveriam. Dessa forma é possível simular toda a interação humana em todos os módulos do sistema, e em poucos segundos.

Requisitos para escrever um teste

Primeiramente devemos entender as regras de negócio da aplicação, e saber como devem se comportar em diferentes situações.

Vamos supor que nosso sistema recebe dois números e retorna a soma desses números para o usuário. Para escrever um teste em cima dessa funcionalidade, deveremos prover dois números de entrada e observar se o valor retornado é a soma dos dois números fornecidos. Se o resultado de fato for a soma dos dois números fornecidos, então o teste passará, do contrário ele reprovará.

Exemplo 1

calculadora.ts
export class Calculadora {
somar(numero1: number, numero2: number) {
return numero1 + numero2;
}
}
calculadora.test.ts
import { Calculadora } from "./calculadora";

test("Deve somar 10 + 10 e retornar 20", () => {
const calculadora = new Calculadora();
const resultado = calculadora.somar(10, 10);

expect(resultado).toBe(20); // true, logo o teste passará.
});

Exemplo 2

Agora, se eu alterar a regra de negócios do método somar, e fazê-lo retornar a multiplicação ao invés da soma, nosso teste irá reprovar, pois ele espera que o resultado seja 20 e não 100.

calculadora.ts
export class Calculadora {
somar(numero1: number, numero2: number) {
return numero1 * numero2;
}
}
calculadora.test.ts
import { Calculadora } from "./calculadora";

test("Deve somar 10 + 10 e retornar 20", () => {
const calculadora = new Calculadora();
const resultado = calculadora.somar(10, 10);

console.log(resultado); // 100

expect(resultado).toBe(20); // 100 != 20, logo é false, o teste reprovará.
});

O que eu devo testar?

Posso testar as regras de negócio de uma classe (unidade), a integração de um serviço com o banco de dados (integração) e o comportamento geral do sistema (de ponta a ponta).

Logo temos testes de unidade, testes de integração e testes de ponta a ponta.

Para que haja uma excelente cobertura, devemos utilizar todos esses tipos de testes. Alguns desenvolvedores optam por utilizar apenas um desses tipos de testes, o que pode resultar em uma ou várias lacunas na cobertura do sistema.

Resumo

  • Testar é executar uma ação no sistema e observar se o resultado obtivo é de fato esperado.
  • Testes automatizados excluem a necessidade de testes humanos e manuais.
  • Os tipos de testes são: unidade, integração e de ponta a ponta.
  • Testar garante que o comportamento do sistema será preservado. Em caso de quebra, os testes avisarão onde ocorreu a quebra.
  • Se um sistema não possuí testes automatizados, não há como o desenvolvedor saber se a alteração que ele fez quebrou o sistema. Ele terá que testar manualmente, e em muitos dos casos poderão ocorrer falhas humanas e o sistema poderá ir para produção com defeito (em muitos casos isso pode significar prejuízo financeiro para a empresa, e até falência da mesma).

Repositório com o código

https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-1

+ + \ No newline at end of file diff --git a/aprenda-a-testar-pt2/index.html b/aprenda-a-testar-pt2/index.html index 3419f89..fc8bed3 100644 --- a/aprenda-a-testar-pt2/index.html +++ b/aprenda-a-testar-pt2/index.html @@ -6,13 +6,13 @@ Aprenda a escrever testes - Parte 2 | Blog Matheus Brunelli - - + +
-

Aprenda a escrever testes - Parte 2

· Leitura de 5 minutos
Matheus R. Brunelli

Como configurar e utilizar um framework de testes no Node utilizando Typescript? Temos várias opções excelentes para isso, e por esse motivo irei escolher a mais fácil para o cenário de Node + Typescript.

Como escolher um framework de testes?

Primeiro devo avaliar quais os cenários quero testar, se é frontend ou backend, e se vou utilizar Javascript ou Typescript.

Vou utilizar Node + Typescript nos exemplos, e isso faz a minha lista ficar restrita a alguns nomes:

Jest e Mocha necessitam de um parser de Typescript para executar, como o ts-jest ou ts-node, o que pode complicar para quem está começando, já que o arquivo de configuração fica muito complexo nesses cenários.

Não quero abrir mão do Typescript e nem da facilidade de configuração, então irei escolher o Vitest. Na página inicial do Vitest contém o Get Started contendo alguns exemplos de instalação e configuração.

Configurando o projeto

Setup Node + Typescript

Vou criar uma pasta vazia, com um nome qualquer.

mkdir vitest-typescript-example

Com o meu Visual Studio Code aberto nessa pasta, vou abrir um terminal integrado e iniciar o Node, e instalar as dependências básicas para o Typescript funcionar.

npm init -y

npm install -D typescript @types/node

Agora vou criar o tsconfig.json, que é o arquivo de configuração do Typescript. Ele irá gerar uma configuração default, e vou manter ela.

npx tsc --init

Pronto, meu projeto já está configurado com Node + Typescript.

Setup Vitest

Agora vou instalar o Vitest como dependência de desenvolvimento.

npm install -D vitest

O Vitest precisa de um arquivo de configuração para poder executar. Na própria documentação tem um exemplo simples. Vou criar um arquivo vitest.config.ts na raiz, e adicionar a configuração básica.

vitest.config.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
reporters: "verbose",
},
});

Veja como o arquivo de configuração é enxuto, bem diferente dos outros frameworks citados no começo do post. Na documentação tenho acesso a API, e como posso personalizar o defineConfig(). Não vou configurar nada extra, já está ótimo como está.

Veja que configurei reporters como verbose, isso para que eu possa obter todas as informações do teste no terminal.

Configurando o package.json

Quando eu executei o npm init -y, foi gerado um arquivo package.json na raiz, com algumas configurações bem simples. Dentro de scripts tem um script test. Vou editá-lo.

package.json
...
"scripts": {
"test": "vitest --run"
}
...

Agora quando eu executar npm run test no terminal, o vitest irá executar meus testes. Como não temos nenhum teste no momento, ele tentará rodar e retornará um erro dizendo que nenhum teste foi encontrado.

Escrevendo o primeiro teste

Vou criar uma pasta test na raiz, e criar um arquivo chamado primeiro-teste.test.ts dentro dela. Em seguida irei adicionar alguns cenários.

É importante respeitar a extensão .test.ts, pois o Vitest procura por essa extensão durante a execução.

primeiro-teste.test.ts
import { describe, test, expect } from "vitest";

describe("Contém um conjunto de testes, que será executado um a um", () => {
test("Deve somar 20 + 50 e retornar 70", () => {
expect(20 + 50).toBe(70);
});

test("Deve concatenar a palavra 'Olá' com a palavra 'Mundo' e retornar 'Olá Mundo'", () => {
expect("Olá " + "Mundo").toBe("Olá Mundo");
});

test("Deve retornar que o Palmeiras não tem mundial", () => {
const temMundial = false;
expect(temMundial).toBeFalsy();
});

test("Deve conter todos os valores do objeto fornecido", () => {
const meuObjeto = {
nome: "Palmeiras",
temMundial: false,
cor: "Verde",
};
expect(meuObjeto).toEqual({
nome: "Palmeiras",
temMundial: false,
cor: "Verde",
});
});
});

Agora vou abrir o terminal e executar npm run test, e o Vitest irá executar e retornar todos esses cenários no terminal, verde caso tenha passado, e vermelho caso tenha reprovado algum.

Sucesso

Erro

Adicionei um campo a mais no objeto do último teste, porém não adicionei no expect, logo o teste fez a comparação e reprovou, pois os objetos não são mais iguais.

Veja como a inteface é amigável, ela exibe com muita clareza qual teste reprovou e o motivo.

Resumo

  • Preciso saber em qual cenário vou escrever meus testes, se é frontend ou backend, pois cada um possuí a ferramenta certa para o cenário.
  • Se eu ainda não sei testar, devo procurar o framework mais fácil para aprender. Nesse caso foi o Vitest, pois ele tem uma filosofia less config.
  • A documentação contém tudo que preciso para configurar o framework, e ainda contém vários exemplos.
  • O Vitest procura por arquivos que tenham a extensão .test.ts.
  • Os resultados dos testes são exibidos no terminal, de uma forma muito amigável.
  • Posso executar o comando npm run test quantas vezes quiser, e o teste executará em milésimos de segundos.
  • Automatizar é bem melhor que testar manualmente.

Repositório com o código

https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-2

- - +
Pular para o conteúdo principal

Aprenda a escrever testes - Parte 2

· Leitura de 5 minutos
Matheus R. Brunelli

Como configurar e utilizar um framework de testes no Node utilizando Typescript? Temos várias opções excelentes para isso, e por esse motivo irei escolher a mais fácil para o cenário de Node + Typescript.

Como escolher um framework de testes?

Primeiro devo avaliar quais os cenários quero testar, se é frontend ou backend, e se vou utilizar Javascript ou Typescript.

Vou utilizar Node + Typescript nos exemplos, e isso faz a minha lista ficar restrita a alguns nomes:

Jest e Mocha necessitam de um parser de Typescript para executar, como o ts-jest ou ts-node, o que pode complicar para quem está começando, já que o arquivo de configuração fica muito complexo nesses cenários.

Não quero abrir mão do Typescript e nem da facilidade de configuração, então irei escolher o Vitest. Na página inicial do Vitest contém o Get Started contendo alguns exemplos de instalação e configuração.

Configurando o projeto

Setup Node + Typescript

Vou criar uma pasta vazia, com um nome qualquer.

mkdir vitest-typescript-example

Com o meu Visual Studio Code aberto nessa pasta, vou abrir um terminal integrado e iniciar o Node, e instalar as dependências básicas para o Typescript funcionar.

npm init -y

npm install -D typescript @types/node

Agora vou criar o tsconfig.json, que é o arquivo de configuração do Typescript. Ele irá gerar uma configuração default, e vou manter ela.

npx tsc --init

Pronto, meu projeto já está configurado com Node + Typescript.

Setup Vitest

Agora vou instalar o Vitest como dependência de desenvolvimento.

npm install -D vitest

O Vitest precisa de um arquivo de configuração para poder executar. Na própria documentação tem um exemplo simples. Vou criar um arquivo vitest.config.ts na raiz, e adicionar a configuração básica.

vitest.config.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
reporters: "verbose",
},
});

Veja como o arquivo de configuração é enxuto, bem diferente dos outros frameworks citados no começo do post. Na documentação tenho acesso a API, e como posso personalizar o defineConfig(). Não vou configurar nada extra, já está ótimo como está.

Veja que configurei reporters como verbose, isso para que eu possa obter todas as informações do teste no terminal.

Configurando o package.json

Quando eu executei o npm init -y, foi gerado um arquivo package.json na raiz, com algumas configurações bem simples. Dentro de scripts tem um script test. Vou editá-lo.

package.json
...
"scripts": {
"test": "vitest --run"
}
...

Agora quando eu executar npm run test no terminal, o vitest irá executar meus testes. Como não temos nenhum teste no momento, ele tentará rodar e retornará um erro dizendo que nenhum teste foi encontrado.

Escrevendo o primeiro teste

Vou criar uma pasta test na raiz, e criar um arquivo chamado primeiro-teste.test.ts dentro dela. Em seguida irei adicionar alguns cenários.

É importante respeitar a extensão .test.ts, pois o Vitest procura por essa extensão durante a execução.

primeiro-teste.test.ts
import { describe, test, expect } from "vitest";

describe("Contém um conjunto de testes, que será executado um a um", () => {
test("Deve somar 20 + 50 e retornar 70", () => {
expect(20 + 50).toBe(70);
});

test("Deve concatenar a palavra 'Olá' com a palavra 'Mundo' e retornar 'Olá Mundo'", () => {
expect("Olá " + "Mundo").toBe("Olá Mundo");
});

test("Deve retornar que o Palmeiras não tem mundial", () => {
const temMundial = false;
expect(temMundial).toBeFalsy();
});

test("Deve conter todos os valores do objeto fornecido", () => {
const meuObjeto = {
nome: "Palmeiras",
temMundial: false,
cor: "Verde",
};
expect(meuObjeto).toEqual({
nome: "Palmeiras",
temMundial: false,
cor: "Verde",
});
});
});

Agora vou abrir o terminal e executar npm run test, e o Vitest irá executar e retornar todos esses cenários no terminal, verde caso tenha passado, e vermelho caso tenha reprovado algum.

Sucesso

Erro

Adicionei um campo a mais no objeto do último teste, porém não adicionei no expect, logo o teste fez a comparação e reprovou, pois os objetos não são mais iguais.

Veja como a inteface é amigável, ela exibe com muita clareza qual teste reprovou e o motivo.

Resumo

  • Preciso saber em qual cenário vou escrever meus testes, se é frontend ou backend, pois cada um possuí a ferramenta certa para o cenário.
  • Se eu ainda não sei testar, devo procurar o framework mais fácil para aprender. Nesse caso foi o Vitest, pois ele tem uma filosofia less config.
  • A documentação contém tudo que preciso para configurar o framework, e ainda contém vários exemplos.
  • O Vitest procura por arquivos que tenham a extensão .test.ts.
  • Os resultados dos testes são exibidos no terminal, de uma forma muito amigável.
  • Posso executar o comando npm run test quantas vezes quiser, e o teste executará em milésimos de segundos.
  • Automatizar é bem melhor que testar manualmente.

Repositório com o código

https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-2

+ + \ No newline at end of file diff --git a/archive/index.html b/archive/index.html index be0ce65..930735e 100644 --- a/archive/index.html +++ b/archive/index.html @@ -6,13 +6,13 @@ Arquivo | Blog Matheus Brunelli - - + + - - +
Pular para o conteúdo principal
+ + \ No newline at end of file diff --git a/assets/js/12fc2115.b328678d.js b/assets/js/12fc2115.de73d99a.js similarity index 78% rename from assets/js/12fc2115.b328678d.js rename to assets/js/12fc2115.de73d99a.js index 6c614e7..176ed59 100644 --- a/assets/js/12fc2115.b328678d.js +++ b/assets/js/12fc2115.de73d99a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkblog=self.webpackChunkblog||[]).push([[1238],{7957:function(a){a.exports=JSON.parse('{"allTagsPath":"/blog/tags","slug":"/blog/tags/qualidade","name":"qualidade","count":2,"permalink":"/blog/tags/qualidade"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkblog=self.webpackChunkblog||[]).push([[1238],{7957:function(a){a.exports=JSON.parse('{"allTagsPath":"/blog/tags","slug":"/blog/tags/qualidade","name":"qualidade","count":3,"permalink":"/blog/tags/qualidade"}')}}]); \ No newline at end of file diff --git a/assets/js/2c46ef68.44f7a85e.js b/assets/js/2c46ef68.44f7a85e.js new file mode 100644 index 0000000..711a5d0 --- /dev/null +++ b/assets/js/2c46ef68.44f7a85e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkblog=self.webpackChunkblog||[]).push([[3485],{3905:function(e,a,o){o.d(a,{Zo:function(){return c},kt:function(){return p}});var r=o(7294);function t(e,a,o){return a in e?Object.defineProperty(e,a,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[a]=o,e}function n(e,a){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);a&&(r=r.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),o.push.apply(o,r)}return o}function i(e){for(var a=1;a=0||(t[o]=e[o]);return t}(e,a);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(t[o]=e[o])}return t}var l=r.createContext({}),m=function(e){var a=r.useContext(l),o=a;return e&&(o="function"==typeof e?e(a):i(i({},a),e)),o},c=function(e){var a=m(e.components);return r.createElement(l.Provider,{value:a},e.children)},u={inlineCode:"code",wrapper:function(e){var a=e.children;return r.createElement(r.Fragment,{},a)}},d=r.forwardRef((function(e,a){var o=e.components,t=e.mdxType,n=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=m(o),p=t,g=d["".concat(l,".").concat(p)]||d[p]||u[p]||n;return o?r.createElement(g,i(i({ref:a},c),{},{components:o})):r.createElement(g,i({ref:a},c))}));function p(e,a){var o=arguments,t=a&&a.mdxType;if("string"==typeof e||t){var n=o.length,i=new Array(n);i[0]=d;var s={};for(var l in a)hasOwnProperty.call(a,l)&&(s[l]=a[l]);s.originalType=e,s.mdxType="string"==typeof e?e:t,i[1]=s;for(var m=2;m=0||(o[r]=e[r]);return o}(e,a);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=t.createContext({}),s=function(e){var a=t.useContext(u),r=a;return e&&(r="function"==typeof e?e(a):l(l({},a),e)),r},c=function(e){var a=s(e.components);return t.createElement(u.Provider,{value:a},e.children)},p={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},m=t.forwardRef((function(e,a){var r=e.components,o=e.mdxType,n=e.originalType,u=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),m=s(r),d=o,f=m["".concat(u,".").concat(d)]||m[d]||p[d]||n;return r?t.createElement(f,l(l({ref:a},c),{},{components:r})):t.createElement(f,l({ref:a},c))}));function d(e,a){var r=arguments,o=a&&a.mdxType;if("string"==typeof e||o){var n=r.length,l=new Array(n);l[0]=m;var i={};for(var u in a)hasOwnProperty.call(a,u)&&(i[u]=a[u]);i.originalType=e,i.mdxType="string"==typeof e?e:o,l[1]=i;for(var s=2;s=0||(t[r]=e[r]);return t}(e,a);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var l=o.createContext({}),c=function(e){var a=o.useContext(l),r=a;return e&&(r="function"==typeof e?e(a):n(n({},a),e)),r},u=function(e){var a=c(e.components);return o.createElement(l.Provider,{value:a},e.children)},m={inlineCode:"code",wrapper:function(e){var a=e.children;return o.createElement(o.Fragment,{},a)}},d=o.forwardRef((function(e,a){var r=e.components,t=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(r),p=t,v=d["".concat(l,".").concat(p)]||d[p]||m[p]||s;return r?o.createElement(v,n(n({ref:a},u),{},{components:r})):o.createElement(v,n({ref:a},u))}));function p(e,a){var r=arguments,t=a&&a.mdxType;if("string"==typeof e||t){var s=r.length,n=new Array(s);n[0]=d;var i={};for(var l in a)hasOwnProperty.call(a,l)&&(i[l]=a[l]);i.originalType=e,i.mdxType="string"==typeof e?e:t,n[1]=i;for(var c=2;c=0||(o[r]=e[r]);return o}(e,a);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=t.createContext({}),c=function(e){var a=t.useContext(l),r=a;return e&&(r="function"==typeof e?e(a):n(n({},a),e)),r},u=function(e){var a=c(e.components);return t.createElement(l.Provider,{value:a},e.children)},m={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},d=t.forwardRef((function(e,a){var r=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(r),p=o,v=d["".concat(l,".").concat(p)]||d[p]||m[p]||s;return r?t.createElement(v,n(n({ref:a},u),{},{components:r})):t.createElement(v,n({ref:a},u))}));function p(e,a){var r=arguments,o=a&&a.mdxType;if("string"==typeof e||o){var s=r.length,n=new Array(s);n[0]=d;var i={};for(var l in a)hasOwnProperty.call(a,l)&&(i[l]=a[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,n[1]=i;for(var c=2;c Jest e Mocha necessitam de um parser de Typescript para executar, como o ts-jest ou ts-node, o que pode complicar para quem est\xe1 come\xe7ando, j\xe1 que o arquivo de configura\xe7\xe3o fica muito complexo nesses cen\xe1rios.\\n\\nN\xe3o quero abrir m\xe3o do Typescript e nem da facilidade de configura\xe7\xe3o, ent\xe3o irei escolher o Vitest. Na p\xe1gina inicial do Vitest cont\xe9m o [Get Started](https://vitest.dev/guide/) contendo alguns exemplos de instala\xe7\xe3o e configura\xe7\xe3o.\\n\\n## Configurando o projeto\\n\\n### Setup Node + Typescript\\n\\nVou criar uma pasta vazia, com um nome qualquer.\\n\\n```sh\\nmkdir vitest-typescript-example\\n```\\n\\nCom o meu Visual Studio Code aberto nessa pasta, vou abrir um terminal integrado e iniciar o Node, e instalar as depend\xeancias b\xe1sicas para o Typescript funcionar.\\n\\n```sh\\nnpm init -y\\n\\nnpm install -D typescript @types/node\\n```\\n\\nAgora vou criar o tsconfig.json, que \xe9 o arquivo de configura\xe7\xe3o do Typescript. Ele ir\xe1 gerar uma configura\xe7\xe3o default, e vou manter ela.\\n\\n```sh\\nnpx tsc --init\\n```\\n\\nPronto, meu projeto j\xe1 est\xe1 configurado com Node + Typescript.\\n\\n### Setup Vitest\\n\\nAgora vou instalar o Vitest como depend\xeancia de desenvolvimento.\\n\\n```sh\\nnpm install -D vitest\\n```\\n\\nO Vitest precisa de um arquivo de configura\xe7\xe3o para poder executar. Na pr\xf3pria documenta\xe7\xe3o tem um exemplo simples. Vou criar um arquivo **vitest.config.ts** na raiz, e adicionar a configura\xe7\xe3o b\xe1sica.\\n\\n```ts title=\\"vitest.config.ts\\"\\nimport { defineConfig } from \\"vitest/config\\";\\n\\nexport default defineConfig({\\n test: {\\n reporters: \\"verbose\\",\\n },\\n});\\n```\\n\\nVeja como o arquivo de configura\xe7\xe3o \xe9 enxuto, bem diferente dos outros frameworks citados no come\xe7o do post. [Na documenta\xe7\xe3o tenho acesso a API](https://vitest.dev/config/), e como posso personalizar o **defineConfig()**. N\xe3o vou configurar nada extra, j\xe1 est\xe1 \xf3timo como est\xe1.\\n\\n> Veja que configurei **reporters** como **verbose**, isso para que eu possa obter todas as informa\xe7\xf5es do teste no terminal.\\n\\n### Configurando o package.json\\n\\nQuando eu executei o **npm init -y**, foi gerado um arquivo **package.json** na raiz, com algumas configura\xe7\xf5es bem simples. Dentro de **scripts** tem um script **test**. Vou edit\xe1-lo.\\n\\n```json title=\\"package.json\\"\\n...\\n\\"scripts\\": {\\n \\"test\\": \\"vitest --run\\"\\n}\\n...\\n```\\n\\n> Agora quando eu executar `npm run test` no terminal, o vitest ir\xe1 executar meus testes. Como n\xe3o temos nenhum teste no momento, ele tentar\xe1 rodar e retornar\xe1 um erro dizendo que nenhum teste foi encontrado.\\n\\n## Escrevendo o primeiro teste\\n\\nVou criar uma pasta **test** na raiz, e criar um arquivo chamado **primeiro-teste.test.ts** dentro dela. Em seguida irei adicionar alguns cen\xe1rios.\\n\\n> \xc9 importante respeitar a extens\xe3o **.test.ts**, pois o Vitest procura por essa extens\xe3o durante a execu\xe7\xe3o.\\n\\n```ts title=\\"primeiro-teste.test.ts\\"\\nimport { describe, test, expect } from \\"vitest\\";\\n\\ndescribe(\\"Cont\xe9m um conjunto de testes, que ser\xe1 executado um a um\\", () => {\\n test(\\"Deve somar 20 + 50 e retornar 70\\", () => {\\n expect(20 + 50).toBe(70);\\n });\\n\\n test(\\"Deve concatenar a palavra \'Ol\xe1\' com a palavra \'Mundo\' e retornar \'Ol\xe1 Mundo\'\\", () => {\\n expect(\\"Ol\xe1 \\" + \\"Mundo\\").toBe(\\"Ol\xe1 Mundo\\");\\n });\\n\\n test(\\"Deve retornar que o Palmeiras n\xe3o tem mundial\\", () => {\\n const temMundial = false;\\n expect(temMundial).toBeFalsy();\\n });\\n\\n test(\\"Deve conter todos os valores do objeto fornecido\\", () => {\\n const meuObjeto = {\\n nome: \\"Palmeiras\\",\\n temMundial: false,\\n cor: \\"Verde\\",\\n };\\n expect(meuObjeto).toEqual({\\n nome: \\"Palmeiras\\",\\n temMundial: false,\\n cor: \\"Verde\\",\\n });\\n });\\n});\\n```\\n\\nAgora vou abrir o terminal e executar `npm run test`, e o Vitest ir\xe1 executar e retornar todos esses cen\xe1rios no terminal, verde caso tenha passado, e vermelho caso tenha reprovado algum.\\n\\n### Sucesso\\n\\n![](vitest-sucess.png)\\n\\n### Erro\\n\\nAdicionei um campo a mais no objeto do \xfaltimo teste, **por\xe9m n\xe3o adicionei no expect**, logo o teste fez a compara\xe7\xe3o e reprovou, pois os objetos n\xe3o s\xe3o mais iguais.\\n\\n> Veja como a inteface \xe9 amig\xe1vel, ela exibe com muita clareza qual teste reprovou e o motivo.\\n\\n![](vitest-error.png)\\n\\n## Resumo\\n\\n- Preciso saber em qual cen\xe1rio vou escrever meus testes, se \xe9 frontend ou backend, pois cada um possu\xed a ferramenta certa para o cen\xe1rio.\\n- Se eu ainda n\xe3o sei testar, devo procurar o framework mais f\xe1cil para aprender. Nesse caso foi o Vitest, pois ele tem uma filosofia **less config**.\\n- A documenta\xe7\xe3o cont\xe9m tudo que preciso para configurar o framework, e ainda cont\xe9m v\xe1rios exemplos.\\n- O Vitest procura por arquivos que tenham a extens\xe3o **.test.ts**.\\n- Os resultados dos testes s\xe3o exibidos no terminal, de uma forma muito amig\xe1vel.\\n- Posso executar o comando `npm run test` quantas vezes quiser, e o teste executar\xe1 em mil\xe9simos de segundos.\\n- Automatizar \xe9 bem melhor que testar manualmente.\\n\\n### Reposit\xf3rio com o c\xf3digo\\n\\n[https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-2](https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-2)"},{"id":"aprenda-a-testar-pt1","metadata":{"permalink":"/blog/aprenda-a-testar-pt1","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-10-17-aprenda-a-testar-pt1/index.md","source":"@site/blog/2022-10-17-aprenda-a-testar-pt1/index.md","title":"Aprenda a escrever testes - Parte 1","description":"Para que servem os testes? Como fa\xe7o para escrever um teste?","date":"2022-10-17T00:00:00.000Z","formattedDate":"17 de outubro de 2022","tags":[{"label":"teste","permalink":"/blog/tags/teste"},{"label":"cobertura","permalink":"/blog/tags/cobertura"},{"label":"qualidade","permalink":"/blog/tags/qualidade"},{"label":"testes automatizados","permalink":"/blog/tags/testes-automatizados"}],"readingTime":3.465,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"aprenda-a-testar-pt1","title":"Aprenda a escrever testes - Parte 1","description":"Para que servem os testes? Como fa\xe7o para escrever um teste?","keywords":["teste","cobertura","qualidade","testes automatizados"],"image":"/img/test.jpg","tags":["teste","cobertura","qualidade","testes automatizados"],"authors":"brunelli"},"prevItem":{"title":"Aprenda a escrever testes - Parte 2","permalink":"/blog/aprenda-a-testar-pt2"},"nextItem":{"title":"Como validar dados de uma forma elegante","permalink":"/blog/como-validar-dados-de-uma-forma-elegante"}},"content":"Para que servem os testes? Como fa\xe7o para escrever um teste? Esse tema ainda pode ser muito confuso para quem est\xe1 come\xe7ando a programar, e at\xe9 para quem j\xe1 possu\xed mais tempo de estrada.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Afinal, para que servem os testes?\\n\\nAntes de responder essa pergunta, vamos entender de que testes estamos falando. A primeira coisa que me vem a mente quando algu\xe9m me pede para testar a aplica\xe7\xe3o \xe9: **executar a aplica\xe7\xe3o e fazer alguma a\xe7\xe3o e ver se o resultado esperado foi alcan\xe7ado.**\\n\\nEsse conceito est\xe1 correto, e de fato isso \xe9 \\"testar a aplica\xe7\xe3o\\". Entretanto uma aplica\xe7\xe3o ir\xe1 conter muitos recursos, que se forem testadas de forma manual, levar\xe1 muito tempo e desgastar\xe1 quem est\xe1 testando. Tamb\xe9m haver\xe1 possibilidades de erros humanos durante esse processo.\\n\\n### Testes automatizados\\n\\nPara isso existem os **testes automatizados**, que \xe9 uma forma de **executar um script que ir\xe1 testar todas as a\xe7\xf5es da aplica\xe7\xe3o**, de forma autom\xe1tica, **simulando a intera\xe7\xe3o humana** e observando se **o resultado esperado foi alca\xe7ado**.\\n\\nOs benef\xedcios dessa pr\xe1tica s\xe3o muitos, visto que, se o teste \xe9 automatizado, posso execut\xe1-lo e assim esperar para ver se todas as funcionalidades do sistema **ainda est\xe3o ok e se comportando como deveriam**. Dessa forma \xe9 poss\xedvel simular toda a intera\xe7\xe3o humana em todos os m\xf3dulos do sistema, **e em poucos segundos.**\\n\\n### Requisitos para escrever um teste\\n\\nPrimeiramente devemos entender as regras de neg\xf3cio da aplica\xe7\xe3o, e saber como devem se comportar em diferentes situa\xe7\xf5es.\\n\\nVamos supor que nosso sistema recebe dois n\xfameros e retorna a soma desses n\xfameros para o usu\xe1rio. Para escrever um teste em cima dessa funcionalidade, deveremos prover **dois n\xfameros de entrada** e observar se o valor retornado **\xe9 a soma dos dois n\xfameros fornecidos**. Se o resultado de fato for a soma dos dois n\xfameros fornecidos, ent\xe3o o teste passar\xe1, do contr\xe1rio ele reprovar\xe1.\\n\\n### Exemplo 1\\n\\n```ts title=\\"calculadora.ts\\"\\nexport class Calculadora {\\n somar(numero1: number, numero2: number) {\\n return numero1 + numero2;\\n }\\n}\\n```\\n\\n```ts title=\\"calculadora.test.ts\\"\\nimport { Calculadora } from \\"./calculadora\\";\\n\\ntest(\\"Deve somar 10 + 10 e retornar 20\\", () => {\\n const calculadora = new Calculadora();\\n const resultado = calculadora.somar(10, 10);\\n\\n expect(resultado).toBe(20); // true, logo o teste passar\xe1.\\n});\\n```\\n\\n### Exemplo 2\\n\\nAgora, se eu alterar a regra de neg\xf3cios do m\xe9todo **somar**, e faz\xea-lo retornar a multiplica\xe7\xe3o ao inv\xe9s da soma, **nosso teste ir\xe1 reprovar**, pois ele espera que o resultado seja **20** e n\xe3o **100**.\\n\\n```ts title=\\"calculadora.ts\\"\\nexport class Calculadora {\\n somar(numero1: number, numero2: number) {\\n return numero1 * numero2;\\n }\\n}\\n```\\n\\n```ts title=\\"calculadora.test.ts\\"\\nimport { Calculadora } from \\"./calculadora\\";\\n\\ntest(\\"Deve somar 10 + 10 e retornar 20\\", () => {\\n const calculadora = new Calculadora();\\n const resultado = calculadora.somar(10, 10);\\n\\n console.log(resultado); // 100\\n\\n expect(resultado).toBe(20); // 100 != 20, logo \xe9 false, o teste reprovar\xe1.\\n});\\n```\\n\\n## O que eu devo testar?\\n\\nPosso testar as regras de neg\xf3cio de uma classe **(unidade)**, a integra\xe7\xe3o de um servi\xe7o com o banco de dados **(integra\xe7\xe3o)** e o comportamento geral do sistema **(de ponta a ponta)**.\\n\\nLogo temos testes de unidade, testes de integra\xe7\xe3o e testes de ponta a ponta.\\n\\nPara que haja uma excelente cobertura, devemos utilizar todos esses tipos de testes. Alguns desenvolvedores optam por utilizar apenas um desses tipos de testes, o que pode resultar em **uma ou v\xe1rias lacunas na cobertura do sistema.**\\n\\n## Resumo\\n\\n- Testar \xe9 executar uma a\xe7\xe3o no sistema e observar se o resultado obtivo \xe9 de fato esperado.\\n- Testes automatizados excluem a necessidade de testes humanos e manuais.\\n- Os tipos de testes s\xe3o: unidade, integra\xe7\xe3o e de ponta a ponta.\\n- Testar garante que o comportamento do sistema ser\xe1 preservado. Em caso de quebra, os testes avisar\xe3o onde ocorreu a quebra.\\n- Se um sistema n\xe3o possu\xed testes automatizados, n\xe3o h\xe1 como o desenvolvedor saber se a altera\xe7\xe3o que ele fez quebrou o sistema. Ele ter\xe1 que testar manualmente, e em muitos dos casos poder\xe3o ocorrer falhas humanas e o sistema poder\xe1 ir para produ\xe7\xe3o com defeito **(em muitos casos isso pode significar preju\xedzo financeiro para a empresa, e at\xe9 fal\xeancia da mesma).**\\n\\n### Reposit\xf3rio com o c\xf3digo\\n\\n[https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-1](https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-1)"},{"id":"como-validar-dados-de-uma-forma-elegante","metadata":{"permalink":"/blog/como-validar-dados-de-uma-forma-elegante","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-02-21-como-validar-dados-de-uma-forma-elegante/index.md","source":"@site/blog/2022-02-21-como-validar-dados-de-uma-forma-elegante/index.md","title":"Como validar dados de uma forma elegante","description":"Hoje vou ensinar uma maneira bem elegante de validar dados no Javascript. E o mais legal, usando somente os recursos nativos da linguagem!","date":"2022-02-21T00:00:00.000Z","formattedDate":"21 de fevereiro de 2022","tags":[{"label":"validador","permalink":"/blog/tags/validador"},{"label":"javascript","permalink":"/blog/tags/javascript"},{"label":"every","permalink":"/blog/tags/every"}],"readingTime":3.72,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"como-validar-dados-de-uma-forma-elegante","title":"Como validar dados de uma forma elegante","description":"Hoje vou ensinar uma maneira bem elegante de validar dados no Javascript. E o mais legal, usando somente os recursos nativos da linguagem!","keywords":["validator","javascript","array"],"image":"/img/every.png","tags":["validador","javascript","every"],"authors":"brunelli"},"prevItem":{"title":"Aprenda a escrever testes - Parte 1","permalink":"/blog/aprenda-a-testar-pt1"},"nextItem":{"title":"Aprenda a criar snippets no VS Code","permalink":"/blog/aprenda-a-criar-snippets-no-vscode"}},"content":"Salve galera, tudo bem com voc\xeas?\\nHoje vou ensinar uma maneira bem elegante de validar dados no Javascript. E o mais legal, usando somente os recursos nativos da linguagem.\\n\\n## Entendendo o cen\xe1rio\\n\\nImagine o seguinte cen\xe1rio, voc\xea precisa construir uma API que ir\xe1 receber os dados de pessoas que querem receber notifica\xe7\xf5es regulares sobre seu cat\xe1logo de produtos.\\n\\n\x3c!-- truncate --\x3e\\n\\n### Requisitos\\n\\nPara sua regra de neg\xf3cios funcionar, voc\xea ir\xe1 precisar dos seguintes requisitos:\\n\\n- Sua API deve ser constru\xedda da forma mais simples poss\xedvel, se poss\xedvel uma [Lambda](https://aws.amazon.com/pt/lambda/).\\n- A rota deve ser do tipo POST.\\n- Receber do cliente nome, sobrenome, email e o cep.\\n- Todos os dados s\xe3o obrigat\xf3rios.\\n\\n## Implementa\xe7\xe3o do endpoint\\n\\nVamos pular toda a parte da constru\xe7\xe3o da API. Vamos prosseguir como se toda a infraestrutura j\xe1 estivesse montada. Algo mais ou menos assim:\\n\\n```js title=\\"subscribers.js\\"\\nexports.subscribers = async (req, res) => {\\n try {\\n const { first_name, last_name, email, cep } = red.body;\\n\\n await subscribersRepository.insert({\\n first_name,\\n last_name,\\n email,\\n cep,\\n });\\n\\n return res.status(200).json({\\n message:\\n \\"Obrigado por assinar nosso cat\xe1logo! Em breve enviaremos a edi\xe7\xe3o desse m\xeas por e-mail.\\",\\n });\\n } catch (error) {\\n return res.status(400).json({\\n message: error.message,\\n });\\n }\\n};\\n```\\n\\nLembra que eu disse que os dados do cliente devem ser obrigat\xf3rios? Em nenhum momento n\xf3s estamos validando isso. Da maneira como os dados est\xe3o vindo, estou repassando para meu repository.\\n\\n## Possibilidades\\n\\n### Condicionais: `if else`\\n\\nA maneira mais simples de satisfazer nossa valida\xe7\xe3o \xe9 criar um `if` para cada campo e lan\xe7ar uma exce\xe7\xe3o caso algum retorne `false`.\\n\\n### Loops padr\xf5es: `for`\\n\\nOutra maneira \xe9 criar um `for` e percorrer o `req.body` com o `Object.keys` e verificar campo a campo.\\n\\n### Conhecendo o `every`\\n\\nMas nosso querido Javascript j\xe1 possu\xed um maravilhoso recurso que far\xe1 todo trabalho pesado para n\xf3s, e tudo isso de forma nativa, sem precisarmos instalar um pacote externo.\\n\\nO [every](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/every) \xe9 um m\xe9todo que itera nosso array e retorna `true` somente se todos os \xedndices retornarem `true`. Com ele \xe9 poss\xedvel percorrer nosso `req.body`, e caso n\xe3o tenha um determinado campo, automagicamente retornar\xe1 `false`, interrompendo dessa forma a itera\xe7\xe3o.\\n\\nVamos ver como ficar\xe1:\\n\\n```js title=\\"subscribersValidator.js\\"\\nclass SubscriberValidator {\\n static isValid(data = {}) {\\n const requiredFields = [\\"first_name\\", \\"last_name\\", \\"email\\", \\"cep\\"];\\n return requiredFields.every((field) => data.hasOwnProperty(field));\\n }\\n}\\n```\\n\\nNote que para cada campo iterado do nosso `requiredFields`, testamos com o [hasOwnProperty](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/HasOwnProperty) se `field` est\xe1 presente no objeto `data`.\\n\\n## Implementando o nosso validador\\n\\nVoltemos ao c\xf3digo do nosso endpoint, agora com nosso `SubscriberValidator`.\\n\\n```js title=\\"subscribers.js\\"\\nconst SubscriberValidator = require(\\"./validators/subscriber-validator\\");\\n\\nexports.subscribers = async (req, res) => {\\n try {\\n if (!SubscriberValidator.isValid(req.body)) {\\n throw new Error(\\"Favor preencher todos os campos.\\");\\n }\\n\\n const { first_name, last_name, email, cep } = red.body;\\n\\n await subscribersRepository.insert({\\n first_name,\\n last_name,\\n email,\\n cep,\\n });\\n\\n return res.status(200).json({\\n message:\\n \\"Obrigado por assinar nosso cat\xe1logo! Em breve enviaremos a edi\xe7\xe3o desse m\xeas por e-mail.\\",\\n });\\n } catch (error) {\\n return res.status(400).json({\\n message: error.message,\\n });\\n }\\n};\\n```\\n\\nVeja como ficou enxuta nossa feature. E o melhor \xe9 que o `every` interrompe imediatamente o loop e retorna `false` caso algum campo n\xe3o esteja l\xe1 no `req.body`.\\n\\n### B\xf4nus\\n\\nPodemos refatorar nosso `SubscriberValidator` e retornar o campo que o usu\xe1rio esqueceu de informar:\\n\\n```js title=\\"subscribersValidator.js\\"\\nclass SubscriberValidator {\\n static isValid(data = {}) {\\n const requiredFields = [\\"first_name\\", \\"last_name\\", \\"email\\", \\"cep\\", \\"phone\\"];\\n let missingField;\\n\\n const isValid = requiredFields.every((field) => {\\n const hasField = data.hasOwnProperty(field);\\n if (!hasField) missingField = field;\\n return hasField;\\n });\\n\\n return {\\n isValid,\\n missingField,\\n };\\n }\\n}\\n```\\n\\nPodemos refatorar nosso endpoint e retornar o campo que est\xe1 faltando na `response`. Dessa forma o usu\xe1rio saber\xe1 onde errou:\\n\\n```js title=\\"subscribers.js\\"\\nconst SubscriberValidator = require(\\"./validators/subscriber-validator\\");\\n\\nexports.subscribers = async (req, res) => {\\n try {\\n const { isValid, missingField } = SubscriberValidator.isValid(req.body);\\n\\n if (!isValid) {\\n throw new Error(`O campo \'${missingField}\' \xe9 obrigat\xf3rio!`);\\n }\\n\\n const { first_name, last_name, email, cep } = red.body;\\n\\n await subscribersRepository.insert({\\n first_name,\\n last_name,\\n email,\\n cep,\\n });\\n\\n return res.status(200).json({\\n message:\\n \\"Obrigado por assinar nosso cat\xe1logo! Em breve enviaremos a edi\xe7\xe3o desse m\xeas por e-mail.\\",\\n });\\n } catch (error) {\\n return res.status(400).json({\\n message: error.message,\\n });\\n }\\n};\\n```\\n\\n## Conclus\xe3o\\n\\nUtilizamos somente recursos nativos da nossa linguagem e evitamos pacotes externos desnecess\xe1rios.\\n\\nCaso sua API precisasse de muitas valida\xe7\xf5es, grava\xe7\xe3o de logs, mensagens super refinadas, ai sim seria melhor utilizar um pacote para fazer esse trabalho.\\n\\nMas aqui era algo extremamente simples.\\n\\nEspero que tenha gostado! Compartilhe essa postagem com seus amigos e colegas de trabalho! Vou ficando por aqui, at\xe9 a pr\xf3xima!"},{"id":"aprenda-a-criar-snippets-no-vscode","metadata":{"permalink":"/blog/aprenda-a-criar-snippets-no-vscode","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-02-20-aprenda-a-criar-snippets-no-vscode/index.md","source":"@site/blog/2022-02-20-aprenda-a-criar-snippets-no-vscode/index.md","title":"Aprenda a criar snippets no VS Code","description":"Hoje quero compartilhar com voc\xeas algo bem bacana, que \xe9 criar seus pr\xf3prios snippets no VS Code...","date":"2022-02-20T00:00:00.000Z","formattedDate":"20 de fevereiro de 2022","tags":[{"label":"snippets","permalink":"/blog/tags/snippets"},{"label":"vscode","permalink":"/blog/tags/vscode"},{"label":"produtividade","permalink":"/blog/tags/produtividade"}],"readingTime":2.705,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"aprenda-a-criar-snippets-no-vscode","title":"Aprenda a criar snippets no VS Code","description":"Hoje quero compartilhar com voc\xeas algo bem bacana, que \xe9 criar seus pr\xf3prios snippets no VS Code...","keywords":["snippets","vscode","visual studio code"],"image":"/img/snippets.png","tags":["snippets","vscode","produtividade"],"authors":"brunelli"},"prevItem":{"title":"Como validar dados de uma forma elegante","permalink":"/blog/como-validar-dados-de-uma-forma-elegante"},"nextItem":{"title":"Criando atalhos para o git","permalink":"/blog/criando-atalhos-para-o-git"}},"content":"Salve galera, tudo bem?\\n\\nHoje quero compartilhar com voc\xeas algo bem bacana, que \xe9 criar seus pr\xf3prios snippets no VS Code.\\n\\n## O que \xe9 um Snippet?\\n\\n\x3c!-- truncate --\x3e\\n\\n### Um atalho\\n\\nNada mais \xe9 que um atalho para a cria\xe7\xe3o de um trecho de c\xf3digo. Pense em um c\xf3digo simples como esse:\\n\\n```js title=\\"L\xf3gica de um loop no Javascript\\"\\nfor (const item of items) {\\n console.log(item);\\n}\\n```\\n\\nEsse tipo de c\xf3digo tende a se repetir muito durante nosso desenvolvimento rotineiro. Com isso, pode ficar chato escrever a mesma sintaxe toda vez.\\n\\n### Produtividade\\n\\n\xc9 ai que a m\xe1gica acontece! Que tal digitiar apenas `newfor` e o VS Code cri\xe1-lo para voc\xea? Sim \xe9 poss\xedvel!\\n\\n## Vamos come\xe7ar\\n\\n### Primeiro passo\\n\\nVamos criar o arquivo principal para nossos snippets.\\n\\nCom seu VS Code aberto, digite Ctrl+Shift+P e digite **snippets** na barra que apareceu, selecione a op\xe7\xe3o **Preferences: Configure User Snippets** e depois **New Global Snippet File**.\\n\\nAbrir\xe1 uma caixinha para voc\xea digitar o nome do seu arquivo de snippets. Voc\xea pode colocar qualquer nome, eu vou colocar **my-snippets**.\\n\\n### Segundo passo\\n\\nVai abrir um arquivo mais ou menos assim:\\n\\n```json title=\\"my-snippets.code-snippets\\"\\n{\\n // Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and\\n // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope\\n // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is\\n // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:\\n // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.\\n // Placeholders with the same ids are connected.\\n // Example:\\n // \\"Print to console\\": {\\n // \\t\\"scope\\": \\"javascript,typescript\\",\\n // \\t\\"prefix\\": \\"log\\",\\n // \\t\\"body\\": [\\n // \\t\\t\\"console.log(\'$1\');\\",\\n // \\t\\t\\"$2\\"\\n // \\t],\\n // \\t\\"description\\": \\"Log output to console\\"\\n // }\\n}\\n```\\n\\nApague tudo e monte essa estrutura:\\n\\n```json title=\\"my-snippets.code-snippets\\"\\n{\\n \\"newfor\\": {\\n \\"scope\\": \\"\\",\\n \\"prefix\\": \\"\\",\\n \\"body\\": [],\\n \\"description\\": \\"\\"\\n }\\n}\\n```\\n\\n#### Significado de cada atributo\\n\\n- **newfor**: \xe9 o nome do nosso snippet\\n- **scope**: em quais tipos de arquivos seu snippet executar\xe1\\n- **prefix**: atalho para seu snippet\\n- **body**: linhas que seu snippet ir\xe1 gerar\\n- **description**: descri\xe7\xe3o do que seu snippet ir\xe1 gerar (n\xe3o obrigat\xf3rio)\\n\\n### Terceiro passo\\n\\nAgora que sabemos o que cada campo significa, vamos preenche-los com nosso c\xf3digo:\\n\\n```json title=\\"my-snippets.code-snippets\\"\\n{\\n \\"newfor\\": {\\n \\"scope\\": \\"javascript, typescript\\",\\n \\"prefix\\": \\"newfor\\",\\n \\"body\\": [\\"for (const item of items) {\\", \\"console.log(item)\\", \\"}\\"],\\n \\"description\\": \\"cria um loop com for\\"\\n }\\n}\\n```\\n\\n### Quarto passo\\n\\nPronto, salve o seu arquivo de snippet, v\xe1 para um arquivo **.js** ou **.ts** e fa\xe7a o teste. Digite `newfor` e aperte Ctrl+ Space bar.\\n\\nDever\xe1 aparecer o nome do seu snippet no autocomplete, dessa forma:\\n![](./screenshot.png)\\n\\nS\xf3 apertar Enter que seu c\xf3digo ser\xe1 gerado. Legal n\xe9?\\n\\n## Conclus\xe3o\\n\\nCaso voc\xea tenha chegado at\xe9 aqui e n\xe3o tenha funcionado, volte desde o come\xe7o e tente novamente com calma, voc\xea deve ter deixado algo passar. \xc9 bem simples.\\n\\nEspero que tenha gostado! Se foi \xfatil para voc\xea, compartilhe com seus amigos e colegas de trabalho!\\n\\nAt\xe9 a pr\xf3xima!"},{"id":"criando-atalhos-para-o-git","metadata":{"permalink":"/blog/criando-atalhos-para-o-git","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-02-19-criando-atalhos-para-o-git/index.md","source":"@site/blog/2022-02-19-criando-atalhos-para-o-git/index.md","title":"Criando atalhos para o git","description":"Hoje vou ensinar como criar atalhos para o git que v\xe3o aumentar tua produtividade. Sem muita enrola\xe7\xe3o, vamos direto para a pr\xe1tica...","date":"2022-02-19T00:00:00.000Z","formattedDate":"19 de fevereiro de 2022","tags":[{"label":"git","permalink":"/blog/tags/git"},{"label":"aliases","permalink":"/blog/tags/aliases"}],"readingTime":2.73,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"criando-atalhos-para-o-git","title":"Criando atalhos para o git","description":"Hoje vou ensinar como criar atalhos para o git que v\xe3o aumentar tua produtividade. Sem muita enrola\xe7\xe3o, vamos direto para a pr\xe1tica...","keywords":["git","aliases","shortcut"],"image":"/img/git.jpg","tags":["git","aliases"],"authors":"brunelli"},"prevItem":{"title":"Aprenda a criar snippets no VS Code","permalink":"/blog/aprenda-a-criar-snippets-no-vscode"},"nextItem":{"title":"Como contornar a dor de escrever um teste unit\xe1rio?","permalink":"/blog/como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio"}},"content":"![Git Logo](/img/git.jpg)\\n\\nOl\xe1, tudo bem?\\n\\nHoje vou ensinar como criar atalhos para o **git** que v\xe3o aumentar tua produtividade.\\nSem muita enrola\xe7\xe3o, vamos direto para a pr\xe1tica.\\n\\n## Escolher o editor de textos padr\xe3o\\n\\nAntes de come\xe7ar, \xe9 bom configurar o editor de texto de sua prefer\xeancia. Eu vou utilizar o [Vim](https://www.vim.org/), mas voc\xea pode utilizar o Code, Nano etc.\\n\\n\x3c!-- truncate --\x3e\\n\\n### Configurar editor\\n\\nSubistitua o **\\"vim\\"** pelo editor de sua preferencia. Segue a lista dos mais utilizados:\\n\\n- vim\\n- nano\\n- code\\n- gedit\\n\\n```bash title=\\"Definir editor padr\xe3o\\"\\ngit config --global core.editor vim\\n```\\n\\n## Prontos para come\xe7ar\\n\\n### Abrir arquivo de configura\xe7\xf5es do git\\n\\nIsso abrit\xe1 seu arquivo de configura\xe7\xf5es do git em seu editor de texto.\\n\\n```bash title=\\"Abrindo meu arquivo de configura\xe7\xf5es\\"\\ngit config --global --edit\\n```\\n\\n### Adicionar usu\xe1rio\\n\\n\xc9 importante adicionar um usu\xe1rio ao seu git config, pois ele ser\xe1 utilizado em seus commits.\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n```\\n\\n## Atalhos\\n\\n### git status\\n\\nVamos definir nosso primeiro atalho, o `git status -s`. Esse comando exibe o status atual da sua **stage area**, quais arquivos est\xe3o commitados, e quais foram modificados.\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n\\n[alias]\\n s = !git status -s\\n```\\n\\nAgora o status dos seus commits ficar\xe3o mais clean.\\n\\n### git add && git commit\\n\\nEsses dois s\xe3o muito utilizados, que tal torn\xe1-los em um \xfanico comando?\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n\\n[alias]\\n s = !git status -s\\n c = !git add --all && git commit -m\\n```\\n\\nAgora quando digitarmos `git c` em nosso terminal, nosso **alias** ir\xe1 adicionar e commitar ao mesmo tempo, s\xf3 vamos precisar informar a mensagem. Exemplo:\\n\\n```bash title=\\"Configurando meu git\\"\\ngit c \'feat: agora ficou mais f\xe1cil!\'\\n```\\n\\n### git pull/push origin HEAD\\n\\nOutro comando muito utilizado. Vamos simplific\xe1-lo.\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n\\n[alias]\\n s = !git status -s\\n c = !git add --all && git commit -m\\n pullo = !git pull origin HEAD\\n pusho = !git push origin HEAD\\n```\\n\\nAgora podemos usar essa combina\xe7\xe3o:\\n\\n```bash\\ngit c \'feat: adicionar simplicidade\' && git pusho\\n```\\n\\n### git log\\n\\nQuem nunca se perdeu ao utilizar um `git log`? S\xe3o muitas informa\xe7\xf5es de uma vez. Vamos simplificar:\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n\\n[alias]\\n s = !git status -s\\n c = !git add --all && git commit -m\\n pullo = !git pull origin HEAD\\n pusho = !git push origin HEAD\\n l = !git log --pretty=format:\'%h %s %cn %cr\'\\n```\\n\\n#### Vamos entender o que fizemos\\n\\n- **%h**: id do commit (hash)\\n- **%s**: mensagem do commit\\n- **%cn**: autor do commit\\n- **%cr**: quanto tempo desde o commit\\n\\nAgora seu `git l` retornar\xe1 os dados do commit de uma forma bem resumida. Tamb\xe9m d\xe1 pra mudar a cor, vou deixar a documenta\xe7\xe3o logo abaixo pra voc\xea consultar.\\n\\n## Links \xfateis\\n\\n- [Pretty format](https://git-scm.com/docs/pretty-formats)\\n- [Git config](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)\\n\\n## Conclus\xe3o\\n\\nN\xe3o existe limites, podemos combinar v\xe1rios comandos e simplificar nossa rotina. Agora voc\xea pode brincar e criar seus pr\xf3prios atalhos!\\n\\nEspero que tenha gostado! Se te ajudou de alguma maneira, compartilhe com seus amigos e colegas de trabalho!\\n\\nAt\xe9 a pr\xf3xima!"},{"id":"como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio","metadata":{"permalink":"/blog/como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2021-12-16-como-contornar-a-dor-de-escrever-um-teste-unitario/index.md","source":"@site/blog/2021-12-16-como-contornar-a-dor-de-escrever-um-teste-unitario/index.md","title":"Como contornar a dor de escrever um teste unit\xe1rio?","description":"Acredito que todo mundo concorda que um c\xf3digo sem testes, \xe9 um c\xf3digo inst\xe1vel e fr\xe1gil \xe0 mudan\xe7as...","date":"2021-12-16T00:00:00.000Z","formattedDate":"16 de dezembro de 2021","tags":[{"label":"tdd","permalink":"/blog/tags/tdd"},{"label":"testes","permalink":"/blog/tags/testes"},{"label":"teste unit\xe1rio","permalink":"/blog/tags/teste-unitario"}],"readingTime":3.6,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio","title":"Como contornar a dor de escrever um teste unit\xe1rio?","description":"Acredito que todo mundo concorda que um c\xf3digo sem testes, \xe9 um c\xf3digo inst\xe1vel e fr\xe1gil \xe0 mudan\xe7as...","keywords":["tdd","tests","tdd example","tdd javascript"],"image":"/img/tdd.jpeg","authors":"brunelli","tags":["tdd","testes","teste unit\xe1rio"]},"prevItem":{"title":"Criando atalhos para o git","permalink":"/blog/criando-atalhos-para-o-git"},"nextItem":{"title":"O impacto da educa\xe7\xe3o em minha vida","permalink":"/blog/o-impacto-da-educa\xe7\xe3o-em-minha-vida"}},"content":"![TDD Banner](/img/tdd.jpeg)\\n\\nSalve galera, tudo tranquilo? Esse \xe9 meu segundo artigo, e gostaria de compartilhar algo que vem me ajudando muito durante o desenvolvimento de software e na minha pr\xf3pria evolu\xe7\xe3o profissional.\\n\\nEstou falando sobre os **testes unit\xe1rios**. Acredito que todo mundo concorda que um c\xf3digo sem testes, \xe9 um c\xf3digo inst\xe1vel e fr\xe1gil \xe0 mudan\xe7as. \xc9 muito ruim programar no escuro, n\xf3s nunca temos certeza que o que estamos desenvolvendo ir\xe1 funcionar em produ\xe7\xe3o, sem conflitar com as features j\xe1 existentes.\\n\\nPor outro lado, escrever testes para uma feature j\xe1 implementada pode ser algo muito doloroso, por isso **muita gente prefere correr o risco e deixar o c\xf3digo sem cobertura.**\\n\\n\x3c!--truncate--\x3e\\n\\nMas recentemente venho estudando fortemente uma metodologia que abriu minha mente, o **TDD**, ou em portugu\xeas **\\"Desenvolvimento guiado por testes\\"**. No TDD n\xf3s criamos o teste primeiro, e s\xf3 depois criamos a implementa\xe7\xe3o de fato, que far\xe1 o teste passar. Isso faz com que nosso c\xf3digo sempre esteja coberto por testes.\\n\\n## Traduzindo\\n\\nSe eu quisesse criar uma fun\xe7\xe3o que me retornasse o maior n\xfamero de uma lista em Javascript, utilizando o **TDD** (escrevendo o teste primeiro), eu come\xe7aria fazendo algo mais ou menos assim:\\n\\n```js title=\\"pegueOMaiorNumero.test.js\\"\\n// Sintaxe de um framework de testes do Javascript\\n\\ndescribe(\\"pegueOMaiorNumero\\", () => {\\n test(\\"deve retornar o maior n\xfamero de uma lista\\", () => {\\n const maiorNumero = pegueOMaiorNumero([1, 9, 7, 15, 21, 10]);\\n expect(maiorNumero).toBe(21);\\n });\\n});\\n```\\n\\nNesse caso, eu forneci uma lista com alguns n\xfameros, onde o 21 \xe9 o maior deles. Mas note que em nenhum momento foi criada a fun\xe7\xe3o **pegueOMaiorNumero**. Estou invocando uma fun\xe7\xe3o que **ainda n\xe3o foi criada**, e ainda estou esperando que o resultado seja 21. Nesse caso o teste ir\xe1 falhar.\\n\\n\xc9 ai que a brincadeira come\xe7a. Quando o teste falha, \xe9 sinal de que precisamos implementar a feature que fa\xe7a esse teste passar.\\n\\n## Ent\xe3o vamos l\xe1!\\n\\nVou criar a fun\xe7\xe3o que far\xe1 o teste passar:\\n\\n```js title=\\"pegueOMaiorNumero.test.js\\"\\nconst pegueOMaiorNumero = (numeros) => {\\n let maior = 0;\\n\\n for (let i = 0; i < numeros.length; i++) {\\n if (numeros[i] > maior) {\\n maior = numeros[i];\\n }\\n }\\n\\n return maior;\\n};\\n\\ndescribe(\\"pegueOMaiorNumero\\", () => {\\n test(\\"deve retornar o maior n\xfamero de uma lista\\", () => {\\n const maiorNumero = pegueOMaiorNumero([1, 9, 7, 15, 21, 10]);\\n expect(maiorNumero).toBe(21);\\n });\\n});\\n```\\n\\nAgora o teste come\xe7ar\xe1 a passar. Veja que o algoritmo n\xe3o ficou dos melhores, mas conseguiu satisfazer o que o teste pediu. Agora que o teste est\xe1 passando, posso refatorar a fun\xe7\xe3o **pegueOMaiorNumero** sem medo, pois ela est\xe1 coberta por um teste. Caso a fun\xe7\xe3o passe a retornar uma string, null, ou um n\xfamero que n\xe3o seja o maior, **o teste ir\xe1 me avisar, reprovando**.\\n\\n## Vamos refatorar, sem medo!\\n\\n```js title=\\"pegueOMaiorNumero.test.js\\"\\nconst pegueOMaiorNumero = (numeros) => {\\n return Math.max(...numeros);\\n};\\n\\ndescribe(\\"pegueOMaiorNumero\\", () => {\\n test(\\"deve retornar o maior n\xfamero de uma lista\\", () => {\\n const maiorNumero = pegueOMaiorNumero([1, 9, 7, 15, 21, 10]);\\n expect(maiorNumero).toBe(21);\\n });\\n});\\n```\\n\\nPronto, se a gente rodar esse teste, ele ir\xe1 continuar passando, pois o **Math.max** est\xe1 fazendo o mesmo que o **la\xe7o de repeti\xe7\xe3o** estava fazendo anteriormente, mas de uma maneira mais enxuta. O fato \xe9 que, temos confian\xe7a de alterar um c\xf3digo que nos fale se a nossa regra de neg\xf3cios falhou. **\xc9 inadmiss\xedvel** que nossa fun\xe7\xe3o **pegueOMariorNumero** retorne um n\xfamero que n\xe3o \xe9 o maior.\\n\\n## Conclus\xe3o\\n\\nNossa simples feature de retornar o maior n\xfamero, **esteve durante todo o tempo de desenvolvimento coberta por um teste**. Se a gente fizesse a feature primeiro ao inv\xe9s do teste, ter\xedamos que test\xe1-la manualmente a cada altera\xe7\xe3o, printando o resultado no console, at\xe9 de fato escrever um teste pra ela. Isso seria **cansativo**. O teste \xe9 automatizado, ou seja, escrevemos uma \xfanica vez, e ele sempre ir\xe1 assegurar o resultado pra gente.\\n\\nEscolhi esse exemplo de algoritmo, pois h\xe1 v\xe1rias formas de implement\xe1-lo. Caso voc\xea descubra alguma forma mais enxuta que essa apresentada, poder\xe1 implementar sem correr o risco de quebrar sua aplica\xe7\xe3o.\\n\\nComo material complementar, recomendo essa live que aconteceu no dia 09/12/2021, e que considero excepcional por **dois motivos: n\xe3o tem enrola\xe7\xe3o, e os caras sabem o que est\xe3o ensinando.** Por hoje \xe9 isso, forte abra\xe7o e at\xe9 a pr\xf3xima!\\n\\n[![Live TDD na pr\xe1tica - Diego Fernandes e Rodrigo Manguinho](https://img.youtube.com/vi/sg1zFpNM5Jw/0.jpg)](https://youtu.be/sg1zFpNM5Jw)\\n\\n- Reposit\xf3rio c\xf3digo fonte: [https://github.com/mrbrunelli/tdd-pega-o-maior-numero](https://github.com/mrbrunelli/tdd-pega-o-maior-numero)"},{"id":"o-impacto-da-educa\xe7\xe3o-em-minha-vida","metadata":{"permalink":"/blog/o-impacto-da-educa\xe7\xe3o-em-minha-vida","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2021-05-07-o-impacto-da-educacao-em-minha-vida/index.md","source":"@site/blog/2021-05-07-o-impacto-da-educacao-em-minha-vida/index.md","title":"O impacto da educa\xe7\xe3o em minha vida","description":"Meu \xfaltimo emprego antes de me tornar Desenvolvedor em 2019 era de Auxiliar de Produ\xe7\xe3o em uma f\xe1brica aqui da cidade...","date":"2021-05-07T00:00:00.000Z","formattedDate":"7 de maio de 2021","tags":[{"label":"educa\xe7\xe3o","permalink":"/blog/tags/educacao"},{"label":"a import\xe2ncia da educa\xe7\xe3o","permalink":"/blog/tags/a-importancia-da-educacao"},{"label":"aprendizado","permalink":"/blog/tags/aprendizado"}],"readingTime":2.82,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"o-impacto-da-educa\xe7\xe3o-em-minha-vida","title":"O impacto da educa\xe7\xe3o em minha vida","description":"Meu \xfaltimo emprego antes de me tornar Desenvolvedor em 2019 era de Auxiliar de Produ\xe7\xe3o em uma f\xe1brica aqui da cidade...","keywords":["a import\xe2ncia da educa\xe7\xe3o","educa\xe7\xe3o","conhecimento","transi\xe7\xe3o de carreira"],"image":"/img/education.jpeg","authors":"brunelli","tags":["educa\xe7\xe3o","a import\xe2ncia da educa\xe7\xe3o","aprendizado"]},"prevItem":{"title":"Como contornar a dor de escrever um teste unit\xe1rio?","permalink":"/blog/como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio"}},"content":"![Education Banner](/img/education.jpeg)\\n\\nOntem enquanto organizava minha gaveta, me deparei com minha certid\xe3o de casamento, onde estava escrito na primeira linha:\\n\\n> MATHEUS RICARDO BRUNELLI, brasileiro, de profiss\xe3o: Auxiliar de Produ\xe7\xe3o. Ano 2018.\\n\\nMeu \xfaltimo emprego antes de me tornar Desenvolvedor em 2019 era de Auxiliar de Produ\xe7\xe3o em uma f\xe1brica aqui da cidade. O trabalho era muito simples, porem muito desgastante, Dorflex e Torsilax (n\xe3o \xe9 propaganda) faziam parte da minha intensa semana.\\n\\n\x3c!--truncate--\x3e\\n\\n### Tecnologia, uma realidade crescente\\n\\nCerto dia a f\xe1brica inteira parou para ouvir o an\xfancio dos coordenadores das faculdades da regi\xe3o, e foi anunciado dentre os demais cursos o curso de Sistemas para Internet, e a fala do coordenador [Anderson Burnes](https://www.linkedin.com/in/profburnes) (que eu j\xe1 conhecia) foi muito convincente, pois naquele ano v\xe1rias empresas estavam passando por transforma\xe7\xf5es digitais, e estavam precisando de desenvolvedores qualificados, e os sal\xe1rios eram bem diferentes da minha realidade.\\n\\nEu trabalhava muito para conseguir sustentar a minha fam\xedlia (eu, esposa e os doguinhos) e mesmo assim n\xe3o era suficiente, um pneu furado ou uma gripe eram suficientes para acabar com nossas economias do m\xeas rsrs.\\n\\n### Educa\xe7\xe3o, um investimento muito rent\xe1vel\\n\\nEu sabia que o \xfanico caminho para uma mudan\xe7a de vida, era atrav\xe9s da educa\xe7\xe3o. E naquele ano estudei muito para o Enem, e consegui uma Bolsa ProUni para o curso de Sistemas para Internet na [UniAlfa](https://www.alfaumuarama.edu.br/fau).\\n\\nMe lembro que dessa vez eu n\xe3o estava apenas fazendo um curso por fazer, eu estava colocando todas minhas energias em algo que eu acreditava poder mudar minha vida.\\n\\n### Esfor\xe7o no lugar certo\\n\\nDurante os primeiros semestres, percebi que existiam muitos caminhos para seguir profiss\xe3o, alguns bem confusos, e eu precisaria ter foco em algo para poder me destacar. Comecei a pesquisar por tecnologias que me ajudariam a entrar no mercado mais r\xe1pido, pois essa era minha maior motiva\xe7\xe3o.\\n\\nQuando obtive um m\xednimo de confian\xe7a nessas tecnologias, pedi demiss\xe3o do meu emprego na f\xe1brica, para que eu pudesse me dedicar aos estudos de forma integral. Minha fam\xedlia ficou com muito medo da minha decis\xe3o, afinal, n\xe3o haviam garantias que eu conseguiria entrar na \xe1rea, antes da nossa min\xfascula reserva financeira acabar.\\n\\n### F\xe9, foco e medo\\n\\nForam esses tr\xeas elementos que me acompanharam nessa transi\xe7\xe3o. F\xe9 porque n\xf3s n\xe3o enxergamos o amanh\xe3. Foco porque o tempo \xe9 escasso. Medo porque ele funciona como uma balan\xe7a, quanto mais arriscado, mais sentimos medo.\\n\\nComo todo trabalhado duro traz recompensas, a minha chegou aos 45 do segundo tempo, quando s\xf3 restavam algumas moedinhas no cofre. Consegui meu primeiro emprego na \xe1rea, gra\xe7as ao networking (vou escrever um artigo s\xf3 desse cara) e ao meu esfor\xe7o \xe9 claro.\\n\\n### Mercado aquecido\\n\\nSe eu pudesse deixar um conselho para quem est\xe1 come\xe7ando, seria:\\n\\n> Estude, e fa\xe7a de tudo para tentar entrar no mercado. Tenha foco, e invista seu tempo estudando o que te dar\xe1 retorno.\\n\\nNem s\xf3 de teoria vive o programador. Essa \xe9 uma profiss\xe3o muito pr\xe1tica, quanto mais se exercita, mais se aprende. Os melhores exerc\xedcios s\xe3o os problemas reais de uma empresa. Mesmo que ganhando pouco no come\xe7o, trabalhar com problemas reais n\xe3o tem pre\xe7o, essa experi\xeancia n\xe3o pode ser adquirida de outra forma.\\n\\n### Considera\xe7\xf5es finais\\n\\nEsse foi meu primeiro artigo, fiquei muito empolgado ao escrev\xea-lo. Se voc\xea chegou at\xe9 aqui, meus agradecimentos. Espero que tenha sido \xfatil para voc\xea.\\n\\nForte abra\xe7o, e at\xe9 o pr\xf3ximo artigo!"}]}')}}]); \ No newline at end of file diff --git a/assets/js/b2f554cd.58e375fe.js b/assets/js/b2f554cd.58e375fe.js new file mode 100644 index 0000000..c4f91cb --- /dev/null +++ b/assets/js/b2f554cd.58e375fe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkblog=self.webpackChunkblog||[]).push([[1477],{10:function(e){e.exports=JSON.parse('{"blogPosts":[{"id":"nao-espere-um-ambiente-favoravel-para-fazer-algo-com-qualidade","metadata":{"permalink":"/blog/nao-espere-um-ambiente-favoravel-para-fazer-algo-com-qualidade","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2023-10-04-nao-espere-um-ambiente-favoravel-para-fazer-algo-com-qualidade/index.md","source":"@site/blog/2023-10-04-nao-espere-um-ambiente-favoravel-para-fazer-algo-com-qualidade/index.md","title":"N\xe3o espere um ambiente favor\xe1vel para fazer algo com qualidade","description":"Como fazer um excelente trabalho, mesmo quando o ambiente \xe9 desfavor\xe1vel?","date":"2023-10-04T00:00:00.000Z","formattedDate":"4 de outubro de 2023","tags":[{"label":"carreira","permalink":"/blog/tags/carreira"},{"label":"dicas","permalink":"/blog/tags/dicas"},{"label":"qualidade","permalink":"/blog/tags/qualidade"},{"label":"testes","permalink":"/blog/tags/testes"},{"label":"negociar","permalink":"/blog/tags/negociar"},{"label":"prazos","permalink":"/blog/tags/prazos"}],"readingTime":4.41,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"nao-espere-um-ambiente-favoravel-para-fazer-algo-com-qualidade","title":"N\xe3o espere um ambiente favor\xe1vel para fazer algo com qualidade","description":"Como fazer um excelente trabalho, mesmo quando o ambiente \xe9 desfavor\xe1vel?","keywords":["carreira","dicas","qualidade","testes","negociar","prazos"],"image":"/img/peace.jpg","tags":["carreira","dicas","qualidade","testes","negociar","prazos"],"authors":"brunelli"},"nextItem":{"title":"Dicas para melhorar as chances em entrevistas","permalink":"/blog/dicas-para-melhorar-as-chances-em-entrevistas"}},"content":"J\xe1 ouviu essa frase alguma vez?\\n\\n> \\"eu at\xe9 queria fazer algo melhor, mas o pessoal passou um prazo curto e falou pra deixar os d\xe9bitos para depois\\"\\n\\nPois \xe9, bem chato n\xe9? S\xf3 que na maioria das vezes que isso acontece, a culpa \xe9 sua!\\n\\n\x3c!-- truncate --\x3e\\n\\n## Frusta\xe7\xe3o\\n\\nEssa \xe9 uma das frases mais comuns no trabalho, e ela \xe9 carregada de frustra\xe7\xe3o, seja por n\xe3o conseguirmos entregar algo relativamente bom, ou por sempre estarmos trabalhando sob press\xe3o de **prazos malucos, que as vezes n\xf3s mesmos damos**.\\n\\nHoje eu gostaria de compartilhar como eu consegui erradicar esse tipo de frusta\xe7\xe3o da minha rotina de trabalho, e como isso tem mais a ver com **intelig\xeancia emocional** do que conhecimento t\xe9cnico\\\\*.\\n\\n### Um ciclo intermin\xe1vel\\n\\nEu j\xe1 fiz muito trabalho com qualidade duvidosa, e sempre vivia mal com isso, porque eu acabava tendo que refazer o trabalho, porque n\xe3o tava tempo de entregar a feature **devidamente validada**.\\n\\nDesde a \xe9poca de faculdade eu j\xe1 me interessava por **programa\xe7\xe3o orientada a objetos** e **testes automatizados**, isso pra mim era trabalhar com **intelig\xeancia e efici\xeancia**, entretanto isso era muito dif\xedcil de aplicar no trabalho, porque todo mundo sempre estava apagando inc\xeandios e remendando coisas.\\n\\nE como o _modus operandi_ do caos \xe9 mais caos, esse ciclo nunca tinha fim. Eu fazia um remendo, e logo o remendo arrebentava, necessitando um novo remendo.\\n\\n## Intelig\xeancia emocional\\n\\nAlgo que aprendi com a experi\xeancia e com \xf3timos mentores, \xe9 que o caos come\xe7a da nossa pr\xf3pria neglig\xeancia. Se tudo \xe9 prioridade, logo nada \xe9 prioridade.\\n\\nCom o tempo comecei a perceber que as pessoas que estavam acima de mim tamb\xe9m n\xe3o sabiam o que estavam fazendo, e talvez as pessoas acima delas tamb\xe9m n\xe3o, e isso \xe9 muito comum em uma organiza\xe7\xe3o.\\n\\n### Questionar \xe9 o come\xe7o\\n\\nQuando passei a questionar as demandas que chegavam para mim, sem medo de levar carteirada _(algumas vezes levei carteirada)_, percebi que muita coisa era desceness\xe1ria para o neg\xf3cio, e que haviam coisas mais importantes \xe0 serem priorizadas.\\n\\nIsso resolveu uma parte da frustra\xe7\xe3o, pois discutindo mais sobre os problemas o time todo passou a compreender melhor as reais necessidades do neg\xf3cio.\\n\\n**Questionar deveria ser um comportamento natural de um engenheiro**, j\xe1 que muito tempo ser\xe1 despendido para realizar uma feature, que no final das contas poder\xe1 ser in\xfatil para o cliente.\\n\\n### Lidar com prazos e requisitos n\xe3o funcionais\\n\\nNa maioria das vezes que o time de engenharia negocia os prazos, eles n\xe3o fazem ideia do que ter\xe3o que fazer, logo o prazo vira um chut\xf4metro.\\n\\nOutro cen\xe1rio \xe9 quando o time n\xe3o sabe interpretar os **requisitos n\xe3o funcionais**, como boa **abstra\xe7\xe3o de c\xf3digo, arquitetura coesa, documenta\xe7\xe3o e testes automatizados**.\\n\\nEntenda, para o cliente \xe9 importante a feature de valor, isso gerar\xe1 caixa para o neg\xf3cio. Mas para essa feature de valor ser sustent\xe1vel, ela precisa ter os pontos dos requisitos n\xe3o funcionais que citei acima.\\n\\nO cliente n\xe3o precisa de testes automatizados ou documenta\xe7\xe3o t\xe9cnica, **mas voc\xea precisa**. S\xf3 \xe9 poss\xedvel evoluir um sistema, sem efeitos colaterais, se ele estiver com uma boa abstra\xe7\xe3o, bem documentado e coberto por testes. Do contr\xe1rio ficar\xe1 cada vez mais dif\xedcil garantir a qualidade das features que vir\xe3o.\\n\\n### Negocie melhor\\n\\nPortanto, mude seu discurso de _\\"a task sem os testes ficar\xe1 pronta em 12 horas de trabalho\\"_ para _\\"a task ficar\xe1 pronta em 16 horas de trabalho\\"_. Coloque na sua estimativa de trabalho todos os requisitos, inclusive os **n\xe3o funcionais**.\\n\\nHoje com essa abordagem, imbutindo todos os requisitos n\xe3o funcionais no prazo, eu consigo realizar meu trabalho com muito mais prazer, consigo fazer um c\xf3digo com uma abstra\xe7\xe3o decente, com testes automatizados e ainda entregando no prazo combinado.\\n\\n## Invertendo o ciclo\\n\\nAgora as novas features ser\xe3o desenvolvidas com menor tempo, j\xe1 que o c\xf3digo estar\xe1 mais modular, e com as regras de neg\xf3cio validadas com testes. Logo, terei mais folga, e poderei refatorar aqueles trechos legados e bisonhos e adicionar cobertura de testes a eles tamb\xe9m.\\n\\nOs bugs natualmente ir\xe3o diminuir, e agora n\xe3o precisarei fazer remendos sem fim, isso \xe9 trabalhar com intelig\xeancia, **fazer menor esfor\xe7o e alcan\xe7ar um resultado melhor que antes**.\\n\\nInvertendo esse ciclo, os deploy n\xe3o ser\xe3o mais um caos, com hotfix pra todo lado (isso \xe9 bizarro) e todos em uma sala de guerra com o stakeholder no cangote. Essa \xe9 uma forma amadora de trabalhar, e muito estressante para todos.\\n\\n## Conclus\xe3o\\n\\nSe ficarmos esperando as pessoas acima de n\xf3s terem essa maturidade, nosso trabalho sempre ser\xe1 um inferno, e n\xf3s s\xf3 vamos criar engenhocas e c\xf3digos descart\xe1veis e in\xfateis que ter\xe3o que ser reescritos.\\n\\n\\\\*Eu disse l\xe1 no come\xe7o do post que isso tem mais a ver com intelig\xeancia emocional do que com capacidade t\xe9cnica, pois eu estou aceitando o fato de que voc\xea j\xe1 saiba fazer o seu trabalho bem, mas que por motivos n\xe3o t\xe9cnicos, acaba sempre frustrado.\\n\\nPor\xe9m **se voc\xea ainda n\xe3o compreende a import\xe2ncia de se ter um c\xf3digo bem testado**, com um bom design e documentado, essa intelig\xeancia emocional que mencionei ser\xe1 in\xfatil para voc\xea.\\n\\nSe esse \xe9 o seu caso, se dedique primeiro a aprender coisas que realmente importam, e busque avan\xe7ar em sua senioridade, e ent\xe3o esses outros pontos que explanei aqui far\xe3o sentido pra voc\xea."},{"id":"dicas-para-melhorar-as-chances-em-entrevistas","metadata":{"permalink":"/blog/dicas-para-melhorar-as-chances-em-entrevistas","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2023-06-12-dicas-para-melhorar-as-chances-em-entrevistas/index.md","source":"@site/blog/2023-06-12-dicas-para-melhorar-as-chances-em-entrevistas/index.md","title":"Dicas para melhorar as chances em entrevistas","description":"Como melhorar as chances em uma entrevista?","date":"2023-06-12T00:00:00.000Z","formattedDate":"12 de junho de 2023","tags":[{"label":"carreira","permalink":"/blog/tags/carreira"},{"label":"entrevista","permalink":"/blog/tags/entrevista"},{"label":"dicas","permalink":"/blog/tags/dicas"}],"readingTime":2.835,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"dicas-para-melhorar-as-chances-em-entrevistas","title":"Dicas para melhorar as chances em entrevistas","description":"Como melhorar as chances em uma entrevista?","keywords":["carreira","entrevista","dicas"],"image":"/img/people-talking.jpeg","tags":["carreira","entrevista","dicas"],"authors":"brunelli"},"prevItem":{"title":"N\xe3o espere um ambiente favor\xe1vel para fazer algo com qualidade","permalink":"/blog/nao-espere-um-ambiente-favoravel-para-fazer-algo-com-qualidade"},"nextItem":{"title":"Aprenda a escrever testes - Parte 2","permalink":"/blog/aprenda-a-testar-pt2"}},"content":"Como melhorar as chances em uma entrevista? Depois de fazer dezenas delas, tanto como candidato quanto entrevistador, percebi um certo padr\xe3o em entrevistas que foram bem sucedidas, e tamb\xe9m em entrevistas que n\xe3o foram.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Negocia\xe7\xe3o\\n\\nEntrevista n\xe3o \xe9 apenas uma triagem com mon\xf3logo, onde o entrevistador faz uma s\xe9rie de quiz ao candidato, e este s\xf3 acena com a cabe\xe7a. A entrevista \xe9 o momento onde ambas as partes ir\xe3o se conhecer e negociar, o candidato ir\xe1 oferecer os seus servi\xe7os e habilidades em troca de um sal\xe1rio. Se ambos est\xe3o nessa etapa, ent\xe3o ambos est\xe3o interessados, ou pelo menos deveriam.\\n\\n### Pergunte\\n\\n\xc9 importante que o candidato fa\xe7a perguntas sobre a empresa, e que n\xe3o seja passivo durante a conversa. Talvez esse seja um dos maiores erros que os candidatos cometam.\\n\\nPerguntar sobre o futuro local de trabalho n\xe3o deveria ser um tabu. Algumas das perguntas que podem ajudar a conhecer melhor a empresa:\\n\\n- Qual a faixa salarial para essa vaga?\\n- Quantos candidatos est\xe3o concorrendo comigo?\\n- Como a empresa lida com horas extras? As pessoas trabalham mais que o combinado?\\n- Como tem sido as \xfaltimas entregas? Houveram muitos atrasos? Se sim, por qu\xea?\\n- Cite 3 pontos que fazem voc\xea amar seu trabalho.\\n- Cite 3 pontos que fazem voc\xea pensar em trocar de emprego.\\n- Quais os objetivos da empresa para os pr\xf3ximos 5 anos?\\n- Qual foi o crescimento da empresa no \xfaltimo ano?\\n\\nAs perguntas n\xe3o precisam ser exatamente essas, o que importa aqui \xe9 colher o m\xe1ximo de informa\xe7\xf5es sobre o local de trabalho, e caso n\xe3o seja do seu interesse, poder\xe1 agradecer e encerrar a entrevista.\\n\\n### Direto ao ponto\\n\\nNem sempre o recrutador conduzir\xe1 bem a entrevista, ent\xe3o ele pode acabar te dando corda demais e voc\xea come\xe7ar a falar sem parar. Procure n\xe3o falar de coisas que n\xe3o ir\xe3o agregar para a entrevista. Falar demais n\xe3o significa que voc\xea est\xe1 indo bem. Responda bem as perguntas, e se necess\xe1rio pe\xe7a para o recrutador reformular a pergunta.\\n\\n### Autopromo\xe7\xe3o\\n\\nDeixe claro o que voc\xea faz bem, em outras palavras, destaque as suas habilidades. Se voc\xea \xe9 bom em fazer a atividade X, ent\xe3o fale disso sem vergonha. O recrutador precisa entender que voc\xea \xe9 realmente bom nisso, ele n\xe3o tem bola de cristal.\\n\\n## Lista de requisitos\\n\\nGeralmente a lista de requisitos das vagas \xe9 extensa, e dificilmente algu\xe9m ter\xe1 dom\xednio sobre todas elas, e isso \xe9 proposital. Muita gente deixa de aplicar para a vaga s\xf3 de olhar a lista de requisitos, e com isso uma grande parcela de curiosos j\xe1 caem fora.\\n\\n### Arrisque\\n\\nO candidato deve arriscar mesmo que n\xe3o cumpra toda a lista de requisitos, e eu vou explicar o porqu\xea. Imagine que a vaga tenha 7 requisitos, e algu\xe9m se candidata com apenas 4 dos 7 requisitos, se voc\xea tiver 5 requisitos, j\xe1 estar\xe1 em vantagem.\\n\\nSe o recrutador n\xe3o encontrar algu\xe9m melhor do que voc\xea e com mais requisitos preenchidos, voc\xea ser\xe1 escolhido. Portanto, as suas chances aumentam quando voc\xea se candidata.\\n\\n## Mais algumas considera\xe7\xf5es\\n\\nN\xe3o faz sentido n\xe3o fazer v\xe1rios processos ao mesmo tempo, a n\xe3o ser que voc\xea tenha um objetivo espec\xedfico. Do contr\xe1rio, quanto mais entrevistas, maiores ser\xe3o as chances. A melhor coisa \xe9 ser aprovado em mais de uma vaga e poder renegociar as condi\xe7\xf5es, e escolher a que mais gostou."},{"id":"aprenda-a-testar-pt2","metadata":{"permalink":"/blog/aprenda-a-testar-pt2","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-10-19-aprenda-a-testar-pt2/index.md","source":"@site/blog/2022-10-19-aprenda-a-testar-pt2/index.md","title":"Aprenda a escrever testes - Parte 2","description":"Como utilizar um framework de testes no Node?","date":"2022-10-19T00:00:00.000Z","formattedDate":"19 de outubro de 2022","tags":[{"label":"teste","permalink":"/blog/tags/teste"},{"label":"cobertura","permalink":"/blog/tags/cobertura"},{"label":"qualidade","permalink":"/blog/tags/qualidade"},{"label":"testes automatizados","permalink":"/blog/tags/testes-automatizados"},{"label":"vitest","permalink":"/blog/tags/vitest"}],"readingTime":4.135,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"aprenda-a-testar-pt2","title":"Aprenda a escrever testes - Parte 2","description":"Como utilizar um framework de testes no Node?","keywords":["teste","cobertura","qualidade","testes automatizados","vitest"],"image":"/img/test.jpg","tags":["teste","cobertura","qualidade","testes automatizados","vitest"],"authors":"brunelli"},"prevItem":{"title":"Dicas para melhorar as chances em entrevistas","permalink":"/blog/dicas-para-melhorar-as-chances-em-entrevistas"},"nextItem":{"title":"Aprenda a escrever testes - Parte 1","permalink":"/blog/aprenda-a-testar-pt1"}},"content":"Como configurar e utilizar um framework de testes no Node utilizando Typescript? Temos v\xe1rias op\xe7\xf5es excelentes para isso, e por esse motivo irei escolher a mais f\xe1cil para o cen\xe1rio de Node + Typescript.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Como escolher um framework de testes?\\n\\nPrimeiro devo avaliar quais os cen\xe1rios quero testar, se \xe9 frontend ou backend, e se vou utilizar Javascript ou Typescript.\\n\\nVou utilizar Node + Typescript nos exemplos, e isso faz a minha lista ficar restrita a alguns nomes:\\n\\n- [Jest](https://jestjs.io/pt-BR/)\\n- [Mocha](https://mochajs.org/)\\n- [Vitest](https://vitest.dev/)\\n\\n> Jest e Mocha necessitam de um parser de Typescript para executar, como o ts-jest ou ts-node, o que pode complicar para quem est\xe1 come\xe7ando, j\xe1 que o arquivo de configura\xe7\xe3o fica muito complexo nesses cen\xe1rios.\\n\\nN\xe3o quero abrir m\xe3o do Typescript e nem da facilidade de configura\xe7\xe3o, ent\xe3o irei escolher o Vitest. Na p\xe1gina inicial do Vitest cont\xe9m o [Get Started](https://vitest.dev/guide/) contendo alguns exemplos de instala\xe7\xe3o e configura\xe7\xe3o.\\n\\n## Configurando o projeto\\n\\n### Setup Node + Typescript\\n\\nVou criar uma pasta vazia, com um nome qualquer.\\n\\n```sh\\nmkdir vitest-typescript-example\\n```\\n\\nCom o meu Visual Studio Code aberto nessa pasta, vou abrir um terminal integrado e iniciar o Node, e instalar as depend\xeancias b\xe1sicas para o Typescript funcionar.\\n\\n```sh\\nnpm init -y\\n\\nnpm install -D typescript @types/node\\n```\\n\\nAgora vou criar o tsconfig.json, que \xe9 o arquivo de configura\xe7\xe3o do Typescript. Ele ir\xe1 gerar uma configura\xe7\xe3o default, e vou manter ela.\\n\\n```sh\\nnpx tsc --init\\n```\\n\\nPronto, meu projeto j\xe1 est\xe1 configurado com Node + Typescript.\\n\\n### Setup Vitest\\n\\nAgora vou instalar o Vitest como depend\xeancia de desenvolvimento.\\n\\n```sh\\nnpm install -D vitest\\n```\\n\\nO Vitest precisa de um arquivo de configura\xe7\xe3o para poder executar. Na pr\xf3pria documenta\xe7\xe3o tem um exemplo simples. Vou criar um arquivo **vitest.config.ts** na raiz, e adicionar a configura\xe7\xe3o b\xe1sica.\\n\\n```ts title=\\"vitest.config.ts\\"\\nimport { defineConfig } from \\"vitest/config\\";\\n\\nexport default defineConfig({\\n test: {\\n reporters: \\"verbose\\",\\n },\\n});\\n```\\n\\nVeja como o arquivo de configura\xe7\xe3o \xe9 enxuto, bem diferente dos outros frameworks citados no come\xe7o do post. [Na documenta\xe7\xe3o tenho acesso a API](https://vitest.dev/config/), e como posso personalizar o **defineConfig()**. N\xe3o vou configurar nada extra, j\xe1 est\xe1 \xf3timo como est\xe1.\\n\\n> Veja que configurei **reporters** como **verbose**, isso para que eu possa obter todas as informa\xe7\xf5es do teste no terminal.\\n\\n### Configurando o package.json\\n\\nQuando eu executei o **npm init -y**, foi gerado um arquivo **package.json** na raiz, com algumas configura\xe7\xf5es bem simples. Dentro de **scripts** tem um script **test**. Vou edit\xe1-lo.\\n\\n```json title=\\"package.json\\"\\n...\\n\\"scripts\\": {\\n \\"test\\": \\"vitest --run\\"\\n}\\n...\\n```\\n\\n> Agora quando eu executar `npm run test` no terminal, o vitest ir\xe1 executar meus testes. Como n\xe3o temos nenhum teste no momento, ele tentar\xe1 rodar e retornar\xe1 um erro dizendo que nenhum teste foi encontrado.\\n\\n## Escrevendo o primeiro teste\\n\\nVou criar uma pasta **test** na raiz, e criar um arquivo chamado **primeiro-teste.test.ts** dentro dela. Em seguida irei adicionar alguns cen\xe1rios.\\n\\n> \xc9 importante respeitar a extens\xe3o **.test.ts**, pois o Vitest procura por essa extens\xe3o durante a execu\xe7\xe3o.\\n\\n```ts title=\\"primeiro-teste.test.ts\\"\\nimport { describe, test, expect } from \\"vitest\\";\\n\\ndescribe(\\"Cont\xe9m um conjunto de testes, que ser\xe1 executado um a um\\", () => {\\n test(\\"Deve somar 20 + 50 e retornar 70\\", () => {\\n expect(20 + 50).toBe(70);\\n });\\n\\n test(\\"Deve concatenar a palavra \'Ol\xe1\' com a palavra \'Mundo\' e retornar \'Ol\xe1 Mundo\'\\", () => {\\n expect(\\"Ol\xe1 \\" + \\"Mundo\\").toBe(\\"Ol\xe1 Mundo\\");\\n });\\n\\n test(\\"Deve retornar que o Palmeiras n\xe3o tem mundial\\", () => {\\n const temMundial = false;\\n expect(temMundial).toBeFalsy();\\n });\\n\\n test(\\"Deve conter todos os valores do objeto fornecido\\", () => {\\n const meuObjeto = {\\n nome: \\"Palmeiras\\",\\n temMundial: false,\\n cor: \\"Verde\\",\\n };\\n expect(meuObjeto).toEqual({\\n nome: \\"Palmeiras\\",\\n temMundial: false,\\n cor: \\"Verde\\",\\n });\\n });\\n});\\n```\\n\\nAgora vou abrir o terminal e executar `npm run test`, e o Vitest ir\xe1 executar e retornar todos esses cen\xe1rios no terminal, verde caso tenha passado, e vermelho caso tenha reprovado algum.\\n\\n### Sucesso\\n\\n![](vitest-sucess.png)\\n\\n### Erro\\n\\nAdicionei um campo a mais no objeto do \xfaltimo teste, **por\xe9m n\xe3o adicionei no expect**, logo o teste fez a compara\xe7\xe3o e reprovou, pois os objetos n\xe3o s\xe3o mais iguais.\\n\\n> Veja como a inteface \xe9 amig\xe1vel, ela exibe com muita clareza qual teste reprovou e o motivo.\\n\\n![](vitest-error.png)\\n\\n## Resumo\\n\\n- Preciso saber em qual cen\xe1rio vou escrever meus testes, se \xe9 frontend ou backend, pois cada um possu\xed a ferramenta certa para o cen\xe1rio.\\n- Se eu ainda n\xe3o sei testar, devo procurar o framework mais f\xe1cil para aprender. Nesse caso foi o Vitest, pois ele tem uma filosofia **less config**.\\n- A documenta\xe7\xe3o cont\xe9m tudo que preciso para configurar o framework, e ainda cont\xe9m v\xe1rios exemplos.\\n- O Vitest procura por arquivos que tenham a extens\xe3o **.test.ts**.\\n- Os resultados dos testes s\xe3o exibidos no terminal, de uma forma muito amig\xe1vel.\\n- Posso executar o comando `npm run test` quantas vezes quiser, e o teste executar\xe1 em mil\xe9simos de segundos.\\n- Automatizar \xe9 bem melhor que testar manualmente.\\n\\n### Reposit\xf3rio com o c\xf3digo\\n\\n[https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-2](https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-2)"},{"id":"aprenda-a-testar-pt1","metadata":{"permalink":"/blog/aprenda-a-testar-pt1","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-10-17-aprenda-a-testar-pt1/index.md","source":"@site/blog/2022-10-17-aprenda-a-testar-pt1/index.md","title":"Aprenda a escrever testes - Parte 1","description":"Para que servem os testes? Como fa\xe7o para escrever um teste?","date":"2022-10-17T00:00:00.000Z","formattedDate":"17 de outubro de 2022","tags":[{"label":"teste","permalink":"/blog/tags/teste"},{"label":"cobertura","permalink":"/blog/tags/cobertura"},{"label":"qualidade","permalink":"/blog/tags/qualidade"},{"label":"testes automatizados","permalink":"/blog/tags/testes-automatizados"}],"readingTime":3.465,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"aprenda-a-testar-pt1","title":"Aprenda a escrever testes - Parte 1","description":"Para que servem os testes? Como fa\xe7o para escrever um teste?","keywords":["teste","cobertura","qualidade","testes automatizados"],"image":"/img/test.jpg","tags":["teste","cobertura","qualidade","testes automatizados"],"authors":"brunelli"},"prevItem":{"title":"Aprenda a escrever testes - Parte 2","permalink":"/blog/aprenda-a-testar-pt2"},"nextItem":{"title":"Como validar dados de uma forma elegante","permalink":"/blog/como-validar-dados-de-uma-forma-elegante"}},"content":"Para que servem os testes? Como fa\xe7o para escrever um teste? Esse tema ainda pode ser muito confuso para quem est\xe1 come\xe7ando a programar, e at\xe9 para quem j\xe1 possu\xed mais tempo de estrada.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Afinal, para que servem os testes?\\n\\nAntes de responder essa pergunta, vamos entender de que testes estamos falando. A primeira coisa que me vem a mente quando algu\xe9m me pede para testar a aplica\xe7\xe3o \xe9: **executar a aplica\xe7\xe3o e fazer alguma a\xe7\xe3o e ver se o resultado esperado foi alcan\xe7ado.**\\n\\nEsse conceito est\xe1 correto, e de fato isso \xe9 \\"testar a aplica\xe7\xe3o\\". Entretanto uma aplica\xe7\xe3o ir\xe1 conter muitos recursos, que se forem testadas de forma manual, levar\xe1 muito tempo e desgastar\xe1 quem est\xe1 testando. Tamb\xe9m haver\xe1 possibilidades de erros humanos durante esse processo.\\n\\n### Testes automatizados\\n\\nPara isso existem os **testes automatizados**, que \xe9 uma forma de **executar um script que ir\xe1 testar todas as a\xe7\xf5es da aplica\xe7\xe3o**, de forma autom\xe1tica, **simulando a intera\xe7\xe3o humana** e observando se **o resultado esperado foi alca\xe7ado**.\\n\\nOs benef\xedcios dessa pr\xe1tica s\xe3o muitos, visto que, se o teste \xe9 automatizado, posso execut\xe1-lo e assim esperar para ver se todas as funcionalidades do sistema **ainda est\xe3o ok e se comportando como deveriam**. Dessa forma \xe9 poss\xedvel simular toda a intera\xe7\xe3o humana em todos os m\xf3dulos do sistema, **e em poucos segundos.**\\n\\n### Requisitos para escrever um teste\\n\\nPrimeiramente devemos entender as regras de neg\xf3cio da aplica\xe7\xe3o, e saber como devem se comportar em diferentes situa\xe7\xf5es.\\n\\nVamos supor que nosso sistema recebe dois n\xfameros e retorna a soma desses n\xfameros para o usu\xe1rio. Para escrever um teste em cima dessa funcionalidade, deveremos prover **dois n\xfameros de entrada** e observar se o valor retornado **\xe9 a soma dos dois n\xfameros fornecidos**. Se o resultado de fato for a soma dos dois n\xfameros fornecidos, ent\xe3o o teste passar\xe1, do contr\xe1rio ele reprovar\xe1.\\n\\n### Exemplo 1\\n\\n```ts title=\\"calculadora.ts\\"\\nexport class Calculadora {\\n somar(numero1: number, numero2: number) {\\n return numero1 + numero2;\\n }\\n}\\n```\\n\\n```ts title=\\"calculadora.test.ts\\"\\nimport { Calculadora } from \\"./calculadora\\";\\n\\ntest(\\"Deve somar 10 + 10 e retornar 20\\", () => {\\n const calculadora = new Calculadora();\\n const resultado = calculadora.somar(10, 10);\\n\\n expect(resultado).toBe(20); // true, logo o teste passar\xe1.\\n});\\n```\\n\\n### Exemplo 2\\n\\nAgora, se eu alterar a regra de neg\xf3cios do m\xe9todo **somar**, e faz\xea-lo retornar a multiplica\xe7\xe3o ao inv\xe9s da soma, **nosso teste ir\xe1 reprovar**, pois ele espera que o resultado seja **20** e n\xe3o **100**.\\n\\n```ts title=\\"calculadora.ts\\"\\nexport class Calculadora {\\n somar(numero1: number, numero2: number) {\\n return numero1 * numero2;\\n }\\n}\\n```\\n\\n```ts title=\\"calculadora.test.ts\\"\\nimport { Calculadora } from \\"./calculadora\\";\\n\\ntest(\\"Deve somar 10 + 10 e retornar 20\\", () => {\\n const calculadora = new Calculadora();\\n const resultado = calculadora.somar(10, 10);\\n\\n console.log(resultado); // 100\\n\\n expect(resultado).toBe(20); // 100 != 20, logo \xe9 false, o teste reprovar\xe1.\\n});\\n```\\n\\n## O que eu devo testar?\\n\\nPosso testar as regras de neg\xf3cio de uma classe **(unidade)**, a integra\xe7\xe3o de um servi\xe7o com o banco de dados **(integra\xe7\xe3o)** e o comportamento geral do sistema **(de ponta a ponta)**.\\n\\nLogo temos testes de unidade, testes de integra\xe7\xe3o e testes de ponta a ponta.\\n\\nPara que haja uma excelente cobertura, devemos utilizar todos esses tipos de testes. Alguns desenvolvedores optam por utilizar apenas um desses tipos de testes, o que pode resultar em **uma ou v\xe1rias lacunas na cobertura do sistema.**\\n\\n## Resumo\\n\\n- Testar \xe9 executar uma a\xe7\xe3o no sistema e observar se o resultado obtivo \xe9 de fato esperado.\\n- Testes automatizados excluem a necessidade de testes humanos e manuais.\\n- Os tipos de testes s\xe3o: unidade, integra\xe7\xe3o e de ponta a ponta.\\n- Testar garante que o comportamento do sistema ser\xe1 preservado. Em caso de quebra, os testes avisar\xe3o onde ocorreu a quebra.\\n- Se um sistema n\xe3o possu\xed testes automatizados, n\xe3o h\xe1 como o desenvolvedor saber se a altera\xe7\xe3o que ele fez quebrou o sistema. Ele ter\xe1 que testar manualmente, e em muitos dos casos poder\xe3o ocorrer falhas humanas e o sistema poder\xe1 ir para produ\xe7\xe3o com defeito **(em muitos casos isso pode significar preju\xedzo financeiro para a empresa, e at\xe9 fal\xeancia da mesma).**\\n\\n### Reposit\xf3rio com o c\xf3digo\\n\\n[https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-1](https://github.com/mrbrunelli/vitest-typescript-example/tree/aprenda-a-testar-parte-1)"},{"id":"como-validar-dados-de-uma-forma-elegante","metadata":{"permalink":"/blog/como-validar-dados-de-uma-forma-elegante","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-02-21-como-validar-dados-de-uma-forma-elegante/index.md","source":"@site/blog/2022-02-21-como-validar-dados-de-uma-forma-elegante/index.md","title":"Como validar dados de uma forma elegante","description":"Hoje vou ensinar uma maneira bem elegante de validar dados no Javascript. E o mais legal, usando somente os recursos nativos da linguagem!","date":"2022-02-21T00:00:00.000Z","formattedDate":"21 de fevereiro de 2022","tags":[{"label":"validador","permalink":"/blog/tags/validador"},{"label":"javascript","permalink":"/blog/tags/javascript"},{"label":"every","permalink":"/blog/tags/every"}],"readingTime":3.72,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"como-validar-dados-de-uma-forma-elegante","title":"Como validar dados de uma forma elegante","description":"Hoje vou ensinar uma maneira bem elegante de validar dados no Javascript. E o mais legal, usando somente os recursos nativos da linguagem!","keywords":["validator","javascript","array"],"image":"/img/every.png","tags":["validador","javascript","every"],"authors":"brunelli"},"prevItem":{"title":"Aprenda a escrever testes - Parte 1","permalink":"/blog/aprenda-a-testar-pt1"},"nextItem":{"title":"Aprenda a criar snippets no VS Code","permalink":"/blog/aprenda-a-criar-snippets-no-vscode"}},"content":"Salve galera, tudo bem com voc\xeas?\\nHoje vou ensinar uma maneira bem elegante de validar dados no Javascript. E o mais legal, usando somente os recursos nativos da linguagem.\\n\\n## Entendendo o cen\xe1rio\\n\\nImagine o seguinte cen\xe1rio, voc\xea precisa construir uma API que ir\xe1 receber os dados de pessoas que querem receber notifica\xe7\xf5es regulares sobre seu cat\xe1logo de produtos.\\n\\n\x3c!-- truncate --\x3e\\n\\n### Requisitos\\n\\nPara sua regra de neg\xf3cios funcionar, voc\xea ir\xe1 precisar dos seguintes requisitos:\\n\\n- Sua API deve ser constru\xedda da forma mais simples poss\xedvel, se poss\xedvel uma [Lambda](https://aws.amazon.com/pt/lambda/).\\n- A rota deve ser do tipo POST.\\n- Receber do cliente nome, sobrenome, email e o cep.\\n- Todos os dados s\xe3o obrigat\xf3rios.\\n\\n## Implementa\xe7\xe3o do endpoint\\n\\nVamos pular toda a parte da constru\xe7\xe3o da API. Vamos prosseguir como se toda a infraestrutura j\xe1 estivesse montada. Algo mais ou menos assim:\\n\\n```js title=\\"subscribers.js\\"\\nexports.subscribers = async (req, res) => {\\n try {\\n const { first_name, last_name, email, cep } = red.body;\\n\\n await subscribersRepository.insert({\\n first_name,\\n last_name,\\n email,\\n cep,\\n });\\n\\n return res.status(200).json({\\n message:\\n \\"Obrigado por assinar nosso cat\xe1logo! Em breve enviaremos a edi\xe7\xe3o desse m\xeas por e-mail.\\",\\n });\\n } catch (error) {\\n return res.status(400).json({\\n message: error.message,\\n });\\n }\\n};\\n```\\n\\nLembra que eu disse que os dados do cliente devem ser obrigat\xf3rios? Em nenhum momento n\xf3s estamos validando isso. Da maneira como os dados est\xe3o vindo, estou repassando para meu repository.\\n\\n## Possibilidades\\n\\n### Condicionais: `if else`\\n\\nA maneira mais simples de satisfazer nossa valida\xe7\xe3o \xe9 criar um `if` para cada campo e lan\xe7ar uma exce\xe7\xe3o caso algum retorne `false`.\\n\\n### Loops padr\xf5es: `for`\\n\\nOutra maneira \xe9 criar um `for` e percorrer o `req.body` com o `Object.keys` e verificar campo a campo.\\n\\n### Conhecendo o `every`\\n\\nMas nosso querido Javascript j\xe1 possu\xed um maravilhoso recurso que far\xe1 todo trabalho pesado para n\xf3s, e tudo isso de forma nativa, sem precisarmos instalar um pacote externo.\\n\\nO [every](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/every) \xe9 um m\xe9todo que itera nosso array e retorna `true` somente se todos os \xedndices retornarem `true`. Com ele \xe9 poss\xedvel percorrer nosso `req.body`, e caso n\xe3o tenha um determinado campo, automagicamente retornar\xe1 `false`, interrompendo dessa forma a itera\xe7\xe3o.\\n\\nVamos ver como ficar\xe1:\\n\\n```js title=\\"subscribersValidator.js\\"\\nclass SubscriberValidator {\\n static isValid(data = {}) {\\n const requiredFields = [\\"first_name\\", \\"last_name\\", \\"email\\", \\"cep\\"];\\n return requiredFields.every((field) => data.hasOwnProperty(field));\\n }\\n}\\n```\\n\\nNote que para cada campo iterado do nosso `requiredFields`, testamos com o [hasOwnProperty](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/HasOwnProperty) se `field` est\xe1 presente no objeto `data`.\\n\\n## Implementando o nosso validador\\n\\nVoltemos ao c\xf3digo do nosso endpoint, agora com nosso `SubscriberValidator`.\\n\\n```js title=\\"subscribers.js\\"\\nconst SubscriberValidator = require(\\"./validators/subscriber-validator\\");\\n\\nexports.subscribers = async (req, res) => {\\n try {\\n if (!SubscriberValidator.isValid(req.body)) {\\n throw new Error(\\"Favor preencher todos os campos.\\");\\n }\\n\\n const { first_name, last_name, email, cep } = red.body;\\n\\n await subscribersRepository.insert({\\n first_name,\\n last_name,\\n email,\\n cep,\\n });\\n\\n return res.status(200).json({\\n message:\\n \\"Obrigado por assinar nosso cat\xe1logo! Em breve enviaremos a edi\xe7\xe3o desse m\xeas por e-mail.\\",\\n });\\n } catch (error) {\\n return res.status(400).json({\\n message: error.message,\\n });\\n }\\n};\\n```\\n\\nVeja como ficou enxuta nossa feature. E o melhor \xe9 que o `every` interrompe imediatamente o loop e retorna `false` caso algum campo n\xe3o esteja l\xe1 no `req.body`.\\n\\n### B\xf4nus\\n\\nPodemos refatorar nosso `SubscriberValidator` e retornar o campo que o usu\xe1rio esqueceu de informar:\\n\\n```js title=\\"subscribersValidator.js\\"\\nclass SubscriberValidator {\\n static isValid(data = {}) {\\n const requiredFields = [\\"first_name\\", \\"last_name\\", \\"email\\", \\"cep\\", \\"phone\\"];\\n let missingField;\\n\\n const isValid = requiredFields.every((field) => {\\n const hasField = data.hasOwnProperty(field);\\n if (!hasField) missingField = field;\\n return hasField;\\n });\\n\\n return {\\n isValid,\\n missingField,\\n };\\n }\\n}\\n```\\n\\nPodemos refatorar nosso endpoint e retornar o campo que est\xe1 faltando na `response`. Dessa forma o usu\xe1rio saber\xe1 onde errou:\\n\\n```js title=\\"subscribers.js\\"\\nconst SubscriberValidator = require(\\"./validators/subscriber-validator\\");\\n\\nexports.subscribers = async (req, res) => {\\n try {\\n const { isValid, missingField } = SubscriberValidator.isValid(req.body);\\n\\n if (!isValid) {\\n throw new Error(`O campo \'${missingField}\' \xe9 obrigat\xf3rio!`);\\n }\\n\\n const { first_name, last_name, email, cep } = red.body;\\n\\n await subscribersRepository.insert({\\n first_name,\\n last_name,\\n email,\\n cep,\\n });\\n\\n return res.status(200).json({\\n message:\\n \\"Obrigado por assinar nosso cat\xe1logo! Em breve enviaremos a edi\xe7\xe3o desse m\xeas por e-mail.\\",\\n });\\n } catch (error) {\\n return res.status(400).json({\\n message: error.message,\\n });\\n }\\n};\\n```\\n\\n## Conclus\xe3o\\n\\nUtilizamos somente recursos nativos da nossa linguagem e evitamos pacotes externos desnecess\xe1rios.\\n\\nCaso sua API precisasse de muitas valida\xe7\xf5es, grava\xe7\xe3o de logs, mensagens super refinadas, ai sim seria melhor utilizar um pacote para fazer esse trabalho.\\n\\nMas aqui era algo extremamente simples.\\n\\nEspero que tenha gostado! Compartilhe essa postagem com seus amigos e colegas de trabalho! Vou ficando por aqui, at\xe9 a pr\xf3xima!"},{"id":"aprenda-a-criar-snippets-no-vscode","metadata":{"permalink":"/blog/aprenda-a-criar-snippets-no-vscode","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-02-20-aprenda-a-criar-snippets-no-vscode/index.md","source":"@site/blog/2022-02-20-aprenda-a-criar-snippets-no-vscode/index.md","title":"Aprenda a criar snippets no VS Code","description":"Hoje quero compartilhar com voc\xeas algo bem bacana, que \xe9 criar seus pr\xf3prios snippets no VS Code...","date":"2022-02-20T00:00:00.000Z","formattedDate":"20 de fevereiro de 2022","tags":[{"label":"snippets","permalink":"/blog/tags/snippets"},{"label":"vscode","permalink":"/blog/tags/vscode"},{"label":"produtividade","permalink":"/blog/tags/produtividade"}],"readingTime":2.705,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"aprenda-a-criar-snippets-no-vscode","title":"Aprenda a criar snippets no VS Code","description":"Hoje quero compartilhar com voc\xeas algo bem bacana, que \xe9 criar seus pr\xf3prios snippets no VS Code...","keywords":["snippets","vscode","visual studio code"],"image":"/img/snippets.png","tags":["snippets","vscode","produtividade"],"authors":"brunelli"},"prevItem":{"title":"Como validar dados de uma forma elegante","permalink":"/blog/como-validar-dados-de-uma-forma-elegante"},"nextItem":{"title":"Criando atalhos para o git","permalink":"/blog/criando-atalhos-para-o-git"}},"content":"Salve galera, tudo bem?\\n\\nHoje quero compartilhar com voc\xeas algo bem bacana, que \xe9 criar seus pr\xf3prios snippets no VS Code.\\n\\n## O que \xe9 um Snippet?\\n\\n\x3c!-- truncate --\x3e\\n\\n### Um atalho\\n\\nNada mais \xe9 que um atalho para a cria\xe7\xe3o de um trecho de c\xf3digo. Pense em um c\xf3digo simples como esse:\\n\\n```js title=\\"L\xf3gica de um loop no Javascript\\"\\nfor (const item of items) {\\n console.log(item);\\n}\\n```\\n\\nEsse tipo de c\xf3digo tende a se repetir muito durante nosso desenvolvimento rotineiro. Com isso, pode ficar chato escrever a mesma sintaxe toda vez.\\n\\n### Produtividade\\n\\n\xc9 ai que a m\xe1gica acontece! Que tal digitiar apenas `newfor` e o VS Code cri\xe1-lo para voc\xea? Sim \xe9 poss\xedvel!\\n\\n## Vamos come\xe7ar\\n\\n### Primeiro passo\\n\\nVamos criar o arquivo principal para nossos snippets.\\n\\nCom seu VS Code aberto, digite Ctrl+Shift+P e digite **snippets** na barra que apareceu, selecione a op\xe7\xe3o **Preferences: Configure User Snippets** e depois **New Global Snippet File**.\\n\\nAbrir\xe1 uma caixinha para voc\xea digitar o nome do seu arquivo de snippets. Voc\xea pode colocar qualquer nome, eu vou colocar **my-snippets**.\\n\\n### Segundo passo\\n\\nVai abrir um arquivo mais ou menos assim:\\n\\n```json title=\\"my-snippets.code-snippets\\"\\n{\\n // Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and\\n // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope\\n // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is\\n // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:\\n // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.\\n // Placeholders with the same ids are connected.\\n // Example:\\n // \\"Print to console\\": {\\n // \\t\\"scope\\": \\"javascript,typescript\\",\\n // \\t\\"prefix\\": \\"log\\",\\n // \\t\\"body\\": [\\n // \\t\\t\\"console.log(\'$1\');\\",\\n // \\t\\t\\"$2\\"\\n // \\t],\\n // \\t\\"description\\": \\"Log output to console\\"\\n // }\\n}\\n```\\n\\nApague tudo e monte essa estrutura:\\n\\n```json title=\\"my-snippets.code-snippets\\"\\n{\\n \\"newfor\\": {\\n \\"scope\\": \\"\\",\\n \\"prefix\\": \\"\\",\\n \\"body\\": [],\\n \\"description\\": \\"\\"\\n }\\n}\\n```\\n\\n#### Significado de cada atributo\\n\\n- **newfor**: \xe9 o nome do nosso snippet\\n- **scope**: em quais tipos de arquivos seu snippet executar\xe1\\n- **prefix**: atalho para seu snippet\\n- **body**: linhas que seu snippet ir\xe1 gerar\\n- **description**: descri\xe7\xe3o do que seu snippet ir\xe1 gerar (n\xe3o obrigat\xf3rio)\\n\\n### Terceiro passo\\n\\nAgora que sabemos o que cada campo significa, vamos preenche-los com nosso c\xf3digo:\\n\\n```json title=\\"my-snippets.code-snippets\\"\\n{\\n \\"newfor\\": {\\n \\"scope\\": \\"javascript, typescript\\",\\n \\"prefix\\": \\"newfor\\",\\n \\"body\\": [\\"for (const item of items) {\\", \\"console.log(item)\\", \\"}\\"],\\n \\"description\\": \\"cria um loop com for\\"\\n }\\n}\\n```\\n\\n### Quarto passo\\n\\nPronto, salve o seu arquivo de snippet, v\xe1 para um arquivo **.js** ou **.ts** e fa\xe7a o teste. Digite `newfor` e aperte Ctrl+ Space bar.\\n\\nDever\xe1 aparecer o nome do seu snippet no autocomplete, dessa forma:\\n![](./screenshot.png)\\n\\nS\xf3 apertar Enter que seu c\xf3digo ser\xe1 gerado. Legal n\xe9?\\n\\n## Conclus\xe3o\\n\\nCaso voc\xea tenha chegado at\xe9 aqui e n\xe3o tenha funcionado, volte desde o come\xe7o e tente novamente com calma, voc\xea deve ter deixado algo passar. \xc9 bem simples.\\n\\nEspero que tenha gostado! Se foi \xfatil para voc\xea, compartilhe com seus amigos e colegas de trabalho!\\n\\nAt\xe9 a pr\xf3xima!"},{"id":"criando-atalhos-para-o-git","metadata":{"permalink":"/blog/criando-atalhos-para-o-git","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2022-02-19-criando-atalhos-para-o-git/index.md","source":"@site/blog/2022-02-19-criando-atalhos-para-o-git/index.md","title":"Criando atalhos para o git","description":"Hoje vou ensinar como criar atalhos para o git que v\xe3o aumentar tua produtividade. Sem muita enrola\xe7\xe3o, vamos direto para a pr\xe1tica...","date":"2022-02-19T00:00:00.000Z","formattedDate":"19 de fevereiro de 2022","tags":[{"label":"git","permalink":"/blog/tags/git"},{"label":"aliases","permalink":"/blog/tags/aliases"}],"readingTime":2.73,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"criando-atalhos-para-o-git","title":"Criando atalhos para o git","description":"Hoje vou ensinar como criar atalhos para o git que v\xe3o aumentar tua produtividade. Sem muita enrola\xe7\xe3o, vamos direto para a pr\xe1tica...","keywords":["git","aliases","shortcut"],"image":"/img/git.jpg","tags":["git","aliases"],"authors":"brunelli"},"prevItem":{"title":"Aprenda a criar snippets no VS Code","permalink":"/blog/aprenda-a-criar-snippets-no-vscode"},"nextItem":{"title":"Como contornar a dor de escrever um teste unit\xe1rio?","permalink":"/blog/como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio"}},"content":"![Git Logo](/img/git.jpg)\\n\\nOl\xe1, tudo bem?\\n\\nHoje vou ensinar como criar atalhos para o **git** que v\xe3o aumentar tua produtividade.\\nSem muita enrola\xe7\xe3o, vamos direto para a pr\xe1tica.\\n\\n## Escolher o editor de textos padr\xe3o\\n\\nAntes de come\xe7ar, \xe9 bom configurar o editor de texto de sua prefer\xeancia. Eu vou utilizar o [Vim](https://www.vim.org/), mas voc\xea pode utilizar o Code, Nano etc.\\n\\n\x3c!-- truncate --\x3e\\n\\n### Configurar editor\\n\\nSubistitua o **\\"vim\\"** pelo editor de sua preferencia. Segue a lista dos mais utilizados:\\n\\n- vim\\n- nano\\n- code\\n- gedit\\n\\n```bash title=\\"Definir editor padr\xe3o\\"\\ngit config --global core.editor vim\\n```\\n\\n## Prontos para come\xe7ar\\n\\n### Abrir arquivo de configura\xe7\xf5es do git\\n\\nIsso abrit\xe1 seu arquivo de configura\xe7\xf5es do git em seu editor de texto.\\n\\n```bash title=\\"Abrindo meu arquivo de configura\xe7\xf5es\\"\\ngit config --global --edit\\n```\\n\\n### Adicionar usu\xe1rio\\n\\n\xc9 importante adicionar um usu\xe1rio ao seu git config, pois ele ser\xe1 utilizado em seus commits.\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n```\\n\\n## Atalhos\\n\\n### git status\\n\\nVamos definir nosso primeiro atalho, o `git status -s`. Esse comando exibe o status atual da sua **stage area**, quais arquivos est\xe3o commitados, e quais foram modificados.\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n\\n[alias]\\n s = !git status -s\\n```\\n\\nAgora o status dos seus commits ficar\xe3o mais clean.\\n\\n### git add && git commit\\n\\nEsses dois s\xe3o muito utilizados, que tal torn\xe1-los em um \xfanico comando?\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n\\n[alias]\\n s = !git status -s\\n c = !git add --all && git commit -m\\n```\\n\\nAgora quando digitarmos `git c` em nosso terminal, nosso **alias** ir\xe1 adicionar e commitar ao mesmo tempo, s\xf3 vamos precisar informar a mensagem. Exemplo:\\n\\n```bash title=\\"Configurando meu git\\"\\ngit c \'feat: agora ficou mais f\xe1cil!\'\\n```\\n\\n### git pull/push origin HEAD\\n\\nOutro comando muito utilizado. Vamos simplific\xe1-lo.\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n\\n[alias]\\n s = !git status -s\\n c = !git add --all && git commit -m\\n pullo = !git pull origin HEAD\\n pusho = !git push origin HEAD\\n```\\n\\nAgora podemos usar essa combina\xe7\xe3o:\\n\\n```bash\\ngit c \'feat: adicionar simplicidade\' && git pusho\\n```\\n\\n### git log\\n\\nQuem nunca se perdeu ao utilizar um `git log`? S\xe3o muitas informa\xe7\xf5es de uma vez. Vamos simplificar:\\n\\n```bash title=\\"Configurando meu git\\"\\n[user]\\n email = meu_email@mail.com\\n name = nome_que_aparecera_nos_commits\\n\\n[alias]\\n s = !git status -s\\n c = !git add --all && git commit -m\\n pullo = !git pull origin HEAD\\n pusho = !git push origin HEAD\\n l = !git log --pretty=format:\'%h %s %cn %cr\'\\n```\\n\\n#### Vamos entender o que fizemos\\n\\n- **%h**: id do commit (hash)\\n- **%s**: mensagem do commit\\n- **%cn**: autor do commit\\n- **%cr**: quanto tempo desde o commit\\n\\nAgora seu `git l` retornar\xe1 os dados do commit de uma forma bem resumida. Tamb\xe9m d\xe1 pra mudar a cor, vou deixar a documenta\xe7\xe3o logo abaixo pra voc\xea consultar.\\n\\n## Links \xfateis\\n\\n- [Pretty format](https://git-scm.com/docs/pretty-formats)\\n- [Git config](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)\\n\\n## Conclus\xe3o\\n\\nN\xe3o existe limites, podemos combinar v\xe1rios comandos e simplificar nossa rotina. Agora voc\xea pode brincar e criar seus pr\xf3prios atalhos!\\n\\nEspero que tenha gostado! Se te ajudou de alguma maneira, compartilhe com seus amigos e colegas de trabalho!\\n\\nAt\xe9 a pr\xf3xima!"},{"id":"como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio","metadata":{"permalink":"/blog/como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2021-12-16-como-contornar-a-dor-de-escrever-um-teste-unitario/index.md","source":"@site/blog/2021-12-16-como-contornar-a-dor-de-escrever-um-teste-unitario/index.md","title":"Como contornar a dor de escrever um teste unit\xe1rio?","description":"Acredito que todo mundo concorda que um c\xf3digo sem testes, \xe9 um c\xf3digo inst\xe1vel e fr\xe1gil \xe0 mudan\xe7as...","date":"2021-12-16T00:00:00.000Z","formattedDate":"16 de dezembro de 2021","tags":[{"label":"tdd","permalink":"/blog/tags/tdd"},{"label":"testes","permalink":"/blog/tags/testes"},{"label":"teste unit\xe1rio","permalink":"/blog/tags/teste-unitario"}],"readingTime":3.6,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio","title":"Como contornar a dor de escrever um teste unit\xe1rio?","description":"Acredito que todo mundo concorda que um c\xf3digo sem testes, \xe9 um c\xf3digo inst\xe1vel e fr\xe1gil \xe0 mudan\xe7as...","keywords":["tdd","tests","tdd example","tdd javascript"],"image":"/img/tdd.jpeg","authors":"brunelli","tags":["tdd","testes","teste unit\xe1rio"]},"prevItem":{"title":"Criando atalhos para o git","permalink":"/blog/criando-atalhos-para-o-git"},"nextItem":{"title":"O impacto da educa\xe7\xe3o em minha vida","permalink":"/blog/o-impacto-da-educa\xe7\xe3o-em-minha-vida"}},"content":"![TDD Banner](/img/tdd.jpeg)\\n\\nSalve galera, tudo tranquilo? Esse \xe9 meu segundo artigo, e gostaria de compartilhar algo que vem me ajudando muito durante o desenvolvimento de software e na minha pr\xf3pria evolu\xe7\xe3o profissional.\\n\\nEstou falando sobre os **testes unit\xe1rios**. Acredito que todo mundo concorda que um c\xf3digo sem testes, \xe9 um c\xf3digo inst\xe1vel e fr\xe1gil \xe0 mudan\xe7as. \xc9 muito ruim programar no escuro, n\xf3s nunca temos certeza que o que estamos desenvolvendo ir\xe1 funcionar em produ\xe7\xe3o, sem conflitar com as features j\xe1 existentes.\\n\\nPor outro lado, escrever testes para uma feature j\xe1 implementada pode ser algo muito doloroso, por isso **muita gente prefere correr o risco e deixar o c\xf3digo sem cobertura.**\\n\\n\x3c!--truncate--\x3e\\n\\nMas recentemente venho estudando fortemente uma metodologia que abriu minha mente, o **TDD**, ou em portugu\xeas **\\"Desenvolvimento guiado por testes\\"**. No TDD n\xf3s criamos o teste primeiro, e s\xf3 depois criamos a implementa\xe7\xe3o de fato, que far\xe1 o teste passar. Isso faz com que nosso c\xf3digo sempre esteja coberto por testes.\\n\\n## Traduzindo\\n\\nSe eu quisesse criar uma fun\xe7\xe3o que me retornasse o maior n\xfamero de uma lista em Javascript, utilizando o **TDD** (escrevendo o teste primeiro), eu come\xe7aria fazendo algo mais ou menos assim:\\n\\n```js title=\\"pegueOMaiorNumero.test.js\\"\\n// Sintaxe de um framework de testes do Javascript\\n\\ndescribe(\\"pegueOMaiorNumero\\", () => {\\n test(\\"deve retornar o maior n\xfamero de uma lista\\", () => {\\n const maiorNumero = pegueOMaiorNumero([1, 9, 7, 15, 21, 10]);\\n expect(maiorNumero).toBe(21);\\n });\\n});\\n```\\n\\nNesse caso, eu forneci uma lista com alguns n\xfameros, onde o 21 \xe9 o maior deles. Mas note que em nenhum momento foi criada a fun\xe7\xe3o **pegueOMaiorNumero**. Estou invocando uma fun\xe7\xe3o que **ainda n\xe3o foi criada**, e ainda estou esperando que o resultado seja 21. Nesse caso o teste ir\xe1 falhar.\\n\\n\xc9 ai que a brincadeira come\xe7a. Quando o teste falha, \xe9 sinal de que precisamos implementar a feature que fa\xe7a esse teste passar.\\n\\n## Ent\xe3o vamos l\xe1!\\n\\nVou criar a fun\xe7\xe3o que far\xe1 o teste passar:\\n\\n```js title=\\"pegueOMaiorNumero.test.js\\"\\nconst pegueOMaiorNumero = (numeros) => {\\n let maior = 0;\\n\\n for (let i = 0; i < numeros.length; i++) {\\n if (numeros[i] > maior) {\\n maior = numeros[i];\\n }\\n }\\n\\n return maior;\\n};\\n\\ndescribe(\\"pegueOMaiorNumero\\", () => {\\n test(\\"deve retornar o maior n\xfamero de uma lista\\", () => {\\n const maiorNumero = pegueOMaiorNumero([1, 9, 7, 15, 21, 10]);\\n expect(maiorNumero).toBe(21);\\n });\\n});\\n```\\n\\nAgora o teste come\xe7ar\xe1 a passar. Veja que o algoritmo n\xe3o ficou dos melhores, mas conseguiu satisfazer o que o teste pediu. Agora que o teste est\xe1 passando, posso refatorar a fun\xe7\xe3o **pegueOMaiorNumero** sem medo, pois ela est\xe1 coberta por um teste. Caso a fun\xe7\xe3o passe a retornar uma string, null, ou um n\xfamero que n\xe3o seja o maior, **o teste ir\xe1 me avisar, reprovando**.\\n\\n## Vamos refatorar, sem medo!\\n\\n```js title=\\"pegueOMaiorNumero.test.js\\"\\nconst pegueOMaiorNumero = (numeros) => {\\n return Math.max(...numeros);\\n};\\n\\ndescribe(\\"pegueOMaiorNumero\\", () => {\\n test(\\"deve retornar o maior n\xfamero de uma lista\\", () => {\\n const maiorNumero = pegueOMaiorNumero([1, 9, 7, 15, 21, 10]);\\n expect(maiorNumero).toBe(21);\\n });\\n});\\n```\\n\\nPronto, se a gente rodar esse teste, ele ir\xe1 continuar passando, pois o **Math.max** est\xe1 fazendo o mesmo que o **la\xe7o de repeti\xe7\xe3o** estava fazendo anteriormente, mas de uma maneira mais enxuta. O fato \xe9 que, temos confian\xe7a de alterar um c\xf3digo que nos fale se a nossa regra de neg\xf3cios falhou. **\xc9 inadmiss\xedvel** que nossa fun\xe7\xe3o **pegueOMariorNumero** retorne um n\xfamero que n\xe3o \xe9 o maior.\\n\\n## Conclus\xe3o\\n\\nNossa simples feature de retornar o maior n\xfamero, **esteve durante todo o tempo de desenvolvimento coberta por um teste**. Se a gente fizesse a feature primeiro ao inv\xe9s do teste, ter\xedamos que test\xe1-la manualmente a cada altera\xe7\xe3o, printando o resultado no console, at\xe9 de fato escrever um teste pra ela. Isso seria **cansativo**. O teste \xe9 automatizado, ou seja, escrevemos uma \xfanica vez, e ele sempre ir\xe1 assegurar o resultado pra gente.\\n\\nEscolhi esse exemplo de algoritmo, pois h\xe1 v\xe1rias formas de implement\xe1-lo. Caso voc\xea descubra alguma forma mais enxuta que essa apresentada, poder\xe1 implementar sem correr o risco de quebrar sua aplica\xe7\xe3o.\\n\\nComo material complementar, recomendo essa live que aconteceu no dia 09/12/2021, e que considero excepcional por **dois motivos: n\xe3o tem enrola\xe7\xe3o, e os caras sabem o que est\xe3o ensinando.** Por hoje \xe9 isso, forte abra\xe7o e at\xe9 a pr\xf3xima!\\n\\n[![Live TDD na pr\xe1tica - Diego Fernandes e Rodrigo Manguinho](https://img.youtube.com/vi/sg1zFpNM5Jw/0.jpg)](https://youtu.be/sg1zFpNM5Jw)\\n\\n- Reposit\xf3rio c\xf3digo fonte: [https://github.com/mrbrunelli/tdd-pega-o-maior-numero](https://github.com/mrbrunelli/tdd-pega-o-maior-numero)"},{"id":"o-impacto-da-educa\xe7\xe3o-em-minha-vida","metadata":{"permalink":"/blog/o-impacto-da-educa\xe7\xe3o-em-minha-vida","editUrl":"https://github.com/mrbrunelli/blog/tree/master/blog/2021-05-07-o-impacto-da-educacao-em-minha-vida/index.md","source":"@site/blog/2021-05-07-o-impacto-da-educacao-em-minha-vida/index.md","title":"O impacto da educa\xe7\xe3o em minha vida","description":"Meu \xfaltimo emprego antes de me tornar Desenvolvedor em 2019 era de Auxiliar de Produ\xe7\xe3o em uma f\xe1brica aqui da cidade...","date":"2021-05-07T00:00:00.000Z","formattedDate":"7 de maio de 2021","tags":[{"label":"educa\xe7\xe3o","permalink":"/blog/tags/educacao"},{"label":"a import\xe2ncia da educa\xe7\xe3o","permalink":"/blog/tags/a-importancia-da-educacao"},{"label":"aprendizado","permalink":"/blog/tags/aprendizado"}],"readingTime":2.82,"truncated":true,"authors":[{"name":"Matheus R. Brunelli","title":"Desenvolvedor de software","url":"https://github.com/mrbrunelli","imageURL":"https://avatars.githubusercontent.com/u/54479807?v=4&s=128","key":"brunelli"}],"frontMatter":{"slug":"o-impacto-da-educa\xe7\xe3o-em-minha-vida","title":"O impacto da educa\xe7\xe3o em minha vida","description":"Meu \xfaltimo emprego antes de me tornar Desenvolvedor em 2019 era de Auxiliar de Produ\xe7\xe3o em uma f\xe1brica aqui da cidade...","keywords":["a import\xe2ncia da educa\xe7\xe3o","educa\xe7\xe3o","conhecimento","transi\xe7\xe3o de carreira"],"image":"/img/education.jpeg","authors":"brunelli","tags":["educa\xe7\xe3o","a import\xe2ncia da educa\xe7\xe3o","aprendizado"]},"prevItem":{"title":"Como contornar a dor de escrever um teste unit\xe1rio?","permalink":"/blog/como-contornar-a-dor-de-escrever-um-teste-unit\xe1rio"}},"content":"![Education Banner](/img/education.jpeg)\\n\\nOntem enquanto organizava minha gaveta, me deparei com minha certid\xe3o de casamento, onde estava escrito na primeira linha:\\n\\n> MATHEUS RICARDO BRUNELLI, brasileiro, de profiss\xe3o: Auxiliar de Produ\xe7\xe3o. Ano 2018.\\n\\nMeu \xfaltimo emprego antes de me tornar Desenvolvedor em 2019 era de Auxiliar de Produ\xe7\xe3o em uma f\xe1brica aqui da cidade. O trabalho era muito simples, porem muito desgastante, Dorflex e Torsilax (n\xe3o \xe9 propaganda) faziam parte da minha intensa semana.\\n\\n\x3c!--truncate--\x3e\\n\\n### Tecnologia, uma realidade crescente\\n\\nCerto dia a f\xe1brica inteira parou para ouvir o an\xfancio dos coordenadores das faculdades da regi\xe3o, e foi anunciado dentre os demais cursos o curso de Sistemas para Internet, e a fala do coordenador [Anderson Burnes](https://www.linkedin.com/in/profburnes) (que eu j\xe1 conhecia) foi muito convincente, pois naquele ano v\xe1rias empresas estavam passando por transforma\xe7\xf5es digitais, e estavam precisando de desenvolvedores qualificados, e os sal\xe1rios eram bem diferentes da minha realidade.\\n\\nEu trabalhava muito para conseguir sustentar a minha fam\xedlia (eu, esposa e os doguinhos) e mesmo assim n\xe3o era suficiente, um pneu furado ou uma gripe eram suficientes para acabar com nossas economias do m\xeas rsrs.\\n\\n### Educa\xe7\xe3o, um investimento muito rent\xe1vel\\n\\nEu sabia que o \xfanico caminho para uma mudan\xe7a de vida, era atrav\xe9s da educa\xe7\xe3o. E naquele ano estudei muito para o Enem, e consegui uma Bolsa ProUni para o curso de Sistemas para Internet na [UniAlfa](https://www.alfaumuarama.edu.br/fau).\\n\\nMe lembro que dessa vez eu n\xe3o estava apenas fazendo um curso por fazer, eu estava colocando todas minhas energias em algo que eu acreditava poder mudar minha vida.\\n\\n### Esfor\xe7o no lugar certo\\n\\nDurante os primeiros semestres, percebi que existiam muitos caminhos para seguir profiss\xe3o, alguns bem confusos, e eu precisaria ter foco em algo para poder me destacar. Comecei a pesquisar por tecnologias que me ajudariam a entrar no mercado mais r\xe1pido, pois essa era minha maior motiva\xe7\xe3o.\\n\\nQuando obtive um m\xednimo de confian\xe7a nessas tecnologias, pedi demiss\xe3o do meu emprego na f\xe1brica, para que eu pudesse me dedicar aos estudos de forma integral. Minha fam\xedlia ficou com muito medo da minha decis\xe3o, afinal, n\xe3o haviam garantias que eu conseguiria entrar na \xe1rea, antes da nossa min\xfascula reserva financeira acabar.\\n\\n### F\xe9, foco e medo\\n\\nForam esses tr\xeas elementos que me acompanharam nessa transi\xe7\xe3o. F\xe9 porque n\xf3s n\xe3o enxergamos o amanh\xe3. Foco porque o tempo \xe9 escasso. Medo porque ele funciona como uma balan\xe7a, quanto mais arriscado, mais sentimos medo.\\n\\nComo todo trabalhado duro traz recompensas, a minha chegou aos 45 do segundo tempo, quando s\xf3 restavam algumas moedinhas no cofre. Consegui meu primeiro emprego na \xe1rea, gra\xe7as ao networking (vou escrever um artigo s\xf3 desse cara) e ao meu esfor\xe7o \xe9 claro.\\n\\n### Mercado aquecido\\n\\nSe eu pudesse deixar um conselho para quem est\xe1 come\xe7ando, seria:\\n\\n> Estude, e fa\xe7a de tudo para tentar entrar no mercado. Tenha foco, e invista seu tempo estudando o que te dar\xe1 retorno.\\n\\nNem s\xf3 de teoria vive o programador. Essa \xe9 uma profiss\xe3o muito pr\xe1tica, quanto mais se exercita, mais se aprende. Os melhores exerc\xedcios s\xe3o os problemas reais de uma empresa. Mesmo que ganhando pouco no come\xe7o, trabalhar com problemas reais n\xe3o tem pre\xe7o, essa experi\xeancia n\xe3o pode ser adquirida de outra forma.\\n\\n### Considera\xe7\xf5es finais\\n\\nEsse foi meu primeiro artigo, fiquei muito empolgado ao escrev\xea-lo. Se voc\xea chegou at\xe9 aqui, meus agradecimentos. Espero que tenha sido \xfatil para voc\xea.\\n\\nForte abra\xe7o, e at\xe9 o pr\xf3ximo artigo!"}]}')}}]); \ No newline at end of file diff --git a/assets/js/d81b4cc7.45e9d7da.js b/assets/js/d81b4cc7.1eeaa3e6.js similarity index 75% rename from assets/js/d81b4cc7.45e9d7da.js rename to assets/js/d81b4cc7.1eeaa3e6.js index 4897a5e..595e39c 100644 --- a/assets/js/d81b4cc7.45e9d7da.js +++ b/assets/js/d81b4cc7.1eeaa3e6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkblog=self.webpackChunkblog||[]).push([[8151],{3905:function(e,r,t){t.d(r,{Zo:function(){return u},kt:function(){return d}});var a=t(7294);function n(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);r&&(a=a.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var r=1;r=0||(n[t]=e[t]);return n}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var c=a.createContext({}),l=function(e){var r=a.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},u=function(e){var r=l(e.components);return a.createElement(c.Provider,{value:r},e.children)},m={inlineCode:"code",wrapper:function(e){var r=e.children;return a.createElement(a.Fragment,{},r)}},p=a.forwardRef((function(e,r){var t=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(t),d=n,f=p["".concat(c,".").concat(d)]||p[d]||m[d]||o;return t?a.createElement(f,i(i({ref:r},u),{},{components:t})):a.createElement(f,i({ref:r},u))}));function d(e,r){var t=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var o=t.length,i=new Array(o);i[0]=p;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s.mdxType="string"==typeof e?e:n,i[1]=s;for(var l=2;l=0||(n[t]=e[t]);return n}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var c=a.createContext({}),l=function(e){var r=a.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},m=function(e){var r=l(e.components);return a.createElement(c.Provider,{value:r},e.children)},u={inlineCode:"code",wrapper:function(e){var r=e.children;return a.createElement(a.Fragment,{},r)}},p=a.forwardRef((function(e,r){var t=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,m=s(e,["components","mdxType","originalType","parentName"]),p=l(t),d=n,f=p["".concat(c,".").concat(d)]||p[d]||u[d]||o;return t?a.createElement(f,i(i({ref:r},m),{},{components:t})):a.createElement(f,i({ref:r},m))}));function d(e,r){var t=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var o=t.length,i=new Array(o);i[0]=p;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s.mdxType="string"==typeof e?e:n,i[1]=s;for(var l=2;l0?e(i,l):t[l]=i}))}(e),t};var f=function(e,t){if("*"===e)return l()({loading:u,loader:function(){return n.e(4608).then(n.bind(n,4608))}});var a=s[e+"-"+t],o=[],i=[],f={},p=d(a);return Object.keys(p).forEach((function(e){var t=c[p[e]];t&&(f[e]=t[0],o.push(t[1]),i.push(t[2]))})),l().Map({loading:u,loader:f,modules:o,webpack:function(){return i},render:function(e,t){var n=JSON.parse(JSON.stringify(a));Object.keys(e).forEach((function(t){for(var r=n,a=t.split("."),o=0;o1?t-1:0),r=1;r\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = '+e+" "+("/"===e?" (default value)":"")+'

\n

We suggest trying baseUrl =

\n
\n'}(e)).replace(/=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n},G=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},H=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return!1===t?String(e):String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},V=function(e){var t=X(e,y.TITLE),n=X(e,M);if(n&&t)return n.replace(/%s/g,(function(){return Array.isArray(t)?t.join(""):t}));var r=X(e,N);return t||r||void 0},W=function(e){return X(e,I)||function(){}},K=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return q({},e,t)}),{})},Y=function(e,t){return t.filter((function(e){return void 0!==e[y.BASE]})).map((function(e){return e[y.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a=0;n--){var r=e[n];if(r.hasOwnProperty(t))return r[t]}return null},J=(r=Date.now(),function(e){var t=Date.now();t-r>16?(r=t,e(t)):setTimeout((function(){J(e)}),0)}),ee=function(e){return clearTimeout(e)},te="undefined"!=typeof window?window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||J:n.g.requestAnimationFrame||J,ne="undefined"!=typeof window?window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||ee:n.g.cancelAnimationFrame||ee,re=function(e){return console&&"function"==typeof console.warn&&console.warn(e)},ae=null,oe=function(e,t){var n=e.baseTag,r=e.bodyAttributes,a=e.htmlAttributes,o=e.linkTags,i=e.metaTags,l=e.noscriptTags,u=e.onChangeClientState,s=e.scriptTags,c=e.styleTags,d=e.title,f=e.titleAttributes;ue(y.BODY,r),ue(y.HTML,a),le(d,f);var p={baseTag:se(y.BASE,n),linkTags:se(y.LINK,o),metaTags:se(y.META,i),noscriptTags:se(y.NOSCRIPT,l),scriptTags:se(y.SCRIPT,s),styleTags:se(y.STYLE,c)},m={},g={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(m[e]=n),r.length&&(g[e]=p[e].oldTags)})),t&&t(),u(e,m,g)},ie=function(e){return Array.isArray(e)?e.join(""):e},le=function(e,t){void 0!==e&&document.title!==e&&(document.title=ie(e)),ue(y.TITLE,t)},ue=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute(B),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),l=0;l=0;d--)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute(B):n.getAttribute(B)!==i.join(",")&&n.setAttribute(B,i.join(","))}},se=function(e,t){var n=document.head||document.querySelector(y.HEAD),r=n.querySelectorAll(e+"["+"data-react-helmet]"),a=Array.prototype.slice.call(r),o=[],i=void 0;return t&&t.length&&t.forEach((function(t){var n=document.createElement(e);for(var r in t)if(t.hasOwnProperty(r))if(r===x)n.innerHTML=t.innerHTML;else if(r===k)n.styleSheet?n.styleSheet.cssText=t.cssText:n.appendChild(document.createTextNode(t.cssText));else{var l=void 0===t[r]?"":t[r];n.setAttribute(r,l)}n.setAttribute(B,"true"),a.some((function(e,t){return i=t,n.isEqualNode(e)}))?a.splice(i,1):o.push(n)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),o.forEach((function(e){return n.appendChild(e)})),{oldTags:a,newTags:o}},ce=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},de=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce((function(t,n){return t[O[n]||n]=e[n],t}),t)},fe=function(e,t,n){switch(e){case y.TITLE:return{toComponent:function(){return e=t.title,n=t.titleAttributes,(r={key:e})[B]=!0,a=de(n,r),[l.createElement(y.TITLE,a,e)];var e,n,r,a},toString:function(){return function(e,t,n,r){var a=ce(n),o=ie(t);return a?"<"+e+' data-react-helmet="true" '+a+">"+H(o,r)+"":"<"+e+' data-react-helmet="true">'+H(o,r)+""}(e,t.title,t.titleAttributes,n)}};case h:case v:return{toComponent:function(){return de(t)},toString:function(){return ce(t)}};default:return{toComponent:function(){return function(e,t){return t.map((function(t,n){var r,a=((r={key:n})[B]=!0,r);return Object.keys(t).forEach((function(e){var n=O[e]||e;if(n===x||n===k){var r=t.innerHTML||t.cssText;a.dangerouslySetInnerHTML={__html:r}}else a[n]=t[e]})),l.createElement(e,a)}))}(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!(e===x||e===k)})).reduce((function(e,t){var a=void 0===r[t]?t:t+'="'+H(r[t],n)+'"';return e?e+" "+a:a}),""),o=r.innerHTML||r.cssText||"",i=-1===F.indexOf(e);return t+"<"+e+' data-react-helmet="true" '+a+(i?"/>":">"+o+"")}),"")}(e,t,n)}}}},pe=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.linkTags,i=e.metaTags,l=e.noscriptTags,u=e.scriptTags,s=e.styleTags,c=e.title,d=void 0===c?"":c,f=e.titleAttributes;return{base:fe(y.BASE,t,r),bodyAttributes:fe(h,n,r),htmlAttributes:fe(v,a,r),link:fe(y.LINK,o,r),meta:fe(y.META,i,r),noscript:fe(y.NOSCRIPT,l,r),script:fe(y.SCRIPT,u,r),style:fe(y.STYLE,s,r),title:fe(y.TITLE,{title:d,titleAttributes:f},r)}},me=d()((function(e){return{baseTag:Y([E,P],e),bodyAttributes:K(h,e),defer:X(e,R),encode:X(e,D),htmlAttributes:K(v,e),linkTags:Q(y.LINK,[A,E],e),metaTags:Q(y.META,[_,w,S,T,C],e),noscriptTags:Q(y.NOSCRIPT,[x],e),onChangeClientState:W(e),scriptTags:Q(y.SCRIPT,[L,x],e),styleTags:Q(y.STYLE,[k],e),title:V(e),titleAttributes:K(b,e)}}),(function(e){ae&&ne(ae),e.defer?ae=te((function(){oe(e,(function(){ae=null}))})):(oe(e),ae=null)}),pe)((function(){return null})),ge=(a=me,i=o=function(e){function t(){return z(this,t),G(this,e.apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.prototype.shouldComponentUpdate=function(e){return!p()(this.props,e)},t.prototype.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case y.SCRIPT:case y.NOSCRIPT:return{innerHTML:t};case y.STYLE:return{cssText:t}}throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")},t.prototype.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren,a=e.newChildProps,o=e.nestedChildren;return q({},r,((t={})[n.type]=[].concat(r[n.type]||[],[q({},a,this.mapNestedChildrenToProps(n,o))]),t))},t.prototype.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case y.TITLE:return q({},a,((t={})[r.type]=i,t.titleAttributes=q({},o),t));case y.BODY:return q({},a,{bodyAttributes:q({},o)});case y.HTML:return q({},a,{htmlAttributes:q({},o)})}return q({},a,((n={})[r.type]=q({},o),n))},t.prototype.mapArrayTypeChildrenToProps=function(e,t){var n=q({},t);return Object.keys(e).forEach((function(t){var r;n=q({},n,((r={})[t]=e[t],r))})),n},t.prototype.warnOnInvalidChildren=function(e,t){return!0},t.prototype.mapChildrenToProps=function(e,t){var n=this,r={};return l.Children.forEach(e,(function(e){if(e&&e.props){var a=e.props,o=a.children,i=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce((function(t,n){return t[j[n]||n]=e[n],t}),t)}($(a,["children"]));switch(n.warnOnInvalidChildren(e,o),e.type){case y.LINK:case y.META:case y.NOSCRIPT:case y.SCRIPT:case y.STYLE:r=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:r,newChildProps:i,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:i,nestedChildren:o})}}})),t=this.mapArrayTypeChildrenToProps(r,t)},t.prototype.render=function(){var e=this.props,t=e.children,n=$(e,["children"]),r=q({},n);return t&&(r=this.mapChildrenToProps(t,r)),l.createElement(a,r)},Z(t,null,[{key:"canUseDOM",set:function(e){a.canUseDOM=e}}]),t}(l.Component),o.propTypes={base:s().object,bodyAttributes:s().object,children:s().oneOfType([s().arrayOf(s().node),s().node]),defaultTitle:s().string,defer:s().bool,encodeSpecialCharacters:s().bool,htmlAttributes:s().object,link:s().arrayOf(s().object),meta:s().arrayOf(s().object),noscript:s().arrayOf(s().object),onChangeClientState:s().func,script:s().arrayOf(s().object),style:s().arrayOf(s().object),title:s().string,titleAttributes:s().object,titleTemplate:s().string},o.defaultProps={defer:!0,encodeSpecialCharacters:!0},o.peek=a.peek,o.rewind=function(){var e=a.rewind();return e||(e=pe({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}})),e},i);ge.renderStatic=ge.rewind;var he=function(e){return l.createElement(ge,Object.assign({},e))}},9960:function(e,t,n){"use strict";n.d(t,{Z:function(){return p}});var r=n(3366),a=n(7294),o=n(3727),i=n(2263),l=n(3919),u=n(412),s=(0,a.createContext)({collectLink:function(){}});var c=n(4996),d=n(8780),f=["isNavLink","to","href","activeClassName","isActive","data-noBrokenLinkCheck","autoAddBaseUrl"];var p=function(e){var t,n,p=e.isNavLink,m=e.to,g=e.href,h=e.activeClassName,v=e.isActive,b=e["data-noBrokenLinkCheck"],y=e.autoAddBaseUrl,w=void 0===y||y,k=(0,r.Z)(e,f),E=(0,i.Z)().siteConfig,S=E.trailingSlash,x=E.baseUrl,C=(0,c.C)().withBaseUrl,_=(0,a.useContext)(s),T=m||g,A=(0,l.Z)(T),L=null==T?void 0:T.replace("pathname://",""),P=void 0!==L?(n=L,w&&function(e){return e.startsWith("/")}(n)?C(n):n):void 0;P&&A&&(P=(0,d.applyTrailingSlash)(P,{trailingSlash:S,baseUrl:x}));var O=(0,a.useRef)(!1),N=p?o.OL:o.rU,R=u.Z.canUseIntersectionObserver,D=(0,a.useRef)();(0,a.useEffect)((function(){return!R&&A&&null!=P&&window.docusaurus.prefetch(P),function(){R&&D.current&&D.current.disconnect()}}),[D,P,R,A]);var I=null!==(t=null==P?void 0:P.startsWith("#"))&&void 0!==t&&t,M=!P||!A||I;return P&&A&&!I&&!b&&_.collectLink(P),M?a.createElement("a",Object.assign({href:P},T&&!A&&{target:"_blank",rel:"noopener noreferrer"},k)):a.createElement(N,Object.assign({},k,{onMouseEnter:function(){O.current||null==P||(window.docusaurus.preload(P),O.current=!0)},innerRef:function(e){var t,n;R&&e&&A&&(t=e,n=function(){null!=P&&window.docusaurus.prefetch(P)},D.current=new window.IntersectionObserver((function(e){e.forEach((function(e){t===e.target&&(e.isIntersecting||e.intersectionRatio>0)&&(D.current.unobserve(t),D.current.disconnect(),n())}))})),D.current.observe(t))},to:P||""},p&&{isActive:v,activeClassName:h}))}},1875:function(e,t){"use strict";t.Z=function(){return null}},5999:function(e,t,n){"use strict";n.d(t,{Z:function(){return c},I:function(){return s}});var r=n(7294),a=/{\w+}/g,o="{}";function i(e,t){var n=[],i=e.replace(a,(function(e){var a=e.substring(1,e.length-1),i=null==t?void 0:t[a];if(void 0!==i){var l=r.isValidElement(i)?i:String(i);return n.push(l),o}return e}));return 0===n.length?e:n.every((function(e){return"string"==typeof e}))?i.split(o).reduce((function(e,t,r){var a;return e.concat(t).concat(null!==(a=n[r])&&void 0!==a?a:"")}),""):i.split(o).reduce((function(e,t,a){return[].concat(e,[r.createElement(r.Fragment,{key:a},t,n[a])])}),[])}var l=n(7529);function u(e){var t,n,r=e.id,a=e.message;if(void 0===r&&void 0===a)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return null!==(n=null!==(t=l[null!=r?r:a])&&void 0!==t?t:a)&&void 0!==n?n:r}function s(e,t){return i(u({message:e.message,id:e.id}),t)}function c(e){var t=e.children,n=e.id,r=e.values;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");return i(u({message:t,id:n}),r)}},9913:function(e,t,n){"use strict";n.d(t,{_:function(){return a},t:function(){return o}});var r=n(7294),a=r.createContext(!1);function o(e){var t=e.children,n=(0,r.useState)(!1),o=n[0],i=n[1];return(0,r.useEffect)((function(){i(!0)}),[]),r.createElement(a.Provider,{value:o},t)}},9935:function(e,t,n){"use strict";n.d(t,{m:function(){return r}});var r="default"},7041:function(e,t,n){"use strict";n.d(t,{_:function(){return s},M:function(){return c}});var r=n(7294),a=n(9782),o=JSON.parse('{"defaultLocale":"pt","locales":["pt","en"],"currentLocale":"pt","localeConfigs":{"pt":{"label":"Portugu\xeas","direction":"ltr","htmlLang":"pt-BR"},"en":{"label":"English","direction":"ltr","htmlLang":"en-US"}}}'),i=n(7529),l=JSON.parse('{"docusaurusVersion":"2.0.0-beta.15","siteVersion":"1.1.1","pluginVersions":{"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.0.0-beta.15"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.0.0-beta.15"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.0.0-beta.15"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.0.0-beta.15"}}}'),u={siteConfig:a.Z,siteMetadata:l,globalData:{},i18n:o,codeTranslations:i},s=r.createContext(u);function c(e){var t=e.children;return r.createElement(s.Provider,{value:u},t)}},3919:function(e,t,n){"use strict";function r(e){return!0===/^(\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{b:function(){return r},Z:function(){return a}})},8143:function(e,t,n){"use strict";n.r(t),n.d(t,{BrowserRouter:function(){return r.VK},HashRouter:function(){return r.UT},Link:function(){return r.rU},MemoryRouter:function(){return r.VA},NavLink:function(){return r.OL},Prompt:function(){return r.NL},Redirect:function(){return r.l_},Route:function(){return r.AW},Router:function(){return r.F0},StaticRouter:function(){return r.gx},Switch:function(){return r.rs},generatePath:function(){return r.Gn},matchPath:function(){return r.LX},useHistory:function(){return r.k6},useLocation:function(){return r.TH},useParams:function(){return r.UO},useRouteMatch:function(){return r.$B},withRouter:function(){return r.EN}});var r=n(3727)},4996:function(e,t,n){"use strict";n.d(t,{C:function(){return o},Z:function(){return i}});var r=n(2263),a=n(3919);function o(){var e=(0,r.Z)().siteConfig,t=e.baseUrl,n=e.url;return{withBaseUrl:function(e,r){return function(e,t,n,r){var o=void 0===r?{}:r,i=o.forcePrependBaseUrl,l=void 0!==i&&i,u=o.absolute,s=void 0!==u&&u;if(!n)return n;if(n.startsWith("#"))return n;if((0,a.b)(n))return n;if(l)return t+n.replace(/^\//,"");var c=n.startsWith(t)?n:t+n.replace(/^\//,"");return s?e+c:c}(n,t,e,r)}}}function i(e,t){return void 0===t&&(t={}),(0,o().withBaseUrl)(e,t)}},2263:function(e,t,n){"use strict";var r=n(7294),a=n(7041);t.Z=function(){return(0,r.useContext)(a._)}},8084:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return o},useAllPluginInstancesData:function(){return i},usePluginData:function(){return l}});var r=n(2263),a=n(9935);function o(){var e=(0,r.Z)().globalData;if(!e)throw new Error("Docusaurus global data not found.");return e}function i(e){var t=o()[e];if(!t)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin.');return t}function l(e,t){void 0===t&&(t=a.m);var n=i(e)[t];if(!n)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin with id "'+t+'".');return n}},2389:function(e,t,n){"use strict";n.d(t,{Z:function(){return o}});var r=n(7294),a=n(9913);function o(){return(0,r.useContext)(a._)}},4953:function(e,t,n){"use strict";var r=n(7294),a=n(9629),o=n(780);function i(e){var t=e.error,n=e.tryAgain;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",height:"50vh",width:"100%",fontSize:"20px"}},r.createElement("h1",null,"This page crashed."),r.createElement("p",null,t.message),r.createElement("button",{type:"button",onClick:n},"Try again"))}t.Z=function(e){var t=e.error,n=e.tryAgain;return r.createElement(o.Z,{fallback:function(){return r.createElement(i,{error:t,tryAgain:n})}},r.createElement(a.Z,{title:"Page Error"},r.createElement(i,{error:t,tryAgain:n})))}},8408:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getDocVersionSuggestions=t.getActiveDocContext=t.getActiveVersion=t.getLatestVersion=t.getActivePlugin=void 0;var r=n(8143);t.getActivePlugin=function(e,t,n){void 0===n&&(n={});var a=Object.entries(e).sort((function(e,t){return t[1].path.localeCompare(e[1].path)})).find((function(e){var n=e[1];return!!(0,r.matchPath)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error("Can't find active docs plugin for \""+t+'" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: '+Object.values(e).map((function(e){return e.path})).join(", "));return o};t.getLatestVersion=function(e){return e.versions.find((function(e){return e.isLast}))};t.getActiveVersion=function(e,n){var a=(0,t.getLatestVersion)(e);return[].concat(e.versions.filter((function(e){return e!==a})),[a]).find((function(e){return!!(0,r.matchPath)(n,{path:e.path,exact:!1,strict:!1})}))};t.getActiveDocContext=function(e,n){var a,o,i=(0,t.getActiveVersion)(e,n),l=null==i?void 0:i.docs.find((function(e){return!!(0,r.matchPath)(n,{path:e.path,exact:!0,strict:!1})}));return{activeVersion:i,activeDoc:l,alternateDocVersions:l?(a=l.id,o={},e.versions.forEach((function(e){e.docs.forEach((function(t){t.id===a&&(o[e.name]=t)}))})),o):{}}};t.getDocVersionSuggestions=function(e,n){var r=(0,t.getLatestVersion)(e),a=(0,t.getActiveDocContext)(e,n);return{latestDocSuggestion:null==a?void 0:a.alternateDocVersions[r.name],latestVersionSuggestion:r}}},7608:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useDocVersionSuggestions=t.useActiveDocContext=t.useActiveVersion=t.useLatestVersion=t.useVersions=t.useActivePluginAndVersion=t.useActivePlugin=t.useDocsData=t.useAllDocsData=void 0;var r=n(655),a=n(8143),o=(0,r.__importStar)(n(8084)),i=n(8408),l={};t.useAllDocsData=function(){var e;return null!==(e=(0,o.default)()["docusaurus-plugin-content-docs"])&&void 0!==e?e:l};t.useDocsData=function(e){return(0,o.usePluginData)("docusaurus-plugin-content-docs",e)};t.useActivePlugin=function(e){void 0===e&&(e={});var n=(0,t.useAllDocsData)(),r=(0,a.useLocation)().pathname;return(0,i.getActivePlugin)(n,r,e)};t.useActivePluginAndVersion=function(e){void 0===e&&(e={});var n=(0,t.useActivePlugin)(e),r=(0,a.useLocation)().pathname;if(n)return{activePlugin:n,activeVersion:(0,i.getActiveVersion)(n.pluginData,r)}};t.useVersions=function(e){return(0,t.useDocsData)(e).versions};t.useLatestVersion=function(e){var n=(0,t.useDocsData)(e);return(0,i.getLatestVersion)(n)};t.useActiveVersion=function(e){var n=(0,t.useDocsData)(e),r=(0,a.useLocation)().pathname;return(0,i.getActiveVersion)(n,r)};t.useActiveDocContext=function(e){var n=(0,t.useDocsData)(e),r=(0,a.useLocation)().pathname;return(0,i.getActiveDocContext)(n,r)};t.useDocVersionSuggestions=function(e){var n=(0,t.useDocsData)(e),r=(0,a.useLocation)().pathname;return(0,i.getDocVersionSuggestions)(n,r)}},5551:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),(0,n(655).__exportStar)(n(7608),t)},541:function(e,t,n){"use strict";n.d(t,{Z:function(){return o}});var r=n(7294),a="iconExternalLink_I5OW";var o=function(e){var t=e.width,n=void 0===t?13.5:t,o=e.height,i=void 0===o?13.5:o;return r.createElement("svg",{width:n,height:i,"aria-hidden":"true",viewBox:"0 0 24 24",className:a},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},9629:function(e,t,n){"use strict";n.d(t,{Z:function(){return ve}});var r=n(7294),a=n(6010),o=n(780),i=n(6775),l=n(5999),u=n(5773),s="skipToContent_ZgBM";function c(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}var d=function(){var e=(0,r.useRef)(null),t=(0,i.k6)().action;return(0,u.SL)((function(n){var r=n.location;e.current&&!r.hash&&"PUSH"===t&&c(e.current)})),r.createElement("div",{ref:e,role:"region"},r.createElement("a",{href:"#",className:s,onClick:function(e){e.preventDefault();var t=document.querySelector("main:first-of-type")||document.querySelector(".main-wrapper");t&&c(t)}},r.createElement(l.Z,{id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"},"Skip to main content")))},f=n(7462),p=n(3366),m=["width","height","color","strokeWidth","className"];function g(e){var t=e.width,n=void 0===t?21:t,a=e.height,o=void 0===a?21:a,i=e.color,l=void 0===i?"currentColor":i,u=e.strokeWidth,s=void 0===u?1.2:u,c=(e.className,(0,p.Z)(e,m));return r.createElement("svg",(0,f.Z)({viewBox:"0 0 15 15",width:n,height:o},c),r.createElement("g",{stroke:l,strokeWidth:s},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}var h="announcementBar_IbjG",v="announcementBarPlaceholder_NC_W",b="announcementBarClose_FG1z",y="announcementBarContent_KsVm";var w=function(){var e=(0,u.nT)(),t=e.isActive,n=e.close,o=(0,u.LU)().announcementBar;if(!t)return null;var i=o.content,s=o.backgroundColor,c=o.textColor,d=o.isCloseable;return r.createElement("div",{className:h,style:{backgroundColor:s,color:c},role:"banner"},d&&r.createElement("div",{className:v}),r.createElement("div",{className:y,dangerouslySetInnerHTML:{__html:i}}),d?r.createElement("button",{type:"button",className:(0,a.Z)("clean-btn close",b),onClick:n,"aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},r.createElement(g,{width:14,height:14,strokeWidth:3.1})):null)},k=n(1875),E=n(2389),S="toggle_Pssr",x="toggleScreenReader_JnkT",C="toggleDisabled_jDku",_="toggleTrack_SSoT",T="toggleTrackCheck_XobZ",A="toggleChecked_cnQY",L="toggleTrackX_YkSC",P="toggleTrackThumb_uRm4",O="toggleFocused_A7DC",N="toggleIcon_eZtF",R=(0,r.memo)((function(e){var t,n=e.className,o=e.switchConfig,i=e.checked,l=e.disabled,u=e.onChange,s=o.darkIcon,c=o.darkIconStyle,d=o.lightIcon,f=o.lightIconStyle,p=(0,r.useState)(i),m=p[0],g=p[1],h=(0,r.useState)(!1),v=h[0],b=h[1],y=(0,r.useRef)(null);return r.createElement("div",{className:(0,a.Z)(S,n,(t={},t[A]=m,t[O]=v,t[C]=l,t))},r.createElement("div",{className:_,role:"button",tabIndex:-1,onClick:function(){var e;return null==(e=y.current)?void 0:e.click()}},r.createElement("div",{className:T},r.createElement("span",{className:N,style:c},s)),r.createElement("div",{className:L},r.createElement("span",{className:N,style:f},d)),r.createElement("div",{className:P})),r.createElement("input",{ref:y,checked:m,type:"checkbox",className:x,"aria-label":"Switch between dark and light mode",onChange:u,onClick:function(){return g(!m)},onFocus:function(){return b(!0)},onBlur:function(){return b(!1)},onKeyDown:function(e){var t;"Enter"===e.key&&(null==(t=y.current)||t.click())}}))}));function D(e){var t=(0,u.LU)().colorMode.switchConfig,n=(0,E.Z)();return r.createElement(R,(0,f.Z)({switchConfig:t,disabled:!n},e))}var I=n(5551),M=n(2207),j=n(9960),F={themedImage:"themedImage_W2Cr","themedImage--light":"themedImage--light_TfLj","themedImage--dark":"themedImage--dark_oUvU"},B=["sources","className","alt"];var U=function(e){var t=(0,E.Z)(),n=(0,u.If)().isDarkTheme,o=e.sources,i=e.className,l=e.alt,s=void 0===l?"":l,c=(0,p.Z)(e,B),d=t?n?["dark"]:["light"]:["light","dark"];return r.createElement(r.Fragment,null,d.map((function(e){return r.createElement("img",(0,f.Z)({key:e,src:o[e],alt:s,className:(0,a.Z)(F.themedImage,F["themedImage--"+e],i)},c))})))},z=n(4996),Z=n(2263),q=["imageClassName","titleClassName"];var $=function(e){var t=(0,Z.Z)().siteConfig.title,n=(0,u.LU)().navbar,a=n.title,o=n.logo,i=void 0===o?{src:""}:o,l=e.imageClassName,s=e.titleClassName,c=(0,p.Z)(e,q),d=(0,z.Z)(i.href||"/"),m={light:(0,z.Z)(i.src),dark:(0,z.Z)(i.srcDark||i.src)},g=r.createElement(U,{sources:m,height:i.height,width:i.width,alt:i.alt||a||t});return r.createElement(j.Z,(0,f.Z)({to:d},c,i.target&&{target:i.target}),i.src&&(l?r.createElement("div",{className:l},g):g),null!=a&&r.createElement("b",{className:s},a))},G=["width","height","className"];var H=function(e){var t=e.width,n=void 0===t?30:t,a=e.height,o=void 0===a?30:a,i=e.className,l=(0,p.Z)(e,G);return r.createElement("svg",(0,f.Z)({className:i,width:n,height:o,viewBox:"0 0 30 30","aria-hidden":"true"},l),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))},V={toggle:"toggle_TdHA",navbarHideable:"navbarHideable_aKYr",navbarHidden:"navbarHidden_KUhG",navbarSidebarToggle:"navbarSidebarToggle_nL8I"},W="right";function K(){return(0,u.LU)().navbar.items}function Y(){var e=(0,u.LU)().colorMode.disableSwitch,t=(0,u.If)(),n=t.isDarkTheme,a=t.setLightTheme,o=t.setDarkTheme;return{isDarkTheme:n,toggle:(0,r.useCallback)((function(e){return e.target.checked?o():a()}),[a,o]),disabled:e}}function Q(e){var t=e.sidebarShown,n=e.toggleSidebar;(0,u.Ni)(t);var o=K(),i=Y(),s=function(e){var t,n=e.sidebarShown,a=e.toggleSidebar,o=null==(t=(0,u.g8)())?void 0:t({toggleSidebar:a}),i=(0,u.D9)(o),l=(0,r.useState)((function(){return!1})),s=l[0],c=l[1];(0,r.useEffect)((function(){o&&!i&&c(!0)}),[o,i]);var d=!!o;return(0,r.useEffect)((function(){d?n||c(!0):c(!1)}),[n,d]),{shown:s,hide:(0,r.useCallback)((function(){c(!1)}),[]),content:o}}({sidebarShown:t,toggleSidebar:n});return r.createElement("div",{className:"navbar-sidebar"},r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement($,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title"}),!i.disabled&&r.createElement(D,{className:V.navbarSidebarToggle,checked:i.isDarkTheme,onChange:i.toggle}),r.createElement("button",{type:"button",className:"clean-btn navbar-sidebar__close",onClick:n},r.createElement(g,{color:"var(--ifm-color-emphasis-600)",className:V.navbarSidebarCloseSvg}))),r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":s.shown})},r.createElement("div",{className:"navbar-sidebar__item menu"},r.createElement("ul",{className:"menu__list"},o.map((function(e,t){return r.createElement(M.Z,(0,f.Z)({mobile:!0},e,{onClick:n,key:t}))})))),r.createElement("div",{className:"navbar-sidebar__item menu"},o.length>0&&r.createElement("button",{type:"button",className:"clean-btn navbar-sidebar__back",onClick:s.hide},r.createElement(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu")),s.content)))}var X=function(){var e,t=(0,u.LU)().navbar,n=t.hideOnScroll,o=t.style,i=function(){var e=(0,u.iP)(),t="mobile"===e,n=(0,r.useState)(!1),a=n[0],o=n[1];(0,u.Rb)((function(){if(a)return o(!1),!1}));var i=(0,r.useCallback)((function(){o((function(e){return!e}))}),[]);return(0,r.useEffect)((function(){"desktop"===e&&o(!1)}),[e]),{shouldRender:t,toggle:i,shown:a}}(),l=Y(),s=(0,I.useActivePlugin)(),c=(0,u.cK)(n),d=c.navbarRef,p=c.isNavbarVisible,m=K(),g=m.some((function(e){return"search"===e.type})),h=function(e){return{leftItems:e.filter((function(e){var t;return"left"===(null!=(t=e.position)?t:W)})),rightItems:e.filter((function(e){var t;return"right"===(null!=(t=e.position)?t:W)}))}}(m),v=h.leftItems,b=h.rightItems;return r.createElement("nav",{ref:d,className:(0,a.Z)("navbar","navbar--fixed-top",(e={"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown},e[V.navbarHideable]=n,e[V.navbarHidden]=n&&!p,e))},r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},((null==m?void 0:m.length)>0||s)&&r.createElement("button",{"aria-label":"Navigation bar toggle",className:"navbar__toggle clean-btn",type:"button",tabIndex:0,onClick:i.toggle,onKeyDown:i.toggle},r.createElement(H,null)),r.createElement($,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title"}),v.map((function(e,t){return r.createElement(M.Z,(0,f.Z)({},e,{key:t}))}))),r.createElement("div",{className:"navbar__items navbar__items--right"},b.map((function(e,t){return r.createElement(M.Z,(0,f.Z)({},e,{key:t}))})),!l.disabled&&r.createElement(D,{className:V.toggle,checked:l.isDarkTheme,onChange:l.toggle}),!g&&r.createElement(k.Z,null))),r.createElement("div",{role:"presentation",className:"navbar-sidebar__backdrop",onClick:i.toggle}),i.shouldRender&&r.createElement(Q,{sidebarShown:i.shown,toggleSidebar:i.toggle}))},J=n(3919),ee="footerLogoLink_RC3H",te=n(541),ne=["to","href","label","prependBaseUrlToHref"];function re(e){var t=e.to,n=e.href,a=e.label,o=e.prependBaseUrlToHref,i=(0,p.Z)(e,ne),l=(0,z.Z)(t),u=(0,z.Z)(n,{forcePrependBaseUrl:!0});return r.createElement(j.Z,(0,f.Z)({className:"footer__link-item"},n?{href:o?u:n}:{to:l},i),n&&!(0,J.Z)(n)?r.createElement("span",null,a,r.createElement(te.Z,null)):a)}function ae(e){var t=e.sources,n=e.alt,a=e.width,o=e.height;return r.createElement(U,{className:"footer__logo",alt:n,sources:t,width:a,height:o})}function oe(e){var t=e.links;return r.createElement(r.Fragment,null,t.map((function(e,t){return r.createElement("div",{key:t,className:"col footer__col"},r.createElement("div",{className:"footer__title"},e.title),r.createElement("ul",{className:"footer__items"},e.items.map((function(e,t){return e.html?r.createElement("li",{key:t,className:"footer__item",dangerouslySetInnerHTML:{__html:e.html}}):r.createElement("li",{key:e.href||e.to,className:"footer__item"},r.createElement(re,e))}))))})))}function ie(e){var t=e.links;return r.createElement("div",{className:"footer__links"},t.map((function(e,n){return r.createElement(r.Fragment,null,e.html?r.createElement("span",{key:n,className:"footer__link-item",dangerouslySetInnerHTML:{__html:e.html}}):r.createElement(re,e),t.length!==n+1&&r.createElement("span",{className:"footer__link-separator"},"\xb7"))})))}function le(){var e=(0,u.LU)().footer,t=e||{},n=t.copyright,o=t.links,i=void 0===o?[]:o,l=t.logo,s=void 0===l?{}:l,c={light:(0,z.Z)(s.src),dark:(0,z.Z)(s.srcDark||s.src)};return e?r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===e.style})},r.createElement("div",{className:"container container-fluid"},i&&i.length>0&&(function(e){return"title"in e[0]}(i)?r.createElement("div",{className:"row footer__links"},r.createElement(oe,{links:i})):r.createElement("div",{className:"footer__links text--center"},r.createElement(ie,{links:i}))),(s||n)&&r.createElement("div",{className:"footer__bottom text--center"},s&&(s.src||s.srcDark)&&r.createElement("div",{className:"margin-bottom--sm"},s.href?r.createElement(j.Z,{href:s.href,className:ee},r.createElement(ae,{alt:s.alt,sources:c,width:s.width,height:s.height})):r.createElement(ae,{alt:s.alt,sources:c})),n?r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:n}}):null))):null}var ue=r.memo(le);function se(e){var t=e.children;return r.createElement(u.SG,null,r.createElement(u.pl,null,r.createElement(u.z5,null,r.createElement(u.OC,null,r.createElement(u.L5,null,r.createElement(u.Cn,null,t))))))}var ce=n(2859);function de(e){var t=e.locale,n=e.version,a=e.tag;return r.createElement(ce.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),a&&r.createElement("meta",{name:"docusaurus_tag",content:a}))}var fe=n(1217);function pe(){var e=(0,Z.Z)().i18n,t=e.defaultLocale,n=e.localeConfigs,a=(0,u.l5)();return r.createElement(ce.Z,null,Object.entries(n).map((function(e){var t=e[0],n=e[1].htmlLang;return r.createElement("link",{key:t,rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:n})})),r.createElement("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}))}function me(e){var t=e.permalink,n=(0,Z.Z)().siteConfig.url,a=function(){var e=(0,Z.Z)().siteConfig.url,t=(0,i.TH)().pathname;return e+(0,z.Z)(t)}(),o=t?""+n+t:a;return r.createElement(ce.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function ge(e){var t=(0,Z.Z)(),n=t.siteConfig.favicon,a=t.i18n,o=a.currentLocale,i=a.localeConfigs,l=(0,u.LU)(),s=l.metadata,c=l.image,d=e.title,p=e.description,m=e.image,g=e.keywords,h=e.searchMetadata,v=(0,z.Z)(n),b=(0,u.pe)(d),y=i[o],w=y.htmlLang,k=y.direction;return r.createElement(r.Fragment,null,r.createElement(ce.Z,null,r.createElement("html",{lang:w,dir:k}),n&&r.createElement("link",{rel:"icon",href:v}),r.createElement("title",null,b),r.createElement("meta",{property:"og:title",content:b}),r.createElement("meta",{name:"twitter:card",content:"summary_large_image"})),c&&r.createElement(fe.Z,{image:c}),m&&r.createElement(fe.Z,{image:m}),r.createElement(fe.Z,{description:p,keywords:g}),r.createElement(me,null),r.createElement(pe,null),r.createElement(de,(0,f.Z)({tag:u.HX,locale:o},h)),r.createElement(ce.Z,null,s.map((function(e,t){return r.createElement("meta",(0,f.Z)({key:"metadata_"+t},e))}))))}function he(e){var t=e.error,n=e.tryAgain;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("p",null,t.message),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},r.createElement(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again when the page crashed"},"Try again"))))))}var ve=function(e){var t=e.children,n=e.noFooter,i=e.wrapperClassName,l=e.pageClassName;return(0,u.t$)(),r.createElement(se,null,r.createElement(ge,e),r.createElement(d,null),r.createElement(w,null),r.createElement(X,null),r.createElement("div",{className:(0,a.Z)(u.kM.wrapper.main,i,l)},r.createElement(o.Z,{fallback:he},t)),!n&&r.createElement(ue,null))}},5525:function(e,t,n){"use strict";var r=n(7462),a=n(3366),o=n(7294),i=n(6010),l=n(3072),u=n(1068),s=["className","isDropdownItem"],c=["className","isDropdownItem"],d=["mobile","position"];function f(e){var t=e.className,n=e.isDropdownItem,u=void 0!==n&&n,c=(0,a.Z)(e,s),d=o.createElement(l.Z,(0,r.Z)({className:(0,i.Z)(u?"dropdown__link":"navbar__item navbar__link",t)},c));return u?o.createElement("li",null,d):d}function p(e){var t=e.className,n=(e.isDropdownItem,(0,a.Z)(e,c));return o.createElement("li",{className:"menu__list-item"},o.createElement(l.Z,(0,r.Z)({className:(0,i.Z)("menu__link",t)},n)))}t.Z=function(e){var t,n=e.mobile,i=void 0!==n&&n,l=(e.position,(0,a.Z)(e,d)),s=i?p:f;return o.createElement(s,(0,r.Z)({},l,{activeClassName:null!=(t=l.activeClassName)?t:(0,u.E)(i)}))}},6400:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7462),a=n(3366),o=n(7294),i=n(5525),l=n(5551),u=n(6010),s=n(1068),c=n(5773),d=["docId","label","docsPluginId"];function f(e){var t,n=e.docId,f=e.label,p=e.docsPluginId,m=(0,a.Z)(e,d),g=(0,l.useActiveDocContext)(p),h=g.activeVersion,v=g.activeDoc,b=(0,c.J)(p).preferredVersion,y=(0,l.useLatestVersion)(p),w=function(e,t){var n=e.flatMap((function(e){return e.docs})),r=n.find((function(e){return e.id===t}));if(!r){var a=n.map((function(e){return e.id})).join("\n- ");throw new Error("DocNavbarItem: couldn't find any doc with id \""+t+'" in version'+(e.length?"s":"")+" "+e.map((function(e){return e.name})).join(", ")+'".\nAvailable doc ids are:\n- '+a)}return r}((0,c.jj)([h,b,y].filter(Boolean)),n),k=(0,s.E)(m.mobile);return o.createElement(i.Z,(0,r.Z)({exact:!0},m,{className:(0,u.Z)(m.className,(t={},t[k]=(null==v?void 0:v.sidebar)&&v.sidebar===w.sidebar,t)),activeClassName:k,label:null!=f?f:w.id,to:w.path}))}},4792:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7462),a=n(3366),o=n(7294),i=n(5525),l=n(5551),u=n(6010),s=n(1068),c=n(5773),d=["sidebarId","label","docsPluginId"];function f(e){var t,n=e.sidebarId,f=e.label,p=e.docsPluginId,m=(0,a.Z)(e,d),g=(0,l.useActiveDocContext)(p),h=g.activeVersion,v=g.activeDoc,b=(0,c.J)(p).preferredVersion,y=(0,l.useLatestVersion)(p),w=function(e,t){var n=e.flatMap((function(e){if(e.sidebars)return Object.entries(e.sidebars)})).filter((function(e){return!!e})),r=n.find((function(e){return e[0]===t}));if(!r)throw new Error("DocSidebarNavbarItem: couldn't find any sidebar with id \""+t+'" in version'+(e.length?"s":"")+" "+e.map((function(e){return e.name})).join(", ")+'".\nAvailable sidebar ids are:\n- '+Object.keys(n).join("\n- "));if(!r[1].link)throw new Error("DocSidebarNavbarItem: couldn't find any document for sidebar with id \""+t+'"');return r[1].link}((0,c.jj)([h,b,y].filter(Boolean)),n),k=(0,s.E)(m.mobile);return o.createElement(i.Z,(0,r.Z)({exact:!0},m,{className:(0,u.Z)(m.className,(t={},t[k]=(null==v?void 0:v.sidebar)===n,t)),activeClassName:k,label:null!=f?f:w.label,to:w.path}))}},9308:function(e,t,n){"use strict";n.d(t,{Z:function(){return p}});var r=n(7462),a=n(3366),o=n(7294),i=n(5525),l=n(3154),u=n(5551),s=n(5773),c=n(5999),d=["mobile","docsPluginId","dropdownActiveClassDisabled","dropdownItemsBefore","dropdownItemsAfter"],f=function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))};function p(e){var t,n,p=e.mobile,m=e.docsPluginId,g=e.dropdownActiveClassDisabled,h=e.dropdownItemsBefore,v=e.dropdownItemsAfter,b=(0,a.Z)(e,d),y=(0,u.useActiveDocContext)(m),w=(0,u.useVersions)(m),k=(0,u.useLatestVersion)(m),E=(0,s.J)(m),S=E.preferredVersion,x=E.savePreferredVersionName;var C,_=(C=w.map((function(e){var t=(null==y?void 0:y.alternateDocVersions[e.name])||f(e);return{isNavLink:!0,label:e.label,to:t.path,isActive:function(){return e===(null==y?void 0:y.activeVersion)},onClick:function(){x(e.name)}}})),[].concat(h,C,v)),T=null!=(t=null!=(n=y.activeVersion)?n:S)?t:k,A=p&&_.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):T.label,L=p&&_.length>1?void 0:f(T).path;return _.length<=1?o.createElement(i.Z,(0,r.Z)({},b,{mobile:p,label:A,to:L,isActive:g?function(){return!1}:void 0})):o.createElement(l.Z,(0,r.Z)({},b,{mobile:p,label:A,to:L,items:_,isActive:g?function(){return!1}:void 0}))}},7250:function(e,t,n){"use strict";n.d(t,{Z:function(){return c}});var r=n(7462),a=n(3366),o=n(7294),i=n(5525),l=n(5551),u=n(5773),s=["label","to","docsPluginId"];function c(e){var t,n=e.label,c=e.to,d=e.docsPluginId,f=(0,a.Z)(e,s),p=(0,l.useActiveVersion)(d),m=(0,u.J)(d).preferredVersion,g=(0,l.useLatestVersion)(d),h=null!=(t=null!=p?p:m)?t:g,v=null!=n?n:h.label,b=null!=c?c:function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))}(h).path;return o.createElement(i.Z,(0,r.Z)({},f,{label:v,to:b}))}},3154:function(e,t,n){"use strict";var r=n(7462),a=n(3366),o=n(7294),i=n(6010),l=n(5773),u=n(3072),s=n(2207),c=["items","position","className"],d=["items","className","position"],f=["mobile"];function p(e,t){return e.some((function(e){return function(e,t){return!!(0,l.Mg)(e.to,t)||!!(0,l.Fx)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)}))}function m(e){var t,n=e.items,l=e.position,d=e.className,f=(0,a.Z)(e,c),p=(0,o.useRef)(null),m=(0,o.useState)(!1),g=m[0],h=m[1];return(0,o.useEffect)((function(){var e=function(e){p.current&&!p.current.contains(e.target)&&h(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),function(){document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)}}),[p]),o.createElement("div",{ref:p,className:(0,i.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===l,"dropdown--show":g})},o.createElement(u.Z,(0,r.Z)({href:f.to?void 0:"#",className:(0,i.Z)("navbar__link",d)},f,{onClick:f.to?void 0:function(e){return e.preventDefault()},onKeyDown:function(e){"Enter"===e.key&&(e.preventDefault(),h(!g))}}),null!=(t=f.children)?t:f.label),o.createElement("ul",{className:"dropdown__menu"},n.map((function(e,t){return o.createElement(s.Z,(0,r.Z)({isDropdownItem:!0,onKeyDown:function(e){if(t===n.length-1&&"Tab"===e.key){e.preventDefault(),h(!1);var r=p.current.nextElementSibling;r&&r.focus()}},activeClassName:"dropdown__link--active"},e,{key:t}))}))))}function g(e){var t,n=e.items,c=e.className,f=(e.position,(0,a.Z)(e,d)),m=(0,l.be)(),g=p(n,m),h=(0,l.uR)({initialState:function(){return!g}}),v=h.collapsed,b=h.toggleCollapsed,y=h.setCollapsed;return(0,o.useEffect)((function(){g&&y(!g)}),[m,g,y]),o.createElement("li",{className:(0,i.Z)("menu__list-item",{"menu__list-item--collapsed":v})},o.createElement(u.Z,(0,r.Z)({role:"button",className:(0,i.Z)("menu__link menu__link--sublist",c)},f,{onClick:function(e){e.preventDefault(),b()}}),null!=(t=f.children)?t:f.label),o.createElement(l.zF,{lazy:!0,as:"ul",className:"menu__list",collapsed:v},n.map((function(e,t){return o.createElement(s.Z,(0,r.Z)({mobile:!0,isDropdownItem:!0,onClick:f.onClick,activeClassName:"menu__link--active"},e,{key:t}))}))))}t.Z=function(e){var t=e.mobile,n=void 0!==t&&t,r=(0,a.Z)(e,f),i=n?g:m;return o.createElement(i,r)}},3072:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7462),a=n(3366),o=n(7294),i=n(9960),l=n(4996),u=n(541),s=n(3919),c=n(5773),d=["activeBasePath","activeBaseRegex","to","href","label","activeClassName","prependBaseUrlToHref"];function f(e){var t,n=e.activeBasePath,f=e.activeBaseRegex,p=e.to,m=e.href,g=e.label,h=e.activeClassName,v=void 0===h?"":h,b=e.prependBaseUrlToHref,y=(0,a.Z)(e,d),w=(0,l.Z)(p),k=(0,l.Z)(n),E=(0,l.Z)(m,{forcePrependBaseUrl:!0}),S=g&&m&&!(0,s.Z)(m),x="dropdown__link--active"===v;return o.createElement(i.Z,(0,r.Z)({},m?{href:b?E:m}:Object.assign({isNavLink:!0,activeClassName:null!=(t=y.className)&&t.includes(v)?"":v,to:w},n||f?{isActive:function(e,t){return f?(0,c.Fx)(f,t.pathname):t.pathname.startsWith(k)}}:null),y),S?o.createElement("span",null,g,o.createElement(u.Z,x&&{width:12,height:12})):g)}},2207:function(e,t,n){"use strict";n.d(t,{Z:function(){return y}});var r=n(3366),a=n(7294),o=n(5525),i=n(3154),l=n(7462),u=["width","height"];var s=function(e){var t=e.width,n=void 0===t?20:t,o=e.height,i=void 0===o?20:o,s=(0,r.Z)(e,u);return a.createElement("svg",(0,l.Z)({viewBox:"0 0 20 20",width:n,height:i,"aria-hidden":"true"},s),a.createElement("path",{fill:"currentColor",d:"M19.753 10.909c-.624-1.707-2.366-2.726-4.661-2.726-.09 0-.176.002-.262.006l-.016-2.063 3.525-.607c.115-.019.133-.119.109-.231-.023-.111-.167-.883-.188-.976-.027-.131-.102-.127-.207-.109-.104.018-3.25.461-3.25.461l-.013-2.078c-.001-.125-.069-.158-.194-.156l-1.025.016c-.105.002-.164.049-.162.148l.033 2.307s-3.061.527-3.144.543c-.084.014-.17.053-.151.143.019.09.19 1.094.208 1.172.018.08.072.129.188.107l2.924-.504.035 2.018c-1.077.281-1.801.824-2.256 1.303-.768.807-1.207 1.887-1.207 2.963 0 1.586.971 2.529 2.328 2.695 3.162.387 5.119-3.06 5.769-4.715 1.097 1.506.256 4.354-2.094 5.98-.043.029-.098.129-.033.207l.619.756c.08.096.206.059.256.023 2.51-1.73 3.661-4.515 2.869-6.683zm-7.386 3.188c-.966-.121-.944-.914-.944-1.453 0-.773.327-1.58.876-2.156a3.21 3.21 0 011.229-.799l.082 4.277a2.773 2.773 0 01-1.243.131zm2.427-.553l.046-4.109c.084-.004.166-.01.252-.01.773 0 1.494.145 1.885.361.391.217-1.023 2.713-2.183 3.758zm-8.95-7.668a.196.196 0 00-.196-.145h-1.95a.194.194 0 00-.194.144L.008 16.916c-.017.051-.011.076.062.076h1.733c.075 0 .099-.023.114-.072l1.008-3.318h3.496l1.008 3.318c.016.049.039.072.113.072h1.734c.072 0 .078-.025.062-.076-.014-.05-3.083-9.741-3.494-11.04zm-2.618 6.318l1.447-5.25 1.447 5.25H3.226z"}))},c=n(2263),d=n(5773),f="iconLanguage_dNtB",p=["mobile","dropdownItemsBefore","dropdownItemsAfter"];function m(e){var t=e.mobile,n=e.dropdownItemsBefore,o=e.dropdownItemsAfter,u=(0,r.Z)(e,p),m=(0,c.Z)().i18n,g=m.currentLocale,h=m.locales,v=m.localeConfigs,b=(0,d.l5)();function y(e){return v[e].label}var w=h.map((function(e){var t="pathname://"+b.createUrl({locale:e,fullyQualified:!1});return{isNavLink:!0,label:y(e),to:t,target:"_self",autoAddBaseUrl:!1,className:e===g?"dropdown__link--active":""}})),k=[].concat(n,w,o),E=t?"Languages":y(g);return a.createElement(i.Z,(0,l.Z)({},u,{mobile:t,label:a.createElement("span",null,a.createElement(s,{className:f}),a.createElement("span",null,E)),items:k}))}var g=n(1875);function h(e){return e.mobile?null:a.createElement(g.Z,null)}var v=["type"],b={default:function(){return o.Z},localeDropdown:function(){return m},search:function(){return h},dropdown:function(){return i.Z},docsVersion:function(){return n(7250).Z},docsVersionDropdown:function(){return n(9308).Z},doc:function(){return n(6400).Z},docSidebar:function(){return n(4792).Z}};function y(e){var t=e.type,n=(0,r.Z)(e,v),o=function(e,t){return e&&"default"!==e?e:t?"dropdown":"default"}(t,void 0!==n.items),i=function(e){var t=b[e];if(!t)throw new Error('No NavbarItem component found for type "'+e+'".');return t()}(o);return a.createElement(i,n)}},1068:function(e,t,n){"use strict";n.d(t,{E:function(){return r}});var r=function(e){return e?"menu__link--active":"navbar__link--active"}},1217:function(e,t,n){"use strict";n.d(t,{Z:function(){return l}});var r=n(7294),a=n(2859),o=n(5773),i=n(4996);function l(e){var t=e.title,n=e.description,l=e.keywords,u=e.image,s=e.children,c=(0,o.pe)(t),d=(0,i.C)().withBaseUrl,f=u?d(u,{absolute:!0}):void 0;return r.createElement(a.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),l&&r.createElement("meta",{name:"keywords",content:Array.isArray(l)?l.join(","):l}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),s)}},467:function(e,t,n){"use strict";n.r(t);var r=n(412),a=n(9782);t.default=function(e){if(r.Z.canUseDOM){var t=a.Z.themeConfig.prism.additionalLanguages;window.Prism=e,t.forEach((function(e){n(6726)("./prism-"+e)})),delete window.Prism}}},2448:function(e,t,n){"use strict";var r=a(n(7410));function a(e){return e&&e.__esModule?e:{default:e}}(0,a(n(467)).default)(r.default)},5773:function(e,t,n){"use strict";n.d(t,{pl:function(){return _e},zF:function(){return oe},SG:function(){return Qe},HX:function(){return I},PO:function(){return me},L5:function(){return w},Cn:function(){return he},OC:function(){return Ue},z5:function(){return nt},kM:function(){return we},Fx:function(){return qe},Mg:function(){return M},PZ:function(){return Oe},bc:function(){return N},Vo:function(){return R},nZ:function(){return D},MA:function(){return Pe},jj:function(){return ye},l5:function(){return f},nT:function(){return Te},uR:function(){return Q},If:function(){return Xe},J:function(){return S},cK:function(){return rt},Rb:function(){return Ne},t$:function(){return at},be:function(){return Ae},SL:function(){return H},Ni:function(){return lt},g8:function(){return be},c2:function(){return Z},D9:function(){return G},pJ:function(){return it},DA:function(){return Fe},Si:function(){return Me},LU:function(){return a},pe:function(){return j},iP:function(){return ft}});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}var o=n(7294);Symbol("EmptyContext");var i="localStorage";function l(e){if(void 0===e&&(e=i),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,u||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),u=!0),null}var t}var u=!1;var s={get:function(){return null},set:function(){},del:function(){}};var c=function(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error('Illegal storage API usage for storage key "'+e+'".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.')}return{get:t,set:t,del:t}}(e);var n=l(null==t?void 0:t.persistence);return null===n?s:{get:function(){try{return n.getItem(e)}catch(t){return console.error("Docusaurus storage error, can't get key="+e,t),null}},set:function(t){try{n.setItem(e,t)}catch(r){console.error("Docusaurus storage error, can't set "+e+"="+t,r)}},del:function(){try{n.removeItem(e)}catch(t){console.error("Docusaurus storage error, can't delete key="+e,t)}}}};var d=n(6775);function f(){var e=(0,r.Z)(),t=e.siteConfig,n=t.baseUrl,a=t.url,o=e.i18n,i=o.defaultLocale,l=o.currentLocale,u=(0,d.TH)().pathname,s=l===i?n:n.replace("/"+l+"/","/"),c=u.replace(n,"");return{createUrl:function(e){var t=e.locale;return""+(e.fullyQualified?a:"")+function(e){return e===i?""+s:""+s+e+"/"}(t)+c}}}var p=n(5551),m=!!p.useAllDocsData;Symbol("EmptyContext");var g=function(e){return"docs-preferred-version-"+e},h={save:function(e,t,n){c(g(e),{persistence:t}).set(n)},read:function(e,t){return c(g(e),{persistence:t}).get()},clear:function(e,t){c(g(e),{persistence:t}).del()}};function v(e){var t=e.pluginIds,n=e.versionPersistence,r=e.allDocsData;var a={};return t.forEach((function(e){a[e]=function(e){var t=h.read(e,n);return r[e].versions.some((function(e){return e.name===t}))?{preferredVersionName:t}:(h.clear(e,n),{preferredVersionName:null})}(e)})),a}function b(){var e=(0,p.useAllDocsData)(),t=a().docs.versionPersistence,n=(0,o.useMemo)((function(){return Object.keys(e)}),[e]),r=(0,o.useState)((function(){return function(e){var t={};return e.forEach((function(e){t[e]={preferredVersionName:null}})),t}(n)})),i=r[0],l=r[1];return(0,o.useEffect)((function(){l(v({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]),[i,(0,o.useMemo)((function(){return{savePreferredVersion:function(e,n){h.save(e,t,n),l((function(t){var r;return Object.assign({},t,((r={})[e]={preferredVersionName:n},r))}))}}}),[t])]}var y=(0,o.createContext)(null);function w(e){var t=e.children;return m?o.createElement(k,null,t):t}function k(e){var t=e.children,n=b();return o.createElement(y.Provider,{value:n},t)}var E=n(9935);function S(e){void 0===e&&(e=E.m);var t=(0,p.useDocsData)(e),n=function(){var e=(0,o.useContext)(y);if(!e)throw new Error('Can\'t find docs preferred context, maybe you forgot to use the "DocsPreferredVersionContextProvider"?');return e}(),r=n[0],a=n[1],i=r[e].preferredVersionName;return{preferredVersion:i?t.versions.find((function(e){return e.name===i})):null,savePreferredVersionName:(0,o.useCallback)((function(t){a.savePreferredVersion(e,t)}),[a,e])}}var x=n(7594),C=n.n(x),_=/title=(["'])(.*?)\1/,T=/{([\d,-]+)}/,A=["js","jsBlock","jsx","python","html"],L={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},python:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},P=["highlight-next-line","highlight-start","highlight-end"],O=function(e){void 0===e&&(e=A);var t=e.map((function(e){var t=L[e],n=t.start,r=t.end;return"(?:"+n+"\\s*("+P.join("|")+")\\s*"+r+")"})).join("|");return new RegExp("^\\s*(?:"+t+")\\s*$")};function N(e){var t,n;return null!==(n=null===(t=null==e?void 0:e.match(_))||void 0===t?void 0:t[2])&&void 0!==n?n:""}function R(e){var t=e.split(" ").find((function(e){return e.startsWith("language-")}));return null==t?void 0:t.replace(/language-/,"")}function D(e,t,n){var r=e.replace(/\n$/,"");if(t&&T.test(t)){var a=t.match(T)[1];return{highlightLines:C()(a).filter((function(e){return e>0})).map((function(e){return e-1})),code:r}}if(void 0===n)return{highlightLines:[],code:r};for(var o,i=function(e){switch(e){case"js":case"javascript":case"ts":case"typescript":return O(["js","jsBlock"]);case"jsx":case"tsx":return O(["js","jsBlock","jsx"]);case"html":return O(["js","jsBlock","html"]);case"python":case"py":return O(["python"]);default:return O()}}(n),l=r.split("\n"),u="",s=0;sn.pluralForms.length&&console.error("For locale="+n.locale+", a maximum of "+n.pluralForms.length+" plural forms are expected ("+n.pluralForms+"), but the message contains "+r.length+" plural forms: "+e+" ");var a=n.select(t),o=n.pluralForms.indexOf(a);return r[Math.min(o,r.length-1)]}(n,t,e)}}}var q="undefined"!=typeof window?o.useLayoutEffect:o.useEffect;function $(e){var t=(0,o.useRef)(e);return q((function(){t.current=e}),[e]),(0,o.useCallback)((function(){return t.current.apply(t,arguments)}),[])}function G(e){var t=(0,o.useRef)();return q((function(){t.current=e})),t.current}function H(e){var t=(0,d.TH)(),n=G(t),r=$(e);(0,o.useEffect)((function(){t!==n&&r({location:t,previousLocation:n})}),[r,t,n])}var V=n(3366),W=n(412),K=["collapsed"],Y=["lazy"];function Q(e){var t=e.initialState,n=(0,o.useState)(null!=t&&t),r=n[0],a=n[1],i=(0,o.useCallback)((function(){a((function(e){return!e}))}),[]);return{collapsed:r,setCollapsed:a,toggleCollapsed:i}}var X={display:"none",overflow:"hidden",height:"0px"},J={display:"block",overflow:"visible",height:"auto"};function ee(e,t){var n=t?X:J;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function te(e){var t=e.collapsibleRef,n=e.collapsed,r=e.animation,a=(0,o.useRef)(!1);(0,o.useEffect)((function(){var e,o=t.current;function i(){var e,t,n=o.scrollHeight,a=null!==(e=null==r?void 0:r.duration)&&void 0!==e?e:function(e){var t=e/36;return Math.round(10*(4+15*Math.pow(t,.25)+t/5))}(n);return{transition:"height "+a+"ms "+(null!==(t=null==r?void 0:r.easing)&&void 0!==t?t:"ease-in-out"),height:n+"px"}}function l(){var e=i();o.style.transition=e.transition,o.style.height=e.height}if(!a.current)return ee(o,n),void(a.current=!0);return o.style.willChange="height",e=requestAnimationFrame((function(){n?(l(),requestAnimationFrame((function(){o.style.height=X.height,o.style.overflow=X.overflow}))):(o.style.display="block",requestAnimationFrame((function(){l()})))})),function(){return cancelAnimationFrame(e)}}),[t,n,r])}function ne(e){if(!W.Z.canUseDOM)return e?X:J}function re(e){var t=e.as,n=void 0===t?"div":t,r=e.collapsed,a=e.children,i=e.animation,l=e.onCollapseTransitionEnd,u=e.className,s=e.disableSSRStyle,c=(0,o.useRef)(null);return te({collapsibleRef:c,collapsed:r,animation:i}),o.createElement(n,{ref:c,style:s?void 0:ne(r),onTransitionEnd:function(e){"height"===e.propertyName&&(ee(c.current,r),null==l||l(r))},className:u},a)}function ae(e){var t=e.collapsed,n=(0,V.Z)(e,K),r=(0,o.useState)(!t),a=r[0],i=r[1];(0,o.useLayoutEffect)((function(){t||i(!0)}),[t]);var l=(0,o.useState)(t),u=l[0],s=l[1];return(0,o.useLayoutEffect)((function(){a&&s(t)}),[a,t]),a?o.createElement(re,Object.assign({},n,{collapsed:u})):null}function oe(e){var t=e.lazy,n=(0,V.Z)(e,Y),r=t?ae:re;return o.createElement(r,Object.assign({},n))}var ie=n(2389),le=n(6010),ue="details_lb9f",se="isBrowser_bmU9",ce="collapsibleContent_i85q",de=["summary","children"];function fe(e){return!!e&&("SUMMARY"===e.tagName||fe(e.parentElement))}function pe(e,t){return!!e&&(e===t||pe(e.parentElement,t))}var me=function(e){var t,n=e.summary,r=e.children,a=(0,V.Z)(e,de),i=(0,ie.Z)(),l=(0,o.useRef)(null),u=Q({initialState:!a.open}),s=u.collapsed,c=u.setCollapsed,d=(0,o.useState)(a.open),f=d[0],p=d[1];return o.createElement("details",Object.assign({},a,{ref:l,open:f,"data-collapsed":s,className:(0,le.Z)(ue,(t={},t[se]=i,t),a.className),onMouseDown:function(e){fe(e.target)&&e.detail>1&&e.preventDefault()},onClick:function(e){e.stopPropagation();var t=e.target;fe(t)&&pe(t,l.current)&&(e.preventDefault(),s?(c(!1),p(!0)):c(!0))}}),n,o.createElement(oe,{lazy:!1,collapsed:s,disableSSRStyle:!0,onCollapseTransitionEnd:function(e){c(e),p(!e)}},o.createElement("div",{className:ce},r)))};var ge=(0,o.createContext)(null);function he(e){var t=e.children;return o.createElement(ge.Provider,{value:(0,o.useState)(null)},t)}function ve(){var e=(0,o.useContext)(ge);if(null===e)throw new Error("MobileSecondaryMenuProvider was not used correctly, context value is null");return e}function be(){var e=ve()[0];if(e){var t=e.component;return function(n){return o.createElement(t,Object.assign({},e.props,n))}}return function(){}}function ye(e){return Array.from(new Set(e))}var we={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block"},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:function(e){return"theme-doc-sidebar-item-category-level-"+e},docSidebarItemLinkLevel:function(e){return"theme-doc-sidebar-item-link-level-"+e}},blog:{}},ke=c("docusaurus.announcement.dismiss"),Ee=c("docusaurus.announcement.id"),Se=function(){return"true"===ke.get()},xe=function(e){return ke.set(String(e))},Ce=(0,o.createContext)(null);function _e(e){var t=e.children,n=function(){var e=a().announcementBar,t=(0,ie.Z)(),n=(0,o.useState)((function(){return!!t&&Se()})),r=n[0],i=n[1];(0,o.useEffect)((function(){i(Se())}),[]);var l=(0,o.useCallback)((function(){xe(!0),i(!0)}),[]);return(0,o.useEffect)((function(){if(e){var t=e.id,n=Ee.get();"annoucement-bar"===n&&(n="announcement-bar");var r=t!==n;Ee.set(t),r&&xe(!1),!r&&Se()||i(!1)}}),[e]),(0,o.useMemo)((function(){return{isActive:!!e&&!r,close:l}}),[e,r,l])}();return o.createElement(Ce.Provider,{value:n},t)}var Te=function(){var e=(0,o.useContext)(Ce);if(!e)throw new Error("useAnnouncementBar(): AnnouncementBar not found in React context: make sure to use the AnnouncementBarProvider on top of the tree");return e};function Ae(){var e=(0,r.Z)().siteConfig.baseUrl;return(0,d.TH)().pathname.replace(e,"/")}var Le=n(5999),Pe=function(){return(0,Le.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"})};function Oe(e){var t={};return Object.values(e).forEach((function(e){var n,r=function(e){return e[0].toUpperCase()}(e.name);t[r]=null!==(n=t[r])&&void 0!==n?n:[],t[r].push(e)})),Object.entries(t).sort((function(e,t){var n=e[0],r=t[0];return n.localeCompare(r)})).map((function(e){return{letter:e[0],tags:e[1].sort((function(e,t){return e.name.localeCompare(t.name)}))}}))}function Ne(e){!function(e){var t=(0,d.k6)().block,n=(0,o.useRef)(e);(0,o.useEffect)((function(){n.current=e}),[e]),(0,o.useEffect)((function(){return t((function(e,t){return n.current(e,t)}))}),[t,n])}((function(t,n){if("POP"===n)return e(t,n)}))}function Re(e){var t=e.getBoundingClientRect();return t.top===t.bottom?Re(e.parentNode):t}function De(e,t){var n,r=t.anchorTopOffset,a=e.find((function(e){return Re(e).top>=r}));return a?function(e){return e.top>0&&e.bottom=n&&e.level<=r}(e)?[Object.assign({},e,{children:t})]:t}))}function Fe(e){var t=e.toc,n=e.minHeadingLevel,r=e.maxHeadingLevel;return(0,o.useMemo)((function(){return je({toc:t,minHeadingLevel:n,maxHeadingLevel:r})}),[t,n,r])}var Be=(0,o.createContext)(void 0);function Ue(e){var t,n=e.children;return o.createElement(Be.Provider,{value:(t=(0,o.useRef)(!0),(0,o.useMemo)((function(){return{scrollEventsEnabledRef:t,enableScrollEvents:function(){t.current=!0},disableScrollEvents:function(){t.current=!1}}}),[]))},n)}function ze(){var e=(0,o.useContext)(Be);if(null==e)throw new Error('"useScrollController" is used but no context provider was found in the React tree.');return e}var Ze=function(){return W.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null};function qe(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var $e=c("theme"),Ge="light",He="dark",Ve=function(e){return e===He?He:Ge},We=function(e){c("theme").set(Ve(e))};function Ke(){var e=a().colorMode,t=e.defaultMode,n=e.disableSwitch,r=e.respectPrefersColorScheme,i=(0,o.useState)(function(e){return W.Z.canUseDOM?Ve(document.documentElement.getAttribute("data-theme")):Ve(e)}(t)),l=i[0],u=i[1],s=(0,o.useCallback)((function(){u(Ge),We(Ge)}),[]),c=(0,o.useCallback)((function(){u(He),We(He)}),[]);return(0,o.useEffect)((function(){document.documentElement.setAttribute("data-theme",Ve(l))}),[l]),(0,o.useEffect)((function(){if(!n)try{var e=$e.get();null!==e&&u(Ve(e))}catch(t){console.error(t)}}),[n,u]),(0,o.useEffect)((function(){n&&!r||window.matchMedia("(prefers-color-scheme: dark)").addListener((function(e){var t=e.matches;u(t?He:Ge)}))}),[n,r]),{isDarkTheme:l===He,setLightTheme:s,setDarkTheme:c}}var Ye=o.createContext(void 0);function Qe(e){var t=e.children,n=Ke(),r=n.isDarkTheme,a=n.setLightTheme,i=n.setDarkTheme,l=(0,o.useMemo)((function(){return{isDarkTheme:r,setLightTheme:a,setDarkTheme:i}}),[r,a,i]);return o.createElement(Ye.Provider,{value:l},t)}function Xe(){var e=(0,o.useContext)(Ye);if(null==e)throw new Error('"useColorMode()" is used outside of "Layout" component. Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.');return e}var Je="docusaurus.tab.",et=(0,o.createContext)(void 0);function tt(){var e=(0,o.useState)({}),t=e[0],n=e[1],r=(0,o.useCallback)((function(e,t){c("docusaurus.tab."+e).set(t)}),[]);return(0,o.useEffect)((function(){try{var e={};(function(e){void 0===e&&(e=i);var t=l(e);if(!t)return[];for(var n=[],r=0;r=l?r(!1):o+s996?ut:st:ct}function ft(){var e=(0,o.useState)((function(){return dt()})),t=e[0],n=e[1];return(0,o.useEffect)((function(){function e(){n(dt())}return window.addEventListener("resize",e),function(){window.removeEventListener("resize",e),clearTimeout(undefined)}}),[]),t}},8802:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var n=t.trailingSlash,r=t.baseUrl;if(e.startsWith("#"))return e;if(void 0===n)return e;var a,o=e.split(/[#?]/)[0],i="/"===o||o===r?o:(a=o,n?function(e){return e.endsWith("/")?e:e+"/"}(a):function(e){return e.endsWith("/")?e.slice(0,-1):e}(a));return e.replace(o,i)}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="post-content";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}})},6010:function(e,t,n){"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!s)for(;d--;d)i.unshift("..");!s||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};function l(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}var u=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=l(t),a=l(n);return r!==t||a!==n?e(r,a):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1},s=n(2177);function c(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function f(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function m(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function g(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function h(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&u(e.state,t.state)}function v(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=g(e,t,f(),w.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),s=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),u(s,i(e,c,d)),1===e?(u(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){u(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),s=document.querySelector(r.parent);return u(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),s!=document.body&&c(s,"nprogress-custom-parent"),s.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),u=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function s(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;s(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);s(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:function(e){"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,o){for(var i,l,u=a(e),s=1;se.trim())))if(/^-?\d+$/.test(r))n.push(parseInt(r,10));else if(t=r.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,r,a,o]=t;if(r&&o){r=parseInt(r),o=parseInt(o);const e=r=d.reach);S+=E.value.length,E=E.next){var x=E.value;if(t.length>e.length)return;if(!(x instanceof a)){var C,_=1;if(b){if(!(C=o(k,S,e,v))||C.index>=e.length)break;var T=C.index,A=C.index+C[0].length,L=S;for(L+=E.value.length;T>=L;)L+=(E=E.next).value.length;if(S=L-=E.value.length,E.value instanceof a)continue;for(var P=E;P!==t.tail&&(Ld.reach&&(d.reach=D);var I=E.prev;if(N&&(I=u(t,I,N),S+=N.length),s(t,I,_),E=u(t,I,new a(f,h?r.tokenize(O,h):O,y,O)),R&&u(t,E,R),_>1){var M={cause:f+","+m,reach:D};i(e,t,n,E.prev,S,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function u(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function s(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var u=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(u=i(t[r-1])+u,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",u,null,u)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var u=o.substring(0,l),d=s(c[a]),p=o.substring(l+a.length),m=[];if(u&&m.push(u),m.push(d),p){var g=[p];e(g),m.push.apply(m,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var u=n;u=0&&p(s,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n=o.length);u++){var s=l[u];if("string"==typeof s||s.content&&"string"==typeof s.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof s?s:s.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++a;var g=f.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=f.substring(m+p.length),b=[];g&&b.push.apply(b,i([g])),b.push(h),v&&b.push.apply(b,i([v])),"string"==typeof s?l.splice.apply(l,[u,1].concat(b)):s.content=b}}else s.content&&i(s.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},u=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,a.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/},function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),t.default=a},9901:function(e){e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},bash:{title:"Bash",alias:"shell",aliasTitles:{shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:"hbs",owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (Scss)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:function(e,t,n){const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:function(e,t,n){var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:function(e,t,n){var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:function(e){"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},u=e[r];if(u){function i(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(u.require,i),t(u.optional,i),t(u.modify,i)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var u=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),s=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(u);i=i.map(s),l=(l||[]).map(s);var c=n(i),d=n(l);i.forEach((function e(n){var r=u[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(u),m=c;a(m);){for(var g in f={},m){var h=u[g];t(h&&h.modify,(function(e){e in d&&(f[e]=!0)}))}for(var v in d)if(!(v in c))for(var b in p(v))if(b in c){f[v]=!0;break}for(var y in m=f)c[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},u={};function s(e){if(e in l)return l[e];u[e]=!0;var a,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)a=r(e);else{var f=i(c.map((function(e){var t=s(e);return delete u[e],t})));o?a=o(f,(function(){return r(e)})):r(e)}return l[e]=a}for(var c in n)s(c);var d=[];for(var f in u)d.push(l[f]);return i(d)}(p,c,t,n)}};return w}}();e.exports=t},2703:function(e,t,n){"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:function(e,t,n){e.exports=n(2703)()},414:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:function(e,t,n){"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n