function quoteId(id) {
	// quote les caractères d'un id pour inclusion dans un selector de jquery
	// par exemple: $("#" + quoteId(someValue))
	if (id.indexOf(":") != -1) id = id.replace(/:/g, "\\:");
	if (id.indexOf(".") != -1) id = id.replace(/\./g, "\\.");
	return id;
}
function stripPrefix(str, prefix) {
	// Si str commence par la chaine prefix, retourner cette chaine sans le préfixe.
	if (prefix !== undefined) {
		var len = prefix.length;
		if (str.slice(0, len) == prefix)
			str = str.slice(len);
	}
	return str;
}
function qid(prefix, obj, stripPrefix) {
	// Récupérer l'id de l'élément obj, enlever le préfixe 'stripPrefix' avec
	// stripPrefix(), insérer le préfixe 'prefix' au début, quoter le résultat
	// et préfixer avec "#"
	return "#" + quoteId(prefix + stripPrefix($(obj).attr("id"), prefix));
}
function delayer(delay) {
	// Retourner une fonction f(name, fn) qui appelle la fonction fn au bout de
	// delay milliscondes. f(name) annule l'appel retardé.
	var timeouts = {};
	return function(name, fn) {
		if (timeouts[name]) clearTimeout(timeouts[name]);
		if (fn) timeouts[name] = setTimeout(function() { fn(); }, delay);
		return timeouts[name];
	}
}

function placeUnder(element, reference) {
	// Positionner l'élément 'element' en dessous de l'élément 'reference'
	element = $(element);
	reference = $(reference);
	
	var offset = reference.offset();
	element.css({
		top: offset.top + reference.offsetHeight,
		left: offset.left,
	});
}
