<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: João Antônio</title>
    <description>The latest articles on Forem by João Antônio (@antjjoao).</description>
    <link>https://forem.com/antjjoao</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3578101%2F152e06d8-6369-4bbe-96c3-8bea4efb4bf2.jpeg</url>
      <title>Forem: João Antônio</title>
      <link>https://forem.com/antjjoao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/antjjoao"/>
    <language>en</language>
    <item>
      <title>por quê?</title>
      <dc:creator>João Antônio</dc:creator>
      <pubDate>Wed, 04 Feb 2026 10:47:10 +0000</pubDate>
      <link>https://forem.com/antjjoao/por-que-4a77</link>
      <guid>https://forem.com/antjjoao/por-que-4a77</guid>
      <description>&lt;p&gt;O desenvolvimento de software exige, de certa forma, um esforço "cognitivo" mínimo da máquina. Diante disso, acredito que pontos como entendimento e compreensão profunda produzem soluções cada vez mais robustas para a grande gambiarra que é a combinação de estruturas lógicas que se transformam em instruções com um determinado fim. O comportamento de uma instrução é interpretado com um nível específico de precisão, não de significado.&lt;/p&gt;

&lt;p&gt;Essa grande gambiarra nasce da interpretação de sinais elétricos. Enquanto elétrons percorrem circuitos em busca de uma fuga para despejar sua energia em algum ponto final, eles se tornam prisioneiros do próprio circuito. São quase escravos de portas que permitem ou bloqueiam sua passagem, velocistas que correm sem saber para onde, sem linha de chegada, queimando todo o combustível disponível até a dissipação total.&lt;/p&gt;

&lt;p&gt;Compreender essas abstrações, assim como as interpretações existentes em cada camada de software e hardware, traz uma enorme sabedoria para a tomada de decisão. Esse entendimento nos conduz à percepção de que tudo depende de contratos fortes e de implementações feitas com o mínimo possível de brechas de sentido e de processo. Quanto mais profundo é o entendimento das camadas, menor é o espaço para ambiguidades e maior é a confiabilidade dos sistemas construídos.&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>JVM, Java Memory Model e CPU: por que funciona em x86 e quebra em ARM</title>
      <dc:creator>João Antônio</dc:creator>
      <pubDate>Mon, 15 Dec 2025 02:17:33 +0000</pubDate>
      <link>https://forem.com/antjjoao/jvm-java-memory-model-e-cpu-por-que-funciona-em-x86-e-quebra-em-arm-280g</link>
      <guid>https://forem.com/antjjoao/jvm-java-memory-model-e-cpu-por-que-funciona-em-x86-e-quebra-em-arm-280g</guid>
      <description>&lt;p&gt;“Mas nunca deu problema na minha máquina.”&lt;/p&gt;

&lt;p&gt;Provavelmente porque sua máquina é x86. Troca pra ARM e alguns bugs de concorrência que estavam “dormindo” aparecem.&lt;/p&gt;

&lt;p&gt;A ideia central: &lt;strong&gt;x86 costuma ser mais “conservador” na prática&lt;/strong&gt;, enquanto &lt;strong&gt;ARM permite mais reordenações&lt;/strong&gt;. Se seu código depende de comportamento “bonzinho” do hardware, ele pode sobreviver em x86 e falhar em ARM.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que o Java Memory Model (JMM) realmente garante
&lt;/h2&gt;

&lt;p&gt;O JMM não fala “threads compartilham memória e pronto”. Ele define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;visibilidade&lt;/strong&gt;: quando o que uma thread escreveu passa a ser visto por outra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ordem&lt;/strong&gt;: quais reordenações são permitidas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;happens-before&lt;/strong&gt;: a relação que cria garantias reais entre threads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sem um &lt;em&gt;happens-before&lt;/em&gt; entre duas ações, você não tem garantia de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ver o valor mais recente&lt;/li&gt;
&lt;li&gt;ver as coisas na ordem que você escreveu&lt;/li&gt;
&lt;li&gt;ver um objeto “pronto”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isso é o motivo de muitos bugs “fantasma”.&lt;/p&gt;




&lt;h2&gt;
  
  
  O erro comum: confiar na ordem do código
&lt;/h2&gt;

&lt;p&gt;Você escreve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ready&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E imagina que outra thread, ao ver &lt;code&gt;ready == true&lt;/code&gt;, vai necessariamente ver &lt;code&gt;x == 42&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O JMM permite que, &lt;strong&gt;sem sincronização&lt;/strong&gt;, outra thread observe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ready == true
x == 0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porque:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x pode ficar em cache/registrador&lt;/li&gt;
&lt;li&gt;as escritas podem ser reordenadas&lt;/li&gt;
&lt;li&gt;a outra thread pode ler valores antigos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O clássico pesado: “objeto meio construído”
&lt;/h2&gt;

&lt;p&gt;Esse é o bug mais traiçoeiro.&lt;/p&gt;

&lt;p&gt;instance = new MyObject();&lt;/p&gt;

&lt;p&gt;Isso parece uma operação, mas por baixo vira algo tipo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;alocar memória&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;inicializar campos (construtor)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;publicar a referência (instance aponta pro objeto)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sem sincronização, a JVM/CPU podem efetivamente permitir que a publicação (3) aconteça antes da inicialização (2) ser visível para outras threads.&lt;/p&gt;

&lt;p&gt;Então uma segunda thread pode ver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (instance != null) {
    instance.doSomething();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E instance não é null, mas o objeto pode estar com campos ainda em estado “default” (0/null). Em padrões como double-checked locking isso já deu dor real em produção.&lt;/p&gt;

&lt;h1&gt;
  
  
  Onde volatile entra (e por que resolve)
&lt;/h1&gt;

&lt;p&gt;Se você declara:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static volatile MyObject instance;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você ganha duas coisas importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visibilidade: leitura de volatile vê o valor mais recente (não “preso” em cache local).&lt;/li&gt;
&lt;li&gt;Ordem: volatile cria barreiras que impedem certas reordenações ao redor da variável.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Regra que importa:
&lt;/h1&gt;

&lt;p&gt;Uma escrita em um volatile acontece-before de qualquer leitura posterior do mesmo volatile.&lt;/p&gt;

&lt;p&gt;Na prática: se a thread B leu instance (volatile) como não-nulo, ela passa a ter garantia de enxergar as escritas que aconteceram antes da thread A publicar essa referência (incluindo os writes do construtor que “prepararam” o objeto).&lt;/p&gt;

&lt;h2&gt;
  
  
  “Como funciona por baixo dos panos”
&lt;/h2&gt;

&lt;p&gt;Escrita em volatile&lt;/p&gt;

&lt;p&gt;Quando a JVM compila uma escrita em volatile, ela precisa garantir que:&lt;/p&gt;

&lt;p&gt;todas as escritas anteriores não fiquem “penduradas” e invisíveis&lt;/p&gt;

&lt;p&gt;a publicação do valor não “passe na frente” de coisas anteriores&lt;/p&gt;

&lt;p&gt;Isso é implementado inserindo memory fences/barriers ao redor do acesso (o tipo exato depende da arquitetura e do JIT).&lt;/p&gt;

&lt;p&gt;Leitura de volatile&lt;/p&gt;

&lt;p&gt;Quando a JVM compila uma leitura de volatile, ela precisa garantir que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;você não leia um valor velho do cache/registrador&lt;/li&gt;
&lt;li&gt;leituras seguintes não sejam movidas “pra antes” dessa leitura&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Também usa barreiras e instruções com semântica apropriada.&lt;/p&gt;

&lt;h2&gt;
  
  
  x86 vs ARM: por que a diferença aparece
&lt;/h2&gt;

&lt;h1&gt;
  
  
  x86 (modelo mais forte na prática)
&lt;/h1&gt;

&lt;p&gt;Em x86, muitas reordenações são menos agressivas e a plataforma tende a “ajudar” sem você pedir. Não significa que o código está correto — significa que o bug pode não se manifestar.&lt;/p&gt;

&lt;p&gt;Resultado: muita gente escreve código sem happens-before e “passa”.&lt;/p&gt;

&lt;h1&gt;
  
  
  ARM (modelo mais fraco)
&lt;/h1&gt;

&lt;p&gt;ARM permite mais reordenação e exige sincronização explícita para garantir ordem/visibilidade. Se você não usou volatile/synchronized/locks/atomics, ARM tem mais chance de mostrar o bug.&lt;/p&gt;

&lt;p&gt;Resultado: o mesmo programa “ok” em x86 pode falhar em ARM sob carga.&lt;/p&gt;

&lt;p&gt;Regra prática (sem filosofia)&lt;/p&gt;

&lt;p&gt;Se tem compartilhamento entre threads, escolha uma estratégia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;volatile: bom para flags/estado simples e publicação segura de referência&lt;/li&gt;
&lt;li&gt;&lt;p&gt;synchronized/Lock: bom para invariantes e operações compostas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Atomic*: bom para operações atômicas sem lock (CAS), com custos/limites próprios&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você não tem happens-before, você está apostando na arquitetura e no acaso.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>computerscience</category>
      <category>java</category>
    </item>
    <item>
      <title>Implementando preço baseado em volumetria com desconto retroativo</title>
      <dc:creator>João Antônio</dc:creator>
      <pubDate>Sat, 08 Nov 2025 14:22:56 +0000</pubDate>
      <link>https://forem.com/antjjoao/implementando-preco-baseado-em-volumetria-com-desconto-retroativo-5505</link>
      <guid>https://forem.com/antjjoao/implementando-preco-baseado-em-volumetria-com-desconto-retroativo-5505</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnpdiqmhepns8mec23oo7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnpdiqmhepns8mec23oo7.png" alt="twitter post" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos à ideia de trabalhar com tiers por volumetria.&lt;br&gt;
Neste exemplo, defini 3 tiers, onde os valores mínimo e máximo são inclusivos, ou seja, tanto o limite mínimo quanto o limite máximo estão dentro do tier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0418xoapgphd67bbp1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0418xoapgphd67bbp1s.png" alt="structs" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se o max for 0, quer dizer que vai do min até o “infinito”.&lt;br&gt;
Cada tier tem um unitPrice, que é o preço de cada pagamento naquela faixa.&lt;/p&gt;

&lt;p&gt;No PlanVersions, a ideia é ter várias versões de um mesmo plano convivendo ao mesmo tempo.&lt;/p&gt;

&lt;p&gt;Se rolar uma atualização de preço e você não quiser que os clientes antigos sejam impactados, o EffectiveAt entra justamente pra isso: você usa a data pra decidir qual versão do plano vale pra cada cobrança.&lt;/p&gt;

&lt;p&gt;Já o CustomerPricing é o vínculo entre o plano e o cliente — e ali você pode colocar um desconto se o cliente for especial… ou só muito gente boa mesmo kkkkk 😄&lt;/p&gt;

&lt;p&gt;aqui abaixo está o uso/exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7jxyzb7gmg2y3oj7adf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7jxyzb7gmg2y3oj7adf.png" alt=" " width="757" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;keep going until you're satisfied or dead.&lt;/p&gt;

</description>
      <category>go</category>
      <category>braziliandevs</category>
      <category>backend</category>
      <category>architecture</category>
    </item>
    <item>
      <title>equals, hashcode, hashmap</title>
      <dc:creator>João Antônio</dc:creator>
      <pubDate>Wed, 22 Oct 2025 01:18:13 +0000</pubDate>
      <link>https://forem.com/antjjoao/equals-hashcode-hashmap-5ah2</link>
      <guid>https://forem.com/antjjoao/equals-hashcode-hashmap-5ah2</guid>
      <description>&lt;h2&gt;
  
  
  O papel de equals() e hashCode() no Java
&lt;/h2&gt;

&lt;p&gt;Esses dois métodos vêm da classe Object, a base de todas as classes em Java.&lt;/p&gt;

&lt;p&gt;Eles determinam como o Java compara objetos e como eles são organizados em coleções baseadas em hash.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;equals(Object o)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define se dois objetos são considerados “iguais”.&lt;/p&gt;

&lt;p&gt;Por padrão (em Object), equals() compara referências (endereço na memória).&lt;/p&gt;

&lt;p&gt;Classes costumam sobrescrever para comparar conteúdo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Cpu {
    String process;
    Pessoa(String process) { this.process = process; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true; 
        if (!(o instanceof Pessoa)) 
        Pessoa p = (Pessoa) o;
        return process.equals(p.process);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hashCode()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Retorna um número inteiro usado pelo algoritmo de hashing de coleções como HashMap e HashSet.&lt;/p&gt;

&lt;p&gt;Serve para descobrir rapidamente onde o objeto deve ficar (qual bucket).&lt;/p&gt;

&lt;p&gt;Objetos “iguais” segundo equals() devem ter o mesmo hashCode(),&lt;br&gt;
o contrário não é obrigatório (mesmo hash não garante igualdade).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public int hashCode() {
    return Objects.hash(nome);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Como o HashMap realmente usa isso
&lt;/h2&gt;

&lt;p&gt;Vamos entender o fluxo interno simplificado:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Você chama map.put(chave, valor).&lt;/li&gt;
&lt;li&gt;O Java calcula hash = chave.hashCode().&lt;/li&gt;
&lt;li&gt;Esse hash é usado pra determinar qual “bucket” no array interno vai armazenar a entrada.&lt;/li&gt;
&lt;li&gt;Dentro do bucket, se houver colisões (outros elementos com mesmo hash), ele compara com equals() para decidir se atualiza o valor ou adiciona outro nó.&lt;/li&gt;
&lt;li&gt;Quando você faz map.get(chave), ele repete o processo:

&lt;ul&gt;
&lt;li&gt;calcula o mesmo hashCode(),&lt;/li&gt;
&lt;li&gt;vai ao mesmo bucket,&lt;/li&gt;
&lt;li&gt;percorre e compara com equals() até achar a chave correspondente.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  O que acontece quando a chave muda
&lt;/h2&gt;

&lt;p&gt;Se você altera qualquer campo da chave depois de adicioná-la ao mapa, o hashCode() calculado na inserção não corresponde mais ao hash atual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultado:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O get() procura no bucket errado, não encontra.&lt;/li&gt;
&lt;li&gt;O remove() também falha (não acha a chave antiga).&lt;/li&gt;
&lt;li&gt;A entrada continua existindo dentro de um bucket “órfão”.&lt;/li&gt;
&lt;li&gt;Isso não é um “vazamento” clássico, mas é um objeto perdido logicamente — ocupa memória, mas não é acessível.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exemplo problemático&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Product{
    String name;
    int code;

    Product(String name, int code) {
        this.name= name;
        this.code= code;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Product)) return false;
        Produto p = (Product) o;
        return code == p.code;
    }

    @Override
    public int hashCode() {
        return Objects.hash(code);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora veja o uso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Map&amp;lt;Produto, Double&amp;gt; precos = new HashMap&amp;lt;&amp;gt;();
Produto p = new Produto("Mouse", 101);
precos.put(p, 79.9);


p.codigo = 999;

// Agora o hash mudou e o mapa não encntra mais a chave
System.out.println(precos.get(p)); //  null
System.out.println(precos.size()); //  1 (ainda existe internamente)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O objeto continua dentro do mapa, mas está “preso” em um bucket diferente e inacessível.&lt;/p&gt;

&lt;h2&gt;
  
  
  O contrato formal (equals / hashCode contract)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A especificação do Java diz:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se dois objetos são iguais segundo equals(), eles devem retornar o mesmo valor em hashCode().&lt;/p&gt;

&lt;p&gt;Se dois objetos têm hashCode() diferentes, eles não podem ser iguais.&lt;/p&gt;

&lt;p&gt;Se dois objetos têm o mesmo hashCode(), eles podem ou não ser iguais (colisão).&lt;/p&gt;

&lt;p&gt;Portanto:&lt;/p&gt;

&lt;p&gt;equals() → true ⇒ hashCode() igual&lt;br&gt;
hashCode() igual ⇒ equals() pode ser true ou false&lt;/p&gt;

&lt;p&gt;feito por João Antônio e caso encontre algum erro, adicione aqui um comentário ou me mande um e-mail.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>java</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
