<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt">
  <title>AlexandreHTRB&#39;s blog</title>
  <subtitle>Conteúdo sobre programação e tópicos diversos.</subtitle>
  <link href="https://alexandrehtrb.github.io/atom_pt.xml" rel="self" />
  <link href="https://alexandrehtrb.github.io/" />
  <updated>2026-06-23T00:00:00Z</updated>
  <id>https://alexandrehtrb.github.io/</id>
  <author>
    <name>Alexandre H. T. R. Bonfitto</name>
  </author>
  <entry>
    <title>Tabela periódica da computação</title>
    <link href="https://alexandrehtrb.github.io/posts/2026/06/tabela-periodica-da-computacao/" />
    <updated>2026-06-23T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2026/06/tabela-periodica-da-computacao/</id>
    <content type="html">&lt;p&gt;Alguns dias atrás, comecei a pensar nas diferentes extensões de arquivos das linguagens de programação e percebi que elas se parecem com símbolos de elementos químicos. Aí pensei: &quot;daria para fazer uma tabela periódica da computação&quot;.&lt;/p&gt;&lt;p&gt;A melhor tabela periódica em HTML que encontrei na internet foi a do &lt;a href=http://adrianroselli.com/2019/05/periodic-table-of-the-elements.html&gt;Adrian Roselli&lt;/a&gt;. Ela é responsiva, funciona na vertical e horizontal, cobre todas as necessidades de acessibilidade, tem suporte a modo escuro, funciona offline e dá até para imprimir!&lt;/p&gt;&lt;p&gt;Procurei fazer uma tabela colocando o que considero de importante da computação como um todo e num sentido mais geral. Acabou sem espaço para coisas como padrões de arquitetura e design. Talvez para isso seja melhor uma tabela periódica de software, ao invés de uma da computação.&lt;/p&gt;&lt;p&gt;Clique &lt;a href=https://alexandrehtrb.github.io/periodic_table_of_computing.html&gt;aqui&lt;/a&gt; para acessar a tabela.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Fazendo um calendário de feriados com programação funcional</title>
    <link href="https://alexandrehtrb.github.io/posts/2026/01/fazendo-um-calendario-de-feriados-com-programacao-funcional/" />
    <updated>2026-01-06T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2026/01/fazendo-um-calendario-de-feriados-com-programacao-funcional/</id>
    <content type="html">&lt;p&gt;Um dos meus projetos pessoais é o site &lt;a href=https://feriadosdobrasil.github.io&gt;Feriados do Brasil&lt;/a&gt;, que é um calendário com os feriados nacionais, estaduais e municipais de várias cidades do país. Enquanto eu desenvolvia esse projeto, encontrei um caso de uso interessante para aplicar programação funcional e resolvi compartilhar neste artigo, mostrando como ela pode fornecer soluções diferentes e elegantes para nossos desafios.&lt;/p&gt;&lt;h2 id=feriados-fixos-e-m%C3%B3veis tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2026/01/fazendo-um-calendario-de-feriados-com-programacao-funcional/#feriados-fixos-e-m%C3%B3veis class=header-anchor&gt;&lt;span&gt;Feriados fixos e móveis&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Existem dois tipos de feriados: os de datas fixas, que caem sempre em um mesmo dia de um mesmo mês, e os de datas móveis, cuja data varia de acordo com o ano. Os feriados móveis mais conhecidos são a Paixão de Cristo, o Carnaval e &lt;em&gt;Corpus Christi&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Apesar de menos comuns, existem muitos feriados móveis, cada um com sua regra determinadora. A tabela abaixo mostra alguns deles.&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Feriado móvel&lt;/th&gt;&lt;th style=text-align:center&gt;Data&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Paixão de Cristo&lt;/td&gt;&lt;td style=text-align:center&gt;calculada via fórmula matemática&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Terça-feira de Carnaval*&lt;/td&gt;&lt;td style=text-align:center&gt;47 dias antes da Páscoa&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;&lt;em&gt;Corpus Christi&lt;/em&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;60 dias depois da Páscoa&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Pentecostes&lt;/td&gt;&lt;td style=text-align:center&gt;50 dias após a Páscoa&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Sagrado Coração de Jesus&lt;/td&gt;&lt;td style=text-align:center&gt;8 dias após &lt;em&gt;Corpus Christi&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Dia do Comércio no&lt;br&gt;Rio de Janeiro&lt;/td&gt;&lt;td style=text-align:center&gt;Terceira segunda-feira de outubro&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Feriados estaduais&lt;br&gt;do Acre**&lt;/td&gt;&lt;td style=text-align:center&gt;Se caírem entre terça-feira e quinta-feira,&lt;br&gt;são deslocados para a sexta-feira seguinte&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Feriados estaduais de&lt;br&gt;Santa Catarina&lt;/td&gt;&lt;td style=text-align:center&gt;Se caírem em dia útil,&lt;br&gt;são deslocados para o domingo seguinte&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;* Carnaval não é um feriado oficial, apesar de ser celebrado em quase todo o país.&lt;br&gt;** Exceto para o Aniversário do Estado, em 15 de junho.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;A questão é: como podemos armazenar os feriados em uma base de dados, considerando que alguns são fixos e outros são móveis? Mais ainda, os de datas móveis têm regras particulares para calcular as datas?&lt;/p&gt;&lt;h2 id=solu%C3%A7%C3%A3o-via-programa%C3%A7%C3%A3o-funcional tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2026/01/fazendo-um-calendario-de-feriados-com-programacao-funcional/#solu%C3%A7%C3%A3o-via-programa%C3%A7%C3%A3o-funcional class=header-anchor&gt;&lt;span&gt;Solução via programação funcional&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;No projeto em questão, a listagem e cálculo de feriados são feitos inteiramente no frontend em JavaScript. Basicamente, os feriados de um município correspondem à união dos feriados nacionais, estaduais e municipais. No código, cada um desses conjuntos é representado por um &lt;em&gt;array&lt;/em&gt; de funções.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; feriadosNacionais&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;JANEIRO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Ano Novo&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  fm&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;calcularTercaFeiraDeCarnaval&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Carnaval&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  fm&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;calcularSextaFeiraSanta&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Paixão de Cristo&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;ABRIL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;21&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Tiradentes&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;MAIO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Dia do Trabalho&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;SETEMBRO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;7&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Independência do Brasil&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;OUTUBRO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;12&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Dia de Nossa Senhora Aparecida&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;OUTUBRO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;28&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Dia do Servidor Público (ponto facultativo)&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;NOVEMBRO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Finados&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;NOVEMBRO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;15&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Proclamação da República&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;NOVEMBRO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;20&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Dia da Consciência Negra&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;DEZEMBRO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;25&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Natal&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;ff&lt;/code&gt; e &lt;code&gt;fm&lt;/code&gt; representam respectivamente &lt;em&gt;feriado fixo&lt;/em&gt; e &lt;em&gt;feriado móvel&lt;/em&gt;. Essas funções recebem o dia e mês ou então uma função para calcular a data, além da descrição do feriado. O retorno delas é outra função, que recebe como argumento o ano numérico e por sua vez retorna um objeto feriado, com a descrição e a data exata (JavaScript &lt;code&gt;Date&lt;/code&gt;).&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// feriado fixo&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;function&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; ff&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;dia&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;desc&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;  return&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ano&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    return&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; { &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;data:&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; new&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; Date&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ano&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;dia&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;descricao:&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; desc&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// feriado móvel&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;function&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; fm&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;funcCalcDia&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;desc&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;  return&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ano&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    return&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; { &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;data:&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; funcCalcDia&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ano&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;descricao:&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; desc&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Aqui usamos dois conceitos da programação funcional: &lt;em&gt;higher-order functions&lt;/em&gt; e &lt;em&gt;currying&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Higher-order functions&lt;/em&gt; são funções que recebem funções como parâmetro de entrada ou então que retornam funções como valores de saída (ou até as duas coisas ao mesmo tempo). &lt;code&gt;fm()&lt;/code&gt; recebe &lt;code&gt;funcCalcDia&lt;/code&gt; como argumento; esta por sua vez receberá um ano numérico e devolverá um objeto &lt;em&gt;Date&lt;/em&gt;. Tanto &lt;code&gt;fm()&lt;/code&gt; como &lt;code&gt;ff()&lt;/code&gt; retornam funções.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Currying&lt;/em&gt; é uma estratégia de aninhamento de funções em cascata. No caso, &lt;code&gt;ff&lt;/code&gt; e &lt;code&gt;fm&lt;/code&gt; aninham as funções internas &lt;code&gt;function (ano) {...}&lt;/code&gt;. Confira em mais detalhes este outro &lt;a href=https://alexandrehtrb.github.io/posts/2025/09/o-que-eh-currying&gt;artigo&lt;/a&gt; sobre &lt;em&gt;currying&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Para obter os feriados de um conjunto, basta iterar por cada função passando o ano como argumento:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; ano&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2026&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; feriados&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; feriadosNacionais&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;map&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;((&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;func&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; func&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ano&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// retorno:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  { &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;data:&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; new&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; Date&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2026&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;descricao:&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Ano Novo&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  { &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;data:&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; new&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; Date&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2026&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;17&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;descricao:&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Carnaval&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  { &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;data:&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; new&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; Date&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2026&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;descricao:&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Paixão de Cristo&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;O código em questão usado para o site é público e está disponível no &lt;a href=https://github.com/alexandrehtrb/FeriadosDoBrasil/blob/master/feriados_calculo.js&gt;GitHub&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=leituras-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2026/01/fazendo-um-calendario-de-feriados-com-programacao-funcional/#leituras-interessantes class=header-anchor&gt;&lt;span&gt;Leituras interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://pt.wikipedia.org/wiki/Feriados_no_Brasil&gt;Wikipédia - Feriados no Brasil&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=http://vision.ime.usp.br/~pmiranda/mc102_1s07/lab01/lab.html&gt;Unicamp - Professor Paulo Miranda - Cálculo da Páscoa&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.tondering.dk/claus/cal/easter.php&gt;The Calendar FAQ - Easter&lt;/a&gt; (em inglês)&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Excel como frontend</title>
    <link href="https://alexandrehtrb.github.io/posts/2025/09/excel-como-frontend/" />
    <updated>2025-09-29T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2025/09/excel-como-frontend/</id>
    <content type="html">&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;Mr. Burns dos Simpsons dizendo Excelente&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2025_09_mr_burns_excellent.avif type=image/avif&gt;&lt;img alt=&quot;Mr. Burns dos Simpsons dizendo Excelente&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_09_mr_burns_excellent.jpg&gt;&lt;/picture&gt;&lt;/p&gt;&lt;p&gt;As finanças pessoais e das empresas. Relatórios governamentais e gerenciais. Extratos de operações. Inventários. Projeções. Simulações. Listas de pessoas. 90% do PIB global. O que todas essas coisas têm em comum?&lt;/p&gt;&lt;p&gt;Todas elas passam pelo Excel.&lt;/p&gt;&lt;p&gt;Nos projetos em que trabalhei, uma das funcionalidades mais pedidas pelos clientes é exportar dados para o Excel, principalmente em setores de &lt;em&gt;back-office&lt;/em&gt;, para que os analistas possam encontrar informações, produzir relatórios e calcular somas com maior facilidade. Não só &lt;em&gt;back-office&lt;/em&gt; — profissionais de campo, atendentes e vendedores também usam essa ferramenta.&lt;/p&gt;&lt;p&gt;Alguns exemplos da vida real:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Relatórios internos de transações de indivíduos;&lt;/li&gt;&lt;li&gt;Relatórios de vendas agrupadas por parceiro de negócio;&lt;/li&gt;&lt;li&gt;Um vendedor que precisa ver a lista de ofertas disponíveis para os clientes;&lt;/li&gt;&lt;li&gt;Um economista que precisa das taxas de inflação dos últimos meses;&lt;/li&gt;&lt;li&gt;Uma analista de RH que quer ver as horas trabalhadas dos funcionários;&lt;/li&gt;&lt;li&gt;Um analista de investimento que necessita do histórico de valores de um ativo.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;O Excel é uma ótima ferramenta para visualizar dados e é muito intuitiva, facilmente usada por qualquer pessoa.&lt;/p&gt;&lt;p&gt;Tendo em vista que ele muitas vezes é o formato final dos dados, surge a questão: ao invés de ter uma aplicação web, com backend e frontend, hospedagem, servidores e etc., não poderíamos fazer tudo direto pelo Excel? Seria mais fácil, não? Neste artigo, vamos explorar essa idéia.&lt;/p&gt;&lt;h2 id=conectando-com-fontes-de-dados-externas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/09/excel-como-frontend/#conectando-com-fontes-de-dados-externas class=header-anchor&gt;&lt;span&gt;Conectando com fontes de dados externas&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O Excel pode se conectar a fontes de dados externas e baixar dados delas. Existem várias integrações disponíveis, tais como:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;XMLs provenientes da internet&lt;/li&gt;&lt;li&gt;Arquivos XML, CSV, TXT e XLSX&lt;/li&gt;&lt;li&gt;Arquivos posicionais&lt;/li&gt;&lt;li&gt;Bancos de dados, como SQL Server, PostgreSQL, MySQL&lt;/li&gt;&lt;li&gt;Azure Blob Storage&lt;/li&gt;&lt;li&gt;Endpoints HTTP&lt;/li&gt;&lt;li&gt;E diversas outras.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Por exemplo, vamos criar um arquivo XML local com o seguinte conteúdo:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipcas_anuais&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2014&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;6,41%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2015&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;10,67%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2016&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;6,29%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2017&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2,95%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2018&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;3,75%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2019&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;4,31%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2020&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;4,52%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2021&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;10,06%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2022&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;5,78%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2023&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;4,62%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;2024&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ano&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;4,83%&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;valor&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipca&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ipcas_anuais&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No Excel, vamos na aba &lt;strong&gt;Dados&lt;/strong&gt;, depois clicar em &lt;strong&gt;Nova Consulta&lt;/strong&gt; &gt; &lt;strong&gt;Do Arquivo&lt;/strong&gt; &gt; &lt;strong&gt;Do XML&lt;/strong&gt;, e então selecionar nosso arquivo.&lt;/p&gt;&lt;img alt=&quot;Importar fonte de dados externa arquivo XML no Excel&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_09_excel_import_xml_file_pt.png class=my-4&gt;&lt;p&gt;Após a importação, o resultado será como abaixo:&lt;/p&gt;&lt;img alt=&quot;Resultado após importação de XML no Excel&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_09_excel_import_xml_file_result_pt.png class=my-4&gt;&lt;p&gt;Sempre que quiser sincronizar os dados, basta ir na aba &lt;strong&gt;Consulta&lt;/strong&gt; e clicar em &lt;strong&gt;Atualizar&lt;/strong&gt;, e a tabela será atualizada com os dados remotos.&lt;/p&gt;&lt;img alt=&quot;Sincronização de fonte de dados externa no Excel&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_09_excel_refresh_data_source_pt.png class=my-4&gt;&lt;h2 id=vantagens tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/09/excel-como-frontend/#vantagens class=header-anchor&gt;&lt;span&gt;Vantagens&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Fazer o Excel puxar dados remotos tem grandes vantagens.&lt;/p&gt;&lt;p&gt;Uma delas é que não precisamos gastar esforço, tempo e infraestrutura construindo um site para disponibilizar esses dados; basta prover uma planilha e a fonte de dados.&lt;/p&gt;&lt;p&gt;Até mesmo a segurança de acesso às informações já está resolvida:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Se a fonte de dados for um arquivo remoto, basta controlar as permissões de acesso a esse arquivo.&lt;/li&gt;&lt;li&gt;Se a fonte de dados for um banco de dados ou endpoint HTTP, pode-se passar uma credencial com permissões apenas para consultas autorizadas.&lt;/li&gt;&lt;li&gt;Autenticação Windows é uma opção para os casos acima.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Outra vantagem é que uma vez baixados, os dados ficam disponíveis para uso mesmo sem conexão com a Internet.&lt;/p&gt;&lt;p&gt;Por fim, ter planilhas individuais confere aos usuários grande liberdade de trabalho, pois eles podem customizar, fazer rascunhos e experimentos nelas.&lt;/p&gt;&lt;h2 id=opera%C3%A7%C3%B5es-de-escrita tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/09/excel-como-frontend/#opera%C3%A7%C3%B5es-de-escrita class=header-anchor&gt;&lt;span&gt;Operações de escrita&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Podemos usar o Excel para inserir, excluir e modificar dados remotos? Sim. O caminho para se fazer isso são os &lt;em&gt;UserForms&lt;/em&gt; e as &lt;em&gt;macros&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Os &lt;em&gt;UserForms&lt;/em&gt; são janelas e formulários customizáveis para que o usuário insira informações. Já as &lt;em&gt;macros&lt;/em&gt; são o código por trás, que valida entradas e é responsável por se conectar a servidores e bancos de dados.&lt;/p&gt;&lt;img alt=&quot;Userform no Excel&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_09_excel_userform.png class=my-4&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;Exemplo de userform no Excel.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Deve-se ter em mente que sempre que for necessária uma mudança nessas integrações de escrita, os usuários terão de baixar versões atualizadas da planilha.&lt;/p&gt;&lt;p&gt;Recomendo os seguintes tutoriais de userforms: um do &lt;a href=https://www.excel-easy.com/vba/userform.html&gt;Excel Easy&lt;/a&gt; e outro da &lt;a href=https://www.wiseowl.co.uk/vba-macros/guides/user-forms/vba-userform/ &gt;Wise Owl Training&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=conclus%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/09/excel-como-frontend/#conclus%C3%A3o class=header-anchor&gt;&lt;span&gt;Conclusão&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Para serviços internos de uma empresa, ou que usem muita matemática e dados em tabela, o Excel pode sim ser uma ótima alternativa.&lt;/p&gt;&lt;p&gt;Quando descobri que o Excel podia se conectar a fontes externas de dados, pensei &quot;como que eu não sabia disso até hoje?&quot;. É muito mais prático. Por ser um software que não é usado diariamente pelos profissionais de TI, ele acaba não sendo conhecido em profundidade por nós, e às vezes, funcionalidades interessantes como essas passam despercebidas.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>O que é currying?</title>
    <link href="https://alexandrehtrb.github.io/posts/2025/09/o-que-eh-currying/" />
    <updated>2025-09-04T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2025/09/o-que-eh-currying/</id>
    <content type="html">&lt;p&gt;&lt;em&gt;Currying&lt;/em&gt; é uma técnica para criar funções que compartilham uma mesma lógica. Nela, funções são aninhadas dentro de outras, cada uma sendo responsável por um parâmetro da lógica total.&lt;/p&gt;&lt;p&gt;Exemplo em JavaScript:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// função curryficada&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;function&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; multiplicarESomar&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;a&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;  return&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;b&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    return&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;      return&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; a&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;*&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; +&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; b&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; f&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; multiplicarESomar&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// f(x) = 2x + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;console&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;log&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;f&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)); &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// 9&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; g&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; multiplicarESomar&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// g(x) = 3x + b&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// b não especificado ainda&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;console&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;log&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;g&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)); &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// 5, b = 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Com &lt;em&gt;currying&lt;/em&gt;, subfunções podem aplicar argumentos fixos a uma função-mãe e herdar a declaração dos parâmetros restantes.&lt;/p&gt;&lt;p&gt;Uma forma de imaginar funções &lt;em&gt;curryficadas&lt;/em&gt; é como se fossem bonecas russas (&lt;a href=https://pt.wikipedia.org/wiki/Matriosca&gt;&lt;em&gt;matryoshkas&lt;/em&gt;&lt;/a&gt;): uma dentro de outra, dentro de outra.&lt;/p&gt;&lt;img alt=&quot;Bonecas russas matryoshkas&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2025_09_matryoshka.jpg&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;Fonte da imagem: &lt;a href=https://pt.aliexpress.com/item/1005010505814497.html&gt;AliExpress&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Essa técnica vem da programação funcional e é muito útil para cálculos e matemática.&lt;/p&gt;&lt;p&gt;Outro exemplo, em F#:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; volumePiramide&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;formulaAreaBase&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;c&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;l&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;a&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  a &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;formulaAreaBase&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;l&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))/&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3.0&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; areaRetangulo&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;c&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;l&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; c &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; l&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; areaTriangulo&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;c&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;l&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; l&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)/&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2.0&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; areaCirculo&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;r&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Math.PI &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; r&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;**&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2.0&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; volumePiramideBaseRetangular&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  volumePiramide&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;areaRetangulo&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; volumePiramideBaseTriangular&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  volumePiramide&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;areaTriangulo&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; volumeCone&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  volumePiramide&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;areaCirculo&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// usos&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; volumePiramideBaseRetangular&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;7.0&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4.0&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;11.0&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; vc&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; volumeCone&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;9.0&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;12.0&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; // raio 9, altura 12&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Quanto menos um parâmetro varia entre as subfunções, mais à esquerda ele deve ficar na declaração curryficada.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Contêineres deveriam ser responsabilidade do sistema operacional</title>
    <link href="https://alexandrehtrb.github.io/posts/2025/06/conteineres-deveriam-ser-responsabilidade-do-sistema-operacional/" />
    <updated>2025-06-10T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2025/06/conteineres-deveriam-ser-responsabilidade-do-sistema-operacional/</id>
    <content type="html">&lt;p&gt;Não antes de 2018, pouco a pouco, nos dias de trabalho na empresa, meus colegas começaram a falar sobre Docker, uma tecnologia que preparava ambientes para rodar os programas nos servidores. Menos de dois anos depois, Docker tinha se tornado a regra e aplicações novas vinham com Dockerfile e arquivos YAML para Kubernetes.&lt;/p&gt;&lt;p&gt;Apesar de entender a finalidade de uso dos contêineres, parte de mim dizia que eram uma solução desnecessariamente pesada e que os problemas solucionados deveriam ser tratados pelos sistemas operacionais. Minha opinião permanece.&lt;/p&gt;&lt;p&gt;Neste artigo, abordarei os problemas resolvidos pelos contêineres, alternativas e uma proposta para ser implementada por sistemas operacionais.&lt;/p&gt;&lt;h2 id=come%C3%A7ando-pelo-fim tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/06/conteineres-deveriam-ser-responsabilidade-do-sistema-operacional/#come%C3%A7ando-pelo-fim class=header-anchor&gt;&lt;span&gt;Começando pelo fim&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Afinal de contas, por que usamos contêineres? A maioria absoluta das respostas é: &quot;Porque preciso rodar minha aplicação na nuvem&quot;.&lt;/p&gt;&lt;p&gt;O Docker resolveu dois problemas: a preparação do ambiente e a segurança de execução.&lt;/p&gt;&lt;p&gt;A preparação do ambiente se dá porque as imagens dos contêineres vêm com o necessário para a execução do programa, que geralmente são o &lt;em&gt;runtime&lt;/em&gt; da aplicação e pacotes relacionados. Isso pode ser complexo principalmente em ambientes Linux, pois há toda uma árvore de dependências que é sensível a mudanças e atualizações. Ter uma árvore de dependências rígida e reproduzível garante estabilidade, evitando que a aplicação pare de funcionar corretamente por incompatibilidade com alguma nova versão de um pacote.&lt;/p&gt;&lt;p&gt;A segurança de execução decorre de o contêiner ser um processo com mapeamento de rede e volume de arquivos isolados, sem risco de invadir e infectar arquivos da máquina principal.&lt;/p&gt;&lt;h3&gt;Preparação de ambiente, sem contêineres&lt;/h3&gt;&lt;p&gt;Existem várias formas de se preparar um ambiente sem recorrer a contêineres.&lt;/p&gt;&lt;p&gt;Uma é realmente instalar as dependências necessárias na máquina.&lt;/p&gt;&lt;p&gt;Outra é compilação autocontida (&lt;em&gt;self-contained deployment&lt;/em&gt;), em que o executável carrega consigo o &lt;em&gt;runtime&lt;/em&gt; da linguagem e todas suas dependências. Assim, a máquina não precisa ter ele instalado.&lt;/p&gt;&lt;p&gt;Algumas linguagens oferecem compilação para código de máquina, chamada de AOT (&lt;em&gt;ahead-of-time compilation&lt;/em&gt;), que faz com que o &lt;em&gt;runtime&lt;/em&gt; não seja necessário e também reduz o número de dependências externas, além de oferecer maior performance e menor consumo de memória aos programas.&lt;/p&gt;&lt;p&gt;A base de uma imagem Docker de sistema operacional é a &lt;em&gt;user space&lt;/em&gt;, que é o sistema operacional, menos sua &lt;em&gt;kernel&lt;/em&gt;. São programas essenciais, bibliotecas, serviços em background e outros arquivos.&lt;/p&gt;&lt;p&gt;Carregar uma &lt;em&gt;user space&lt;/em&gt; de sistema operacional para cada contêiner desperdiça memória RAM e disco rígido. A imagem Docker do Ubuntu, por exemplo, ocupa 188MB, o que é bastante. Existem imagens ultra-leves que deixam apenas o que é estritamente necessário; por exemplo, a imagem Alpine Linux ocupa apenas 5MB. Ainda assim, é um peso extra para cada aplicação.&lt;/p&gt;&lt;p&gt;As soluções acima mostram como mitigar o risco de uma árvore de dependências frágil.&lt;/p&gt;&lt;h3&gt;Segurança de execução, sem contêineres&lt;/h3&gt;&lt;p&gt;Esse ponto é mais complicado. Aqui, queremos limitar o acesso do programa ao sistema de arquivos e à rede.&lt;/p&gt;&lt;p&gt;Na maioria dos sistemas operacionais, o controle de acesso ao sistema de arquivos é a nível de usuário. Para fazer com que um programa só possa acessar determinados arquivos e diretórios, é preciso criar um usuário (ou grupo de usuários) com essas regras e então fazer com que o programa seja sempre executado a partir desse usuário.&lt;/p&gt;&lt;p&gt;Já a restrição de comunicação de rede é feita via &lt;em&gt;firewall&lt;/em&gt;, com controle de acesso a nível de usuários e programas.&lt;/p&gt;&lt;h2 id=proposta%3A-manifestos-de-execu%C3%A7%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/06/conteineres-deveriam-ser-responsabilidade-do-sistema-operacional/#proposta%3A-manifestos-de-execu%C3%A7%C3%A3o class=header-anchor&gt;&lt;span&gt;Proposta: Manifestos de execução&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Uma sugestão para sistemas operacionais seria ter manifestos de execução, que definem claramente como um programa é executado e as permissões dele no sistema.&lt;/p&gt;&lt;p&gt;O manifesto de execução poderia ainda definir com quais dispositivos e periféricos o programa interage. Ou seja, poderia ser útil também para programas desktop, com interfaces gráficas.&lt;/p&gt;&lt;p&gt;Esse arquivo poderia ser assinado com um par de chaves pública-privada para garantia de autenticidade. Um &lt;em&gt;hash&lt;/em&gt; verificaria se o executável corresponde ao esperado pelo manifesto.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;manifestVersion&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;v1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;author&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;myCompany&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;myApp&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;./myapp&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;hash&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&amp;lt;hash_do_executável&gt;&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; # opcional&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;allowedDirectories&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;appDir&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    path&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;./**/&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; # todos os subdiretórios&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    permission&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;read&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;sharedFolder&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    path&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&#92;&#92;EnvGeoServer&#92;Repository&#92;Tools&#92;admin&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    permission&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;readWrite&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;allowedNetwork&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;localhost&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    direction&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;inbound&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    ip&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;127.0.0.1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    protocol&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;tcp&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    port&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;8080&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;allowedDevices&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  - &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;mouse&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  - &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;keyboard&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  - &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;audioOut&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  - &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;display&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=fontes-e-leituras-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/06/conteineres-deveriam-ser-responsabilidade-do-sistema-operacional/#fontes-e-leituras-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e leituras interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://iximiuz.com/en/posts/you-dont-need-an-image-to-run-a-container/ &gt;Ivan Velichko - You Don&#39;t Need an Image To Run a Container&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://stackoverflow.com/questions/32756988/what-is-meant-by-shared-kernel-in-docker&gt;Stack Overflow - What is meant by shared kernel in Docker?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/windows/win32/secauthz/appcontainer-isolation&gt;AppContainer isolation - Win32 apps | Microsoft Learn&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://superuser.com/questions/1238613/restrict-access-to-files-by-list-of-programs&gt;SuperUser - Restrict access to files by list of programs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://stackoverflow.com/questions/11345374/prevent-accessing-files-outside-of-given-working-directory&gt;Stack Overflow - Prevent accessing files outside of given working directory&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://stuff.mit.edu/afs/sipb/project/android/docs/guide/topics/manifest/manifest-intro.html&gt;The AndroidManifest.xml File | Android Developers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://pt.wikipedia.org/wiki/Compila%C3%A7%C3%A3o_AOT&gt;Wikipédia - Compilação AOT&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Logs estruturados em .NET com NativeAOT</title>
    <link href="https://alexandrehtrb.github.io/posts/2025/04/logs-estruturados-em-dotnet-com-nativeaot/" />
    <updated>2025-04-15T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2025/04/logs-estruturados-em-dotnet-com-nativeaot/</id>
    <content type="html">&lt;p&gt;NativeAOT e &lt;em&gt;trimming&lt;/em&gt; são duas novas opções de compilação em .NET que surgiram nos últimos anos, proporcionando executáveis menores, mais rápidos e com menor consumo de memória RAM. Resumidamente, o NativeAOT compila direto para código nativo de máquina e o &lt;em&gt;trimming&lt;/em&gt; remove trechos de código desnecessários.&lt;/p&gt;&lt;p&gt;Para aplicar essas opções, é necessário que todos os caminhos de código sejam analisáveis estaticamente, ou seja, &lt;strong&gt;não pode haver uso de &lt;em&gt;reflection&lt;/em&gt; na aplicação&lt;/strong&gt;, sob o risco de ter partes importantes removidas acidentalmente e haver comportamentos indesejáveis durante a execução.&lt;/p&gt;&lt;p&gt;A maioria das bibliotecas de logging atualmente (12/04/2025) trabalha com &lt;em&gt;reflection&lt;/em&gt;, principalmente para suportar logs estruturados. Neste artigo, vamos ver como fazer um logger estruturado customizado, compatível com NativeAOT e &lt;em&gt;trimming&lt;/em&gt;.&lt;/p&gt;&lt;h2 id=logs-estruturados tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/04/logs-estruturados-em-dotnet-com-nativeaot/#logs-estruturados class=header-anchor&gt;&lt;span&gt;Logs estruturados&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Em um log estruturado, as mensagens ficam em uma estrutura de chaves-valores, como JSON ou XML. Esse formato permite que elas sejam facilmente processadas por bancos de dados e motores de logs.&lt;/p&gt;&lt;p&gt;Considere o exemplo abaixo:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; municipio&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Bento Gonçalves / RS&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;PrevisaoTempo&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; previsao&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    tempMin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    tempMax&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;21&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    chuvaMm&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32.5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    ventoKmh&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;6&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;using&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;BeginScope&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;{@PrevisaoTempo}&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;previsao&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;LogInformation&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Previsão do tempo para {Municipio} em {Data}&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        municipio&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;DateTime&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Today&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Log estruturado em JSON:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Timestamp&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;2025-04-12T20:25:57.8532799Z&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Level&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Information&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Template&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Previsão do tempo para {Municipio} em {Data}&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Municipio&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Bento Gonçalves / RS&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Data&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;2025-04-13&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;@PrevisaoTempo&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;    &quot;TemperaturaMinimaEmC&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;    &quot;TemperaturaMaximaEmC&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;21&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;    &quot;ChuvaEmMm&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32.5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;    &quot;VentoEmKmH&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;6&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Quando um parâmetro entre chaves tem arroba (&#39;@&#39;) no início, trata-se de um objeto complexo e suas propriedades internas são lidas como chave-valor. Quando não há arroba, trata-se de um valor simples, como um número, um Guid ou uma string.&lt;/p&gt;&lt;p&gt;Os escopos são informações complementares ao log, que podem ser relevantes.&lt;/p&gt;&lt;h2 id=interface-ilogger-em-.net tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/04/logs-estruturados-em-dotnet-com-nativeaot/#interface-ilogger-em-.net class=header-anchor&gt;&lt;span&gt;Interface &lt;code&gt;ILogger&lt;/code&gt; em .NET&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O .NET moderno faz uso extensivo da interface &lt;code&gt;Microsoft.Extensions.Logging.ILogger&lt;/code&gt;. Ela é descrita abaixo (&lt;a href=https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/ILogger.cs&gt;código-fonte&lt;/a&gt;):&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;namespace&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Logging&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; interface&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ILogger&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    void&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; Log&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;LogLevel&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; logLevel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;EventId&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; eventId&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; state&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Exception&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;exception&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Func&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Exception&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;formatter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    bool&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; IsEnabled&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;LogLevel&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; logLevel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;    IDisposable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;BeginScope&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; state&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;where&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; TState&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; : &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;notnull&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Apesar de não estar explícito na interface, o &lt;code&gt;TState&lt;/code&gt; quase sempre é um tipo que herda de &lt;code&gt;IReadOnlyList&amp;lt;KeyValuePair&amp;lt;string, object?&gt;&gt;&lt;/code&gt;, isso é verificável pelo próprio código-fonte do .NET runtime: &lt;a href=https://github.com/dotnet/runtime/blob/e220a94d842524b408c35b381fc326c4159005f0/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LoggerExtensions.cs#L486&gt;classe LoggerExtensions&lt;/a&gt; e &lt;a href=https://github.com/dotnet/runtime/blob/e220a94d842524b408c35b381fc326c4159005f0/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs#L16&gt;classe FormattedLogValues&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;O &lt;code&gt;TState&lt;/code&gt; contém pares de chave-valor, incluindo o template da mensagem e valores dos parâmetros. Isso vale tanto para o &lt;code&gt;TState&lt;/code&gt; do método &lt;code&gt;Log&lt;/code&gt; como do método &lt;code&gt;BeginScope&lt;/code&gt;.&lt;/p&gt;&lt;h2 id=logger-sem-reflection tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/04/logs-estruturados-em-dotnet-com-nativeaot/#logger-sem-reflection class=header-anchor&gt;&lt;span&gt;Logger sem &lt;em&gt;reflection&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A questão aqui é como formatar uma mensagem de log de forma genérica e sem usar &lt;em&gt;reflection&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Como solução, vamos fazer um log em JSON com o apoio de &lt;em&gt;source generators&lt;/em&gt;. No &lt;code&gt;JsonSerializerContext&lt;/code&gt; a ser usado no nosso logger, precisaremos incluir todos os tipos de objeto que possam vir como parâmetros de log.&lt;/p&gt;&lt;h3&gt;Considerações&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Nosso logger implementará a interface &lt;code&gt;ILogger&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Consideraremos que o &lt;code&gt;TState&lt;/code&gt; sempre herda de &lt;code&gt;IReadOnlyList&amp;lt;KeyValuePair&amp;lt;string, object?&gt;&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Filtraremos as mensagens para pegar apenas as relevantes, de modo a também diminuir a quantidade de tipos adicionados ao &lt;code&gt;JsonSerializerContext&lt;/code&gt;. Isso é importante principalmente para projetos ASP.NET.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Neste exemplo, a saída de log será no console.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Usaremos o formato &lt;a href=https://clef-json.org/ &gt;&lt;strong&gt;CLEF&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;O &lt;code&gt;scopeProvider&lt;/code&gt; é responsável por ler os escopos capturados. Usaremos a implementação padrão &lt;code&gt;LoggerExternalScopeProvider&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Código&lt;/h3&gt;&lt;p&gt;No setup do HostBuilder / WebApplicationBuilder (Program.cs):&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;webAppBuilder&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Logging&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ClearProviders&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;AddProvider&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;new&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ClefLoggerProvider&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Logger provider:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; sealed&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; class&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ClefLoggerProvider&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; : &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;ILoggerProvider&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ILogger&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; CreateLogger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; categoryName&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;        new&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ClefLogger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;categoryName&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;new&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; LoggerExternalScopeProvider&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; void&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; Dispose&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;() { }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No JsonSerializerContext:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;[&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;JsonSerializable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;typeof&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Dictionary&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;object&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?&gt;))]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;[&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;JsonSerializable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;typeof&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;double&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;))]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;[&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;JsonSerializable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;typeof&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;long&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;))]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// adicionar tipos aqui, por exemplo:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;[&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;JsonSerializable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;typeof&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;PrevisaoTempo&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;))]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// opções de JSON&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;[&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;JsonSourceGenerationOptions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    WriteIndented&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; false&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    PropertyNamingPolicy&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; JsonKnownNamingPolicy&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;CamelCase&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    DefaultIgnoreCondition&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; JsonIgnoreCondition&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;WhenWritingNull&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; partial&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; class&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; AppJsonSrcGenContext&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; : &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;JsonSerializerContext&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Logger:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; sealed&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; class&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ClefLogger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    string&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; categoryName&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;    IExternalScopeProvider&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;scopeProvider&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) : &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;ILogger&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    private&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; static&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; readonly&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;[] &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;logsParaIgnorar&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Request starting&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Executing&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Setting HTTP status code&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Executed&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Writing value&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Write content&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Sending file&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;        &quot;Request reached the end of the middleware pipeline without being handled by application code.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    ];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; IDisposable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;BeginScope&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; state&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;        where&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; TState&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; : &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;notnull&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        scopeProvider&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;?&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Push&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;state&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;??&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; default&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; bool&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; IsEnabled&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;LogLevel&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; logLevel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; true&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    private&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; static&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; bool&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; FiltrarPropriedades&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;KeyValuePair&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;object&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;kv&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        kv&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Key&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; !=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;{OriginalFormat}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;        &amp;&amp;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; kv&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Value&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; !=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; null&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;        &amp;&amp;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;kv&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Value&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; is&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; string&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; s&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; ?&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; !&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;IsNullOrEmpty&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;s&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;:&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; true&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    private&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; static&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; bool&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; DeveIgnorarLog&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;originalFormat&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        originalFormat&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; is&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; null&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; ||&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; logsParaIgnorar&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Any&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;originalFormat&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;StartsWith&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; void&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; Log&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;LogLevel&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; logLevel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;EventId&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; eventId&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; state&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Exception&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;exception&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Func&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;TState&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Exception&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;formatter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        if&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;state&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; is&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; not&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; IEnumerable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;KeyValuePair&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;object&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msgProps&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;            return&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;originalFormat&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?)&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msgProps&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;FirstOrDefault&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;kv&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&gt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; kv&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Key&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; ==&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;{OriginalFormat}&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;).&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Value&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        if&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;DeveIgnorarLog&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;originalFormat&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;            return&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;        List&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;IEnumerable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;KeyValuePair&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;object&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?&gt;&gt;&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;scopes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        scopeProvider&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;?&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ForEachScope&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;((&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;scope&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;st&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;            if&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;scope&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; is&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; IEnumerable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;KeyValuePair&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;object&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;scopeItems&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;                scopes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Add&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;scopeItems&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Where&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;FiltrarPropriedades&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        }, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;state&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;        IEnumerable&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;KeyValuePair&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;object&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;standardProps&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        [&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;            new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;@i&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;eventId&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;            new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;@t&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;DateTime&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;UtcNow&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ToString&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;yyyy-MM-ddTHH:mm:ss.fffffffZ&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;            new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;@c&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;categoryName&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;            new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;@l&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Enum&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;GetName&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;logLevel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;            //new(&quot;@m&quot;, formatter(state, exception)),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;            new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;@mt&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;originalFormat&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;            new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;@x&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;exception&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;?&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ToString&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        ];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;        var&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; standardProps&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Concat&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msgProps&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Where&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;FiltrarPropriedades&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Concat&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;scopes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;SelectMany&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&gt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; x&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;            // evitando chaves repetidas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;DistinctBy&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;kv&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&gt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; kv&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Key&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;            // remover nulos para JSON&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Where&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&gt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; x&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Value&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; is&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; not&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; null&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ToDictionary&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        try&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;            EscreverLinhaLog&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        catch&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Exception&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; jsonEx&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;            msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; standardProps&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;                .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Append&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;AVISO&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Não foi possível serializar mensagem original em JSON.&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;                .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Append&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;JsonException&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;jsonEx&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ToString&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;()))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;                // remover nulos para JSON&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;                .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Where&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&gt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; x&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Value&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; is&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; not&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; null&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;                .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ToDictionary&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;            EscreverLinhaLog&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // TODO: Usar fila para evitar concorrência&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // Mudar saída se quiser: arquivo, motor de logs, etc.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    private&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; void&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; EscreverLinhaLog&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Dictionary&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;object&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        string&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; json&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; JsonSerializer&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Serialize&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;AppJsonSrcGenContext&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Default&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;DictionaryStringObject&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        Console&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;WriteLine&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;json&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;O logger acima funciona com NativeAOT e &lt;em&gt;trimming&lt;/em&gt; habilitados.&lt;/p&gt;&lt;p&gt;Se houver algum erro de serialização de JSON, o bloco catch formata uma nova mensagem de log sem as propriedades e escopos (possíveis causadores do erro) e coloca a JsonException relativa ao problema.&lt;/p&gt;&lt;h3&gt;Exemplo de log gerado&lt;/h3&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;@t&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;2025-04-15T12:09:58.4990143Z&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;@c&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Microsoft.AspNetCore.Hosting.Diagnostics&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;@l&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Information&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;@mt&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Request finished {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} - {StatusCode} {ContentLength} {ContentType} {ElapsedMilliseconds}ms&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;ElapsedMilliseconds&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;124.2172&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;StatusCode&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;201&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;ContentType&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;application/json; charset=utf-8&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Protocol&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;HTTP/2&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Method&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;POST&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Scheme&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;https&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Host&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;localhost:5001&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;Path&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;RequestId&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;0HNBS2ORC5B08:00000001&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#0451a5;--shiki-dark:#62A6CA&gt;  &quot;RequestPath&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=fontes-e-links-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/04/logs-estruturados-em-dotnet-com-nativeaot/#fontes-e-links-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e links interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ &gt;Microsoft Learn - .NET Native AOT Deployment&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options&gt;Microsoft Learn - .NET Trimming options&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/aspnet/core/fundamentals/native-aot&gt;Microsoft Learn - ASP.NET Core support for Native AOT&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://messagetemplates.org/ &gt;Message Templates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://clef-json.org/ &gt;Compact Log Event Format (CLEF)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Método dos mínimos quadrados com programação funcional</title>
    <link href="https://alexandrehtrb.github.io/posts/2025/03/metodo-dos-minimos-quadrados-com-programacao-funcional/" />
    <updated>2025-03-07T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2025/03/metodo-dos-minimos-quadrados-com-programacao-funcional/</id>
    <content type="html">&lt;p&gt;Suponha que você tenha um conjunto de dados numéricos e queira formar uma estimativa futura a partir deles. Alguns exemplos:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Preço de um produto;&lt;/li&gt;&lt;li&gt;Demanda e produção históricas;&lt;/li&gt;&lt;li&gt;Cotação de ativos financeiros;&lt;/li&gt;&lt;li&gt;Calibração de uma máquina ao longo do tempo;&lt;/li&gt;&lt;li&gt;Concentração de reagentes e produtos químicos;&lt;/li&gt;&lt;li&gt;Velocidade de propagação de uma doença;&lt;/li&gt;&lt;li&gt;Volume de reservatórios de água;&lt;/li&gt;&lt;li&gt;Demanda de energia elétrica;&lt;/li&gt;&lt;li&gt;Consumo de combustível.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;O método dos mínimos quadrados é uma ferramenta matemática que gera uma equação próxima de medições existentes. Diversas curvas podem ser aproximadas, como lineares, polinomiais, exponenciais, logarítmicas e diversas outras.&lt;/p&gt;&lt;p&gt;Considere o gráfico abaixo, de vendas por mês. A linha azul é a aproximação linear e a linha vermelha corresponde às medições reais.&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;---
config:
    xyChart:
        width: 540
    themeVariables:
        xyChart:
            backgroundColor: &quot;#00000000&quot;
            plotColorPalette: &quot;#C00, #22F&quot;
---
xychart-beta
    title &quot;Vendas por mês (R$)&quot;
    x-axis &quot;mês&quot; [1,2,3,4,5,6,7,8,9,10,11,12]
    y-axis 0 --&gt; 50000
    line [17000, 24000, 16000, 30000, 35000, 26000, 29000, 40000, 44000, 35000, 41000, 47000]
	line [18461.538, 20923.076, 23384.614, 25846.152, 28307.690, 30769.228, 33230.766, 35692.304, 38153.842, 40615.380, 43076.918, 45538.456]
	%% =2461,538 * x + 16000

&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=base-te%C3%B3rica tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/03/metodo-dos-minimos-quadrados-com-programacao-funcional/#base-te%C3%B3rica class=header-anchor&gt;&lt;span&gt;Base teórica&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Considere &lt;strong&gt;f(x)&lt;/strong&gt; sendo a equação que queremos gerar e &lt;strong&gt;(x&lt;sub&gt;i&lt;/sub&gt;, y&lt;sub&gt;i&lt;/sub&gt;)&lt;/strong&gt; as medições coletadas. A melhor equação é aquela cujas diferenças entre aproximações e medições sejam as menores possíveis; em outras palavras:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;|f(x&lt;sub&gt;i&lt;/sub&gt;) − y&lt;sub&gt;i&lt;/sub&gt;|&lt;/strong&gt; é a distância entre aproximação e realidade;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Σ&lt;/strong&gt; é o somatório.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Σ|f(x&lt;sub&gt;i&lt;/sub&gt;) − y&lt;sub&gt;i&lt;/sub&gt;|&lt;/strong&gt; deve ser o mais próximo de zero.&lt;/li&gt;&lt;/ul&gt;&lt;img alt=&quot;Diferenças entre aproximação e medições.&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2025_03_least_ordinary_squares_errors.png&gt;&lt;p&gt;Vamos chamar de SQE a soma dos quadrados dos erros: &lt;strong&gt;SQE = Σ(f(x&lt;sub&gt;i&lt;/sub&gt;) − y&lt;sub&gt;i&lt;/sub&gt;)&lt;sup&gt;2&lt;/sup&gt;&lt;/strong&gt;. Como o objetivo é &quot;medir a distância&quot; entre aproximação e realidade, é mais fácil elevarmos a diferença ao quadrado, ao invés de aplicar o módulo.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Precisamos aplicar módulo ou elevar ao quadrado para medição de distância pois uma subtração simples poderia resultar em um valor negativo, e não existe distância negativa.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;O mínimo de SQE depende do tipo de função que queremos aproximar:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Linear: &lt;strong&gt;f(x) = ax + b&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Exponencial: &lt;strong&gt;f(x) = a ⋅ e&lt;sup&gt;bx&lt;/sup&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Potencial: &lt;strong&gt;f(x) = ax&lt;sup&gt;b&lt;/sup&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Logarítmica: &lt;strong&gt;f(x) = a + b ⋅ ln(x)&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Substituindo f(x) pelas funções acima em SQE, teremos que ela depende das variáveis a e b. No caso da aproximação linear: &lt;strong&gt;SQE(a,b) = Σ(ax&lt;sub&gt;i&lt;/sub&gt; + b − y&lt;sub&gt;i&lt;/sub&gt;)&lt;sup&gt;2&lt;/sup&gt;&lt;/strong&gt;. x&lt;sub&gt;i&lt;/sub&gt; e y&lt;sub&gt;i&lt;/sub&gt; são constantes, por serem pré-fornecidos.&lt;/p&gt;&lt;p&gt;O mínimo de uma função fica no ponto em que sua derivada (leia-se inclinação) é igual a zero:&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;---
config:
    xyChart:
        width: 540
    themeVariables:
        xyChart:
            backgroundColor: &quot;#00000000&quot;
            plotColorPalette: &quot;#CC0000, #f59316, #f59316, #f59316&quot;
---
xychart-beta
    title &quot;y = x²&quot;
    x-axis &quot;x&quot; -6 --&gt; 6
    y-axis &quot;y&quot; 0 --&gt; 40
    line [36,25,16,9,4,1,0,1,4,9,16,25,36]
	line [27,21,15,9,3,-3,-9,-15,-21,-27,-33,-39,-45]
    line [0,0,0,0,0,0,0,0,0,0,0]
    line [-45,-39,-33,-27,-21,-15,-9,-3,3,9,15,21,27]

&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;Em vermelho: y = x². Em laranja: as derivadas (retas de inclinação) em x = −3, 0 e 3.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Temos que SQE vai ter seu ponto mínimo onde as derivadas parciais em relação a &lt;strong&gt;a&lt;/strong&gt; e &lt;strong&gt;b&lt;/strong&gt; tiverem valor zero, resolvendo o sistema de equações:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;∂SQE(a,b) / ∂a = 0&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;∂SQE(a,b) / ∂b = 0&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Essa é a base teórica do método dos mínimos quadrados. Se você ficou interessado e quer se aprofundar na teoria, há links no final desta página com explicações adicionais sobre o assunto. Particularmente, recomendo esta &lt;a href=https://alexandrehtrb.github.io/assets/misc/aula_ufpr_m%C3%ADnimos_quadrados.pdf&gt;aula da UFPR&lt;/a&gt;.&lt;/p&gt;&lt;br&gt;&lt;h1 id=programa%C3%A7%C3%A3o-funcional tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/03/metodo-dos-minimos-quadrados-com-programacao-funcional/#programa%C3%A7%C3%A3o-funcional class=header-anchor&gt;&lt;span&gt;Programação funcional&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;A programação funcional é um paradigma que foca nas transformações dos dados: como em uma função matemática, um valor &lt;strong&gt;x&lt;/strong&gt; entra e é transformado por &lt;strong&gt;f(x)&lt;/strong&gt;. Num código funcional, transformações muitas vezes são aplicadas em cascata, ex.: &lt;strong&gt;f(g(h(x)))&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Neste artigo, vamos usar a linguagem F#, que usa o &lt;a href=https://dotnet.microsoft.com&gt;&lt;em&gt;runtime&lt;/em&gt; .NET&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Este &lt;a href=https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/#linguagem-f%23&gt;post&lt;/a&gt; explica como montar seu ambiente e tem dicas de sintaxe da linguagem.&lt;/p&gt;&lt;br&gt;&lt;h1 id=aproxima%C3%A7%C3%A3o-linear tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/03/metodo-dos-minimos-quadrados-com-programacao-funcional/#aproxima%C3%A7%C3%A3o-linear class=header-anchor&gt;&lt;span&gt;Aproximação linear&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;A equação gerada será do tipo &lt;strong&gt;f(x) = ax + b&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Tendo um conjunto de valores medidos (x&lt;sub&gt;i&lt;/sub&gt;, y&lt;sub&gt;i&lt;/sub&gt;), a e b são calculados por:&lt;/p&gt;&lt;br&gt;&lt;p&gt;&lt;svg aria-hidden=true focusable=false height=60px role=img style=vertical-align:-2.194ex viewBox=&quot;0 -1460 10250.3 2429.9&quot; width=90% xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink&gt;&lt;defs&gt;&lt;path d=&quot;M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z&quot; id=MJX-1-TEX-I-1D44E&gt;&lt;/path&gt;&lt;path d=&quot;M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z&quot; id=MJX-1-TEX-N-3D&gt;&lt;/path&gt;&lt;path d=&quot;M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z&quot; id=MJX-1-TEX-I-1D45B&gt;&lt;/path&gt;&lt;path d=&quot;M61 748Q64 750 489 750H913L954 640Q965 609 976 579T993 533T999 516H979L959 517Q936 579 886 621T777 682Q724 700 655 705T436 710H319Q183 710 183 709Q186 706 348 484T511 259Q517 250 513 244L490 216Q466 188 420 134T330 27L149 -187Q149 -188 362 -188Q388 -188 436 -188T506 -189Q679 -189 778 -162T936 -43Q946 -27 959 6H999L913 -249L489 -250Q65 -250 62 -248Q56 -246 56 -239Q56 -234 118 -161Q186 -81 245 -11L428 206Q428 207 242 462L57 717L56 728Q56 744 61 748Z&quot; id=MJX-1-TEX-SO-2211&gt;&lt;/path&gt;&lt;path d=&quot;M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z&quot; id=MJX-1-TEX-I-1D465&gt;&lt;/path&gt;&lt;path d=&quot;M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z&quot; id=MJX-1-TEX-I-1D466&gt;&lt;/path&gt;&lt;path d=&quot;M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z&quot; id=MJX-1-TEX-N-2212&gt;&lt;/path&gt;&lt;path d=&quot;M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z&quot; id=MJX-1-TEX-N-32&gt;&lt;/path&gt;&lt;path d=&quot;M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z&quot; id=MJX-1-TEX-N-28&gt;&lt;/path&gt;&lt;path d=&quot;M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z&quot; id=MJX-1-TEX-N-29&gt;&lt;/path&gt;&lt;/defs&gt;&lt;g transform=scale(1,-1) fill=currentColor stroke=currentColor stroke-width=0&gt;&lt;g data-mml-node=math&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D44E xlink:href=#MJX-1-TEX-I-1D44E&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(806.8,0)&gt;&lt;use data-c=3D xlink:href=#MJX-1-TEX-N-3D&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mfrac transform=translate(1862.6,0)&gt;&lt;g data-mml-node=mrow transform=translate(220,710)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D45B xlink:href=#MJX-1-TEX-I-1D45B&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(766.7,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-1-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(1989.3,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-1-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(2561.3,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-1-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(3273.6,0)&gt;&lt;use data-c=2212 xlink:href=#MJX-1-TEX-N-2212&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4273.8,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-1-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(5496.4,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-1-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(6235.1,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-1-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(7457.8,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-1-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mrow transform=translate(579.1,-719.9)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D45B xlink:href=#MJX-1-TEX-I-1D45B&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(766.7,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-1-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(1989.3,0)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D465 xlink:href=#MJX-1-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(605,289) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-1-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(3220.1,0)&gt;&lt;use data-c=2212 xlink:href=#MJX-1-TEX-N-2212&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4220.3,0)&gt;&lt;use data-c=28 xlink:href=#MJX-1-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4609.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-1-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(5832,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-1-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(6404,0)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=29 xlink:href=#MJX-1-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(422,289) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-1-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;rect height=60 width=8147.8 x=120 y=220&gt;&lt;/rect&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/p&gt;&lt;br&gt;&lt;p&gt;&lt;svg aria-hidden=true focusable=false height=60px role=img style=vertical-align:-2.194ex viewBox=&quot;0 -1543.9 11781.6 2513.9&quot; width=90% xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink&gt;&lt;defs&gt;&lt;path d=&quot;M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z&quot; id=MJX-3-TEX-I-1D44F&gt;&lt;/path&gt;&lt;path d=&quot;M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z&quot; id=MJX-3-TEX-N-3D&gt;&lt;/path&gt;&lt;path d=&quot;M61 748Q64 750 489 750H913L954 640Q965 609 976 579T993 533T999 516H979L959 517Q936 579 886 621T777 682Q724 700 655 705T436 710H319Q183 710 183 709Q186 706 348 484T511 259Q517 250 513 244L490 216Q466 188 420 134T330 27L149 -187Q149 -188 362 -188Q388 -188 436 -188T506 -189Q679 -189 778 -162T936 -43Q946 -27 959 6H999L913 -249L489 -250Q65 -250 62 -248Q56 -246 56 -239Q56 -234 118 -161Q186 -81 245 -11L428 206Q428 207 242 462L57 717L56 728Q56 744 61 748Z&quot; id=MJX-3-TEX-SO-2211&gt;&lt;/path&gt;&lt;path d=&quot;M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z&quot; id=MJX-3-TEX-I-1D466&gt;&lt;/path&gt;&lt;path d=&quot;M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z&quot; id=MJX-3-TEX-I-1D465&gt;&lt;/path&gt;&lt;path d=&quot;M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z&quot; id=MJX-3-TEX-N-32&gt;&lt;/path&gt;&lt;path d=&quot;M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z&quot; id=MJX-3-TEX-N-2212&gt;&lt;/path&gt;&lt;path d=&quot;M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z&quot; id=MJX-3-TEX-I-1D45B&gt;&lt;/path&gt;&lt;path d=&quot;M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z&quot; id=MJX-3-TEX-N-28&gt;&lt;/path&gt;&lt;path d=&quot;M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z&quot; id=MJX-3-TEX-N-29&gt;&lt;/path&gt;&lt;/defs&gt;&lt;g transform=scale(1,-1) fill=currentColor stroke=currentColor stroke-width=0&gt;&lt;g data-mml-node=math&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D44F xlink:href=#MJX-3-TEX-I-1D44F&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(706.8,0)&gt;&lt;use data-c=3D xlink:href=#MJX-3-TEX-N-3D&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mfrac transform=translate(1762.6,0)&gt;&lt;g data-mml-node=mrow transform=translate(220,710)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=2211 xlink:href=#MJX-3-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(1222.7,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-3-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(1879.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-3-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(3102,0)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D465 xlink:href=#MJX-3-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(605,363) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-3-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4332.8,0)&gt;&lt;use data-c=2212 xlink:href=#MJX-3-TEX-N-2212&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(5333,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-3-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(6555.7,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-3-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(7127.7,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-3-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(7784.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-3-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(9007,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-3-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mrow transform=translate(1394.7,-719.9)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D45B xlink:href=#MJX-3-TEX-I-1D45B&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(766.7,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-3-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(1989.3,0)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D465 xlink:href=#MJX-3-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(605,289) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-3-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(3220.1,0)&gt;&lt;use data-c=2212 xlink:href=#MJX-3-TEX-N-2212&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4220.3,0)&gt;&lt;use data-c=28 xlink:href=#MJX-3-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4609.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-3-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(5832,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-3-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(6404,0)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=29 xlink:href=#MJX-3-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(422,289) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-3-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;rect height=60 width=9779 x=120 y=220&gt;&lt;/rect&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/p&gt;&lt;br&gt;&lt;p&gt;O código em F# abaixo calcula a aproximação linear.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;x&lt;/code&gt; e &lt;code&gt;y&lt;/code&gt; são os valores de entrada.&lt;/li&gt;&lt;li&gt;&lt;code&gt;Seq.sumBy&lt;/code&gt; soma os resultados de uma função aplicada aos valores de uma seqüência:&lt;ul&gt;&lt;li&gt;&lt;code&gt;x = [1, 2, 3]&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;x |&gt; Seq.sumBy(fun i -&gt; 2 * i) = 12&lt;/code&gt;&lt;/li&gt;&lt;li&gt;(2*1 + 2*2 + 2*3 = 12)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;Seq.zip&lt;/code&gt; forma uma seqüência de pares vindos de duas outras seqüências. Por exemplo:&lt;ul&gt;&lt;li&gt;&lt;code&gt;x = [1, 2, 3]&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;y = [9, 8, 7]&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;Seq.zip(x)(y) = [ (1, 9), (2, 8), (3, 7) ]&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// s = soma&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; s&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    v &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;|&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sum&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// sm = soma de multiplicações&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    Seq.zip&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sumBy &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; aproximacaoLinear&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;) =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; n&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; x.Length &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;|&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; double&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sx&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; s&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sx2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; s&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sxy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; d&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; n&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sx2 &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sx&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;**&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; a&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;n&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sxy &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sx&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)/&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;d&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; b&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sx2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sy &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sxy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sx&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)/&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;d&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;a&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;b&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=aproxima%C3%A7%C3%A3o-exponencial tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/03/metodo-dos-minimos-quadrados-com-programacao-funcional/#aproxima%C3%A7%C3%A3o-exponencial class=header-anchor&gt;&lt;span&gt;Aproximação exponencial&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;A equação gerada será do tipo &lt;strong&gt;f(x) = A ⋅ e&lt;sup&gt;bx&lt;/sup&gt;&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;e&lt;/strong&gt; é a &lt;a href=https://pt.wikipedia.org/wiki/E_(constante_matem%C3%A1tica)&gt;base natural&lt;/a&gt;, aproximadamente igual a 2,71828.&lt;/p&gt;&lt;p&gt;Tendo um conjunto de valores medidos (x&lt;sub&gt;i&lt;/sub&gt;, y&lt;sub&gt;i&lt;/sub&gt;), a e b são calculados por:&lt;/p&gt;&lt;br&gt;&lt;p&gt;&lt;svg aria-hidden=true focusable=false height=60px role=img style=vertical-align:-2.194ex viewBox=&quot;0 -1543.9 18621.6 2513.9&quot; width=90% xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink&gt;&lt;defs&gt;&lt;path d=&quot;M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z&quot; id=MJX-4-TEX-I-1D44E&gt;&lt;/path&gt;&lt;path d=&quot;M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z&quot; id=MJX-4-TEX-N-3D&gt;&lt;/path&gt;&lt;path d=&quot;M61 748Q64 750 489 750H913L954 640Q965 609 976 579T993 533T999 516H979L959 517Q936 579 886 621T777 682Q724 700 655 705T436 710H319Q183 710 183 709Q186 706 348 484T511 259Q517 250 513 244L490 216Q466 188 420 134T330 27L149 -187Q149 -188 362 -188Q388 -188 436 -188T506 -189Q679 -189 778 -162T936 -43Q946 -27 959 6H999L913 -249L489 -250Q65 -250 62 -248Q56 -246 56 -239Q56 -234 118 -161Q186 -81 245 -11L428 206Q428 207 242 462L57 717L56 728Q56 744 61 748Z&quot; id=MJX-4-TEX-SO-2211&gt;&lt;/path&gt;&lt;path d=&quot;M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z&quot; id=MJX-4-TEX-N-28&gt;&lt;/path&gt;&lt;path d=&quot;M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z&quot; id=MJX-4-TEX-I-1D465&gt;&lt;/path&gt;&lt;path d=&quot;M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z&quot; id=MJX-4-TEX-N-32&gt;&lt;/path&gt;&lt;path d=&quot;M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z&quot; id=MJX-4-TEX-I-1D466&gt;&lt;/path&gt;&lt;path d=&quot;M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z&quot; id=MJX-4-TEX-N-29&gt;&lt;/path&gt;&lt;path d=&quot;M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z&quot; id=MJX-4-TEX-N-6C&gt;&lt;/path&gt;&lt;path d=&quot;M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q450 438 463 329Q464 322 464 190V104Q464 66 466 59T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z&quot; id=MJX-4-TEX-N-6E&gt;&lt;/path&gt;&lt;path d=&quot;&quot; id=MJX-4-TEX-N-2061&gt;&lt;/path&gt;&lt;path d=&quot;M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z&quot; id=MJX-4-TEX-N-2212&gt;&lt;/path&gt;&lt;/defs&gt;&lt;g transform=scale(1,-1) fill=currentColor stroke=currentColor stroke-width=0&gt;&lt;g data-mml-node=math&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D44E xlink:href=#MJX-4-TEX-I-1D44E&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(806.8,0)&gt;&lt;use data-c=3D xlink:href=#MJX-4-TEX-N-3D&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mfrac transform=translate(1862.6,0)&gt;&lt;g data-mml-node=mrow transform=translate(220,710)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=2211 xlink:href=#MJX-4-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(1056,0)&gt;&lt;use data-c=28 xlink:href=#MJX-4-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(1445,0)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D465 xlink:href=#MJX-4-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(605,363) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-4-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(2453.6,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(2943.6,0)&gt;&lt;use data-c=29 xlink:href=#MJX-4-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(3499.2,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-4-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4555.2,0)&gt;&lt;use data-c=28 xlink:href=#MJX-4-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(4944.2,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(5600.9,0)&gt;&lt;use data-c=6C xlink:href=#MJX-4-TEX-N-6C&gt;&lt;/use&gt;&lt;use data-c=6E xlink:href=#MJX-4-TEX-N-6E transform=translate(278,0)&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(6434.9,0)&gt;&lt;use data-c=2061 xlink:href=#MJX-4-TEX-N-2061&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(6601.6,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(7091.6,0)&gt;&lt;use data-c=29 xlink:href=#MJX-4-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(7702.8,0)&gt;&lt;use data-c=2212 xlink:href=#MJX-4-TEX-N-2212&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(8703,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-4-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(9759,0)&gt;&lt;use data-c=28 xlink:href=#MJX-4-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(10148,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-4-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(10720,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(11210,0)&gt;&lt;use data-c=29 xlink:href=#MJX-4-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(11765.7,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-4-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(12821.7,0)&gt;&lt;use data-c=28 xlink:href=#MJX-4-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(13210.7,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-4-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(13782.7,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(14439.3,0)&gt;&lt;use data-c=6C xlink:href=#MJX-4-TEX-N-6C&gt;&lt;/use&gt;&lt;use data-c=6E xlink:href=#MJX-4-TEX-N-6E transform=translate(278,0)&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(15273.3,0)&gt;&lt;use data-c=2061 xlink:href=#MJX-4-TEX-N-2061&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(15440,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(15930,0)&gt;&lt;use data-c=29 xlink:href=#MJX-4-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mrow transform=translate(3412.7,-719.9)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=2211 xlink:href=#MJX-4-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(1222.7,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(1879.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-4-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(2935.3,0)&gt;&lt;use data-c=28 xlink:href=#MJX-4-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(3324.3,0)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D465 xlink:href=#MJX-4-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(605,289) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-4-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(4332.9,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4822.9,0)&gt;&lt;use data-c=29 xlink:href=#MJX-4-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(5434.1,0)&gt;&lt;use data-c=2212 xlink:href=#MJX-4-TEX-N-2212&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(6434.3,0)&gt;&lt;use data-c=28 xlink:href=#MJX-4-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(6823.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-4-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(8046,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-4-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(8618,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-4-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(9108,0)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=29 xlink:href=#MJX-4-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(422,289) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-4-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;rect height=60 width=16519 x=120 y=220&gt;&lt;/rect&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/p&gt;&lt;br&gt;&lt;p&gt;&lt;svg aria-hidden=true focusable=false height=60px role=img style=vertical-align:-2.194ex viewBox=&quot;0 -1460 16901.7 2429.9&quot; width=90% xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink&gt;&lt;defs&gt;&lt;path d=&quot;M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z&quot; id=MJX-5-TEX-I-1D44F&gt;&lt;/path&gt;&lt;path d=&quot;M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z&quot; id=MJX-5-TEX-N-3D&gt;&lt;/path&gt;&lt;path d=&quot;M61 748Q64 750 489 750H913L954 640Q965 609 976 579T993 533T999 516H979L959 517Q936 579 886 621T777 682Q724 700 655 705T436 710H319Q183 710 183 709Q186 706 348 484T511 259Q517 250 513 244L490 216Q466 188 420 134T330 27L149 -187Q149 -188 362 -188Q388 -188 436 -188T506 -189Q679 -189 778 -162T936 -43Q946 -27 959 6H999L913 -249L489 -250Q65 -250 62 -248Q56 -246 56 -239Q56 -234 118 -161Q186 -81 245 -11L428 206Q428 207 242 462L57 717L56 728Q56 744 61 748Z&quot; id=MJX-5-TEX-SO-2211&gt;&lt;/path&gt;&lt;path d=&quot;M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z&quot; id=MJX-5-TEX-I-1D466&gt;&lt;/path&gt;&lt;path d=&quot;M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z&quot; id=MJX-5-TEX-N-28&gt;&lt;/path&gt;&lt;path d=&quot;M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z&quot; id=MJX-5-TEX-I-1D465&gt;&lt;/path&gt;&lt;path d=&quot;M42 46H56Q95 46 103 60V68Q103 77 103 91T103 124T104 167T104 217T104 272T104 329Q104 366 104 407T104 482T104 542T103 586T103 603Q100 622 89 628T44 637H26V660Q26 683 28 683L38 684Q48 685 67 686T104 688Q121 689 141 690T171 693T182 694H185V379Q185 62 186 60Q190 52 198 49Q219 46 247 46H263V0H255L232 1Q209 2 183 2T145 3T107 3T57 1L34 0H26V46H42Z&quot; id=MJX-5-TEX-N-6C&gt;&lt;/path&gt;&lt;path d=&quot;M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q450 438 463 329Q464 322 464 190V104Q464 66 466 59T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z&quot; id=MJX-5-TEX-N-6E&gt;&lt;/path&gt;&lt;path d=&quot;&quot; id=MJX-5-TEX-N-2061&gt;&lt;/path&gt;&lt;path d=&quot;M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z&quot; id=MJX-5-TEX-N-29&gt;&lt;/path&gt;&lt;path d=&quot;M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z&quot; id=MJX-5-TEX-N-2212&gt;&lt;/path&gt;&lt;path d=&quot;M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z&quot; id=MJX-5-TEX-N-32&gt;&lt;/path&gt;&lt;/defs&gt;&lt;g transform=scale(1,-1) fill=currentColor stroke=currentColor stroke-width=0&gt;&lt;g data-mml-node=math&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D44F xlink:href=#MJX-5-TEX-I-1D44F&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(706.8,0)&gt;&lt;use data-c=3D xlink:href=#MJX-5-TEX-N-3D&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mfrac transform=translate(1762.6,0)&gt;&lt;g data-mml-node=mrow transform=translate(220,710)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=2211 xlink:href=#MJX-5-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(1222.7,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(1879.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-5-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(2935.3,0)&gt;&lt;use data-c=28 xlink:href=#MJX-5-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(3324.3,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-5-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(3896.3,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(4553,0)&gt;&lt;use data-c=6C xlink:href=#MJX-5-TEX-N-6C&gt;&lt;/use&gt;&lt;use data-c=6E xlink:href=#MJX-5-TEX-N-6E transform=translate(278,0)&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(5387,0)&gt;&lt;use data-c=2061 xlink:href=#MJX-5-TEX-N-2061&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(5553.7,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(6043.7,0)&gt;&lt;use data-c=29 xlink:href=#MJX-5-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(6654.9,0)&gt;&lt;use data-c=2212 xlink:href=#MJX-5-TEX-N-2212&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(7655.1,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-5-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(8711.1,0)&gt;&lt;use data-c=28 xlink:href=#MJX-5-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(9100.1,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-5-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(9672.1,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(10162.1,0)&gt;&lt;use data-c=29 xlink:href=#MJX-5-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(10717.8,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-5-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(11773.8,0)&gt;&lt;use data-c=28 xlink:href=#MJX-5-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(12162.8,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(12819.4,0)&gt;&lt;use data-c=6C xlink:href=#MJX-5-TEX-N-6C&gt;&lt;/use&gt;&lt;use data-c=6E xlink:href=#MJX-5-TEX-N-6E transform=translate(278,0)&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(13653.4,0)&gt;&lt;use data-c=2061 xlink:href=#MJX-5-TEX-N-2061&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(13820.1,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(14310.1,0)&gt;&lt;use data-c=29 xlink:href=#MJX-5-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mrow transform=translate(2602.8,-719.9)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=2211 xlink:href=#MJX-5-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(1222.7,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(1879.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-5-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(2935.3,0)&gt;&lt;use data-c=28 xlink:href=#MJX-5-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(3324.3,0)&gt;&lt;g data-mml-node=mi&gt;&lt;use data-c=1D465 xlink:href=#MJX-5-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(605,289) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-5-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(4332.9,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(4822.9,0)&gt;&lt;use data-c=29 xlink:href=#MJX-5-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(5434.1,0)&gt;&lt;use data-c=2212 xlink:href=#MJX-5-TEX-N-2212&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(6434.3,0)&gt;&lt;use data-c=28 xlink:href=#MJX-5-TEX-N-28&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mo transform=translate(6823.3,0)&gt;&lt;use data-c=2211 xlink:href=#MJX-5-TEX-SO-2211&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(8046,0)&gt;&lt;use data-c=1D465 xlink:href=#MJX-5-TEX-I-1D465&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mi transform=translate(8618,0)&gt;&lt;use data-c=1D466 xlink:href=#MJX-5-TEX-I-1D466&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=msup transform=translate(9108,0)&gt;&lt;g data-mml-node=mo&gt;&lt;use data-c=29 xlink:href=#MJX-5-TEX-N-29&gt;&lt;/use&gt;&lt;/g&gt;&lt;g data-mml-node=mn transform=&quot;translate(422,289) scale(0.707)&quot;&gt;&lt;use data-c=32 xlink:href=#MJX-5-TEX-N-32&gt;&lt;/use&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;rect height=60 width=14899.1 x=120 y=220&gt;&lt;/rect&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/p&gt;&lt;br&gt;&lt;p&gt;O código em F# abaixo calcula a aproximação exponencial.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;ln&lt;/strong&gt; é o logaritmo natural, na base &lt;strong&gt;e&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;A = e&lt;sup&gt;a&lt;/sup&gt;&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;&lt;code&gt;Seq.zip3&lt;/code&gt; segue a mesma lógica que o &lt;code&gt;Seq.zip&lt;/code&gt;, porém forma uma seqüência de trios vindos de três outras seqüências.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Importante&lt;/strong&gt;: os valores de y precisam ser todos maiores do que zero, pois não existe logaritmo de valor zero ou negativo.&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// s = soma&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; s&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    v &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;|&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sum&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// sm = soma de multiplicações&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    Seq.zip&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sumBy &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; ln&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; System.Math.Log&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// smm = soma(v1 * v2 * v3)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; smm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    Seq.zip3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sumBy &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;a&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;b&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;c&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; a &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; b &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; c&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// smln = soma(v1 * ln(v2))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; smln&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    Seq.zip&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sumBy &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;a&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;b&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; a &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ln&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;b&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// smmln = soma(v1 * v2 * ln(v3))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; smmln&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;v3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    Seq.zip3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;v3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sumBy &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;a&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;b&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;c&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; a &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; b &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ln&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// exponencial: y = A * e^(b*x)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; aproximacaoExponencial&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[])(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;[]):&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;double &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; double&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;) =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sx2y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; smm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sylny&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; smln&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sxy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sxylny&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; smmln&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; sy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; s&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; d&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sx2y &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sxy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;**&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; a&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sx2y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sylny &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sxy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sxylny&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)/&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;d&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; b&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sxylny &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sxy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sylny&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)/&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;d&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; A&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; System.Math.Exp&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;a&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;A&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; b&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=caso-de-estudo%3A-minera%C3%A7%C3%A3o-de-prata tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/03/metodo-dos-minimos-quadrados-com-programacao-funcional/#caso-de-estudo%3A-minera%C3%A7%C3%A3o-de-prata class=header-anchor&gt;&lt;span&gt;Caso de estudo: Mineração de prata&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;img alt=&quot;&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2025_03_argentina_pirquitas_silver_mine.jpg&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;Mina Pirquitas, Jujuy, Argentina.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Vamos extrair dados do site &lt;a href=https://ourworldindata.org/metals-minerals&gt;Our World in Data&lt;/a&gt; sobre a mineração mundial de prata, entre 1900 e 2023, e vamos fazer as aproximações linear e exponencial.&lt;/p&gt;&lt;p&gt;Arquivo CSV disponível neste &lt;a href=https://alexandrehtrb.github.io/assets/misc/1900-2023-silver_mining_production.csv&gt;link&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Resultados:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;f(x)&lt;/strong&gt; é a mineração em toneladas, x é o ano.&lt;/li&gt;&lt;li&gt;Linear: &lt;strong&gt;f(x) = 162,897x − 308090,816&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Exponencial: &lt;strong&gt;f(x) = 0,000000002257 ⋅ e&lt;sup&gt;0,01485166x&lt;/sup&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;---
config:
    xyChart:
        width: 540
    themeVariables:
        xyChart:
            backgroundColor: &quot;#00000000&quot;
            plotColorPalette: &quot;#CC0000, #2222FF, #00CC00&quot;
---
xychart-beta
    title &quot;Produção anual de prata (ton. mét.)&quot;
    x-axis &quot;Ano&quot; 1900 --&gt; 2023
    y-axis 0 --&gt; 30000
    line [ 5400, 5380, 5060, 5220, 5110, 5360, 5130, 5730, 6320, 6600, 6900, 7040, 6980, 7010, 5240, 5730, 5250, 5420, 6140, 5490, 5390, 5330, 6530, 7650, 7450, 7650, 7890, 7900, 8020, 8120, 7740, 6080, 5130, 5340, 5990, 6890, 7920, 8640, 8320, 8300, 8570, 8140, 7780, 6380, 5740, 5040, 3970, 5220, 5440, 5570, 6320, 6210, 6700, 6900, 6670, 7000, 7020, 7190, 7430, 6910, 7320, 7370, 7650, 7780, 7730, 8010, 8300, 8030, 8560, 9200, 9360, 9170, 9380, 9700, 9260, 9430, 9840, 10300, 10700, 10800, 10700, 11200, 11500, 12100, 13100, 13100, 13000, 14000, 15500, 16400, 16600, 15600, 14900, 14100, 14000, 14900, 15100, 16500, 17200, 17600, 18100, 18700, 18800, 18800, 20000, 20800, 20100, 20800, 21300, 22300, 23300, 23300, 24300, 26700, 28000, 27600, 28600, 26500, 25900, 25800, 23500, 25000, 25600, 26000 ]
	line [ 1413.484, 1576.381, 1739.278, 1902.175, 2065.072, 2227.969, 2390.866, 2553.763, 2716.66, 2879.557, 3042.454, 3205.351, 3368.248, 3531.145, 3694.042, 3856.939, 4019.836, 4182.733, 4345.63, 4508.527, 4671.424, 4834.321, 4997.218, 5160.115, 5323.012, 5485.909, 5648.806, 5811.703, 5974.6, 6137.497, 6300.394, 6463.291, 6626.188, 6789.085, 6951.982, 7114.879, 7277.776, 7440.673, 7603.57, 7766.467, 7929.364, 8092.261, 8255.158, 8418.055, 8580.952, 8743.849, 8906.746, 9069.643, 9232.54, 9395.437, 9558.334, 9721.231, 9884.128, 10047.025, 10209.922, 10372.819, 10535.716, 10698.613, 10861.51, 11024.407, 11187.304, 11350.201, 11513.098, 11675.995, 11838.892, 12001.789, 12164.686, 12327.583, 12490.48, 12653.377, 12816.274, 12979.171, 13142.068, 13304.965, 13467.862, 13630.759, 13793.656, 13956.553, 14119.45, 14282.347, 14445.244, 14608.141, 14771.038, 14933.935, 15096.832, 15259.729, 15422.626, 15585.523, 15748.42, 15911.317, 16074.214, 16237.111, 16400.008, 16562.905, 16725.802, 16888.699, 17051.596, 17214.493, 17377.39, 17540.287, 17703.184, 17866.081, 18028.978, 18191.875, 18354.772, 18517.669, 18680.566, 18843.463, 19006.36, 19169.257, 19332.154, 19495.051, 19657.948, 19820.845, 19983.742, 20146.639, 20309.536, 20472.433, 20635.33, 20798.227, 20961.124, 21124.021, 21286.918, 21449.815 ]
	line [ 4059.94, 4120.69, 4182.34, 4244.92, 4308.44, 4372.90, 4438.33, 4504.74, 4572.14, 4640.55, 4709.99, 4780.46, 4851.99, 4924.58, 4998.27, 5073.06, 5148.96, 5226.00, 5304.20, 5383.56, 5464.11, 5545.87, 5628.85, 5713.07, 5798.55, 5885.31, 5973.37, 6062.75, 6153.46, 6245.53, 6338.98, 6433.83, 6530.10, 6627.80, 6726.97, 6827.62, 6929.78, 7033.47, 7138.71, 7245.52, 7353.93, 7463.96, 7575.64, 7689.00, 7804.04, 7920.81, 8039.32, 8159.61, 8281.70, 8405.62, 8531.39, 8659.04, 8788.60, 8920.10, 9053.56, 9189.03, 9326.52, 9466.07, 9607.70, 9751.46, 9897.36, 10045.45, 10195.76, 10348.31, 10503.15, 10660.30, 10819.81, 10981.70, 11146.01, 11312.78, 11482.05, 11653.85, 11828.22, 12005.20, 12184.83, 12367.15, 12552.19, 12740.00, 12930.62, 13124.10, 13320.47, 13519.78, 13722.07, 13927.38, 14135.77, 14347.28, 14561.95, 14779.83, 15000.97, 15225.43, 15453.24, 15684.46, 15919.13, 16157.32, 16399.08, 16644.45, 16893.49, 17146.26, 17402.81, 17663.20, 17927.49, 18195.73, 18467.98, 18744.31, 19024.77, 19309.43, 19598.34, 19891.58, 20189.21, 20491.29, 20797.89, 21109.08, 21424.93, 21745.50, 22070.86, 22401.10, 22736.28, 23076.47, 23421.75, 23772.20, 24127.89, 24488.90, 24855.32, 25227.21 ]
	%% linear: 162,897 * ano - 308090,816
	%% exponencial: =(0,000000002257)*e^(ano*0,01485166)

&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;Linha vermelha: produção anual; linha azul: aproximação linear; linha verde: aproximação exponencial.&lt;/em&gt;&lt;/p&gt;&lt;br&gt;&lt;h1 id=fontes-e-leituras-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/03/metodo-dos-minimos-quadrados-com-programacao-funcional/#fontes-e-leituras-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e leituras interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://docs.ufpr.br/~agnelo.vieira/MetodosNumericos/MMQ.pdf&gt;Universidade Federal do Paraná - Ajuste de Curva pelo Método dos Quadrados Mínimos&lt;/a&gt; (&lt;a href=https://alexandrehtrb.github.io/assets/misc/aula_ufpr_m%C3%ADnimos_quadrados.pdf&gt;backup&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href=https://indico.ifsc.usp.br/event/1/attachments/1/21/CursoMMQSifscUSPAgosto2019OtavianoHelene.pdf&gt;Instituto de Física da USP - Mini curso de Método dos Mínimos Quadrados, Otaviano Helene&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://mathworld.wolfram.com/LeastSquaresFitting.html&gt;Wolfram MathWorld - Least Squares Fitting, Linear&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20250228131909/https://mathworld.wolfram.com/LeastSquaresFitting.html&gt;WebArchive&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href=https://mathworld.wolfram.com/LeastSquaresFittingExponential.html&gt;Wolfram MathWorld - Least Squares Fitting, Exponential&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20250212183347/https://mathworld.wolfram.com/LeastSquaresFittingExponential.html&gt;WebArchive&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href=https://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html&gt;Wolfram MathWorld - Least Squares Fitting, Power Law&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20250212183356/https://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html&gt;WebArchive&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href=https://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html&gt;Wolfram MathWorld - Least Squares Fitting, Logarithmic&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20250212183349/https://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html&gt;WebArchive&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.mathjax.org/ &gt;MathJax - LaTeX renderer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://ourworldindata.org/metals-minerals&gt;Our World In Data - Metals and Minerals&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.mining.com/worlds-top-10-silver-mines/ &gt;Mining.com - World’s top 10 silver mines&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Gráficos feitos com &lt;a href=https://mermaid.live/ &gt;Mermaid.js XY Charts&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Interfaces como princípio de engenharia</title>
    <link href="https://alexandrehtrb.github.io/posts/2025/02/interfaces-como-principio-de-engenharia/" />
    <updated>2025-02-20T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2025/02/interfaces-como-principio-de-engenharia/</id>
    <content type="html">&lt;p&gt;Uma interface é o modo como duas coisas diferentes se comunicam.&lt;/p&gt;&lt;p&gt;Em engenharia, interfaces são muito úteis para abstrair a lógica macro de um sistema. Com elas, componentes podem focar em funções específicas e as interfaces definem como eles se conectam.&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;flowchart LR
  A
  B
  subgraph S[S]
    direction RL
    a
    b
  end
  a-.-&gt;A  
  b-.-&gt;B
  classDef abstract stroke:#f66,stroke-width:2px,stroke-dasharray: 5 5
  class a,b abstract;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;No diagrama acima, o sistema S delega as tarefas a e b para os componentes A e B, respectivamente. As setas representam interfaces.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Vamos analisar aqui benefícios das interfaces com um olhar para produtos de engenharia de modo geral.&lt;/p&gt;&lt;h3&gt;Reúso&lt;/h3&gt;&lt;p&gt;Interfaces permitem que um componente seja projetado para atender mais de um sistema.&lt;/p&gt;&lt;h3&gt;Reaproveitamento&lt;/h3&gt;&lt;p&gt;O raciocínio é parecido com o do reúso, porém, o reúso trata da concepção de um componente visando atender vários casos de uso; reaproveitamento trata-se de usar um componente já existente, ao invés de criar um novo.&lt;/p&gt;&lt;h3&gt;Intercambialidade&lt;/h3&gt;&lt;p&gt;Partes podem ser trocadas por outras equivalentes.&lt;/p&gt;&lt;h3&gt;Paralelismo de trabalho&lt;/h3&gt;&lt;p&gt;Times distintos podem trabalhar em paralelo nas partes, entregando mais rapidamente o produto final.&lt;/p&gt;&lt;h3&gt;Dissipação de risco&lt;/h3&gt;&lt;p&gt;Está relacionado ao paralelismo de trabalho. Problemas em uma frente de trabalho não afetam outras frentes.&lt;/p&gt;&lt;h3&gt;Custos de maquinário&lt;/h3&gt;&lt;p&gt;A produção de uma peça requer máquinas, que custam dinheiro. Repassar a produção para outros evita esse custo.&lt;/p&gt;&lt;h3&gt;Especialização&lt;/h3&gt;&lt;p&gt;Times e empresas com conhecimentos específicos sobre um tipo de componente os produzem com melhor qualidade.&lt;/p&gt;&lt;h3&gt;Testes unitários&lt;/h3&gt;&lt;p&gt;Interfaces possibilitam testes de forma isolada no componente, tal que as dependências externas são substituídas por simulações ou imitações — em inglês, &lt;em&gt;&lt;strong&gt;mocks&lt;/strong&gt;&lt;/em&gt;. Por serem testes individualizados, há mais atenção e foco no componente em si, além de não ser necessário ter todo o sistema pronto para então validá-lo.&lt;/p&gt;&lt;p&gt;Isso também contribui para o &lt;em&gt;&lt;strong&gt;shift-left testing&lt;/strong&gt;&lt;/em&gt;, que é a idéia de antecipar validações no fluxo de trabalho: ao realizar testes isoladamente, problemas ficam visíveis mais cedo no processo.&lt;/p&gt;&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2025_02_shift_left_testing.avif type=image/avif&gt;&lt;img alt=&quot;&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_02_shift_left_testing.jpg&gt;&lt;/picture&gt;&lt;/p&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;Comparação entre abordagens de testes shift-left e tradicional.&lt;/em&gt;&lt;/p&gt;&lt;h2 id=exemplos-de-interfaces-em-engenharia tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/02/interfaces-como-principio-de-engenharia/#exemplos-de-interfaces-em-engenharia class=header-anchor&gt;&lt;span&gt;Exemplos de interfaces em engenharia&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3&gt;Computadores&lt;/h3&gt;&lt;p&gt;O &lt;em&gt;hardware&lt;/em&gt; dos computadores é extremamente modular, o que facilita trocar partes em manutenções e &lt;em&gt;upgrades&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2025_02_computer_motherboard_diagram.avif type=image/avif&gt;&lt;img alt=&quot;&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_02_computer_motherboard_diagram.jpg&gt;&lt;/picture&gt;&lt;/p&gt;&lt;p&gt;&lt;em class=&quot;italic text-sm&quot;&gt;Diagrama da placa-mãe de um computador.&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Qualquer processador que tenha o mesmo soquete que a placa-mãe pode ser usado;&lt;/li&gt;&lt;li&gt;Qualquer pente de memória RAM que tenha o mesmo soquete (ex.: DIMM, SO-DIMM) e mesma classe (ex.: DDR3, DDR4, DDR5) que a placa-mãe é aceito;&lt;/li&gt;&lt;li&gt;Qualquer dispositivo com interface SATA é aceito: discos rígidos, leitoras de CD/DVD.&lt;/li&gt;&lt;li&gt;Qualquer fonte de energia pode ser usada, desde que forneça através do conector correspondente da placa-mãe (ex.: ATX).&lt;/li&gt;&lt;li&gt;Por fim, uma placa-mãe pode ser trocada reaproveitando as demais partes.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Redes elétricas e hidráulicas&lt;/h3&gt;&lt;img alt=&quot;Quadro de disjuntores&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_02_circuit_breaker_panel.jpg class=my-4&gt;&lt;p&gt;Instalações elétricas e hidráulicas também são altamente modularizadas.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Disjuntores elétricos e registros hidráulicos permitem que subsistemas sejam isolados e reparados sem afetar outros.&lt;/li&gt;&lt;li&gt;Terminais podem ser substituídos com facilidade.&lt;ul&gt;&lt;li&gt;Para elétrica: tomadas, lâmpadas, interruptores, disjuntores; basta atender à tensão (voltagem) e corrente máxima (amperagem).&lt;/li&gt;&lt;li&gt;Para hidráulica: sifões, torneiras, chuveiros - basta atender ao tamanho das conexões.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;A exceção é reparos dentro da alvenaria, como em conduítes e encanamentos, porém, problemas neles tendem a ser mais raros.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;h1 id=poss%C3%ADveis-contrapartidas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/02/interfaces-como-principio-de-engenharia/#poss%C3%ADveis-contrapartidas class=header-anchor&gt;&lt;span&gt;Possíveis contrapartidas&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;h3&gt;Eficiência energética e material&lt;/h3&gt;&lt;p&gt;Conexões consomem energia e material, na construção e na operação. Em componentes condensados ou com ligações diretas, essas perdas são mitigadas ou até mesmo eliminadas.&lt;/p&gt;&lt;h3&gt;Coesão do sistema&lt;/h3&gt;&lt;p&gt;Em toda conexão, há o risco de descasamento entre as partes. Diminuir o número de intermediários torna o sistema mais coeso.&lt;/p&gt;&lt;h3&gt;Liberdade de inovação&lt;/h3&gt;&lt;p&gt;Interfaces definidas por terceiros podem não atender da melhor forma possível um caso de uso em questão. Nessas situações, pode ser interessante romper padrões de mercado e criar suas próprias interfaces.&lt;/p&gt;&lt;h2 id=caso-de-estudo%3A-querosene-de-avia%C3%A7%C3%A3o-em-aeroportos tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/02/interfaces-como-principio-de-engenharia/#caso-de-estudo%3A-querosene-de-avia%C3%A7%C3%A3o-em-aeroportos class=header-anchor&gt;&lt;span&gt;Caso de estudo: Querosene de aviação em aeroportos&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Aeroportos precisam de querosene de aviação (QAV) para abastecer as aeronaves.&lt;/p&gt;&lt;p&gt;Em aeroportos pequenos e médios, o QAV chega aos reservatórios via caminhões-tanque, que saem das distribuidoras. Porém, em aeroportos grandes e com alto consumo de combustível, o QAV chega via dutos que saem diretamente das refinarias, chamados de querodutos.&lt;/p&gt;&lt;p&gt;Os querodutos são caros de serem construídos, porém a demanda elevada justifica e a operação acaba sendo mais barata e eficiente do que usar caminhões-tanque.&lt;/p&gt;&lt;p&gt;Durante a greve dos caminhoneiros de 2018, aeroportos brasileiros que dependiam de caminhões-tanque sofreram com escassez de combustível e alguns tiveram suas atividades paralisadas. Já os aeroportos servidos por querodutos, Cumbica e Galeão, continuaram funcionando normalmente.&lt;/p&gt;&lt;img alt=&quot;Infraestrutura de abastecimento de combustível de aviação em Guarulhos&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2025_02_aviation_fuel_tanks.jpg class=my-4&gt;&lt;br&gt;&lt;h1 id=conclus%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/02/interfaces-como-principio-de-engenharia/#conclus%C3%A3o class=header-anchor&gt;&lt;span&gt;Conclusão&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;O conceito de interfaces vem da idéia de partes intercambiáveis e sua utilização resulta em sistemas melhores, mais confiáveis, mais baratos, de manutenção mais fácil e mais rápidos de serem desenvolvidos. Além disso, contribuem para o reúso de partes, evitando que sistemas precisem ser trocados por inteiro.&lt;/p&gt;&lt;p&gt;Em alguns casos, contudo, desenhar sua própria interface, ou então &quot;cortar o intermediário&quot;, pode tornar o sistema mais coeso e eficiente.&lt;/p&gt;&lt;br&gt;&lt;h1 id=fontes-e-leituras-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/02/interfaces-como-principio-de-engenharia/#fontes-e-leituras-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e leituras interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://mermaid.live&gt;Diagramas Mermaid&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://en.wikipedia.org/wiki/Interchangeable_parts&gt;Wikipédia - Partes intercambiáveis&lt;/a&gt; (em inglês)&lt;/li&gt;&lt;li&gt;&lt;a href=https://blog.onedaytesting.com.br/shift-left-testing/ &gt;One Day Testing Blog - Shift Left Testing: A prática de teste que antecipa problemas e acelera entregas&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://lightrun.com/shift-left-testing/ &gt;Lightrun - Shift Left Testing: 6 Essentials for Successful Implementation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://computer.howstuffworks.com/motherboard1.htm&gt;How Stuff Works - How Motherboards Work&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://pt.wikipedia.org/wiki/Greve_dos_caminhoneiros_no_Brasil_em_2018&gt;Wikipédia - Greve dos caminhoneiros no Brasil em 2018&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://g1.globo.com/economia/noticia/so-8-aeroportos-no-pais-estao-sendo-reabastecidos-regularmente-entre-eles-guarulhos-congonhas-galeao-e-santos-dumont.ghtml&gt;G1 - Só 8 aeroportos no país estão sendo reabastecidos regularmente, entre eles Guarulhos, Congonhas, Galeão e Santos Dumont (25/05/2018)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.cnt.org.br/agencia-cnt/saiba-como-funciona-abastecimento-maiores-aeroportos&gt;Confederação Nacional do Transporte - Saiba como funciona o abastecimento em dois dos maiores aeroportos do Brasil&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Introdução ao FFmpeg</title>
    <link href="https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/" />
    <updated>2025-01-13T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/</id>
    <content type="html">&lt;h2 id=introdu%C3%A7%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#introdu%C3%A7%C3%A3o class=header-anchor&gt;&lt;span&gt;Introdução&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Sabe aquele vídeo engraçado que você viu na Internet? Ou o filme que assistiu no cinema? Se você assistiu um vídeo digital nos últimos 15 anos, há grandes chances de ele ter passado pelo FFmpeg em algum momento, seja para edição, reprodução ou distribuição.&lt;/p&gt;&lt;p&gt;O FFmpeg é um programa de transformação de vídeo e áudio que é usado por diversas empresas de multimídia, como YouTube, TikTok e Vimeo.&lt;/p&gt;&lt;p&gt;Neste artigo, vamos aprender como usá-lo, através de exemplos práticos.&lt;/p&gt;&lt;h2 id=%C3%ADndice tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#%C3%ADndice class=header-anchor&gt;&lt;span&gt;Índice&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#instala%C3%A7%C3%A3o-do-ffmpeg&gt;Instalação do FFmpeg&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#mudar-formato-do-arquivo&gt;Mudar formato do arquivo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#extrair-%C3%A1udio-de-um-v%C3%ADdeo&gt;Extrair áudio de um vídeo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#diminuir-tamanho-do-arquivo&gt;Diminuir tamanho do arquivo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#cortar-trecho-do-v%C3%ADdeo&gt;Cortar trecho do vídeo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#aumentar-e-diminuir-volume-de-som&gt;Aumentar e diminuir volume de som&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#redimensionar-frames&gt;Redimensionar &lt;em&gt;frames&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#inserir-legendas&gt;Inserir legendas&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#colocar-texto-em-cima-do-v%C3%ADdeo&gt;Colocar texto em cima do vídeo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#inspecionar-metadados&gt;Inspecionar metadados&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=instala%C3%A7%C3%A3o-do-ffmpeg tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#instala%C3%A7%C3%A3o-do-ffmpeg class=header-anchor&gt;&lt;span&gt;Instalação do FFmpeg&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3&gt;Linux&lt;/h3&gt;&lt;p&gt;Debian / Ubuntu:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; apt&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; apt&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; install&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; ffmpeg&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ffmpeg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -version&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Fedora:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; dnf&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; install&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;$(&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;rpm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -E&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; %fedora&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;.noarch.rpm&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; dnf&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; install&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;$(&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;rpm&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -E&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; %fedora&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;.noarch.rpm&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; dnf&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; upgrade&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; --refresh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; dnf&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; install&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; ffmpeg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; --allowerasing&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; dnf&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; install&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; ffmpeg-devel&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; --allowerasing&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ffmpeg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -version&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Arch Linux:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; pacman&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -Sy&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;sudo&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; pacman&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -S&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; ffmpeg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ffmpeg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -version&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;macOS&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Instalar o &lt;a href=https://brew.sh/ &gt;Brew&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Executar no Terminal:&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;brew&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;brew&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; install&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; ffmpeg&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ffmpeg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -version&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Windows&lt;/h3&gt;&lt;p&gt;Você pode instalar via Winget (disponível para Windows 11, Windows Server 2025):&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;winget install &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;--&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;id&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;Gyan.FFmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;e&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ou instalar manualmente:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Baixar a versão mais recente do FFmpeg para Windows (&lt;a href=https://github.com/GyanD/codexffmpeg/releases&gt;link&lt;/a&gt;). A versão &lt;code&gt;essentials&lt;/code&gt; é a mais indicada para a maioria dos usuários.&lt;/li&gt;&lt;li&gt;Descompactar o zip baixado.&lt;/li&gt;&lt;li&gt;Adicionar o caminho da pasta &lt;code&gt;bin&lt;/code&gt; ao PATH. Para isto:&lt;ul&gt;&lt;li&gt;No Windows Explorer, clicar com o botão direito do mouse em &lt;em&gt;Este Computador&lt;/em&gt; &gt; &lt;em&gt;Propriedades&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Na janela que se abriu, clicar em &lt;em&gt;Configurações avançadas do sistema&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Em &lt;em&gt;Propriedades do sistema&lt;/em&gt;, clicar em &lt;em&gt;Variáveis de Ambiente...&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Em &lt;em&gt;Variáveis de usuário para X&lt;/em&gt;, selecionar a linha com &lt;strong&gt;Path&lt;/strong&gt; e clicar em &lt;em&gt;Editar...&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Adicionar o caminho da pasta na lista. Vai ser algo como: &lt;code&gt;C:&#92;Users&#92;usuario&#92;Downloads&#92;ffmpeg-7.0.1-essentials_build&#92;bin&lt;/code&gt; (alterar para o caminho na sua máquina).&lt;/li&gt;&lt;li&gt;Clicar em OK nas janelas para salvar as alterações.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Como usar&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;O FFmpeg é usado via Terminal, Prompt de Comando ou PowerShell. No seu computador, abra um desses programas.&lt;/li&gt;&lt;li&gt;Nos exemplos, os arquivos são especificados sem a pasta, o que implica a pasta atual da linha de comando. Para mudar o diretório atual:&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;cd C:&#92;Users&#92;usuario&#92;Videos&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Se os arquivos estão (ou serão gerados) em outras pastas, é necessário passar o caminho completo do arquivo, por exemplo:&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;C:&#92;Vídeos&#92;entrada.mov&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c copy &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;C:&#92;Vídeos&#92;saida.mp4&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=opera%C3%A7%C3%B5es tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#opera%C3%A7%C3%B5es class=header-anchor&gt;&lt;span&gt;Operações&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;h2 id=mudar-formato-do-arquivo tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#mudar-formato-do-arquivo class=header-anchor&gt;&lt;span&gt;Mudar formato do arquivo&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Os formatos de vídeo geralmente são apenas contêineres de transporte, sendo que o conteúdo em si é determinado pelos codecs. Exemplos de contêineres: &lt;code&gt;MP4&lt;/code&gt;, &lt;code&gt;AVI&lt;/code&gt;, &lt;code&gt;MKV&lt;/code&gt;, &lt;code&gt;MOV&lt;/code&gt;, &lt;code&gt;WebM&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Os codecs de vídeo mais populares são:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;H.264&lt;/strong&gt;, é o mais antigo e com maior suporte de plataformas.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;H.265&lt;/strong&gt;, é mais recente e resulta em tamanho até 50% menor do que o H.264, porém, alguns navegadores Web e players não têm compatibilidade com ele.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;AV1&lt;/strong&gt; é um codec novo. Ele tem licença de uso livre e promete compressão mais rápida e melhor do que o H.265, entretanto, o FFmpeg não o suporta plenamente ainda (06/01/2025).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;VP9&lt;/strong&gt;, usado em vídeos &lt;code&gt;.webm&lt;/code&gt; e pelo YouTube.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Os principais codecs de áudio são:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;MP3&lt;/strong&gt;, amplamente suportado, tem boa compressão e poucas perdas (&lt;em&gt;lossy&lt;/em&gt;).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;AAC&lt;/strong&gt;, usado no MP4, tem compressão e qualidade um pouco melhores do que o MP3.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Opus&lt;/strong&gt;, &lt;em&gt;lossy&lt;/em&gt; com boa qualidade.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;FLAC&lt;/strong&gt;, é um codec com compressão sem perdas (&lt;em&gt;lossless&lt;/em&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Conversão de formato mantendo os codecs:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mov &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c copy saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Conversão de formato e de codecs (&lt;em&gt;transcoding&lt;/em&gt;).&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;-c:v&lt;/code&gt;: codec de vídeo&lt;/li&gt;&lt;li&gt;&lt;code&gt;-c:a&lt;/code&gt;: codec de áudio&lt;/li&gt;&lt;li&gt;&lt;code&gt;-b:a&lt;/code&gt;: &lt;em&gt;bitrate&lt;/em&gt; do áudio&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mov &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:v h264 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:a libopus &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;b:a 96k saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=extrair-%C3%A1udio-de-um-v%C3%ADdeo tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#extrair-%C3%A1udio-de-um-v%C3%ADdeo class=header-anchor&gt;&lt;span&gt;Extrair áudio de um vídeo&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Extração total, mantendo o codec de áudio:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;MP4 -&gt; AAC ou M4A&lt;/li&gt;&lt;li&gt;MKV -&gt; diversos&lt;/li&gt;&lt;li&gt;WebM -&gt; Opus ou Ogg Vorbis&lt;/li&gt;&lt;li&gt;MOV -&gt; ALAC&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;vn &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:a copy saida.m4a&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Extração com &lt;em&gt;transcoding&lt;/em&gt; (mudança de codec). &lt;code&gt;-q:a&lt;/code&gt; é a qualidade, de 0 a 9; quanto menor, melhor a qualidade.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;vn &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:a libmp3lame &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;q:a &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; saida.mp3&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Extração do áudio de um trecho do vídeo. &lt;code&gt;-ss&lt;/code&gt; é o início, &lt;code&gt;-to&lt;/code&gt; é o fim.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ss &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;00&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;00&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;07&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;to &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;00&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;00&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;10.7&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;vn &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:a libmp3lame &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;q:a &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; saida.mp3&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=diminuir-tamanho-do-arquivo tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#diminuir-tamanho-do-arquivo class=header-anchor&gt;&lt;span&gt;Diminuir tamanho do arquivo&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Existem várias formas de se reduzir o tamanho de um vídeo. Nesta seção, abordaremos compressão.&lt;/p&gt;&lt;p&gt;Para entender a fundo o funcionamento, recomendo ler a documentação oficial dos codecs (exemplos: &lt;a href=https://trac.ffmpeg.org/wiki/Encode/H.264&gt;H.264&lt;/a&gt; e &lt;a href=https://trac.ffmpeg.org/wiki/Encode/H.265&gt;H.265&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Limitar com CRF.&lt;/strong&gt; A flag &lt;code&gt;-crf&lt;/code&gt;, &lt;em&gt;Constant Rate Factor&lt;/em&gt;, controla a qualidade e valor menor significa menos compressão e mais qualidade. A escala é de 0 a 51, valor padrão 23.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:v libx264 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;crf &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;23&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;pix_fmt yuv420p &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:a copy saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;-pix_fmt yuv420p&lt;/code&gt; é necessário para compatibilidade com o Apple QuickTime e alguns outros players.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;Limitar o &lt;em&gt;bitrate&lt;/em&gt;.&lt;/strong&gt; Pode-se colocar um limite no &lt;em&gt;bitrate&lt;/em&gt; do vídeo, tornando seu tamanho mais previsível. Essa opção pode ser combinada com o CRF. No exemplo abaixo, o encoder procura limitar o bitrate máximo em 1Mbit/s.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:v libx264 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;crf &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;23&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;maxrate &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1M&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;bufsize &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2M&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;pix_fmt yuv420p &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:a copy saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Transcodar para codecs mais modernos.&lt;/strong&gt; O H.265, por exemplo, produz arquivos menores do que o H.264. A escala do CRF aqui é de 0 a 51, com valor padrão 28.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Deve-se lembrar que não são todos os navegadores e players que suportam H.265.&lt;/em&gt;&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:v libx265 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;crf &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;28&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;tag:v hvc1 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:a copy saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;-tag:v hvc1&lt;/code&gt; é para o vídeo gerado ter compatibilidade com o Apple QuickTime.&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id=cortar-trecho-do-v%C3%ADdeo tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#cortar-trecho-do-v%C3%ADdeo class=header-anchor&gt;&lt;span&gt;Cortar trecho do vídeo&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ss &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;00&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;00&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;19.4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;to &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;00&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;03&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;50&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c copy saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Os parâmetros de tempo podem ser colocados antes ou depois do parâmetro de entrada.&lt;/p&gt;&lt;p&gt;Colocados antes (&lt;code&gt;-ss -to -i&lt;/code&gt;), resulta-se em uma operação mais rápida pois o corte é na entrada, que depois é processada; porém, o corte pode ser impreciso e pode haver dissincronia entre o áudio e o vídeo.&lt;/p&gt;&lt;p&gt;Colocados depois (&lt;code&gt;-i -ss -to&lt;/code&gt;), o corte é mais preciso e não há risco de dissincronia; contudo, a operação é mais lenta porque o corte é na saída, após todo o processamento do vídeo.&lt;/p&gt;&lt;p&gt;Em dúvida, pode-se experimentar primeiro o corte na entrada (primeira opção) e ver o resultado; se o resultado não for correto, então partir para o corte na saída (segunda opção).&lt;/p&gt;&lt;h2 id=aumentar-e-diminuir-volume-de-som tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#aumentar-e-diminuir-volume-de-som class=header-anchor&gt;&lt;span&gt;Aumentar e diminuir volume de som&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O exemplo abaixo aumenta o volume em 2,4 vezes.&lt;/p&gt;&lt;p&gt;Para reduzir à metade, valor 0,5 (usar ponto ao invés de vírgula).&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;af &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;volume=2.4&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=redimensionar-frames tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#redimensionar-frames class=header-anchor&gt;&lt;span&gt;Redimensionar &lt;em&gt;frames&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Dimensões fixas, largura por altura:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;lavfi &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;scale=&#39;720:480&#39;&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Uma dimensão fixada e a outra proporcional, para manter o aspecto:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;lavfi &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;scale=&#39;720:-2&#39;&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Redução por proporções:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;lavfi &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;scale=&#39;floor(iw/4)*2:floor(ih/4)*2&#39;&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No exemplo acima, usou-se a função &lt;code&gt;floor(d/4) * 2&lt;/code&gt; para calcular a metade porque alguns codecs requerem que as dimensões sejam sempre números pares.&lt;/p&gt;&lt;h2 id=inserir-legendas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#inserir-legendas class=header-anchor&gt;&lt;span&gt;Inserir legendas&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3&gt;Legendas opcionais&lt;/h3&gt;&lt;p&gt;Também chamadas de legendas &lt;em&gt;soft&lt;/em&gt;, aparecem ao clicar com o botão direito do mouse no player e escolher a legenda. Mais de uma pode ser adicionada, por exemplo, para mais de um idioma.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i legendas.srt &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c copy &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:s mov_text &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;metadata:s:s:&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; language&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;eng saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Legendas fixas&lt;/h3&gt;&lt;p&gt;Também chamadas de legendas &lt;em&gt;hard&lt;/em&gt; ou &lt;em&gt;burned&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;code&gt;legendas.srt&lt;/code&gt; é o arquivo de legendas. &lt;code&gt;Alignment=2&lt;/code&gt; significa posição centro inferior.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;lavfi &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;subtitles=legendas.srt:force_style=&#39;Alignment=2,OutlineColour=&amp;H100000000,BorderStyle=3,Outline=1,Shadow=0,Fontsize=18,MarginL=5,MarginV=25&#39;&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;crf &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:a copy saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Exemplo de resultado:&lt;/p&gt;&lt;p&gt;&lt;video controls src=https://alexandrehtrb.github.io/assets/videos/posts/2025_01_ffmpeg_burned_subtitles.mp4&gt;&lt;/video&gt;&lt;/p&gt;&lt;h2 id=colocar-texto-em-cima-do-v%C3%ADdeo tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#colocar-texto-em-cima-do-v%C3%ADdeo class=header-anchor&gt;&lt;span&gt;Colocar texto em cima do vídeo&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Usaremos o &lt;code&gt;pad&lt;/code&gt; e o &lt;code&gt;drawtext&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;O &lt;code&gt;pad&lt;/code&gt; coloca uma camada ao redor do vídeo; no exemplo abaixo, faremos de côr preta em cima do vídeo. Para isso, estenderemos a altura do frame em 100 e desenharemos a camada entre 0 e 100 na direção vertical:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# ih = input height&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;pad=width=iw:height=(ih+100):x=0:y=100:color=black&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;O &lt;code&gt;drawtext&lt;/code&gt; desenhará o texto na camada. Nosso texto terá duas linhas, então, usaremos ele duas vezes.&lt;/p&gt;&lt;p&gt;&lt;code&gt;x=(w-text_w)/2&lt;/code&gt; centraliza horizontalmente o texto. A coordenada &lt;code&gt;y&lt;/code&gt; determina a posição vertical da linha.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;drawtext=:font=&#39;Arial&#39;:text=&#39;Men′s Volleyball 2016 Olympics&#39;:fontsize=24:fontcolor=white:x=(w-text_w)/2:y=25&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;drawtext=:font=&#39;Arial&#39;:text=&#39;BRA 3 - 0 ITA&#39;:fontsize=24:fontcolor=white:x=(w-text_w)/2:y=54&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Comando:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffmpeg &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;i entrada.mp4 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;lavfi &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;format=yuv420p,pad=width=iw:height=(ih+100):x=0:y=100:color=black, drawtext=:font=&#39;Arial&#39;:text=&#39;Men′s Volleyball 2016 Olympics&#39;:fontsize=24:fontcolor=white:x=(w-text_w)/2:y=25, drawtext=:font=&#39;Arial&#39;:text=&#39;BRA 3 - 0 ITA&#39;:fontsize=24:fontcolor=white:x=(w-text_w)/2:y=54&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;c:v libx264 &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;crf &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;25&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; saida.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;format=yuv420p&lt;/code&gt; é necessário para compatibilidade com Apple QuickTime e alguns outros players.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Exemplo de resultado:&lt;/p&gt;&lt;p&gt;&lt;video controls src=https://alexandrehtrb.github.io/assets/videos/posts/2025_01_ffmpeg_text_layer_on_top.mp4&gt;&lt;/video&gt;&lt;/p&gt;&lt;h2 id=inspecionar-metadados tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#inspecionar-metadados class=header-anchor&gt;&lt;span&gt;Inspecionar metadados&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Detalha quais codecs foram usados, resolução e &lt;em&gt;bitrate&lt;/em&gt; do áudio e do vídeo, dentre outras informações.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ffprobe video.mp4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=fontes-e-links-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2025/01/introducao-ao-ffmpeg/#fontes-e-links-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e links interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Oz8TYyn-k40&quot;&gt;007 GoldenEye - Bond e Xenia no cassino&lt;/a&gt; (todos os direitos reservados)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=KLIa2UaE2KE&quot;&gt;Olimpíadas Rio 2016 - Brasil conquista o ouro no vôlei masculino&lt;/a&gt; (todos os direitos reservados)&lt;/li&gt;&lt;li&gt;&lt;a href=https://ffmpeg.org/ &gt;Site oficial do FFmpeg&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://trac.ffmpeg.org/wiki/Projects&gt;FFmpeg - Projetos que o usam&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://streaminglearningcenter.com/blogs/youtube-uses-ffmpeg-for-encoding.html&gt;Streaming Learning Center - YouTube uses FFmpeg for encoding&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://theirstack.com/en/technology/ffmpeg&gt;TheirStack - List of companies using FFmpeg&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://trac.ffmpeg.org/wiki/Encode/H.264&gt;FFmpeg - H.264 Video Encoding Guide&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://trac.ffmpeg.org/wiki/Encode/H.265&gt;FFmpeg - H.265/HEVC Video Encoding Guide&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://unix.stackexchange.com/questions/28803/how-can-i-reduce-a-videos-size-with-ffmpeg&gt;Unix Stack Exchange - How can I reduce a video&#39;s size with ffmpeg?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://trac.ffmpeg.org/wiki/Scaling&gt;FFmpeg - Scaling&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://trac.ffmpeg.org/wiki/Seeking&gt;FFmpeg - Seeking&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://stackoverflow.com/questions/6984628/ffmpeg-ss-weird-behaviour&gt;Stack Overflow - FFmpeg -ss weird behaviour&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://superuser.com/questions/624563/how-to-resize-a-video-to-make-it-smaller-with-ffmpeg&gt;Super User - How to resize a video to make it smaller with FFmpeg&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://tribunadejundiai.com.br/mais/inovacao/flac-aac-opus-e-mp3-entenda-as-diferencas-entre-os-arquivos-de-audio/ &gt;Tribuna de Jundiaí - FLAC, AAC, Opus e MP3: entenda as diferenças entre os arquivos de áudio&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://stackoverflow.com/questions/57869367/ffmpeg-subtitles-alignment-and-position&gt;Stack Overflow - ffmpeg subtitles alignment and position&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://subtitletools.com/subtitle-sync-shifter&gt;Subtitle Tools - Sync subtitles&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;script&gt;document.querySelectorAll(&quot;pre.shiki&quot;).forEach(e=&gt;{e.classList.add(&quot;wrapped&quot;)})&lt;/script&gt;</content>
  </entry>
  <entry>
    <title>Propriedades especiais em projetos .NET</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/" />
    <updated>2024-12-17T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/</id>
    <content type="html">&lt;h1 id=arquivos-de-projeto-.net tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#arquivos-de-projeto-.net class=header-anchor&gt;&lt;span&gt;Arquivos de projeto .NET&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Certas configurações em projetos .NET modificam como o projeto é compilado, e a performance e tamanho dos programas publicados.&lt;/p&gt;&lt;p&gt;Essas configurações ficam nos arquivos .csproj (C#), .fsproj (F#) e .vbproj (VB.NET); também podem ser passadas via linha de comando, ao executar &lt;code&gt;dotnet run&lt;/code&gt;, &lt;code&gt;dotnet build&lt;/code&gt; e &lt;code&gt;dotnet publish&lt;/code&gt;.&lt;/p&gt;&lt;h2 id=em-arquivos-de-projeto tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#em-arquivos-de-projeto class=header-anchor&gt;&lt;span&gt;Em arquivos de projeto&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;Project&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; Sdk&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;Microsoft.NET.Sdk&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;    &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;OutputType&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;Exe&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;OutputType&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;    &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TargetFramework&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;net8.0&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TargetFramework&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;    &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;Nullable&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;enable&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;Nullable&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;    &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ImplicitUsings&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;enable&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ImplicitUsings&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;Project&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=via-linha-de-comando tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#via-linha-de-comando class=header-anchor&gt;&lt;span&gt;Via linha de comando&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;dotnet publish &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;  --&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;configuration Release &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;  --&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;self&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;contained true &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;  --&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;runtime &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;linux-x64&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;  -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;p:PublishSingleFile&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;true &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;  --&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;output &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;./out/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=propriedades tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#propriedades class=header-anchor&gt;&lt;span&gt;Propriedades&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#targetframework&gt;TargetFramework&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#nullable&gt;Nullable&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#implicitusings&gt;ImplicitUsings&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#treatwarningsaserrors&gt;TreatWarningsAsErrors&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#configuration&gt;Configuration&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#selfcontained&gt;SelfContained&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#publishsinglefile&gt;PublishSingleFile&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#enablecompressioninsinglefile&gt;EnableCompressionInSingleFile&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#publishreadytorun&gt;PublishReadyToRun&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#trimming&gt;Trimming&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#nativeaot&gt;NativeAOT&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#version&gt;Version&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#applicationicon&gt;ApplicationIcon&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=targetframework tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#targetframework class=header-anchor&gt;&lt;span&gt;TargetFramework&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Diz para quais versões do .NET seu projeto deve compilar. Geralmente, especifica-se apenas um TFM (&lt;em&gt;target framework moniker&lt;/em&gt;), porém, se precisar atender a mais de uma versão do .NET, você pode especificar uma lista de TFMs, separados por ponto-e-vírgula (&#39;;&#39;).&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  &amp;lt;!-- apenas um --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TargetFramework&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;net8.0&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TargetFramework&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  &amp;lt;!-- múltiplos. note o plural. --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TargetFrameworks&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;netstandard1.4;net40;net45&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TargetFrameworks&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=nullable tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#nullable class=header-anchor&gt;&lt;span&gt;Nullable&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Quando presente com valor true, avisa sempre que uma variável que pode ser nula for usada em um local que não aceita nulos.&lt;/p&gt;&lt;p&gt;Considere o código abaixo. Há um aviso de que um valor nulo pode acabar sendo passado para o método &lt;code&gt;int.Parse()&lt;/code&gt;, método este que não aceita strings nulas.&lt;/p&gt;&lt;img alt=&quot;Aviso de possível valor nulo&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_12_warning_nulavel.png&gt;&lt;p&gt;Há quatro formas de resolver esse aviso:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Alterar a assinatura do método. Quando uma variável tem interrogação após o tipo (&lt;code&gt;string?&lt;/code&gt;), significa que aceita nulos; sem interrogação (&lt;code&gt;string&lt;/code&gt;), espera-se um valor não-nulo.&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; int&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; ConverterParaInt&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    int&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Parse&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start=2&gt;&lt;li&gt;Proteger via código contra valores nulos.&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; int&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; ConverterParaInt&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    if&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; ==&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; null&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        throw&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; new&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ArgumentNullException&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;nameof&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    else&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        return&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; int&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Parse&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start=3&gt;&lt;li&gt;Marcar com uma exclamação. Ela indica que o valor é seguro.&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; int&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; ConverterParaInt&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    int&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Parse&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;!&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start=4&gt;&lt;li&gt;Desabilitar a verificação de nuláveis via diretiva de compilação.&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E6C92&gt;#nullable disable warnings&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; int&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; ConverterParaInt&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        int&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Parse&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;stringNumerica&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E6C92&gt;#nullable restore warnings&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=implicitusings tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#implicitusings class=header-anchor&gt;&lt;span&gt;ImplicitUsings&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Faz com que todos os arquivos de código (.cs, .fs, .vb) venham com alguns usings declarados implicitamente, de modo que não é necessário declarar manualmente.&lt;/p&gt;&lt;p&gt;A lista de namespaces varia conforme o tipo de projeto.&lt;/p&gt;&lt;p&gt;Para projetos console e class libraries:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Collections&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Generic&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;IO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Linq&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Net&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Http&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Threading&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Threading&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Tasks&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para projetos Web, além dos listados acima:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Net&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Http&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Json&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;AspNetCore&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Builder&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;AspNetCore&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Hosting&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;AspNetCore&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Http&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;AspNetCore&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Routing&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Configuration&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;DependencyInjection&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Hosting&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Logging&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para Workers, a primeira lista, mais:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Configuration&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;DependencyInjection&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Hosting&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Extensions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Logging&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=treatwarningsaserrors tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#treatwarningsaserrors class=header-anchor&gt;&lt;span&gt;TreatWarningsAsErrors&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Faz com que avisos sejam considerados erros e assim o projeto não compile se houver algum aviso.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TreatWarningsAsErrors&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;True&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TreatWarningsAsErrors&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;É uma opção interessante para melhorar a qualidade do código, pois força os desenvolvedores a se atentarem aos avisos, que indicam possíveis falhas de lógica e tratamento de dados. Um exemplo é combinar essa opção junto com o &lt;em&gt;Nullable&lt;/em&gt;.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Comentário do autor&lt;/strong&gt;: apenas isso como medida não tornará seu código melhor. Os devs podem simplesmente contornar os avisos, por exemplo, através de &lt;code&gt;#pragma warning disable&lt;/code&gt; ou ignorar nuláveis via exclamação (ver acima). Um código de qualidade é resultado de boas práticas de programação e revisões por pares.&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id=configuration tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#configuration class=header-anchor&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Determina se o projeto vai ser compilado como Debug ou Release.&lt;/p&gt;&lt;p&gt;Em modo Debug, a compilação produz arquivos de símbolos (.pdb) que facilitam o debug do código via IDE e breakpoints. Além disso, o código não é optimizado plenamente.&lt;/p&gt;&lt;p&gt;No modo Release, a compilação não produz arquivos de símbolos e a optimização do código é total. Sempre que for gerar um programa para publicação, deve-se usar a configuração Release.&lt;/p&gt;&lt;p&gt;Essa opção é passada via flags.&lt;/p&gt;&lt;h2 id=selfcontained tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#selfcontained class=header-anchor&gt;&lt;span&gt;SelfContained&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Embute o .NET runtime junto ao executável publicado. Isso significa que a máquina de destino (onde o programa vai rodar) não precisará ter ele instalado.&lt;/p&gt;&lt;p&gt;Essa opção faz com que o tamanho do executável final seja maior (por ter o .NET runtime consigo).&lt;/p&gt;&lt;h2 id=publishsinglefile tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#publishsinglefile class=header-anchor&gt;&lt;span&gt;PublishSingleFile&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Condensa as várias DLLs e arquivos auxiliares do programa em um único arquivo executável, diminuindo a quantidade de arquivos publicados. Isso é interessante para programas portáteis (portable).&lt;/p&gt;&lt;p&gt;&lt;em&gt;DLLs interop em C/C++ são imunes a essa opção e vão aparecer em arquivos separados.&lt;/em&gt;&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PublishSingleFile&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;True&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PublishSingleFile&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=enablecompressioninsinglefile tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#enablecompressioninsinglefile class=header-anchor&gt;&lt;span&gt;EnableCompressionInSingleFile&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Junto com a opção acima, comprime o executável condensado, diminuindo seu tamanho no disco rígido. Um contraponto é que a inicialização do programa fica mais lenta, pois ele precisa descomprimir seu conteúdo antes de executar. (Ele não cria arquivos ao executar; a descompressão é feita em memória.)&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;EnableCompressionInSingleFile&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;True&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;EnableCompressionInSingleFile&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=publishreadytorun tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#publishreadytorun class=header-anchor&gt;&lt;span&gt;PublishReadyToRun&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;É uma optimização especial do compilador que torna a inicialização do programa mais rápida, prevendo como ele vai executar na máquina de destino e trocando partes de código intermedíario (IL, intermediate language) por código de máquina (Assembly). Isso é interessante para APIs, por exemplo, pois assim elas demoram menos tempo para entrar em funcionamento.&lt;/p&gt;&lt;p&gt;Essa opção aumenta o tamanho do executável final e aumenta o tempo de compilação.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PublishReadyToRun&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;True&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PublishReadyToRun&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=trimming tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#trimming class=header-anchor&gt;&lt;span&gt;Trimming&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Recorta partes não utilizadas do código e de bibliotecas do programa, diminuindo significativamente o tamanho do executável final.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Essa opção deve ser usada com cuidado&lt;/strong&gt;, pois pode remover partes importantes do código e causar erros durante a execução. Para evitar esses problemas, o compilador emite avisos em linhas suscetíveis de serem recortadas, para que o programador adote alternativas ou então marque o código para não ser removido.&lt;/p&gt;&lt;p&gt;O recorte pode ser parcial, ou seja, só em classes e bibliotecas especificadas, ou então no programa inteiro.&lt;/p&gt;&lt;p&gt;Esse tema é extenso e requer uma leitura com atenção, por isso, recomendo a &lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options&gt;documentação&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Exemplo de trimming parcial:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PublishTrimmed&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;true&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PublishTrimmed&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TrimMode&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;partial&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TrimMode&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;&amp;lt;!-- lista de assemblies que serão trimmados --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ItemGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;TrimmableAssembly&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; Include&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;MyAssembly&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ItemGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=nativeaot tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#nativeaot class=header-anchor&gt;&lt;span&gt;NativeAOT&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;NativeAOT é um tipo especial de compilação direto para linguagem de máquina, aumentando a performance do programa.&lt;/p&gt;&lt;p&gt;Na compilação tradicional, o executável final é composto pelo código em linguagem intermediária (IL, &lt;em&gt;intermediate language&lt;/em&gt;) que é interpretado pelo .NET runtime (CoreCLR). Durante a execução do programa, o runtime traduz cada instrução em IL para código de máquina, e assim o programa roda.&lt;/p&gt;&lt;p&gt;Ao compilar diretamente para linguagem nativa, o intermediário é removido e pode-se aproveitar diversas optimizações específicas de arquitetura de processador e sistema operacional, de modo que:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;a execução fica mais rápida,&lt;/li&gt;&lt;li&gt;consome menos memória RAM,&lt;/li&gt;&lt;li&gt;o tamanho do executável final é menor.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Essa opção de compilação não é simples de usar, contudo.&lt;/strong&gt; Ela requer que todos os caminhos de código possam ser analisados estaticamente, em outras palavras, &lt;em&gt;não é possível usar reflection no programa&lt;/em&gt;, o que afeta por exemplo a serialização e desserialização de JSON e XML.&lt;/p&gt;&lt;p&gt;Para (des)serialização de JSON, uma solução é os source generators do System.Text.Json, que escrevem e lêem JSONs através de código gerado em tempo de compilação.&lt;/p&gt;&lt;p&gt;WPF e Windows Forms são baseados em reflection e por isso não suportam NativeAOT; mas aplicações console e ASP.NET minimal APIs têm suporte ao NativeAOT.&lt;/p&gt;&lt;p&gt;Assim como o trimming, usar essa funcionalidade requer cuidado e vale ler a &lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ &gt;documentação oficial&lt;/a&gt;.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PublishAot&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;true&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PublishAot&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=version tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#version class=header-anchor&gt;&lt;span&gt;Version&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Marca qual é a versão do programa, do arquivo ou do assembly.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;Version&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;3.7.1&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;Version&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  &amp;lt;!-- o valor de Version é reutilizado abaixo --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;FileVersion&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;$(Version)&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;FileVersion&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;AssemblyVersion&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;$(Version)&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;AssemblyVersion&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para pegar a versão via código:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; versionName&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; Assembly&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;GetExecutingAssembly&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;                             .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;GetName&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;                             .&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Version&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;?&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;                             .&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ToString&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// versionName = &quot;3.7.1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Aviso&lt;/strong&gt;: o versionamento de pacotes NuGet é feito através de outras propriedades. Confira mais na &lt;a href=https://learn.microsoft.com/en-us/nuget/create-packages/package-authoring-best-practices&gt;documentação&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id=applicationicon tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#applicationicon class=header-anchor&gt;&lt;span&gt;ApplicationIcon&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Coloca um ícone no programa para exibição no Windows Explorer.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ApplicationIcon&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;my_program.ico&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ApplicationIcon&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;PropertyGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=fontes-e-leituras-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/12/propriedades-especiais-em-projetos-dotnet/#fontes-e-leituras-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e leituras interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/standard/frameworks#how-to-specify-a-target-framework&gt;.NET Docs - Target frameworks in SDK-style projects&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://devblogs.microsoft.com/dotnet/embracing-nullable-reference-types/ &gt;Microsoft DevBlogs - Embracing nullable reference types&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://dotnetcoretutorials.com/implicit-using-statements-in-net-6/ &gt;DotNetCore Tutorials - Implicit Using Statements In .NET 6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview&gt;.NET Docs - Single-file deployment&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/ &gt;.NET Docs - .NET application publishing overview&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run&gt;.NET Docs - ReadyToRun Compilation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options&gt;.NET Docs - Trimming options&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ &gt;.NET Docs - Native AOT deployment&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/source-generation&gt;.NET Docs - How to use source generation in System.Text.Json&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://github.com/dotnet/core/issues/6260&gt;GitHub Dotnet Core repo - How to set application icon on Windows?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/nuget/create-packages/package-authoring-best-practices&gt;.NET Docs - NuGet Package authoring best practices&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props&gt;.NET Docs - MSBuild reference for .NET SDK projects&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties?view=vs-2022&quot;&gt;MSBuild Docs - Common MSBuild project properties&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-reserved-and-well-known-properties?view=vs-2022&quot;&gt;MSBuild Docs - MSBuild reserved and well-known properties&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Os pais da qualidade, Deming e Shewhart</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/10/os-pais-da-qualidade-deming-e-shewhart/" />
    <updated>2024-10-14T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/10/os-pais-da-qualidade-deming-e-shewhart/</id>
    <content type="html">&lt;p&gt;Nos anos 1980, havia um pensamento na cultura pop que o Japão conquistaria o mundo — não pela força, mas por sua economia pujante, que foi a segunda maior do mundo entre 1990 e 2010. Podemos ver isso em vários filmes, como no &lt;em&gt;De Volta Para o Futuro Parte II&lt;/em&gt;, em que o chefe do Marty McFly no futuro é japonês; e em &lt;em&gt;Duro de Matar&lt;/em&gt;, em que a esposa do protagonista trabalha numa empresa japonesa, no fim da década de 80. O chefe dela é o Sr. Takagi, na imagem abaixo.&lt;/p&gt;&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;Duro de Matar - John McClane, Ellis, Takagi e Holly Gennaro&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2024_10_die_hard_takagi.avif type=image/avif&gt;&lt;img alt=&quot;Duro de Matar - John McClane, Ellis, Takagi e Holly Gennaro&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_10_die_hard_takagi.jpg&gt;&lt;/picture&gt;&lt;/p&gt;&lt;p&gt;A palavra-chave que resume o milagre econômico japonês é &lt;strong&gt;qualidade&lt;/strong&gt;. Ao focar em produtos melhores, com menos defeitos e com processos industriais mais eficientes, a indústria japonesa ganhou a atenção dos consumidores e espaço na economia global.&lt;/p&gt;&lt;p&gt;Essa transformação começou com dois homens, cujos trabalhos mudaram o Japão e as empresas de todo o mundo.&lt;/p&gt;&lt;h2 id=deming-e-shewhart tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/10/os-pais-da-qualidade-deming-e-shewhart/#deming-e-shewhart class=header-anchor&gt;&lt;span&gt;Deming e Shewhart&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;William Edwards Deming (1900-1993) foi um estatístico, engenheiro, economista e consultor americano. Por seu trabalho, ele é conhecido como &lt;em&gt;o pai da qualidade&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Deming fez graduação em engenharia elétrica, e depois mestrado e doutorado em matemática e física. Em 1927, ele começou a trabalhar no Departamento de Agricultura dos EUA e lá, por meio de colegas, conheceu Walter Andrew Shewhart (1891-1967), este que é conhecido como &lt;em&gt;o pai do controle estatístico de qualidade&lt;/em&gt;. Shewhart era um engenheiro da Bell Telephone Company e usava estatística para melhorar a confiabilidade e clareza sonora das linhas telefônicas.&lt;/p&gt;&lt;p&gt;Shewhart ensinou a Deming muitas ferramentas que serviram de base para seus trabalhos futuros, dentre elas, os gráficos de controle e os ciclos PDCA.&lt;/p&gt;&lt;h3&gt;Gráfico de controle&lt;/h3&gt;&lt;p&gt;Mostra quanto algo fica dentro de uma margem de tolerância ao longo do tempo.&lt;/p&gt;&lt;p&gt;Alguns casos da vida real: o tamanho de peças mecânicas produzidas; a quantidade de remédio inserida em cada comprimido; o tempo de trajeto entre duas cidades.&lt;/p&gt;&lt;p&gt;Abaixo, vemos um processo que inicialmente está fora de controle; depois, fica dentro da zona de tolerância; e por fim, dentro de uma zona mais estreita, denotando melhora na qualidade do processo.&lt;/p&gt;&lt;img alt=&quot;Gráfico de controle&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_10_control_chart.jpg class=my-4&gt;&lt;p&gt;Com um gráfico de controle podemos detectar anomalias numa linha de produção, ou então estimar quando uma máquina precisará de manutenção.&lt;/p&gt;&lt;h2 id=segunda-guerra-mundial-e-p%C3%B3s-guerra tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/10/os-pais-da-qualidade-deming-e-shewhart/#segunda-guerra-mundial-e-p%C3%B3s-guerra class=header-anchor&gt;&lt;span&gt;Segunda Guerra Mundial e pós-guerra&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Durante a Segunda Guerra Mundial, Deming fez parte do Comitê Técnico Emergencial dos EUA, focado em melhorar a indústria armamentícia. O controle estatístico de qualidade foi aplicado nas fábricas e diminuiu o número de falhas em armamentos americanos.&lt;/p&gt;&lt;p&gt;Após a guerra, Deming foi convocado para preparar o censo japonês de 1951 e seu trabalho e envolvimento na sociedade japonesa o fizeram ser notado, a ponto de a União Japonesa de Cientistas e Engenheiros (JUSE) chamá-lo para lhes ensinar sobre estatística e qualidade. Suas aulas foram um tremendo sucesso e foram transcritas em livros com milhares de cópias vendidas.&lt;/p&gt;&lt;p&gt;Em uma palestra a executivos japoneses em 1950, Deming lhes disse que implementar o controle estatístico de qualidade nas suas empresas diminuiria custos e desperdícios, aumentaria a produtividade e cativaria os consumidores, atraídos por produtos melhores. Os executivos levaram essas idéias para suas companhias e tiveram resultados muito positivos.&lt;/p&gt;&lt;p&gt;Nas décadas seguintes, o Japão viu sua economia ressurgir das cinzas e ganhar destaque mundial, em grande parte devido à implementação das idéias de Deming. O crescimento do PIB girava entre 8-10% ao ano.&lt;/p&gt;&lt;img alt=&quot;William Edwards Deming no Japão&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_10_william_edwards_deming_in_japan.jpg class=my-4&gt; &lt;em class=&quot;italic text-sm&quot;&gt;Deming, à direita na foto, em visita ao Japão.&lt;/em&gt;&lt;h3&gt;Caso de estudo: Transmissão Mazda-Ford&lt;/h3&gt;&lt;p&gt;Nos anos 80, a Ford fez uma parceria com a Mazda para produzir câmbios automáticos para carros da Ford.&lt;/p&gt;&lt;p&gt;Ambas as companhias produziam essa transmissão e nas duas os produtos saíam de fábrica dentro das margens de tolerância. Contudo, transmissões Ford recebiam mais reclamações de clientes e tinham reparos mais caros; não só isso, as pessoas chegavam às concessionárias da Ford pedindo que seus carros novos viéssem com transmissão japonesa, pois eram mais macios de dirigir.&lt;/p&gt;&lt;p&gt;Os engenheiros da Ford investigaram e notaram que as transmissões Ford tinham variância de 70% da margem de tolerância, enquanto que as transmissões Mazda tinham variância de 27%. Por exemplo, se a especificação de uma peça era de 300mm ± 3mm, na Ford as peças variavam 2,1mm; na Mazda, 1,15mm.&lt;/p&gt;&lt;p&gt;O custo de produção na Mazda era um pouco mais caro, porém, o custo de arcar com a garantia na Ford era maior.&lt;/p&gt;&lt;p&gt;Após esse estudo, a fábrica da Ford melhorou a qualidade das suas transmissões, que se tornaram melhores do que as da Mazda.&lt;/p&gt;&lt;h3&gt;Caso de estudo: TVs da Sony&lt;/h3&gt;&lt;p&gt;Também nos anos 80, a Sony tinha duas plantas de produção de TVs, uma no Japão e outra em San Diego, Califórnia.&lt;/p&gt;&lt;p&gt;Um dos parâmetros de qualidade era a densidade de côr, com margem de tolerância entre 9 e 14. As TVs produzidas em San Diego todas estavam dentro da margem, enquanto que 1,3 em cada 1000 das produzidas no Japão estavam fora. Todavia, os consumidores preferiam as TVs japonesas, pois a imagem na tela era mais homogênea, devido a uma menor variância de densidade de côr.&lt;/p&gt;&lt;h2 id=reconhecimento-nos-eua tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/10/os-pais-da-qualidade-deming-e-shewhart/#reconhecimento-nos-eua class=header-anchor&gt;&lt;span&gt;Reconhecimento nos EUA&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Ironicamente, as idéias de Deming caíram em desuso nos EUA após a guerra e não tiveram aceitação entre os executivos americanos, pois eles acreditavam que qualidade era um custo, e não um investimento.&lt;/p&gt;&lt;p&gt;Nas décadas seguintes, Deming estendeu seu trabalho para além da estatística, abordando como melhorar a eficiência e organização nas empresas, resumindo suas idéias nos chamados &lt;strong&gt;14 pontos para gestão&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Em 1980, a NBC produziu um documentário comparando empresas americanas e japonesas. Um dos entrevistados foi Deming, que começou a receber propostas de trabalho após aparecer na TV. Uma das empresas que o contratou foi a Ford.&lt;/p&gt;&lt;p&gt;No início da década de 1980, a Ford registrava prejuízos de mais de 3 bilhões de dólares. Deming foi contratado e disse que a gerência era responsável por 85% dos problemas que impediam o desenvolvimento de carros melhores. Os executivos da Ford levaram isso a sério e adotaram as idéias de Deming: em 1986, a empresa se tornou a montadora americana com maior lucro, ultrapassando a General Motors pela primeira vez desde a década de 1920. O lucro cresceu consistentemente nos anos seguintes.&lt;/p&gt;&lt;img alt=&quot;Linha de produção do Ford Taurus, em 1986&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_10_ford_taurus_production_line.jpg class=my-4&gt; &lt;em class=&quot;italic text-sm&quot;&gt;Linha de produção do Ford Taurus, em 1986. O modelo foi um sucesso de vendas e salvou a companhia da falência.&lt;/em&gt;&lt;h2 id=14-pontos-para-gest%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/10/os-pais-da-qualidade-deming-e-shewhart/#14-pontos-para-gest%C3%A3o class=header-anchor&gt;&lt;span&gt;14 pontos para gestão&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;No livro &lt;em&gt;Saia da Crise&lt;/em&gt;, Deming cita os seguintes pontos para a boa gestão de uma empresa:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Criar constância de propósito de aperfeiçoamento do produto e serviço, a fim de torná-los competitivos, perpetuá-los no mercado e gerar empregos.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Adotar a nova filosofia. Vivemos numa nova era econômica. Os executivos e gerentes ocidentais devem despertar para o desafio, conscientizar-se de suas responsabilidades e assumir a liderança em direção à transformação.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Acabar com a dependência de inspeção para a obtenção da qualidade. Eliminar a necessidade de inspeção em massa, focando em fazer certo desde o começo.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Acabar com a prática de escolher fornecedores apenas com base em preço. Em vez disso, minimizar o custo total. Preferir um único fornecedor para cada item, estabelecendo relacionamentos duradouros, calcados na qualidade e na confiança.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Aperfeiçoar constante e continuamente todo o processo de planejamento, produção e serviços, com o objetivo de aumentar a qualidade e a produtividade e, conseqüentemente, reduzir custos.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Fornecer treinamento no local de trabalho.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Instituir liderança. O objetivo da liderança é ajudar as pessoas e máquinas a realizar um trabalho melhor.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Eliminar o medo no local de trabalho.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Quebrar as barreiras entre departamentos. Os colaboradores dos setores de pesquisa, projetos, vendas, compras ou produção devem trabalhar em equipe, para antever problemas na produção ou nos produtos e serviços.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Eliminar &lt;em&gt;slogans&lt;/em&gt;, exortações e pedidos para que a produtividade aumente e não ocorram erros. Tais exortações apenas instigam rivalidades entre as pessoas, sendo que o grosso das causas de baixa qualidade e produtividade está no sistema como um todo e não na força de trabalho.&lt;br&gt;&lt;br&gt;a) Eliminar metas numéricas para o chão de fábrica.&lt;br&gt;&lt;br&gt;b) Eliminar administração por objetivos — líderes devem conhecer o sistema e prover um plano de trabalho.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Remover barreiras que roubem das pessoas o sentimento de orgulho no trabalho. A atenção dos supervisores deve voltar-se para a qualidade e não para números.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Remover barreiras que roubam dos gerentes e engenheiros o justo direito de se orgulhar do produto de seu trabalho. Isso significa abolir avaliações anuais e de mérito, e da administração por objetivos ou números.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Instituir um programa vigoroso de educação e auto-aperfeiçoamento para todo o pessoal.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Empenhar todos na companhia para conseguir essa transformação. É um trabalho de todos.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=fontes-e-leituras-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/10/os-pais-da-qualidade-deming-e-shewhart/#fontes-e-leituras-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e leituras interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://tvtropes.org/pmwiki/pmwiki.php/Analysis/JapanTakesOverTheWorld&gt;TV Tropes - Japan Takes Over The World - Analysis&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://en.wikipedia.org/wiki/List_of_countries_by_largest_historical_GDP&gt;Wikipédia - Lista de países com maiores PIBs históricos&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://popculturereferences.com/wp-content/uploads/2021/11/its-a-rolex.jpg&gt;Duro de Matar, fotografia dos personagens&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.bizmanualz.com/improve-business-processes/how-to-use-control-charts-for-continuous-improvement.html&gt;BizManualz - How to Use Control Charts for Continuous Improvement&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://pt.wikipedia.org/wiki/William_Edwards_Deming&gt;Wikipédia - William Edwards Deming&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://pt.wikipedia.org/wiki/Walter_A._Shewhart&gt;Wikipédia - Walter Andrew Shewhart&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://deming.org/deming-the-man/ &gt;The Deming Institute - The Man&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.nae.edu/19579/19581/51314/51341/188359/W-EDWARDS-DEMING-19001993&gt;National Academy of Engineering - W. Edwards Deming&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=vcG_Pmt_Ny4&quot;&gt;YouTube - Documentário da NBC &quot;Se o Japão pode, por que não podemos?&quot; (1980)&lt;/a&gt; &lt;strong&gt;(recomendado)&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=http://hclectures.blogspot.com/1970/08/demings-1950-lecture-to-japanese.html&gt;Transcrição da palestra de Deming a executivos do Japão em 1950&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://specinnovations.com/blog/ford-vs.-mazda-transmissions&gt;Spec Innovations - Ford vs. Mazda transmissions&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://elsmar.com/elsmarqualityforum/threads/the-famous-ford-study-of-mazda-transmissions-can-the-characteristic-be-measured.1263/ &gt;Elsmar Quality Forum - The Famous Ford Study of Mazda Transmissions - Can the characteristic be measured?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.nytimes.com/2001/06/13/business/management-ford-embraces-six-sigma.html&gt;New York Times - Management: Ford Embraces Six Sigma (13/06/2001)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Collation e encoding em bancos de dados</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/08/collation-e-encoding-em-bancos-de-dados/" />
    <updated>2024-08-29T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/08/collation-e-encoding-em-bancos-de-dados/</id>
    <content type="html">&lt;h2 id=introdu%C3%A7%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/collation-e-encoding-em-bancos-de-dados/#introdu%C3%A7%C3%A3o class=header-anchor&gt;&lt;span&gt;Introdução&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Toda informação em um computador é armazenada e processada na sua representação em número binário.&lt;/p&gt;&lt;p&gt;Mas e os textos? Um texto é uma seqüência de caractéres, um caractér sendo uma letra ou um símbolo. Cada caractér é representado por um número binário, sendo que o mapeamento caractér-número é chamado de &lt;strong&gt;encoding&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;A tabela abaixo é do encoding Windows-1252, que contempla 255 caractéres possíveis, cada um representado por um &lt;em&gt;byte&lt;/em&gt;. Você pode ver essa tabela com o Mapa de Caractéres do Windows (Win+R, &lt;code&gt;charmap&lt;/code&gt;).&lt;/p&gt;&lt;img alt=&quot;Tabela do encoding Windows-1252&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_08_windows_1252_table.gif&gt;&lt;p&gt;A &lt;strong&gt;collation&lt;/strong&gt;, por sua vez, é a regra de ordenação usada para comparar textos. Ela também determina qual é o encoding utilizado para armazenamento.&lt;/p&gt;&lt;p&gt;No Microsoft SQL Server, no nome de uma collation, CI / CS significa case (in)sensitive — diferenciação por maiúsculas e minúsculas; AI / AS, accent (in)sensitive — diferenciação por acentos. Com uma collation case-insensitive (CI), por exemplo, tanto faz pesquisar &lt;code&gt;silva&lt;/code&gt; ou &lt;code&gt;SILVA&lt;/code&gt;. Com uma collation accent-insensitive (AI), &lt;code&gt;Acucar&lt;/code&gt; e &lt;code&gt;Açúcar&lt;/code&gt; são considerados iguais em comparações.&lt;/p&gt;&lt;p&gt;Accent-insensitive na verdade é insensível para todos os &lt;a href=https://pt.wikipedia.org/wiki/Diacr%C3%ADtico&gt;diacríticos&lt;/a&gt; de um idioma, como cedilhas (ç, ş) e acentos (é, ã, ô, etc). Algumas collations mais antigas não cobrem todos os diacríticos nas comparações (&lt;a href=https://dba.stackexchange.com/questions/343799/a-collation-that-ignores-cedillas-for-comparison&gt;link&lt;/a&gt;), por isso, collations mais novas são preferíveis.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Name],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  COLLATIONPROPERTY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;( [Name], &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;LCID&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [LCID],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  COLLATIONPROPERTY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;( [Name], &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;CodePage&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [CodePage]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sys.fn_helpcollations()&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ORDER BY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Name];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Nome&lt;/th&gt;&lt;th style=text-align:center&gt;Encoding&lt;/th&gt;&lt;th style=text-align:center&gt;Compara &lt;em&gt;casing&lt;/em&gt;&lt;/th&gt;&lt;th style=text-align:center&gt;Compara acentos&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Latin1_General_&lt;br&gt;CI_AS&lt;/td&gt;&lt;td style=text-align:center&gt;Windows-1252&lt;/td&gt;&lt;td style=text-align:center&gt;Não&lt;/td&gt;&lt;td style=text-align:center&gt;Sim&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Latin1_General_&lt;br&gt;100_CI_AS_&lt;br&gt;KS_SC_UTF8&lt;/td&gt;&lt;td style=text-align:center&gt;UTF-8 (65001)&lt;/td&gt;&lt;td style=text-align:center&gt;Não&lt;/td&gt;&lt;td style=text-align:center&gt;Sim&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Latin1_General_&lt;br&gt;100_CS_AS_&lt;br&gt;KS_SC_UTF8&lt;/td&gt;&lt;td style=text-align:center&gt;UTF-8 (65001)&lt;/td&gt;&lt;td style=text-align:center&gt;Sim&lt;/td&gt;&lt;td style=text-align:center&gt;Sim&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id=unicode%2C-utf-8-e-utf-16 tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/collation-e-encoding-em-bancos-de-dados/#unicode%2C-utf-8-e-utf-16 class=header-anchor&gt;&lt;span&gt;Unicode, UTF-8 e UTF-16&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O Unicode é uma tabela que define um número para cada caractér, compreendendo símbolos, algarismos e letras de diversos alfabetos. O número atribuído a um caractér é chamado de &lt;strong&gt;code point&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;O UTF-8 e o UTF-16 são encodings que seguem o Unicode. Basicamente, são formas de armazenar esses números em &lt;em&gt;bytes&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;O UTF-16 usa 2 bytes para a maioria dos caractéres e 4 para aqueles acima do intervalo padrão. Esse encoding é usado nas strings da maioria das linguagens de programação.&lt;/p&gt;&lt;p&gt;O UTF-8 usa uma quantidade variável de bytes, de 1 a 4 por caractér. É o principal encoding da Internet.&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Intervalo Unicode&lt;/th&gt;&lt;th style=text-align:center&gt;Grupos&lt;/th&gt;&lt;th style=text-align:center&gt;Bytes por char, UTF-8&lt;/th&gt;&lt;th style=text-align:center&gt;Bytes por char, UTF-16&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;0x0000 a 0x007F&lt;/td&gt;&lt;td style=text-align:center&gt;Alfabeto latino básico, algarismos arábicos (0 a 9), símbolos básicos do teclado&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;0x0080 a 0x07FF&lt;/td&gt;&lt;td style=text-align:center&gt;Alfabetos latino estendido (com acentos, cedilhas), grego, cirílico, árabe, hebraico&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;0x0800 a 0xFFFF&lt;/td&gt;&lt;td style=text-align:center&gt;Ideogramas japoneses e chineses; símbolos variados; operadores matemáticos&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;0x010000 a 0x10FFFF&lt;/td&gt;&lt;td style=text-align:center&gt;Pictogramas de escritas antigas (ex.: hieróglifos egípcios); emojis; símbolos musicais&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;A escolha do encoding afeta diretamente o tamanho usado para armazenamento de textos. Se a maioria dos caractéres estiver no intervalo de alfabeto latino básico, o UTF-8 é melhor, porque usa menos bytes do que o UTF-16; mas, se a escrita for asiática, o UTF-16 tem vantagem, pois o caractér ocupa 2 bytes, contra 3 do UTF-8.&lt;/p&gt;&lt;p&gt;A tabela abaixo mostra como um número Unicode é convertido para UTF-8 ou UTF-16, para cada intervalo acima.&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Caractér de exemplo&lt;/th&gt;&lt;th style=text-align:center&gt;Code point em binário&lt;/th&gt;&lt;th style=text-align:center&gt;Em UTF-8&lt;/th&gt;&lt;th style=text-align:center&gt;Em UTF-16&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;P&lt;/strong&gt; (0x0050)&lt;/td&gt;&lt;td style=text-align:center&gt;00110010&lt;/td&gt;&lt;td style=text-align:center&gt;00110010&lt;/td&gt;&lt;td style=text-align:center&gt;00000000 00110010&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;Ω&lt;/strong&gt; (0x03A9)&lt;/td&gt;&lt;td style=text-align:center&gt;00000&lt;span style=color:green&gt;011&lt;/span&gt; &lt;span style=color:red&gt;1010&lt;/span&gt;&lt;span style=color:purple&gt;1001&lt;/span&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;110&lt;span style=color:green&gt;011&lt;/span&gt;&lt;span style=color:red&gt;10&lt;/span&gt; 10&lt;span style=color:red&gt;10&lt;/span&gt;&lt;span style=color:purple&gt;1001&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;00000011 10101001&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;€&lt;/strong&gt; (0x20AC)&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;span style=color:#00f&gt;0010&lt;/span&gt;&lt;span style=color:green&gt;0000&lt;/span&gt; &lt;span style=color:red&gt;1010&lt;/span&gt;&lt;span style=color:purple&gt;1100&lt;/span&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;1110&lt;span style=color:#00f&gt;0010&lt;/span&gt; 10&lt;span style=color:green&gt;0000&lt;/span&gt;&lt;span style=color:red&gt;10&lt;/span&gt; 10&lt;span style=color:red&gt;10&lt;/span&gt;&lt;span style=color:purple&gt;1100&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;00100000 10101100&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;🐎 (0x1F40E)&lt;/td&gt;&lt;td style=text-align:center&gt;000&lt;span style=color:#2e8b57&gt;0&lt;/span&gt;&lt;span style=color:sienna&gt;0001&lt;/span&gt; &lt;span style=color:#00f&gt;1111&lt;/span&gt;&lt;span style=color:green&gt;0100&lt;/span&gt; &lt;span style=color:red&gt;0000&lt;/span&gt;&lt;span style=color:purple&gt;1110&lt;/span&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;11110&lt;span style=color:#2e8b57&gt;0&lt;/span&gt;&lt;span style=color:sienna&gt;00&lt;/span&gt; 10&lt;span style=color:sienna&gt;01&lt;/span&gt;&lt;span style=color:#00f&gt;1111&lt;/span&gt; 10&lt;span style=color:green&gt;0100&lt;/span&gt;&lt;span style=color:red&gt;00&lt;/span&gt; 10&lt;span style=color:red&gt;00&lt;/span&gt;&lt;span style=color:purple&gt;1110&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;110110&lt;span style=color:#c71585&gt;00&lt;/span&gt; &lt;span style=color:#c71585&gt;00&lt;/span&gt;&lt;span style=color:#00f&gt;1111&lt;/span&gt;&lt;span style=color:green&gt;01&lt;/span&gt; 110111&lt;span style=color:green&gt;00&lt;/span&gt; &lt;span style=color:red&gt;0000&lt;/span&gt;&lt;span style=color:purple&gt;1110&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;A lógica do UTF-16 para code points acima de 0x010000 é:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;U = code point&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;W1 = 2 bytes superiores&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;W2 = 2 bytes inferiores&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;W = U - 0x10000 &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;W = yyyyyyyyyyxxxxxxxxxx (20 dígitos binários)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;W1 = 110110yy yyyyyyyy&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;W2 = 110111xx xxxxxxxx&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;-&gt; não há risco de W1 e W2 serem encarados como &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;outros caracteres porque o intervalo possível deles &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;é protegido na tabela Unicode.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=textos-em-bancos-de-dados-sql tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/collation-e-encoding-em-bancos-de-dados/#textos-em-bancos-de-dados-sql class=header-anchor&gt;&lt;span&gt;Textos em bancos de dados SQL&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;CHAR e NCHAR recebem textos de tamanhos fixos; já o VARCHAR e o NVARCHAR aceitam tamanhos variáveis.&lt;/p&gt;&lt;p&gt;NCHAR e NVARCHAR são tipos presentes no SQL Server e o &#39;N&#39; indica que eles armazenam o texto em codificação UTF-16. Já o CHAR e VARCHAR armazenam conforme o encoding da collation do banco.&lt;/p&gt;&lt;p&gt;Na declaração de tipo de coluna, é especificado o tamanho aceito por ela, por exemplo, &lt;code&gt;NVARCHAR(n)&lt;/code&gt;. &lt;em&gt;É muito comum as pessoas pensarem que n é o tamanho em caractéres, mas isso não é verdade.&lt;/em&gt; Para CHAR e VARCHAR, n define o tamanho em bytes; para NCHAR e NVARCHAR, n é o tamanho em pares de bytes (x2).&lt;/p&gt;&lt;h3&gt;Exemplo prático&lt;/h3&gt;&lt;p&gt;Temos dois bancos de dados, um com collation Latin1_General_CI_AS (encoding Windows-1252) e outro com a collation Latin1_General_100_CI_AS_KS_SC_UTF8 (encoding UTF-8). Para cada um deles, vamos comparar o armazenamento entre VARCHAR e NVARCHAR, para textos em alfabeto latino básico, latino estendido, grego e emojis. Segue o script para executar:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Pessoa] (&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;VARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;24&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [NomeUtf16] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;24&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Pessoa] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Pericles&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Pericles&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- latino sem acento&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Péricles&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Péricles&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- latino com acento&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;N&#39;Περικλῆς&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;N&#39;Περικλῆς&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- grego&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;N&#39;美しいキモノ&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;N&#39;美しいキモノ&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- japonês katakana&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;N&#39;Papai Noel 🎅&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;N&#39;Papai Noel 🎅&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;); &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- com emoji&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- o prefixo N é necessário para strings unicode&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Nome], &lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;DATALENGTH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;([Nome]) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [TamanhoEmBytes],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [NomeUtf16], &lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;DATALENGTH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;([NomeUtf16]) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [TamanhoEmBytes]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Pessoa];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DROP&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Pessoa];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Latin1 General CI AS&lt;/h3&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Nome VARCHAR&lt;/th&gt;&lt;th style=text-align:center&gt;Tamanho em bytes&lt;/th&gt;&lt;th style=text-align:center&gt;Nome NVARCHAR&lt;/th&gt;&lt;th style=text-align:center&gt;Tamanho em bytes&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Pericles&lt;/td&gt;&lt;td style=text-align:center&gt;8&lt;/td&gt;&lt;td style=text-align:center&gt;Pericles&lt;/td&gt;&lt;td style=text-align:center&gt;16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Péricles&lt;/td&gt;&lt;td style=text-align:center&gt;8&lt;/td&gt;&lt;td style=text-align:center&gt;Péricles&lt;/td&gt;&lt;td style=text-align:center&gt;16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;?e??????&lt;/td&gt;&lt;td style=text-align:center&gt;8&lt;/td&gt;&lt;td style=text-align:center&gt;Περικλῆς&lt;/td&gt;&lt;td style=text-align:center&gt;16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;??????&lt;/td&gt;&lt;td style=text-align:center&gt;6&lt;/td&gt;&lt;td style=text-align:center&gt;美しいキモノ&lt;/td&gt;&lt;td style=text-align:center&gt;12&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Papai Noel ??&lt;/td&gt;&lt;td style=text-align:center&gt;13&lt;/td&gt;&lt;td style=text-align:center&gt;Papai Noel 🎅&lt;/td&gt;&lt;td style=text-align:center&gt;26&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Podemos perceber que o encoding Windows-1252 não suporta caractéres gregos, japoneses e emojis, que são substituídos por &#39;?&#39;. Apesar disso, consegue atender muito bem palavras latinas, gastando apenas 1 byte por letra, mesmo naquelas com acentos ou cedilhas.&lt;/p&gt;&lt;h3&gt;Latin1 General 100 CI AS KS SC UTF8&lt;/h3&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Nome VARCHAR&lt;/th&gt;&lt;th style=text-align:center&gt;Tamanho em bytes&lt;/th&gt;&lt;th style=text-align:center&gt;Nome NVARCHAR&lt;/th&gt;&lt;th style=text-align:center&gt;Tamanho em bytes&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Pericles&lt;/td&gt;&lt;td style=text-align:center&gt;8&lt;/td&gt;&lt;td style=text-align:center&gt;Pericles&lt;/td&gt;&lt;td style=text-align:center&gt;16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Péricles&lt;/td&gt;&lt;td style=text-align:center&gt;9&lt;/td&gt;&lt;td style=text-align:center&gt;Péricles&lt;/td&gt;&lt;td style=text-align:center&gt;16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Περικλῆς&lt;/td&gt;&lt;td style=text-align:center&gt;17&lt;/td&gt;&lt;td style=text-align:center&gt;Περικλῆς&lt;/td&gt;&lt;td style=text-align:center&gt;16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;美しいキモノ&lt;/td&gt;&lt;td style=text-align:center&gt;18&lt;/td&gt;&lt;td style=text-align:center&gt;美しいキモノ&lt;/td&gt;&lt;td style=text-align:center&gt;12&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Papai Noel 🎅&lt;/td&gt;&lt;td style=text-align:center&gt;15&lt;/td&gt;&lt;td style=text-align:center&gt;Papai Noel 🎅&lt;/td&gt;&lt;td style=text-align:center&gt;26&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Com a collation UTF-8, o campo VARCHAR suportou com sucesso todos os caractéres e teve maior eficiência em geral. O terceiro nome, Περικλῆς, precisou de 17 bytes porque a letra ῆ (unicode 0x1FC6) é do grego antigo e requer 3 bytes em UTF-8. Para japonês katakana, UTF-16 provou-se mais eficiente.&lt;/p&gt;&lt;h2 id=fontes-e-leituras-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/collation-e-encoding-em-bancos-de-dados/#fontes-e-leituras-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e leituras interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://www.charset.org/charsets/windows-1252&gt;Tabela Windows-1252&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://en.wikipedia.org/wiki/UTF-8&gt;Wikipédia - UTF-8&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://en.wikipedia.org/wiki/UTF-16&gt;Wikipédia - UTF-16&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://symbl.cc/pt/unicode-table/ &gt;Tabela Unicode&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://www.unicode.org/emoji/charts/full-emoji-list.html&gt;Emojis Unicode&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://techcommunity.microsoft.com/t5/azure-sql-blog/introducing-utf-8-support-for-azure-sql-database/ba-p/757748&gt;Azure SQL Blog - Introducing UTF-8 support for Azure SQL Database&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-ver16#utf8&quot;&gt;Microsoft Learn - Suporte ao UTF-8 no SQL Server&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Iceberg SQL</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/" />
    <updated>2024-08-14T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/</id>
    <content type="html">&lt;h2 id=introdu%C3%A7%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#introdu%C3%A7%C3%A3o class=header-anchor&gt;&lt;span&gt;Introdução&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A linguagem SQL, em inglês, &lt;em&gt;Structured Query Language&lt;/em&gt;, surgiu pela primeira vez em 1974 e é uma das principais linguagens até hoje, em se tratando de bancos de dados.&lt;/p&gt;&lt;p&gt;O SQL evoluiu muito ao longo dos anos e principalmente nas duas últimas décadas, com novas técnicas de organização de dados, que surgiram diante de novos competidores (NoSQL) e novas necessidades (analytics, data warehouse, computação na nuvem).&lt;/p&gt;&lt;p&gt;Este artigo é uma lista de trapaças do SQL, abordando desde comandos comuns até aqueles raros e com aplicações muito interessantes. Procurei fazer aqui uma lista fácil de entender tanto para iniciantes como para quem já tem familiaridade com a linguagem.&lt;/p&gt;&lt;p&gt;Os exemplos aqui são em Microsoft SQL Server, porém, a maioria deles existe de forma igual ou semelhante em outros bancos de dados, como o PostgreSQL, MySQL e Oracle.&lt;/p&gt;&lt;br&gt;&lt;img alt=&quot;Iceberg de comandos SQL&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_08_sql_iceberg.jpg class=my-4&gt;&lt;br&gt;&lt;p&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#antes-de-come%C3%A7ar&gt;&lt;strong&gt;Antes de começar&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#instala%C3%A7%C3%A3o&gt;Instalação&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#tabelas-de-exemplo&gt;Tabelas de exemplo&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#leituras-e-consultas&gt;&lt;strong&gt;Leituras e consultas&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#select&gt;SELECT&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#left%2C-right%2C-inner-joins&gt;LEFT, RIGHT, INNER JOINS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#views&gt;VIEWS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#group-by%2C-having&gt;GROUP BY, HAVING&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#union%2C-intersect%2C-except&gt;UNION, INTERSECT, EXCEPT&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#subqueries&gt;SUBQUERIES&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#self-join&gt;SELF JOIN&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#cross-join&gt;CROSS JOIN&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#pivot&gt;PIVOT&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#rollup%2C-cube%2C-grouping-sets&gt;ROLLUP, CUBE, GROUPING SETS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#window-function&gt;WINDOW FUNCTION&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#nolock&gt;NOLOCK&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#altera%C3%A7%C3%B5es-de-dados&gt;&lt;strong&gt;Alterações de dados&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#insert%2C-update%2C-delete&gt;INSERT, UPDATE, DELETE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#stored-procedures&gt;STORED PROCEDURES&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#merge&gt;MERGE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#bulk-insert&gt;BULK INSERT&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#forma%C3%A7%C3%A3o-de-tabelas&gt;&lt;strong&gt;Formação de tabelas&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#primary-key%2C-foreign-key&gt;PRIMARY KEY, FOREIGN KEY&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#indexes&gt;INDEXES&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#unique&gt;UNIQUE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#sparse&gt;SPARSE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#columnstore&gt;COLUMNSTORE&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#especiais&gt;&lt;strong&gt;Especiais&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#import-dlls&gt;IMPORT DLLs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#json&gt;JSON&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#applocks&gt;APPLOCKS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#view-execution-plan&gt;VIEW EXECUTION PLAN&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#conclus%C3%B5es-finais&gt;&lt;strong&gt;Conclusões finais&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;br&gt;&lt;h1 id=antes-de-come%C3%A7ar tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#antes-de-come%C3%A7ar class=header-anchor&gt;&lt;span&gt;Antes de começar&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;h2 id=instala%C3%A7%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#instala%C3%A7%C3%A3o class=header-anchor&gt;&lt;span&gt;Instalação&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Para testar os exemplos do artigo, recomendo ter instalados o SQL Server (&lt;a href=&quot;https://go.microsoft.com/fwlink/?LinkID=866662&quot;&gt;download&lt;/a&gt;) e o SQL Server Management Studio (SSMS) (&lt;a href=https://aka.ms/ssmsfullsetup&gt;download&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;Após as instalações, entrar no SSMS e logar na sua instância:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Autenticação do Windows&lt;/li&gt;&lt;li&gt;Nome do servidor: &lt;code&gt;.&lt;/code&gt; (ponto)&lt;/li&gt;&lt;li&gt;Marcar &lt;em&gt;Certificado do Servidor Confiável&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Essas opções podem mudar conforme a configuração durante a instalação.&lt;/p&gt;&lt;p&gt;Depois, escolher um banco de dados no painel esquerdo; se não houver um, clicar com o botão direito do mouse em &lt;em&gt;Bancos de Dados&lt;/em&gt; e criar um.&lt;/p&gt;&lt;p&gt;Para escrever um script SQL, clicar em &lt;em&gt;Nova Consulta&lt;/em&gt;, no menu superior. Para executar, apertar F5 ou clicar em &lt;em&gt;Executar&lt;/em&gt;.&lt;/p&gt;&lt;h2 id=tabelas-de-exemplo tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#tabelas-de-exemplo class=header-anchor&gt;&lt;span&gt;Tabelas de exemplo&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Vamos começar com duas tabelas que vão servir de base para nossos exemplos: tabela &lt;strong&gt;Fruta&lt;/strong&gt; e tabela &lt;strong&gt;Familia&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Tabela &lt;code&gt;[dbo].[Fruta]&lt;/code&gt;:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Id&lt;/th&gt;&lt;th style=text-align:center&gt;Nome&lt;/th&gt;&lt;th style=text-align:center&gt;IdFamília&lt;/th&gt;&lt;th style=text-align:center&gt;Calorias*&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;Côco&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;354&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;Tâmara&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;282&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;Morango&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;32&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;Melancia&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;30&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;Maracujá&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;97&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;6&lt;/td&gt;&lt;td style=text-align:center&gt;Cereja&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;64&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;7&lt;/td&gt;&lt;td style=text-align:center&gt;Abacaxi&lt;/td&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;48&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;8&lt;/td&gt;&lt;td style=text-align:center&gt;Maçã&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;52&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;* Quantidade de calorias por 100g. Fonte: &lt;a href=https://www.mundoboaforma.com.br/tabela-de-calorias-das-frutas/ &gt;Mundo Boa Forma&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Tabela &lt;code&gt;[dbo].[Familia]&lt;/code&gt;:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Id&lt;/th&gt;&lt;th style=text-align:center&gt;Família&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;Arecaceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;Cucurbitaceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;Rosaceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;Passifloraceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;Bromeliaceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;6&lt;/td&gt;&lt;td style=text-align:center&gt;Malvaceae&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Para criá-las, executar o script SQL abaixo no seu banco.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia](&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Id] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; IDENTITY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;PRIMARY KEY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; CLUSTERED&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;64&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Arecaceae&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Cucurbitaceae&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Rosaceae&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Passifloraceae&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Bromeliaceae&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Malvaceae&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta](&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Id] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; IDENTITY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;PRIMARY KEY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; CLUSTERED&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;64&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [IdFamilia] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; FOREIGN KEY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; REFERENCES&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia](Id),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Calorias] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Côco&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;354&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Tâmara&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;282&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Morango&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Melancia&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;30&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Maracujá&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;97&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Cereja&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;64&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Abacaxi&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;48&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Maçã&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;52&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=leituras-e-consultas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#leituras-e-consultas class=header-anchor&gt;&lt;span&gt;Leituras e consultas&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;h2 id=select tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#select class=header-anchor&gt;&lt;span&gt;SELECT&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Obtém dados devolvendo em forma de tabela.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Nome], [Calorias]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Calorias] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 50&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Retorna:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Nome&lt;/th&gt;&lt;th style=text-align:center&gt;Calorias&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Morango&lt;/td&gt;&lt;td style=text-align:center&gt;32&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Melancia&lt;/td&gt;&lt;td style=text-align:center&gt;30&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Abacaxi&lt;/td&gt;&lt;td style=text-align:center&gt;48&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;code&gt;*&lt;/code&gt; significa retornar todas as colunas:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Calorias] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 50&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Id&lt;/th&gt;&lt;th style=text-align:center&gt;Nome&lt;/th&gt;&lt;th style=text-align:center&gt;IdFamilia&lt;/th&gt;&lt;th style=text-align:center&gt;Calorias&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;Morango&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;32&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;Melancia&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;30&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;7&lt;/td&gt;&lt;td style=text-align:center&gt;Abacaxi&lt;/td&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;48&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id=left%2C-right%2C-inner-joins tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#left%2C-right%2C-inner-joins class=header-anchor&gt;&lt;span&gt;LEFT, RIGHT, INNER JOINS&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Entrelaça duas ou mais tabelas com base em colunas de referência; esse entrelaçamento pode ser usado em consultas, inserções, alterações e exclusões.&lt;/p&gt;&lt;p&gt;Aqui vamos focar apenas no INNER JOIN e no LEFT JOIN.&lt;/p&gt;&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;Diferentes tipos de JOINs no SQL&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2024_08_sql_joins.avif type=image/avif&gt;&lt;img alt=&quot;Diferentes tipos de JOINs no SQL&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_08_sql_joins.png&gt;&lt;/picture&gt;&lt;/p&gt;&lt;h3&gt;INNER JOIN&lt;/h3&gt;&lt;p&gt;O &lt;code&gt;INNER JOIN&lt;/code&gt; é uma intersecção perfeita, ou seja, os valores de entrelaçamento devem existir em ambas as tabelas. Se existir em uma linha da tabela X, mas sem linha correspondente em outra tabela Y, a linha da tabela X não é considerada. Exemplo:&lt;/p&gt;&lt;p&gt;Tabela &lt;code&gt;[dbo].[Fruta]&lt;/code&gt;:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Id&lt;/th&gt;&lt;th style=text-align:center&gt;Nome&lt;/th&gt;&lt;th style=text-align:center&gt;&lt;strong&gt;&lt;mark&gt;IdFamília&lt;/mark&gt;&lt;/strong&gt;&lt;/th&gt;&lt;th style=text-align:center&gt;Calorias&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;Morango&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;&lt;mark&gt;3&lt;/mark&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;32&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;Melancia&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;&lt;mark&gt;2&lt;/mark&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;30&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;7&lt;/td&gt;&lt;td style=text-align:center&gt;Abacaxi&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;&lt;mark&gt;5&lt;/mark&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;48&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Tabela &lt;code&gt;[dbo].[Familia]&lt;/code&gt;:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;&lt;strong&gt;&lt;mark&gt;Id&lt;/mark&gt;&lt;/strong&gt;&lt;/th&gt;&lt;th style=text-align:center&gt;Família&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;&lt;mark&gt;2&lt;/mark&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;Cucurbitaceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;&lt;mark&gt;3&lt;/mark&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;Rosaceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;&lt;mark&gt;5&lt;/mark&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;Bromeliaceae&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Comando SQL:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    fr.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Nome],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    fa.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Família]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] fr&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INNER JOIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] fa &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[IdFamilia] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fa.[Id]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[Calorias] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 50&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Retorna:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Nome&lt;/th&gt;&lt;th style=text-align:center&gt;Família&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Morango&lt;/td&gt;&lt;td style=text-align:center&gt;Rosaceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Melancia&lt;/td&gt;&lt;td style=text-align:center&gt;Cucurbitaceae&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Abacaxi&lt;/td&gt;&lt;td style=text-align:center&gt;Bromeliaceae&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;LEFT / RIGHT JOIN&lt;/h3&gt;&lt;p&gt;O &lt;code&gt;LEFT JOIN&lt;/code&gt; e o &lt;code&gt;RIGHT JOIN&lt;/code&gt; são intersecções imperfeitas, de modo que o valor de referência pode não existir em uma das tabelas; se não existir, então os valores vindos da tabela sem linha correspondente virão nulos.&lt;/p&gt;&lt;p&gt;Nas tabelas acima, a família &lt;em&gt;Malvaceae&lt;/em&gt; (id = 6) não tem nenhuma fruta cadastrada.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    fa.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Família],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    fr.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Fruta]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] fa&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;LEFT JOIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] fr &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[IdFamilia] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fa.[Id]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Família&lt;/th&gt;&lt;th style=text-align:center&gt;Fruta&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Arecaceae&lt;/td&gt;&lt;td style=text-align:center&gt;Côco&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Arecaceae&lt;/td&gt;&lt;td style=text-align:center&gt;Tâmara&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Cucurbitaceae&lt;/td&gt;&lt;td style=text-align:center&gt;Melancia&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Rosaceae&lt;/td&gt;&lt;td style=text-align:center&gt;Morango&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Rosaceae&lt;/td&gt;&lt;td style=text-align:center&gt;Cereja&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Rosaceae&lt;/td&gt;&lt;td style=text-align:center&gt;Maçã&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Passifloraceae&lt;/td&gt;&lt;td style=text-align:center&gt;Maracujá&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Bromeliaceae&lt;/td&gt;&lt;td style=text-align:center&gt;Abacaxi&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Malvaceae&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;code&gt;NULL&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id=views tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#views class=header-anchor&gt;&lt;span&gt;VIEWS&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As VIEWS são consultas encapsuladas: ao invés de executar toda vez uma consulta SQL que é complexa, você pode &quot;apelidar&quot; essa consulta através de uma view, o que simplifica a chamada. Essa técnica é boa para abstrair lógica e para controlar permissões de acesso, por exemplo, um usuário pode chamar a view, mas ficar impedido de acessar as tabelas do banco.&lt;/p&gt;&lt;p&gt;Criação da view:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; OR&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ALTER&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; VIEW [dbo].[ViewObterFrutas] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    fr.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Fruta],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    fa.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Família]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] fr&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  INNER JOIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] fa &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[IdFamilia] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fa.[Id]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para executá-la:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- a view age como se fosse uma tabela&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[ViewObterFrutas]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=group-by%2C-having tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#group-by%2C-having class=header-anchor&gt;&lt;span&gt;GROUP BY, HAVING&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O GROUP BY é uma instrução de agrupamento e o HAVING é um filtro que se aplica a grupos.&lt;/p&gt;&lt;p&gt;As colunas retornadas por um SELECT com agrupamento precisam estar especificadas no GROUP BY, ou então estarem em funções de agregação, como contagens, somas, médias, etc.&lt;/p&gt;&lt;p&gt;Exemplo:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[IdFamilia], &lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;COUNT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(fr.[Id]) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; QuantidadeDeFrutas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] fr&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GROUP BY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[IdFamilia]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;IdFamília&lt;/th&gt;&lt;th style=text-align:center&gt;QuantidadeDeFrutas&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Com inner join e filtro sobre os grupos:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fa.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Família], &lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;COUNT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(fr.[Id]) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; QuantidadeDeFrutas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] fr&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INNER JOIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] fa &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[IdFamilia] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fa.[Id]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GROUP BY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fa.[Nome]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;HAVING&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; COUNT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(fr.[Id]) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; -- família c/ 2 ou mais frutas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Família&lt;/th&gt;&lt;th style=text-align:center&gt;QuantidadeDeFrutas&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Arecaceae&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Rosaceae&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id=union%2C-intersect%2C-except tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#union%2C-intersect%2C-except class=header-anchor&gt;&lt;span&gt;UNION, INTERSECT, EXCEPT&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;São operadores de conjuntos (ver &lt;a href=https://brasilescola.uol.com.br/matematica/conjunto.htm&gt;teoria dos conjuntos&lt;/a&gt; na matemática). São diferentes do entrelaçamento que acontece nos JOINS — enquanto que nos JOINS o entrelaçamento é com colunas, nos conjuntos o entrelaçamento é com linhas. Os exemplos abaixo mostram visualmente.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;UNION: Retorna elementos que pertencem a um conjunto &lt;strong&gt;ou&lt;/strong&gt; outro.&lt;/li&gt;&lt;li&gt;INTERSECT: Retorna elementos que pertencem a um conjunto &lt;strong&gt;e&lt;/strong&gt; a outro, ao mesmo tempo.&lt;/li&gt;&lt;li&gt;EXCEPT: Retorna elementos que pertencem a um conjunto, &lt;strong&gt;mas não a&lt;/strong&gt; outro.&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @a &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (X &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @a &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @b &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (X &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @b &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;6&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @a&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;UNION&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; -- INTERSECT, EXCEPT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @b&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;A&lt;/th&gt;&lt;th style=text-align:center&gt;B&lt;/th&gt;&lt;th style=text-align:center&gt;UNION&lt;/th&gt;&lt;th style=text-align:center&gt;INTERSECT&lt;/th&gt;&lt;th style=text-align:center&gt;EXCEPT&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;6&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;6&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;Por que usar um UNION se posso simplesmente escrever &lt;code&gt;WHERE critério1 OR critério2&lt;/code&gt; ?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Às vezes queremos unir linhas vindas de tabelas diferentes:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Tabela1 &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; criterio&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;UNION&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Tabela2 &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; criterio&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;p&gt;O que é UNION ALL?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Na teoria dos conjuntos, um conjunto nunca tem elementos repetidos. Porém, nas consultas em SQL, às vezes queremos que uma união permita duplicações, para isso, usamos UNION ALL ao invés de só UNION.&lt;/p&gt;&lt;h2 id=subqueries tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#subqueries class=header-anchor&gt;&lt;span&gt;SUBQUERIES&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;São consultas que ocorrem dentro de outras. Podem ser úteis em algumas operações mais complexas, porém, sempre que possível, é melhor substituir uma subquery por um join, pois este tem execução mais rápida.&lt;/p&gt;&lt;p&gt;No exemplo abaixo, o nome da família da fruta é obtido através de subquery:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    fr.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Nome],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fa.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] fa &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fa.[Id] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[IdFamilia]) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Família]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] fr&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; fr.[Calorias] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 50&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=self-join tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#self-join class=header-anchor&gt;&lt;span&gt;SELF JOIN&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;É um join de uma tabela consigo mesma. Muito usado para operações em árvores.&lt;/p&gt;&lt;p&gt;Abaixo, temos uma tabela Funcionários, sendo que um funcionário pode ser chefe de outros:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @funcionarios &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (Id &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, Nome &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), IdChefe &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @funcionarios &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Marco&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Antônio&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Fernando&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Luciana&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Fabiana&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  f1.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Funcionário],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  f2.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [SubordinadoA]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @funcionarios f1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;LEFT JOIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @funcionarios f2 &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; f1.[IdChefe] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; f2.[Id]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ORDER BY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; f2.[Id] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ASC&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Funcionário&lt;/th&gt;&lt;th style=text-align:center&gt;SubordinadoA&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Antônio&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;code&gt;NULL&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Fernando&lt;/td&gt;&lt;td style=text-align:center&gt;Antônio&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Luciana&lt;/td&gt;&lt;td style=text-align:center&gt;Antônio&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Fabiana&lt;/td&gt;&lt;td style=text-align:center&gt;Luciana&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Marco&lt;/td&gt;&lt;td style=text-align:center&gt;Luciana&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id=cross-join tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#cross-join class=header-anchor&gt;&lt;span&gt;CROSS JOIN&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;É o produto cartesiano entre tabelas, basicamente, faz todas as combinações possíveis dos elementos de uma com a outra.&lt;/p&gt;&lt;p&gt;Considere duas tabelas, Sorvete e Cobertura, e queremos ver quais são as combinações.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @sorvete &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (Id &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, Nome &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @sorvete &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Morango&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Flocos&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Chocolate&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @cobertura &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (Id &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, Nome &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @cobertura &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Calda de chocolate&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Nozes&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; s.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Sorvete, c.[Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Cobertura&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @sorvete s &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CROSS JOIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @cobertura c&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ORDER BY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; s.[Id] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ASC&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, c.[Id] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ASC&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Sorvete&lt;/th&gt;&lt;th style=text-align:center&gt;Cobertura&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Morango&lt;/td&gt;&lt;td style=text-align:center&gt;Calda de chocolate&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Morango&lt;/td&gt;&lt;td style=text-align:center&gt;Nozes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Flocos&lt;/td&gt;&lt;td style=text-align:center&gt;Calda de chocolate&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Flocos&lt;/td&gt;&lt;td style=text-align:center&gt;Nozes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Chocolate&lt;/td&gt;&lt;td style=text-align:center&gt;Calda de chocolate&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;Chocolate&lt;/td&gt;&lt;td style=text-align:center&gt;Nozes&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id=pivot tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#pivot class=header-anchor&gt;&lt;span&gt;PIVOT&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;Ross pedindo para girar o sofá - Friends&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2024_08_friends_pivot.avif type=image/avif&gt;&lt;img alt=&quot;Ross pedindo para girar o sofá - Friends&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_08_friends_pivot.jpg&gt;&lt;/picture&gt;&lt;/p&gt;&lt;p&gt;A instrução PIVOT é muito interessante. Ela transforma linhas em colunas, ou seja, rotaciona em 90º uma parte da tabela. Ela é muito boa para cruzar duas ou mais colunas de uma mesma tabela.&lt;/p&gt;&lt;p&gt;No exemplo abaixo, temos uma tabela Vendas em que cada linha dela é a quantidade de um produto vendida em um determinado dia. Queremos ver esses dados de uma forma mais clara, transformando as datas de vendas em colunas, e para isso, usaremos o PIVOT.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @vendas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (IdProduto &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, Quantidade &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, DataVenda &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;DATE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @vendas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;52&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-05&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;902&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-05&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;196&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-06&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;212&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-06&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;488&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-07&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;384&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-07&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1121&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-08&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;49&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-08&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;88&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-09&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;12&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-09&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;98&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-09&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [DataVenda], [IdProduto], [Quantidade]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @vendas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) t&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;PIVOT(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;  SUM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;([Quantidade]) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FOR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [DataVenda] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;IN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ([2024-08-05],[2024-08-06],[2024-08-07],[2024-08-08],[2024-08-09])&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; pvt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;IdProduto&lt;/th&gt;&lt;th style=text-align:center&gt;2024-08-05&lt;/th&gt;&lt;th style=text-align:center&gt;2024-08-06&lt;/th&gt;&lt;th style=text-align:center&gt;2024-08-07&lt;/th&gt;&lt;th style=text-align:center&gt;2024-08-08&lt;/th&gt;&lt;th style=text-align:center&gt;2024-08-09&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;196&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;1121&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;49&lt;/td&gt;&lt;td style=text-align:center&gt;12&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;902&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;488&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;88&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;212&lt;/td&gt;&lt;td style=text-align:center&gt;384&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;52&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;98&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;blockquote&gt;&lt;p&gt;E se eu quiser gerar as colunas dinamicamente, sem especificar valores fixos para elas?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Você pode gerar dinamicamente o texto do comando SQL e então rodá-lo. &lt;a href=https://www.sqlshack.com/dynamic-pivot-tables-in-sql-server/ &gt;Este artigo&lt;/a&gt; mostra como fazer isso dentro de uma procedure:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; PROCEDURE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; dbo.GerarBoletinsAlunos&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  @ColunaParaPivotar  &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;255&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  @ListaParaPivotar   &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;255&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;BEGIN&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @SqlStatement &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(MAX)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  SET&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @SqlStatement &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; N&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;    SELECT * FROM (&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;      SELECT [Estudante], [Matéria], [NotaProva]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;      FROM [Notas]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;    ) x&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;    PIVOT (&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;      AVG([NotaProva]) -- média das provas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;      FOR [&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;+&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;@ColunaParaPivotar&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;+&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;      IN (&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;+&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;@ListaParaPivotar&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;+&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;    ) AS pvt&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  EXEC&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(@SqlStatement)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;END&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para executar:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;EXEC&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; dbo.GerarBoletinsAlunos&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;  N&#39;Matéria&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;  N&#39;[Português],[Matemática],[Ciências]&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=rollup%2C-cube%2C-grouping-sets tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#rollup%2C-cube%2C-grouping-sets class=header-anchor&gt;&lt;span&gt;ROLLUP, CUBE, GROUPING SETS&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;São tipos de GROUP BY que analisam também os subgrupos possíveis.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @vendas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (IdProduto &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, Quantidade &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, DataVenda &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;DATE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @vendas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;52&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-05&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;902&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-05&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;196&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-06&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;212&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-06&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;488&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-07&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;384&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;2024-08-07&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [DataVenda], [IdProduto], &lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;SUM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;([Quantidade]) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Quantidade]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @vendas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GROUP BY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ROLLUP&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;([DataVenda],[IdProduto]) &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- CUBE, GROUPING SETS&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;ROLLUP&lt;/h3&gt;&lt;p&gt;Monta subgrupos em pirâmide, da direita para a esquerda na declaração. Ex.: &lt;code&gt;GROUP BY ROLLUP([ColA], [ColB])&lt;/code&gt; vai analisar:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;[ColA], [ColB] (subgrupo de A e B)&lt;/li&gt;&lt;li&gt;[ColA], NULL (subgrupo de A para todos os valores de B)&lt;/li&gt;&lt;li&gt;NULL, NULL (grupo geral)&lt;/li&gt;&lt;/ul&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;DataVenda&lt;/th&gt;&lt;th style=text-align:center&gt;IdProduto&lt;/th&gt;&lt;th style=text-align:center&gt;Quantidade&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-05&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;902&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-05&lt;/td&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;52&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-05&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;954&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-06&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;196&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-06&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;212&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-06&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;408&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-07&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;488&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-07&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;384&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-07&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;872&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;2234&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;CUBE&lt;/h3&gt;&lt;p&gt;Monta todos os subgrupos possíveis. Ex.: &lt;code&gt;GROUP BY CUBE([ColA], [ColB])&lt;/code&gt; gerará:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;[ColA], [ColB] (subgrupo de A e B)&lt;/li&gt;&lt;li&gt;[ColA], NULL (subgrupo de A para todos os valores de B)&lt;/li&gt;&lt;li&gt;NULL, [ColB] (subgrupo de B para todos os valores de A)&lt;/li&gt;&lt;li&gt;NULL, NULL (grupo geral)&lt;/li&gt;&lt;/ul&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;DataVenda&lt;/th&gt;&lt;th style=text-align:center&gt;IdProduto&lt;/th&gt;&lt;th style=text-align:center&gt;Quantidade&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-06&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;196&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;196&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-05&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;902&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-07&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;488&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;1390&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-06&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;212&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-07&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;384&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;596&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-05&lt;/td&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;52&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;52&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;2234&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-05&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;954&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-06&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;408&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-07&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;872&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;GROUPING SETS&lt;/h3&gt;&lt;p&gt;Junta os subgrupos possíveis de cada coluna em análise, mas não cruza colunas entre si. Ex.: &lt;code&gt;GROUP BY GROUPING SETS([ColA], [ColB])&lt;/code&gt; produz:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;[ColA], NULL (subgrupo de A para todos os valores de B)&lt;/li&gt;&lt;li&gt;NULL, [ColB] (subgrupo de B para todos os valores de A)&lt;/li&gt;&lt;/ul&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;DataVenda&lt;/th&gt;&lt;th style=text-align:center&gt;IdProduto&lt;/th&gt;&lt;th style=text-align:center&gt;Quantidade&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;1&lt;/td&gt;&lt;td style=text-align:center&gt;196&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;3&lt;/td&gt;&lt;td style=text-align:center&gt;1390&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;4&lt;/td&gt;&lt;td style=text-align:center&gt;596&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;5&lt;/td&gt;&lt;td style=text-align:center&gt;52&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-05&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;954&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-06&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;408&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;2024-08-07&lt;/td&gt;&lt;td style=text-align:center&gt;NULL&lt;/td&gt;&lt;td style=text-align:center&gt;872&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id=window-function tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#window-function class=header-anchor&gt;&lt;span&gt;WINDOW FUNCTION&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;São funções que atribuem valores olhando para fatias (ou janelas) da tabela. São muito úteis para fazer paginação, por exemplo, em pesquisas de produtos.&lt;/p&gt;&lt;p&gt;É um tema extenso e com várias possibilidades, por isso, não vou entrar em detalhes aqui, contudo, recomendo &lt;a href=https://www.sqlshack.com/use-window-functions-sql-server/ &gt;este artigo&lt;/a&gt; que explica muito bem como as window functions funcionam.&lt;/p&gt;&lt;h2 id=nolock tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#nolock class=header-anchor&gt;&lt;span&gt;NOLOCK&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;NOLOCK, ou READ UNCOMMITTED, é um modo de leitura que, como o nome sugere, ignora locks.&lt;/p&gt;&lt;p&gt;Uma consulta normal usa o nível de isolamento padrão, READ COMMITTED, que lê apenas dados commitados na tabela. Em uma tabela com tráfego intenso (muitas operações simultâneas), uma consulta pode enfrentar problemas de concorrência com inserts, updates e deletes.&lt;/p&gt;&lt;p&gt;Com a opção NOLOCK, a leitura não compete com essas operações. Porém, esse tipo de leitura inclui registros não-commitados, tal que &lt;em&gt;dados inconsistentes podem aparecer nos resultados&lt;/em&gt;. De forma geral, NOLOCK deve ser usado apenas se houver de fato um problema de concorrência, e se eventuais inconsistências forem toleráveis. Um exemplo de uso é a extração de relatórios analíticos.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WITH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOLOCK&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Calorias] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 50&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=altera%C3%A7%C3%B5es-de-dados tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#altera%C3%A7%C3%B5es-de-dados class=header-anchor&gt;&lt;span&gt;Alterações de dados&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;h2 id=insert%2C-update%2C-delete tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#insert%2C-update%2C-delete class=header-anchor&gt;&lt;span&gt;INSERT, UPDATE, DELETE&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Adiciona, modifica e exclui registros em uma tabela.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @pessoas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (Id &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, Nome &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- inserindo com VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @pessoas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Cláudio&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Carolina&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- inserindo com SELECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @pessoas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Josias&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- alterando nome&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;UPDATE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @pessoas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SET&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Nome] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;Cláudia&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Id] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- excluindo pessoa&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DELETE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @pessoas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Nome] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;Josias&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- resultado final&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @pessoas&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=stored-procedures tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#stored-procedures class=header-anchor&gt;&lt;span&gt;STORED PROCEDURES&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;São scripts que aceitam parâmetros e executam ações no banco de dados; podem devolver resultados em tabela e retornar valores.&lt;/p&gt;&lt;p&gt;A procedure abaixo pode ser usada para cadastrar frutas (considerando exemplo &lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#tabelas-de-exemplo&gt;do início&lt;/a&gt;).&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; OR&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ALTER&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; PROCEDURE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[ProcCadastrarFruta]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  @fruta &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  @familia &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  @calorias &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;BEGIN&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  -- verifica se fruta já está cadastrada&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  IF&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; EXISTS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Nome] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @fruta)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  BEGIN&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    RAISERROR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Fruta já cadastrada!&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    RETURN&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;; &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- interromper execução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  END&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  -- cadastra família se não existir&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  IF&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; EXISTS&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Nome] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @familia)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  BEGIN&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (@familia);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  END&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  -- pega o id da família&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @idFamilia &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Id] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Nome] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @familia)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  -- cadastra a fruta&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  INSERT INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;VALUES&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (@fruta, @idFamilia, @calorias);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  RETURN&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 0&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;; &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- tudo certo&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;END&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para executar:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;EXECUTE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[ProcCadastrarFruta]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  @fruta &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;Laranja&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  @familia &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;Rutaceae&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  @calorias &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 37&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=merge tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#merge class=header-anchor&gt;&lt;span&gt;MERGE&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Permite executar simultaneamente inserções, modificações e exclusões, comparando uma tabela de origem com outra de destino. Essa instrução é usada para sincronização entre fontes de dados diferentes. Se as sincronizações são sempre INSERTS, ou sempre UPDATES, usar estas operações específicas resulta em performance melhor.&lt;/p&gt;&lt;p&gt;Também não vou entrar em detalhes aqui, porém, recomendo &lt;a href=https://dirceuresende.com/blog/sql-server-como-utilizar-o-comando-merge-para-inserir-atualizar-e-apagar-dados-com-apenas-1-comando/ &gt;este artigo&lt;/a&gt; para quem interessar.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;MERGE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; target_table &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;USING&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; source_table&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; merge_condition&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHEN&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; MATCHED&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; THEN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; update_statement&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHEN&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; MATCHED&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; THEN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; insert_statement&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHEN&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; MATCHED&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; BY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; SOURCE &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;THEN&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; DELETE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=bulk-insert tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#bulk-insert class=header-anchor&gt;&lt;span&gt;BULK INSERT&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O BULK INSERT é uma inserção em massa de dados vindos de um arquivo, geralmente em formato CSV, XML ou então arquivo posicional (&lt;em&gt;flat file&lt;/em&gt;).&lt;/p&gt;&lt;p&gt;Essa é uma estratégia para mover uma grande quantidade de registros de um lugar para outro, principalmente se forem usados arquivos posicionais, pois eles são muito &quot;sucintos&quot; e têm altas taxas de compressão quando zipados (exemplo: um arquivo posicional de 900MB, quando zipado, pode ser reduzido a 30MB, dependendo do caso).&lt;/p&gt;&lt;p&gt;Considere o arquivo posicional a seguir. Repare que as posições de início de cada campo são sempre as mesmas — nome da fruta (0..16), nome da família (16..32), calorias (32..35):&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;Graviola        Annonaceae      66 &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Mamão Papaya    Caricaceae      46 &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Cambucá         Myrtaceae       66 &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Bacuri          Clusiaceae      105&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Cupuaçu         Malvaceae       49 &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para importar um arquivo com BULK INSERT, recomendo 1) usar um arquivo formatador e 2) inserir primeiro em uma tabela intermediária, pois muitas vezes precisamos polir os dados antes de passar para a tabela final, por exemplo, remover espaços em branco ou converter datas. O arquivo a seguir é um &lt;em&gt;format file&lt;/em&gt; em XML.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;?&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;xml&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; version&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;BCPFORMAT&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xmlns&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;http://schemas.microsoft.com/sqlserver/2004/bulkload/format&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xmlns:xsi&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;	&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;RECORD&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;		&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;FIELD&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; ID&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;F1&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xsi:type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;CharFixed&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; LENGTH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;16&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;/&gt;&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;&amp;lt;!-- Nome da fruta --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;		&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;FIELD&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; ID&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;F2&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xsi:type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;CharFixed&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; LENGTH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;16&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;/&gt;&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;&amp;lt;!-- Nome da família --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;		&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;FIELD&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; ID&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;F3&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xsi:type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;CharFixed&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; LENGTH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;3&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;/&gt;&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;&amp;lt;!-- Calorias --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;		&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;FIELD&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; ID&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;F4&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xsi:type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;CharTerm&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; TERMINATOR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;&#92;r&#92;n&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; MAX_LENGTH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;6&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;/&gt;&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;&amp;lt;!-- Fim de linha --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;	&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;RECORD&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;	&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ROW&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;		&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;COLUMN&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; SOURCE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;F1&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; NAME&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;NomeFruta&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xsi:type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;SQLVARYCHAR&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; LENGTH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;16&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; NULLABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;NO&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;		&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;COLUMN&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; SOURCE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;F2&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; NAME&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;NomeFamilia&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xsi:type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;SQLVARYCHAR&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; LENGTH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;16&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; NULLABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;NO&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;		&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;COLUMN&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; SOURCE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;F3&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; NAME&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;Calorias&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; xsi:type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;SQLINT&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;	&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ROW&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;BCPFORMAT&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para executar um BULK INSERT em SQL:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- tabela temporária&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; #entrada&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(Fruta &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), Família &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;), Calorias &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;BULK &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;INSERT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; #entrada &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;C:&#92;MinhaPasta&#92;arquivo_posicional.txt&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WITH&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  CODEPAGE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;65001&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- codificação UTF-8 com BOM&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  FORMATFILE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;C:&#92;MinhaPasta&#92;arquivo_formatador.xml&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  BATCHSIZE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 4000&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- polimento (remover espaços em branco)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;UPDATE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; #entrada&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SET&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Fruta] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; TRIM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;([Fruta]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    [Família] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; TRIM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;([Família])&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; #entrada&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DROP&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; #entrada&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Confira mais nas documentações oficiais:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql?view=sql-server-ver16&quot;&gt;Comando BULK INSERT&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/sql/relational-databases/import-export/use-a-format-file-to-bulk-import-data-sql-server?view=sql-server-ver16&quot;&gt;Usar um arquivo de formato para importar em massa&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/sql/relational-databases/import-export/xml-format-files-sql-server?view=sql-server-ver16&quot;&gt;Arquivos de formato, em XML&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Exportando arquivos posicionais&lt;/h3&gt;&lt;p&gt;Infelizmente, não existem maneiras práticas de se gerar arquivos diretamente do banco; no caso do SQL Server, há apenas o &lt;em&gt;Import / Export Wizard&lt;/em&gt;, que é uma interface gráfica dentro do SSMS.&lt;/p&gt;&lt;p&gt;Todavia, é possível criar um programa que lê linhas do banco de dados e gera um arquivo posicional a partir delas; pode ser um programa console simples.&lt;/p&gt;&lt;br&gt;&lt;h1 id=forma%C3%A7%C3%A3o-de-tabelas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#forma%C3%A7%C3%A3o-de-tabelas class=header-anchor&gt;&lt;span&gt;Formação de tabelas&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;h2 id=primary-key%2C-foreign-key tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#primary-key%2C-foreign-key class=header-anchor&gt;&lt;span&gt;PRIMARY KEY, FOREIGN KEY&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A chave primária é um identificador exclusivo para cada linha da tabela e determina qual é a principal coluna de pesquisa, estruturando a tabela em uma &lt;a href=https://pt.wikipedia.org/wiki/%C3%81rvore_B&gt;árvore B&lt;/a&gt;; isto torna a leitura muito mais rápida.&lt;/p&gt;&lt;p&gt;Uma chave estrangeira é uma ligação entre a coluna de uma tabela com a chave primária de outra. Isso aumenta a performance dos JOINs entre essas tabelas e serve como validação de entradas, pois um valor só é válido se estiver cadastrado na tabela estrangeira.&lt;/p&gt;&lt;p&gt;Retomando o exemplo do início:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Fruta](&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Id] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; IDENTITY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;PRIMARY KEY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; CLUSTERED&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Nome] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;64&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [IdFamilia] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; FOREIGN KEY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; REFERENCES&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Familia](Id),&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  [Calorias] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=indexes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#indexes class=header-anchor&gt;&lt;span&gt;INDEXES&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;São trilhas adicionais de pesquisa em uma tabela que servem para percorrer ela, em paralelo à chave primária. São úteis em tabelas que terão mais de um critério de busca.&lt;/p&gt;&lt;p&gt;Imagine uma tabela Pessoa, com as colunas Id, CPF e Nome: é comum querermos pesquisar uma pessoa pelo CPF ou pelo nome, porém, essas colunas não são a chave primária, o que torna a pesquisa através desses campos mais lenta. Nesses casos, a pesquisa é feita individualmente registro por registro, na tabela inteira; além disso, é uma comparação textual, e não numérica, porque CPF e nome são textos. Comparações textuais são mais lentas do que as numéricas, como é o caso do Id.&lt;/p&gt;&lt;p&gt;Para melhorar a velocidade de pesquisa, criamos índices. O tipo mais comum de índice é o &lt;em&gt;hash index&lt;/em&gt;, que atribui um número aleatório para cada valor indexado e salva esse número junto à tabela. Sempre que houver uma pesquisa com esse critério, a comparação será numérica e com performance melhor do que verificar cada linha e campo individualmente.&lt;/p&gt;&lt;p&gt;Criação de índice:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- uma coluna&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; INDEX&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; IX_Pessoa_CPF&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Pessoa]([CPF]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- mais de uma coluna&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; INDEX&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; IX_Endereco_CidadeEstadoPais&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;ON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Endereco]([Cidade],[Estado],[País]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=unique tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#unique class=header-anchor&gt;&lt;span&gt;UNIQUE&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;É um tipo especial de &lt;em&gt;constraint&lt;/em&gt; que impede valores repetidos em uma coluna. Na maioria dos bancos de dados, criar uma unique constraint também cria um índice para essa coluna.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Pessoa] (  &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  Id &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; PRIMARY KEY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; CLUSTERED&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  CPF &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;CHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;11&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  Nome &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;64&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;  CONSTRAINT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CT_Unique_Pessoa_CPF &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;UNIQUE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;([CPF])&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=sparse tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#sparse class=header-anchor&gt;&lt;span&gt;SPARSE&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;É um modificador de coluna que otimiza o armazenamento quando há muitos valores nulos.&lt;/p&gt;&lt;p&gt;No armazenamento tradicional, um campo tem um tamanho reservado para ele na linha mesmo quando o valor é nulo, acarretando em desperdício.&lt;/p&gt;&lt;p&gt;Usando colunas esparsas, um campo com valor nulo ocupa zero bytes na linha e campos não-nulos ocupam o tamanho original acrescido de 4 bytes.&lt;/p&gt;&lt;p&gt;Exemplo prático, coluna &lt;code&gt;NVARCHAR(16)&lt;/code&gt; precisa de 32 bytes. Com sparse, se o valor for nulo, ocupará 0 bytes; se for não-nulo, ocupará 36 bytes.&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Percentagem de nulos&lt;/th&gt;&lt;th style=text-align:center&gt;Diferença de tamanho da coluna&lt;br&gt;com SPARSE&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;0%&lt;/td&gt;&lt;td style=text-align:center&gt;+12,5%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;25%&lt;/td&gt;&lt;td style=text-align:center&gt;-15,6%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;75%&lt;/td&gt;&lt;td style=text-align:center&gt;-71,9%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Fórmula matemática: &lt;code&gt;1 - ((T+4)/T) * (1-N)&lt;/code&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;T&lt;/strong&gt; : tamanho original do campo&lt;/li&gt;&lt;li&gt;&lt;strong&gt;N&lt;/strong&gt; : percentagem de nulos&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Se praticamente não houver nulos, não há vantagem em usar colunas esparsas, mas elas economizam armazenamento se a taxa de nulabilidade for média ou alta.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Pessoa] (  &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  Id &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; PRIMARY KEY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; CLUSTERED&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  CPF &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;CHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;11&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  Nome &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;64&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  CorPreferida &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) SPARSE &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=columnstore tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#columnstore class=header-anchor&gt;&lt;span&gt;COLUMNSTORE&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;em&gt;Columnstore&lt;/em&gt; é uma estratégia de armazenamento.&lt;/p&gt;&lt;p&gt;O modo padrão de armazenamento de uma tabela é linear, por linhas, que ficam dentro de páginas. A, B e C são colunas:&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;flowchart TB
  subgraph page[Página]
    direction LR
    subgraph row1[Linha 1]
      direction TB
      A1
      B1
      C1
    end
    subgraph row2[Linha 2]
      direction TB
      A2
      B2
      C2
    end    
    subgraph row3[Linha 3]
      direction TB
      A3
      B3
      C3
    end
end
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No armazenamento colunar, uma página é exclusiva de uma coluna:&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;flowchart TB
  subgraph pageC[Página]
    subgraph columnC[Coluna C]
      direction LR
      C1
      C2
      C3
    end
  end
  subgraph pageB[Página]
    subgraph columnB[Coluna B]
      direction LR
      B1
      B2
      B3
    end
  end  
  subgraph pageA[Página]
    subgraph columnA[Coluna A]
      direction LR
      A1
      A2
      A3
    end
  end
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Qual é a vantagem dessa abordagem? O armazenamento colunar tem compressão por padrão, e se os valores se repetem muito nas colunas, consegue-se reduzir o tamanho de armazenamento.&lt;/p&gt;&lt;p&gt;Veja a seguir como funciona a compressão colunar:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=text-align:center&gt;Coluna sem compressão&lt;/th&gt;&lt;th style=text-align:center&gt;Coluna com compressão&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;A&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;5 x A&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;A&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;2 x B&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;A&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;3 x A&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;A&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;A&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;B&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;B&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;A&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;A&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=text-align:center&gt;A&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Segundo a &lt;a href=&quot;https://learn.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-overview?view=sql-server-ver16&quot;&gt;documentação do SQL Server&lt;/a&gt;, o tamanho de armazenamento pode ser até 10x menor e a velocidade de leitura 10x maior, comparado a um armazenamento linear.&lt;/p&gt;&lt;h3&gt;Quando usar columnstore&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Alto número de repetições de valores na direção vertical.&lt;/li&gt;&lt;li&gt;Baixa cardinalidade (variações possíveis de valores).&lt;/li&gt;&lt;li&gt;Volume grande de dados (mais de 500 mil linhas).&lt;/li&gt;&lt;li&gt;Cargas analíticas: somas, médias, contagens.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Quando não usar columnstore&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Registros que sofrem muitas atualizações e exclusões, pois a compactação é desfeita quando há mudanças.&lt;/li&gt;&lt;li&gt;Registros que são entidades, pois &lt;strong&gt;tabelas columnstore não têm chave primária&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;Contra-indicado se precisar de muitos JOINs com essa tabela.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Clusterizado vs não-clusterizado&lt;/h3&gt;&lt;p&gt;Um índice columnstore &lt;strong&gt;clusterizado&lt;/strong&gt; é quando a tabela usa armazenamento colunar. Um índice columnstore &lt;strong&gt;não-clusterizado&lt;/strong&gt; é quando a tabela usa armazenamento linear e o columnstore é um índice auxiliar, paralelo; essa é uma opção quando se quer os benefícios do columnstore (performance em cargas analíticas) sem perder as propriedades de uma tabela linear (chaves primárias).&lt;/p&gt;&lt;h3&gt;Comando SQL&lt;/h3&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TABLE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[EntradaArquivoFruta](&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;	Fruta &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;	Família &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;	Calorias &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NOT NULL&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;	INDEX&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CCI_EntradaArquivoFruta &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CLUSTERED&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; COLUMNSTORE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;h1 id=especiais tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#especiais class=header-anchor&gt;&lt;span&gt;Especiais&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;h2 id=import-dlls tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#import-dlls class=header-anchor&gt;&lt;span&gt;IMPORT DLLs&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Sim, é possível importar DLLs para executar no SQL Server.&lt;/p&gt;&lt;p&gt;DLLs customizadas podem ser interessantes no SQL para casos em que não há funcionalidade nativa, como: ler e escrever arquivos no sistema; efetuar chamadas HTTP; gerar e validar &lt;em&gt;hashes&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;As DLLs precisam estar em .NET Framework e serem assinadas com um &lt;em&gt;strong name&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;O processo é um pouco complexo e me baseei &lt;a href=https://www.c-sharpcorner.com/article/assembly-in-ms-sql-server/ &gt;neste artigo&lt;/a&gt; do C-Sharp Corner. Seguem os passos:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Criar um projeto Class Library em .NET Framework&lt;/li&gt;&lt;li&gt;Exemplo de código C# abaixo:&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;namespace&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; MinhaLibDotnetSql&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; static&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; class&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Class1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;        public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; static&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; double&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; CalcularHipotenusa&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;double&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; cateto1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;double&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; cateto2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;            Math&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Sqrt&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Math&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Pow&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;cateto1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;+&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; Math&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Pow&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;cateto2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start=3&gt;&lt;li&gt;No Visual Studio, clicar com o botão direito do mouse no projeto, &lt;em&gt;Propriedades&lt;/em&gt;, &lt;em&gt;Assinatura&lt;/em&gt;, marcar &lt;strong&gt;Assinar o assembly&lt;/strong&gt;. Escolher ou gerar um arquivo de chave de nome forte. Se for criar, pode desmarcar &lt;em&gt;Proteger o arquivo de chaves com senha&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Compilar o projeto.&lt;/li&gt;&lt;li&gt;Agora, precisamos importar a chave assimétrica de assinatura, criar um login no banco &lt;code&gt;master&lt;/code&gt; e conceder permissão de UNSAFE ASSEMBLY para ele:&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;USE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [master]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ASYMMETRIC&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; KEY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ChaveAssimetrica1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; EXECUTABLE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FILE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;C:&#92;Projetos&#92;MinhaLibDotnetSql&#92;bin&#92;Debug&#92;MinhaLibDotnetSql.dll&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; LOGIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; LoginChaveAssimetrica1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ASYMMETRIC&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; KEY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ChaveAssimetrica1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GRANT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; UNSAFE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ASSEMBLY&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; LoginChaveAssimetrica1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start=6&gt;&lt;li&gt;No seu banco de dados de aplicação, criar um usuário para o login anterior, importar o assembly e habilitar a execução de código CLR:&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;USE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [SeuBancoDB];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; USER&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; UserLoginChaveAssimetrica1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FOR&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; LOGIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; LoginChaveAssimetrica1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ASSEMBLY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; AssemblyMinhaLib&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;C:&#92;Projetos&#92;MinhaLibDotnetSql&#92;bin&#92;Debug&#92;MinhaLibDotnetSql.dll&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WITH&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; PERMISSION_SET&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; SAFE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;sp_configure &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;clr enabled&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;RECONFIGURE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start=7&gt;&lt;li&gt;Vamos agora criar uma FUNCTION que executa o código da DLL:&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;USE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [SeuBancoDB];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- para string, usar parâmetro NVARCHAR&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FUNCTION&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[CalcularHipotenusa] (@cateto1 &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FLOAT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, @cateto2 &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FLOAT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;RETURNS&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FLOAT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  EXTERNAL&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; NAME&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [AssemblyMinhaLib].[MinhaLibDotnetSql.Class1].[CalcularHipotenusa];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start=8&gt;&lt;li&gt;Para executar a função:&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- retorna 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[CalcularHipotenusa] (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;4&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;as&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Hipotenusa];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- retorna 13&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[CalcularHipotenusa] (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;5&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;12&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;as&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Hipotenusa];&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=json tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#json class=header-anchor&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Para lidar com JSONs no banco de dados.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @json &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NVARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;100&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;{&quot;cidades&quot;: [&quot;Aracaju&quot;, &quot;João Pessoa&quot;, &quot;Maceió&quot;]}&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- retorna 3 linhas com as cidades&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; OPENJSON&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(@json, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;$.cidades&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;-- retorna uma linha com a cidade escolhida&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; JSON_VALUE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(@json, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;$.cidades[1]&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ver mais na &lt;a href=&quot;https://learn.microsoft.com/pt-br/sql/relational-databases/json/json-data-sql-server?view=sql-server-ver16&quot;&gt;documentação completa&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=applocks tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#applocks class=header-anchor&gt;&lt;span&gt;APPLOCKS&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;São trancas de aplicação dentro do banco de dados. São diferentes de locks em linhas de uma tabela.&lt;/p&gt;&lt;p&gt;Podem ser usadas para controle de concorrência, por exemplo, para leitura de mensagens com múltiplos consumidores simultâneos.&lt;/p&gt;&lt;p&gt;As funções no SQL Server são &lt;code&gt;sp_getapplock&lt;/code&gt; e &lt;code&gt;sp_releaseapplock&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Confira mais no artigo sobre &lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#mensagens-em-bancos-de-dados&gt;arquitetura assíncrona sem filas&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=view-execution-plan tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#view-execution-plan class=header-anchor&gt;&lt;span&gt;VIEW EXECUTION PLAN&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O plano de execução detalha quais são as etapas que o banco de dados precisa percorrer para executar um comando ou uma consulta.&lt;/p&gt;&lt;p&gt;No SSMS, basta habilitar a opção &lt;em&gt;Incluir plano de execução&lt;/em&gt; no menu superior para que o plano seja exibido junto com os resultados.&lt;/p&gt;&lt;p&gt;Ao analisar o custo de cada etapa, você pode entender quais são os gargalos de performance e a partir daí implementar melhorias, tais como criar índices, refazer os critérios de WHERE e JOIN nas consultas, entre outras.&lt;/p&gt;&lt;img alt=&quot;Plano de execução SQL&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_08_sql_execution_plan.jpg class=my-4&gt;&lt;br&gt;&lt;h1 id=conclus%C3%B5es-finais tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/08/iceberg-sql/#conclus%C3%B5es-finais class=header-anchor&gt;&lt;span&gt;Conclusões finais&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;img alt=&quot;Jack e Rose no Titanic&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_08_titanic.jpg class=my-4&gt;&lt;p&gt;O SQL é uma ferramenta extremamente poderosa e completa, e adquiriu novas capacidades ao longo dos anos. Não é à toa que é o &lt;em&gt;mainstream&lt;/em&gt; de banco de dados até hoje — ele é a base de desenvolvimento de sistemas complexos.&lt;/p&gt;&lt;p&gt;Esse artigo cobriu funções comuns e desconhecidas do SQL, e ainda assim existem inúmeras outras que poderiam ser abordadas aqui e com aplicações na vida real, por isso, vale a pena &quot;fuçar&quot; a documentação do seu banco de dados, pois muitas vezes ela tem a resposta para o desafio que você tem.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Shiki e Mermaid no 11ty</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/" />
    <updated>2024-07-16T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/</id>
    <content type="html">&lt;h2 id=11ty%2C-shiki-e-mermaid tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#11ty%2C-shiki-e-mermaid class=header-anchor&gt;&lt;span&gt;11ty, Shiki e Mermaid&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O &lt;a href=https://www.11ty.dev/ &gt;11ty&lt;/a&gt; (Eleventy) é um gerador de sites estáticos que usa templates. Ele tem uma pipeline de execução que torna fácil adicionar plug-ins e transformações a arquivos HTML, JS e CSS.&lt;/p&gt;&lt;p&gt;O &lt;a href=https://shiki.style/ &gt;Shiki&lt;/a&gt; é um pacote npm que renderiza blocos de código HTML com coloração de sintaxe de acordo com a linguagem do código. Dentre suas vantagens, ele permite temas duais (que alternam entre claro e escuro), notações de código com diferenças e foco, e temas customizados.&lt;/p&gt;&lt;p&gt;Neste post, vamos ver como integrar o Shiki e diagramas &lt;a href=https://mermaid.js.org&gt;Mermaid&lt;/a&gt; em um projeto 11ty.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#integrando-com-o-shiki&gt;Integrando com o Shiki&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#integrando-com-o-mermaid&gt;Integrando com o Mermaid&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#resultados-finais&gt;Resultados finais&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#bot%C3%B5es-para-copiar-c%C3%B3digo&gt;Botões para copiar código&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=integrando-com-o-shiki tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#integrando-com-o-shiki class=header-anchor&gt;&lt;span&gt;Integrando com o Shiki&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;h3&gt;Adicionar o Shiki ao projeto&lt;/h3&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;npm&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; install&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -D&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; shiki&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Plug-in para o Shiki&lt;/h3&gt;&lt;p&gt;Criar um arquivo Javascript para configuração do Shiki no seu projeto, por exemplo, no caminho &lt;code&gt;./shiki.config.mjs&lt;/code&gt; (vamos fazer usando ES Modules). O &lt;code&gt;highlighter&lt;/code&gt; deve ser usado preferencialmente como um singleton.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;import&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; { &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;createHighlighter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; } &lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;from&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;shiki&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;export&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; default&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;options&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // empty call to notify 11ty that we use this feature&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // eslint-disable-next-line no-empty-function&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;amendLibrary&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;md&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, () &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; { });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;on&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;eleventy.before&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;async&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; () &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;    const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; highlighter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; await&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; createHighlighter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;      themes:&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;light-plus&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;dark-plus&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;      langs:&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;html&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;sql&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;xml&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;javascript&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;amendLibrary&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;md&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mdLib&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;      mdLib&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;set&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;        highlight&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;:&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;code&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;lang&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;          return&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; highlighter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;codeToHtml&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;code&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;          {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;            lang:&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; lang&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;            themes:&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;              light:&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;light-plus&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;              dark:&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;dark-plus&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;          });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;      })&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Chamar plug-in do Shiki no &lt;code&gt;eleventy.config.mjs&lt;/code&gt;&lt;/h3&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes has-diff&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;import&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; shikiPlugin&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; from&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;./shiki.config.mjs&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;export&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; default&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // substituir plug-in de syntax highlight padrão do 11ty&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff remove&quot;&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;addPlugin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;syntaxHighlight&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;addPlugin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;shikiPlugin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=integrando-com-o-mermaid tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#integrando-com-o-mermaid class=header-anchor&gt;&lt;span&gt;Integrando com o Mermaid&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Se você quer usar o Shiki e também quer ter diagramas Mermaid, é necessário alterar o plug-in do Shiki para renderizar blocos Mermaid como divs HTML, ao invés de blocos de código.&lt;/p&gt;&lt;h3&gt;Adicionar o htmlencode ao projeto&lt;/h3&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;npm&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; install&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -D&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; htmlencode&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Modificar o plug-in do Shiki&lt;/h3&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes has-diff&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;import&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; { &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;createHighlighter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; } &lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;from&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;shiki&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;import&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; htmlencode&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; from&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;htmlencode&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;export&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; default&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;options&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // empty call to notify 11ty that we use this feature&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // eslint-disable-next-line no-empty-function&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;amendLibrary&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;md&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, () &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; { });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;on&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;eleventy.before&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;async&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; () &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;    const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; highlighter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; await&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; createHighlighter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;      themes:&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;light-plus&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;dark-plus&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;      langs:&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;html&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;sql&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;xml&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;javascript&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;amendLibrary&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;md&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mdLib&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;      mdLib&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;set&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;        highlight&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;:&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;code&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;lang&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;          if&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;lang&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; ===&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;mermaid&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;            const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; extra_classes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; options&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;extra_classes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; ?&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39; &#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; +&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; options&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;extra_classes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; :&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;            return&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; `&amp;lt;div class=&quot;mermaid&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A73A1&gt;${&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;extra_classes&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A73A1&gt;}&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;&gt;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A73A1&gt;${&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;htmlencode&lt;/span&gt;&lt;span style=color:#000000FF;--shiki-dark:#AFAC7C&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;htmlEncode&lt;/span&gt;&lt;span style=color:#000000FF;--shiki-dark:#AFAC7C&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;code&lt;/span&gt;&lt;span style=color:#000000FF;--shiki-dark:#AFAC7C&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A73A1&gt;}&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&amp;lt;/div&gt;`&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;          } &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;          else&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; { &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;            return&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; highlighter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;codeToHtml&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;code&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;              lang:&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; lang&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;              themes:&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;                light:&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;light-plus&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;                dark:&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;dark-plus&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;              }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;          } &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;      })&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Plug-in para o Mermaid&lt;/h3&gt;&lt;p&gt;Criar um arquivo Javascript para configuração do Mermaid no seu projeto, por exemplo, no caminho &lt;code&gt;./mermaid.config.mjs&lt;/code&gt; (vamos fazer usando ES Modules):&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;export&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; default&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;options&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;  let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; mermaid_config&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;    startOnLoad:&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; false&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;    theme:&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;default&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#71B0D3&gt;    loadOnSave:&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  };&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;  let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; src&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; options&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;?.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mermaid_js_src&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; ||&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;https://unpkg.com/mermaid/dist/mermaid.esm.min.mjs&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;addShortcode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;mermaid_js_scripts&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, () &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    return&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; `&amp;lt;script type=&quot;module&quot; async&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;              import mermaid from &quot;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A73A1&gt;${&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;src&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A73A1&gt;}&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;              const config = &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A73A1&gt;${&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt;JSON&lt;/span&gt;&lt;span style=color:#000000FF;--shiki-dark:#AFAC7C&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;stringify&lt;/span&gt;&lt;span style=color:#000000FF;--shiki-dark:#AFAC7C&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mermaid_config&lt;/span&gt;&lt;span style=color:#000000FF;--shiki-dark:#AFAC7C&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A73A1&gt;}&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;              mermaid.initialize(config);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;              await mermaid.run({&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;                querySelector: &#39;.mermaid&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;              });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;            &amp;lt;/script&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;  return&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Chamar plug-in do Mermaid no &lt;code&gt;eleventy.config.mjs&lt;/code&gt;&lt;/h3&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes has-diff&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;import&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; shikiPlugin&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; from&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;./shiki.config.mjs&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;import&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; mermaidPlugin&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; from&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;./mermaid.config.mjs&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;export&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; default&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;addPlugin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;shikiPlugin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;  eleventyConfig&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;addPlugin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mermaidPlugin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;  // ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Incluir script do Mermaid nas páginas&lt;/h3&gt;&lt;p&gt;Adicionar o shortcode &lt;code&gt;mermaid_js_scripts&lt;/code&gt; nas páginas e templates que vão ter diagramas:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;{% mermaid_js_scripts %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=resultados-finais tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#resultados-finais class=header-anchor&gt;&lt;span&gt;Resultados finais&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Vamos ver funcionando.&lt;/p&gt;&lt;p&gt;Bloco de código SQL com coloração de sintaxe:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; INTO&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; dbo.NewProducts&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Production.Product&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ListPrice &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&gt;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 25&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AND&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; ListPrice &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 100&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Diagrama de fluxo do Mermaid:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;flowchart TD&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;    A[Christmas] --&gt;|Get money| B(Go shopping)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;    B --&gt; C{Let me think}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;    C --&gt;|One| D[Laptop]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;    C --&gt;|Two| E[iPhone]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;    C --&gt;|Three| F[fa:fa-car Car]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;flowchart TD
    A[Christmas] --&gt;|Get money| B(Go shopping)
    B --&gt; C{Let me think}
    C --&gt;|One| D[Laptop]
    C --&gt;|Two| E[iPhone]
    C --&gt;|Three| F[fa:fa-car Car]
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Se quiser conferir um exemplo completo de código para este blog, visite nosso &lt;a href=https://github.com/alexandrehtrb/alexandrehtrb.github.io&gt;repo no GitHub&lt;/a&gt;. Lá você encontra como alternar entre tema claro e escuro, tanto para o Shiki como para o Mermaid.&lt;/p&gt;&lt;h2 id=bot%C3%B5es-para-copiar-c%C3%B3digo tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#bot%C3%B5es-para-copiar-c%C3%B3digo class=header-anchor&gt;&lt;span&gt;Botões para copiar código&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O Shiki não provê de fábrica botões para copiar código, porém, podemos adicioná-los através de um script do lado do cliente. Aqui, usaremos uma versão modificada do exemplo &lt;a href=https://junges.dev/2-how-to-add-github-copy-to-clipboard-button-on-your-docsblog&gt;deste post de blog&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Referenciar o script nos templates&lt;/h3&gt;&lt;p&gt;Adicionar a tag &lt;code&gt;&amp;lt;script&gt;&lt;/code&gt; abaixo nos templates e arquivos HTML:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;script&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; src&lt;/span&gt;&lt;span style=color:#000000FF;--shiki-dark:#AFAC7C&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;/assets/scripts/addCopyCodeButtons.js&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;script&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Script para adicionar botões de copiar código&lt;/h3&gt;&lt;p&gt;Vamos criar um script de lado de cliente que vai pegar todos os blocos de código e inserir botões de copiar neles. Os ícones estão declarados em linha neste exemplo, como SVGs.&lt;/p&gt;&lt;p&gt;Exemplo de arquivo no caminho &lt;code&gt;src/scripts/addCopyCodeButtons.js&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; blocks&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; document&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;querySelectorAll&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;pre.shiki&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; copyCodeIconSvg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;&amp;lt;svg height=&quot;16&quot; viewBox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; width=&quot;16&quot;&gt;&amp;lt;path fill=&quot;#666666&quot; d=&quot;M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z&quot;&gt;&amp;lt;/path&gt;&amp;lt;path fill=&quot;#666666&quot; d=&quot;M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z&quot;&gt;&amp;lt;/path&gt;&amp;lt;/svg&gt;&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; codeCopiedIconSvg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;&amp;lt;svg height=&quot;16&quot; viewBox=&quot;0 0 16 16&quot; version=&quot;1.1&quot; width=&quot;16&quot;&gt;&amp;lt;path fill=&quot;#28D751&quot; d=&quot;M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z&quot;&gt;&amp;lt;/path&gt;&amp;lt;/svg&gt;&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;blocks&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;forEach&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;((&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;block&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    if&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;!&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;navigator&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;clipboard&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        return&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; document&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;createElement&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;button&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;className&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;button-copy-code&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ariaLabel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;title&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Copiar&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;innerHTML&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; copyCodeIconSvg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    block&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;appendChild&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;addEventListener&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;click&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;async&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; () &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;=&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        await&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; copyCode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;block&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;async&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; function&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; copyCode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;block&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; copiedCode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; block&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;cloneNode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;true&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    copiedCode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;removeChild&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;copiedCode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;querySelector&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;button.button-copy-code&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;    const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; html&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; copiedCode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;outerHTML&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;replace&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#811f3f;--shiki-dark:#9C4444&gt;/&amp;lt;&lt;/span&gt;&lt;span style=color:#d16969;--shiki-dark:#AC6E56&gt;[^&lt;/span&gt;&lt;span style=color:#811f3f;--shiki-dark:#AD4F4F&gt;&gt;&lt;/span&gt;&lt;span style=color:#d16969;--shiki-dark:#AC6E56&gt;]&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#AF955D&gt;*&lt;/span&gt;&lt;span style=color:#811f3f;--shiki-dark:#9C4444&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#AF955D&gt;?&lt;/span&gt;&lt;span style=color:#811f3f;--shiki-dark:#9C4444&gt;/&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;gm&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    block&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;querySelector&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;button.button-copy-code&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;).&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;innerHTML&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; codeCopiedIconSvg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ariaLabel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;title&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Copiado!&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;    setTimeout&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;function&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        block&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;querySelector&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;button.button-copy-code&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;).&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;innerHTML&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; copyCodeIconSvg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ariaLabel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; button&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;title&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Copiar&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;2000&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;    const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; parsedHTML&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; htmlDecode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;html&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    await&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; navigator&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;clipboard&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;writeText&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;parsedHTML&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;function&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; htmlDecode&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;input&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;    const&lt;/span&gt;&lt;span style=color:#0070c1;--shiki-dark:#65A5C7&gt; doc&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt; new&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; DOMParser&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;().&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;parseFromString&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;input&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;text/html&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;    return&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; doc&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;documentElement&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;textContent&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;CSS para os botões de copiar código&lt;/h3&gt;&lt;p&gt;O CSS abaixo controla a posição e visibilidade dos botões:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#998558&gt;pre&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;[&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt;class&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;*=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;shiki&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#e50000;--shiki-dark:#62A6CA&gt;  position&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#0451a5;--shiki-dark:#AD7159&gt;relative&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#e50000;--shiki-dark:#62A6CA&gt;  margin&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;5&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#85A574&gt;px&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 0&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#e50000;--shiki-dark:#62A6CA&gt;  padding&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1.75&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#85A574&gt;rem&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 0&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1.75&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#85A574&gt;rem&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#85A574&gt;rem&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#998558&gt;pre&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; &gt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#B69D69&gt; .button-copy-code&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#e50000;--shiki-dark:#62A6CA&gt;  position&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#0451a5;--shiki-dark:#AD7159&gt;absolute&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#e50000;--shiki-dark:#62A6CA&gt;  top&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;32&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#85A574&gt;px&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#e50000;--shiki-dark:#62A6CA&gt;  right&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#85A574&gt;px&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;@media&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; only&lt;/span&gt;&lt;span style=color:#0451a5;--shiki-dark:#AD7159&gt; screen&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; and&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#62A6CA&gt;max-device-width&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;480&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#85A574&gt;px&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#998558&gt;  pre&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; &gt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#B69D69&gt; .button-copy-code&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#e50000;--shiki-dark:#62A6CA&gt;    display&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#0451a5;--shiki-dark:#AD7159&gt;none&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=refer%C3%AAncias tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/07/shiki-e-mermaid-no-11ty/#refer%C3%AAncias class=header-anchor&gt;&lt;span&gt;Referências&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://www.11ty.dev/docs/ &gt;11ty docs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://shiki.style/guide/ &gt;Shiki docs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://mermaid.js.org/intro/ &gt;Mermaid docs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://junges.dev/2-how-to-add-github-copy-to-clipboard-button-on-your-docsblog&gt;Junges.dev - How to add GitHub Copy to Clipboard button on your docs/blog&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Arquitetura assíncrona sem filas</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/" />
    <updated>2024-06-24T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/</id>
    <content type="html">&lt;img alt=&quot;Fila de pessoas para comprar ingresso para show do Paul McCartney&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_06_fila_ingressos_paul_mccartney.jpg&gt;&lt;h2 id=arquitetura-ass%C3%ADncrona tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#arquitetura-ass%C3%ADncrona class=header-anchor&gt;&lt;span&gt;Arquitetura assíncrona&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Uma estratégia comum em sistemas complexos é o assincronismo, que é deixar tarefas mais pesadas rodando em segundo plano e apenas quando elas forem acabadas receber um retorno delas. A idéia é entregar uma resposta mais imediata ao usuário, permitindo que ele possa fazer outras atividades enquanto isso. Essa abordagem existe tanto nas próprias linguagens de programação, por exemplo, através das palavras-chaves &lt;code&gt;async / await&lt;/code&gt;, como também em arquitetura de sistemas, com um processamento orientado a mensagens ou eventos.&lt;/p&gt;&lt;p&gt;Existem filas dedicadas que são muito populares atualmente, como Apache Kafka e RabbitMQ, que são usadas para processamento assíncrono. Elas podem lidar com altos volumes de mensagens recebidas e processadas em paralelo, tratando também de concorrência de leitura e confirmação pós-processamento.&lt;/p&gt;&lt;p&gt;Apesar da popularidade dessas filas, outras alternativas mais leves e práticas podem ser utilizadas em substituição, resolvendo os mesmos problemas de maneira mais simples e até mais barata. Vamos conhecê-las.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#mensagens-em-bancos-de-dados&gt;Mensagens em bancos de dados&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#mensagens-em-caches-distribu%C3%ADdos&gt;Mensagens em caches distribuídos&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#threads-paralelas&gt;Threads paralelas&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=mensagens-em-bancos-de-dados tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#mensagens-em-bancos-de-dados class=header-anchor&gt;&lt;span&gt;Mensagens em bancos de dados&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Aqui, um banco de dados guarda as mensagens. Há uma aplicação publicadora, que insere as mensagens no banco, e outra consumidora, que as lê.&lt;/p&gt;&lt;p&gt;Neste caso, as mensagens ficam persistidas e não correm risco de perdas por reinicializações. Tanto bancos SQL como NoSQL podem ser usados.&lt;/p&gt;&lt;p&gt;Como exemplo, podemos ter uma tabela em um banco de dados SQL que armazena as mensagens:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;| Id |      Status      | Conteudo |&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;|----|------------------|----------|&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;|  1 | Processada       |   msg1   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;|  2 | Processada       |   msg2   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;|  3 | FalhaAoProcessar |   msg3   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;|  4 | EmProcessamento  |   msg4   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;|  5 | Aguardando       |   msg5   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;|  6 | Aguardando       |   msg6   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A coluna &lt;code&gt;Status&lt;/code&gt; serve como controle de quais mensagens já foram e quais ainda precisam ser processadas. Pelo menos quatro status devem existir:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Aguardando processamento&lt;/li&gt;&lt;li&gt;Em processamento&lt;/li&gt;&lt;li&gt;Falha ao processar&lt;/li&gt;&lt;li&gt;Processada&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;O status &lt;em&gt;FalhaAoProcessar&lt;/em&gt; é muito importante, pois ele permite que os desenvolvedores analisem as mensagens com esse status a fim de identificar possíveis bugs de processamento e mensagens que vêm inválidas ou mal-formatadas.&lt;/p&gt;&lt;p&gt;Aqui, se houver mais de um consumidor simultâneo, devemos nos precaver contra concorrências de leitura, para evitar que uma mensagem seja processada mais de uma vez. A solução para isso é uma tranca.&lt;/p&gt;&lt;h3&gt;Tranca no banco de dados&lt;/h3&gt;&lt;p&gt;Uma tranca (mutex) restringe um acesso enquanto uma rotina detiver a posse dessa tranca.&lt;/p&gt;&lt;p&gt;Quando um consumidor for pegar a próxima mensagem para processar, ele deve trancar para leitura, para impedir que outros consumidores peguem a mesma mensagem que ele ao mesmo tempo. Se não conseguiu abrir a tranca, é porque outro consumidor chegou antes, assim, deve esperar a tranca ser liberada.&lt;/p&gt;&lt;p&gt;Durante o trancamento, a mensagem é obtida e marcada como &lt;em&gt;EmProcessamento&lt;/em&gt;, e após isso, é liberada a leitura por outros consumidores.&lt;/p&gt;&lt;p&gt;Essa técnica existe em vários bancos de dados:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;SQL Server&lt;/strong&gt;: &lt;code&gt;sp_getapplock&lt;/code&gt; com &lt;code&gt;sp_releaseapplock&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;: &lt;code&gt;pg_advisory_xact_lock()&lt;/code&gt; com &lt;code&gt;SET LOCAL lock_timeout = &#39;4s&#39;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;MongoDB&lt;/strong&gt;: &lt;code&gt;db.coll.findAndModify()&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;O código abaixo é uma stored procedure em SQL Server que pega a próxima mensagem a ser lida usando uma tranca de aplicação (&lt;em&gt;app lock&lt;/em&gt;).&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;CREATE&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; OR&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ALTER&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; PROCEDURE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; PegarMensagemParaProcessar&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    @status &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;VARCHAR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;30&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;AS&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;BEGIN&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TRANSACTION&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @res &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    -- trancando para leitura&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    EXEC&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @res &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sp_getapplock                 &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;         @Resource &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;TRANCA_PEGAR_MENSAGEM&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;         @LockMode &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;Exclusive&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;         @LockOwner &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;Transaction&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;         @LockTimeout &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 60000&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;         @DbPrincipal &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;public&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    -- verifica se obteve a tranca&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    IF&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @res &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;NOT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; IN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    BEGIN&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        RAISERROR&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&#39;Não foi possível trancar para leitura.&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;16&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    END&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    ELSE&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    BEGIN&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;      -- obtendo uma mensagem com o status que queremos&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;      DECLARE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @msgId &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;INT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SELECT&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; TOP&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Id] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Mensagens] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Status] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @status);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;      -- marcando a mensagem com status &#39;EmProcessamento&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;      UPDATE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Mensagens] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;SET&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Status] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;EmProcessamento&#39;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Id] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @msgId;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;      -- retornando a mensagem para leitura&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;      SELECT&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; *&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; FROM&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [dbo].[Mensagens] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;WHERE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; [Id] &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @msgId;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;      -- liberando a tranca após leitura  &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;      EXEC&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; @res &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; sp_releaseapplock &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;           @Resource &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;TRANCA_PEGAR_MENSAGEM&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;           @DbPrincipal &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;public&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;           @LockOwner &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;Transaction&#39;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    END&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;COMMIT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;GO&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;O consumidor deve executar o comando SQL:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;EXECUTE&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; PegarMensagemParaProcessar @status &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &#39;Aguardando&#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Invocação&lt;/h3&gt;&lt;p&gt;Não há como o banco de dados proativamente invocar um consumidor, alertando este que há uma nova mensagem a ser processada. Assim, outras formas de acionamento devem ser usadas, como o consumidor periodicamente verificar se há novas mensagens; ou então &lt;em&gt;cron jobs&lt;/em&gt;, que agendam a execução do consumidor em certos horários do dia.&lt;/p&gt;&lt;h2 id=mensagens-em-caches-distribu%C3%ADdos tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#mensagens-em-caches-distribu%C3%ADdos class=header-anchor&gt;&lt;span&gt;Mensagens em caches distribuídos&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Caches distribuídos, como o Redis, podem armazenar mensagens, que podem ficar dentro de pares chave-valor, filas e outras estruturas de dados.&lt;/p&gt;&lt;p&gt;Esta implementação pode ser considerada uma variação da apresentada acima.&lt;/p&gt;&lt;p&gt;Uma vantagem é que a implementação de filas vem de fábrica, poupando esforço de desenvolvimento.&lt;/p&gt;&lt;p&gt;Porém, como desvantagem, as mensagens podem ser perdidas em caso de reinicialização do cache, pois não há persistência (por ser um armazenamento volátil).&lt;/p&gt;&lt;p&gt;Exemplo de fila usando comandos do Redis:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# insere ao fim da fila&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;LPUSH&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; minha_fila&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Tarefa1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# insere ao fim da fila&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;LPUSH&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; minha_fila&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Tarefa2&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# tira primeiro da fila: &quot;Tarefa1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;RPOP&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; minha_fila&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# tira primeiro da fila: &quot;Tarefa2&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;RPOP&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; minha_fila&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Trancas distribuídas&lt;/h3&gt;&lt;p&gt;Caches distribuídos podem fornecer trancas para evitar concorrência de leitura. A documentação do Redis detalha como implementar uma tranca distribuída de forma segura e considerando múltiplos consumidores.&lt;/p&gt;&lt;h2 id=threads-paralelas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#threads-paralelas class=header-anchor&gt;&lt;span&gt;Threads paralelas&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Esta opção é muito prática quando se quer condensar o processamento em uma mesma aplicação — ela mesma produz e consome a mensagem internamente, em threads separadas.&lt;/p&gt;&lt;p&gt;A comunicação entre as threads de produção e consumo se dá através de filas concorrentes (thread-safe) no código, como os channels, em .NET, ou ConcurrentLinkedQueue, em Java. A thread de consumo deve rodar indefinidamente em plano de fundo, processando mensagens conforme elas chegam na fila.&lt;/p&gt;&lt;p&gt;Alguns cenários reais em que essa opção pode ser boa:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Cadastro de usuários&lt;/strong&gt;: uma API recebe uma chamada para cadastrar um usuário, sendo que diversas etapas são executadas, como verificação de identidade, prevenção anti-fraudes e envio de email de confirmação para o usuário. Essas etapas podem ser leves o suficiente para não necessitarem rodar em uma aplicação apartada.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Logs e métricas&lt;/strong&gt;: na maioria dos programas, o envio de logs e métricas se dá em threads em background.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Devemos levar em conta que esse processamento implica maior consumo de CPU e memória RAM na aplicação e pode competir com outras tarefas dela por esses recursos. Soluções para isso são escalabilidade vertical (aumentar CPU e RAM disponíveis) ou horizontal (distribuir a carga entre outras instâncias).&lt;/p&gt;&lt;h3&gt;Exemplo prático&lt;/h3&gt;&lt;p&gt;O código abaixo é de uma Minimal API do ASP.NET que usa channels para processar mensagens, que são recebidas em um endpoint HTTP e repassadas para um &lt;code&gt;MyMessageProcessor&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Para rodar o programa abaixo:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Ter o &lt;a href=https://dotnet.microsoft.com/ &gt;.NET SDK&lt;/a&gt; instalado na máquina&lt;/li&gt;&lt;li&gt;Criar um projeto Minimal API:&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# linha de comando&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;mkdir&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; MinhaAPIChannels&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;cd&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; ./MinhaAPIChannels/&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;dotnet&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; new&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; web&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ol start=3&gt;&lt;li&gt;Copiar e colar o código abaixo no arquivo &lt;code&gt;Program.cs&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Rodar o projeto, &lt;code&gt;dotnet run&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; System&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Threading&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Channels&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#417EB1&gt;using&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Microsoft&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;AspNetCore&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;Mvc&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;var&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; builder&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; WebApplication&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;CreateBuilder&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;args&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// criando o canal e o processador de mensagens&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;var&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; channel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; Channel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;CreateUnbounded&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessage&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;builder&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Services&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;AddSingleton&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;ChannelWriter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessage&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;channel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Writer&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;builder&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Services&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;AddSingleton&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;ChannelReader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessage&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;channel&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Reader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;builder&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Services&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;AddSingleton&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessageProcessor&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;var&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; app&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; builder&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Build&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;app&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;MapGet&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, () &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;Hello World!&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// endpoint de recebimento de mensagens:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// GET /message?content=minha_mensagem_aqui&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;app&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;MapGet&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;/message&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;    async&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    (&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        [&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;FromQuery&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; &quot;content&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)] &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;?&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; content&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        [&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;FromServices&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;] &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ILogger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;MyMessage&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&gt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        [&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;FromServices&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;] &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;ChannelWriter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;MyMessage&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&gt;&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; channelWriter&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    ) =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;LogInformation&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Mensagem recebida: {content}&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;content&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;        await&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; channelWriter&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;WriteAsync&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;new&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;content&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        return&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; Results&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Ok&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// necessário para iniciar o processamento&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;var&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; msgProcessor&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; app&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Services&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;GetService&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessageProcessor&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msgProcessor&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;!&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;IniciarProcessamento&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;app&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// classe da mensagem&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; sealed&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; record&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; MyMessage&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;string&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;? &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Content&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// classe do processador&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; sealed&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt; class&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; MyMessageProcessor&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    private&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; readonly&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ILogger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessageProcessor&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    private&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; readonly&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; ChannelReader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessage&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;channelReader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; MyMessageProcessor&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;ILogger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessageProcessor&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;                              ChannelReader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessage&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;&gt; &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;channelReader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C79AC&gt;        this&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C79AC&gt;        this&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;channelReader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; =&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; channelReader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    public&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; void&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; IniciarProcessamento&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;        // inicia thread em background &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;        // para processar mensagens&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        Task&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Factory&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;StartNew&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;async&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; () &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;=&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;            await&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; foreach&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3E79AA&gt;var&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; msg&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; in&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; channelReader&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ReadAllAsync&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;())&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;                await&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; ProcessarMensagemAsync&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        }, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;TaskCreationOptions&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;LongRunning&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt;    private&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3C7AAD&gt; async&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Task&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; ProcessarMensagemAsync&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt;MyMessage&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;LogInformation&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Mensagem em processamento: {content}&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Content&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;        // operações aqui&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#4183B9&gt;        await&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; Task&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;Delay&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;3000&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;        logger&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;LogInformation&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;(&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;Mensagem processada: {content}&quot;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;, &lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;msg&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;.&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;Content&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para testar, basta ir no navegador Web e acessar a URL &lt;code&gt;http://localhost:{porta}/message?content=minha_mensagem_aqui&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;video controls src=https://alexandrehtrb.github.io/assets/videos/posts/2024_06_dotnet_channels_pt.mp4&gt;&lt;/video&gt;&lt;/p&gt;&lt;h2 id=crit%C3%A9rios-de-an%C3%A1lise tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#crit%C3%A9rios-de-an%C3%A1lise class=header-anchor&gt;&lt;span&gt;Critérios de análise&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Para decidir se uma arquitetura assíncrona é recomendada para seu caso, considere:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;O usuário precisa receber uma resposta imediata?&lt;/li&gt;&lt;li&gt;Uma mensagem individual demora muito tempo para processar?&lt;/li&gt;&lt;li&gt;Uma mensagem individual gasta muita CPU e memória para processar?&lt;/li&gt;&lt;li&gt;As mensagens podem ser processadas em lotes (várias juntas de uma vez)?&lt;/li&gt;&lt;li&gt;O volume de mensagens é alto?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Várias respostas positivas acima indicam que ela é adequada.&lt;/p&gt;&lt;p&gt;Para escolher qual implementação usar, pergunte-se:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;O processamento precisa ser iniciado de imediato?&lt;/li&gt;&lt;li&gt;A ordem de processamento importa?&lt;/li&gt;&lt;li&gt;Existe prioridade de mensagens?&lt;/li&gt;&lt;li&gt;Pode haver mais de um consumidor paralelo?&lt;/li&gt;&lt;li&gt;A eventual perda de uma mensagem seria tolerável?&lt;/li&gt;&lt;li&gt;Se uma mensagem for perdida, como recuperá-la?&lt;/li&gt;&lt;li&gt;Se uma mensagem for inválida ou improcessável, como tratá-la?&lt;/li&gt;&lt;li&gt;Se uma mensagem foi processada parcialmente, a retentativa causaria problemas?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As perguntas acima podem te ajudar a decidir qual estratégia de assincronia é a melhor para seu cenário.&lt;/p&gt;&lt;h2 id=fontes-e-links-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/arquitetura-assincrona-sem-filas/#fontes-e-links-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e links interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://g1.globo.com/pop-arte/noticia/2011/04/no-rio-fas-fazem-fila-para-comprar-ingressos-de-show-de-mccartney.html&gt;No Rio, fãs fazem fila para comprar ingressos do show de McCartney (11/04/2011)&lt;/a&gt; (imagem inicial)&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.sqlteam.com/articles/application-locks-or-mutexes-in-sql-server-2005&gt;Application Locks (or Mutexes) in SQL Server 2005&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://aarniala.fi/blog/postgres-advisory-locks/ &gt;Application-level locking with Postgres advisory locks&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://stackoverflow.com/a/20963803&gt;Stack Overflow - Controlling duration of PostgreSQL lock waits&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.mongodb.com/community/forums/t/locking-documents-in-mongo/6865&gt;Locking Documents In Mongo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://redis.io/glossary/redis-queue/ &gt;Glossário do Redis - Queue&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://redis.io/docs/latest/develop/use/patterns/distributed-locks/ &gt;Documentação do Redis - Distributed Locks&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://www.macoratti.net/20/12/net_chanel1.htm&gt;.NET Core - Apresentando a classe Channel&lt;t&gt;&lt;/t&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://learn.microsoft.com/pt-br/dotnet/core/extensions/channels&gt;Documentação do .NET - Canais&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html&gt;Documentação do Java - ConcurrentLinkedQueue&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Introdução a programação funcional</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/" />
    <updated>2024-06-05T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/</id>
    <content type="html">&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;Le Chiffre, 007 Casino Royale&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2024_06_cassino_royale_le_chiffre.avif type=image/avif&gt;&lt;img alt=&quot;Le Chiffre, 007 Casino Royale&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_06_cassino_royale_le_chiffre.jpg&gt;&lt;/picture&gt;&lt;/p&gt;&lt;h2 id=paradigmas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/#paradigmas class=header-anchor&gt;&lt;span&gt;Paradigmas&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Um paradigma é uma maneira de se pensar, de se observar e de se descrever algo ou um raciocínio; é um modelo mental, no qual nos baseamos para entender as coisas ao nosso redor. Cada pessoa tem um jeito próprio de enxergar o mundo e isso se reflete nas coisas que ela faz e produz.&lt;/p&gt;&lt;p&gt;Em programação, um código pode ser escrito de múltiplas formas e com resultados equivalentes — ou seja, o conceito de paradigmas se aplica.&lt;/p&gt;&lt;p&gt;Existem alguns paradigmas de programação que são os mais difundidos, entre eles:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Programação imperativa&lt;/strong&gt;: Aqui, o programa é organizado em &lt;em&gt;ordens&lt;/em&gt;: &quot;faça isto&quot;, &quot;faça aquilo&quot;, &quot;se isso, então faça mais isso&quot;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Programação orientada a objetos (POO)&lt;/strong&gt;: O foco é em &lt;em&gt;quem (ou o quê)&lt;/em&gt; realiza uma ação. Cada objeto é um ator responsável por uma ação, e pode chamar outros objetos para realizarem outras ações.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Programação funcional (PF)&lt;/strong&gt;: Neste paradigma, o modelo é em torno de &lt;em&gt;como se juntam&lt;/em&gt; as ações. Elas se encaixam como em uma linha de montagem, em que o fim de uma etapa desemboca no início da etapa seguinte, e no fim há um produto pronto.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=um-pouco-sobre-pf tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/#um-pouco-sobre-pf class=header-anchor&gt;&lt;span&gt;Um pouco sobre PF&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A programação funcional tem origem na matemática de funções.&lt;/p&gt;&lt;p&gt;Funções matemáticas podem ser compostas, tal que a saída de uma função é entrada de outra. Por exemplo:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;f(x) = 3x + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;g(x) = 2x&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;// composições&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;f ○ g (x) = f(g(x)) = 3(2x) + 1 = 6x + 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;g ○ f (x) = g(f(x)) = 2(3x + 1) = 6x + 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;O mesmo raciocínio se aplica na programação funcional: o retorno de um método é freqüentemente usado como valor de entrada para outro. O exemplo concreto abaixo mostra funções compostas na linguagem F#.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;module&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Program &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; f&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;+&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; g&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;x&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; fg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; g &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; f &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// f(g(x)), saída de g é entrada de f&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; gf&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; f &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; g &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// g(f(x)), saída de f é entrada de g&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt; [&amp;lt;EntryPoint&gt;]&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; main _ &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        printfn &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;f(1) = &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;%d&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;f&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        printfn &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;g(1) = &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;%d&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;g&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        printfn &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;fg(1) = &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;%d&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;fg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        printfn &lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;gf(1) = &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;%d&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt;&quot;&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;gf&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;        0&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // vai printar:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // f(1) = 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // g(1) = 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // fg(1) = 7&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // gf(1) = 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=quando-usar-programa%C3%A7%C3%A3o-funcional tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/#quando-usar-programa%C3%A7%C3%A3o-funcional class=header-anchor&gt;&lt;span&gt;Quando usar programação funcional&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A PF se destaca em tarefas de natureza matemática. Pense em cálculos de engenharia, de contabilidade, impostos, finanças, calendários e estatísticas. Ela também lida muito bem com categorizações e reconhecimento de padrões.&lt;/p&gt;&lt;p&gt;As áreas de inteligência artificial e aprendizado de máquina necessitam de matemática pesada e portanto podem se beneficiar da programação funcional.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Posso chamar um código funcional em um projeto POO ou imperativo?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Pode! Algumas linguagens orientadas a objeto permitem invocar código de linguagens funcionais, por exemplo, C# pode interagir com F#, e Java pode interagir com Scala.&lt;/p&gt;&lt;h2 id=quando-n%C3%A3o-usar-programa%C3%A7%C3%A3o-funcional tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/#quando-n%C3%A3o-usar-programa%C3%A7%C3%A3o-funcional class=header-anchor&gt;&lt;span&gt;Quando não usar programação funcional&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Para tarefas como envio e recebimento de mensagens, ler e salvar informações em um banco de dados, ou publicação em filas, há poucas vantagens em se optar pela PF, pois a maioria das ações não se entrelaça. Nesses casos, uma linguagem POO ou imperativa normalmente é melhor.&lt;/p&gt;&lt;h2 id=linguagem-f%23 tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/#linguagem-f%23 class=header-anchor&gt;&lt;span&gt;Linguagem F#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Neste artigo, vamos usar a linguagem funcional F# para um estudo de caso. F# usa o &lt;a href=https://dotnet.microsoft.com&gt;&lt;em&gt;runtime&lt;/em&gt; .NET&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Para preparar sua máquina para desenvolver em F#, você vai precisar instalar:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://dotnet.microsoft.com/ &gt;.NET SDK&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://visualstudio.microsoft.com/ &gt;Visual Studio&lt;/a&gt; ou&lt;/li&gt;&lt;li&gt;&lt;a href=https://code.visualstudio.com/ &gt;VS Code&lt;/a&gt; com a extensão &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=faldor20.fsharp-language-server-updated&quot;&gt;F# language server updated&lt;/a&gt; (não usar a extensão do Ionide F#)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Para criar um projeto F# via linha de comando:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;mkdir&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; MeuProjetoFSharp&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;cd&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; ./MeuProjetoFSharp/&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;dotnet&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; new&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; console&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; --language&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; F#&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Antes de começar, algumas dicas de sintaxe:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Declaração de função:&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// note que cada parâmetro tem um par de parênteses.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// a última linha é o retorno da função.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; soma&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;+&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Função anônima / lambda:&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;fun&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;-&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Operador de descarte &lt;code&gt;_&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; minhaTupla&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// só a primeira parte interessa.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// a segunda é descartada `_`&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; _&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; minhaTupla&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Pipelining&lt;/em&gt; &lt;code&gt;|&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; numeros&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; [&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; dobrar&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; incrementar&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;+&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;(*&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;|&gt; significa que o resultado do anterior&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;é o último argumento da próxima função.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;numeros |&gt; Seq.map(incrementar)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;é a mesma coisa que:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;Seq.map(incrementar)(numeros)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;*)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; numerosIncrementadosDobrados&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  numeros &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// 1, 2, 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.map&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;incrementar&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; // 2, 3, 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;  |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.map&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;dobrar&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; // 4, 6, 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=estudo-de-caso%3A-p%C3%B4quer tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/#estudo-de-caso%3A-p%C3%B4quer class=header-anchor&gt;&lt;span&gt;Estudo de caso: pôquer&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;No pôquer, um jogador tem uma mão com cinco cartas de baralho, cada carta definida por um naipe mais uma face. Existem quatro naipes (ouros ♦️, paus ♣️, copas ♥️ e espadas ♠️) e treze faces (2 a 10, valete J, dama Q, rei K, ás A). As cartas da mão podem formar combinações especiais e o jogador que tiver a combinação mais rara vence a rodada do jogo.&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Combinação&lt;/th&gt;&lt;th&gt;Exemplo&lt;/th&gt;&lt;th&gt;Descrição&lt;/th&gt;&lt;th&gt;Chance&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Royal Straight Flush&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;&lt;span style=color:red&gt;A️♦️&lt;/span&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;span style=color:red&gt;K♦️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;Q♦️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;J♦️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;10♦️&lt;/span&gt;️&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Seqüência consecutiva de mesmo naipe, de 10 a ás.&lt;/td&gt;&lt;td&gt;0,000154%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Straight Flush&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;5♣️&lt;/strong&gt;, &lt;strong&gt;6♣️&lt;/strong&gt;,️ &lt;strong&gt;7♣️&lt;/strong&gt;,️ &lt;strong&gt;8♣️&lt;/strong&gt;, &lt;strong&gt;9♣️&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Seqüência consecutiva de mesmo naipe (que não seja a real, acima).&lt;/td&gt;&lt;td&gt;0,00139%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Quadra&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;J♣️&lt;/strong&gt;, &lt;strong&gt;J♠️&lt;/strong&gt;,️ &lt;strong&gt;&lt;span style=color:red&gt;J♦️&lt;/span&gt;️&lt;/strong&gt;️,️ &lt;strong&gt;&lt;span style=color:red&gt;J♥️&lt;/span&gt;️&lt;/strong&gt;️, 2♣️️&lt;/td&gt;&lt;td&gt;Quatro cartas de mesma face.&lt;/td&gt;&lt;td&gt;0,02401%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Full House&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;4♣️&lt;/strong&gt;, &lt;strong&gt;&lt;span style=color:red&gt;4♦️&lt;/span&gt;️&lt;/strong&gt;️,️ &lt;strong&gt;&lt;span style=color:red&gt;10♦️&lt;/span&gt;️&lt;/strong&gt;, &lt;strong&gt;10♣️️&lt;/strong&gt;, &lt;strong&gt;10♠️&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Uma trinca e um par.&lt;/td&gt;&lt;td&gt;0,1441%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Flush&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;&lt;span style=color:red&gt;4♥️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;7♥️&lt;/span&gt;️&lt;/strong&gt;️,️ &lt;strong&gt;&lt;span style=color:red&gt;8♥️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;J♥️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;A♥️&lt;/span&gt;️&lt;/strong&gt;️&lt;/td&gt;&lt;td&gt;Cartas de mesmo naipe, mas sem formar seqüência consecutiva.&lt;/td&gt;&lt;td&gt;0,1965%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Straight&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;&lt;span style=color:red&gt;A♥️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;2♣️&lt;/strong&gt;,️ &lt;strong&gt;&lt;span style=color:red&gt;3♥️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;4♦️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;5♠️&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Seqüência consecutiva de faces, mas com naipes distintos.&lt;/td&gt;&lt;td&gt;0,3925%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Trinca&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;span style=color:red&gt;2♦️&lt;/span&gt;️, K♣️,️ &lt;strong&gt;&lt;span style=color:red&gt;7♦️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;7♣️&lt;/strong&gt;, &lt;strong&gt;7♠️&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Três cartas de faces iguais.&lt;/td&gt;&lt;td&gt;2,1128%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Dois pares&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;&lt;span style=color:red&gt;8♥️&lt;/span&gt;️&lt;/strong&gt;️,️ &lt;strong&gt;&lt;span style=color:red&gt;8♦️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;9♥️&lt;/span&gt;️&lt;/strong&gt;️, &lt;strong&gt;9♠️&lt;/strong&gt;, &lt;span style=color:red&gt;7♥️&lt;/span&gt;️&lt;/td&gt;&lt;td&gt;Dois pares de cartas.&lt;/td&gt;&lt;td&gt;4,7539%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Par&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;span style=color:red&gt;10♦️&lt;/span&gt;️,️ &lt;strong&gt;K♠️&lt;/strong&gt;, &lt;strong&gt;&lt;span style=color:red&gt;K♥️&lt;/span&gt;️&lt;/strong&gt;️, 2♠️, 5♠️&lt;/td&gt;&lt;td&gt;Duas cartas de mesma face.&lt;/td&gt;&lt;td&gt;42,2569%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Carta mais alta&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;span style=color:red&gt;6♦️&lt;/span&gt;️, &lt;span style=color:red&gt;3♦️&lt;/span&gt;️, &lt;strong&gt;&lt;span style=color:red&gt;10♥️&lt;/span&gt;️&lt;/strong&gt;,️ &lt;span style=color:red&gt;7♦️&lt;/span&gt;️, &lt;span style=color:red&gt;2♦️&lt;/span&gt;️&lt;/td&gt;&lt;td&gt;Quando a mão não corresponde a uma das combinações acima.&lt;/td&gt;&lt;td&gt;50,1177%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Domínio de um jogo de pôquer&lt;/h3&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;namespace&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Poker.Domain&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;module&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; PokerGame &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // esta é uma união discriminada&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    type&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Naipe&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Espadas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;|&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Paus &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;|&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Copas &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;|&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Ouros&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // este é um enum&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    type&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Face&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Dois &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Três &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Quatro &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 4&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Cinco &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 5&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seis &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 6&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Sete &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 7&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Oito &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Nove &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 9&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Dez &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 10&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Valete &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 11&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Dama &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 12&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Rei &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 13&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Ás &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 14&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    // isto é uma tupla&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    type&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Carta&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Naipe &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;*&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Face&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    type&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Carta list&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    type&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; CombinacaoMao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; RoyalStraightFlush &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 10&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; StraightFlush &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 9&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Quadra &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; FullHouse &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 7&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Flush &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Straight &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Trinca &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; DoisPares &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Par &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    |&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CartaMaisAlta &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; temStraight&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        mao&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sortBy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;face&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; face&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.pairwise&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.forall&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ((&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;face1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;),&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;face2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;            (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;int face2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;int face1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ||&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;face2 &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Face.Ás &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;&amp;&amp;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; face1 &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Face.Cinco&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; temFlush&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        let&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;umNaipe&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; umaFace&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.head mao&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        mao&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.map &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;naipe&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; naipe&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.forall &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;((=)&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;umNaipe&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; temReiAs&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; temUmRei&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.exists&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;face&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; face &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Face.Rei&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; temUmAs&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.exists&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;face&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; face &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Face.Ás&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        temUmRei &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;&amp;&amp;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; temUmAs&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; obterEmOrdemCrescenteQuantidadesPorFace&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;        mao&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.countBy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; face&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; face&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.sortBy&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; qtdPorFace&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; qtdPorFace&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.map&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(fun&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;_&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; qtdPorFace&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; qtdPorFace&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; Seq.toList&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;    let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; obterCombinacaoMao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; Mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;        match&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; obterEmOrdemCrescenteQuantidadesPorFace&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;mao&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; with&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; [&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 4&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ]&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.Quadra&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; [&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ]&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.FullHouse&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; [&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 3&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ]&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.Trinca&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; [&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ]&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.DoisPares&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; [&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 1&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;;&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 2&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; ]&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.Par&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;        |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; _&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; match&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;temStraight&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;hand&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;),&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; temFlush&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;hand&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;),&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; temReiAs&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;hand&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;))&lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt; with&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;               |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;true&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; true&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; true&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.RoyalStraightFlush&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;               |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;true&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; true&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; false&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.StraightFlush&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;               |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;true&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; false&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; _)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.Straight&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;               |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; (&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;false&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt; true&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;,&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; _)&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.Flush&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;               |&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; _&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt; -&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; CombinacaoMao.CartaMaisAlta&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Em apenas um arquivo, conseguimos descrever a lógica do problema a ser resolvido. Ainda que a sintaxe da linguagem não seja familiar para quem vê pela primeira vez, há um padrão lógico de transformações e comparações nos métodos.&lt;/p&gt;&lt;p&gt;O último método, &lt;code&gt;obterCombinacaoMao&lt;/code&gt;, compara as quantidades de cartas por face para saber se há uma combinação por quantidade (quadras, trincas, full houses, dois pares e pares). Se não houver, então analisa se a combinação é seqüencial e/ou de naipe (straight, flush, straight flush e royal straight flush). Por fim, se não houver correspondência, então é carta mais alta.&lt;/p&gt;&lt;p&gt;Confesso que quando mexi com linguagem funcional pela primeira vez eu achei difícil, um pouco por causa da sintaxe que é bem diferente, e também porque vários exemplos de código na internet usam tipagem implícita, que é menos óbvia de se entender:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// tipagem implícita (inferência)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; soma x y &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;+&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;// declaração mais explícita possível&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;let&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt; soma&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;x&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;)(&lt;/span&gt;&lt;span style=color:#001080;--shiki-dark:#65A5C7&gt;y&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;:&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;):&lt;/span&gt;&lt;span style=color:#267f99;--shiki-dark:#39AC95&gt; int &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;  x &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;+&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Contudo, se você tem alguma situação em que uma abordagem funcional é melhor, digo que vale a pena persistir e aprender, começando com exemplos mais simples e pequenos, e progredir conforme se sentir mais seguro.&lt;/p&gt;&lt;p&gt;O código acima está disponível no &lt;a href=https://github.com/alexandrehtrb/FunctionalPoker/ &gt;GitHub&lt;/a&gt;, com testes unitários e mostrando como integrar um projeto F# com um projeto C#.&lt;/p&gt;&lt;h4&gt;Arquivos fs para compilação&lt;/h4&gt;&lt;p&gt;Se você estiver usando VS Code, sempre que adicionar um arquivo &lt;code&gt;.fs&lt;/code&gt; ao seu projeto, lembre de incluí-lo no &lt;code&gt;.fsproj&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ItemGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;Compile&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; Include&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;Library.fs&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;Compile&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; Include&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;Module2.fs&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;ItemGroup&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=fontes-e-links-interessantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/06/introducao-a-programacao-funcional/#fontes-e-links-interessantes class=header-anchor&gt;&lt;span&gt;Fontes e links interessantes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://www.007.com/focus-of-the-week-le-chiffre/ &gt;Imagem do Le Chiffre, vilão do 007&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://pt.wikipedia.org/wiki/Paradigma&gt;Wikipédia - Paradigma&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://pt.wikipedia.org/wiki/Probabilidade_no_p%C3%B4quer&gt;Wikipédia - Probabilidade no pôquer&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://fsprojects.github.io/fsharp-cheatsheet/ &gt;F# cheatsheet&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://camilotk.github.io/fsharp-by-example/ &gt;F# by example&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=https://fsharpforfunandprofit.com/ &gt;F# for fun and profit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Pipelines para .NET</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/04/pipelines-para-dotnet/" />
    <updated>2024-04-29T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/04/pipelines-para-dotnet/</id>
    <content type="html">&lt;h2 id=pipelines tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/04/pipelines-para-dotnet/#pipelines class=header-anchor&gt;&lt;span&gt;&lt;em&gt;Pipelines&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As esteiras automatizadas, também conhecidas como &lt;em&gt;pipelines&lt;/em&gt;, são seqüências de comandos executados para garantir a integridade do seu código e para gerar um artefato final, como um programa executável ou uma biblioteca.&lt;/p&gt;&lt;p&gt;Ter uma &lt;em&gt;pipeline&lt;/em&gt; significa ter um processo consistente que minimiza o risco de erros humanos no produto final e economiza tempo do programador, pois ele pode se ocupar de outras tarefas enquanto o código é compilado, verificado e empacotado.&lt;/p&gt;&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;Esteira de produção&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2024_04_conveyor_belt.avif type=image/avif&gt;&lt;img alt=&quot;Esteira de produção&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_04_conveyor_belt.jpg&gt;&lt;/picture&gt;&lt;/p&gt;&lt;h2 id=etapas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/04/pipelines-para-dotnet/#etapas class=header-anchor&gt;&lt;span&gt;Etapas&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;flowchart TD
    checkout --&gt;
    clean --&gt; 
    restore --&gt;
    audit --&gt;
    sbom --&gt;
    build --&gt;
    unittests[unit tests]
    unittests --se for programa--&gt; publish --com docker--&gt; dockerk8s[docker / kubernetes]
    publish --sem docker--&gt; zipinstaller[zip / instalador]
    unittests --se for pacote nuget--&gt; pack --&gt; nugetpush[nuget push]
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;checkout&lt;/h3&gt;&lt;p&gt;Obtém o código da branch em questão, no Git. Se for um processo de integração (CI), pega o código da branch que pretende ser mergeada; se for um &lt;em&gt;deploy&lt;/em&gt; (CD), pega o código da branch de publicação, como &lt;em&gt;develop&lt;/em&gt;, &lt;em&gt;master&lt;/em&gt; ou &lt;em&gt;release_candidate&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Linha de comando: &lt;code&gt;git clone&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;clean&lt;/h3&gt;&lt;p&gt;Limpa as pastas &lt;em&gt;bin&lt;/em&gt; e &lt;em&gt;obj&lt;/em&gt;, para garantir que tudo vai começar do zero, sem interferências de compilações anteriores.&lt;/p&gt;&lt;p&gt;Linha de comando: &lt;code&gt;dotnet clean&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;restore&lt;/h3&gt;&lt;p&gt;Garante que as referências entre os projetos na solução estão corretas e faz o download dos pacotes NuGet necessários.&lt;/p&gt;&lt;p&gt;Linha de comando: &lt;code&gt;dotnet restore&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;audit&lt;/h3&gt;&lt;p&gt;Verifica se há algum pacote NuGet do projeto com problemas de segurança, conferindo nas listas de vulnerabilidades &lt;a href=https://cve.mitre.org/ &gt;CVE&lt;/a&gt; (&lt;em&gt;Common Vulnerabilities and Exposures&lt;/em&gt;) e &lt;a href=https://github.com/advisories&gt;GHSA&lt;/a&gt; (&lt;em&gt;GitHub Advisory Database&lt;/em&gt;).&lt;/p&gt;&lt;p&gt;Linha de comando: &lt;code&gt;dotnet list package --vulnerable --include-transitive&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;sbom&lt;/h3&gt;&lt;p&gt;O SBOM, em inglês, &lt;em&gt;software bill of materials&lt;/em&gt;, é um documento que informa quais componentes foram utilizados para a produção de um programa ou biblioteca.&lt;/p&gt;&lt;p&gt;Esse documento é de suma importância para &lt;em&gt;softwares&lt;/em&gt; críticos, pois através dele, as organizações podem facilmente saber quais de suas aplicações estão em perigo quando uma vulnerabilidade em uma biblioteca é reportada. Após o &lt;a href=https://www.eetimes.com/solarwinds-fallout-are-sboms-the-answer/ &gt;ciberataque ao governo dos EUA em 2020&lt;/a&gt;, os SBOMs tornaram-se uma prática endossada pela Casa Branca.&lt;/p&gt;&lt;p&gt;Recomendo o formato &lt;a href=https://github.com/CycloneDX/cyclonedx-dotnet&gt;CycloneDX&lt;/a&gt;, por ser mais sucinto e de leitura mais fácil.&lt;/p&gt;&lt;p&gt;Linha de comando:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Em formato CycloneDX: &lt;code&gt;dotnet CycloneDX&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Em formato SPDX: &lt;code&gt;sbom-tool generate&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;build&lt;/h3&gt;&lt;p&gt;Compila o código da solução.&lt;/p&gt;&lt;p&gt;Linha de comando: &lt;code&gt;dotnet build&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;unit tests&lt;/h3&gt;&lt;p&gt;Roda os testes unitários da solução para assegurar que estão passando.&lt;/p&gt;&lt;p&gt;Nessa etapa, podemos produzir um relatório que exibe o nível de cobertura dos testes unitários em relação ao código, mostrando quais classes, métodos e linhas foram abrangidos pelos testes. O &lt;a href=https://reportgenerator.io&gt;ReportGenerator&lt;/a&gt; é a principal ferramenta para esses relatórios em projetos .NET.&lt;/p&gt;&lt;p&gt;Linha de comando:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Testes unitários: &lt;code&gt;dotnet test&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Relatório de cobertura: &lt;code&gt;reportgenerator&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;publish&lt;/h3&gt;&lt;p&gt;Gera o programa final, voltado para execução. Essa etapa difere do &lt;em&gt;build&lt;/em&gt; porque nesta, pode-se especificar opções de compilação, como o &lt;em&gt;runtime&lt;/em&gt; de destino, se é &lt;em&gt;self-contained&lt;/em&gt;, se é &lt;em&gt;single-file&lt;/em&gt;, entre outras.&lt;/p&gt;&lt;p&gt;Linha de comando: &lt;code&gt;dotnet publish&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;pack&lt;/h3&gt;&lt;p&gt;Produz um pacote NuGet, no caso de um código que é feito para ser uma biblioteca.&lt;/p&gt;&lt;p&gt;Linha de comando: &lt;code&gt;dotnet pack&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;nuget push&lt;/h3&gt;&lt;p&gt;Sobe o pacote para um servidor NuGet, privado ou público, para que possa ser utilizado por outras pessoas.&lt;/p&gt;&lt;p&gt;Linha de comando: &lt;code&gt;dotnet nuget push&lt;/code&gt;&lt;/p&gt;&lt;h2 id=motores-de-pipeline tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/04/pipelines-para-dotnet/#motores-de-pipeline class=header-anchor&gt;&lt;span&gt;Motores de &lt;em&gt;pipeline&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Existem vários motores de &lt;em&gt;pipeline&lt;/em&gt; disponíveis, como o GitHub Actions, GitLab CI, Jenkins, Azure Pipelines, CircleCI e diversos outros.&lt;/p&gt;&lt;p&gt;Além desses, você pode ter sua pipeline como um script para rodar localmente na sua máquina. Essa é uma boa prática por ser uma salvaguarda caso sua pipeline remota esteja fora do ar e porque permite testar modificações antes de commitá-las.&lt;/p&gt;&lt;p&gt;Recomendo pessoalmente usar scripts &lt;a href=https://github.com/PowerShell/PowerShell&gt;PowerShell&lt;/a&gt; para pipelines locais, pois é uma linguagem multiplataforma e amigável, com fácil interação com XML e JSON. Contudo, você pode usar outras linguagens de script, como Batch, Shell, Python e outras que você preferir.&lt;/p&gt;&lt;h2 id=exemplo-em-github-actions-para-programa-.net tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/04/pipelines-para-dotnet/#exemplo-em-github-actions-para-programa-.net class=header-anchor&gt;&lt;span&gt;Exemplo em GitHub Actions para programa .NET&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Publicar console / API / programa desktop&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;on&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;  workflow_dispatch&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# acionamento manual&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    inputs&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      version&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        required&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;string&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      rid&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        required&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        default&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;linux-x64&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; # onde o programa vai rodar&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;string&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;        # https://learn.microsoft.com/en-us/dotnet/core/rid-catalog&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;jobs&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;  gerar_programa&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    runs-on&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;ubuntu-latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    env&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      OUTPUT_FOLDER&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ format(&#39;./out/{0}/&#39;, inputs.rid) }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      VERSION_NAME&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ inputs.version }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      RID&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ inputs.rid }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    steps&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Checkout&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/checkout@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        fetch-depth&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Instalar .NET SDK&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/setup-dotnet@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        dotnet-version&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;8.x&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; # versão do .NET aqui&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Instalar CycloneDX .NET&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet tool install --global CycloneDX&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Limpar solução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet clean --nologo --verbosity quiet&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Restaurar solução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet restore --nologo --verbosity quiet&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Auditar solução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $projectPath = &quot;./src/MeuProjeto.Console/MeuProjeto.Console.csproj&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $jsonObj = (dotnet list $projectPath package --vulnerable --include-transitive --format json) | ConvertFrom-Json;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $hasAnyVulnerability = ($jsonObj.projects[0].frameworks -ne $null);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        if ($hasAnyVulnerability) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;          dotnet list package --vulnerable --include-transitive;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;          exit 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Compilar solução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet build --no-restore --configuration Release --nologo --verbosity quiet&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Rodar testes unitários&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet test --no-build --configuration Release --nologo --verbosity quiet --collect:&quot;XPlat Code Coverage&quot; --results-directory ./TestResults/&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Relatório de cobertura de testes unitários&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;danielpalme/ReportGenerator-GitHub-Action@5.2.4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        reports&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;TestResults/**/coverage.cobertura.xml&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        targetdir&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;TestResults&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        reporttypes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;JsonSummary;Html&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Gerar SBOM&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet CycloneDX ./src/MeuProjeto.Console/MeuProjeto.Console.csproj -o $env:OUTPUT_FOLDER -f sbom.json -sv $env:VERSION_NAME --json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Publicar programa&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        dotnet publish ./src/MeuProjeto.Console/MeuProjeto.Console.csproj `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        --verbosity quiet `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        --nologo `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        --configuration Release `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        -p:PublishSingleFile=true `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        -p:Version=${env:VERSION_NAME} `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        --self-contained true `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        --runtime ${env:RID} `&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        --output ${env:OUTPUT_FOLDER};&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Setar atributos de execução (UNIX apenas)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      if&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ startsWith(inputs.rid, &#39;linux&#39;) || startsWith(inputs.rid, &#39;osx&#39;) }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;chmod +x &quot;${env:OUTPUT_FOLDER}/MeuProjeto.Console&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Empacotar programa&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $zipName = &quot;MeuProjeto.Console_${env:VERSION_NAME}_${env:RID}.zip&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        # se for Linux ou MacOSX, devemos usar o zip ao invés do Compress-Archive,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        # para preservar os atributos de arquivos do Unix.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        if ($IsWindows) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;          Compress-Archive -CompressionLevel Optimal -Path $env:OUTPUT_FOLDER -DestinationPath &quot;./out/${zipName}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        } else {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;          cd $env:OUTPUT_FOLDER&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;          zip -9 -r ../${zipName} *&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;          cd ../..&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        Remove-Item $env:OUTPUT_FOLDER -Force -Recurse -ErrorAction Ignore&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        echo &quot;OUTPUT_FILE_NAME=${zipName}&quot; | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Subir programa para resultados do workflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/upload-artifact@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        compression-level&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; # não precisa comprimir pq passo anterior já comprime&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ env.OUTPUT_FILE_NAME }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        path&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ format(&#39;./out/{0}&#39;, env.OUTPUT_FILE_NAME) }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Subir SBOM para resultados do workflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/upload-artifact@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;sbom.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        path&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;./out/sbom.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Subir relatório de cobertura para resultados do workflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/upload-artifact@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;relatorio_de_cobertura&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        path&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;TestResults&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    # outras etapas subseqüentes podem ser adicionadas aqui,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    # como docker e kubernetes,&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;    # ou geração de instalador, no caso de programas desktop.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=exemplo-em-github-actions-para-pacote-nuget tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/04/pipelines-para-dotnet/#exemplo-em-github-actions-para-pacote-nuget class=header-anchor&gt;&lt;span&gt;Exemplo em GitHub Actions para pacote NuGet&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Publicar pacote NuGet&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#3A6A91&gt;on&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;  workflow_dispatch&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# acionamento manual&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;jobs&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;  gerar_pacote_nuget&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    runs-on&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;ubuntu-latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;    steps&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Checkout&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/checkout@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        fetch-depth&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Instalar .NET SDK&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/setup-dotnet@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        dotnet-version&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;8.x&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; # versão do .NET aqui&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Instalar CycloneDX .NET&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet tool install --global CycloneDX&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Limpar solução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet clean --nologo --verbosity quiet&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Restaurar solução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet restore --nologo --verbosity quiet&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Auditar solução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $projectPath = &quot;./src/MeuProjeto.Console/MeuProjeto.Console.csproj&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $jsonObj = (dotnet list $projectPath package --vulnerable --include-transitive --format json) | ConvertFrom-Json;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $hasAnyVulnerability = ($jsonObj.projects[0].frameworks -ne $null);&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        if ($hasAnyVulnerability) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;          dotnet list package --vulnerable --include-transitive;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;          exit 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Compilar solução&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet build --no-restore --configuration Release --nologo --verbosity quiet&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Rodar testes unitários&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet test --no-build --configuration Release --nologo --verbosity quiet --collect:&quot;XPlat Code Coverage&quot; --results-directory ./TestResults/&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Relatório de cobertura de testes unitários&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;danielpalme/ReportGenerator-GitHub-Action@5.2.4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        reports&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;TestResults/**/coverage.cobertura.xml&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        targetdir&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;TestResults&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        reporttypes&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;JsonSummary;Html&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Ler versão do pacote&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        # o PackageVersion deve estar declarado no .csproj&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        ([XML]$nugetCsprojXml = Get-Content ./src/MeuProjeto.Biblioteca/MeuProjeto.Biblioteca.csproj)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $versionName = $nugetCsprojXml.Project.PropertyGroup.PackageVersion&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        # adiciona às variáveis de ambiente do workflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        echo &quot;VERSION_NAME=${versionName}&quot; | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Gerar SBOM&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet CycloneDX ./src/MeuProjeto.Biblioteca/MeuProjeto.Biblioteca.csproj -o ./out/ -f sbom_meuprojeto_biblioteca.json -sv $env:VERSION_NAME --json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Gerar pacote&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;dotnet pack ./src/MeuProjeto.Biblioteca/MeuProjeto.Biblioteca.csproj --nologo --verbosity quiet --configuration Release&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Subir pacote para servidor NuGet&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      shell&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;pwsh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      run&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#af00db;--shiki-dark:#9C5E97&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        $filePath = &quot;./src/MeuProjeto.Biblioteca/bin/Release/MeuProjeto.Biblioteca.${env:VERSION_NAME}.nupkg&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        dotnet nuget push $filePath --api-key $env:NUGET_API_KEY --source https://api.nuget.org/v3/index.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        # se for um servidor NuGet privado, usar outro source.&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        # portal web para testes do NuGet: https://int.nugettest.org&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;        # source para testes: https://apiint.nugettest.org/v3/index.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      env&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        NUGET_API_KEY&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ secrets.MINHA_NUGET_API_KEY }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Subir pacote para resultados do workflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/upload-artifact@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        compression-level&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt;0&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; # não precisa comprimir pq .nupkg já é um zip&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ format(&#39;MeuProjeto.Biblioteca.{0}.nupkg&#39;, env.VERSION_NAME) }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        path&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;${{ format(&#39;./src/MeuProjeto.Biblioteca/bin/Release/MeuProjeto.Biblioteca.{0}.nupkg&#39;, env.VERSION_NAME) }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Subir SBOM para resultados do workflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/upload-artifact@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;sbom_meuprojeto_biblioteca.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        path&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;./out/sbom_meuprojeto_biblioteca.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;    - &lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;Subir relatório de cobertura para resultados do workflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      uses&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;actions/upload-artifact@v4&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;      with&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        name&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;relatorio_de_cobertura&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;        path&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;: &lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;TestResults&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=fonte-da-imagem tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/04/pipelines-para-dotnet/#fonte-da-imagem class=header-anchor&gt;&lt;span&gt;Fonte da imagem&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=https://dyno.co.nz/products/telescopic-and-expandable-conveyors/telescopic-conveyor/ &gt;https://dyno.co.nz/products/telescopic-and-expandable-conveyors/telescopic-conveyor/&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>HTTP/2 e HTTP/3 explicados
</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/" />
    <updated>2024-03-11T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/</id>
    <content type="html">&lt;p&gt;No início da década de 1990, Tim Berners-Lee e sua equipe no &lt;a href=https://home.cern&gt;CERN&lt;/a&gt; trabalharam juntos para formar a base da World Wide Web, definindo quatro peças-chaves para a rede mundial de computadores:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Um formato de documento para hipertexto (o HTML)&lt;/li&gt;&lt;li&gt;Um protocolo de transmissão de dados (o HTTP)&lt;/li&gt;&lt;li&gt;Um navegador de internet para exibir hipertexto (o primeiro navegador, WorldWideWeb)&lt;/li&gt;&lt;li&gt;Um servidor para transmitir esses dados (uma versão inicial do httpd)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;O HTTP, em questão, aproveitou os protocolos TCP/IP já existentes como meio de transporte de dados. Os bytes de uma mensagem HTTP ficam na &lt;a href=https://pt.wikipedia.org/wiki/Camada_de_aplica%C3%A7%C3%A3o&gt;camada de aplicação&lt;/a&gt;, em azul claro na imagem abaixo.&lt;/p&gt;&lt;img alt=&quot;Modelo OSI&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_03_osi_model_tcp_ip.png&gt;&lt;h2 id=http%2F0.9 tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#http%2F0.9 class=header-anchor&gt;&lt;span&gt;HTTP/0.9&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Foi a primeira versão de rascunho do HTTP. O único método existente era o &lt;code&gt;GET&lt;/code&gt;; não havia cabeçalhos nem status codes; e o único formato possível de resposta era o HTML. Assim como no HTTP/1.0 e no HTTP/1.1, as mensagens HTTP seguiam um formato de texto em ASCII.&lt;/p&gt;&lt;p&gt;Exemplo de requisição HTTP/0.9:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;GET /mypage.html&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Exemplo de resposta:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;&amp;lt;html&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;  A very simple HTML page&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&amp;lt;/html&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=http%2F1.0 tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#http%2F1.0 class=header-anchor&gt;&lt;span&gt;HTTP/1.0&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Esta versão deu ao HTTP a sua estrutura atual, parecida com a de um &lt;a href=https://brasilescola.uol.com.br/redacao/memorando.htm&gt;memorando&lt;/a&gt;, com cabeçalhos e conteúdo, também introduzindo novos métodos (&lt;code&gt;HEAD&lt;/code&gt; e &lt;code&gt;POST&lt;/code&gt;), MIME types, status codes e versionamento do protocolo.&lt;/p&gt;&lt;p&gt;Exemplo de requisição HTTP/1.0:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;GET /mypage.html HTTP/1.0&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Exemplo de resposta:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;200 OK&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Date: Tue, 15 Nov 1994 08:12:31 GMT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Server: CERN/3.0 libwww/2.17&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Content-Type: text/html&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&amp;lt;HTML&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;A page with an image&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;  &amp;lt;IMG SRC=&quot;/myimage.gif&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&amp;lt;/HTML&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=http%2F1.1 tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#http%2F1.1 class=header-anchor&gt;&lt;span&gt;HTTP/1.1&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Esta versão surgiu no início de 1997, poucos meses depois da predecessora. As principais mudanças foram:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Reaproveitamento de conexões TCP (keep-alive), poupando recursos da máquina e de rede. Na versão anterior, uma conexão nova era criada para cada requisição e encerrada logo após a resposta.&lt;/li&gt;&lt;li&gt;Cabeçalho &lt;code&gt;Host&lt;/code&gt;, permitindo que mais de um servidor esteja alocado sob um mesmo IP.&lt;/li&gt;&lt;li&gt;Convenções de cabeçalhos de encoding, cache, idioma e MIME type.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Exemplo de requisição HTTP/1.1:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;GET /api/fruit/orange HTTP/1.1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Host: www.fruityvice.com&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Accept-Encoding: gzip, deflate, br&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Exemplo de resposta:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;HTTP/1.1 200 OK&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Server: nginx/1.16.1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Date: Sun, 10 Mar 2024 20:44:25 GMT&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Transfer-Encoding: chunked&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Connection: keep-alive&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;X-Content-Type-Options: nosniff&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;X-XSS-Protection: 1; mode=block&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Cache-Control: no-store, must-revalidate, no-cache, max-age=0&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Pragma: no-cache&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;X-Frame-Options: DENY&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Content-Type: application/json&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;Expires: 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;{&quot;name&quot;:&quot;Orange&quot;,&quot;id&quot;:2,&quot;family&quot;:&quot;Rutaceae&quot;,&quot;order&quot;:&quot;Sapindales&quot;,&quot;genus&quot;:&quot;Citrus&quot;,&quot;nutritions&quot;:{&quot;calories&quot;:43,&quot;fat&quot;:0.2,&quot;sugar&quot;:8.2,&quot;carbohydrates&quot;:8.3,&quot;protein&quot;:1.0}}&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img alt=&quot;HTTP1 em pacotes TCP&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_03_http1_tcp_packets.png&gt;&lt;h2 id=http%2F2 tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#http%2F2 class=header-anchor&gt;&lt;span&gt;HTTP/2&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Em 2015, após muitos anos de observação e estudos sobre a performance da internet em geral, foi proposto e criado o HTTP/2, uma nova versão, baseada no SPDY do Google.&lt;/p&gt;&lt;p&gt;Dentre as principais mudanças, estão a multiplexação de várias mensagens dentro de um único pacote TCP; formato binário das mensagens; e compressão dos cabeçalhos, com HPACK.&lt;/p&gt;&lt;p&gt;No HTTP/1.1, duas requisições HTTP não podem trafegar juntas em uma mesma conexão TCP — é necessário que a primeira delas termine para que a subseqüente se inicie. Isso se chama bloqueio de cabeça de fila (&lt;em&gt;head-of-line blocking&lt;/em&gt;, em inglês). No diagrama abaixo, a requisição 2 não pode começar até que a resposta 1 tenha chegado, considerando que apenas uma conexão TCP é usada.&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;sequenceDiagram
    Cliente-&gt;&gt;+Servidor: req 1
    Servidor--&gt;&gt;-Cliente: res 1
    Cliente-&gt;&gt;+Servidor: req 2
    Servidor--&gt;&gt;-Cliente: res 2
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Com o HTTP/2, esse problema é resolvido através de &lt;em&gt;streams&lt;/em&gt;: cada &lt;em&gt;stream&lt;/em&gt; corresponde a uma mensagem. Vários &lt;em&gt;streams&lt;/em&gt; podem estar entremeados dentro de um mesmo pacote TCP. Se um &lt;em&gt;stream&lt;/em&gt; não puder emitir dados por algum motivo, outros podem aproveitar e entrar em seu lugar no pacote TCP.&lt;/p&gt;&lt;p&gt;Os &lt;em&gt;streams&lt;/em&gt; são divididos em &lt;em&gt;frames&lt;/em&gt;, cada um contendo: o tipo do &lt;em&gt;frame&lt;/em&gt;, o &lt;em&gt;stream&lt;/em&gt; ao qual pertence, e o comprimento em bytes. No diagrama abaixo, um retângulo colorido é um pacote TCP e um ✉ é um &lt;em&gt;frame&lt;/em&gt; HTTP/2. O primeiro e o terceiro pacotes TCP carregam &lt;em&gt;frames&lt;/em&gt; de &lt;em&gt;streams&lt;/em&gt; diferentes.&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;sequenceDiagram
    rect rgb(239, 190, 125)
        Cliente-&gt;&gt;+Servidor: req1: #9993;1/1&amp;lt;br&gt;+&amp;lt;br&gt;req2: #9993;1/1
    end
    rect rgb(197, 234, 189)
        Servidor--&gt;&gt;Cliente: res1: #9993;1/2
    end
    rect rgb(197, 234, 189)
        Servidor--&gt;&gt;-Cliente: res1: #9993;2/2&amp;lt;br&gt;+&amp;lt;br&gt;res2: #9993;1/1
    end
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A imagem abaixo mostra como os &lt;em&gt;frames&lt;/em&gt; entram em pacotes TCP. O &lt;em&gt;stream&lt;/em&gt; 1 representa uma resposta HTTP de um arquivo JavaScript e o &lt;em&gt;stream&lt;/em&gt; 2 representa uma resposta HTTP de um arquivo CSS, transmitidos via HTTP/2.&lt;/p&gt;&lt;img alt=&quot;Frames HTTP2 em pacotes TCP&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_03_http2_tcp_packets.png&gt;&lt;h2 id=http%2F3 tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#http%2F3 class=header-anchor&gt;&lt;span&gt;HTTP/3&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O HTTP/3 surgiu diante de um novo protocolo de transporte proposto pelo Google, o QUIC, em 2012. O QUIC é encapsulado dentro do UDP, e comparado ao TCP, propõe:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;menos &lt;em&gt;roundtrips&lt;/em&gt; (idas-e-voltas) de pacotes para estabelecimento de conexão e estabelecimento de criptografia TLS;&lt;/li&gt;&lt;li&gt;ter conexões mais resilientes quanto a perda de pacotes;&lt;/li&gt;&lt;li&gt;resolver o bloqueio de cabeça de fila que existe no protocolo TCP e no TLS.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;O HTTP/2 consegue resolver o bloqueio de cabeça de fila relacionado ao HTTP, porém, esse tipo de bloqueio também existe no protocolo TCP e no TLS. O TCP entende que os dados que deve enviar fazem parte de uma seqüência de pacotes contígüos, e se um desses pacotes for perdido, ele deve ser reenviado para o destinatário, a fim de que se preserve a integridade da informação. &lt;em&gt;No TCP, pacotes subseqüentes não podem ser enviados enquanto o pacote perdido não chegar com sucesso no destino.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;O diagrama abaixo explica visualmente como isso ocorre no HTTP/2. O segundo pacote tinha &lt;em&gt;frames&lt;/em&gt; apenas da resposta 1, porém a perda dele atrasa tanto a resposta 1 como a resposta 2 — ou seja, não há paralelismo nesse caso.&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;sequenceDiagram
    rect rgb(239, 190, 125)
        Cliente-&gt;&gt;+Servidor: req1: #9993;1/1&amp;lt;br&gt;+&amp;lt;br&gt;req2: #9993;1/1
    end
    rect rgb(197, 234, 189)
        Servidor--xCliente: res1: #9993;1/2
    end
    Note over Cliente,Servidor: pacote TCP perdido&amp;lt;br&gt;precisa ser reenviado.&amp;lt;br&gt;atrasa tanto res1 como res2
    rect rgb(197, 234, 189)
        Servidor--&gt;&gt;Cliente: res1: #9993;1/2
    end
    rect rgb(197, 234, 189)
        Servidor--&gt;&gt;-Cliente: res1: #9993;2/2&amp;lt;br&gt;+&amp;lt;br&gt;res2: #9993;1/1
    end
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para resolver o bloqueio de cabeça de fila do TCP, o QUIC opta por utilizar o UDP como protocolo de transporte, pois este é um protocolo sem garantias de recebimento. A responsabilidade de garantia de integridade, que no TCP fica na camada de transporte, passa no QUIC para a camada de aplicação, de modo que os &lt;em&gt;frames&lt;/em&gt; de uma mensagem podem chegar fora de ordem, sem bloquear &lt;em&gt;streams&lt;/em&gt; não-relacionados.&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;sequenceDiagram
    rect rgb(255, 179, 217)
        Cliente-&gt;&gt;Servidor: req1: #9993;1/1&amp;lt;br&gt;+&amp;lt;br&gt;req2: #9993;1/1
    end
    rect rgb(179, 205, 230)
        Servidor--xCliente: res1: #9993;1/2
    end
    Note over Cliente,Servidor: pacote QUIC perdido&amp;lt;br&gt;não bloqueia outros pacotes
    rect rgb(179, 205, 230)
        Servidor--&gt;&gt;Cliente: res1: #9993;2/2&amp;lt;br&gt;+&amp;lt;br&gt;res2: #9993;1/1
    end
    Note over Cliente,Servidor: reenvio do pacote perdido.&amp;lt;br&gt;res2 não foi afetado
    rect rgb(179, 205, 230)
        Servidor--&gt;&gt;Cliente: res1: #9993;1/2
    end
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img alt=&quot;Pacotes QUIC HTTP3&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_03_http3_quic_packets.png&gt;&lt;p&gt;O bloqueio de cabeça de fila relacionado ao TLS (criptografia SSL) ocorre no TCP porque a criptografia é geralmente aplicada sobre a mensagem inteira, de modo que todos os seus pacotes precisam chegar ao destino para então ocorrer a decriptação. No caso do QUIC, a criptografia é individual para cada pacote QUIC, que é decriptado na chegada, sem haver a necessidade de receber todos os pacotes primeiro.&lt;/p&gt;&lt;p&gt;TLS com TCP:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Dados de entrada: &lt;code&gt;A+B+C&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Dados encriptados: &lt;code&gt;crypt(A+B+C) = D+E+F&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Pacotes: &lt;code&gt;D, E, F&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Recebimento: &lt;code&gt;decrypt(D+E+F)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;A+B+C&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;TLS com QUIC:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Dados de entrada: &lt;code&gt;A+B+C&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Dados encriptados: &lt;code&gt;crypt(A) = X, crypt(B) = Y, crypt(C) = Z&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Pacotes: &lt;code&gt;X, Y, Z&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Recebimento: &lt;code&gt;decrypt(X) + decrypt(Y) + decrypt(Z)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;A+B+C&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=tabela-de-compara%C3%A7%C3%A3o tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#tabela-de-compara%C3%A7%C3%A3o class=header-anchor&gt;&lt;span&gt;Tabela de comparação&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th style=text-align:center&gt;HTTP/1.1&lt;/th&gt;&lt;th style=text-align:center&gt;HTTP/2&lt;/th&gt;&lt;th style=text-align:center&gt;HTTP/3&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Protocolo&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;de transporte&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;TCP,&lt;br&gt;conexão persistente&lt;/td&gt;&lt;td style=text-align:center&gt;TCP,&lt;br&gt;conexão persistente&lt;/td&gt;&lt;td style=text-align:center&gt;UDP,&lt;br&gt;conexão persistente&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Bloqueio de&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;cabeça de fila&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;(&lt;em&gt;HOL blocking&lt;/em&gt;)&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;HTTP/1.x HOL&lt;br&gt;TCP HOL&lt;br&gt;TLS HOL&lt;/td&gt;&lt;td style=text-align:center&gt;TCP HOL&lt;br&gt;TLS HOL&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Formato das mensagens&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;texto em ASCII&lt;/td&gt;&lt;td style=text-align:center&gt;binário&lt;/td&gt;&lt;td style=text-align:center&gt;binário&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Compressão de cabeçalhos&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;-&lt;/td&gt;&lt;td style=text-align:center&gt;HPACK&lt;/td&gt;&lt;td style=text-align:center&gt;QPACK&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Nº de idas-e-voltas&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;para iniciar&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;(handshakes)&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;br&gt;1 do TCP&lt;br&gt;+2 do TLS 1.2*&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;br&gt;1 do TCP&lt;br&gt;+1 do TLS 1.3*&lt;/td&gt;&lt;td style=text-align:center&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;br&gt;0 do UDP&lt;br&gt;+0 do TLS 1.3 com 0-RTT*&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Identificação de conexão&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;IP e porta de origem&lt;/td&gt;&lt;td style=text-align:center&gt;IP e porta de origem&lt;/td&gt;&lt;td style=text-align:center&gt;connection ID**,&lt;br&gt;resistente a mudanças de IP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Criptografia&lt;/strong&gt;&lt;/td&gt;&lt;td style=text-align:center&gt;não obrigatória;&lt;br&gt;aplicada na mensagem inteira&lt;/td&gt;&lt;td style=text-align:center&gt;não obrigatória;&lt;br&gt;aplicada na mensagem inteira&lt;/td&gt;&lt;td style=text-align:center&gt;TLS 1.3 embutido;&lt;br&gt;aplicada por pacote QUIC&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;* O TLS 1.2 requer 2 &lt;em&gt;roundtrips&lt;/em&gt; para &lt;em&gt;handshake&lt;/em&gt; criptográfico e o TLS 1.3 requer apenas 1, com a opção de 0-RTT (&lt;em&gt;zero roundtrip time resumption&lt;/em&gt;), em que não há necessidade de &lt;em&gt;handshake&lt;/em&gt; prévio. &lt;strong&gt;Porém, o 0-RTT possibilita &lt;a href=https://blog.cloudflare.com/introducing-0-rtt&gt;ataques de replay&lt;/a&gt; e por isso é inseguro. Ele é opcional e pode ser deixado desabilitado.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;** O connection ID do QUIC pode ser usado para &lt;em&gt;fingerprinting&lt;/em&gt;, colocando em risco a privacidade dos usuários, segundo &lt;a href=https://alexandrehtrb.github.io/assets/misc/2024_03_research_A_QUIC_Look_at_Web_Tracking.pdf&gt;pesquisa&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=qual-%C3%A9-a-melhor-vers%C3%A3o%3F tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#qual-%C3%A9-a-melhor-vers%C3%A3o%3F class=header-anchor&gt;&lt;span&gt;Qual é a melhor versão?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;As duas melhores versões atualmente são o HTTP/2 e o HTTP/3.&lt;/p&gt;&lt;p&gt;O HTTP/3 foi desenhado para conexões instáveis, como redes de telefonia celular e de satélite. Para contornar instabilidades de rede, o QUIC tem grande independência dos fluxos de dados e resiliência caso pacotes sejam perdidos. Porém, o HTTP/3 tem desvantagens de performance, em razão de 1) o protocolo UDP não ter sido otimizado pelos sistemas operacionais e roteadores ao longo das últimas décadas, devido ao baixo uso dele em geral, tornando-o comparativamente mais lento do que o TCP; e 2) a criptografia pacote-por-pacote no QUIC requer um número maior de operações matemáticas, tornando-a menos eficiente do que a criptografia de mensagem inteira no TCP. Há ainda o problema de o protocolo UDP (usado pelo QUIC) ser restringido em algumas redes para proteger contra, por exemplo, &lt;a href=https://www.cloudflare.com/learning/ddos/udp-flood-ddos-attack/ &gt;ataque de inundação de UDP&lt;/a&gt; e &lt;a href=https://blog.cloudflare.com/deep-inside-a-dns-amplification-ddos-attack&gt;ataque de amplificação de DNS&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Em conexões confiáveis e plenas, o HTTP/2 muitas vezes oferece performance melhor do que o HTTP/3.&lt;/p&gt;&lt;p&gt;Para evitar o bloqueio de cabeça de fila no HTTP/1.x, muitos navegadores e HTTP clients abrem várias conexões TCP, para que as requisições corram em paralelo. Em cenários com muitas requisições e respostas pesadas em paralelo, essa técnica &lt;em&gt;pode&lt;/em&gt; fazer com que o HTTP/1.x ofereça maior taxa de transferência (&lt;em&gt;throughput&lt;/em&gt;) comparado ao HTTP/2 ou HTTP/3, porém, é uma forma menos eficiente de se resolver o problema. Uma solução alternativa é ter múltiplas conexões HTTP/2-3 ao mesmo tempo (&lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/api/system.net.http.socketshttphandler.enablemultiplehttp2connections?view=net-8.0#system-net-http-socketshttphandler-enablemultiplehttp2connections&quot;&gt;exemplo em C#&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;De modo geral, recomenda-se realizar testes de compatibilidade e de performance para decidir qual é a versão mais indicada, além disso, um servidor pode aceitar conexões tanto de HTTP/2 como de HTTP/3, cabendo ao cliente decidir qual versão usar.&lt;/p&gt;&lt;h2 id=ferramenta-de-testes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#ferramenta-de-testes class=header-anchor&gt;&lt;span&gt;Ferramenta de testes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Recomendo o &lt;a href=https://pororoca.io&gt;Pororoca&lt;/a&gt; (feito por mim 🙂).&lt;/p&gt;&lt;h2 id=bibliografia tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/03/http2-e-http3-explicados/#bibliografia class=header-anchor&gt;&lt;span&gt;Bibliografia&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP&gt;MDN - Evolution of HTTP&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://developer.mozilla.org/en-US/docs/Web/HTTP/Connection_management_in_HTTP_1.x&gt;MDN - Connection management in HTTP/1.x&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://davidwills.us/cmit265/osi.html&gt;David Wills - OSI reference model&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/ &gt;Web Performance Calendar - Head-of-Line Blocking in QUIC and HTTP/3: The Details&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20240311184108/https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/ &gt;WebArchive&lt;/a&gt;) &lt;strong&gt;(leitura recomendada)&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://en.wikipedia.org/wiki/QUIC&gt;Wikipédia - QUIC&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://blog.cloudflare.com/introducing-0-rtt&gt;Cloudflare - Introducing Zero Round Trip Time Resumption (0-RTT)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://http3-explained.haxx.se/en/quic/quic-connections&gt;HTTP/3 explained - QUIC connections&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=https://svs.informatik.uni-hamburg.de/publications/2019/2019-02-26-Sy-PET_Symposium-A_QUIC_Look_at_Web_Tracking.pdf&gt;Erik Sy*, Christian Burkert, Hannes Federrath, and Mathias Fischer - A QUIC Look at Web Tracking&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;script&gt;function afterMermaidRenderCallback(){isDarkMode()&amp;&amp;document.querySelectorAll(&quot;rect.rect&quot;).forEach(t=&gt;{var r=t.getAttribute(&quot;fill&quot;);&quot;rgb(239, 190, 125)&quot;==r?t.setAttribute(&quot;fill&quot;,&quot;rgb(93, 60, 24)&quot;):&quot;rgb(197, 234, 189)&quot;==r?t.setAttribute(&quot;fill&quot;,&quot;rgb(6, 58, 33)&quot;):&quot;rgb(255, 179, 217)&quot;==r?t.setAttribute(&quot;fill&quot;,&quot;rgb(53, 1, 44)&quot;):&quot;rgb(179, 205, 230)&quot;==r&amp;&amp;t.setAttribute(&quot;fill&quot;,&quot;rgb(0, 30, 69)&quot;)})}&lt;/script&gt;</content>
  </entry>
  <entry>
    <title>Formatos de imagem modernos: JXL e AVIF
</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/" />
    <updated>2024-01-28T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/</id>
    <content type="html">&lt;h2 id=computa%C3%A7%C3%A3o%2C-fotografia-e-imagens tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#computa%C3%A7%C3%A3o%2C-fotografia-e-imagens class=header-anchor&gt;&lt;span&gt;Computação, fotografia e imagens&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A visualização de imagens é fundamental em vários setores, como artes plásticas, fotografias profissionais, cartografia, astrofotografia, medicina diagnóstica, preservações históricas e cinema. A qualidade das imagens é muito importante para se notar detalhes, como um toque artístico, uma imprecisão, ou um elemento imperceptível à primeira vista.&lt;/p&gt;&lt;p&gt;Em uma tela de computador, uma imagem é representada por milhares de &lt;em&gt;pixels&lt;/em&gt; (&lt;strong&gt;pic&lt;/strong&gt;ture &lt;strong&gt;el&lt;/strong&gt;ement), cada &lt;em&gt;pixel&lt;/em&gt; correspondendo a uma cor e sua intensidade. Considere uma imagem de tamanho 1.024px x 768px = 786.432 &lt;em&gt;pixels&lt;/em&gt;; se cada pixel for RGBA e tiver 4 &lt;em&gt;bytes&lt;/em&gt;, 1 para vermelho, 1 para verde, 1 para azul e 1 para transparência, essa imagem terá um tamanho de 3,1MB, o que é bastante alto. Contudo, escolhendo técnicas de compressão e um formato de arquivo adequados, podemos ter essa imagem com a mesma qualidade e ocupando muito menos espaço em memória.&lt;/p&gt;&lt;img alt=&quot;Exemplos de imagens de alta resolução&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_01_hires_images_examples.jpg class=my-4&gt;&lt;h2 id=novos-formatos tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#novos-formatos class=header-anchor&gt;&lt;span&gt;Novos formatos&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Por volta de 2019, surgiram no mercado dois novos formatos de arquivo, o JXL e o AVIF, prometendo menor consumo de memória em disco e maior preservação de detalhes.&lt;/p&gt;&lt;p&gt;Ambos compartilham como características:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Compressão com perdas (&lt;em&gt;lossy compression&lt;/em&gt;), ou sem perdas (&lt;em&gt;lossless compression&lt;/em&gt;), mais eficiente do que formatos predecessores, como o JPEG e PNG, e retendo alta definição.&lt;/li&gt;&lt;li&gt;Suporte a animações e transparências.&lt;/li&gt;&lt;li&gt;&lt;em&gt;Open-source&lt;/em&gt; e licença livre de &lt;em&gt;royalties&lt;/em&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;JXL&lt;/h3&gt;&lt;p&gt;O JXL, ou JPEG-XL, começou em 2017 com uma chamada de propostas para um formato de imagem de nova geração. A proposta final foi a junção de duas outras: a PIK, do Google, e a FLIF, da Cloudinary.&lt;/p&gt;&lt;h3&gt;AVIF&lt;/h3&gt;&lt;p&gt;O AVIF é um formato criado pela Alliance for Open Media, um consórcio de várias empresas de tecnologia, como a Netflix, Meta e Google, com o objetivo de formar padrões de mercado para mídia digital. A primeira especificação do AVIF é de 2018.&lt;/p&gt;&lt;h2 id=quando-devo-usar-o-jxl%3F tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#quando-devo-usar-o-jxl%3F class=header-anchor&gt;&lt;span&gt;Quando devo usar o JXL?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O JXL é melhor para:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Imagens de alta e extrema alta resolução e nível de detalhes.&lt;/li&gt;&lt;li&gt;Situações em que a velocidade de processamento é importante, pois o &lt;em&gt;encoding&lt;/em&gt; do JXL é de 5 a 10 vezes mais rápido do que o AVIF.&lt;/li&gt;&lt;li&gt;Altíssima precisão de côres.&lt;/li&gt;&lt;li&gt;&lt;em&gt;Decoding&lt;/em&gt; progressivo: a imagem pode ser visualizada conforme é baixada.&lt;/li&gt;&lt;li&gt;Imagens de dimensões muito grandes, pois suporta tamanhos de mais de 1 bilhão x 1 bilhão de pixels. O AVIF suporta imagens em no máximo 8K (8193px x 4320px).&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=quando-devo-usar-o-avif%3F tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#quando-devo-usar-o-avif%3F class=header-anchor&gt;&lt;span&gt;Quando devo usar o AVIF?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O AVIF é melhor para:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Imagens em páginas Web, pois a maioria dos navegadores suporta AVIF (94%), enquanto que poucos navegadores suportam JXL (15%). Dados obtidos pelo &lt;a href=https://caniuse.com/avif&gt;caniuse&lt;/a&gt; (08/05/2026).&lt;/li&gt;&lt;li&gt;Vídeos e animações, pois tem excelente taxa de compressão para eles, acima de 90% em alguns casos. É um ótimo substituto aos GIFs.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=testes-de-compress%C3%A3o-e-performance tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#testes-de-compress%C3%A3o-e-performance class=header-anchor&gt;&lt;span&gt;Testes de compressão e performance&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Exemplos:&lt;/p&gt;&lt;p&gt;A imagem original abaixo é um JPG de dimensões 8192x5464, com tamanho de 11MB. Em formato JXL (q=90), o tamanho ficou em 7,3MB. Em AVIF (q=90), ficou em 8,3MB.&lt;/p&gt;&lt;img alt=&quot;Escadas-rolantes de uma estação de metrô&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_01_subway_escalators.jpg class=my-4&gt;&lt;p&gt;O GIF original abaixo tem tamanho de 3,1MB. Em formato JXL (q=90), o tamanho ficou em 2,5MB. Em AVIF (q=90), ficou em 79kB. Impressionante!&lt;/p&gt;&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;Emilia Clarke&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2024_01_emilia_clarke.avif type=image/avif&gt;&lt;img alt=&quot;Emilia Clarke&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_01_emilia_clarke.gif&gt;&lt;/picture&gt;&lt;/p&gt;&lt;p&gt;Este repositório no GitHub (&lt;a href=https://github.com/alexandrehtrb/jxl-avif-simple-benchmark&gt;link&lt;/a&gt;) executa testes para comparar as velocidades e taxas de compressão do JXL e do AVIF. A comparação não é qualitativa, nem científica. Como imagens de entrada, estão:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;GIFs animados de alta, média e baixa complexidade.&lt;/li&gt;&lt;li&gt;Fotografias em JPEG de média, alta e altíssima resolução.&lt;/li&gt;&lt;li&gt;Infográficos em PNG e JPEG, para avaliar a compressão de imagens com textos.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=ferramentas tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#ferramentas class=header-anchor&gt;&lt;span&gt;Ferramentas&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Existem sites na internet que podem fazer conversões para AVIF e JXL. Eu recomendo o &lt;a href=https://ezgif.com&gt;ezgif&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;A maioria dos navegadores suporta abrir arquivos &lt;code&gt;.avif&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Para visualizar JXL, há o &lt;a href=https://www.gimp.org/ &gt;GIMP&lt;/a&gt;, o &lt;a href=https://www.irfanview.com/ &gt;Irfanview&lt;/a&gt; e &lt;a href=https://github.com/libjxl/libjxl/blob/main/doc/software_support.md&gt;outros programas&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Conversão para &lt;code&gt;.jxl&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;Para converter uma imagem para JXL, usando a &lt;a href=https://github.com/libjxl/libjxl&gt;ferramenta oficial&lt;/a&gt;:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;cjxl&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; img_entrada.jpg&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; img_saida.jxl&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -q&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 90&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; --lossless_jpeg=0&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Conversão para &lt;code&gt;.avif&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;Há duas ferramentas principais: o &lt;a href=https://github.com/kornelski/cavif-rs&gt;cavif-rs&lt;/a&gt; e o &lt;a href=https://ffmpeg.org/ &gt;ffmpeg&lt;/a&gt;. O cavif-rs atualmente não suporta GIFs, então para estes devemos usar o ffmpeg.&lt;/p&gt;&lt;p&gt;Para converter uma imagem estática para AVIF, usando o cavif-rs:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;cavif&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; img_entrada.jpg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -o&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; img_saida.avif&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -Q&lt;/span&gt;&lt;span style=color:#098658;--shiki-dark:#84967A&gt; 90&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -f&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Para converter uma GIF para AVIF usando o ffmpeg, você precisará também da &lt;a href=https://github.com/AOMediaCodec/libavif&gt;libavif&lt;/a&gt;.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# sudo apt install ffmpeg&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# sudo apt install libavif-bin&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# primeiro, converter de .gif para .y4m&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ffmpeg&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -i&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; entrada.gif&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -pix_fmt&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; yuv420p&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -f&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; yuv4mpegpipe&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; temp.y4m&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# depois, de .y4m para .avif&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;avifenc&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; temp.y4m&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; saida.avif&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=exibi%C3%A7%C3%A3o-em-html-com-fallback tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#exibi%C3%A7%C3%A3o-em-html-com-fallback class=header-anchor&gt;&lt;span&gt;Exibição em HTML com &lt;em&gt;fallback&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Se você quer usar esses novos formatos, mas quer garantir compatibilidade com navegadores Web mais antigos, você pode usar a tag HTML &lt;code&gt;&amp;lt;picture&gt;&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;html&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;head&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;    &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;title&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;Animated AVIF Example&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;title&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;head&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;body&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;    &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;picture&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;      &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;source&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; type&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;image/avif&quot;&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; srcset&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;minha_animacao.avif&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;      &amp;lt;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;img&lt;/span&gt;&lt;span style=color:#e50000;--shiki-dark:#6E9BB3&gt; src&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;=&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt;&quot;minha_animacao.gif&quot;&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt; /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;picture&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;body&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&amp;lt;/&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#3F74A0&gt;html&lt;/span&gt;&lt;span style=color:maroon;--shiki-dark:#535353&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Se o navegador tiver suporte, tentará primeiro carregar a imagem em formato AVIF; senão, carregará a imagem em formato GIF. A animação abaixo está dentro de uma tag &lt;code&gt;&amp;lt;picture&gt;&lt;/code&gt; — você pode conferir o formato ao salvar o arquivo.&lt;/p&gt;&lt;p&gt;&lt;picture class=my-4&gt;&lt;source alt=&quot;Cortinas balançando com o vento&quot; srcset=https://alexandrehtrb.github.io/assets/img/posts/2024_01_curtains.avif type=image/avif&gt;&lt;img alt=&quot;Cortinas balançando com o vento&quot; src=https://alexandrehtrb.github.io/assets/img/posts/2024_01_curtains.gif&gt;&lt;/picture&gt;&lt;/p&gt;&lt;p&gt;Devido ao tamanho menor das imagens, as páginas carregam mais rápido.&lt;/p&gt;&lt;h2 id=para-ler-mais tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#para-ler-mais class=header-anchor&gt;&lt;span&gt;Para ler mais&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=https://tonisagrista.com/blog/2023/jpegxl-vs-avif/ &gt;JPEG XL vs AVIF: A Comparison&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20240121144338/https://tonisagrista.com/blog/2023/jpegxl-vs-avif/ &gt;WebArchive&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://eclipseo.github.io/image-comparison-web/#adventure-with-the-windmills*1:1&amp;AOM_3.1.1=s&amp;JXL_20210715=s&amp;subset1&quot;&gt;Image formats comparison&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=https://siipo.la/blog/whats-the-best-lossless-image-format-comparing-png-webp-avif-and-jpeg-xl&gt;What’s the best lossless image format? Comparing PNG, WebP, AVIF, and JPEG XL&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20240121174347/https://siipo.la/blog/whats-the-best-lossless-image-format-comparing-png-webp-avif-and-jpeg-xl&gt;WebArchive&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&lt;a href=https://kornel.ski/en/faircomparison&gt;How to compare images fairly&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20240126200642/https://kornel.ski/en/faircomparison&gt;WebArchive&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&lt;a href=https://cloudinary.com/blog/how_jpeg_xl_compares_to_other_image_codecs&gt;How JPEG XL Compares to Other Image Codecs&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20240121174134/https://cloudinary.com/blog/how_jpeg_xl_compares_to_other_image_codecs&gt;WebArchive&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&lt;a href=https://www.mdpi.com/2078-2489/8/4/131&gt;The Current Role of Image Compression Standards in Medical Imaging&lt;/a&gt; (&lt;a href=https://web.archive.org/web/20240126221119/https://www.mdpi.com/2078-2489/8/4/131&gt;WebArchive&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&lt;a href=https://codelabs.developers.google.com/codelabs/avif#0&gt;Serving AVIF images codelab&lt;/a&gt;&lt;/p&gt;&lt;h2 id=fontes-das-imagens tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/formatos-de-imagem-modernos-jxl-avif/#fontes-das-imagens class=header-anchor&gt;&lt;span&gt;Fontes das imagens&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Todas extraídas do Unsplash:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://unsplash.com/photos/black-hole-galaxy-illustration-Oze6U2m1oYU?utm_content=creditShareLink&amp;utm_medium=referral&amp;utm_source=unsplash&quot;&gt;Galáxia&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://unsplash.com/photos/teeth-x-ray-KeVKEs1_RDU?utm_content=creditShareLink&amp;utm_medium=referral&amp;utm_source=unsplash&quot;&gt;Radiografia dental&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://unsplash.com/photos/an-underground-subway-station-with-escalators-and-stairs-hLIi1IU5IU0?utm_content=creditShareLink&amp;utm_medium=referral&amp;utm_source=unsplash&quot;&gt;Escadas-rolantes na estação de metrô&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Links simbólicos em multi-repos</title>
    <link href="https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/" />
    <updated>2024-01-19T00:00:00Z</updated>
    <id>https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/</id>
    <content type="html">&lt;h2 id=arquivos-repetidos tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/#arquivos-repetidos class=header-anchor&gt;&lt;span&gt;Arquivos repetidos&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Diga: a organização de arquivos abaixo lhe é familiar?&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;&gt; tree C:&#92;MeusProjetos&#92; /F&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;C:&#92;MeusProjetos&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;├──── Repo1&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          src&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          .editorconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          lint.xml&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          build.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          runtestcoverage.ps1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;├──── Repo2&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          src&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          .editorconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          lint.xml&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          build.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          runtestcoverage.ps1&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│ ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note que há arquivos iguais em conteúdo e com uma cópia deles em cada diretório de projeto. Alguns exemplos de arquivos repetidos são:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Arquivos de estilo de código:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;.editorconfig&lt;/code&gt; (várias linguagens)&lt;/li&gt;&lt;li&gt;&lt;code&gt;checkstyle.xml&lt;/code&gt; (Java, Android)&lt;/li&gt;&lt;li&gt;&lt;code&gt;.eslintrc&lt;/code&gt; (JavaScript, TypeScript)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Arquivos de scripts:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;build.sh&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;runtestcoverage.ps1&lt;/code&gt; (scripts gerais)&lt;/li&gt;&lt;li&gt;&lt;code&gt;CMakeLists.txt&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;Makefile&lt;/code&gt; (compilação para C/C++)&lt;/li&gt;&lt;li&gt;&lt;code&gt;Jenkinsfile&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Arquivos de segredos e configurações de execução:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;appsettings.json&lt;/code&gt; (.NET)&lt;/li&gt;&lt;li&gt;&lt;code&gt;Web.config&lt;/code&gt; (ASP NET Framework)&lt;/li&gt;&lt;li&gt;&lt;code&gt;.env&lt;/code&gt; (npm)&lt;/li&gt;&lt;li&gt;outros&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Se você tem vários repositórios com arquivos repetidos, fica cansativo alterar esses arquivos, pois o esforço precisa ser feito em cada repositório.&lt;/p&gt;&lt;h2 id=ponteiros%3F tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/#ponteiros%3F class=header-anchor&gt;&lt;span&gt;Ponteiros?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Em programação, existe o conceito de ponteiro — algo que aponta para outra coisa. Geralmente, associamos ponteiros a memória, algo que aponta para um valor ou estrutura na memória RAM. Porém, o conceito de ponteiros existe também em sistemas de arquivos: são os links simbólicos, &lt;strong&gt;&lt;em&gt;symlinks&lt;/em&gt;, arquivos que apontam para outros arquivos.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Os links simbólicos são uma tecnologia consolidada, tendo surgido já na década de 1960. Há suporte amplo no Linux, Mac OSX e Windows, mesmo em versões mais antigas.&lt;/p&gt;&lt;h2 id=liga%C3%A7%C3%B5es tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/#liga%C3%A7%C3%B5es class=header-anchor&gt;&lt;span&gt;Ligações&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Em um sistema de arquivos, cada elemento, arquivo ou pasta, é representado por um &lt;em&gt;inode&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Um &lt;em&gt;inode&lt;/em&gt; de arquivo é composto por metadados e o endereço no disco rígido. &lt;em&gt;Inodes&lt;/em&gt; de diretórios são listas de outros &lt;em&gt;inodes&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Existem dois tipos de ligações: os &lt;em&gt;hardlinks&lt;/em&gt; e os &lt;em&gt;symlinks&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Um &lt;em&gt;&lt;strong&gt;hardlink&lt;/strong&gt;&lt;/em&gt; é quando um arquivo aponta para o mesmo &lt;em&gt;inode&lt;/em&gt; que outro arquivo. Ambos acessam o mesmo conteúdo no disco rígido. Quando um arquivo é excluído, o conteúdo do outro não é perdido.&lt;/p&gt;&lt;p&gt;Um &lt;em&gt;&lt;strong&gt;symlink&lt;/strong&gt;&lt;/em&gt; é quando um arquivo aponta para outro arquivo. Nesse caso, o arquivo ponteiro depende do arquivo original para acessar o conteúdo. Se o arquivo original for excluído ou mudar de local, o &lt;em&gt;symlink&lt;/em&gt; torna-se inválido.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Symlinks&lt;/em&gt; podem ter caminhos absolutos ou relativos.&lt;/p&gt;&lt;p&gt;Exemplo de caminho absoluto: &lt;code&gt;/home/alexandre/Projetos/arquivo.txt&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Exemplo de caminho relativo: &lt;code&gt;../arquivo.txt&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=language-mermaid&gt;&lt;div class=mermaid&gt;graph TD;
    I(inode)
    A(arquivo.txt)
    AHL(arquivo_hardlink.txt)
    ASL(arquivo_symlink.txt)
    A==&gt;I
    AHL==hardlink==&gt;I
    ASL-.symlink.-&gt;A
    style I fill:#f9f,stroke:#333,stroke-width:4px,color:#000
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=symlinks-para-organiza%C3%A7%C3%A3o-de-arquivos tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/#symlinks-para-organiza%C3%A7%C3%A3o-de-arquivos class=header-anchor&gt;&lt;span&gt;&lt;em&gt;Symlinks&lt;/em&gt; para organização de arquivos&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Considerando o cenário exposto no começo do artigo, podemos unificar arquivos de vários projetos, fazendo uso de &lt;em&gt;symlinks&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Dentro da cada repositório, vamos criar links que apontarão para arquivos em uma pasta Configs, em um nível acima. A pasta Configs pode se tornar um repositório à parte, separado do Repo1 e do Repo2.&lt;/p&gt;&lt;p&gt;O diagrama abaixo exemplifica melhor. &lt;code&gt;--&gt;&lt;/code&gt; indica um &lt;em&gt;symlink&lt;/em&gt;.&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span&gt;C:&#92;MeusProjetos&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;├──── Configs&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          .editorconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          build.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;├──── Repo1&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          .editorconfig --&gt; ../Configs/.editorconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          build.sh --&gt; ../Configs/build.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;├──── Repo2&#92;&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          .editorconfig --&gt; ../Configs/.editorconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          build.sh --&gt; ../Configs/build.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│          ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;│ ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No VS Code, &lt;em&gt;symlinks&lt;/em&gt; têm uma setinha ao lado direito do nome do arquivo.&lt;/p&gt;&lt;img alt=&quot;Symlinks no VS Code&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_01_vscode_symlinks.png&gt;&lt;p&gt;O comando para criar links simbólicos no Linux e no Mac OSX é:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;ln&lt;/span&gt;&lt;span style=color:#00f;--shiki-dark:#9C6650&gt; -s&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; ../Configs/arquivo_original.txt&lt;/span&gt;&lt;span style=color:#a31515;--shiki-dark:#9C6650&gt; arquivo_symlink.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Na linha de comando do Windows:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;REM&lt;/span&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt; requer elevação de Administrador&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#00f;--shiki-dark:#417EB1&gt;mklink&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt; arquivo_symlink.txt ..&#92;Configs&#92;arquivo_original.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No PowerShell:&lt;/p&gt;&lt;pre class=&quot;NomosBlack light-plus shiki shiki-themes&quot; style=background-color:#fff;--shiki-dark-bg:#000000;color:#000;--shiki-dark:#d4d4d4 tabindex=0&gt;&lt;code&gt;&lt;span class=line&gt;&lt;span style=color:green;--shiki-dark:#007E2A&gt;# requer elevação de Administrador&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;span style=color:#795e26;--shiki-dark:#B6B677&gt;New-Item&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt; -&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;ItemType SymbolicLink &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;Path arquivo_symlink.txt &lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;-&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;Value ..&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;/&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;Configs&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#A5A5A5&gt;/&lt;/span&gt;&lt;span style=color:#000;--shiki-dark:#D4D4D4&gt;arquivo_original.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=line&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=git tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/#git class=header-anchor&gt;&lt;span&gt;Git&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;O Git suporta ter arquivos &lt;em&gt;symlink&lt;/em&gt; commitados nos repositórios.&lt;/p&gt;&lt;p&gt;No GitHub, eles aparecem com uma setinha e nome em azul.&lt;/p&gt;&lt;img alt=&quot;Symlinks repo&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_01_github_symlink_repo.png&gt;&lt;p&gt;Na navegação online e em pull requests, o conteúdo do arquivo aparece como um texto do caminho, absoluto ou relativo.&lt;/p&gt;&lt;img alt=&quot;Symlinks repo file&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_01_github_symlink_file.png&gt;&lt;h2 id=quando-devo-usar-essa-abordagem%3F tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/#quando-devo-usar-essa-abordagem%3F class=header-anchor&gt;&lt;span&gt;Quando devo usar essa abordagem?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Organizar arquivos com &lt;em&gt;symlinks&lt;/em&gt; é bom em situações com muitos projetos, que usam vários arquivos em comum.&lt;/p&gt;&lt;p&gt;Se há poucos arquivos em comum, ou se há poucos repositórios, tudo bem ter arquivos replicados!&lt;/p&gt;&lt;p&gt;Em alguns casos, como pipelines, é melhor escolher outras abordagens de reuso. O GitHub Actions, por exemplo, sugere adotar &lt;a href=https://github.blog/2022-02-10-using-reusable-workflows-github-actions/ &gt;&lt;em&gt;reusable workflows&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Diretórios simbólicos podem ser uma boa alternativa a submódulos do Git.&lt;/p&gt;&lt;h2 id=detalhes-importantes tabindex=-1&gt;&lt;a href=https://alexandrehtrb.github.io/posts/2024/01/links-simbolicos-em-multi-repos/#detalhes-importantes class=header-anchor&gt;&lt;span&gt;Detalhes importantes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;Se você estiver usando Windows, é necessário habilitar links simbólicos durante a instalação do Git:&lt;/li&gt;&lt;/ol&gt;&lt;img alt=&quot;Git for Windows setup Symlinks&quot; class=my-4 src=https://alexandrehtrb.github.io/assets/img/posts/2024_01_git_windows_setup_symlinks.png&gt;&lt;ol start=2&gt;&lt;li&gt;&lt;p&gt;Alguns sistemas de arquivos não suportam links simbólicos, por exemplo, FAT32 e exFAT. Esses sistemas de arquivos são comuns em pen-drives e cartões SD.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;Symlinks&lt;/em&gt; são diferentes de atalhos do Windows. Estes últimos são arquivos com extensão &lt;code&gt;.lnk&lt;/code&gt; e que são abertos apenas pelo Windows Explorer e pelo Desktop.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;</content>
  </entry>
</feed>