Samx Here
n1udSecurity


Server : Apache
System : Linux ks5.tuic.fr 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64
User : pragmatice ( 1003)
PHP Version : 8.2.24
Disable Function : NONE
Directory :  /home/pragmatice/public_html/tnifacile/_materiaux/_temporaire/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/pragmatice/public_html/tnifacile/_materiaux/_temporaire/fts_communes.js

/* Crédits de TNI Facile et de ses modules */
function creditsEtc() {
	var c= "";
	c+= "<div class='cred_haut' style='text-align:center;'><button data-cred='mentions' class='btn btn-info btn-petit bt_mentions'>Mentions légales</button> <button data-cred='cgu' class='btn btn-info btn-petit bt_mentions'>C.G.U.</button> <button data-cred='credits' class='btn btn-info btn-petit bt_credits'>Crédits</button> <button data-cred='historique' class='btn btn-info btn-petit bt_historique'>Historique</button> <button data-cred='partager' class='btn btn-info btn-petit bt_partager'>Partager</button></div>";
	c+= "<div class='cred_bas' style='margin-bottom:10px;'>";
	c+= "<div class='mentions'><h5>Editeur</h5><div><a href='http://pragmatice.net/lesite/spip.php?page=pragmatice' target='_blank'>Association PragmaTICE</a></div><h5>URL</h5><div><a href='http://tnifacile.fr' target='_blank'> http://tnifacile.fr</a></div><h5>Hébergement</h5><div><a href='https://www.ovh.com/fr/' target='_blank'>OVH</a></div><h5>Contact</h5><div><a href='http://pragmatice.net/lesite/spip.php?page=contact' target='_blank'>Envoyer un message</a> à PragmaTICE</div></div>";
	c+= "<div class='cgu'><h5>Public et accès au site</h5><div><p>TNI Facile est un portail Web multiplateforme pour tableau interactif, sans publicité ni compte à créer, destiné à l'école primaire <em>(maternelle et élémentaire)</em>. Il est accessible gratuitement en tout lieu à tout utilisateur ayant un accès à Internet.</p></div><h5>Données personnelles</h5><div><p>Les données <em>(prénoms des élèves, activités et événements du calendrier)</em> sont enregistrées dans un espace dédié du navigateur Web <em>(Web Storage)</em>. Elles peuvent être effacées lorsque l'on vide l'historique du navigateur, selon les options choisies.</p><p>Ces données sont enregistrées exclusivement sur le poste à partir duquel elles sont consultées. Aucune donnée n'est récupérée ni stockée sur les serveurs de PragmaTICE.</p></div><h5>Responsabilités</h5><div><p>PragmaTICE met en oeuvre tous les moyens mis à sa disposition pour assurer un accès de qualité à ses services. L'obligation étant de moyens, le site ne s'engage pas à atteindre ce résultat.</p><p>Tout événement dû à un cas de force majeure ayant pour conséquence une perte de données ou un dysfonctionnement du réseau ou du serveur n'engage pas la responsabilité de PragmaTICE.</p><p>L'accès aux services du site peut à tout moment faire l'objet d'une interruption, d'une suspension, d'une modification sans préavis pour une maintenance ou pour tout autre cas. L'utilisateur s'oblige à ne réclamer aucune indemnisation suite à l'interruption, à la suspension ou à la modification des conditions d'utilisation.</p></div><h5>Liens hypertextes</h5><div><p>De nombreux liens hypertextes sortants sont présents sur le site, cependant les pages web où mènent ces liens n'engagent en rien la responsabilité de PragmaTICE qui n'a pas le contrôle de ces liens.</p><p>L'utilisateur s'interdit donc à engager la responsabilité du site concernant le contenu et les ressources relatives à ces liens hypertextes sortants.</p></div></div>";
	c+= "<div class='credits'><h5>Conception et développement</h5><div>Eric Chenavier</div><h5>Ressources associées</h5><div>Rubrique <a href='http://pragmatice.net/lesite/spip.php?rubrique8' target='_blank'>Applications Web pour TNI</a> du site de PragmaTICE, extraits de <a href='http://pragmatice.net/pragmactivites/ealor/' target='_blank'>EALOR</a> et <a href='http://pragmatice.net/pragmactivites/lectorbus/' target='_blank'>LectOrBus</a></div><h5>Images</h5><div><a href='http://www.art4apps.org/images/' target='_blank'>Arts 4 Apps</a>, <a href='https://www.flaticon.com/' target='_blank'>Flaticon</a>, <a href='http://www.iconfinder.com/' target='_blank'>Iconfinder</a>, <a href='http://www.isaac-fr.org/type-outils/pictogrammes/' target='_blank'>ISAAC FR</a>, <a href='http://pixabay.com/fr/' target='_blank'>Pixabay</a></div><h5>Sons</h5><div><a href='https://www.bensound.com/' target='_blank'>Bensound.com</a>, <a href='http://www.universal-soundbank.com/' target='_blank'>Universal-Soundbank bruitages gratuits</a></div><h5>Synthèse vocale</h5><div><a href='https://responsivevoice.org/' target='_blank'>Responsive Voice JS</a></div><h5>Traductions</h5><div>Olivier Baltassat pour l'anglais et l'italien, Jean-Christophe Dye pour l'espagnol et Nicolas Picot pour l'allemand</div><h5>Tests & suggestions</h5><div>Frantz Céron, Sandrine Céron, Anne Delezenne, Patricia Eglaine, Thierry Labat, Frédéric Mathy, Nadège Serclérat</div><h5>Frameworks & plugins</h5><div><a href='https://getbootstrap.com/docs/3.3/' target='_blank'>Bootstrap 3</a>, <a href='https://jquery.com/' target='_blank'>Jquery</a>, <a href='https://jqueryui.com/' target='_blank'>JQuery UI</a>, <a href='https://github.com/jeromeetienne/jquery-qrcode' target='_blank'>Jquery.qrcode</a>, <a href='http://www.greywyvern.com/code/javascript/keyboard' target='_blank'>Virtual Keyboard Interface</a>, <a href='https://zenorocha.github.io/clipboard.js' target='_blank'>Clipboard.js</a>, <a href='https://html2canvas.hertzen.com/' target='_blank'>Html2canvas.js</a>, <a href='https://summernote.org/' target='_blank'>Summernote</a> </div></div>";
	c+= "<div class='historique'><h5>2 septembre 2018</h5><div>Mise en ligne du site, comprenant les widgets et autres ressources de la page d'accueil, TNI Etiquettes; TNI Quiz, TNI Nombres <em>(13 applications)</em> et TNI Rituels <em>(17 applications)</em></div></div>";
	c+= "<div class='partager'>";
	c+= "Faire découvrir ce site...";
	c+= "<a target='_blank' title='Twitter' href=\"https://twitter.com/share?url="+document.location.href+"&text="+$('title').text()+"\" rel='nofollow' onclick=\"javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=400,width=700');return false;\"><img style='margin:5px;' src='images/logo_partage_twitter.png' alt='Twitter' /></a>";
	c+= "<a target='_blank' title='Facebook' href=\"https://www.facebook.com/sharer.php?u="+document.location.href+"&t="+$('title').text()+"\" rel='nofollow' onclick=\"javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=500,width=700');return false;\"><img style='margin:5px;' src='images/logo_partage_facebook.png' alt='Facebook' /></a>";
	c+= "<a target='_blank' title='Google +' href=\"https://plus.google.com/share?url="+document.location.href+"&hl=fr\" rel='nofollow' onclick=\"javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=450,width=650');return false;\"><img style='margin:5px;' src='images/logo_partage_gplus.png' alt='Google Plus' /></a>";
	c+= "<a target='_blank' title='Linkedin' href=\"https://www.linkedin.com/shareArticle?mini=true&url="+document.location.href+"&title="+$('title').text()+"\" rel='nofollow' onclick=\"javascript:window.open(this.href, '','menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=450,width=650');return false;\"><img style='margin:5px;' src='images/logo_partage_linkedin.png' alt='Linkedin' /></a>";
	c+= "<a target='_blank' title='Envoyer par mail' href=\"mailto:?subject="+$('title').text()+"&body=Bonjour,%0D%0A%0D%0AVoici le lien vers un site très pratique pour organiser sa classe et faire progresser ses élèves :%0D%0A"+document.location.href+"%0D%0A%0D%0ABonne découverte !\" rel='nofollow'><img style='margin:5px;' src='images/logo_partage_email.png' alt='email' /></a>";
	c+= "<p>Si vous avez testé TNI Facile ou un de ses modules <em>(TNI Etiquettes, TNI Nombres, TNI Quiz ou TNI Rituels)</em>, et publié un article qui présente cet outil, vous pouvez nous <a href='http://pragmatice.net/lesite/spip.php?page=contact' target='_blank'>envoyer son URL</a> pour qu'il soit référencé ci-dessous...</p>";
	c+= "</div>";
	c+= "</div>";// fin div .cred_bas
	$('.credits_etc').html(c);
	$('.cred_haut button').click(function () {
        var choix = $(this).attr('data-cred');
		$('.cred_haut button').removeClass('btn-primary').addClass('btn-info');
		if ($("."+choix).is(":hidden")) {
			$('.cred_bas > div').hide();
			$("."+choix).slideDown();
			$(this).removeClass('btn-info').addClass('btn-primary');
		}
		else {
			$("."+choix).slideUp();
		}
    });
}

/* Mélanger les éléments d'un tableau https://css-tricks.com/snippets/javascript/shuffle-array/ */
function shuffle(o) {
	for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
	return o;
}

/* Remplacer les occurrences http://cwestblog.com/2011/07/25/javascript-string-prototype-replaceall/ */
String.prototype.replaceAll = function(target, replacement) {
  return this.split(target).join(replacement);
};

/* Récupérer l'URL sans les paramètres */
function urlSansParam() {
	var urlSansParam = document.location.href;
	if (document.location.href.indexOf("?") != -1)	urlSansParam = document.location.href.substring( 0 ,document.location.href.lastIndexOf( "?" ) );
	return urlSansParam;
}

/* Récupérer l'URL sans les paramètres */
function urlSansParamNiDiese() {
	var urlSansParam = document.location.href;
	if (document.location.href.indexOf("?") != -1)	urlSansParam = document.location.href.substring( 0 ,document.location.href.lastIndexOf( "?" ) );
	urlSansParam = urlSansParam.replace('#','');
	return urlSansParam;
}

/* Changer l'url sans echarger la page */
function ChangeUrl(page, url) {
	if (typeof (history.pushState) != "undefined") {
		var obj = {Page: page, Url: url};
		history.pushState(obj, obj.Page, obj.Url);
	} else {
		window.location.href = "homePage"; // alert("Browser does not support HTML5.");
	} //ChangeUrl('Page1', 'homePage'); 
}

/* Supprimer les doublons d'un tableau https://www.unicoda.com/?p=579 */
function cleanArray(array) {
  var i, j, len = array.length, out = [], obj = {};
  for (i = 0; i < len; i++) {
    obj[array[i]] = 0;
  }
  for (j in obj) {
    out.push(j);
  }
  return out;
}
// var nbr = [42, 101010, 7, 42, 7, 42, 101010];
// var newNbr = cleanArray(nbr);

/* Cloner un tableau https://davidwalsh.name/javascript-clone-array */
Array.prototype.clone = function() {    
	var clone = [];
	for(var i in this)
	{
		clone[i] = this[i]
	}    
	return clone;
};

// Générer un nombre entier aléatoire compris entre les 2 bornes (bornes comprises)
function aleatoire(min, max) {
	return (Math.floor((max-min+1)*Math.random())+min);
}

// Ecrire un nombre en imposant le nombre de chiffres de sa partie décimale
function arrondirDec(nb,nbDec) {
	var num = nb;
	var n = num.toFixed(nbDec);
	return n;
}

/* Trier un tableau de nombres https://www.miximum.fr/blog/trier-un-tableau-de-nombres-avec-javascript/ */
function nombresCroissants(x, y) {
    return x - y;
}
function nombresDecroissants(x, y) {
    return y - x;
}

/* Mettre le premier caractère en majuscule /*/
function majPremCar(chaine) {
	return chaine.replace(chaine[0],chaine[0].toUpperCase());
}

// Gérer le plier déplier de la doc
function gererPlierDeplierDoc() {
	$(".contenu_doc h4").next().hide();
	$(".contenu_doc h4").click(function(){
		var lancre = $(this).attr('id');
		$(".contenu_doc h4").next().slideUp();
		if ($(this).next().is(":visible")) {
			$(this).next().slideUp();
		}
		else {
			$(this).next().slideDown();
			if (lancre !== "undefined") setTimeout(function(){$('html,body').animate({scrollTop: $("#"+lancre).offset().top}, 'slow');}, 500);
		}
	});
	// Afficher tous les paragraphes de la doc
	$('body').on('click', '.bt_doc_afficher', function () {
		$(".contenu_doc > div").slideDown();
	});
}

/* Jouer un son */
function jouerSon(son) { 
	var leson = new Audio();
	leson.src = son;
	leson.play();
}

/* Gérer la flèche de retour en haut de page */
function retourHaut() {
	$(window).scroll(function() {
		//	Afficher le bouton si absence d'ascenseur
		if ( $(window).scrollTop() == 0 ) $('#returnOnTop').fadeOut();
		else $('#returnOnTop').fadeIn();
	});
}

// Ajouter 1 à z-index pour placer l'élément sélectionné au premier plan
function chercherZindexWidgetDeplacableSuivant() {
	$('.widget_deplacable').each(function(){
		var lindex = $(this).css("z-index");
		tabZindexWD.push(parseInt(lindex));
	});
	var max=0;
	for (i=0 ; i < tabZindexWD.length ; i++) {
		if (tabZindexWD[i] > max) max = tabZindexWD[i];
	}
	return max+1;
}

/* Activer le rideau => class .bt_rideau */
var tabZindexWD = [];
function activerRideau() {
	$('.bt_rideau').click(function () {
		if ($('.bt_rideau').hasClass('on')) {
			$('.bt_rideau').removeClass('on').attr('src','images/icone_bt_rideau_on_24.png').attr("title","Afficher le rideau");
			$('#tnif_rideau').hide();
		} else {
			$('.bt_rideau').addClass('on').attr('src','images/icone_bt_rideau_off_24.png').attr("title","Supprimer le rideau");
			if (!$("#tnif_rideau").hasClass('deja_utilise')) {
				var lRideau = $(window).width()-20;
				var hRideau = $(window).height()-60;
				$("#tnif_rideau").css('width',lRideau+'px').css('height',hRideau+'px').addClass('deja_utilise');
			}
			// $('#tnif_rideau').show().css('z-index',chercherZindexWidgetDeplacableSuivant());
			$('#tnif_rideau').show().css('z-index',1000000);
			$(".redimensionnable").resizable({
				handles: "all"
			});
		}
	});
	$('.bt_rideau_pleinecran').click(function () {
		var lRideau = $(window).width()-20;
		var hRideau = $(window).height()-60;
		$("#tnif_rideau").css('width',lRideau+'px').css('height',hRideau+'px').css('top','55px').css('left','10px');
	});
}

/* Génération de la fenêtre modale pour la copie d'écran */
function modaleCopieEcran() {
	var fenetre = '<div class="modal-dialog">';
	fenetre += '<div class="modal-content">';
	fenetre += "<div class='modal-header'><button type='button' class='close' data-dismiss='modal'>&times;</button><h4 class='modal-title'><img src='images/icone_disquette_32.png' /> Clic droit sur l'image -> Enregistrer l'image sous...</h4></div>";
	// fenetre += "<div class='modal-header'><button type='button' class='close' data-dismiss='modal'>&times;</button><div style='padding-right:50px;' class='input-group'><input id='nom_fichier_image_copie_ecran' class='form-control' placeholder=\"Saisir le nom de l'image\" type='text'><div class='input-group-btn'><button class='btn btn-info bt_enregistrer_image_copie_ecran'>Enregistrer</button></div></div></div>";
	fenetre += '<div class="modal-body">';
	fenetre += "<div id='aff_image_copie_ecran'></div>";
	fenetre += '</div></div></div>';
	$('#modale_copie_ecran').html(fenetre);
}

/* Faire une copie d'écran */
var copieEnCours = false;
function copieEcran(zone) {
	$('#aff_image_copie_ecran').html('');
	if (copieEnCours == false) {
		setTimeout(afficherModaleCE, 2000);
		copieEnCours = true;
		html2canvas(zone).then(function(canvas) {
			var imageGen  = canvas.toDataURL("image/png");
			$('#aff_image_copie_ecran').html("<img src='"+imageGen+"' />");
		});
	}
}
function afficherModaleCE() {
	$('#modale_copie_ecran').modal();
	copieEnCours = false;
}

// Gestion des boutons de mise en forme des post-it
function commande(nom, argument){
    if (typeof argument === 'undefined') {
        argument = '';
    }
    document.execCommand(nom, false, argument);
}







/* -------------------------------------------------------
CLAVIER NUMERIQUE MAISON
---------------------------------------------------------- */

function activerClavierNumerique() {
	$('body').on('click', '.clavier_num', function () {//lié à la fonction clavierNum() qui génère l'html
		if ($(this).prev().is(":hidden")) {
			$('.clavier_num').prev().hide();
			$(this).prev().show();
		}
		else $(this).prev().hide();
	});
	$('body').on('click', '.clavier_num_sans_virgule', function () {//lié à la fonction clavierNumSansVirgule() qui génère l'html
		if ($(this).prev().is(":hidden")) {
			$('.clavier_num_sans_virgule').prev().hide();
			$(this).prev().show();
		}
		else $(this).prev().hide();
	});
	$('body').on('click', '.clavier_num_ope', function () {//lié à la fonction clavierNumOpe() qui génère l'html
		if ($(this).prev().is(":hidden")) {
			$('.clavier_num_ope').prev().hide();
			$(this).prev().show();
		}
		else $(this).prev().hide();
	});
	$('body').on('click', '.clavier_num_chiffres_seuls', function () {//lié à la fonction clavierNumChiffresSeuls() qui génère l'html
		if ($(this).prev().is(":hidden")) {
			$('.clavier_num_chiffres_seuls').prev().hide();
			$(this).prev().show();
		}
		else $(this).prev().hide();
	});
	$('body').on('click', '.touches_clavier_16 > img', function () {
		var saisieEnCours = $(this).parent().prev().val();
		var laTouche = $(this).attr('data-touche');
		//var linput = $(this).parent().prev();
		if (laTouche == "virgule") laTouche = ",";
		if (laTouche == "touche_bleue_vide") laTouche = "";
		if (laTouche == "plus") laTouche = "+";
		if (laTouche == "moins") laTouche = "-";
		if (laTouche == "multiplie") laTouche = "x";
		if (laTouche == "divise") laTouche = "÷";
		if (laTouche == "retour") {
			if (saisieEnCours != "") {
				saisieEnCours = saisieEnCours.slice(0, -1);
				$(this).parent().prev().val(saisieEnCours);
			}
		} else {
			$(this).parent().prev().val(saisieEnCours+laTouche);
		}
	});	
}

function clavierNum() {
// exemple html 	c += "<div style='position:relative;'><input id='saisie_cpt_pas' class='form-control' placeholder='Saisir le pas' /><div class='touches_clavier_16' style='width:48px; height:64px; background:#FFF; position:absolute; top:-66px; right:0px; display:none;'></div><img class='pointer scale_p015 clavier_num' src='images/logo_clavier_16_10.png' style='position:absolute; bottom:2px; right:0px;'></div>";
	var tabCNumBase = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'virgule', 'retour'];
	var cNumBase = "";
	for (i=0 ; i < tabCNumBase.length ; i++) {
		cNumBase += "<img data-touche='"+tabCNumBase[i]+"' class='scale_p015 pointer' src='images/clavier/"+tabCNumBase[i]+"_16.png' />";
	}
	$('.clavier_num').prev().html(cNumBase);	
}

function clavierNumSansVirgule() {
	var tabCNumBase = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'touche_bleue_vide', 'retour'];
	var cNumBase = "";
	for (i=0 ; i < tabCNumBase.length ; i++) {
		cNumBase += "<img data-touche='"+tabCNumBase[i]+"' class='scale_p015 pointer' src='images/clavier/"+tabCNumBase[i]+"_16.png' />";
	}
	$('.clavier_num_sans_virgule').prev().html(cNumBase);	
}

function clavierNumOpe() {
	var tabCNumBase = ['7', '8', '9', 'plus', '4', '5', '6', 'moins', '1', '2', '3', 'multiplie', '0', 'virgule', 'retour', 'divise'];
	var cNumBase = "";
	for (i=0 ; i < tabCNumBase.length ; i++) {
		cNumBase += "<img data-touche='"+tabCNumBase[i]+"' class='scale_p015 pointer' src='images/clavier/"+tabCNumBase[i]+"_16.png' />";
	}
	$('.clavier_num_ope').prev().html(cNumBase);
}

function clavierNumValidation() {
	var tabCNumBase = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'virgule', 'retour'];
	var cNumBase = "";
	for (i=0 ; i < tabCNumBase.length ; i++) {
		cNumBase += "<img data-touche='"+tabCNumBase[i]+"' class='scale_p015 pointer' src='images/clavier/"+tabCNumBase[i]+"_16.png' />";
	}
	cNumBase += "<img data-touche='fermer' class='scale_p015 pointer' src='images/clavier/icone_fermer_20_20.png' title='Fermer le clavier' /><img data-touche='valider' class='scale_p015 pointer' src='images/clavier/icone_valider_20_28.png' title='Valider ce nombre' />";
	$('.clavier_num_validation').html(cNumBase);
}

function clavierNumChiffresSeuls() {
	var tabCNumBase = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'touche_bleue_vide', 'touche_bleue_vide'];
	var cNumBase = "";
	for (i=0 ; i < tabCNumBase.length ; i++) {
		cNumBase += "<img data-touche='"+tabCNumBase[i]+"' class='scale_p015 pointer' src='images/clavier/"+tabCNumBase[i]+"_16.png' />";
	}
	$('.clavier_num_chiffres_seuls').prev().html(cNumBase);	
}



/*==========================
 FONCTIONS CALCULATRICE ETC
 ============================*/

function afficherCalcTables() {
    var c = "<div class='modal-dialog'>";
    c+= "<div class='modal-content'>";
    c+= "<div class='modal-body'>";
    c+= "<button type='button' class='close' data-dismiss='modal'>&times;</button> <div style='margin-bottom:15px;'><button data-bt='bt_calc' class='bt_ct btn btn-primary'>Calculatrice</button> <button data-bt='bt_table_a' class='bt_ct btn btn-secondary'>Tables +</button> <button data-bt='bt_table_m' class='bt_ct btn btn-secondary'>Tables x</button> <button data-bt='bt_tab_conv' class='bt_ct btn btn-secondary'>Tableaux de conversion</button> <span style='margin-left:10px;' title='Réduire la taille des caractères' class='glyphicon glyphicon-zoom-out pointer scale_p01 reduire_taille'></span> <span style='margin-left:10px;' title='Agrandir la taille des caractères' class='glyphicon glyphicon-zoom-in pointer scale_p01 agrandir_taille'></span></div>";
    c+= "<div id='bt_calc' class='aff_ct'>"+afficherCalculatrice()+"</div>";
    c+= "<div id='bt_table_a' class='aff_ct' style='display:none;'>"+afficherTableA()+"</div>";
    c+= "<div id='bt_table_m' class='aff_ct' style='display:none;'>"+afficherTableM()+"</div>";
    c+= "<div id='bt_tab_conv' class='aff_ct' style='display:none; position:relative;'>"+afficherTabConv()+"</div>";
    c+= "</div></div></div>";
    $('#modale_calculatrice').html(c).modal();
    $('.bt_ct').click(function () {
        var btClique = $(this).attr('data-bt');
        $('.bt_ct').removeClass('btn-primary').addClass('btn-secondary');
        $(this).removeClass('btn-secondary').addClass('btn-primary');
        $('.aff_ct').slideUp();
        $('#'+btClique).slideDown();
		if (btClique == "bt_tab_conv") {
			$('#modale_calculatrice .reduire_taille').hide();
			$('#modale_calculatrice .agrandir_taille').hide();

		} else {
			$('#modale_calculatrice .reduire_taille').show();
			$('#modale_calculatrice .agrandir_taille').show();
		}
    });
    $('.tab_tables th').click(function () {
        var celClique = $(this).attr('id');
        $('.'+celClique).toggleClass('on');
    });
    $('#a_signe').click(function () {
        $('.tab_tables_a tr').children().removeClass('on');
    });
    $('#m_signe').click(function () {
        $('.tab_tables_m tr').children().removeClass('on');
    });
    $('.reduire_taille').click(function () {
        var taille = $('.taille_variable').attr('data-taille');
        if (taille > 59) {
            taille = parseInt(taille) - 20;
        }
        $('.tab_tables').attr('data-taille',taille).css('font-size',taille+'%');
        $('.tab_calc').attr('data-taille',taille).find('span').css('font-size',taille+'%');
    });
    $('.agrandir_taille').click(function () {
        var taille = $('.taille_variable').attr('data-taille');
        taille = parseInt(taille) + 20;
        $('.tab_tables').attr('data-taille',taille).css('font-size',taille+'%');
        $('.tab_calc').attr('data-taille',taille).find('span').css('font-size',taille+'%');
    });
    var divEuc = false;
    $('.tab_calc button').click(function () {
        $('.aff_reste').hide().children().text("");
        $('.aff_ope_memoire').hide();
        if ($(this).hasClass('bt_aff') && $(this).attr('id') != 'bt_init' && $(this).attr('id') != 'bt_resultat') {
            var carAff = $(this).text();
            $('.aff_ope span').append(carAff);
            if ($(this).attr('id') != 'bt_div_euc') {
                var carOpe = $(this).attr('data-op');
                $('#calc_ope').append(carOpe);
                $('#calc_reste').append(carOpe);
            } else {
                divEuc = true;
                $('.non_div_euc').attr('disabled','disabled');
                var carQuotient = $(this).attr('data-quotient');
                $('#calc_ope').append(carQuotient);
                var carReste = $(this).attr('data-reste');
                $('#calc_reste').append(carReste);
            }
        }
        if ($(this).attr('id') == 'bt_init') {
            $('.aff_ope span').html('&nbsp;');
            $('.aff_reste').hide().children().text("");
            $('#calc_ope').html('');
            $('#calc_reste').html('');
            $('.tab_calc button').removeAttr('disabled');
            $('.aff_ope_memoire').hide();
            divEuc = false;
        }
        if ($(this).attr('id') == 'bt_resultat') {
            var atraiterResultat = $('#calc_ope').text();            
            var atraiterReste = $('#calc_reste').text();
            var validFormule = /^[0-9\.\*%\(\)\+\-\/]*$/;
            if (validFormule.test(atraiterResultat) && validFormule.test(atraiterReste)) {
                var opeEnCours = $('.aff_ope span').text();
                if (divEuc) {
                    var resultat = Math.floor(eval(atraiterResultat));
                    var reste = eval(atraiterReste);
                    $('.aff_reste').show().children().text("reste = "+reste);
                    $('.tab_calc button').attr('disabled','disabled');
                    $('#bt_init').removeAttr('disabled');
                } else {
                    var resultat = Math.round(eval(atraiterResultat)*10000000)/10000000;
                    $('.tab_calc button').removeAttr('disabled');
                }
                $('.aff_ope').children().text(resultat);
                $('#calc_ope').text(resultat);
                $('#calc_reste').text(resultat);
                $('.aff_ope_memoire').show().children().text(opeEnCours);
            } else {
                alert('Formule de calcul incorrecte !');
            }
        }
    });
	// tableaux de conversion
	$('.conv_choix_unite > li').click(function () {
		var choix = $(this).attr('rel');
		$('.conv_choix_unite > li').removeClass('on');
		$(this).addClass('on');
		$('.conv_tableau > div').hide();
		$(choix).slideDown();
		// if ($('#conv_calque').is(":hidden")) $('#conv_calque').show();
    });
	$('.conv_bt_sentrainer').click(function () {
		window.open('https://monappli.net/app/mathematiques/grandeurs/conversions/','_blank');
    });
	var transparentBoard = new DrawingBoard.Board('conv_calque', {// calque de dessin
		background: false,
		controls: [
			'Color',
			{ Size: { type: 'dropdown' } },
			{ DrawingMode: { filler: false } },
			'Navigation'
		],
		size: 2,
		webStorage: 'false',
		enlargeYourContainer: true,
		droppable: true, //try dropping an image on the canvas!
		stretchImg: true //the dropped image can be automatically ugly resized to to take the canvas size
	});	

}

function afficherCalculatrice() {
    var c = "<table data-taille='100' class='tab_calc taille_variable' style='font-size:100%; background:#F0F0FF;'>";
    c+= "<tr> <td colspan=6> <div class='cadre_affichage'><div class='aff_ope_memoire' style='display:none;'><span></span></div> <div class='aff_ope'><span>&nbsp;</span></div> <div class='aff_reste' style='display:none;'><span></span></div></div></td> </tr>";
    c+= "<tr> <td><button data-op='7' class='btn btn-block btn-default bt_car bt_aff'><span>7</span></button></td> <td><button data-op='8' class='btn btn-block btn-default bt_car bt_aff'><span>8</span></button></td> <td><button data-op='9' class='btn btn-block btn-default bt_car bt_aff'><span>9</span></button></td> <td><span>&nbsp;</span></td> <td><button data-op='+' class='btn btn-block btn-info bt_ope bt_aff non_div_euc'><span>+</span></button></td> <td><button id='bt_init' class='btn btn-block btn-success'><span>C</span></button></td> </tr>";
    c+= "<tr> <td><button data-op='4' class='btn btn-block btn-default bt_cat bt_aff'><span>4</span></button></td> <td><button data-op='5' class='btn btn-block btn-default bt_car bt_aff'><span>5</span></button></td> <td><button data-op='6' class='btn btn-block btn-default bt_car bt_aff'><span>6</span></button></td> <td><span>&nbsp;</span></td> <td><button data-op='-' class='btn btn-block btn-info bt_ope bt_aff non_div_euc'><span>&minus;</span></button></td> <td><button data-op='(' class='btn btn-block btn-default bt_car bt_aff non_div_euc'><span>(</span></button></td> </tr>";
    c+= "<tr> <td><button data-op='1' class='btn btn-block btn-default bt_car bt_aff'><span>1</span></button></td> <td><button data-op='2' class='btn btn-block btn-default bt_car bt_aff'><span>2</span></button></td> <td><button data-op='3' class='btn btn-block btn-default bt_car bt_aff'><span>3</span></button></td> <td><span>&nbsp;</span></td> <td><button data-op='*' class='btn btn-block btn-info bt_ope bt_aff non_div_euc'><span>&times;</span></button></td> <td><button data-op=')' class='btn btn-block btn-default bt_car bt_aff non_div_euc'><span>)</span></button></td> </tr>";
    c+= "<tr> <td><button data-op='0' class='btn btn-block btn-default bt_car bt_aff'><span>0</span></button></td> <td><button data-op='.' class='btn btn-block btn-default bt_car bt_aff non_div_euc'><span>,</span></button></td> <td><button id='bt_resultat' class='btn btn-block btn-primary'><span>=</span></button></td> <td><span>&nbsp;</span></td> <td><button data-op='/' class='btn btn-block btn-info bt_ope bt_aff non_div_euc'><span> &frasl; </span></button></td> <td><button data-quotient='/' data-reste='%' id='bt_div_euc' class='btn btn-block btn-info bt_aff'><span>&divide;</span></button></td> </tr>";
    c+= "</table>";
    c+= "<div id='calc_ope' style='display:none;'></div>";
    c+= "<div id='calc_reste' style='display:none;'></div>";
    c+= "<p style='margin-top:15px;'>Cette calculatrice basique intègre la division euclidienne (&divide;).</p>";
    c+= "<p>Utiliser une <a target='_blank' href='https://www.online-calculator.com/full-screen-maths-calculator/'>calculatrice plus complète</a>, avec gestion de la mémoire...</p>";
    return c;
}

function afficherTableA() {
    var c = "Cliquer sur un nombre bleu pour sélectionner ou désélectionner, et sur <img src='images/logo_table_add_24.png' /> pour tout désélectionner.";
    c+= "<table data-taille='100' class='tab_tables tab_tables_a taille_variable' style='font-size:100%'>";
    c+= "<tr> <th id='a_signe' title='Supprimer la sélection'><img src='images/logo_table_add_24.png' /></th> <th id='ac0' class='ac0'>0</th> <th id='ac1' class='ac1'>1</th> <th id='ac2' class='ac2'>2</th> <th id='ac3' class='ac3'>3</th> <th id='ac4' class='ac4'>4</th> <th id='ac5' class='ac5'>5</th> <th id='ac6' class='ac6'>6</th> <th id='ac7' class='ac7'>7</th> <th id='ac8' class='ac8'>8</th> <th id='ac9' class='ac9'>9</th> <th id='ac10' class='ac10'>10</th> </tr>";
    c+= "<tr> <th id='al0' class='al0'>0</th> <td class='ac0 al0'>0</td> <td class='ac1 al0'>1</td> <td class='ac2 al0'>2</td> <td class='ac3 al0'>3</td> <td class='ac4 al0'>4</td> <td class='ac5 al0'>5</td> <td class='ac6 al0'>6</td> <td class='ac7 al0'>7</td> <td class='ac8 al0'>8</td> <td class='ac9 al0'>9</td> <td class='ac10 al0'>10</td> </tr>";
    c+= "<tr> <th id='al1' class='al1'>1</th> <td class='ac0 al1'>1</td> <td class='ac1 al1'>2</td> <td class='ac2 al1'>3</td> <td class='ac3 al1'>4</td> <td class='ac4 al1'>5</td> <td class='ac5 al1'>6</td> <td class='ac6 al1'>7</td> <td class='ac7 al1'>8</td> <td class='ac8 al1'>9</td> <td class='ac9 al1'>10</td> <td class='ac10 al1'>11</td> </tr>";
    c+= "<tr> <th id='al2' class='al2'>2</th> <td class='ac0 al2'>2</td> <td class='ac1 al2'>3</td> <td class='ac2 al2'>4</td> <td class='ac3 al2'>5</td> <td class='ac4 al2'>6</td> <td class='ac5 al2'>7</td> <td class='ac6 al2'>8</td> <td class='ac7 al2'>9</td> <td class='ac8 al2'>10</td> <td class='ac9 al2'>11</td> <td class='ac10 al2'>12</td> </tr>";
    c+= "<tr> <th id='al3' class='al3'>3</th> <td class='ac0 al3'>3</td> <td class='ac1 al3'>4</td> <td class='ac2 al3'>5</td> <td class='ac3 al3'>6</td> <td class='ac4 al3'>7</td> <td class='ac5 al3'>8</td> <td class='ac6 al3'>9</td> <td class='ac7 al3'>10</td> <td class='ac8 al3'>11</td> <td class='ac9 al3'>12</td> <td class='ac10 al3'>13</td> </tr>";
    c+= "<tr> <th id='al4' class='al4'>4</th> <td class='ac0 al4'>4</td> <td class='ac1 al4'>5</td> <td class='ac2 al4'>6</td> <td class='ac3 al4'>7</td> <td class='ac4 al4'>8</td> <td class='ac5 al4'>9</td> <td class='ac6 al4'>10</td> <td class='ac7 al4'>11</td> <td class='ac8 al4'>12</td> <td class='ac9 al4'>13</td> <td class='ac10 al4'>14</td> </tr>";
    c+= "<tr> <th id='al5' class='al5'>5</th> <td class='ac0 al5'>5</td> <td class='ac1 al5'>6</td> <td class='ac2 al5'>7</td> <td class='ac3 al5'>8</td> <td class='ac4 al5'>9</td> <td class='ac5 al5'>10</td> <td class='ac6 al5'>11</td> <td class='ac7 al5'>12</td> <td class='ac8 al5'>13</td> <td class='ac9 al5'>14</td> <td class='ac10 al5'>15</td> </tr>";
    c+= "<tr> <th id='al6' class='al6'>6</th> <td class='ac0 al6'>6</td> <td class='ac1 al6'>7</td> <td class='ac2 al6'>8</td> <td class='ac3 al6'>9</td> <td class='ac4 al6'>10</td> <td class='ac5 al6'>11</td> <td class='ac6 al6'>12</td> <td class='ac7 al6'>13</td> <td class='ac8 al6'>14</td> <td class='ac9 al6'>15</td> <td class='ac10 al6'>16</td> </tr>";
    c+= "<tr> <th id='al7' class='al7'>7</th> <td class='ac0 al7'>7</td> <td class='ac1 al7'>8</td> <td class='ac2 al7'>9</td> <td class='ac3 al7'>10</td> <td class='ac4 al7'>11</td> <td class='ac5 al7'>12</td> <td class='ac6 al7'>13</td> <td class='ac7 al7'>14</td> <td class='ac8 al7'>15</td> <td class='ac9 al7'>16</td> <td class='ac10 al7'>17</td> </tr>";
    c+= "<tr> <th id='al8' class='al8'>8</th> <td class='ac0 al8'>8</td> <td class='ac1 al8'>9</td> <td class='ac2 al8'>10</td> <td class='ac3 al8'>11</td> <td class='ac4 al8'>12</td> <td class='ac5 al8'>13</td> <td class='ac6 al8'>14</td> <td class='ac7 al8'>15</td> <td class='ac8 al8'>16</td> <td class='ac9 al8'>17</td> <td class='ac10 al8'>18</td> </tr>";
    c+= "<tr> <th id='al9' class='al9'>9</th> <td class='ac0 al9'>9</td> <td class='ac1 al9'>10</td> <td class='ac2 al9'>11</td> <td class='ac3 al9'>12</td> <td class='ac4 al9'>13</td> <td class='ac5 al9'>14</td> <td class='ac6 al9'>15</td> <td class='ac7 al9'>16</td> <td class='ac8 al9'>17</td> <td class='ac9 al9'>18</td> <td class='ac10 al9'>19</td> </tr>";
    c+= "<tr> <th id='al10' class='al10'>10</th> <td class='ac0 al10'>10</td> <td class='ac1 al10'>11</td> <td class='ac2 al10'>12</td> <td class='ac3 al10'>13</td> <td class='ac4 al10'>14</td> <td class='ac5 al10'>15</td> <td class='ac6 al10'>16</td> <td class='ac7 al10'>17</td> <td class='ac8 al10'>18</td> <td class='ac9 al10'>19</td> <td class='ac10 al10'>20</td> </tr>";
    c+= "</table>";
    return c;
}

function afficherTableM() {
    var c = "Cliquer sur un nombre bleu pour sélectionner ou désélectionner, et sur <img src='images/logo_table_mul_24.png' /> pour tout désélectionner.";
    c+= "<table data-taille='100' class='tab_tables tab_tables_m taille_variable' style='font-size:100%'>";
    c+= "<tr> <th id='m_signe' title='Supprimer la sélection'><img src='images/logo_table_mul_24.png' /></th> <th id='mc0' class='mc0'>0</th> <th id='mc1' class='mc1'>1</th> <th id='mc2' class='mc2'>2</th> <th id='mc3' class='mc3'>3</th> <th id='mc4' class='mc4'>4</th> <th id='mc5' class='mc5'>5</th> <th id='mc6' class='mc6'>6</th> <th id='mc7' class='mc7'>7</th> <th id='mc8' class='mc8'>8</th> <th id='mc9' class='mc9'>9</th> <th id='mc10' class='mc10'>10</th> </tr>";
    c+= "<tr> <th id='ml0' class='ml0'>0</th> <td class='mc0 ml0'>0</td> <td class='mc1 ml0'>0</td> <td class='mc2 ml0'>0</td> <td class='mc3 ml0'>0</td> <td class='mc4 ml0'>0</td> <td class='mc5 ml0'>0</td> <td class='mc6 ml0'>0</td> <td class='mc7 ml0'>0</td> <td class='mc8 ml0'>0</td> <td class='mc9 ml0'>0</td> <td class='mc10 ml0'>0</td> </tr>";
    c+= "<tr> <th id='ml1' class='ml1'>1</th> <td class='mc0 ml1'>0</td> <td class='mc1 ml1'>1</td> <td class='mc2 ml1'>2</td> <td class='mc3 ml1'>3</td> <td class='mc4 ml1'>4</td> <td class='mc5 ml1'>5</td> <td class='mc6 ml1'>6</td> <td class='mc7 ml1'>7</td> <td class='mc8 ml1'>8</td> <td class='mc9 ml1'>9</td> <td class='mc10 ml1'>10</td> </tr>";
    c+= "<tr> <th id='ml2' class='ml2'>2</th> <td class='mc0 ml2'>0</td> <td class='mc1 ml2'>2</td> <td class='mc2 ml2'>4</td> <td class='mc3 ml2'>6</td> <td class='mc4 ml2'>8</td> <td class='mc5 ml2'>10</td> <td class='mc6 ml2'>12</td> <td class='mc7 ml2'>14</td> <td class='mc8 ml2'>16</td> <td class='mc9 ml2'>18</td> <td class='mc10 ml2'>20</td> </tr>";
    c+= "<tr> <th id='ml3' class='ml3'>3</th> <td class='mc0 ml3'>0</td> <td class='mc1 ml3'>3</td> <td class='mc2 ml3'>6</td> <td class='mc3 ml3'>9</td> <td class='mc4 ml3'>12</td> <td class='mc5 ml3'>15</td> <td class='mc6 ml3'>18</td> <td class='mc7 ml3'>21</td> <td class='mc8 ml3'>24</td> <td class='mc9 ml3'>27</td> <td class='mc10 ml3'>30</td> </tr>";
    c+= "<tr> <th id='ml4' class='ml4'>4</th> <td class='mc0 ml4'>0</td> <td class='mc1 ml4'>4</td> <td class='mc2 ml4'>8</td> <td class='mc3 ml4'>12</td> <td class='mc4 ml4'>16</td> <td class='mc5 ml4'>20</td> <td class='mc6 ml4'>24</td> <td class='mc7 ml4'>28</td> <td class='mc8 ml4'>32</td> <td class='mc9 ml4'>36</td> <td class='mc10 ml4'>40</td> </tr>";
    c+= "<tr> <th id='ml5' class='ml5'>5</th> <td class='mc0 ml5'>0</td> <td class='mc1 ml5'>5</td> <td class='mc2 ml5'>10</td> <td class='mc3 ml5'>15</td> <td class='mc4 ml5'>20</td> <td class='mc5 ml5'>25</td> <td class='mc6 ml5'>30</td> <td class='mc7 ml5'>35</td> <td class='mc8 ml5'>40</td> <td class='mc9 ml5'>45</td> <td class='mc10 ml5'>50</td> </tr>";
    c+= "<tr> <th id='ml6' class='ml6'>6</th> <td class='mc0 ml6'>0</td> <td class='mc1 ml6'>6</td> <td class='mc2 ml6'>12</td> <td class='mc3 ml6'>18</td> <td class='mc4 ml6'>24</td> <td class='mc5 ml6'>30</td> <td class='mc6 ml6'>36</td> <td class='mc7 ml6'>42</td> <td class='mc8 ml6'>48</td> <td class='mc9 ml6'>54</td> <td class='mc10 ml6'>60</td> </tr>";
    c+= "<tr> <th id='ml7' class='ml7'>7</th> <td class='mc0 ml7'>0</td> <td class='mc1 ml7'>7</td> <td class='mc2 ml7'>14</td> <td class='mc3 ml7'>21</td> <td class='mc4 ml7'>28</td> <td class='mc5 ml7'>35</td> <td class='mc6 ml7'>42</td> <td class='mc7 ml7'>49</td> <td class='mc8 ml7'>56</td> <td class='mc9 ml7'>63</td> <td class='mc10 ml7'>70</td> </tr>";
    c+= "<tr> <th id='ml8' class='ml8'>8</th> <td class='mc0 ml8'>0</td> <td class='mc1 ml8'>8</td> <td class='mc2 ml8'>16</td> <td class='mc3 ml8'>24</td> <td class='mc4 ml8'>32</td> <td class='mc5 ml8'>40</td> <td class='mc6 ml8'>48</td> <td class='mc7 ml8'>56</td> <td class='mc8 ml8'>64</td> <td class='mc9 ml8'>72</td> <td class='mc10 ml8'>80</td> </tr>";
    c+= "<tr> <th id='ml9' class='ml9'>9</th> <td class='mc0 ml9'>0</td> <td class='mc1 ml9'>9</td> <td class='mc2 ml9'>18</td> <td class='mc3 ml9'>27</td> <td class='mc4 ml9'>36</td> <td class='mc5 ml9'>45</td> <td class='mc6 ml9'>54</td> <td class='mc7 ml9'>63</td> <td class='mc8 ml9'>72</td> <td class='mc9 ml9'>81</td> <td class='mc10 ml9'>90</td> </tr>";
    c+= "<tr> <th id='ml10' class='ml10'>10</th> <td class='mc0 ml10'>0</td> <td class='mc1 ml10'>10</td> <td class='mc2 ml10'>20</td> <td class='mc3 ml10'>30</td> <td class='mc4 ml10'>40</td> <td class='mc5 ml10'>50</td> <td class='mc6 ml10'>60</td> <td class='mc7 ml10'>70</td> <td class='mc8 ml10'>80</td> <td class='mc9 ml10'>90</td> <td class='mc10 ml10'>100</td> </tr>";
    c+= "</table>";
    return c;
}

function afficherTabConv() {
    var c = "<div class='conv_choix_unite'><button class='btn btn-info btn-petit conv_bt_sentrainer' style='float:right;'>S'entraîner...</button><li rel='#bt_conv_longueur' class='faux_bouton2 on'>Longueur</li><li rel='#bt_conv_masse' class='faux_bouton2'>Masse</li><li rel='#bt_conv_capacite' class='faux_bouton2'>Capacité</li><li rel='#bt_conv_surface' class='faux_bouton2'>Surface</li><li rel='#bt_conv_volume' class='faux_bouton2'>Volume</li></div>";
    c+= "<div class='conv_tableau'>";
	c+= "<div id='bt_conv_longueur' style='display:block;'><table><tr><th>km</th><th>hm</th><th>dam</th><th>m</th><th>dm</th><th>cm</th><th>mm</th></tr>"+convCreerLigneSimple(5)+"</table></div>";
	c+= "<div id='bt_conv_masse'><table><tr><th>kg</th><th>hg</th><th>dag</th><th>g</th><th>dg</th><th>cg</th><th>mg</th></tr>"+convCreerLigneSimple(5)+"</table></div>";
	c+= "<div id='bt_conv_capacite'><table><tr><th>kl</th><th>hl</th><th>dal</th><th>l</th><th>dl</th><th>cl</th><th>ml</th></tr>"+convCreerLigneSimple(5)+"</table></div>";
	c+= "<div id='bt_conv_surface'><table><tr><th colspan='2'>km<sup>2</sup></th><th colspan='2'>hm<sup>2</sup></th><th colspan='2'>dam<sup>2</sup></th><th colspan='2'>m<sup>2</sup></th><th colspan='2'>dm<sup>2</sup></th><th colspan='2'>cm<sup>2</sup></th><th colspan='2'>mm<sup>2</sup></th></tr>"+convCreerLigneDouble(5)+"</table></div>";
	c+= "<div id='bt_conv_volume'><table><tr><th colspan='3'>km<sup>3</sup></th><th colspan='3'>hm<sup>3</sup></th><th colspan='3'>dam<sup>3</sup></th><th colspan='3'>m<sup>3</sup></th><th colspan='3'>dm<sup>3</sup></th><th colspan='3'>cm<sup>3</sup></th><th colspan='3'>mm<sup>3</sup></th></tr>"+convCreerLigneTriple(5)+"</table></div>";
	c+= "</div>";
	c+= "<div id='conv_calque'></div>";// affichage du calque
	return c;
}

function convCreerLigneSimple(nb) {
	var ligne = "<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>";
	var lignes = "";
	for (i=0 ; i < nb ; i++) {
		lignes += ligne;
	}
	return lignes;
}
function convCreerLigneDouble(nb) {
	var ligne = "<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>";
	var lignes = "";
	for (i=0 ; i < nb ; i++) {
		lignes += ligne;
	}
	return lignes;
}
function convCreerLigneTriple(nb) {
	var ligne = "<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>";
	var lignes = "";
	for (i=0 ; i < nb ; i++) {
		lignes += ligne;
	}
	return lignes;
}

/*==========================
 FONCTIONS SITES REFERENCES
 ============================*/

function genST(nom,url,logo) {
	var bt = "<li data-url=\""+url+"\">";
    bt += "<img src=\"images/logos_sites/"+logo+"\" />";
    bt += "<div>"+nom+"</div>";
    bt += "</li>";
    return bt;
}

// Générer et ouvrir la modale des focus de Pragmatice
function afficherFocusPragmatice() {
    var c = "<div class='modal-dialog modal-lg'>";
    c+= "<div class='modal-content bleu_leger'>";
    c+= "<div class='modal-body focus_pragmatice'>";
    c+= "<h4>Applications Web produites par l'association PragmaTICE <a title='En savoir plus sur PragmaTICE...' target='_blank' href='http://pragmatice.net/'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a> <button type='button' class='close' data-dismiss='modal'>&times;</button></h4>";
	c+= "<div class='row' style='margin-top:20px; font-size:90%;'>";
	c+= "<div class='col-lg-6 col-md-6 col-sm-12 col-xs-12'>";
	c+= "<div style='margin-bottom:20px;'><a target='_blank' href='http://pragmatice.net/pragmactivites/ealor/'><img src='images/logo_app_ealor_128.png'class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'><b>EALOR</b> est un générateur d’activités multimédia multijoueur favorisant l’acquisition du lexique <em>(écrit et oral)</em> français ou anglais, destinées à tout public&nbsp;: lecteurs, non lecteurs ou élèves allophones.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "<div style='margin-bottom:20px;'><a target='_blank' href='http://pragmatice.net/pragmactivites/labonnecategorie/'><img src='images/logo_app_bonne_categorie_128.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'><b>La Bonne Catégorie</b> est une application Web pédagogique multijoueur qui consiste à associer ou à classer des mots, expressions ou nombres selon deux modalités de jeu&nbsp;: fixe ou animée.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "<div><a target='_blank' href='http://pragmatice.net/pragmactivites/letextemystere/'><img src='images/logo_app_texte_mystere_128.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'><b>Le Texte Mystère</b> est un jeu pédagogique multijoueur qui consiste à reconstituer un texte en devinant ses mots cachés, développant des compétences en compréhension de lecture et orthographe.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "<div><a target='_blank' href='https://pragmatice.net/pragmactivites/orthodefi/'><img src='images/logo_odefi_128.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'><b>OrthoDéfi</b> est une application Web pédagogique multijoueur qui permet de s’entraîner à mémoriser et à analyser des mots pour bien les orthographier.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "<div><a target='_blank' href='https://pragmatice.net/pragmactivites/pragmaquiz/'><img src='images/logo_pragmaquiz_128.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'><b>PragmaQuiz</b> est un générateur de quiz pour l’école, multimédia, multijoueur, qui propose plusieurs activités à partir d’un même quiz, et peut adapter les questions en fonction des réponses de l’apprenant.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "<div><a target='_blank' href='https://pragmatice.net/pragmactivites/jemepresente/'><img src='images/logo_jemepresente_128.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'><b>\"Je me présente\"</b> est une application Web pédagogique multijoueur et multimédia qui permet de s’entraîner, dans plusieurs langues, à poser et à répondre à 9 questions qui peuvent caractériser un personnage.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "</div>";
	c+= "<div class='col-lg-6 col-md-6 col-sm-12 col-xs-12'>";
	c+= "<div><a target='_blank' href='http://pragmatice.net/pragmactivites/lectorbus/'><img src='images/logo_app_lectorbus_128.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'><b>LectOrBus</b> est une application Web pédagogique multijoueur qui permet de générer automatiquement des activités interactives d’entraînement à la lecture et à l’orthographe <em>(du cycle 1 au cycle 3)</em>, à partir de mots, phrases ou textes.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "<div><a target='_blank' href='http://pragmatice.net/pragmaprodu/petitlivremultimedia/'><img src='images/logo_app_petitlivremultimedia_128.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'>L’application <b>Petit Livre Multimédia</b> permet de consulter et de créer des livres numériques de 8 pages qui peuvent être imprimés dans trois formats&nbsp;: petit livre A7, livret A5 <em>(2 feuilles R°V°)</em> ou affiches A4.<br />Des jeux interactifs générés automatiquement à partir du contenu du livre <em>(Ranger dans l’ordre - Associer des médias - Mémoriser le livre - Reconstituer un puzzle)</em> sont disponibles en fin de livre.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "<div style='margin-top:15px;'><a target='_blank' href='https://pragmatice.net/pragmaprodu/lecodageenchante/'><img src='images/logo_lce_128_base.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'>Composée de 5 modules paramétrables pour différencier les apprentissages, l’application Web <b>\"Le Codage Enchanté\"</b> permet de coder ou décoder des déplacements sur quadrillage, afin de construire ses propres parcours scénarisés à l’aide des pictogrammes fournis, de créer des albums multimédia (consultables à la manière de Narramus), de dessiner, tout en s’initiant à l’algorithmie.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "<div style='margin-top:15px;'><a target='_blank' href='https://pragmatice.net/pragmactivites/pragmalexique/'><img src='images/logo_plexique_128.png' class='scale_p01' style='margin-bottom:10px;' /></a><div style='padding-left:120px;'><b>PragmaLexique</b> est une application Web multimédia, gratuite et téléchargeable, qui permet via l’apprentissage ritualisé d’un ou deux mots par jour, de découvrir et de réinvestir du vocabulaire et de sensibiliser les élèves à la lecture-écriture.</div></div>";
	c+= "<div style='clear:both;'></div>";
	c+= "</div>";
	c+= "</div>";
    c+= "</div></div></div>";
    $('#modale_focus_pragmatice').html(c).modal();
}

var sitesOutilsNumeration = "";
sitesOutilsNumeration+= genST("Abaque","http://micetf.fr/abaque/","abaque.png");
sitesOutilsNumeration+= genST("Barres-doigts","http://micetf.fr/barres-doigts/","barresdoigts.png");
sitesOutilsNumeration+= genST("Boulier interactif","http://micetf.fr/boulierHTML5/","boulier.png");
sitesOutilsNumeration+= genST("Boulier virtuel (MLC)","https://apps.mathlearningcenter.org/number-rack/","mathlearningcenter_boulier.png");
sitesOutilsNumeration+= genST("Cartons Montessori","http://micetf.fr/montessori/","cartons_montessori.png");
sitesOutilsNumeration+= genST("Glisse-nombre Mathix","https://mathix.org/glisse-nombre/index.html","glissenombre_mathix.png");
sitesOutilsNumeration+= genST("Groupements GaBuZoMeu","http://micetf.fr/gabuzomeu/","groupements_gabuzomeu.png");
sitesOutilsNumeration+= genST("Groupements par 10","http://micetf.fr/groupements/","groupements_par10.png");
sitesOutilsNumeration+= genST("L’abaque","https://monappli.net/app/mathematiques/nombres/abaque/","abaque_f.png");
sitesOutilsNumeration+= genST("Le château des nombres","http://micetf.fr/chateau/","chateaudesnombres.png");
sitesOutilsNumeration+= genST("Les conversions","https://monappli.net/app/mathematiques/grandeurs/conversions/","conversions.png");
sitesOutilsNumeration+= genST("Les nombres décimaux","http://micetf.fr/decimaux/","nombres_decimaux.png");
sitesOutilsNumeration+= genST("Ligne de nombres (MLC)","https://apps.mathlearningcenter.org/number-line/","mathlearningcenter_lignedenombres.png");
sitesOutilsNumeration+= genST("Lignes graduées","http://micetf.fr/graduations/","lignes_graduees.png");
sitesOutilsNumeration+= genST("Nombre d'objets (MLC)","https://apps.mathlearningcenter.org/number-pieces/","mathlearningcenter_nombredejetons.png");
sitesOutilsNumeration+= genST("Nombre de jetons (MLC)","https://apps.mathlearningcenter.org/number-frames/","mathlearningcenter_nombredobjets.png");
sitesOutilsNumeration+= genST("Nombre pensé","http://micetf.fr/cibles/","nombre_pense.png");
sitesOutilsNumeration+= genST("Numération","http://micetf.fr/Numeration/","numeration.png");
sitesOutilsNumeration+= genST("Numération - Opération","http://micetf.fr/numop/","numop.png");
sitesOutilsNumeration+= genST("Online Abacus","https://www.online-calculator.com/full-screen-abacus/","online_abacus.png");
sitesOutilsNumeration+= genST("Tableau de conversion (m2)","http://micetf.fr/conversion2/","conversion_m2.png");
sitesOutilsNumeration+= genST("Tableaux de conversion (m,g,l)","http://micetf.fr/conversion/","conversion_mgl.png");


// Générer et ouvrir la modale des activités de français
function afficherActFrancais() {
    var c = "<div class='modal-dialog modal-lg'>";
    c+= "<div class='modal-content bleu_leger'>";
    c+= "<div class='modal-body sites_tni'>";
    c+= "<button type='button' class='close' data-dismiss='modal'>&times;</button> <div style='margin-bottom:15px;'><button data-bt='bt_langue' class='bt_act_fr btn btn-primary'>Étude de la langue</button><button data-bt='bt_lecture_ecriture' class='bt_act_fr btn btn-secondary'>Lecture et écriture</button></div>";
	c+= "<div id='bt_langue' class='aff_act_fr'>";
    c+= "<h4>Étude de la langue <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique173'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Anagramme","http://micetf.fr/anagrammes/","anagramme.png");
    //c+= genST("Conjuguer un verbe","http://applipla.net/app/applis/conjuguer-verbe.html","conjuguer-verbe.png");
    c+= genST("Conjugueur","https://monappli.net/app/francais/conjugaison/conjugueur/","conjugueur.png");
    c+= genST("Dictée","https://monappli.net/app/francais/orthographe/dictee/","dictee.png");
    c+= genST("EALOR","http://pragmatice.net/pragmactivites/ealor/","ealor.png");
    c+= genST("HTML5 Crossword Generator","http://www.classtools.net/crossword/","html5_crossword_generator.png");
    c+= genST("Je fais une dictée","https://micetf.fr/dictee/","dictee_jecree.png");
    c+= genST("La Bonne Catégorie","http://pragmatice.net/pragmactivites/labonnecategorie/","labonnecategorie.png");
    c+= genST("La ruche des Mots","http://micetf.fr/ruche-mots/","laruchedesmots.png");
    c+= genST("Le Bon Article (défini)","https://micetf.fr/JeuxLecture/#LeBonArticle-defini","lebonarticle_lecture.png");
    c+= genST("Le Bon Article (indéfini)","https://micetf.fr/JeuxLecture/#LeBonArticle-indefini","lebonarticle2_lecture.png");
    c+= genST("Le Texte Mystère","http://pragmatice.net/pragmactivites/letextemystere/","letextemystere.png");
    c+= genST("LectOrBus","http://pragmatice.net/pragmactivites/lectorbus/","lectorbus.png");
    c+= genST("Les homophones","https://monappli.net/app/francais/orthographe/homophones/","homophones.png");
    c+= genST("O.R.L.F.","http://micetf.fr/ORLF/","orlf.png");
    c+= genST("Ordre alphabétique","https://monappli.net/app/francais/lettres/ordre-alphabetique/","ordre-alphabet.png");
    c+= genST("Parcours de Phrases","http://micetf.fr/parcours-de-phrases/","parcours_de_phrases.png");
	c+= "</div>";
	c+= "<div id='bt_lecture_ecriture' class='aff_act_fr' style='display:none;'>";
	c+= "<h4>Lecture et écriture <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique174'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Acrostiches","http://micetf.fr/acrostiche/","acrostiche.png");
    c+= genST("Ateliers TIC Écouter la lecture","http://seduc.csdecou.qc.ca/5-au-quotidien/ateliers-tic-ecouter-la-lecture/","tic_ecouterlalecture.png");
    c+= genST("Conscience Phonologique","http://micetf.fr/phonologie/","conscience_phonologique.png");
    c+= genST("Cryptext","http://www.jeu-de-puzzle.net/cryptext/flash/2010/jouer.php","cryptext.png");
    c+= genST("Dégradation de Cambridge","http://micetf.fr/cambridge/","cambridge.png");
    c+= genST("Discrimination visuelle","http://micetf.fr/discrimination/","discrimination_visuelle.png");
    c+= genST("EALOR","http://pragmatice.net/pragmactivites/ealor/","ealor.png");
    c+= genST("EasyPrompteur","http://www.easyprompter.com/","easyprompteur.png");
    c+= genST("Fabrique de Pourquoi ? Parce que !","http://micetf.fr/FabriquePourquoiParceque/","fabrique_pourquoi.png");
    c+= genST("La Bonne Image (lecture)","https://micetf.fr/JeuxLecture/#LaBonneImage-1","labonneimage_lecture.png");
    c+= genST("Le Bon Mot (lecture)","https://micetf.fr/JeuxLecture/#LeBonMot-1","lebonmot_lecture.png");
    c+= genST("Le Texte Mystère","http://pragmatice.net/pragmactivites/letextemystere/","letextemystere.png");
    c+= genST("LectOrBus","http://pragmatice.net/pragmactivites/lectorbus/","lectorbus.png");
    c+= genST("Les lettres de l’alphabet","https://monappli.net/app/francais/lettres/lettres-alphabet/","lettres-alphabet.png");
    //c+= genST("Minuscules majuscules","http://applipla.net/app/applis/clavier-min-maj.html","clavier-min-maj.png");
    c+= genST("Petite Fabrique Personnelle d’Histoires","http://micetf.fr/FabriqueHistoires/","fabrique_histoire.png");
    c+= genST("Reconstituer un mot","https://monappli.net/app/francais/mot/reconstituer-mot/","reconstituer-mot.png");
    c+= genST("Reconstituer une phrase (appliplaNet)","https://monappli.net/app/francais/phrase/reconstituer-phrase/","reconstituer-phrase.png");
    c+= genST("Reconstituer une phrase (MiCetF)","http://micetf.fr/phrases/","reconstituer_une_phrase.png");
    c+= genST("Short Edition Jeunesse","https://jeunesse.short-edition.com/","short_edition_jeunesse.png");
    c+= genST("WebLireCouleur","http://lirecouleur.arkaline.fr/web.html","weblirecouleur.png");
	c+= "</div>";
    c+= "<h4 style='padding:0; margin:0;'></h4>";
    c+= "</div></div></div>";
    $('#modale_act_francais').html(c).modal();
	$('.bt_act_fr').click(function () {
		var btClique = $(this).attr('data-bt');
		$('.bt_act_fr').removeClass('btn-primary').addClass('btn-secondary');
		$(this).removeClass('btn-secondary').addClass('btn-primary');
		$('.aff_act_fr').slideUp();
		$('#'+btClique).slideDown();
	});
}

// Générer et ouvrir la modale des activités de maths
function afficherActMaths() {
    var c = "<div class='modal-dialog modal-lg'>";
    c+= "<div class='modal-content bleu_leger'>";
    c+= "<div class='modal-body sites_tni'>";
	c+= "<button type='button' class='close' data-dismiss='modal'>&times;</button> <div style='margin-bottom:15px;'><button data-bt='bt_calcul' class='bt_act_ma btn btn-primary'>Calcul</button><button data-bt='bt_espace_geometrie' class='bt_act_ma btn btn-secondary'>Espace et géométrie</button><button data-bt='bt_grandeurs_mesures' class='bt_act_ma btn btn-secondary'>Grandeurs et mesures</button><button data-bt='bt_nombres' class='bt_act_ma btn btn-secondary'>Nombres</button><button data-bt='bt_outils_virtuels' class='bt_act_ma btn btn-secondary'>Outils virtuels</button><button data-bt='bt_resolution_problemes' class='bt_act_ma btn btn-secondary'>Résolution de problèmes</button><button data-bt='bt_tous_domaines' class='bt_act_ma btn btn-secondary'>Tous domaines</button></div>";
	c+= "<div id='bt_calcul' class='aff_act_ma'>";
    c+= "<h4>Calcul <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique176'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Addi-Grilles 2.0","http://micetf.fr/addigrille/","addigrille.png");
    c+= genST("Additions","http://micetf.fr/addition/","addition_m.png");
    c+= genST("Calcul Mental","http://micetf.fr/calculmental/","calculmental.png");
    c+= genST("Divisator","http://micetf.fr/divisator/","divisator.png");
    c+= genST("L’addition","https://monappli.net/app/mathematiques/calcul-mental/addition/","addition.png");
    c+= genST("L’addition à trou","https://monappli.net/app/mathematiques/calcul-mental/addition-lacunaire/","addition-cdu-lacunaire.png");
    //c+= genST("L’addition avec choix CDU","http://applipla.net/app/applis/addition-cdu.html","addition-cdu.png");
    c+= genST("L’addition posée","https://monappli.net/app/mathematiques/calcul-ecrit/addition/","calcul-ecrit-addition.png");
    c+= genST("La division","https://monappli.net/app/mathematiques/calcul-mental/division/","division.png");
    c+= genST("La multiplication","https://monappli.net/app/mathematiques/calcul-mental/multiplication/","multiplication.png");
    c+= genST("La soustraction","https://monappli.net/app/mathematiques/calcul-mental/soustraction/","soustraction.png");
    c+= genST("La soustraction à trou","https://monappli.net/app/mathematiques/calcul-mental/soustraction-lacunaire/","soustraction-cdu-lacunaire.png");
    //c+= genST("La soustraction avec choix CDU","http://applipla.net/app/applis/soustraction-cdu.html","soustraction-cdu.png");
    c+= genST("La soustraction avec emprunt","https://monappli.net/app/mathematiques/calcul-ecrit/soustraction-emprunt/","calcul-ecrit-soustraction-emprunt.png");
    c+= genST("La soustraction par compensation","https://monappli.net/app/mathematiques/calcul-ecrit/soustraction-compensation/","calcul-ecrit-soustraction-compensation.png");
    //c+= genST("Le complément","http://applipla.net/app/applis/complement.html","complement.png");
    c+= genST("Le compte est bon","http://mamisab.chez-alice.fr/","lecompteeestbon.png");
    //c+= genST("Les doubles","http://applipla.net/app/applis/doubles.html","doubles.png");
    c+= genST("Mathadorix","http://mathix.org/linux/archives/6963#a-vous-de-jouer","mathadorix.png");
    c+= genST("Tables - Arithmétique","https://phet.colorado.edu/sims/html/arithmetic/latest/arithmetic_fr.html","arithmetique.png");
    c+= genST("Tables - La Bonne Catégorie","http://pragmatice.net/pragmactivites/labonnecategorie/","labonnecategorie.png");
    //c+= genST("Tables - Le défi","http://applipla.net/app/applis/defi.html","defi.png");
    //c+= genST("Tables - Les associations","http://applipla.net/app/applis/associations.html","associations.png");
    //c+= genST("Tables - Les tables de multiplications","http://applipla.net/app/applis/table-multiplication.html","table-multiplication.png");
    //c+= genST("Tables - Tableau à double entrée","http://applipla.net/app/applis/tableau-double-entrees.html","tableau-double-entrees.png");
	c+= "</div>";
	c+= "<div id='bt_espace_geometrie' class='aff_act_ma' style='display:none;'>";
    c+= "<h4>Espace et géométrie <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique177'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Beebot : le jeu","http://classedeflorent.fr/accueil/jeux/beebot/index.php","beebot_lejeu.png");
    c+= genST("Code.org","https://code.org/","code_org.png");
    c+= genST("ColoGrilles","http://micetf.fr/cologrilles/","cologrilles.png");
    c+= genST("Déplacements sur quadrillages","https://www.clicmaclasse.fr/activites/deplacements/deplacements.php","deplacement_sur_quadrillage.png");
    c+= genST("Formes géométriques (MLC)","https://apps.mathlearningcenter.org/pattern-shapes/","mathlearningcenter_formesgeometriques.png");
    c+= genST("Geogebra","https://www.geogebra.org/geometry","geogebra.png");
    //c+= genST("Glisser Déposer","http://applipla.net/app/applis/glisser-deposer.html","glisser-deposer.png");
    c+= genST("InstrumenPoche","https://instrumenpoche.sesamath.net/v2/iep.php","instrumenpoche.png");
    c+= genST("Je veux tracer","http://pcolleu.free.fr/maths/flash/geometrie.html","jeveuxtracer.png");
    c+= genST("La chasse au nuage","http://micetf.fr/reperage/","lachasseauxnuages.png");
    c+= genST("La fabrique de robots","http://micetf.fr/robots/","lafabriquederobots.png");
    //c+= genST("Le labyrinthe","http://applipla.net/app/applis/labyrinthe.html","labyrinthe.png");
    c+= genST("Logitic","http://micetf.fr/logitic/","logitic.png");
    c+= genST("Reproduction sur quadrillage","http://micetf.fr/reproduction-sur-quadrillage/","reproduction_sur_quadrillage.png");
    c+= genST("Scratch","https://scratch.mit.edu/","scratch.png");
    c+= genST("Symétrie sur quadrillage","http://micetf.fr/symetrie-sur-quadrillage/","symetriesurquadrillage.png");
    c+= genST("TracenPoche","http://tracenpoche.sesamath.net/flashfr/","tracenpoche.png");
    c+= genST("Vers la symétrie...","http://micetf.fr/Symetrie/","verslasymetrie.png");
	c+= "</div>";
	c+= "<div id='bt_grandeurs_mesures' class='aff_act_ma' style='display:none;'>";
    c+= "<h4>Grandeurs et mesures <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique178'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Action d’équilibrage","https://phet.colorado.edu/sims/html/balancing-act/latest/balancing-act_fr.html","actionsdequilibrage.png");
    c+= genST("Constructeur d’Aire","https://phet.colorado.edu/sims/html/area-builder/latest/area-builder_fr.html","constructeurdaire.png");
    c+= genST("Estimation","https://phet.colorado.edu/sims/estimation/estimation_fr.html","estimation.png");
    c+= genST("Geoboard (MLC)","https://apps.mathlearningcenter.org/geoboard/","mathlearningcenter_geoboard.png");
    c+= genST("Jeux d’argent","http://tice67.site.ac-strasbourg.fr/fr/index_argent","jeuxdargent.png");
    c+= genST("Jeux de pesée","http://tice67.site.ac-strasbourg.fr/fr/index_pesee","jeuxdepesee.png");
    c+= genST("L’horloge","https://monappli.net/app/mathematiques/grandeurs/horloge/","horloge-interactive.png");
    c+= genST("La balance","https://monappli.net/app/mathematiques/grandeurs/balance/","balance-interactive.png");
    c+= genST("La monnaie","https://monappli.net/app/mathematiques/grandeurs/monnaie/","monnaie.png");
    c+= genST("Lecture de l’heure","http://micetf.fr/LectureHeure","lecture_heure.png");
    //c+= genST("Les cadrans","http://applipla.net/app/applis/cadran.html","cadran.png");
    c+= genST("Les conversions","https://monappli.net/app/mathematiques/grandeurs/conversions/","conversions.png");
    c+= genST("Périmètre et aire d’un rectangle","http://micetf.fr/mesures/","perimetre_aire.png");
	c+= "</div>";
	c+= "<div id='bt_nombres' class='aff_act_ma' style='display:none;'>";
    c+= "<h4>Nombres <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique175'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Classer des nombres","https://monappli.net/app/mathematiques/nombres/ordonner/","ordonner.png");
    c+= genST("Comparer des nombres","https://monappli.net/app/mathematiques/nombres/comparer/","comparer.png");
    c+= genST("Dictée de nombres","http://micetf.fr/dicteenombres/","dictee_nombres.png");
    c+= genST("Écriture fractionnaire","http://micetf.fr/Fractions/","ecriture_fractionnaire.png");
    c+= genST("Faire un dix","https://phet.colorado.edu/sims/html/make-a-ten/latest/make-a-ten_fr.html","faireundix.png");
    c+= genST("Fractions","http://applipla.net/app/applis/fractions.html","fractions.png");
    c+= genST("Fractions (MLC)","https://apps.mathlearningcenter.org/fractions/","mathlearningcenter_fractions.png");
    c+= genST("Fractions équivalentes","https://phet.colorado.edu/sims/html/fraction-matcher/latest/fraction-matcher_fr.html","fractions_equivalentes.png");
    c+= genST("Jeu des Cibles","http://micetf.fr/cibles/","jeudescibles.png");
    c+= genST("Jeu du parachutiste","http://micetf.fr/parachute/","jeu_parachutiste.png");
    c+= genST("Jeu du parapente","http://micetf.fr/parapente/","jeu_parapente.png");
    c+= genST("La ruche des Nombres","http://micetf.fr/ruche-nombres/","laruchedesnombres.png");
    //c+= genST("Le complément de dix","http://applipla.net/app/applis/complement-10.html","complement-10.png");
    c+= genST("Le glisse-nombre","https://monappli.net/app/mathematiques/nombres/glisse-nombre/","le-glisse-nombre.png");
    c+= genST("Le nombre mystère","https://monappli.net/app/mathematiques/nombres/mystere/","nombre-mystere.png");
    c+= genST("Le nombre pensé","http://micetf.fr/pense/","lenombrepense.png");
    c+= genST("Ordonner des nombres","http://micetf.fr/ordonner/","ordonner_nombres.png");
    //c+= genST("Passage à la dizaine","http://applipla.net/app/applis/passage-dizaine.html","passage-dizaine.png");
    //c+= genST("Trouver le nombre mystère","http://applipla.net/app/applis/trouver-nombre.html","trouver-nombre.png");
	c+= "</div>";
	
	c+= "<div id='bt_outils_virtuels' class='aff_act_ma' style='display:none;'>";
    c+= "<h4>Outils virtuels <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique185'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
	c+= sitesOutilsNumeration;
	c+= "</div>";
	
	
	c+= "<div id='bt_resolution_problemes' class='aff_act_ma' style='display:none;'>";
    c+= "<h4>Résolution de problèmes <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique179'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Abaques-taquins","http://micetf.fr/abataquin/","abaques-taquins.png");
    c+= genST("Aire de jeu proportionnelle","https://phet.colorado.edu/sims/html/proportion-playground/latest/proportion-playground_fr.html","airedejeu.png");
    c+= genST("Embouteillages","http://micetf.fr/embouteillages/","embouteillages.png");
    c+= genST("La Course au 21","http://micetf.fr/CourseAu21/","courseau21.png");
    c+= genST("Mastermind","http://micetf.fr/mastermind/","mastermind.png");
    c+= genST("Mosaïque express","http://micetf.fr/mosaique/","mosaique.png");
    c+= genST("Résolution de problèmes","http://micetf.fr/Problemes","resolution_problemes.png");
    c+= genST("Sudoku pour la classe","http://micetf.fr/sudoku/","sudoku.png");
    c+= genST("Véhicules","http://micetf.fr/vehicules/","vehicules.png");
	c+= "</div>";
	c+= "<div id='bt_tous_domaines' class='aff_act_ma' style='display:none;'>";
    c+= "<h4>Tous domaines <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique193'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Activités mathématiques","http://pragmatice.net/activites_mathematiques/","activites_mathematiques.png");
    c+= genST("Calcul@tice ","https://calculatice.ac-lille.fr/spip.php?rubrique2","calculatice.png");
    c+= genST("Maths en vie","http://www.ac-grenoble.fr/ien.st-gervais/mathsenvie/","mathsenvie.png");
	c+= "</div>";
    c+= "<h4 style='padding:0; margin:0;'></h4>";
    c+= "</div></div></div>";
    $('#modale_act_maths').html(c).modal();
	$('.bt_act_ma').click(function () {
		var btClique = $(this).attr('data-bt');
		$('.bt_act_ma').removeClass('btn-primary').addClass('btn-secondary');
		$(this).removeClass('btn-secondary').addClass('btn-primary');
		$('.aff_act_ma').slideUp();
		$('#'+btClique).slideDown();
	});
}

// Générer et ouvrir la modale des activités diverses
function afficherActDiverses() {
    var c = "<div class='modal-dialog modal-lg'>";
    c+= "<div class='modal-content bleu_leger'>";
    c+= "<div class='modal-body sites_tni'>";
	c+= "<button type='button' class='close' data-dismiss='modal'>&times;</button> <div style='margin-bottom:15px;'><button data-bt='bt_art' class='bt_act_di btn btn-primary'>Arts</button><button data-bt='bt_hist_geo' class='bt_act_di btn btn-secondary'>Hist. Géographie EMC</button><button data-bt='bt_lve' class='bt_act_di btn btn-secondary'>LVE</button><button data-bt='bt_memoire_observation' class='bt_act_di btn btn-secondary'>Mémoire et observation</button><button data-bt='bt_multidomaine' class='bt_act_di btn btn-secondary'>Multidomaine</button></div>";
	c+= "<div id='bt_art' class='aff_act_di'>";
    c+= "<h4>Arts <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique192'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Animations et jeux musicaux","http://bourgoise.fr/animations/flash.html","animations_jeux_musicaux.png");
	c+= "</div>";
	c+= "<div id='bt_hist_geo' class='aff_act_di' style='display:none;'>";
    c+= "<h4>Histoire Géographie EMC <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique180'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Cartes interactives avec Flash","http://serbal.pntic.mec.es/ealg0027/cartflash.htm","cartes_interactives_flash.png");
    c+= genST("Frise chronologique","http://marelle.org/cdi/h-histoire/frises/imgcol/contact_1.htm","frise.png");
    c+= genST("Frise chronologique histoire et archéologie","https://multimedia.inrap.fr/archeologie-preventive/chronologie-generale#item-3","frise_chronologique_histoire_arc.png");
    c+= genST("Générateur de frises","http://micetf.fr/frise/","generateur_frise.png");
    c+= genST("Géoportail","https://www.geoportail.gouv.fr/","geoportail.png");
    c+= genST("Jeux de géographie","http://jeux-geographie.fr/","jeuxdegeographie.png");
    c+= genST("Jeux géographiques","http://www.jeux-geographiques.com/","jeux-geographiques.png");
    c+= genST("Remonter le temps","https://remonterletemps.ign.fr/","remonterletemps.png");
    c+= genST("Toporama","http://www.toporopa.eu/fr/","toporama.png");
	c+= "</div>";
	c+= "<div id='bt_lve' class='aff_act_di' style='display:none;'>";
    c+= "<h4>Langues vivantes étrangères <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique188'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Dictée de nombres","http://micetf.fr/dicteenombres/","dictee_nombres.png");
    c+= genST("EALOR","http://pragmatice.net/pragmactivites/ealor/","ealor.png");
    c+= genST("Je fais une dictée","https://micetf.fr/dictee/","dictee_jecree.png");
	c+= "</div>";
	c+= "<div id='bt_memoire_observation' class='aff_act_di' style='display:none;'>";
    c+= "<h4>Mémoire et observation <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique181'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Différences","http://micetf.fr/differences/","differences.png");
    c+= genST("EALOR","http://pragmatice.net/pragmactivites/ealor/","ealor.png");
    c+= genST("Images séquentielles","http://micetf.fr/images-sequentielles/","images_sequentielles.png");
    c+= genST("Jeu de Memory","http://micetf.fr/memory/","memory_mi.png");
    c+= genST("L’image mystère","https://monappli.net/app/jeux/observation/image-mystere/","image-mystere.png");
    c+= genST("Le Mémory","https://monappli.net/app/jeux/memorisation/memory/","le-memory.png");
    c+= genST("LectOrBus","http://pragmatice.net/pragmactivites/lectorbus/","lectorbus.png");
    //c+= genST("Les images séquentielles","http://applipla.net/app/applis/images-sequentielles.html","images-sequentielles.png");
    c+= genST("Les puzzles","https://monappli.net/app/jeux/observation/puzzle/","puzzle.png");
    c+= genST("PictureToPuzzle","http://micetf.fr/picturetopuzzle/","picturetopuzzle.png");
	c+= "</div>";
	c+= "<div id='bt_multidomaine' class='aff_act_di' style='display:none;'>";
    c+= "<h4>Multidomaine <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique189'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Dustbin Game","http://www.classtools.net/education-games-php/dustbin","dustbin_game.png");
    c+= genST("EALOR","http://pragmatice.net/pragmactivites/ealor/","ealor.png");
    c+= genST("La Bonne Catégorie","http://pragmatice.net/pragmactivites/labonnecategorie/","labonnecategorie.png");
    c+= genST("LearningApps","http://learningapps.org/setLanguage.php?language=FR&return=%2F","learningapps.png");
    c+= genST("LectOrBus","http://pragmatice.net/pragmactivites/lectorbus/","lectorbus.png");
    c+= genST("La Bonne Image (quiz)","http://micetf.fr/la-bonne-image/","labonneimage_quiz.png");
    c+= genST("Le Bon Mot (quiz)","http://micetf.fr/le-bon-mot/","lebonmot_quiz.png");
	c+= "</div>";
    c+= "<h4 style='padding:0; margin:0;'></h4>";
    c+= "</div></div></div>";
    $('#modale_act_diverses').html(c).modal();
	$('.bt_act_di').click(function () {
		var btClique = $(this).attr('data-bt');
		$('.bt_act_di').removeClass('btn-primary').addClass('btn-secondary');
		$(this).removeClass('btn-secondary').addClass('btn-primary');
		$('.aff_act_di').slideUp();
		$('#'+btClique).slideDown();
	});
}

// Générer et ouvrir la modale des supports
function afficherSupports() {
    var c = "<div class='modal-dialog modal-lg'>";
    c+= "<div class='modal-content bleu_leger'>";
    c+= "<div class='modal-body sites_tni'>";
	c+= "<button type='button' class='close' data-dismiss='modal'>&times;</button> <div style='margin-bottom:15px;'><button data-bt='bt_videos_animations' class='bt_act_su btn btn-primary'>Animations et vidéos</button><button data-bt='bt_fonds' class='bt_act_su btn btn-secondary'>Fonds d'écran</button><button data-bt='bt_instrument_mesure' class='bt_act_su btn btn-secondary'>Instruments de mesure</button><button data-bt='bt_numeration_calcul' class='bt_act_su btn btn-secondary'>Numération et calcul</button><button data-bt='bt_production' class='bt_act_su btn btn-secondary'>Production</button><button data-bt='bt_tableaux_virtuels' class='bt_act_su btn btn-secondary'>Tableaux virtuels</button><button data-bt='bt_tirages' class='bt_act_su btn btn-secondary'>Tirages aléatoires</button></div>";
	c+= "<div id='bt_videos_animations' class='aff_act_su'>";
	c+= "<h4>Animations et vidéos <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique191'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("1 jour 1 actu","http://www.1jour1actu.com/","1jour1actu.png");
    c+= genST("1 jour 1 question","https://www.youtube.com/channel/UCLmlUMA_bGiMWWgfDwfNDgw","1jour1question.png");
    c+= genST("Apprends l’anglais avec Kiwi","https://www.youtube.com/channel/UC7-gqKShqpiwPURAITIlKVQ","kiwi.png");
    c+= genST("Comptines et chansons pour enfants","http://comptines.tv/","comptines.png");
    c+= genST("D'capsules pour l'école","http://dcapsulespourlecole.weebly.com/","dcapsules.png");
    c+= genST("English for Schools","http://kids.englishforschools.fr/","englishforschools.png");
    c+= genST("Équipe Animations FLASH","http://www.pearltrees.com/t/animations-flash/id8011747","equipe_animations_flash.png");
    c+= genST("Francetv Éducation","http://education.francetv.fr/matiere/actualite/ecole","francetveducation.png");
    c+= genST("Histoires de Pirates","https://www.youtube.com/channel/UCopJ4WLILpzchs12InKSs5w","histoiresdepirates.png");
    c+= genST("lesite.tv","http://www.lesite.tv/edutheque/","lesitetv.png");
    c+= genST("L'espace citoyen des 7-11 ans","https://lespetitscitoyens.com/voir/","lespetitscitoyens.png");
    c+= genST("Les devinettes de Reinette","https://www.youtube.com/channel/UCGz8IYFCZasdxDcncGOBivg","lesdevinettesdereinette.png");
    c+= genST("Les fondamentaux","https://www.reseau-canope.fr/fondamentaux/","lesfondamentaux.png");
    c+= genST("Notre histoire","https://www.youtube.com/channel/UCoDB-R_Dehh3_oiW5siNqTA","notrehistoire.png");
    c+= genST("Sid le petit scientifique","https://education.francetv.fr/matiere/decouverte-des-sciences/ce1/programme/decouvre-avec-sid","sid.png");
    c+= genST("Vinz et Lou","https://www.vinzetlou.net/fr/ressources/theme","vinzetlou.png");
	c+= "</div>";
	c+= "<div id='bt_fonds' class='aff_act_su' style='display:none;'>";
    c+= "<h4>Fonds d'écran <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique187'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Cursivecole","https://cursivecole.fr/","cursivecole.png");
    c+= genST("Fonds de cartes IGN","http://education.ign.fr/primaire/fonds-de-cartes","fondsdecartesign.png");
    c+= genST("Générateur de feuilles","http://www.desmoulins.fr/index.php?pg=scripts!online!feuilles","generateurdefeuilles.png");
	c+= "</div>";
	c+= "<div id='bt_instrument_mesure' class='aff_act_su' style='display:none;'>";
    c+= "<h4>Instruments de mesure <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique183'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Bouncy Balls","https://bouncyballs.org/","bouncyballs.png");
    c+= genST("Chronomètre Stopwatch","http://www.online-stopwatch.com/analog-stopwatch/full-screen/","chronomètre_stopwatch.png");
    c+= genST("Jeux de pesée","http://tice67.site.ac-strasbourg.fr/fr/index_pesee","jeuxdepesee.png");
    c+= genST("L’horloge","https://monappli.net/app/mathematiques/grandeurs/horloge/","horloge-interactive.png");
    c+= genST("La balance","https://monappli.net/app/mathematiques/grandeurs/balance/","balance-interactive.png");
    c+= genST("La règle","https://monappli.net/app/mathematiques/grandeurs/regle/","regle.png");
    c+= genST("Le rapporteur","https://monappli.net/app/mathematiques/grandeurs/rapporteur/","rapporteur-interactif.png");
    c+= genST("Le thermomètre","https://monappli.net/app/mathematiques/grandeurs/thermometre/","thermometre-interactif.png");
    c+= genST("Minuteur Stopwatch","http://www.online-stopwatch.com/countdown-clock/full-screen/","minuteur_stopwatch.png");
    c+= genST("Minuteurs pour la classe","http://www.online-stopwatch.com/classroom-timers/","minuteurs_classe.png");
    c+= genST("Temps Qui Reste","http://micetf.fr/tempsquireste/","tempsquireste.png");
    c+= genST("Thermomètre interactif","http://micetf.fr/thermometre/","thermometre.png");
	c+= "</div>";
	c+= "<div id='bt_numeration_calcul' class='aff_act_su' style='display:none;'>";
    c+= "<h4>Numération et calcul <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique185'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= sitesOutilsNumeration;
	c+= "</div>";
	c+= "<div id='bt_production' class='aff_act_su' style='display:none;'>";
    c+= "<h4>Production <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique190'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Framacalc","https://lite.framacalc.org//","framacalc.png");
    c+= genST("Frama.link","https://frama.link/","framalink.png");
    c+= genST("Framapad","https://framapad.org/","framapad.png");
    c+= genST("Framaslides","https://framaslides.org/","framaslides.png");
    c+= genST("Framavectoriel","https://framavectoriel.org/","framavectoriel.png");
    c+= genST("Framemo","https://framemo.org/","framemo.png");
    c+= genST("Framindmap","https://framindmap.org/","framindmap.png");
    c+= genST("Petit Livre Multimédia","http://pragmatice.net/pragmaprodu/petitlivremultimedia/","petitlivremultimedia.png");
    c+= genST("Pixlr Editor","https://www.pixlr.com/editor/?loc=fr","pixlr.png");
    c+= genST("Texte en couleur","https://cahiersfantastiques.fr/texte-en-couleur.php","texteencouleur.png");
	c+= "</div>";
	c+= "<div id='bt_tableaux_virtuels' class='aff_act_su' style='display:none;'>";
    c+= "<h4>Tableaux virtuels <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique184'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Alphabet","http://micetf.fr/alphabet/","alphabet.png");
    c+= genST("Ardoise","http://micetf.fr/ardoise/","ardoise.png");
    c+= genST("ClassroomScreen","https://www.classroomscreen.com/","classroomscreen.png");
    c+= genST("Classement","http://micetf.fr/classement/","classement.png");
    c+= genST("La météo","https://monappli.net/app/utilitaires/rituels/meteo/","la-meteo.png");
    c+= genST("Stoodle","https://stoodle.ck12.org/","stoodle.png");
    c+= genST("Virtual Manipulatives","http://www.glencoe.com/sites/common_assets/mathematics/ebook_assets/vmf/VMF-Interface.html","virtual_manipulatives.png");
    c+= genST("Witeboard","https://witeboard.com/","witeboard.png");
	c+= "</div>";
	c+= "<div id='bt_tirages' class='aff_act_su' style='display:none;'>";
    c+= "<h4>Tirages aléatoires <a title='En savoir plus sur ces activités...' target='_blank' href='http://pragmatice.net/lesite/spip.php?rubrique186'><img class='pointer scale_p01' src='images/icone_info_24.png' /></a></h4>";
    c+= genST("Fruit Machine","http://www.classtools.net/education-games-php/fruit_machine","fruit_machine.png");
    c+= genST("Le choixpeau magique","http://micetf.fr/choixpeau/","choixpeau.png");
    c+= genST("Les dés","https://monappli.net/app/utilitaires/tirages/des/","les-des.png");
    c+= genST("Nombre aléatoire","https://monappli.net/app/utilitaires/tirages/nombre-aleatoire/","nombre-aleatoire.png");
    c+= genST("Noms et nombres aléatoires","https://www.online-stopwatch.com/french/random/","noms_nombres_aleatoires.png");
    c+= genST("Random Name Picker","https://www.classtools.net/random-name-picker/","random_name_picker.png");
    c+= genST("Tirage au sort","https://monappli.net/app/utilitaires/tirages/sort/","tirage-au-sort.png");
	c+= "</div>";
    c+= "<h4 style='padding:0; margin:0;'></h4>";
    c+= "</div></div></div>";
    $('#modale_supports').html(c).modal();
	$('.bt_act_su').click(function () {
		var btClique = $(this).attr('data-bt');
		$('.bt_act_su').removeClass('btn-primary').addClass('btn-secondary');
		$(this).removeClass('btn-secondary').addClass('btn-primary');
		$('.aff_act_su').slideUp();
		$('#'+btClique).slideDown();
	});
}

// Générer et ouvrir la modale des moteurs de recherche
function moteursRecherche() {
    if ($("#modale_moteurs_recherche").size() < 1) {// si l'id modale_moteurs_recherche n'existe pas, on génére l'html
        var oRech = '<div class="modal fade" id="modale_moteurs_recherche" role="dialog">';
        oRech += '<div class="modal-dialog">';
        oRech += '<div class="modal-content">';
        oRech += '<div class="modal-body">';
        oRech += '<button type="button" class="close" data-dismiss="modal">&times;</button>';
        oRech += '<label>Saisis le mot à rechercher et clique sur un bouton.</label>';
        oRech += '<div class="row">';
        oRech += '<div class="col-lg-7 col-md-7 col-sm-7 col-xs-12" style="position:relative">';
        oRech += '<input id="mot_recherche_saisi" type="text" class="form-control">';
		oRech += "<img id='bt_clavier_recherche' class='pointer scale_p015' src='images/logo_clavier_16_10.png' style='position:absolute; top:20px; right:20px;' />";
		oRech += "<div class='clavier_basique' style='display:none;'>";// début clavier virtuel
		oRech += "<button>a</button><button>z</button><button>e</button><button>r</button><button>t</button><button>y</button><button>u</button><button>i</button><button>o</button><button>p</button><br />";
		oRech += "<button>q</button><button>s</button><button>d</button><button>f</button><button>g</button><button>h</button><button>j</button><button>k</button><button>l</button><button>m</button><br />";
		oRech += "<button>w</button><button>x</button><button>c</button><button>v</button><button>b</button><button>n</button><button style='visibility:hidden;'>a</button><button>&nbsp;</button><button>'</button><button>-</button><br />";
		oRech += "<button>à</button><button>â</button><button>ä</button><button>ç</button><button>é</button><button>è</button><button>ê</button><button>ë</button><button>î</button><button>ï</button><br />";
		oRech += "<button>ô</button><button>ö</button><button>ù</button><button>û</button><button>ü</button><button style='visibility:hidden;'>a</button><button style='visibility:hidden;'>a</button><button style='visibility:hidden;'>a</button><button style='visibility:hidden;'>a</button><button data-bt='retour'>&larr;</button><br />";
		oRech += "<button>0</button><button>1</button><button>2</button><button>3</button><button>4</button><button>5</button><button>6</button><button>7</button><button>8</button><button>9</button>";
		oRech += "</div>";// fin clavier virtuel
        oRech += '<div id="image_rechercher" class="cadre_image_rechercher"><img src="images/rechercher/rechercher_accueil.png"></div>';
        // oRech += '<button id="bt_lexique" class="btn btn-info btn-block no_imprim"><span class="glyphicon glyphicon-book"></span> Lexique collaboratif</button>';
        oRech += '</div>';// Fin <div class="col-sm-7">
        oRech += '<div class="col-lg-5 col-md-5 col-sm-5 col-xs-12 pave_boutons_recherche">';
        oRech += '<p><button id="bt_recherche_dictionnaire" class="btn btn-info no_imprim bt_recherche">Dictionnaire</button></p>';
        oRech += '<p><button id="bt_recherche_encyclopedie" class="btn btn-info no_imprim bt_recherche">Encyclopédie</button></p>';
        oRech += '<p><button id="bt_recherche_synonyme" class="btn btn-info no_imprim bt_recherche">Synonyme</button></p>';
        oRech += '<p><button id="bt_recherche_contraire" class="btn btn-info no_imprim bt_recherche">Contraire</button></p>';
        oRech += '<p><button id="bt_recherche_conjugaison" class="btn btn-info no_imprim bt_recherche">Conjugaison</button></p>';
        oRech += '<p><button id="bt_recherche_expression" class="btn btn-info no_imprim bt_recherche">Expression</button></p>';
        oRech += '<p><button id="bt_recherche_rime" class="btn btn-info no_imprim bt_recherche">Rime</button></p>';
        oRech += '<ul>';
        oRech += '<li><button title="Web" id="bt_recherche_moteur_web" class="btn btn-info bt_recherche"><img alt="Web" src="images/rechercher/rechercher_icone_moteur_web.png" /></button></li>';
        oRech += '<li><button title="Actualités" id="bt_recherche_moteur_actualite" class="btn btn-info bt_recherche"><img alt="Actualité" src="images/rechercher/rechercher_icone_moteur_actualite.png" /></button></li>';
        oRech += '<li><button title="Education" id="bt_recherche_moteur_education" class="btn btn-info bt_recherche"><img alt="Education" src="images/rechercher/rechercher_icone_moteur_education.png" /></button></li>';
        oRech += '<li><button title="Images" id="bt_recherche_moteur_image" class="btn btn-info bt_recherche"><img alt="Images" src="images/rechercher/rechercher_icone_moteur_image.png" /></button></li>';
        oRech += '<li><button title="Vidéos" id="bt_recherche_moteur_video" class="btn btn-info bt_recherche"><img alt="Vidéos" src="images/rechercher/rechercher_icone_moteur_video.png" /></button></li>';
        oRech += '</ul>';
        oRech += '<ul class="rechercher_suite">';
        oRech += '<li><a target="_blank" href="http://weblitoo.net/favoris/categorie.php?idc=19">Banque d\'images et de sons</a></li>';
        oRech += '<li><a target="_blank" href="http://weblitoo.net/favoris/categorie.php?idc=12">Dictionnaires et encyclopédies</a></li>';
        oRech += '<li><a target="_blank" href="http://weblitoo.net/favoris/categorie.php?idc=38">Moteurs de recherche</a></li>';
        oRech += '</ul>';
        oRech += '</div>';// Fin <div class="col-sm-5">
        oRech += '</div>';// Fin <div class="row">
        oRech += '<div id="affichage_lexique" style="margin-top:10px; display:none;">Affichage des mots à concevoir...</div>';
        oRech += '</div></div></div>';
        $('body').append(oRech);
        // $('#bt_lexique').click(function () {
            // $('#affichage_lexique').slideToggle();
        // });
		$('.clavier_basique > button').click(function () {
            var saisieEnCours = $('#mot_recherche_saisi').val();
			var lecar = $(this).html();
			var dataBt = $(this).attr('data-bt');
			if (lecar === "&nbsp;") lecar = " ";
			if (dataBt === "retour") {
				if (saisieEnCours != "") {
					saisieEnCours = saisieEnCours.slice(0, -1);
					$('#mot_recherche_saisi').val(saisieEnCours);
				}
			}
			else {
				$('#mot_recherche_saisi').val(saisieEnCours+lecar);
			}
        });
		$('#bt_clavier_recherche').click(function () {
            $('.clavier_basique').slideToggle();
        });
		$('#mot_recherche_saisi').val('');
		$('#image_rechercher').html('<img src="images/rechercher/rechercher_accueil.png">');
		$('#modale_moteurs_recherche').on('shown.bs.modal', function () {
			$(this).find('.form-control:visible:first').focus();
		});
		$('.bt_recherche').click(function () {
			var mot_saisi = $('#mot_recherche_saisi').val();
			var id_bt_choisi = $(this).attr('id');
			if (mot_saisi) {
				if (id_bt_choisi == 'bt_recherche_dictionnaire')
					window.open('http://www.dictionnaire.net/definition/' + mot_saisi + '.html', '_blank');
				if (id_bt_choisi == 'bt_recherche_encyclopedie')
					window.open('https://fr.vikidia.org/wiki/' + mot_saisi, '_blank');
				if (id_bt_choisi == 'bt_recherche_synonyme')
					window.open('http://www.synonymo.fr/synonyme/' + mot_saisi, '_blank');
				if (id_bt_choisi == 'bt_recherche_contraire')
					window.open('http://www.antonyme.org/antonyme/' + mot_saisi, '_blank');
				if (id_bt_choisi == 'bt_recherche_conjugaison')
					window.open('http://www.conjugue-moi.com/conjuguer.php?verbe=' + mot_saisi, '_blank');
				if (id_bt_choisi == 'bt_recherche_expression')
					window.open('http://www.les-expressions.com/resultats.php?search=' + escape(mot_saisi), '_blank');
				if (id_bt_choisi == 'bt_recherche_rime')
					window.open('http://www.dicodesrimes.com/rime/' + escape(mot_saisi), '_blank');
				if (id_bt_choisi == 'bt_recherche_moteur_web')
					window.open('https://www.qwantjunior.com/?q=' + mot_saisi + '&t=web', '_blank');
				if (id_bt_choisi == 'bt_recherche_moteur_actualite')
					window.open('https://www.qwantjunior.com/?q=' + mot_saisi + '&t=news', '_blank');
				if (id_bt_choisi == 'bt_recherche_moteur_education')
					window.open('https://www.qwantjunior.com/?q=' + mot_saisi + '&t=education', '_blank');
				if (id_bt_choisi == 'bt_recherche_moteur_image')
					window.open('https://www.qwantjunior.com/?q=' + mot_saisi + '&t=images', '_blank');
				if (id_bt_choisi == 'bt_recherche_moteur_video')
					window.open('https://www.qwantjunior.com/?q=' + mot_saisi + '&t=videos', '_blank');
			} else {
				alert('Oups ! Saisis le mot à rechercher...');
				$('#mot_recherche_saisi').focus();
			}
		});
		$('.bt_recherche').mouseover(function () {
			var mot_saisi = $('#mot_recherche_saisi').val();
			var id_bt_choisi = $(this).attr('id');
			if (id_bt_choisi == 'bt_recherche_dictionnaire')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_dictionnaire.png">');
			if (id_bt_choisi == 'bt_recherche_encyclopedie')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_encyclopedie.png">');
			if (id_bt_choisi == 'bt_recherche_synonyme')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_synonyme.png">');
			if (id_bt_choisi == 'bt_recherche_contraire')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_contraire.png">');
			if (id_bt_choisi == 'bt_recherche_conjugaison')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_conjugaison.png">');
			if (id_bt_choisi == 'bt_recherche_expression')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_expression.png">');
			if (id_bt_choisi == 'bt_recherche_rime')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_rime.png">');
			if (id_bt_choisi == 'bt_recherche_moteur_web')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_qwant_web.png">');
			if (id_bt_choisi == 'bt_recherche_moteur_actualite')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_qwant_actualite.png">');
			if (id_bt_choisi == 'bt_recherche_moteur_education')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_qwant_education.png">');
			if (id_bt_choisi == 'bt_recherche_moteur_image')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_qwant_image.png">');
			if (id_bt_choisi == 'bt_recherche_moteur_video')
				$('#image_rechercher').html('<img src="images/rechercher/rechercher_qwant_video.png">');
		});
    }	
	$("#modale_moteurs_recherche").modal();
}

/* -------------------------
FONCTIONS PLUGIN JQUERY SELECTION https://github.com/madapaja/jquery.selection
----------------------------*/

/*!
 * jQuery.selection - jQuery Plugin
 *
 * Copyright (c) 2010-2014 IWASAKI Koji (@madapaja).
 * http://blog.madapaja.net/
 * Under The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
(function($, win, doc) {
    /**
     * get caret status of the selection of the element
     *
     * @param   {Element}   element         target DOM element
     * @return  {Object}    return
     * @return  {String}    return.text     selected text
     * @return  {Number}    return.start    start position of the selection
     * @return  {Number}    return.end      end position of the selection
     */
    var _getCaretInfo = function(element){
        var res = {
            text: '',
            start: 0,
            end: 0
        };

        if (!element.value) {
            /* no value or empty string */
            return res;
        }

        try {
            if (win.getSelection) {
                /* except IE */
                res.start = element.selectionStart;
                res.end = element.selectionEnd;
                res.text = element.value.slice(res.start, res.end);
            } else if (doc.selection) {
                /* for IE */
                element.focus();

                var range = doc.selection.createRange(),
                    range2 = doc.body.createTextRange();

                res.text = range.text;

                try {
                    range2.moveToElementText(element);
                    range2.setEndPoint('StartToStart', range);
                } catch (e) {
                    range2 = element.createTextRange();
                    range2.setEndPoint('StartToStart', range);
                }

                res.start = element.value.length - range2.text.length;
                res.end = res.start + range.text.length;
            }
        } catch (e) {
            /* give up */
        }

        return res;
    };

    /**
     * caret operation for the element
     * @type {Object}
     */
    var _CaretOperation = {
        /**
         * get caret position
         *
         * @param   {Element}   element         target element
         * @return  {Object}    return
         * @return  {Number}    return.start    start position for the selection
         * @return  {Number}    return.end      end position for the selection
         */
        getPos: function(element) {
            var tmp = _getCaretInfo(element);
            return {start: tmp.start, end: tmp.end};
        },

        /**
         * set caret position
         *
         * @param   {Element}   element         target element
         * @param   {Object}    toRange         caret position
         * @param   {Number}    toRange.start   start position for the selection
         * @param   {Number}    toRange.end     end position for the selection
         * @param   {String}    caret           caret mode: any of the following: "keep" | "start" | "end"
         */
        setPos: function(element, toRange, caret) {
            caret = this._caretMode(caret);

            if (caret === 'start') {
                toRange.end = toRange.start;
            } else if (caret === 'end') {
                toRange.start = toRange.end;
            }

            element.focus();
            try {
                if (element.createTextRange) {
                    var range = element.createTextRange();

                    if (win.navigator.userAgent.toLowerCase().indexOf("msie") >= 0) {
                        toRange.start = element.value.substr(0, toRange.start).replace(/\r/g, '').length;
                        toRange.end = element.value.substr(0, toRange.end).replace(/\r/g, '').length;
                    }

                    range.collapse(true);
                    range.moveStart('character', toRange.start);
                    range.moveEnd('character', toRange.end - toRange.start);

                    range.select();
                } else if (element.setSelectionRange) {
                    element.setSelectionRange(toRange.start, toRange.end);
                }
            } catch (e) {
                /* give up */
            }
        },

        /**
         * get selected text
         *
         * @param   {Element}   element         target element
         * @return  {String}    return          selected text
         */
        getText: function(element) {
            return _getCaretInfo(element).text;
        },

        /**
         * get caret mode
         *
         * @param   {String}    caret           caret mode
         * @return  {String}    return          any of the following: "keep" | "start" | "end"
         */
        _caretMode: function(caret) {
            caret = caret || "keep";
            if (caret === false) {
                caret = 'end';
            }

            switch (caret) {
                case 'keep':
                case 'start':
                case 'end':
                    break;

                default:
                    caret = 'keep';
            }

            return caret;
        },

        /**
         * replace selected text
         *
         * @param   {Element}   element         target element
         * @param   {String}    text            replacement text
         * @param   {String}    caret           caret mode: any of the following: "keep" | "start" | "end"
         */
        replace: function(element, text, caret) {
            var tmp = _getCaretInfo(element),
                orig = element.value,
                pos = $(element).scrollTop(),
                range = {start: tmp.start, end: tmp.start + text.length};

            element.value = orig.substr(0, tmp.start) + text + orig.substr(tmp.end);

            $(element).scrollTop(pos);
            this.setPos(element, range, caret);
        },

        /**
         * insert before the selected text
         *
         * @param   {Element}   element         target element
         * @param   {String}    text            insertion text
         * @param   {String}    caret           caret mode: any of the following: "keep" | "start" | "end"
         */
        insertBefore: function(element, text, caret) {
            var tmp = _getCaretInfo(element),
                orig = element.value,
                pos = $(element).scrollTop(),
                range = {start: tmp.start + text.length, end: tmp.end + text.length};

            element.value = orig.substr(0, tmp.start) + text + orig.substr(tmp.start);

            $(element).scrollTop(pos);
            this.setPos(element, range, caret);
        },

        /**
         * insert after the selected text
         *
         * @param   {Element}   element         target element
         * @param   {String}    text            insertion text
         * @param   {String}    caret           caret mode: any of the following: "keep" | "start" | "end"
         */
        insertAfter: function(element, text, caret) {
            var tmp = _getCaretInfo(element),
                orig = element.value,
                pos = $(element).scrollTop(),
                range = {start: tmp.start, end: tmp.end};

            element.value = orig.substr(0, tmp.end) + text + orig.substr(tmp.end);

            $(element).scrollTop(pos);
            this.setPos(element, range, caret);
        }
    };

    /* add jQuery.selection */
    $.extend({
        /**
         * get selected text on the window
         *
         * @param   {String}    mode            selection mode: any of the following: "text" | "html"
         * @return  {String}    return
         */
        selection: function(mode) {
            var getText = ((mode || 'text').toLowerCase() === 'text');

            try {
                if (win.getSelection) {
                    if (getText) {
                        // get text
                        return win.getSelection().toString();
                    } else {
                        // get html
                        var sel = win.getSelection(), range;

                        if (sel.getRangeAt) {
                            range = sel.getRangeAt(0);
                        } else {
                            range = doc.createRange();
                            range.setStart(sel.anchorNode, sel.anchorOffset);
                            range.setEnd(sel.focusNode, sel.focusOffset);
                        }

                        return $('<div></div>').append(range.cloneContents()).html();
                    }
                } else if (doc.selection) {
                    if (getText) {
                        // get text
                        return doc.selection.createRange().text;
                    } else {
                        // get html
                        return doc.selection.createRange().htmlText;
                    }
                }
            } catch (e) {
                /* give up */
            }

            return '';
        }
    });

    /* add selection */
    $.fn.extend({
        selection: function(mode, opts) {
            opts = opts || {};

            switch (mode) {
                /**
                 * selection('getPos')
                 * get caret position
                 *
                 * @return  {Object}    return
                 * @return  {Number}    return.start    start position for the selection
                 * @return  {Number}    return.end      end position for the selection
                 */
                case 'getPos':
                    return _CaretOperation.getPos(this[0]);

                /**
                 * selection('setPos', opts)
                 * set caret position
                 *
                 * @param   {Number}    opts.start      start position for the selection
                 * @param   {Number}    opts.end        end position for the selection
                 */
                case 'setPos':
                    return this.each(function() {
                        _CaretOperation.setPos(this, opts);
                    });

                /**
                 * selection('replace', opts)
                 * replace the selected text
                 *
                 * @param   {String}    opts.text            replacement text
                 * @param   {String}    opts.caret           caret mode: any of the following: "keep" | "start" | "end"
                 */
                case 'replace':
                    return this.each(function() {
                        _CaretOperation.replace(this, opts.text, opts.caret);
                    });

                /**
                 * selection('insert', opts)
                 * insert before/after the selected text
                 *
                 * @param   {String}    opts.text            insertion text
                 * @param   {String}    opts.caret           caret mode: any of the following: "keep" | "start" | "end"
                 * @param   {String}    opts.mode            insertion mode: any of the following: "before" | "after"
                 */
                case 'insert':
                    return this.each(function() {
                        if (opts.mode === 'before') {
                            _CaretOperation.insertBefore(this, opts.text, opts.caret);
                        } else {
                            _CaretOperation.insertAfter(this, opts.text, opts.caret);
                        }
                    });

                /**
                 * selection('get')
                 * get selected text
                 *
                 * @return  {String}    return
                 */
                case 'get':
                    /* falls through */
                default:
                    return _CaretOperation.getText(this[0]);
            }

            return this;
        }
    });
})(jQuery, window, window.document);


/*==========================
/* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js
* Copyright (c) 2015 Emmanuel Pelletier
* Licensed MIT 
============================*/

(function() {
	
'use strict';

/**
 * SimpleUndo is a very basic javascript undo/redo stack for managing histories of basically anything.
 * 
 * options are: {
 * 	* `provider` : required. a function to call on `save`, which should provide the current state of the historized object through the given "done" callback
 * 	* `maxLength` : the maximum number of items in history
 * 	* `opUpdate` : a function to call to notify of changes in history. Will be called on `save`, `undo`, `redo` and `clear`
 * }
 * 
 */
var SimpleUndo = function(options) {
	
	var settings = options ? options : {};
	var defaultOptions = {
		provider: function() {
			throw new Error("No provider!");
		},
		maxLength: 30,
		onUpdate: function() {}
	};
	
	this.provider = (typeof settings.provider != 'undefined') ? settings.provider : defaultOptions.provider;
	this.maxLength = (typeof settings.maxLength != 'undefined') ? settings.maxLength : defaultOptions.maxLength;
	this.onUpdate = (typeof settings.onUpdate != 'undefined') ? settings.onUpdate : defaultOptions.onUpdate;
	
	this.initialItem = null;
	this.clear();
};

function truncate (stack, limit) {
	while (stack.length > limit) {
		stack.shift();
	}
}

SimpleUndo.prototype.initialize = function(initialItem) {
	this.stack[0] = initialItem;
	this.initialItem = initialItem;
};


SimpleUndo.prototype.clear = function() {
	this.stack = [this.initialItem];
	this.position = 0;
	this.onUpdate();
};

SimpleUndo.prototype.save = function() {
	this.provider(function(current) {
		truncate(this.stack, this.maxLength);
		this.position = Math.min(this.position,this.stack.length - 1);
		
		this.stack = this.stack.slice(0, this.position + 1);
		this.stack.push(current);
		this.position++;
		this.onUpdate();
	}.bind(this));
};

SimpleUndo.prototype.undo = function(callback) {
	if (this.canUndo()) {
		var item =  this.stack[--this.position];
		this.onUpdate();
		
		if (callback) {
			callback(item);
		}
	}
};

SimpleUndo.prototype.redo = function(callback) {
	if (this.canRedo()) {
		var item = this.stack[++this.position];
		this.onUpdate();
		
		if (callback) {
			callback(item);
		}
	}
};

SimpleUndo.prototype.canUndo = function() {
	return this.position > 0;
};

SimpleUndo.prototype.canRedo = function() {
	return this.position < this.count();
};

SimpleUndo.prototype.count = function() {
	return this.stack.length - 1; // -1 because of initial item
};

//exports
// node module
if (typeof module != 'undefined') {
	module.exports = SimpleUndo;
}

// browser global
if (typeof window != 'undefined') {
	window.SimpleUndo = SimpleUndo;
}

})();
window.DrawingBoard = typeof DrawingBoard !== "undefined" ? DrawingBoard : {};


DrawingBoard.Utils = {};

/*!
* Tim (lite)
*   github.com/premasagar/tim
*//*
	A tiny, secure JavaScript micro-templating script.
*/
DrawingBoard.Utils.tpl = (function(){
	"use strict";

	var start   = "{{",
		end     = "}}",
		path    = "[a-z0-9_][\\.a-z0-9_]*", // e.g. config.person.name
		pattern = new RegExp(start + "\\s*("+ path +")\\s*" + end, "gi"),
		undef;

	return function(template, data){
		// Merge data into the template string
		return template.replace(pattern, function(tag, token){
			var path = token.split("."),
				len = path.length,
				lookup = data,
				i = 0;

			for (; i < len; i++){
				lookup = lookup[path[i]];

				// Property not found
				if (lookup === undef){
					throw "tim: '" + path[i] + "' not found in " + tag;
				}

				// Return the required value
				if (i === len - 1){
					return lookup;
				}
			}
		});
	};
}());

/**
 * https://github.com/jeromeetienne/microevent.js http://leimi.github.io/drawingboard.js/
 * MicroEvent - to make any js object an event emitter (server or browser)
 *
 * - pure javascript - server compatible, browser compatible
 * - dont rely on the browser doms
 * - super simple - you get it immediatly, no mistery, no magic involved
 *
 * - create a MicroEventDebug with goodies to debug
 *   - make it safer to use
*/
DrawingBoard.Utils.MicroEvent = function(){};

DrawingBoard.Utils.MicroEvent.prototype = {
	bind : function(event, fct){
		this._events = this._events || {};
		this._events[event] = this._events[event]	|| [];
		this._events[event].push(fct);
	},
	unbind : function(event, fct){
		this._events = this._events || {};
		if( event in this._events === false  )	return;
		this._events[event].splice(this._events[event].indexOf(fct), 1);
	},
	trigger : function(event /* , args... */){
		this._events = this._events || {};
		if( event in this._events === false  )	return;
		for(var i = 0; i < this._events[event].length; i++){
			this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
		}
	}
};

//I know.
DrawingBoard.Utils._boxBorderSize = function($el, withPadding, withMargin, direction) {
	withPadding = !!withPadding || true;
	withMargin = !!withMargin || false;
	var width = 0,
		props;
	if (direction == "width") {
		props = ['border-left-width', 'border-right-width'];
		if (withPadding) props.push('padding-left', 'padding-right');
		if (withMargin) props.push('margin-left', 'margin-right');
	} else {
		props = ['border-top-width', 'border-bottom-width'];
		if (withPadding) props.push('padding-top', 'padding-bottom');
		if (withMargin) props.push('margin-top', 'margin-bottom');
	}
	for (var i = props.length - 1; i >= 0; i--)
		width += parseInt($el.css(props[i]).replace('px', ''), 10);
	return width;
};

DrawingBoard.Utils.boxBorderWidth = function($el, withPadding, withMargin) {
	return DrawingBoard.Utils._boxBorderSize($el, withPadding, withMargin, 'width');
};

DrawingBoard.Utils.boxBorderHeight = function($el, withPadding, withMargin) {
	return DrawingBoard.Utils._boxBorderSize($el, withPadding, withMargin, 'height');
};

DrawingBoard.Utils.isColor = function(string) {
	if (!string || !string.length) return false;
	return (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i).test(string) || $.inArray(string.substring(0, 3), ['rgb', 'hsl']) !== -1;
};

/**
 * Packs an RGB color into a single integer.
 */
DrawingBoard.Utils.RGBToInt = function(r, g, b) {
	var c = 0;
	c |= (r & 255) << 16;
	c |= (g & 255) << 8;
	c |= (b & 255);
	return c;
};

/**
 * Returns informations on the pixel located at (x,y).
 */
DrawingBoard.Utils.pixelAt = function(image, x, y) {
	var i = (y * image.width + x) * 4;
	var c = DrawingBoard.Utils.RGBToInt(
		image.data[i],
		image.data[i + 1],
		image.data[i + 2]
	);

	return [
		i, // INDEX
		x, // X
		y, // Y
		c  // COLOR
	];
};

/**
 * Compares two colors with the given tolerance (between 0 and 255).
 */
DrawingBoard.Utils.compareColors = function(a, b, tolerance) {
	if (tolerance === 0) {
		return (a === b);
	}

	var ra = (a >> 16) & 255, rb = (b >> 16) & 255,
		ga = (a >> 8) & 255, gb = (b >> 8) & 255,
		ba = a & 255, bb = b & 255;

	return (Math.abs(ra - rb) <= tolerance)
		&& (Math.abs(ga - gb) <= tolerance)
		&& (Math.abs(ba - bb) <= tolerance);
};

(function() {
	var lastTime = 0;
	var vendors = ['ms', 'moz', 'webkit', 'o'];
	for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
		window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
		window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
	}
}());

window.DrawingBoard = typeof DrawingBoard !== "undefined" ? DrawingBoard : {};

/**
 * pass the id of the html element to put the drawing board into
 * and some options : {
 *	controls: array of controls to initialize with the drawingboard. 'Colors', 'Size', and 'Navigation' by default
 *		instead of simple strings, you can pass an object to define a control opts
 *		ie ['Color', { Navigation: { reset: false }}]
 *	controlsPosition: "top left" by default. Define where to put the controls: at the "top" or "bottom" of the canvas, aligned to "left"/"right"/"center"
 *	background: background of the drawing board. Give a hex color or an image url "#ffffff" (white) by default
 *	color: pencil color ("#000000" by default)
 *	size: pencil size (3 by default)
 *	webStorage: 'session', 'local' or false ('session' by default). store the current drawing in session or local storage and restore it when you come back
 *	droppable: true or false (false by default). If true, dropping an image on the canvas will include it and allow you to draw on it,
 *	errorMessage: html string to put in the board's element on browsers that don't support canvas.
 *	stretchImg: default behavior of image setting on the canvas: set to the canvas width/height or not? false by default
 * }
 */
DrawingBoard.Board = function(id, opts) {
	this.opts = this.mergeOptions(opts);

	this.ev = new DrawingBoard.Utils.MicroEvent();

	this.id = id;
	this.$el = $(document.getElementById(id));
	if (!this.$el.length)
		return false;

	var tpl = '<div class="drawing-board-canvas-wrapper"></canvas><canvas class="drawing-board-canvas"></canvas><div class="drawing-board-cursor drawing-board-utils-hidden"></div></div>';
	if (this.opts.controlsPosition.indexOf("bottom") > -1) tpl += '<div class="drawing-board-controls"></div>';
	else tpl = '<div class="drawing-board-controls"></div>' + tpl;

	this.$el.addClass('drawing-board').append(tpl);
	this.dom = {
		$canvasWrapper: this.$el.find('.drawing-board-canvas-wrapper'),
		$canvas: this.$el.find('.drawing-board-canvas'),
		$cursor: this.$el.find('.drawing-board-cursor'),
		$controls: this.$el.find('.drawing-board-controls')
	};

	$.each(['left', 'right', 'center'], $.proxy(function(n, val) {
		if (this.opts.controlsPosition.indexOf(val) > -1) {
			this.dom.$controls.attr('data-align', val);
			return false;
		}
	}, this));

	this.canvas = this.dom.$canvas.get(0);
	this.ctx = this.canvas && this.canvas.getContext && this.canvas.getContext('2d') ? this.canvas.getContext('2d') : null;
	this.color = this.opts.color;

	if (!this.ctx) {
		if (this.opts.errorMessage)
			this.$el.html(this.opts.errorMessage);
		return false;
	}

	this.storage = this._getStorage();

	this.initHistory();
	//init default board values before controls are added (mostly pencil color and size)
	this.reset({ webStorage: false, history: false, background: false });
	//init controls (they will need the default board values to work like pencil color and size)
	this.initControls();
	//set board's size after the controls div is added
	this.resize();
	//reset the board to take all resized space
	this.reset({ webStorage: false, history: false, background: true });
	this.restoreWebStorage();
	this.initDropEvents();
	this.initDrawEvents();
};



DrawingBoard.Board.defaultOpts = {
	controls: ['Color', 'DrawingMode', 'Size', 'Navigation'],
	controlsPosition: "top left",
	color: "#000000",
	size: 1,
	background: "#fff",
	eraserColor: "background",
	fillTolerance: 100,
	fillHack: true, //try to prevent issues with anti-aliasing with a little hack by default
	webStorage: 'session',
	droppable: false,
	enlargeYourContainer: false,
	errorMessage: "<p>It seems you use an obsolete browser. <a href=\"http://browsehappy.com/\" target=\"_blank\">Update it</a> to start drawing.</p>",
	stretchImg: false //when setting the canvas img, strech the image at the whole canvas size when this opt is true
};



DrawingBoard.Board.prototype = {

	mergeOptions: function(opts) {
		opts = $.extend({}, DrawingBoard.Board.defaultOpts, opts);
		if (!opts.background && opts.eraserColor === "background")
			opts.eraserColor = "transparent";
		return opts;
	},

	/**
	 * Canvas reset/resize methods: put back the canvas to its default values
	 *
	 * depending on options, can set color, size, background back to default values
	 * and store the reseted canvas in webstorage and history queue
	 *
	 * resize values depend on the `enlargeYourContainer` option
	 */

	reset: function(opts) {
		opts = $.extend({
			color: this.opts.color,
			size: this.opts.size,
			webStorage: true,
			history: true,
			background: false
		}, opts);

		this.setMode('pencil');

		if (opts.background) {
			this.resetBackground(this.opts.background, $.proxy(function() {
				if (opts.history) this.saveHistory();
			}, this));
		}

		if (opts.color) this.setColor(opts.color);
		if (opts.size) this.ctx.lineWidth = opts.size;

		this.ctx.lineCap = "round";
		this.ctx.lineJoin = "round";
		// this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.width);

		if (opts.webStorage) this.saveWebStorage();

		// if opts.background we already dealt with the history
		if (opts.history && !opts.background) this.saveHistory();

		this.blankCanvas = this.getImg();

		this.ev.trigger('board:reset', opts);
	},

	resetBackground: function(background, callback) {
		background = background || this.opts.background;

		var bgIsColor = DrawingBoard.Utils.isColor(background);
		var prevMode = this.getMode();
		this.setMode('pencil');
		this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
		if (bgIsColor) {
			this.ctx.fillStyle = background;
			this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
			this.history.initialize(this.getImg());
			if (callback) callback();
		} else if (background)
			this.setImg(background, {
				callback: $.proxy(function() {
					this.history.initialize(this.getImg());
					if (callback) callback();
				}, this)
			});
		this.setMode(prevMode);
	},

	resize: function() {
		this.dom.$controls.toggleClass('drawing-board-controls-hidden', (!this.controls || !this.controls.length));

		var canvasWidth, canvasHeight;
		var widths = [
			this.$el.width(),
			DrawingBoard.Utils.boxBorderWidth(this.$el),
			DrawingBoard.Utils.boxBorderWidth(this.dom.$canvasWrapper, true, true)
		];
		var heights = [
			this.$el.height(),
			DrawingBoard.Utils.boxBorderHeight(this.$el),
			this.dom.$controls.height(),
			DrawingBoard.Utils.boxBorderHeight(this.dom.$controls, false, true),
			DrawingBoard.Utils.boxBorderHeight(this.dom.$canvasWrapper, true, true)
		];
		var that = this;
		var sum = function(values, multiplier) { //make the sum of all array values
			multiplier = multiplier || 1;
			var res = values[0];
			for (var i = 1; i < values.length; i++) {
				res = res + (values[i]*multiplier);
			}
			return res;
		};
		var sub = function(values) { return sum(values, -1); }; //substract all array values from the first one

		if (this.opts.enlargeYourContainer) {
			canvasWidth = this.$el.width();
			canvasHeight = this.$el.height();

			this.$el.width( sum(widths) );
			this.$el.height( sum(heights) );
		} else {
			canvasWidth = sub(widths);
			canvasHeight = sub(heights);
		}

		this.dom.$canvasWrapper.css('width', canvasWidth + 'px');
		this.dom.$canvasWrapper.css('height', canvasHeight + 'px');

		this.dom.$canvas.css('width', canvasWidth + 'px');
		this.dom.$canvas.css('height', canvasHeight + 'px');

		this.canvas.width = canvasWidth;
		this.canvas.height = canvasHeight;
	},



	/**
	 * Controls:
	 * the drawing board can has various UI elements to control it.
	 * one control is represented by a class in the namespace DrawingBoard.Control
	 * it must have a $el property (jQuery object), representing the html element to append on the drawing board at initialization.
	 *
	 */

	initControls: function() {
		this.controls = [];
		if (!this.opts.controls.length || !DrawingBoard.Control) return false;
		for (var i = 0; i < this.opts.controls.length; i++) {
			var c = null;
			if (typeof this.opts.controls[i] == "string")
				c = new window['DrawingBoard']['Control'][this.opts.controls[i]](this);
			else if (typeof this.opts.controls[i] == "object") {
				for (var controlName in this.opts.controls[i]) break;
				c = new window['DrawingBoard']['Control'][controlName](this, this.opts.controls[i][controlName]);
			}
			if (c) {
				this.addControl(c);
			}
		}
	},

	//add a new control or an existing one at the position you want in the UI
	//to add a totally new control, you can pass a string with the js class as 1st parameter and control options as 2nd ie "addControl('Navigation', { reset: false }"
	//the last parameter (2nd or 3rd depending on the situation) is always the position you want to place the control at
	addControl: function(control, optsOrPos, pos) {
		if (typeof control !== "string" && (typeof control !== "object" || !control instanceof DrawingBoard.Control))
			return false;

		var opts = typeof optsOrPos == "object" ? optsOrPos : {};
		pos = pos ? pos*1 : (typeof optsOrPos == "number" ? optsOrPos : null);

		if (typeof control == "string")
			control = new window['DrawingBoard']['Control'][control](this, opts);

		if (pos)
			this.dom.$controls.children().eq(pos).before(control.$el);
		else
			this.dom.$controls.append(control.$el);

		if (!this.controls)
			this.controls = [];
		this.controls.push(control);
		this.dom.$controls.removeClass('drawing-board-controls-hidden');
	},



	/**
	 * History methods: undo and redo drawed lines
	 */

	initHistory: function() {
		this.history = new SimpleUndo({
			maxLength: 30,
			provider: $.proxy(function(done) {
				done(this.getImg());
			}, this),
			onUpdate: $.proxy(function() {
				this.ev.trigger('historyNavigation');
			}, this)
		});
	},

	saveHistory: function() {
		this.history.save();
	},

	restoreHistory: function(image) {
		this.setImg(image, {
			callback: $.proxy(function() {
				this.saveWebStorage();
			}, this)
		});
	},

	goBackInHistory: function() {
		this.history.undo($.proxy(this.restoreHistory, this));
	},

	goForthInHistory: function() {
		this.history.redo($.proxy(this.restoreHistory, this));
	},

	/**
	 * Image methods: you can directly put an image on the canvas, get it in base64 data url or start a download
	 */

	setImg: function(src, opts) {
		opts = $.extend({
			stretch: this.opts.stretchImg,
			callback: null
		}, opts);

		var ctx = this.ctx;
		var img = new Image();
		var oldGCO = ctx.globalCompositeOperation;
		img.onload = function() {
			ctx.globalCompositeOperation = "source-over";
			ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

			if (opts.stretch) {
				ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
			} else {
				ctx.drawImage(img, 0, 0);
			}

			ctx.globalCompositeOperation = oldGCO;

			if (opts.callback) {
				opts.callback();
			}
		};
		img.src = src;
	},

	getImg: function() {
		return this.canvas.toDataURL("image/png");
	},

	downloadImg: function() {// Modification Eric
		var img = this.getImg();
		img = img.replace("image/png", "image/octet-stream");
		var ua=window.navigator.userAgent;
		if (ua.indexOf("Chrome") != -1 || ua.indexOf("Firefox") != -1 || ua.indexOf("Opera") != -1) {
			
			var ladate = new Date();
			var a = ladate.getFullYear();
			var m = ladate.getMonth();
			m++;
			if (m < 10) {m = "0"+m}
			var n = ladate.getDate();
			var h = ladate.getHours();
			if (h < 10) {h = "0"+h}
			var mn = ladate.getMinutes();
			if (mn < 10) {mn = "0"+mn}
			var s = ladate.getSeconds();
			if (s < 10) {s = "0"+s}
			var nomImage = "tnifacile-"+a+"-"+m+"-"+n+"-"+h+"-"+mn+"-"+s;
			
			var link = document.createElement('a');
			document.body.appendChild(link); 
			link.download = nomImage+'.png';
			link.href = img;
			link.click();
			document.body.removeChild(link);
		} else {
			alert("Fonctionnalité incompatble avec votre navigateur Web. Merci d'utiliser un navigateur moderne tel que Firefox ou Chrome.");
			// window.location.href = img;
		}
	},



	/**
	 * WebStorage handling : save and restore to local or session storage
	 */

	saveWebStorage: function() {
		if (window[this.storage]) {
			window[this.storage].setItem('drawing-board-' + this.id, this.getImg());
			this.ev.trigger('board:save' + this.storage.charAt(0).toUpperCase() + this.storage.slice(1), this.getImg());
		}
	},

	restoreWebStorage: function() {
		if (window[this.storage] && window[this.storage].getItem('drawing-board-' + this.id) !== null) {
			this.setImg(window[this.storage].getItem('drawing-board-' + this.id));
			this.ev.trigger('board:restore' + this.storage.charAt(0).toUpperCase() + this.storage.slice(1), window[this.storage].getItem('drawing-board-' + this.id));
		}
	},

	clearWebStorage: function() {
		if (window[this.storage] && window[this.storage].getItem('drawing-board-' + this.id) !== null) {
			window[this.storage].removeItem('drawing-board-' + this.id);
			this.ev.trigger('board:clear' + this.storage.charAt(0).toUpperCase() + this.storage.slice(1));
		}
	},

	_getStorage: function() {
		if (!this.opts.webStorage || !(this.opts.webStorage === 'session' || this.opts.webStorage === 'local')) return false;
		return this.opts.webStorage + 'Storage';
	},



	/**
	 * Drop an image on the canvas to draw on it
	 */

	initDropEvents: function() {
		if (!this.opts.droppable)
			return false;

		this.dom.$canvas.on('dragover dragenter drop', function(e) {
			e.stopPropagation();
			e.preventDefault();
		});

		this.dom.$canvas.on('drop', $.proxy(this._onCanvasDrop, this));
	},

	_onCanvasDrop: function(e) {
		e = e.originalEvent ? e.originalEvent : e;
		var files = e.dataTransfer.files;
		if (!files || !files.length || files[0].type.indexOf('image') == -1 || !window.FileReader)
			return false;
		var fr = new FileReader();
		fr.readAsDataURL(files[0]);
		fr.onload = $.proxy(function(ev) {
			this.setImg(ev.target.result, {
				callback: $.proxy(function() {
					this.saveHistory();
				}, this)
			});
			this.ev.trigger('board:imageDropped', ev.target.result);
			this.ev.trigger('board:userAction');
		}, this);
	},



	/**
	 * set and get current drawing mode
	 *
	 * possible modes are "pencil" (draw normally), "eraser" (draw transparent, like, erase, you know), "filler" (paint can)
	 */

	setMode: function(newMode, silent) {
		silent = silent || false;
		newMode = newMode || 'pencil';

		this.ev.unbind('board:startDrawing', $.proxy(this.fill, this));

		if (this.opts.eraserColor === "transparent")
			this.ctx.globalCompositeOperation = newMode === "eraser" ? "destination-out" : "source-over";
		else {
			if (newMode === "eraser") {
				if (this.opts.eraserColor === "background" && DrawingBoard.Utils.isColor(this.opts.background))
					this.ctx.strokeStyle = this.opts.background;
				else if (DrawingBoard.Utils.isColor(this.opts.eraserColor))
					this.ctx.strokeStyle = this.opts.eraserColor;
			} else if (!this.mode || this.mode === "eraser") {
				this.ctx.strokeStyle = this.color;
			}

			if (newMode === "filler")
				this.ev.bind('board:startDrawing', $.proxy(this.fill, this));
		}
		this.mode = newMode;
		if (!silent)
			this.ev.trigger('board:mode', this.mode);
	},

	getMode: function() {
		return this.mode || "pencil";
	},

	setColor: function(color) {
		var that = this;
		color = color || this.color;
		if (!DrawingBoard.Utils.isColor(color))
			return false;
		this.color = color;
		if (this.opts.eraserColor !== "transparent" && this.mode === "eraser") {
			var setStrokeStyle = function(mode) {
				if (mode !== "eraser")
					that.strokeStyle = that.color;
				that.ev.unbind('board:mode', setStrokeStyle);
			};
			this.ev.bind('board:mode', setStrokeStyle);
		} else
			this.ctx.strokeStyle = this.color;
	},

	/**
	 * Fills an area with the current stroke color.
	 */
	fill: function(e) {
		if (this.getImg() === this.blankCanvas) {
			this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
			this.ctx.fillStyle = this.color;
			this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
			return;
		}

		var img = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);

		// constants identifying pixels components
		var INDEX = 0, X = 1, Y = 2, COLOR = 3;

		// target color components
		var stroke = this.ctx.strokeStyle;
		var r = parseInt(stroke.substr(1, 2), 16);
		var g = parseInt(stroke.substr(3, 2), 16);
		var b = parseInt(stroke.substr(5, 2), 16);

		// starting point
		var start = DrawingBoard.Utils.pixelAt(img, parseInt(e.coords.x, 10), parseInt(e.coords.y, 10));
		var startColor = start[COLOR];
		var tolerance = this.opts.fillTolerance;
		var useHack = this.opts.fillHack; //see https://github.com/Leimi/drawingboard.js/pull/38

		// no need to continue if starting and target colors are the same
		if (DrawingBoard.Utils.compareColors(startColor, DrawingBoard.Utils.RGBToInt(r, g, b), tolerance))
			return;

		// pixels to evaluate
		var queue = [start];

		// loop vars
		var pixel, x, y;
		var maxX = img.width - 1;
		var maxY = img.height - 1;

		function updatePixelColor(pixel) {
			img.data[pixel[INDEX]] = r;
			img.data[pixel[INDEX] + 1] = g;
			img.data[pixel[INDEX] + 2] = b;
		}

		while ((pixel = queue.pop())) {
			if (useHack)
				updatePixelColor(pixel);

			if (DrawingBoard.Utils.compareColors(pixel[COLOR], startColor, tolerance)) {
				if (!useHack)
					updatePixelColor(pixel);
				if (pixel[X] > 0) // west
					queue.push(DrawingBoard.Utils.pixelAt(img, pixel[X] - 1, pixel[Y]));
				if (pixel[X] < maxX) // east
					queue.push(DrawingBoard.Utils.pixelAt(img, pixel[X] + 1, pixel[Y]));
				if (pixel[Y] > 0) // north
					queue.push(DrawingBoard.Utils.pixelAt(img, pixel[X], pixel[Y] - 1));
				if (pixel[Y] < maxY) // south
					queue.push(DrawingBoard.Utils.pixelAt(img, pixel[X], pixel[Y] + 1));
			}
		}

		this.ctx.putImageData(img, 0, 0);
	},


	/**
	 * Drawing handling, with mouse or touch
	 */

	initDrawEvents: function() {
		this.isDrawing = false;
		this.isMouseHovering = false;
		this.coords = {};
		this.coords.old = this.coords.current = this.coords.oldMid = { x: 0, y: 0 };

		this.dom.$canvas.on('mousedown touchstart', $.proxy(function(e) {
			this._onInputStart(e, this._getInputCoords(e) );
		}, this));

		this.dom.$canvas.on('mousemove touchmove', $.proxy(function(e) {
			this._onInputMove(e, this._getInputCoords(e) );
		}, this));

		this.dom.$canvas.on('mousemove', $.proxy(function(e) {

		}, this));

		this.dom.$canvas.on('mouseup touchend', $.proxy(function(e) {
			this._onInputStop(e, this._getInputCoords(e) );
		}, this));

		this.dom.$canvas.on('mouseover', $.proxy(function(e) {
			this._onMouseOver(e, this._getInputCoords(e) );
		}, this));

		this.dom.$canvas.on('mouseout', $.proxy(function(e) {
			this._onMouseOut(e, this._getInputCoords(e) );

		}, this));

		$('body').on('mouseup touchend', $.proxy(function(e) {
			this.isDrawing = false;
		}, this));

		if (window.requestAnimationFrame) requestAnimationFrame( $.proxy(this.draw, this) );
	},

	draw: function() {
		//if the pencil size is big (>10), the small crosshair makes a friend: a circle of the size of the pencil
		//todo: have the circle works on every browser - it currently should be added only when CSS pointer-events are supported
		//we assume that if requestAnimationFrame is supported, pointer-events is too, but this is terribad.
		if (window.requestAnimationFrame && this.ctx.lineWidth > 10 && this.isMouseHovering) {
			this.dom.$cursor.css({ width: this.ctx.lineWidth + 'px', height: this.ctx.lineWidth + 'px' });
			var transform = DrawingBoard.Utils.tpl("translateX({{x}}px) translateY({{y}}px)", { x: this.coords.current.x-(this.ctx.lineWidth/2), y: this.coords.current.y-(this.ctx.lineWidth/2) });
			this.dom.$cursor.css({ 'transform': transform, '-webkit-transform': transform, '-ms-transform': transform });
			this.dom.$cursor.removeClass('drawing-board-utils-hidden');
		} else {
			this.dom.$cursor.addClass('drawing-board-utils-hidden');
		}

		if (this.isDrawing) {
			var currentMid = this._getMidInputCoords(this.coords.current);
			this.ctx.beginPath();
			this.ctx.moveTo(currentMid.x, currentMid.y);
			this.ctx.quadraticCurveTo(this.coords.old.x, this.coords.old.y, this.coords.oldMid.x, this.coords.oldMid.y);
			this.ctx.stroke();

			this.coords.old = this.coords.current;
			this.coords.oldMid = currentMid;
		}

		if (window.requestAnimationFrame) requestAnimationFrame( $.proxy(function() { this.draw(); }, this) );
	},

	_onInputStart: function(e, coords) {
		this.coords.current = this.coords.old = coords;
		this.coords.oldMid = this._getMidInputCoords(coords);
		this.isDrawing = true;

		if (!window.requestAnimationFrame) this.draw();

		this.ev.trigger('board:startDrawing', {e: e, coords: coords});
		e.stopPropagation();
		e.preventDefault();
	},

	_onInputMove: function(e, coords) {
		this.coords.current = coords;
		this.ev.trigger('board:drawing', {e: e, coords: coords});

		if (!window.requestAnimationFrame) this.draw();

		e.stopPropagation();
		e.preventDefault();
	},

	_onInputStop: function(e, coords) {
		if (this.isDrawing && (!e.touches || e.touches.length === 0)) {
			this.isDrawing = false;

			this.saveWebStorage();
			this.saveHistory();

			this.ev.trigger('board:stopDrawing', {e: e, coords: coords});
			this.ev.trigger('board:userAction');
			e.stopPropagation();
			e.preventDefault();
		}
	},

	_onMouseOver: function(e, coords) {
		this.isMouseHovering = true;
		this.coords.old = this._getInputCoords(e);
		this.coords.oldMid = this._getMidInputCoords(this.coords.old);

		this.ev.trigger('board:mouseOver', {e: e, coords: coords});
	},

	_onMouseOut: function(e, coords) {
		this.isMouseHovering = false;

		this.ev.trigger('board:mouseOut', {e: e, coords: coords});
	},

	_getInputCoords: function(e) {
		e = e.originalEvent ? e.originalEvent : e;
		var
			rect = this.canvas.getBoundingClientRect(),
			width = this.dom.$canvas.width(),
			height = this.dom.$canvas.height()
		;
		var x, y;
		if (e.touches && e.touches.length == 1) {
			x = e.touches[0].pageX;
			y = e.touches[0].pageY;
		} else {
			x = e.pageX;
			y = e.pageY;
		}
		x = x - this.dom.$canvas.offset().left;
		y = y - this.dom.$canvas.offset().top;
		x *= (width / rect.width);
		y *= (height / rect.height);
		return {
			x: x,
			y: y
		};
	},

	_getMidInputCoords: function(coords) {
		return {
			x: this.coords.old.x + coords.x>>1,
			y: this.coords.old.y + coords.y>>1
		};
	}
};

DrawingBoard.Control = function(drawingBoard, opts) {
	this.board = drawingBoard;
	this.opts = $.extend({}, this.defaults, opts);

	this.$el = $(document.createElement('div')).addClass('drawing-board-control');
	if (this.name)
		this.$el.addClass('drawing-board-control-' + this.name);

	this.board.ev.bind('board:reset', $.proxy(this.onBoardReset, this));

	this.initialize.apply(this, arguments);
	return this;
};

DrawingBoard.Control.prototype = {

	name: '',

	defaults: {},

	initialize: function() {

	},

	addToBoard: function() {
		this.board.addControl(this);
	},

	onBoardReset: function(opts) {

	}

};

//extend directly taken from backbone.js
DrawingBoard.Control.extend = function(protoProps, staticProps) {
	var parent = this;
	var child;
	if (protoProps && protoProps.hasOwnProperty('constructor')) {
		child = protoProps.constructor;
	} else {
		child = function(){ return parent.apply(this, arguments); };
	}
	$.extend(child, parent, staticProps);
	var Surrogate = function(){ this.constructor = child; };
	Surrogate.prototype = parent.prototype;
	child.prototype = new Surrogate();
	if (protoProps) $.extend(child.prototype, protoProps);
	child.__super__ = parent.prototype;
	return child;
};
DrawingBoard.Control.Color = DrawingBoard.Control.extend({
	name: 'colors',

	initialize: function() {
		this.initTemplate();

		var that = this;
		this.$el.on('click', '.drawing-board-control-colors-picker', function(e) {
			var color = $(this).attr('data-color');
			that.board.setColor(color);
			that.$el.find('.drawing-board-control-colors-current')
				.css('background-color', color)
				.attr('data-color', color);

			that.board.ev.trigger('color:changed', color);
			that.$el.find('.drawing-board-control-colors-rainbows').addClass('drawing-board-utils-hidden');

			e.preventDefault();
		});

		this.$el.on('click', '.drawing-board-control-colors-current', function(e) {
			that.$el.find('.drawing-board-control-colors-rainbows').toggleClass('drawing-board-utils-hidden');
			e.preventDefault();
		});

		$('body').on('click', function(e) {
			var $target = $(e.target);
			var $relatedButton = $target.hasClass('drawing-board-control-colors-current') ? $target : $target.closest('.drawing-board-control-colors-current');
			var $myButton = that.$el.find('.drawing-board-control-colors-current');
			var $popup = that.$el.find('.drawing-board-control-colors-rainbows');
			if ( (!$relatedButton.length || $relatedButton.get(0) !== $myButton.get(0)) && !$popup.hasClass('drawing-board-utils-hidden') )
				$popup.addClass('drawing-board-utils-hidden');
		});
	},

	initTemplate: function() {
		var tpl = '<div class="drawing-board-control-inner">' +
			'<div class="drawing-board-control-colors-current" style="background-color: {{color}}" data-color="{{color}}"></div>' +
			'<div class="drawing-board-control-colors-rainbows">{{rainbows}}</div>' +
			'</div>';
		var oneColorTpl = '<div class="drawing-board-control-colors-picker" data-color="{{color}}" style="background-color: {{color}}"></div>';
		var rainbows = '';
		$.each([0.75, 0.5, 0.25], $.proxy(function(key, val) {
			var i = 0;
			var additionalColor = null;
			rainbows += '<div class="drawing-board-control-colors-rainbow">';
			if (val == 0.25) additionalColor = this._rgba(0, 0, 0, 1);
			if (val == 0.5) additionalColor = this._rgba(150, 150, 150, 1);
			if (val == 0.75) additionalColor = this._rgba(255, 255, 255, 1);
			rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: additionalColor.toString() });
			while (i <= 330) {
				rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: this._hsl2Rgba(this._hsl(i-60, 1, val)).toString() });
				i+=30;
			}
			rainbows += '</div>';
		}, this));

		this.$el.append( $( DrawingBoard.Utils.tpl(tpl, {color: this.board.color, rainbows: rainbows }) ) );
		this.$el.find('.drawing-board-control-colors-rainbows').addClass('drawing-board-utils-hidden');
	},

	onBoardReset: function(opts) {
		this.board.setColor(this.$el.find('.drawing-board-control-colors-current').attr('data-color'));
	},

	_rgba: function(r, g, b, a) {
		return { r: r, g: g, b: b, a: a, toString: function() { return "rgba(" + r +", " + g + ", " + b + ", " + a + ")"; } };
	},

	_hsl: function(h, s, l) {
		return { h: h, s: s, l: l, toString: function() { return "hsl(" + h +", " + s*100 + "%, " + l*100 + "%)"; } };
	},

	_hex2Rgba: function(hex) {
		var num = parseInt(hex.substring(1), 16);
		return this._rgba(num >> 16, num >> 8 & 255, num & 255, 1);
	},

	//conversion function (modified a bit) taken from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
	_hsl2Rgba: function(hsl) {
		var h = hsl.h/360, s = hsl.s, l = hsl.l, r, g, b;
		function hue2rgb(p, q, t) {
			if(t < 0) t += 1;
			if(t > 1) t -= 1;
			if(t < 1/6) return p + (q - p) * 6 * t;
			if(t < 1/2) return q;
			if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
			return p;
		}
		if (s === 0) {
			r = g = b = l; // achromatic
		} else {
			var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
			var p = 2 * l - q;
			r = Math.floor( (hue2rgb(p, q, h + 1/3)) * 255);
			g = Math.floor( (hue2rgb(p, q, h)) * 255);
			b = Math.floor( (hue2rgb(p, q, h - 1/3)) * 255);
		}
		return this._rgba(r, g, b, 1);
	}
});
DrawingBoard.Control.DrawingMode = DrawingBoard.Control.extend({

	name: 'drawingmode',

	defaults: {
		pencil: true,
		eraser: true,
		filler: true
	},

	initialize: function() {

		this.prevMode = this.board.getMode();

		$.each(["pencil", "eraser", "filler"], $.proxy(function(k, value) {
			if (this.opts[value]) {
				this.$el.append('<button class="drawing-board-control-drawingmode-' + value + '-button" data-mode="' + value + '"></button>');
			}
		}, this));

		this.$el.on('click', 'button[data-mode]', $.proxy(function(e) {
			var value = $(e.currentTarget).attr('data-mode');
			var mode = this.board.getMode();
			if (mode !== value) this.prevMode = mode;
			var newMode = mode === value ? this.prevMode : value;
			this.board.setMode( newMode );
			e.preventDefault();
		}, this));

		this.board.ev.bind('board:mode', $.proxy(function(mode) {
			this.toggleButtons(mode);
		}, this));

		this.toggleButtons( this.board.getMode() );
	},

	toggleButtons: function(mode) {
		this.$el.find('button[data-mode]').each(function(k, item) {
			var $item = $(item);
			$item.toggleClass('active', mode === $item.attr('data-mode'));
		});
	}

});

DrawingBoard.Control.Navigation = DrawingBoard.Control.extend({

	name: 'navigation',

	defaults: {
		back: true,
		forward: true,
		reset: true
	},

	initialize: function() {
		var el = '';
		if (this.opts.back) el += '<button class="drawing-board-control-navigation-back"><img src="images/icone_bt_drawing_undo.png" /></button>';
		if (this.opts.forward) el += '<button class="drawing-board-control-navigation-forward"><img src="images/icone_bt_drawing_redo.png" /></button>';
		if (this.opts.reset) el += '<button class="drawing-board-control-navigation-reset"><img src="images/icone_bt_drawing_supprimer.png" /></button>';
		this.$el.append(el);

		if (this.opts.back) {
			var $back = this.$el.find('.drawing-board-control-navigation-back');
			this.board.ev.bind('historyNavigation', $.proxy(this.updateBack, this, $back));
			this.$el.on('click', '.drawing-board-control-navigation-back', $.proxy(function(e) {
				this.board.goBackInHistory();
				e.preventDefault();
			}, this));

			this.updateBack($back);
		}

		if (this.opts.forward) {
			var $forward = this.$el.find('.drawing-board-control-navigation-forward');
			this.board.ev.bind('historyNavigation', $.proxy(this.updateForward, this, $forward));
			this.$el.on('click', '.drawing-board-control-navigation-forward', $.proxy(function(e) {
				this.board.goForthInHistory();
				e.preventDefault();
			}, this));

			this.updateForward($forward);
		}

		if (this.opts.reset) {
			this.$el.on('click', '.drawing-board-control-navigation-reset', $.proxy(function(e) {
				this.board.reset({ background: true });
				e.preventDefault();
			}, this));
		}
	},

	updateBack: function($back) {
		if (this.board.history.canUndo()) {
			$back.removeAttr('disabled');
		} else {
			$back.attr('disabled', 'disabled');
		}
	},

	updateForward: function($forward) {
		if (this.board.history.canRedo()) {
			$forward.removeAttr('disabled');
		} else {
			$forward.attr('disabled', 'disabled');
		}
	}
});
DrawingBoard.Control.Size = DrawingBoard.Control.extend({

	name: 'size',

	defaults: {
		type: "auto",
		dropdownValues: [1, 3, 6, 10, 20, 30, 40, 50],
		min: 1,
		max: 50
	},

	types: ['dropdown', 'range'],

	initialize: function() {
		if (this.opts.type == "auto")
			this.opts.type = this._iHasRangeInput() ? 'range' : 'dropdown';
		var tpl = $.inArray(this.opts.type, this.types) > -1 ? this['_' + this.opts.type + 'Template']() : false;
		if (!tpl) return false;

		this.val = this.board.opts.size;

		this.$el.append( $( tpl ) );
		this.$el.attr('data-drawing-board-type', this.opts.type);
		this.updateView();

		var that = this;

		if (this.opts.type == "range") {
			this.$el.on('change', '.drawing-board-control-size-range-input', function(e) {
				that.val = $(this).val();
				that.updateView();

				that.board.ev.trigger('size:changed', that.val);

				e.preventDefault();
			});
		}

		if (this.opts.type == "dropdown") {
			this.$el.on('click', '.drawing-board-control-size-dropdown-current', $.proxy(function(e) {
				this.$el.find('.drawing-board-control-size-dropdown').toggleClass('drawing-board-utils-hidden');
			}, this));

			this.$el.on('click', '[data-size]', function(e) {
				that.val = parseInt($(this).attr('data-size'), 0);
				that.updateView();

				that.board.ev.trigger('size:changed', that.val);

				e.preventDefault();
			});
		}
	},

	_rangeTemplate: function() {
		var tpl = '<div class="drawing-board-control-inner" title="{{size}}">' +
			'<input type="range" min="{{min}}" max="{{max}}" value="{{size}}" step="1" class="drawing-board-control-size-range-input">' +
			'<span class="drawing-board-control-size-range-current"></span>' +
			'</div>';
		return DrawingBoard.Utils.tpl(tpl, {
			min: this.opts.min,
			max: this.opts.max,
			size: this.board.opts.size
		});
	},

	_dropdownTemplate: function() {
		var tpl = '<div class="drawing-board-control-inner" title="{{size}}">' +
			'<div class="drawing-board-control-size-dropdown-current"><span></span></div>' +
			'<ul class="drawing-board-control-size-dropdown">';
		$.each(this.opts.dropdownValues, function(i, size) {
			tpl += DrawingBoard.Utils.tpl(
				'<li data-size="{{size}}"><span style="width: {{size}}px; height: {{size}}px; border-radius: {{size}}px;"></span></li>',
				{ size: size }
			);
		});
		tpl += '</ul></div>';
		return tpl;
	},

	onBoardReset: function(opts) {
		this.updateView();
	},

	updateView: function() {
		var val = this.val;
		this.board.ctx.lineWidth = val;

		this.$el.find('.drawing-board-control-size-range-current, .drawing-board-control-size-dropdown-current span').css({
			width: val + 'px',
			height: val + 'px',
			borderRadius: val + 'px',
			marginLeft: -1*val/2 + 'px',
			marginTop: -1*val/2 + 'px'
		});

		this.$el.find('.drawing-board-control-inner').attr('title', val);

		if (this.opts.type == 'dropdown') {
			var closest = null;
			$.each(this.opts.dropdownValues, function(i, size) {
				if (closest === null || Math.abs(size - val) < Math.abs(closest - val))
					closest = size;
			});
			this.$el.find('.drawing-board-control-size-dropdown').addClass('drawing-board-utils-hidden');
		}
	},

	_iHasRangeInput: function() {
		var inputElem  = document.createElement('input'),
			smile = ':)',
			docElement = document.documentElement,
			inputElemType = 'range',
			available;
		inputElem.setAttribute('type', inputElemType);
		available = inputElem.type !== 'text';
		inputElem.value         = smile;
		inputElem.style.cssText = 'position:absolute;visibility:hidden;';
		if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
			docElement.appendChild(inputElem);
			defaultView = document.defaultView;
			available = defaultView.getComputedStyle &&
				defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
				(inputElem.offsetHeight !== 0);
			docElement.removeChild(inputElem);
		}
		return !!available;
	}
});
DrawingBoard.Control.Download = DrawingBoard.Control.extend({

	name: 'download',

	initialize: function() {
		this.$el.append('<button class="drawing-board-control-download-button"></button>');
		this.$el.on('click', '.drawing-board-control-download-button', $.proxy(function(e) {
			this.board.downloadImg();
			e.preventDefault();
		}, this));
	}
});



SAMX