<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mais um blog inútil.</title>
	<atom:link href="http://blol.org/feed" rel="self" type="application/rss+xml" />
	<link>http://blol.org</link>
	<description>Blog sobre coisas verdadeiramente inúteis</description>
	<lastBuildDate>Mon, 14 May 2012 02:02:59 +0000</lastBuildDate>
	<language>pt-pt</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Arvorezinha 2.0 Python</title>
		<link>http://blol.org/1840-arvorezinha-2-0-python</link>
		<comments>http://blol.org/1840-arvorezinha-2-0-python#comments</comments>
		<pubDate>Mon, 14 May 2012 02:00:47 +0000</pubDate>
		<dc:creator>thread</dc:creator>
				<category><![CDATA[Arvorezinha]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Serious Business]]></category>
		<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1840</guid>
		<description><![CDATA[Ora cá vai mais uma Arvorezinha 2.0 em Python: #!/usr/bin/python import sys print ("".join(map(lambda top: ((' ' * ((int(sys.argv[1])) - top / 2 - 1)) + ('*' * top)) + "\n", range(1, int(sys.argv[1]) * 2 + 1, 2))) + ((' ' * (int(sys.argv[1]) / 2)) + ('#' * (int(sys.argv[1]) - ((int(sys.argv[1]) + 1) % 2)) [...]]]></description>
			<content:encoded><![CDATA[<p>Ora cá vai mais uma Arvorezinha 2.0 em Python:</p>
<p><code><br />
#!/usr/bin/python<br />
import sys</p>
<p>print ("".join(map(lambda top: ((' ' * ((int(sys.argv[1])) - top / 2 - 1)) + ('*' * top)) + "\n", range(1, int(sys.argv[1]) * 2 + 1, 2))) + ((' ' * (int(sys.argv[1]) / 2)) + ('#' * (int(sys.argv[1]) - ((int(sys.argv[1]) + 1) % 2)) + "\n")) * (int(sys.argv[1]) / 2)).strip('\n')<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1840-arvorezinha-2-0-python/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Arvorezinha em perl</title>
		<link>http://blol.org/1834-arvorezinha-em-perl-2</link>
		<comments>http://blol.org/1834-arvorezinha-em-perl-2#comments</comments>
		<pubDate>Wed, 04 Jan 2012 16:54:15 +0000</pubDate>
		<dc:creator>korn</dc:creator>
				<category><![CDATA[Arvorezinha]]></category>
		<category><![CDATA[Serious Business]]></category>
		<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1834</guid>
		<description><![CDATA[Como a ultima arvorezinha era muito grande, vai aqui uma versão reduzida da v2!]]></description>
			<content:encoded><![CDATA[<p>Como a ultima arvorezinha era muito grande, vai aqui uma versão reduzida da v2!</p>
<pre class="brush: perl; title: ; notranslate">
#!/usr/bin/perl
$i=$ARGV[0];map{$a.=&quot; &quot;x($i-$_-1).&quot;*&quot;x($_*2+1).&quot;\n&quot;;$b.=&quot; &quot;x($i/2).&quot;#&quot;x($i%2?$i:$i-1).&quot;\n&quot;if($i-$_+1)%2}(0..$i-1);print$a.$b;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1834-arvorezinha-em-perl-2/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Como não ganhar um iPad 2</title>
		<link>http://blol.org/1804-como-nao-ganhar-um-ipad-2</link>
		<comments>http://blol.org/1804-como-nao-ganhar-um-ipad-2#comments</comments>
		<pubDate>Mon, 26 Dec 2011 03:09:09 +0000</pubDate>
		<dc:creator>falso</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Cracking]]></category>
		<category><![CDATA[Drama]]></category>
		<category><![CDATA[Fail]]></category>
		<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1804</guid>
		<description><![CDATA[Boas noites, Venho hoje aqui blogar a minha tristeza ao saber que a password do concurso para ganhar um iPad 2 no Pplware é alta string manhosa. Vou começar então a falar da minha jornada para tentar ganhar isto&#8230; Comecei por andar a procurar qual era o software que usava a extensão &#8220;xcon&#8221;, um amigo [...]]]></description>
			<content:encoded><![CDATA[<p>Boas noites,</p>
<p>Venho hoje aqui blogar a minha tristeza ao saber que a password do <a href="http://pplware.sapo.pt/pessoal/passatempos/ganha-um-ipad-2-com-o-pplware-e-a-officelan/" target="_blank">concurso para ganhar um iPad 2 no Pplware</a> é alta string manhosa.</p>
<p>Vou começar então a falar da minha jornada para tentar ganhar isto&#8230;</p>
<p>Comecei por andar a procurar qual era o software que usava a extensão &#8220;xcon&#8221;, um amigo meu descobriu entretanto que era o <a href="http://www.dataconceal.com/" target="_blank">Conceal</a>, um software todo manhoso em .NET.<br />
Experimentei umas passwords básicas no programa só para ver se advinhava antes de fazer alguma coisa mais complexa, mas o programa era tão manhoso que se usasse uma password invalida ele crashava, então desisti dessa aproximação.</p>
<p>Falei com um amigo meu todo cromo da criptografia e ele automagicamente disse-me que aquilo eram blocos de TripleDES CBC.</p>
<p>Caso os senhores do Pplware não saibam, bruteforcar TripleDes não é assim pêra doce, <a href="http://en.wikipedia.org/wiki/EFF_DES_cracker#Technology" target="_blank">citando a Wikipedia</a> (está sempre correcta :-P):</p>
<p>&#8220;Deep Crack was designed by Cryptography Research, Inc., Advanced Wireless Technologies and the EFF. &#8230;  Advanced Wireless Technologies built 1856 custom ASICDES chips housed on 29 circuit boards of 64 chips each. The boards were then fitted in six cabinets and mounted in a Sun-4/470 chassis. &#8230; The entire machine was capable of testing over 90 billion keys per second. <strong>It would take about 9 days to test every possible key at that rate. On average, the correct key would be found in half that time.</strong>&#8221;</p>
<p>Entretanto, eu sem sabendo que era alta string manhosa, e pensando que a password poderia ser o titulo de algum dos produtos entre 50 e 100€, fiz um scriptzinho que ia la parsar o site do OfficeLan e sacar de la os títulos todos (faz uso do <a href="http://code.google.com/p/phpquery/" target="_blank">phpQuery</a>):</p>
<pre class="brush: php; title: ; notranslate">
&lt;head&gt;
  &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;/head&gt;
&lt;?php

require('phpQuery.php');

// batota, tem o total hardcoded
for($start = 0; $start &lt;= 120; $start = $start + 20) {
	$url = 'http://shop.officelan.pt/pesquisa.html?start='.$start;
	$fields = array(
		'yagendoo_price_min'=&gt;urlencode('50'),
		'yagendoo_price_max'=&gt;urlencode('100'),
		'option'=&gt;urlencode('com_yagendoo_vmsearch'),
	);
	$fields_string = &quot;&quot;;
	foreach($fields as $key=&gt;$value) { $fields_string .= $key.'='.$value.'&amp;'; }
	rtrim($fields_string,'&amp;');

	$ch = curl_init();
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_POST,count($fields));
	curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

	$result = curl_exec($ch);

	curl_close($ch);

	$doc = phpQuery::newDocument($result);
	phpQuery::selectDocument($doc);

	foreach(pq('span.yagendoo_searchresult_title a') as $product) {
			echo $product-&gt;nodeValue;
			echo '&lt;br/&gt;';
	}
}
</pre>
<p>E com o resultado fui experimentar o seguinte:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

$produtos = array(
  'MikroTik RouterBOARD 411U (Level 4) - RB411U - RB/411U',
  'MikroTik RouterBOARD 411AR (Level 4) - RB411AR - RB/411AR',
  ...
  'ANTENA INTERLINE SECTORIAL 12dBi/2.4GHz Mimo',
  'ANTENA INTERLINE SECTORIAL 12dBi/2.4GHz',
  'Presente', 'Presente_Natal', 'Presente_Natal.zip',
  'OfficeLan', 'pplware', 'natal',
);

$string = file_get_contents('nome_produto_offiLan.xcon');
foreach($produtos as $key) {
	$output = mcrypt_decrypt( MCRYPT_3DES , $key , $string , 'cbc');
	echo '&lt;h4&gt;'.$key.'&lt;/h4&gt;';
	echo '&lt;pre&gt;'.$output.'&lt;/pre&gt;';
}
</pre>
<p>Mas sem grandes resultados&#8230; Então foi que me disseram que o TripleDES CBC alem de uma key na cifra usa também outra variável, que é o IV (Initialization vector), que pelo que entendi, são dados usados para &#8220;inicializar&#8221; a cifra.<br />
Então o tal programa tinha de usar algum algoritmo para &#8220;gerar&#8221; um IV a partir da nossa password ou então usava algum valor fixo, decidi tentar descobrir.</p>
<p>Andei a procura de técnicas sobre reversing a cenas .NET e achei alta programinha hacker, <a href="http://www.reflector.net/" target="_blank">.NET Reflector</a>.<br />
Neste belo software, abre-se um executável .NET e ele escreve mais ou menos o codigo desse executável em belíssimo código C#, só os nomes de algumas funções e variáveis é que se perdem&#8230;</p>
<p>Então abri o executável do Conceal, e andei la a vasculhar, e no Form2 achei lá uma função chamada tdes_decrypt() e vi que era a função desejada, mas que a key e o IV eram calculados noutro lado, então com outra feature bonita deste programa, fiz Analyze nessa função e vi que era chamada pela func2(), e BINGO nessa achei o algoritmo que era usado para a key e o IV.</p>
<p><a href="http://blol.org/wp-content/uploads/2011/12/reflector.png"><img src="http://blol.org/wp-content/uploads/2011/12/reflector-300x239.png" alt="reflector 300x239 Como não ganhar um iPad 2" title="reflector" width="300" height="239" class="aligncenter size-medium wp-image-1811" /></a></p>
<p>Decidi então criar um novo projecto C# no Visual Studio, onde iria utilizar o código do programa gerado pelo Reflector, mas podia-lhe alimentar um array gigante de passwords (a lista de produtos anterior). E com poucas dificuldades consegui mete-lo a funcionar, mas rapidamente vi que nenhuma das passwords que estava tentar usar era a correcta.<br />
Sem saber mais o que tentar, rapidamente desisti&#8230;</p>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace unconceal
{
    class Program
    {
        public static void tdes_decrypt(String inputfile, String outputfile, byte[] key, byte[] IV)
        {
            long bytecount = 0L;
            long fread_len = 0L;
            int numbytes = 0;
            byte[] mybuffer = new byte[0xf4241];
            TripleDESCryptoServiceProvider tdesProvider;
            CryptoStream cryptStream;

            FileStream freader = new FileStream(inputfile, FileMode.Open, FileAccess.ReadWrite);
            FileStream fwriter = new FileStream(outputfile, FileMode.OpenOrCreate, FileAccess.Write);

            fread_len = freader.Length;

            tdesProvider = new TripleDESCryptoServiceProvider();
            tdesProvider.Key = key;
            tdesProvider.IV = IV;
            tdesProvider.Padding = PaddingMode.Zeros;

            cryptStream = new CryptoStream(fwriter, tdesProvider.CreateDecryptor(), CryptoStreamMode.Write);
            int num = 0;
            num = inputfile.Length - 1;

            while (bytecount &lt; fread_len)
            {
                numbytes = freader.Read(mybuffer, 0, 0xf4240);
                cryptStream.Write(mybuffer, 0, numbytes);
                bytecount += numbytes;
            }

            while (bytecount % 8 != 0)
            {
                cryptStream.WriteByte(0);
                bytecount++;
            }

            freader.Close();
            cryptStream.Close();
        }

        static void Main(string[] args)
        {
            List&lt;string&gt; passwords = new List&lt;string&gt;(new string[]
	        {
                &quot;MikroTik RouterBOARD 411U (Level 4) - RB411U - RB/411U&quot;,
                &quot;MikroTik RouterBOARD 411AR (Level 4) - RB411AR - RB/411AR&quot;,
                ...
                &quot;ANTENA INTERLINE SECTORIAL 12dBi/2.4GHz Mimo&quot;,
                &quot;ANTENA INTERLINE SECTORIAL 12dBi/2.4GHz&quot;,
                &quot;Presente&quot;,
                &quot;Presente_Natal&quot;,
                &quot;Presente_Natal.zip&quot;,
                &quot;OfficeLan&quot;,
                &quot;pplware&quot;,
                &quot;natal&quot;,
                &quot;Natal&quot;,
                &quot;iPad2&quot;,
                &quot;Natal 2011&quot;,
                &quot;PPLWARE.COM&quot;,
                &quot;EBA428ECA16691133FA946FED56AF824E8527BB6&quot;,
                &quot;_F2Liz12!&quot; // password correct, mas só agora :(
        	});

            int x = 0;
            foreach (String for_keyf1 in passwords)
            {
                String password = for_keyf1.ToString();

                byte[] bytes = new byte[0x2710];
                int charIndex = 0;
                int length = for_keyf1.Length;
                byte[] buffer2 = new byte[length + 1];
                int index = 0;
                int num4 = 0;
                int num7 = length - 1;
                for (index = 0; index &lt;= num7; index++)
                {
                    num4 += 3;
                    buffer2[index] = (byte)(Convert.ToInt64(for_keyf1[index]) + (index + num4));
                    num4--;
                }
                new ASCIIEncoding().GetBytes(Encoding.ASCII.GetString(buffer2), charIndex, Encoding.ASCII.GetString(buffer2).Length, bytes, charIndex);
                byte[] buffer3 = new SHA1CryptoServiceProvider().ComputeHash(bytes);

                byte[] key = new byte[24];
                key[0] = buffer3[2];
                key[1] = buffer3[6];
                key[2] = buffer3[0x12];
                key[3] = buffer3[0x10];
                key[4] = buffer3[0x13];
                key[5] = buffer3[1];
                key[6] = buffer3[9];
                key[7] = buffer3[7];
                key[8] = buffer3[14];
                key[9] = buffer3[3];
                key[10] = buffer3[8];
                key[11] = buffer3[0x11];
                key[12] = buffer3[10];
                key[13] = buffer3[15];
                key[14] = buffer3[0];
                key[15] = buffer3[11];
                key[0x10] = buffer3[9];
                key[0x11] = buffer3[4];
                key[0x12] = buffer3[0x12];
                key[0x13] = buffer3[5];
                key[20] = buffer3[11];
                key[0x15] = buffer3[2];
                key[0x16] = buffer3[0x13];
                key[0x17] = buffer3[0];

                byte[] iv = new byte[8];
                iv[0] = buffer3[2];
                iv[1] = buffer3[6];
                iv[2] = buffer3[0x12];
                iv[3] = buffer3[0x10];
                iv[4] = buffer3[0x13];
                iv[5] = buffer3[1];
                iv[6] = buffer3[9];
                iv[7] = buffer3[7];

                tdes_decrypt(@&quot;C:\Users\falso\Documents\Visual Studio 2010\Projects\unconceal\unconceal\nome_produto_offiLan.xcon&quot;,
                    @&quot;C:\Users\falso\Documents\Visual Studio 2010\Projects\unconceal\unconceal\&quot; + x.ToString() + &quot;.txt&quot;,
                    key, iv);

                string text = System.IO.File.ReadAllText(@&quot;C:\Users\falso\Documents\Visual Studio 2010\Projects\unconceal\unconceal\&quot; + x.ToString() + &quot;.txt&quot;);
                System.Console.WriteLine(&quot;String = {0}&quot;, text);
                x++;
            }
        }
    }
}
</pre>
<p>Hoje dia 26 de Dezembro, lembrei-me de ir ver qual era afinal a <a href="http://pplware.sapo.pt/pessoal/passatempos/ganha-um-ipad-2-com-o-pplware-e-a-officelan-%E2%80%93-codigo-secreto/" target="_blank">password do concurso</a>, e foi então que descobri que era &#8220;_F2Liz12!&#8221;, adicionei essa string ao meu programinha em C# e não é que funcionou?</p>
<p><a href="http://blol.org/wp-content/uploads/2011/12/unconceal.png"><img src="http://blol.org/wp-content/uploads/2011/12/unconceal.png" alt="unconceal Como não ganhar um iPad 2" title="unconceal" width="837" height="442" class="aligncenter size-full wp-image-1814" /></a></p>
<p>Download do projecto <a href='http://blol.org/wp-content/uploads/2011/12/unconceal.zip'>unconceal</a> (belo nome :-P) para Visual Studio, para caso alguém esteja interessado em brincar mais com isto. Não esquecer os caminhos que estão hardcoded ao chamar a função tdes_decrypt().</p>
<p>Acho que para a próxima os senhores do Pplware deviam fazer concursos mais bem pensados, onde ganhe quem acha o resultado final, e não quem escolhe um produto à sorte que esteja no intervalo de preços dito inicialmente (dor de corno).</p>
<p>Um abraço e até à próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1804-como-nao-ganhar-um-ipad-2/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Ano do Linux no Desktop</title>
		<link>http://blol.org/1796-ano-do-linux-no-desktop</link>
		<comments>http://blol.org/1796-ano-do-linux-no-desktop#comments</comments>
		<pubDate>Thu, 22 Dec 2011 15:33:54 +0000</pubDate>
		<dc:creator>madinfo</dc:creator>
				<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1796</guid>
		<description><![CDATA[Faltam apenas 10 dias!!!]]></description>
			<content:encoded><![CDATA[<p>Faltam apenas 10 dias!!! </p>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1796-ano-do-linux-no-desktop/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Quake 1</title>
		<link>http://blol.org/1793-quake-1</link>
		<comments>http://blol.org/1793-quake-1#comments</comments>
		<pubDate>Wed, 30 Nov 2011 14:17:41 +0000</pubDate>
		<dc:creator>madinfo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1793</guid>
		<description><![CDATA[Tenho que blolar sobre isto&#8230; Encontra-se um server de Quake 1 Shareware a correr com CRMOD (bons velhos tempos do quake.telepac.pt em que tínhamos que fazer reconnect 50 mil vezes pois o server só tinha 16 slots), para quem quiser jogar pode sacar 17 magnificas megas de jogo em cadaval.net/quake e entrar no quake.cadaval.net para [...]]]></description>
			<content:encoded><![CDATA[<p>Tenho que blolar sobre isto&#8230; Encontra-se um server de Quake 1 Shareware a correr com CRMOD (bons velhos tempos do quake.telepac.pt em que tínhamos que fazer reconnect 50 mil vezes pois o server só tinha 16 slots), para quem quiser jogar pode sacar 17 magnificas megas de jogo em cadaval.net/quake e entrar no quake.cadaval.net para jogar&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1793-quake-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Novas arvorezinhas (1.0 e 2.0) em Perl</title>
		<link>http://blol.org/1782-nova-arvorezinhas-1-0-e-2-0-em-perl</link>
		<comments>http://blol.org/1782-nova-arvorezinhas-1-0-e-2-0-em-perl#comments</comments>
		<pubDate>Thu, 20 Oct 2011 15:05:30 +0000</pubDate>
		<dc:creator>falco</dc:creator>
				<category><![CDATA[Arvorezinha]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Serious Business]]></category>
		<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1782</guid>
		<description><![CDATA[A arvorezinha em Perl que existe, não desenha a arvorezinha toda, com código escrito por quem faz o código da arvorezinha. Na minha opinião isso não respeitava o standard. Como tal achei que devia fazer uma arvorezinha como deve ser em Perl: A versão 1.0: print "*"x$_,"\n" for(1 .. 5); Para este não ser um [...]]]></description>
			<content:encoded><![CDATA[<p>A arvorezinha em Perl que existe, não desenha a arvorezinha toda, com código escrito por quem faz o código da arvorezinha. Na minha opinião isso não respeitava o standard. Como tal achei que devia fazer uma arvorezinha como deve ser em Perl:</p>
<p>A versão 1.0:<br />
<code><br />
print "*"x$_,"\n" for(1 .. 5);<br />
</code></p>
<p>Para este não ser um post demasiado parvo. Resolvi fazer uma arvorezinha em versão 2.0. em Perl. Inspirei-me no código do falso, mas não consegui resolver o bug do tronco (também não tentei muito):</p>
<pre>
use 5.010;
use strict;
use warnings;

# I'm not playing Perl Golf!

our $RAMO = "*";
our $ESPACO = qq/ /;
our $TRONCO = "#";

run();

sub run {
    my $altura = $ARGV[0] || 0;

    desenha_ramos($altura);
    desenha_tronco($altura);
}

sub desenha_ramos {
    my ($altura) = @_;

    for(1 .. $altura) {
        my $linha = desenha_elemento(1, ($altura - $_), $ESPACO);
        $linha .= $RAMO for( 1 .. (($_ * 2) - 1) );
        say $linha;
    }
}

sub desenha_tronco {
    my ($altura) = @_;

    my $largura = ($altura * 2) - 1;
    $altura = ($altura / 2);

    for(1 .. $altura) {
        if($altura % 2) {
            my $sombra = desenha_elemento(0, (($largura / 4) - 1), $ESPACO);
            my $tronco = desenha_elemento(0, (($largura / 2) - 1), $TRONCO);

            say $sombra.$tronco;
        }
        else {
            my $sombra = desenha_elemento(0, ($largura / 4), $ESPACO);
            my $tronco = desenha_elemento(1, (($largura / 2) - 1), $TRONCO);

            say $sombra.$tronco;
        }
    }
}

sub desenha_elemento {
    my ($min, $max, $tipo_elemento) = @_;

    my $elemento = $tipo_elemento;
    $elemento = sprintf("%s%s", $elemento, $tipo_elemento) for($min .. $max);

    return $elemento;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1782-nova-arvorezinhas-1-0-e-2-0-em-perl/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ementalicious</title>
		<link>http://blol.org/1766-ementalicious</link>
		<comments>http://blol.org/1766-ementalicious#comments</comments>
		<pubDate>Wed, 06 Jul 2011 21:22:11 +0000</pubDate>
		<dc:creator>falco</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Serious Business]]></category>
		<category><![CDATA[Cantinas]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1766</guid>
		<description><![CDATA[Quando revi o post do falso sobre as <a href="http://blol.org/1155-cantina-fct-unl-no-google-calendar">ementas das cantinas da UNL</a>, fiquei aborrecido com o entusiasmo do falso em relação ao <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a>.

É um facto que o Python é <strong>gay</strong>. E por isso resolvi mostrar ao falso, como é que se programa com linguagens de homem. Mas entretanto, resolvi que em vez de fazer o mesmo que o falso, iria antes criar um saite, que para além de disponibilizar as ementas em HTML, também iria disponibilizar em RSS e JSON.]]></description>
			<content:encoded><![CDATA[<p>Quando revi o post do falso sobre as <a href="http://blol.org/1155-cantina-fct-unl-no-google-calendar">ementas das cantinas da UNL</a>, fiquei aborrecido com o entusiasmo do falso em relação ao <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a>.</p>
<p>É um facto que o Python é <strong>gay</strong>. E por isso resolvi mostrar ao falso, como é que se programa com linguagens de homem. Mas entretanto, resolvi que em vez de fazer o mesmo que o falso, iria antes criar um saite, que para além de disponibilizar as ementas em HTML, também iria disponibilizar em RSS e JSON.</p>
<p>O saite vai ser desenvolvido por fases&#8230; Nesta fase o saite apenas está a mostrar numa página o mesmo conteúdo que a página das cantinas da UNL.</p>
<p>O site está a ser feito em Perl com <a href="http://mojolicio.us/perldoc/Mojolicious/Lite">Mojo::Lite</a>, que é uma versão aligeirada e simplificada da framework para web <a href="http://mojolicio.us/">MojoLicious</a></p>
<p>O site são apenas dois ficheiros, como eu não tenho skills de Word Press e não consigo colocar aqui o código todo bonitinho meti tudo numa tarball, que vocês podem obter <a href="http://ubuntuone.com/p/139r/">aqui</a>.</p>
<p><b>Notas importantes:</b><b></b></p>
<ul>
<li>O código está licenciado com a GNU General Public License version 3.</li>
<li>Para correr a aplicação é necessário ter Perl e Mojolicious instalado.</li>
<li>Ao contrário do que o falso pensa, usar expressões regulares, não é mau e não devemos ter problemas em utilizar quando úteis.</li>
</ul>
<p>Querido falsinho se quiseres dar-te ao trabalho de meter aqui o código todo bonitinho, eu dava-te dois beijinhos e um abraço.</p>
<p>Eis o screenshot da página:</p>
<div id="attachment_1776" class="wp-caption aligncenter" style="width: 310px"><a href="http://blol.org/wp-content/uploads/2011/07/CapturaEcra-1.png"><img src="http://blol.org/wp-content/uploads/2011/07/CapturaEcra-1-300x187.png" alt="CapturaEcra 1 300x187 Ementalicious" width="300" height="187" class="size-medium wp-image-1776" title="Ementalicious" /></a><p class="wp-caption-text">Imagem da página com os menus das várias faculdades</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1766-ementalicious/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>BrainFucker</title>
		<link>http://blol.org/1742-brainfucker</link>
		<comments>http://blol.org/1742-brainfucker#comments</comments>
		<pubDate>Mon, 04 Jul 2011 22:54:45 +0000</pubDate>
		<dc:creator>falso</dc:creator>
				<category><![CDATA[Arvorezinha]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1742</guid>
		<description><![CDATA[Ora viva!!! Há uns tempos atrás vi nas internets um projecto verdadeiramente inutil, do calibre das coisas que vão aparecendo por aqui, chamado Brainfuck Developer, que é um IDE para programar e debugar Brainfuck. Senti-me um pouco cabisbaixo ao ver que alguém tinha tentado chegar aos meus calcanhares em nível de inutilidade, portanto decidi por [...]]]></description>
			<content:encoded><![CDATA[<p>Ora viva!!!</p>
<p>Há uns tempos atrás vi nas internets um projecto verdadeiramente inutil, do calibre das coisas que vão aparecendo por aqui, chamado <a href="http://4mhz.de/bfdev.html">Brainfuck Developer</a>, que é um IDE para programar e debugar <a href="http://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a>.<br />
Senti-me um pouco cabisbaixo ao ver que alguém tinha tentado chegar aos meus calcanhares em nível de inutilidade, portanto decidi por mãos à obra para me redimir. E então à boa maneira dos projectos open sores, decidi ripar a ideia, e comecei a desenvolver o BrainFucker, um IDE de Brainfuck para OSX!<br />
Claro que isto não foi assim feito do pé-pra-mão, até porque não sabia nada de Objective-C nem de Cocoa, mas com o tempo, e pachorra aos fins de semana e tal, finalmente está disponível a versão 0.1.</p>
<p><img src="http://blol.org/wp-content/uploads/2011/07/BrainFuckerScreenSnapz001.png" alt="BrainFuckerScreenSnapz001 BrainFucker" title="BrainFuckerScreenSnapz001" width="470" height="380" class="aligncenter size-full wp-image-1746" /></p>
<p>Suporta correr programas de Brainfuck que só usem OUTPUT (.), o INPUT (,) ainda não está implementado, mas provavelmente vai ser uma DialogBox a pedir o valor.<br />
Possibilidade de correr programas STEP-BY-STEP para ver as alterações dos valores e posição do apontador de memoria.</p>
<p><img src="http://blol.org/wp-content/uploads/2011/07/BrainFuckerScreenSnapz002.png" alt="BrainFuckerScreenSnapz002 BrainFucker" title="BrainFuckerScreenSnapz002" width="695" height="401" class="aligncenter size-full wp-image-1747" /><br />
<img src="http://blol.org/wp-content/uploads/2011/07/BrainFuckerScreenSnapz003.png" alt="BrainFuckerScreenSnapz003 BrainFucker" title="BrainFuckerScreenSnapz003" width="695" height="401" class="aligncenter size-full wp-image-1748" /></p>
<p>Espero que isto sirva para alguém aprender Brainfuck, ou mesmo para aprender como não programar em Objective-C.<br />
O codigo está disponivel no <a href="https://github.com/falsovsky/BrainFucker">github</a>. E um build experimental está disponível: <a href="http://blol.org/wp-content/uploads/2011/07/BrainFucker.zip">BrainFucker.zip</a> &#8211; Apenas testado em OSX 10.4 e 10.5 POWERPC (só para quem ama). Agradeço a alguém que reporte se também funciona em Intels.</p>
<p>Cumprimentos, e um bem haja!</p>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1742-brainfucker/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Adeus AquaPC, olá PCDiga</title>
		<link>http://blol.org/1729-adeus-aquapc-ola-pcdiga</link>
		<comments>http://blol.org/1729-adeus-aquapc-ola-pcdiga#comments</comments>
		<pubDate>Tue, 22 Feb 2011 19:07:36 +0000</pubDate>
		<dc:creator>mirage</dc:creator>
				<category><![CDATA[Serious Business]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1729</guid>
		<description><![CDATA[Carta aberta à AquaPC Resumindo a história, encomendei uma placa gráfica em Novembro, que ficou em espera sem darem qualquer acompanhamento, e foi cancelada a 31 de Janeiro por alegada falta de stock. Dias depois, o stock apareceu, 40 euros mais caro do que o valor quando fiz a encomenda. Pedi para reabrirem a encomenda. [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Carta aberta à AquaPC</strong></p>
<p>Resumindo a história, encomendei uma placa gráfica em Novembro, que ficou em espera sem darem qualquer acompanhamento, e foi cancelada a 31 de Janeiro por alegada falta de stock. Dias depois, o stock apareceu, 40 euros mais caro do que o valor quando fiz a encomenda. Pedi para reabrirem a encomenda. Não obtive resposta durante uma semana e eis que a placa deixou de estar em stock.</p>
<p>De notar que o stock terminou no dia seguinte a eu vos ter telefonado, como último recurso, e a única resposta que obtive foi &#8220;tem de ser o chefe a decidir&#8221;. E decidiu muitíssimo bem. Isto soma-se a mails anteriores que vos enviei a pedir informações (não relativas a esta encomenda) que também não foram respondidos.</p>
<p>É incrível como a AquaPC antigamente era uma referência na qualidade do serviço e atendimento, e hoje parece ir no caminho duma Chip7 ou semelhante em que os clientes deixam de ser pessoas e passam a ser números de encomenda.</p>
<p>É com tristeza que vos informo que perderam um cliente fiel desde 2005, que não tinha problemas em pagar um extra (sim, nunca tiveram os preços mais competitivos) para ter garantia de qualidade.</p>
<p>Adeus AquaPC, olá PCDiga.</p>
<p>&#8211;<br />
Tiago Sousa</p>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1729-adeus-aquapc-ola-pcdiga/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Árvorezinha 2.0</title>
		<link>http://blol.org/1715-arvorezinha-2-0</link>
		<comments>http://blol.org/1715-arvorezinha-2-0#comments</comments>
		<pubDate>Tue, 14 Dec 2010 01:07:15 +0000</pubDate>
		<dc:creator>falso</dc:creator>
				<category><![CDATA[Arvorezinha]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Drama]]></category>
		<category><![CDATA[Useless]]></category>

		<guid isPermaLink="false">http://blol.org/?p=1715</guid>
		<description><![CDATA[Ora viva amigos! Há uns tempos no trabalho um colega meu começou a fazer pouco das minhas árvorezinhas, a dizer que só eram meia árvore, e que eu devia era de fazer uma árvore completa. Eu fiquei SENTIDO com tal AFRONTA, e fiquei a MATUTAR sobre isso, até que decidi por mãos à obra, e [...]]]></description>
			<content:encoded><![CDATA[<p>Ora viva amigos!</p>
<p>Há uns tempos no trabalho um colega meu começou a fazer pouco das minhas árvorezinhas, a dizer que só eram meia árvore, e que eu devia era de fazer uma árvore completa. Eu fiquei SENTIDO com tal AFRONTA, e fiquei a MATUTAR sobre isso, até que decidi por mãos à obra, e criar a Árvorezinha 2.0.</p>
<p>Primeiro decidi faze-la em C porque é a linguagem STANDARD!</p>
<pre>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main(int argc, char *argv[])
{
        int altura;
        int i,x;
        int lul;

        if (argc &lt; 2)
        {
                return(0);
        }
        altura = atoi(argv[1]);

        /* Ciclo da altura da Arvore */
        for(i = 1; i &lt;= altura; i++)
        {

                /*
                        Numero de Espaços
                        Começa em 0 porque existem linhas com 0 espaços
                        Algoritmo: altura - linha
                */
                for(x = 0 ; x &lt; (altura-i); x++)
                {
                        putchar(' ');
                }

                /*
                        Numero de Asteriscos
                        Começa em 1 porque não existem linhas sem *
                        Algoritmo: (2 * linha) - 1
                */
                for (x = 1; x &lt;= (2*i)-1; x++)
                {
                        putchar('*');
                }

                putchar('\n');
        }

        /* Largura ultima linha */
        lul = (altura * 2) - 1;

        /*
                Ciclo da altura do tronco
                Algoritmo: altura / 2
        */
        for(i = 1; i &lt;= (altura/2); i++)
        {
                /*
                        Por causa do ASCII nao permitir meio char
                        tive de fazer duas implementacoes diferentes,
                        uma para quando o  valor da altura do tronco
                        e' par, e outra para quando e' impar.
                */
                if (altura % 2)
                {
                        /* Impar */

                        /*
                                Numero de Espaços
                                Algoritmo: (lul / 4) - 1
                        */
                        for(x = 0; x &lt;= (lul/4)-1; x++)
                        {
                                putchar(' ');
                        }

                        /*
                                Numero de # (tronco)
                                Algoritmo: lul / 2
                        */
                        for(x = 0; x &lt;= (lul/2); x++)
                        {
                                putchar('#');
                        }

                        putchar('\n');
                }
                else
                {
                        /* Par */

                        /*
                                Numero de Espaços
                                Algoritmo: lul / 4
                        */
                        for(x = 0; x &lt;= (lul/4); x++)
                        {
                                putchar(' ');
                        }

                        /*
                                Numero de # (tronco)
                                Algoritmo: (lul / 2) - 1
                        */
                        for(x = 0; x &lt;= (lul/2)-1; x++)
                        {
                                putchar('#');
                        }

                        putchar('\n');
                }
        }

}
</pre>
</pre>
<p>A pedido de muitas famílias, foi me imposta a tarefa de fazer um RFC da nova árvorezinha, mas não tenho muito jeito para escrever algoritmos em pseudo-código. Então tal obra heróica fica para o caro leitor, façam me um baseado no código em C e enviem-me!</p>
<p>Segundo as próprias leis já pré-estabelecidas da Árvorezinha, tem de existir uma implementação em Assembly! Então não podia cá faltar a minha versão em x86 Assembly.</p>
<pre>
<pre class="brush: plain; title: ; notranslate">

;
; Arvorezinha 2.0
; x86 Assembly
; Copyright (C) 2010 Pedro de Oliveira
; http://blol.org
;
; this assembly can never fail
;
        BITS            32
        GLOBAL          main

; Vou usar duas funcoes da libc para o codigo nao crescer gigantescamente
; com rotinas que nao interessam nada para aqui.
        EXTERN          atoi
        EXTERN          printf

; Definicao das Variaveis
SECTION         .data

        argc    dd      0
        argv    dd      0

        erro    db      &quot;ERRO! Executar: %s &lt;altura da arvore&gt;&quot;,10,0

        card    db      '#'
        newl    db      0xa
        aste    db      '*'
        espa    db      ' '

        altura  dd      0
        i       dd      1
        x       dd      0
        lul     dd      0

; He cometh!
SECTION         .text

main:
        pop     eax                     ; Ignorar...

        pop     eax                     ; Saca o argc da Stack
        mov     dword [argc], eax       ; Guarda o valor na variavel argc

        pop     ebx                     ; Saca a posicao de memoria do
                                        ; argv[0] da Stack
        mov     eax, dword [ebx]        ; Mete a posicao em EAX
        mov     [argv], eax             ; Guarda-a em argv

        add     ebx,0x4                 ; Salta 4 bytes para a frente
                                        ; para o argv[1] ficar em EBX

        mov     eax, [argc]             ; Mete o argc em EAX
        cmp     eax, 0x2                ; Verifica se e' diferente de 2
        jne     jafoste                 ; Se for sai com erro

        push    dword [ebx]             ; Mete o valor de argv[1] na Stack
        call    atoi                    ; Corre o atoi com esse valor
        mov     [altura], eax           ; O resultado fica em EAX, guarda
                                        ; na variavel altura

ciclo_linhas:
        ; INICIO - CICLO DAS LINHAS DA ARVORE
        mov     eax, [i]                ; i em EAX
        mov     ebx, [altura]           ; altura em EBX

        cmp     ebx, eax                ; Compara
        jb      prepara_tronco          ; i &gt; altura ? proximo passo
        mov     dword [x], 0            ; Mete x a 0

ciclo_espacos:
        ; INICIO - CICLO DE ESPAÇOS ANTES DOS ASTERISCOS
        mov     eax, [x]                ; x em EAX

        ; pretende-se (altura - i) em EBX
        mov     ebx, [altura]           ; altura em EBX
        mov     ecx, [i]                ; i em ECX
        sub     ebx, ecx                ; EBX - ECX

        cmp     ebx, eax                ; Compara
        jbe     prepara_asteriscos      ; x &gt;= (altura - i) ? proximo passo

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     ciclo_espacos           ; Volta para o inicio do ciclo
        ; FIM - CICLO DE ESPAÇOS ANTES DOS ASTERISCOS

prepara_asteriscos:
        mov     dword [x], 1            ; Mete x a 1

ciclo_asteriscos:
        ; INICIO - CICLO DE ASTERISCOS (ARVORE)
        mov     ebx, [x]                ; x em EBX

        ; pretende-se (2 * i) - 1 em EAX
        mov     eax, 2                  ; 2 em EAX
        mov     ecx, [i]                ; i em ECX
        mul     ecx                     ; Multiplica EAX por ECX
        dec     eax                     ; Subtrai 1 a EAX

        cmp     eax, ebx                ; Compara
        jb      fim_ciclo_linhas        ; x &gt; (2*i)-1 ? proximo passo

        push    aste                    ; Asterisco
        call    print                   ; write()

        call    incrementa_x
        jmp     ciclo_asteriscos        ; Volta para o inicio do ciclo
        ; FIM - CICLO DE ASTERISCOS (ARVORE)

fim_ciclo_linhas:
        push    newl                    ; Newline
        call    print                   ; write()

        call    incrementa_i
        jmp     ciclo_linhas            ; Volta para o inicio
        ; FIM - CICLO DAS LINHAS DA ARVORE

prepara_tronco:
        ; pretende-se (altura * 2) - 1 em EAX
        mov     eax, [altura]           ; altura em EAX
        mov     ecx, 2                  ; 2 em ECX
        mul     ecx                     ; Multiplica EAX por ECX
        dec     eax                     ; Subtrai 1 a EAX
        mov     dword [lul], eax        ; Guarda a largura da ultima linha
                                        ; em lul

        mov     dword [i], 1            ; Mete o i a 1

ciclo_linhas_tronco:
        ; BEGIN - CICLO DAS LINHAS DO TRONCO
        mov     ecx, [i]                ; i em ECX

        ; pretende-se (altura / 2)
        mov     eax, [altura]           ; altura em EAX
        shr     eax, 1                  ; divide por 2

        cmp     ecx, eax                ; Compara ECX com EAX
        jg      sair                    ; i &gt; (altura / 2) ? Adeus!

        mov     eax, [altura]           ; altura em EAX
        test    eax, 1
        je      pc_tronco_par_espacos   ; e' par?

; --------------------------- IMPAR -------------------------------
pc_tronco_impar_espacos:
        mov     dword [x], 0            ; Mete-se x a 0

c_tronco_impar_espacos:
        ; INICIO - CICLO DOS ESPAÇOS ANTES DO TRONCO (IMPAR)
        mov     ecx, [x]                ; x em EAX

        ; pretende-se (lul / 4) - 1 em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 2                  ; Divide por 4
        dec     eax                     ; Subtrai 1

        cmp     eax, ecx                ; Compara
        jb      pc_tronco_impar_cardinal; x &gt; (lul/4)-1 ? Next!

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     c_tronco_impar_espacos  ; Volta para o inicio
        ; FIM - CICLO DOS ESPAÇOS ANTES DO TRONCO (IMPAR)

pc_tronco_impar_cardinal:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_impar_cardinal:
        ; INICIO - CICLO DOS CARDINAIS DO TRONCO (IMPAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 2) em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 1                  ; Divide por 2

        cmp     eax, ecx                ; Compara
        jb      fim_ciclo_linhas_tronco ; x &gt; (lul/2) ? Next!

        push    card                    ; Cardinal
        call    print                   ; write()

        call    incrementa_x

        jmp     c_tronco_impar_cardinal ; Volta para o inico
        ; FIM - CICLO DOS CARDINAIS DO TRONCO (IMPAR)

; --------------------- FIM IMPAR --------------------------------

; ----------------------------- PAR ------------------------------
pc_tronco_par_espacos:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_par_espacos:
        ; INICIO - CICLO DOS ESPAÇOS ANTES DO TRONCO (PAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 4) em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 2                  ; divide por 4

        cmp     eax, ecx                ; Compara
        jb      pc_tronco_par_cardinal  ; x &gt; (lul / 4) ? Next!

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     c_tronco_par_espacos    ; Volto para o inico do ciclo
        ; FIM - CICLO DOS ESPAÇOS ANTES DO TRONCO (PAR)

pc_tronco_par_cardinal:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_par_cardinal:
        ; INICIO - CICLO DOS CARDINAIS DO TRONCO (PAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 2) - 1 em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 1                  ; Divide por 2
        dec     eax                     ; Subtrai 1

        cmp     eax, ecx                ; Compara
        jb      fim_ciclo_linhas_tronco ; x &gt; (lul / 2) - 1 ? uhuhuh

        push    card                    ; Cardinal
        call    print                   ; write()

        call    incrementa_x

        jmp     c_tronco_par_cardinal   ; Volta para o inicio do ciclo
        ; FIM - CICLO DOS CARDINAIS DO TRONCO (PAR)
; ----------------------- FIM PAR ----------------------------------

fim_ciclo_linhas_tronco:
        push    newl
        call    print

        call    incrementa_i
        jmp     ciclo_linhas_tronco     ; Volta para o inico do ciclo
        ; FIM - CICLO DAS LINHAS DO TRONCO

jafoste:
        mov     eax, [argv]             ; Mete o apontador de argv em EAX
        push    dword eax               ; Mete o endereço de argv na Stack
        push    dword erro              ; Mete o endereço da String na Stack
        call    printf                  ; Escreve no ecra!

sair:
        mov     ebx,0x0                 ; valor de saida
        mov     eax,0x1                 ; sys_exit
        int     0x80

print:
        mov     ecx,[esp+4]             ; Mete o argumento em ECX
        mov     edx,1                   ; Length
        mov     ebx,1                   ; stdout
        mov     eax,4                   ; sys_write
        int     0x80
        ret

incrementa_x:
        mov     eax, [x]
        inc     eax
        mov     dword [x], eax
        ret

incrementa_i:
        mov     eax, [i]
        inc     eax
        mov     dword [i], eax
        ret
</pre>
</pre>
<p>E aqui vai a prova dos nove:</p>
<pre>
<pre class="brush: plain; title: ; notranslate">
falso@lemonparty:~/src/zbr$ make
rm -f arvore2 arvore.o
nasm -f elf arvore.asm -o arvore.o
gcc -g -o arvore2 arvore.o
falso@lemonparty:~/src/zbr$ ./arvore2 4
   *
  ***
 *****
*******
  ###
  ###
falso@lemonparty:~/src/zbr$ ./arvore2 5
    *
   ***
  *****
 *******
*********
  #####
  #####
falso@lemonparty:~/src/zbr$
</pre>
</pre>
<p>Espero lançar futuramente um género de Unit Tests, para testar as varias implementações da Arvorezinha 2.0 que possam surgir, para ver se cumprem o standard ou não.</p>
<p>Espero que tenham gostado do post, até à proxima, fiquem bem e joguem muito! Chuuuuuuack!</p>
]]></content:encoded>
			<wfw:commentRss>http://blol.org/1715-arvorezinha-2-0/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

