Appel à enseignants/intervenants

September 26, 2012 § 2 Comments

Pour Mozilla, l’année universitaire 2012-2013 est l’année de Firefox OS, l’année des Open Web Applications et l’année à laquelle la communauté Mozilla lance sa campagne de libération des téléphones et applications portables !

Nous avons besoin de vous pour enseigner les technologies des Open Web Applications aux communautés francophones.
L’objectif des cours est de former des étudiants ingénieurs ou équivalents aux technologies nécessaires pour le développement ouvert d’applications web ouvertes. Nous cherchons notamment des enseignements sur les sujets suivants :
  • JavaScript avancé (clôtures, événements, prototypes, itérateurs/générateurs, timeouts)

Déroulement des cours

Autant que possible, les cours seront donnés en français face à une classe de MIAGE de  l’Université d’Évry, où ils seront aussi enregistrés. Les cours seront mis à disposition de toute la communauté Mozilla francophone dans le cadre de Mozilla Education. Les documents correspondants seront eux-mêmes mis à  disposition sous licence libre sur github.
Si  vous ne pouvez pas vous rendre à Évry, mais si vous pouvez enregistrer des cours par vous-mêmes, n’hésitez pas à nous contacter. Nous mettrons vos cours à disposition du public francophone.
Si vous avez d’autres idées, n’hésitez pas à nous les proposer. En ce moment, nos capacités d’enregistrement sont limitées mais nous ferons notre possible pour enregistrer et mettre votre cours à disposition.

Pour participer

  • Si vous pouvez assurer ces cours (entièrement ou en partie), suivez les liens ci-dessus
  • Pour proposer d’autres cours que vous pouvez vous-même assurer, ajoutez la description de vos cours sur (cliquez sur “New issue”). Précisez si vous avez des contraintes géographiques ou besoin de matériel spécifique.

Et après ?

Notre objectif est d’étendre cette initiative hors de la région parisienne et surtout hors de France. Nous espérons notamment pouvoir organiser des cours en Afrique Francophone. La suite au prochain épisode !




C data finalization – in JavaScript

May 2, 2012 § 4 Comments

A few iterations ago, the Mozilla Platform introducefd js-ctypes, a very nice Foreign Function Interface (FFI) for JavaScript. As its inspiration, Python’s ctypes, js-ctypes lets (privileged) JavaScript code open native libraries, import their functions and call these functions almost as if they were regular JavaScript functions.

Here is an example using the Unix libc:

// Open the C library
let libcCandidates = [
  'libSystem.dylib',// MacOS X
  '',      // Linux
  ''         // Android, B2G
let libc;
for each(let candidate in libcCandidates) {
  libc =;
  if (libc) {

// Import some functions from libc
let open = libc.declare("open", ctypes.default_abi,
  /*return int*/,
  /*const char* path*/ctypes.char.ptr,
  /*int oflag*/
  /*int mode*/;
let read ="read", ctypes.default_abi,
  /*return ssize_t*/ ctypes.ssize_t,
  /*int fildes*/,
  /*void *buf*/ ctypes.voidptr_t,
  /*size_t nbytes*/ ctypes.size_t);
let close ="close", ctypes.default_abi,
  /*return int*/,
  /*int fd*/;

// Now use them
let myfile = open("/etc/passwd", 0, 0);
if (myfile == -1)
  throw new Error("Could not open file");
// ...

If you are familiar with XPConnect, the mechanism generally used in the Mozilla Platform for letting JavaScript and C++ interact, you can see that using js-ctypes to call native code directly is much nicer than adding a C++ XPCOM/XPConnect layer. From what I hear, it seems to be also much faster, as XPConnect needs to perform expensive magic to ensure that memory is properly passed between JavaScript and C++. In addition, this selfsame memory magic now prevents XPConnect from being executed from threads other than the main thread, which makes js-ctypes the only manner of doing any system access from worker threads.

Now, js-ctypes nicely solves the issue of calling native code from JavaScript. However, JavaScript and C are very different languages, with very different paradigms, so getting them to coexist requires a little more than simply the ability to place calls or convert values. In particular, C has:

  • manual resource management (memory must be released, file descriptors must be closed, locks must be released, etc.);
  • no language-level mechanism for error management (a task smaller than a process cannot be killed because of an error).

By contrast, Javascript has:

  • automated memory management, but no support for managing automatically resources other than memory (no user-level finalization or scoped resources mechanism);
  • several language/vm-level mechanisms that can kill a task in non-trivial manners (exceptions, “this script is busy”, etc.)

Unfortunately, putting all of this together makes it quite difficult to write JavaScript code that manipulates C resources without leaking. Such leaks can cause both performance issues (memory leaks, in particular, tend to slow down the whole system) and hard-to-track errors (leaking file descriptors can prevent the application from opening any new file, or, under Windows, can prevent the application from reopening some files that were improperly closed, while leaking locks can completely freeze an application).

Introducing C data finalization

For this reason, we have recently added a new features to js-ctypes, designed to add automated resource management to JavaScript: C data finalization.

Specifying a finalizer is simple:

function openfile(path, flags, mode) {
  let fd = open(path, flags, mode);
  if (fd == -1) {
    throw new Error("Could not open file " + path);
  return ctypes.CDataFinalizer(fd, close);

What this code does is ensure that, whenever the file descriptor is garbage-collected, function close is called, releasing the C resources represented by that file descriptor. This value is C data with a finalizer, aka CDataFinalizer.

You can use it just as you would use the C data through js-ctypes:

let myfile = openfile("/etc/passwd", 0, 0);
let result = read(myfile, myarray, 4096); // Read some data
// Wherever required, |myfile| is automatically converted to
// the underlying integer value.
// Once |myfile| has no reference, it will (eventually) be
// closed.

It is, of course, possible (and strongly recommended) to close the file manually to ensure that resources are immediately available for the process and the rest of the system:

let myfile = openfile("/etc/passwd", 0, 0);
// ...
// ... do whatever you wish to do with that file
let result = myfile.dispose(); // This calls |close|.

// From this point, |myfile| cannot be converted to the underlying
// integer value anymore. Any attempt to do so will raise an
// exception.

Or, an equivalent but more verbose solution, using forget:

let myfile = openfile("/etc/passwd", 0, 0);
// ...
// ... do whatever you wish to do with that file
let fd = myfile.forget();
// From this point, |myfile| cannot be converted to the underlying
// integer value anymore. Any attempt to do so will raise an
// exception.
let result = close(fd);

This mechanism is, of course, not restricted to file descriptors. It has been used with success to other data structures, including malloc-allocated strings.

Details and caveat

JavaScript does not feature finalization and might never do so. There are good reasons for this: finalization considerably complicates the garbage-collector and introduces the possibility of subtle bugs and leaks that the various JS implementors do not want to inflict to their users (if you are curious, two of the main problems are resurrection of dead references and finalization of cyclic data structures).

Consequently, C data finalizers are not full-featured finalizers. Indeed, the main limitation of C data finalizers is that its first argument must be a C value and its second argument must be a pointer to a C function – for the above mentioned reasons, letting users specify any JavaScript function as a finalizer would open a can of worms that nobody really wants to see crawling around.

Also, before using a finalizer, you should be aware that JavaScript garbage-collection is not necessarily deterministic – during the testing phase of CDataFinalizer, we have encountered memory errors caused by developers (ok, I will confess, that was me, sorry guys) making invalid assumptions about just when values would be garbage-collected. Let me emphasize this: any hypothesis you make about when a value is finalized is bound to be regularly false. In other words, C data finalizers should be used as a last line of defense, not as the default mechanism for recovering resources.

Still, C data finalizers are a powerful mechanism that make manipulation of C values with JavaScript much more reliable. Indeed, it is one of the core mechanisms used pervasively by the OS.File library.

edit As per Steve Fink’s suggestion, I have emphasized that users should not rely on the behavior of garbage-collection/finalization, and clarified the can of worms.

Student projects update

February 2, 2012 § 1 Comment

As mentioned previously on this page, the Mozilla Community is very interested in collaborating with universities around student projects. I am personally mentoring or co-mentoring a few of these projects and I will try to blog about their progress regularly.

Note to the students I can only blog if you tell me your current status!

Note to other students Do you want to take part in an open-source / open web project? Then feel free to contact me, I will be glad to help you or to introduce you to someone who might. You can find me on Tweeter (ImYoric), by e-mail, on (dteller), or by IRC, on, channel #introduction (Yoric).

Save as .epub (Firefox add-on)

(Kevin CORRE, Benjamin ROCHER, Elie AHUMA, Sylvestre ANTOINE – Université d’Orléans, MIAGE 2)

Objective Add the following feature to Firefox, as an add-on: Save a page and its resources as one file, using open standard .epub. This open-standard file can then be transferred to just about any device, edited with LibreOffice, etc.

Current status Early stage of coding. The first items of the user interface are in place, as well as some experiments regarding how to create an .epub file.

Follow this project This project lives on github.

Detect use of the wrong account (Thunderbird add-on)

(Baptiste MEYNIER, Johan JANS, Maxime DENOYER, Mustapha OUCHEIKH – Université d’Orléans, MIAGE 2)

Objective Add the following feature to Thunderbird, as an add-on: Detect that a message is being sent to a correspondant using the wrong account (e.g. using a professional account for a personal message or a personal account for a professional message).

Current status Early stage of coding. The first items of the user interface are in place, as well as some experiments regarding how to react to the user clicking on “send”.

Follow this project This project lives on github.

Simplify the addition of several alarms for the same event in Lightning (Thunderbird add-on)

(Loïc LE MÉRO aka Morkai – Université d’Évry, MIAGE 2)

Objective Lightning offers the ability to add several alarms for the same event (e.g. 1 day before then 15 minutes before). Improve the user interface to make this more discoverable.

Current status (unknown, waiting for Loïc to tell me).

Follow this project This project lives on Bugzilla.

Extend Lightning alarms (Thunderbird add-on)

           (Anto DOMINIC PAUL – Université d’Évry, MIAGE 2)

Objective Lightning offers the ability to attach alarms to an event. Extend this feature to make it possible to play a music or execute a script when the alarm is triggered.

Current status (unknown, waiting for Arno to tell me).

Follow this project This project lives on Bugzilla.

Handle resources in Lightning events (Thunderbird add-on)

(Julien LACROIX – Université d’Évry, MIAGE 2)

Objective Add the ability to attach resource requirements to events: a picnic requires food (one resource), drinks (one resource), cutlery (one resource), etc… Who will bring them? Also, add the ability to attach a geolocation to events, to help finding the way. Who brings the beer?

Current status Early stages of coding. First prototype of geolocation implemented, and work on requirements added.

Follow this project This project lives on github.

Remind me that I need to reply within 24h/remind me that I expect a reply within 24h (Thunderbird add-on)

(Vincent LEGUEVEL, Mickael MAINGE – Université d’Évry, MIAGE 2)

Objective Add the ability to mark a message as “I need to answer within …” / “I expect an answer within …”. Nag the user as long as she hasn’t sent or received the reply.

Current status (unknown, waiting for Vincent or Mickael to tell me more)

Follow this project This project lives on two Bugzilla bugs: need to send / expect to receive.

Call For Classrooms

January 17, 2012 § 1 Comment

(and Researchers, Professors, Teachers, Students …)

Mozilla is working with numerous educators, professors and researchers across the world, both to bring open-source, the open web and web technologies into the classroom, and to bring the contributions of students and their mentors to the world. You can be a part of this, and your field does not have to be Computer Science.

« Read the rest of this entry »

Introducing JavaScript native file management

December 6, 2011 § 28 Comments


The Mozilla Platform keeps improving: JavaScript native file management is an undergoing work to provide a high-performance JavaScript-friendly API to manipulate the file system.

The Mozilla Platform, JavaScript and Files

The Mozilla Platform is the application development framework behind Firefox, Thunderbird, Instantbird, Camino, Songbird and a number of other applications.

While the performance-critical components of the Mozilla Platform are developed in C/C++, an increasing number of components and add-ons are implemented in pure JavaScript. While JavaScript cannot hope to match the speed or robustness of C++ yet (edit: at least not on all aspects), the richness and dynamism of the language permit the creation of extremely flexible and developer-friendly APIs, as well as quick prototyping and concise implementation of complex algorithms without the fear of memory errors and with features such as higher-level programming, asynchronous programming and now clean and efficient multi-threading. If you combine this with the impressive speed-ups experienced by JavaScript in the recent years, it is easy to understand why the language has become a key element in the current effort to make the Mozilla Platform and its add-ons faster and more responsive at all levels.

« Read the rest of this entry »

Stages chez Mozilla Paris… ou ailleurs

November 19, 2011 § 1 Comment

edit Nous sommes pleins jusqu’à Juin. Nous ne pouvons plus prendre de stagiaires sur Paris dont les stages commencent avant Juin.

Comme tous les ans, Mozilla propose des stages en informatique, orientés Développement, R&D ou Recherche. Selon le sujet, le stage peut vous emmener à Paris, aux États-Unis, au Canada, en Chine…

À propos de Mozilla

La Fondation Mozilla est une association à but non-lucratif, fondée pour encourager un Internet ouvert, innovant et participatif. Vous avez probablement entendu parler de Mozilla Firefox, le navigateur open-source qui a réintroduit sur le web les standards ouverts et la sécurité, ou de Mozilla Thunderbird, le client de messagerie multi-plateforme, open-source et extensible. Les activités de Mozilla ne s’arrêtent pas à ces deux produits et se prolongent à de nombreux projets pour le présent et l’avenir, tels que :

  • Boot-to-Gecko, système d’exploitation totalement ouvert et construit par la communauté, pour les téléphones portables, tablettes et autres machines communicantes ;

  • SpiderMonkey, une famille de Machines Virtuelles conçues pour l’analyse statique et dynamique, la compilation et l’exécution des langages web, en particulier JavaScript ;
  • DeHydra et JSHydra, outils d’analyse statique pour les langages C++ et JavaScript ;

  • Rust, un nouveau langage de programmation conçu pour le développement d’applications système parallèles sûres ;

  • WebAPI, un ensemble d’outils qui permettent d’étendre les capacités des applications web au-delà de celles des applications traditionnelles, la sécurité et la confidentialité en plus ;

  • Gecko, le moteur de rendu extensible et portable pour le HTML, le XML et les interfaces graphiques, qui a permis Firefox, Thunderbird et de nombreuses autres applications ;

  • BrowserID, une technique innovante qui fournit aux utilisateurs et aux développeurs les outils cryptographiques pour assurer l’identification sur le web, sans compromettre la vie privée, la simplicité ou la sécurité ;

  • les fonctionnalités Mozilla Services de gestion d’identité par le Cloud ;

  • et d’autres encore…

À propos de vous

Mozilla proposes plusieurs stages dans ses installations à travers le monde sur de nombreux sujets.

Votre profil :

  • vous voulez faire du web un endroit meilleur, sur lequel chacun peut naviguer et contribuer en toute sécurité, sans avoir à craindre pour sa sécurité ou sa vie privée ;
  • vous souhaitez prendre part à un projet utilisé par plus de 33% de la population du web ;
  • vous voulez que votre travail soit utile à tous et visible par tous ;
  • vous avez de fortes compétences en Algorithmique et en Informatique ;
  • vous avez de fortes compétences dans au moins l’un des domaines suivants :
    • systèmes d’exploitation ;
    • réseaux ;
    • géométrie algorithmique ;
    • compilation ;
    • cryptographie ;
    • analyse statique ;
    • langages de programmation ;
    • extraire des informations pertinentes à partir de données exotiques ;
    • algorithmique distribuée ;
    • le web en tant que plate-forme ;
    • interactions avec les communautés du logiciel libre ;
    • toute autre compétence qui, à votre avis, pourrait nous servir.
  • sur certains sujets, un excellent niveau d’Anglais peut être indispensable ;
  • les stages sont généralement prévus pour des étudiants M1 ou M2 mais si vous arrivez à nous impressionner par vos réalisations ou par vos connaissances, le diplôme n’est pas indispensable.

Si vous vous reconnaissez, nous vous invitons à nous contacter. En fonction du sujet, les stages peuvent vous emmener à Paris, Mountain View, San Francisco, Toronto, Taipei, ou d’autres lieux à travers le monde.

Les meilleurs stagiaires peuvent espérer un contrat freelance, un CDI ou/et une bourse de doctorat.

Pour nous contacter

Pour toute question, contactez :

  • pour tout ce qui concerne les stages chez Mozilla, Julie Deroche (à, jderoche) – Mozilla Mountain View, College Recruiting ;
  • pour les stages à Paris, David Rajchenbach-Teller (à, dteller) – Mozilla Paris, Développeur / Chercheur.

First look at Google Dart

October 13, 2011 § 4 Comments

A few weeks ago, the browser and web development communities started wondering about this mysterious new web language that Google was about to unveil: Dart. Part of the interrogation was technical – what would that language look like? how would a new language justify its existence? what problems would it solve? – and part was more strategic – what was Google doing preparing a web language in secret? where the leaked memos that seemed to imply a web-standards-breaking stance something that Google would indeed pursue? was Google trying to solve web-related problems, Google-related problems or Oracle-related problems?

Now, Google has unveiled the specifications of Dart, as well as library documentation. Neither will be sufficient to answer all questions, but they give us an opportunity to look at some of the technical sides of the problem. As a programming language researcher/designer and a member of the web browser community, I just had to spend some quality time with the Dart specifications.

So, how’s Dart? Well, let’s look at it.

What Dart is

Dart is a programming language and a Virtual Machine. As a programming language, Dart positions itself somewhere in the scope between scripting/web development and application development. From the world of application development, Dart brings

  • clean concurrency primitives that would feel at home in Scala, Clojure or Erlang – including a level of concurrent error reporting;
  • a clean module mechanism, including a notion of privacy;
  • a type system offering genericity, interfaces and classes;
  • compilation and a virtual machine;
  • a library of data structures;
  • no eval();
  • data structures that do not change shape with time.

From the world of scripting/web development, Dart brings:

  • usability in any standards-compliant browser, without any plug-in (although it will work better in a plug-in and/or in Chrome);
  • DOM access;
  • emphasis on fast start-up;
  • a liberal approach to typing (i.e. types are optional and the type system is incorrect, according to the specifications);
  • dynamic errors;
  • closures (which are actually not scripting/web development related, but until Java 8 lands or until Scala, F# or Haskell gain popularity, most developers will believe that they are).

Where Dart might help

Web development has a number of big problems. I have trolled written about some of them in previous posts, and Dart was definitely designed to help, at least a little.


JavaScript is interpreted, can be written inline in html and supports eval(). By opposition, Dart code is compiled. Dart does not have eval() and Dart code is not written inline in html. Consequently, Dart itself offers a smaller attack surface for cross-site scripting.  Note that Dart can still be used as a component for a XSS targeting the document itself, and that using Dart does not prevent an attacker from using JavaScript to inject XSS in the page.

Safety and Code Hygiene

Out-of-the-box, JavaScript does not offer any static or hybrid typing. Dart offers (optional, hybrid) typing. This is a very useful tool for helping developers and developer groups find errors in their code quickly.

JavaScript offers prototype-based object-oriented programming, without explicit private methods/fields. By opposition, Dart offers modules, classes (with support for private methods/fields) and interfaces. Again, very useful for providing abstractions that do not leak [too much].

For historical reasons, JavaScript offers weird and error-prone scoping and will let developers get away without realizing that they are dereferencing undefined variables. Dart does away with this. Again, this is a good way to find errors quickly.


Out-of-the-box, JavaScript does not provide data structures, or much in the way of libraries. By opposition, Dart provides a few data structures and libraries.


For a long time, JavaScript exceptions were not extensible. Eventually, it became possible to define new kinds of exceptions. However, JavaScript still doesn’t support matching the exception constructor, by opposition to what almost all other programming languages do. Dart makes no exception and allows matching upon the exception constructor. This makes exception-handling a little nicer and debugging exception traces a little more robust.


For a long time, JavaScript did not provide any form of concurrency primitive. Recent versions of JavaScript do offer Workers. Similarly, Dart offers Isolates, with a paradigm very similar to Workers. Where Workers are always concurrent, Isolates can also be made non-concurrent, for better performance at the expense of reactivity. Initialization and error-reporting are also a little different, but otherwise, Isolates and Workers are quite comparable.


Dart promises better speed than JavaScript. I cannot judge about it.


Dart offers “string interpolation” to insert a value in a string. Nice but not life-altering. Also, out-of-the-box, JavaScript DOM access is quite verbose. By opposition, Dart provides syntactic sugar that makes it a little nicer.

Where Dart might hinder

Vendor control/adoption

The single biggest problem with Dart is, of course, its source. To get the VM in the browsers, Google will have to convince both developers and other browser vendors to either reimplement the VM by themselves or use a Google-issued VM. This is possible, but this will be difficult for Google.

The open vehicle for this is to convince developers to us Dart for server-side programming – where Dart will be competing with Java, Scala, C#, F#, Python, JavaScript, Erlang and even Google’s Go – and for client-side programming by getting through JavaScript – which will severely hinder performance, safety and security.

The vendor controlled vehicle will be to integrate the VM in Chrome and Android and encourage developers targeting the Chrome Market and Android Market to use Dart. Some speculate that this is a manner for Google to get rid of the Java dependency on the Android Market. In this case, of course, there will be little competition.

Libraries and documentation

JavaScript has a host of libraries and considerable documentation. I will admit that much of the documentation one may find around the web is not good (hint: use Mozilla’s documentation, it is the only reliable source I have found), but that is still infinitely more than what Dart can provide at the moment.

In other words, for the moment, Dart cannot take advantage of the special effects, the game-building libraries, the streaming libraries, etc. that have been developed for JavaScript. This, of course, is something that Google has the resources to change relatively fast, but, by experience, I can tell that many developers are averse to relearning.

Doing it without Dart


We’re not going to get rid of XSS without some effort, even with Dart. However, making sure that JavaScript offers an attack surface no larger than Dart is easy: forbid eval() and forbid any inline JavaScript. It would be quite easy to add an option to HTML documents to ensure that this is the case. Note that this option remains necessary even if all the code is written in Dart, as Dart does not prevent from injecting JavaScript.

Code Hygiene

Out-of-the-box, JavaScript does not offer any support for static/hybrid typing. However, Google has demonstrated how to add static typing with the Google Closure Compiler and Mozilla has demonstrated how to add hybrid typing with Dynamic Type Inference. Both projects indicate that we can obtain something at least as good as Dart in JavaScript, without altering/reinventing the language.

Out-of-the-box, JavaScript does not offer modules. However, Mozilla has been offering a module system for JavaScript for years and new versions of the language are in the process of standardizing this.

Also, while classes and private fields are probably the least surprising techniques for application developers coming to the web, developers used to dynamic or functional languages know that closures and prototypes are essentially equivalent. So, this is essentially a matter of taste.

Finally, clean, lexical scoping will be welcomed by all developers who know what these words mean and quite a few others. Fortunately, it is also coming to JavaScript with recent versions of the language.


Isolates are nice. Workers are nice. Isolates are a little easier to set-up, so I would like to see an Isolate-like API for Workers. Other than that, they are essentially equivalent.


So far, Google has always managed to deliver on speed promises with V8, so I would tend to believe them. However, recent improvements in JavaScript analysis also promise to analyze away all the cases that can make JavaScript slower than Java, and I also tend to believe these promises. Consequently, I will venture no guess about it.


It is a shame that JavaScript does not come with more libraries. However, many frameworks are available that implement standard data structures and more.


Dart exceptions are a little nicer than JavaScript exceptions, there no doubt about that. However, making JavaScript exceptions as good as Dart exceptions would be quite simple. The only difficulty is getting this improvement into the standard.


String interpolations are nice to have, but not really life-altering. If necessary, they can trivially be implemented by a pre-processor. CoffeeScript might already do it, I’m not sure. Adding this to the JS standard might be tricky, for reasons of backwards compatibility, but there is not much to it.

Dart-style DOM access is nice, too. However, adding this to JavaScript would be quite trivial, in particular with next-generation DOM implementations such as dom.js.

The result

I admit that I am a little disappointed. When Dart was announced, I was hoping something truly evolutionary. So far, what I have found out is a nice language, certainly, but not much more. While Dart is definitely better in many aspects than today’s JavaScript, given the current evolution of JavaScript, none of these aspects is a deal-breaker. However, several aspects of Dart (in particular, typing and exceptions) indicate a good direction in which I believe JavaScript should evolve, and I hope that the presence of Dart can get JavaScript standardization moving faster.

If we consider I my opinion, there are three ways that Google can get Dart adopted on the web:

  • make it the default choice for Android & Chrome development;
  • provide a set of killer libraries for the web, that work on all browsers but are truly usable only with Dart (DirectX anyone? something Cocoa-style, perhaps?);
  • spend Google-sized budgets on adoption (PR, marketing, GSoC, open-source projects, etc.).

Nevertheless, for the moment, I will keep far away from Dart and look hopefully at Scala-GWT, WebSharper or Ocsigen.

Where Am I?

You are currently browsing entries tagged with open-source at Il y a du thé renversé au bord de la table.