lc4j, a language categorization Java library

On this page you will find the "language categorization library" for the Java programming language.
You can download the library (with source code) directly here.

Requirements

Any modern system (JDK >= 1.4.1) should be enough in order to compile/run this library.
However, please note that the following libraries are needed for this application to compile/run:

and they must be placed in your $CLASSPATH.

Features

lc4j has been designed to be a compact, fast and scalable Java library that implements the algorithms described in:


Cavnar, W. B. and J. M. Trenkle, "N-Gram-Based Text Categorization"
In Proceedings of Third Annual Symposium on Document Analysis and
Information Retrieval, Las Vegas, NV, UNLV Publications/Reprographics,
pp. 161-175, 11-13 April 1994.

(Citeseer entry)

to categorize texts using n-grams. A directory with sample language models is provided to implement a language guesser from scratch.

This idea behind this program and most of the sample texts have their roots in TextCat, a free Perl library which implements the text categorization algorithm.

Examples

Let’s say that you want to determine the language of this phrase:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi id eros
You just fire up lc4j (yes, it is a library but also has a main) with the one-line command:
echo "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi id eros" | java net.olivo.lc4j.LanguageCategorization

and the program will reply in a way similar to this:

time taken to load all available language models: 0.371s
time taken to effectively determine the language: 0.027s
probable language(s): [latin.lm]

If more than one language matches, other languages are reported (in decreasing order of probability) in the list. If more than the maximum number of matched languages are matched, an "UNKNOWN" language is reported. This and other parameters can be changed with command-line parameters.

lc4j is cool, since (about half of them are those from TextCat) it is packed with lots of different languages and creating your own is easier than ever.
As a general rule of thumb, please remember that the longer the text, the better the output.
The number of language-models given in this version of lc4j is over 150, but since many languages are just duplicates in various common encodings, the actual number of distinct languages recognized is more or less 80-90. Adding a new language is easy however: just follow the instructions provided in the accompanying files.

Obviously, being a Java library, lc4j can be easily integrated inside your Java application (say a crawler, or a data-mining app) and can give you all that you need to determine the language of any document.
Moreover, as explained in the paper cited above, there is the possibility of using this algorithm to make some clustering of the documents by topic, although better algorithms exist in this field; for the sake of demonstration, a sample agglomerative-clustering algorithm that uses the distance between n-gram tables as measure is provided in the JAR file.

Download

Click here to download the library and its source code (about 748 KB)

Bugs

Altough this is far from being a bug, there is one thing that you should be careful about: language-models and encodings. In fact lc4j requires that it in order to recognize a language given in some encoding there should be a corresponding file that contains some sentences of that language in that encoding.
So, if you have a Chinese text in UTF-8 encoding and the program has – say – been trained only in Chinese – BIG5 encoding, the results will unlikely be correct.
A bug regarding how multi-bytes encoding are read, has been fixed in version 0.4 released on Dec 18th, 2011, thanks to the input of David Dahan.

For the rest, currently there is no known bug. If you find any, please contact me.
Thanks!

If you want further information about my projects, please visit my software section.

3 Comments

Ubi, my MS thesis (italian)

I have a 5-years University Degree (cum laude) in Computer Science.

"Università degli Studi di Milano" logo I graduated at the University of Milan on May 6th, 2003 (11:35 am). For personal, statistical reasons, I keep note that, since I started on October 5th, 1999 (16:30 pm) it only took me 4 years, 7 months, 19 hours and (roughly) 5 minutes to complete this 5-years course :)
(one day more if you consider that year 2000 had 366 days… yes, I was the first of my course ;)

During my MS thesis I worked on a search engine, the Ubi engine – which is, by the way, better than Google :)

The Ubi logo, with its refrain :)

More seriously, the idea was that we could create a search engine capable of giving results comparable (in quality) to the ones given by the other search engines, for instance like Google.
Everything started out from the UbiCrawler project, in the LAW laboratory.

Ubi screenshot on a query
(click on the picture to enlarge)

The whole search engine was written using the Java language and uses many 3rd-party classes that overcome many limits we found exist in the Java standard classes. Some of these classes are GPL’ed and are available at this site and also at this site.

Since I’m not the owner of all the source code of the project, but only of a part of it, I won’t post here any source code. Posting my sources would be completely useless to the reader, since you must have a general understanding of the whole project if you want to reproduce the behaviour of the search engine.

My MS thesis shows many useful techniques which are probably used by the commercial search engines in order to give ranks to the documents. Since search results were very similar to those given back by many commercial search engines, it might be worth reading it. Apart from that, there are also some nice notes about search engines and about the problem of rank aggregation, which I have faced during my thesis. In short, the rank aggregation problem is the problem you have to face when you want to speed up searches, by "cutting" match-evaluation after a certain number of positives, but being (almost) sure you don’t lose anything significant.

On this site there are also some slides about search engines and algorithms. They are available in PowerPoint format (Italian language).

Here is the thesis essay, available only in Italian:


Uno dei problemi aperti dell’informatica e dell’information retrieval più affascinanti degli ultimi anni è quello di rispondere alle interrogazioni poste da esseri umani ai motori di ricerca.

I motori di ricerca si distinguono dalle basi di dati e dai sistemi di information retrieval tradizionali per diverse ragioni: il World–Wide Web (web) è immenso (si calcola che, compressa, la porzione di web ad oggi raggiungibile occupi circa 50 terabyte, per un totale di oltre tre miliardi di pagine), raddoppia di dimensione ogni dodici mesi e si aggiorna con una frequenza impredicibile; inoltre i dati non sono strutturati e sono altamente eterogenei nel contenuto e nella qualità.

Il recupero di tali quantità di dati è reso difficile non soltanto dalla loro mole, ma anche da una serie di fattori legati all’affidabilità dei server su cui tali dati vengono ospitati e dalle reti attraversate per raggiungerli.

La studio dei motori di ricerca è relativamente recente, e le pubblicazioni in letteratura su questo argomento, per quanto esso sia molto dibattuto, tendono ad essere molto poche e soprattutto molto poco approfondite; tra i motivi che spingono i ricercatori che se ne occupano a non divulgare tutti i dettagli del loro lavoro vi sono forti interessi economici legati all’uso commerciale dei motori di ricerca.

Lo scopo di questa tesi è stata la costruzione di un motore di ricerca scalabile, preciso e soprattutto flessibile e che potesse competere con i motori di ricerca commerciali — se non per numero di pagine trattate, almeno per qualità dei risultati. Per raggiungere questi obbiettivi si è partiti da una implementazione accurata dei migliori algoritmi noti in letteratura, a cui è seguita una fase di affinamento basata da un lato su considerazioni di tipo ingegneristico e dall’altro da un attento confronto dei risultati ottentuti con quelli restituiti dai motori di ricerca commerciali in risposta a varie interrogazioni.

Lo schema seguito da un motore di ricerca nel momento in cui un utente inserisce un’interrogazione è, in prima approssimazione, il seguente. Anzitutto il motore opera una scrematura delle pagine che soddisfano l’interrogazione sottopostagli, in maniera tale da eliminare subito un numero significativo di pagine che probabilmente non interessano all’utente; ciononostante, a causa delle dimensioni del web, il numero di pagine rimanenti è in generale molto elevato. Pertanto, l’ordinamento relativo di tali pagine è forse la cosa più importante che un motore di ricerca si deve occupare di fornire, in quanto è proprio tale ordinamento a dare all’utente la sensazione di aver trovato quel che stava cercando.

Una tecnica possibile, ad esempio, è quella di preferire le pagine a cui si riferiscono molte altre pagine, oppure quelle in cui i termini dell’interrogazione compaiono in posizioni ravvicinate. Altre tecniche, più sofisticate, si basano sulla struttura di interconnessione tra le pagine del web.

Nei primi capitoli vengono anzitutto presentati ed analizzati alcuni algoritmi noti proposti da tempo in letteratura e che si reputa vengano utilizzati dai più famosi motori di ricerca commerciali per decidere l’ordine di presentazione dei risultati. Alcuni di questi algoritmi sono stati utilizzati nel motore di ricerca che costituisce lo scopo di questa tesi.

Nei capitoli successivi si analizzano alcune euristiche tese anzitutto a migliorare la qualità dei risultati e che cercano di fornire risposte più mirate e precise alle interrogazioni sottoposte al motore di ricerca, in maniera da emulare e, per quanto possibile, migliorare lo stato attuale dell’arte, rappresentato in questo caso dai motori di ricerca commerciali; in seconda battuta, vengono presentate altre euristiche volte a diminuire i tempi di risposta alle interrogazioni, in maniera da rendere realistico l’utilizzo del motore di ricerca sviluppato.

Infine, è stata studiata ed implementata una tecnica per aggregare i risultati dei vari algoritmi tra di loro in maniera efficiente ed in modo altamente parametrico, così da rendere possibile la sperimentazione dell’impatto dei vari algoritmi sulla qualità della risposta.

If you want further information about my projects, please visit my software section.

No Comments

Some slides on search engines (italian)

From this page you can download several set of slides regarding the search engines. All of them are available in PowerPoint format and have been written for an Italian-speaking audience. Some of them were also used for speeches at the Department of Computer Science of the University of Milan.

  • first set of slides: well-known ranking algorithms used by some search enginesdownload set (about 167 KB)
  • second set of slides: heuristics to better search quality (presentation of my
    thesis work) – download set (about 209 KB)

  • third set of slides: a UbiCrawler presentation I took with a friend of mine at the Webb.it 04 trade fair – download set (about 512 KB)

If you want further information about my projects, please visit my software section.

No Comments

Mail-conversion tips and tricks (Outlook/OE/MBOX/Eudora/Lotus Notes)

Short introduction

Mail conversion: what an incredible hassle! Have you ever stuck in wanting to change your favourite mail application and discovered that the format it uses is just… plain horrible and it seems almost impossible to convert your 10GB mail archive?

Well, I did it many times. Nowadays I tend to use only mail programs which use only the old-but-dear UNIX mailbox format or the Maildir format.
This is definitely the most used format all over the world for storing mail, and despite its age and some problems it has, it is very good since it is read by many mail apps.

So, how can you convert your existing mail archive to another one? Let’s find out!

But first of all, a small note:
I SHOULD NOT BE HELD RESPONSIBLE OF ANY DAMAGE THAT MAY HAPPEN TO YOU, YOUR COMPUTER, YOUR DATA OR ANYTHING ELSE FOR THE INSTRUCTIONS PROVIDED BELOW. USE THEM AT YOUR OWN RISK.

List of the mail apps techinques described here

In this page I’m going to describe some techniques I’ve successfully managed to work with these apps:

You may find however that these techniques also work for other apps. If you do, let me known!

Outlook/Outlook Express to UNIX mailbox

This is definitely the most simple way of mail format interchange among those described here. You have to install an IMAP server on your machine (e.g., Cyrus IMAP server) and add a new IMAP account to Outlook Express that points to an ad-hoc account on your newly installed local IMAP server.

Then, create the folders you need in your IMAP server and move all your email to the new account by dragging and dropping it directly in Outlook. Despite it may take a lot of time if you have a lot of mail, you now have all the email on your local IMAP server and you can do whatever you want from there: download it in your new email client, or use the UNIX mailbox files that you can gather from the server and change them.
Instructions and uses are trivial, and I’m not going to list them here.

Please note that attachments are usually preserved in the right way!

Eudora to UNIX mailbox

This step is a bit more difficult. You have to behave exactly in the same way as in Outlook, but when you have finished moving your email to the server you have to modify the UNIX mailbox files the IMAP server has created, since Eudora (at least the version I used, 6.0 for Windows) tends to insert some proprietary-tags (or at least non-standard conformant tags) in the exported files.

To clean these tags, I used this bash and Perl
hand-crafted script:


#!/bin/bash

perl -0777 -pe 's/n<x-html>/Content-Type: text/htmlnn<x-html>/g' "$1" > "$1.new"
perl -0777 -pe 's/Content-type:.{0,1}text/plainnContent-type: text/htmln/Content-type: text/htmln/gi' "$1.new" > "$1.newnew"
perl -0777 -pe 's/nn<html>n/nContent-Type: text/htmlnn<html>/gi' "$1.newnew" > "$1.newnewnew"
rm "$1.new" && rm "$1.newnew" && mv "$1.newnewnew" "$1.new"

which should be run on every mailbox file you export from the IMAP server.
(if the script above breaks lines, be sure to copy them properly!)

Please note that the given script requires a parameter, which is the name of the mailbox to be cleaned.

This way was enough for me to have Eudora export everything properly into a nice UNIX mailbox file.

Lotus Notes to UNIX mailbox

Lotus Notes is a widely-used application used in large corporations. Calling it a mail app would be very reductive: in some way, it is to a mail application as Emacs is to file editor.

As many large corporations, also mine uses Lotus Notes. So I started looking for a way of converting its mail format to a UNIX mailbox file so that I can import it in my favourite email client (which, by the way, happens to be
Mail.app)

I had to hack a bit with Lotus Domino in order to be able to do email conversion: in fact, user and database creation, along with control access lists are not immediate to find in Domino.

If you have IMAP access to the server you’re lucky, and you should go no further: download mail with your favourite client and you have finished.

Otherwise, the first thing you have to do is to create a local copy of your NSF database (Database -> New Copy), which must have no permission set (or all permissions allowed by everybody – this can be changed through the Database -> Access Control menu)

After that, go to the IBM website and find a trial version of Lotus Domino, both client and server.
Download them (you will need a free registration for doing this) and install them on your computer (a PC with Windows, in my case).
Startup the server in IMAP mode (which is the default, so you shouldn’t do anything) and create an account to use the .nsf file you created a few steps ago.

Finally, set up your favourite mail application to connect to your local Notes server using the new account ID.
After that, simply download all the Lotus Notes email to your app!

Please note that if you use POP3 access, you can’t synchronize your sent email, but only your received email.

Final notes

I hope that the information provided here was enough for your needs. If you need further help, feel free to ask.

This page was the result of past experiences I had with these email formats, and I found that the Internet, despite full of ideas on the mail-conversion topic, was not giving the right answers I was looking for (not, at least, in a single place).
In any case, I suggest you to make a search on Google to find the answers you need and also to visit this other site.

If you want further information about my projects, please visit my software section.

No Comments

Chatty, a PHP chat script

Short introduction

Chatty :) is a very nice script that lets you create a simple but very-good looking chat in a few minutes. Distributed under GPL and written entirely in PHP (which means it will run better on PHP hosting, since it has been designed to ensure smooth work of PHP applications), it is highly customizable and fully open to modifications.
Now works properly also with non-western languages. It requires MySQL as a backend RDBMS.

You can download the chat program (with source code) directly here.

Features

Here is a short list of features of “Chatty :)” (as of version 1.0.4):

  • registration is needed to enter the chat;
  • multi-coloured chat: every user can have a different color;
  • list of connected users;
  • works with MySQL (www.mysql.org);
  • works with non-western languages;
  • can be easily localized
  • supports emoticons
  • fixed for possible cross-site scripting attacks.

Moreover, Chatty is currently used in many sites over the Internet. With its fully-customizable graphics, Chatty is one of the best GPL chat systems out there, and it probably is worth a try if you’re looking for a free and stable chat system for your activity or site.

Screenshot

Here you find a screenshot of “Chatty :)” in action:

Chatty screenshot
(click on the picture to enlarge)

License

This chat program is distributed under GPL version 2 (or above, at your choice) and you can do whatever you want with this source code, as long as you respect the GPL license.

Download

Click here to download the source code (about 22 KB)

TODO

There are many things to do:

  • make it more customizable (fonts, colors, …);
  • make it work with other DBMS than MySQL;
  • make it possible to have more chatrooms;
  • create an online interface for the administrator(s) of the chat;
  • create an online interface for the moderator(s) of the chat;
  • create one-to-one (private) chatrooms;
  • create a system to exchange messages with users not currently connected.

Bugs

Currently there is no known bug. If you find any, please contact me.
Thanks!

If you want further information about my projects, please visit my software section.

18 Comments

Imagethumb, a PHP image-resizing script

Serbo-Croatian? Translation here by by Jovana Milutinovich

Short introduction

ImageThumb is a PHP script which allows you to resize any image so that you can place the resulting thumbnail on a page. The script was created to avoid the manual creation of thumbnails, which on some sites with lots of images may take a lot of time.

NEW: now supports thumbnail caching!

Please note that using this script on a page with many images to be resized and/or with many hits, might be a very bad idea, due to server load (especially if you disable caching). Use it wisely!

Requirements

The requirements are few:

  • a web hosting server (like Apache)
  • the GD-libraryinstalled in the system somewhere
  • PHP support inside the webserver (PHP >= 4.0.4), with GD-library support enabled

Currently GIF, JPEG and PNG formats are supported.

Usage

Usage is very simple. If image.jpg is the image you want to resize, and the desired maximum width is 400, in the HTML code you’ll have to write:

<a href="image.jpg"><img src="imagethumb.php?s=image.jpg&w=400" border="0"></a>

so that, with a single mouse click, the image can be opened.

But ImageThumb goes even further: if you want to resize an image which stays on a remote webserver, just put its URL instead of its local path and everything will work! (obviously, it will probably take more time to show the resized image)

Download it here.

Thanks for the modifications made in December 2005 by Chris Rossi, now ImageThumb has the ability of saving generated thumbnails in a cache (whose path is specified in the first lines of the script). By doing this, it comes in handy also for forums and bulletin boards, such as the famous phpBB.

In case of broken thumbs, you may want to flush the temporary caching directory, specified in the first lines of the script.

For more information regarding the usage of ImageThumb, please read its source code (it’s very simple) or contact me.

If you want further information about my projects, please visit my software section.

1 Comment

Grafico, a really old software to draw math functions (italian)

Sorry for the inconvenience, but this page and the program therein contained are available only in Italian language. However, if you want a translation on-the-fly of this page, you can use the Google translate tool.

Grafico 4.0 (1998-1999)

Logo PCFloppy+PCMagazineSONO FIERO DI ANNUNCIARE CHE QUESTO PROGRAMMA E’ STATO PUBBLICATO SULLA AUTOREVOLE RIVISTA ITALIANA PCMAGAZINE (EDITA DA JACKSON INFORMATICA) NEL MESE DI MAGGIO 1999 NELLO SPAZIO DEDICATO AI PROGRAMMATORI ITALIANI. DESIDERO RINGRAZIARE TUTTI COLORO CHE MI HANNO AIUTATO, IN UN MODO O NELL’ALTRO. UN GRAZIE SPECIALE A SILVIO D’ANGELO E ROBERTO FULIGNI, CHE MI HANNO AIUTATO ED INCORAGGIATO NELLA PRIMA VERSIONE DEL PROGRAMMA.
 
Qui potete trovare una scansione dell’articolo

Introduzione

Grafico è un programma che ho ideato nel dicembre del 1997 e che ho sviluppato nel corso dei primi mesi del 1998. Sebbene il suo nome sia tutt’altro che originale, questo programma è in grado di compiere diverse operazioni riguardo lo studio di funzioni matematiche. Alla fine di aprile 1999 sono state aggiunte alcune nuove funzionalità per quanto riguarda le funzioni supportate dal programma.

Caratteristiche del programma

In breve, ecco le caratteristiche principali del programma in questione:

  • possibilità di studiare una qualunque funzione matematica (razionale, irrazionale, fratta, goniometrica, logaritmica, …);
  • possibilità di visualizzarne la sua derivata prima con in più alcuni punti particolarmente significativi ricavabili da essa; la derivata seconda non è stata implementata, ma è possibile inserire una breve funzione anche per essa tramite semplici formule di calcolo numerico; chi sia interessato mi contatti, sarò lieto di fornire indicazioni a coloro che me le richiederanno;
  • possibilità di visualizzare il grafico di rotazione della curva attorno all’asse delle ascisse (un problema che si trova spesso durante la discussione di volumi tramite integrali; a questo proposito anche qui non è stato implementato il calcolo dell’integrale della curva, ma il metodo è piuttosto facile, dato che è sufficiente utilizzare qualche formula del calcolo numerico; chi sia interessato mi contatti);
  • possibilità di caricare e salvare un file contenente un massimo di 16 funzioni, richiamabili molto facilmente per una rapida consultazione;
  • possibilità di cambiare la scala di visualizzazione da numeri interi a radianti (l’ideale per le funzioni goniometriche);
  • possibilità di scorrere il grafico della curva, di ingrandire e di rimpicciolire parti di essa, di aumentare o diminuire la risoluzione della curva (modificando la distanza tra i punti) e possibilità di visualizzare il dominiodella curva;
  • possibilità di estrapolare punti dal grafico, al fine di visualizzarne l’ordinata.

E qui di seguito le nuove funzioni supportate dalla versione 4.0:

  • seno, coseno e tangente iperbolica;
  • SettSh, SettCh, SettTanh (funzioni inverse di seno, coseno e tangente iperbolica rispettivamente);
  • sgn (segno) di x;
  • int (parte intera) di x;
  • tutte queste funzioni hanno la derivata prima;
  • adesso è inoltre possibile visualizzare la lista delle funzioni accettate tramite la guida in linea.

Screenshot

La figura qui sotto mostra, in dimensione francobollo, una sovrapposizione di schermate del programma (quella in alto a sinistra è uno studio di funzione in verde con la derivata prima in viola e l’asse Y fuori dal dominio evidenziato in blu e quella in basso a destra è la rotazione di una curva attorno all’asse delle X):

Screenshot del programma

Licenza

Per chi fosse interessato alla modifica dei sorgenti, come ho specificato nell’unico file sorgente facente parte del progetto rilascio gratuitamente il codice sorgente e permetto di compiere qualunque modifica gli si voglia apportare, purché rimanga il mio nome nei crediti e purché tale codice non lo si utilizzi per scopi di lucro e/o commerciali.

Sarà per me molto gradita una notifica via e-mail nel caso qualcuno lo decida di modificare o lo trovi interessante.

Download

Per scaricare il software cliccare qui (circa 98 KB).

Scaricando ed utilizzando il software qui fornito viene accettato che in nessun caso sarò potuto essere ritenuto responsabile per i danni (inclusi, senza limitazioni, il danno per perdita, mancato guadagno, interruzione dell’attività, perdita di informazioni o altre perdite economiche) derivanti dall’uso del prodotto "Grafico", anche nel caso io sia stato avvertito dalla possibilità di danni.

Contiene librerie copyright © 1985-1990 by Borland International, Inc.

If you want further information about my projects, please visit my software section.

No Comments

PHP guides (italian)

In July 2000 I wrote some guides about the PHP language which were later published by the site Guidainlinea.com and other minor sites.

These guides cover various aspects of the PHP language and are targeted for a beginner audience. However, also some advanced topic is covered by these short manuals, especially in the FAQs. Topics range from basic usage of fundamental PHP built-in classes to the usage of some MySQL API calls. There are also some examples available inside.

These guides are available only in Italian language as a zip file containing HTML pages and can be downloaded here (about 32 KB).

If you want further information about my projects, please visit my software section.

No Comments

Intersteno.it/.org

Short introduction

The "Intersteno" is a world non-profit organization for fast typewriting. They study solutions to write faster, run courses and try to keep hand and type-writing technology at pace with the needs of government and private agencies.

For the world congress held in Rome (Italy) in July 2003, I was chosen to create a whole working site in 5 different languages which not only had to be fully functional with respect to the visitor, but also had to have the possibility of booking hotels, booking partecipation to the Congress and collecting results sent through the Internet for a special computer typing contest.

The site has been done in PHP and has many features, the most relevant of which is an administrative, multi-priviledged interface which lets you modify almost the whole site and collect almost every information within a few mouse-clicks.
This interface, being multi-priviledged, is the ideal for handling various section which must be run with respect to the
user’s actual privileges.

Internet contest

During the following years, I’ve created a software (TypingSoftware) that lets people do a keyboarding competition over the Internet, with the results being gathered from the central server (which happens to be intersteno.it).
This software has been used to organize several Internet competition among many world-wide schools in 2003, 2004, 2005 and 2006; currently, it is widely given in outsourcing to other keyboarding local organizations in Europe (Switzerland, Belgium, Turkey) in order to let them organize their own typing speed contests.

Screenshots

Here are two actual screenshots of the site: the left one is taken from one of the site pages, the right one is taken from the administrative pages.

Intersteno admin area

Intersteno public area
(click on the pictures to enlarge)

Visit the site

Click here to visit the site (please remember that the administrative interface is not available to the casual visitor)

The Congress

The Rome Congress I attended as an Organizing Committee member was very well made. Over 500 participants from all over the world came in Rome to attend the Congress, a Congress which was widely reckoned as the best Intersteno Congress ever made, thanks to the organization of Mr. Gian Paolo Trivulzio.

The greatest part of the Congress was kept in the astonishing majesty of the Sheraton Rome hotel, where I, with many others, worked very hard to make that Congress a reality.

I greatly enjoyed those days. Thanks Gian Paolo!

If you want further information about my projects, please visit my software section.

No Comments

css.php