#flsafa-french-app{--nv:#12306b;--lb:#2f86e8;--bl:#eaf3ff;--or:#ff8a1f;--ln:#cfe0f7;font:17px/1.5 Verdana,"Segoe UI",system-ui,sans-serif;color:var(--nv);background:var(--bl);border-radius:20px;padding:14px;max-width:880px;margin:0 auto;box-sizing:border-box;text-align:left}#flsafa-french-app *{box-sizing:border-box}#flsafa-french-app h2{font-size:1.5rem;margin:0 0 8px;color:var(--nv)}#flsafa-french-app h3{font-size:1.05rem;margin:10px 0 4px;color:var(--nv)}#flsafa-french-app p{margin:6px 0}#flsafa-french-app [hidden]{display:none!important}#flsafa-french-app .ff-top{display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;background:var(--nv);color:#fff;border-radius:16px;padding:10px 14px}#flsafa-french-app .ff-brand{color:#fff!important;font-weight:800;font-size:1.2rem;text-decoration:none!important}#flsafa-french-app .ff-brand span{color:var(--or)}#flsafa-french-app .ff-lv{display:flex;gap:6px;flex-wrap:wrap}#flsafa-french-app .ff-lv .ff-b{font-size:.8rem;min-height:44px;padding:4px 10px;background:#fff;color:var(--nv)}#flsafa-french-app .ff-lv .on{background:var(--or);color:#fff}#flsafa-french-app .ff-hud{display:flex;gap:10px;align-items:center;font-weight:700}#flsafa-french-app .ff-b{min-height:48px;padding:10px 16px;border:0;border-radius:14px;font:700 1rem Verdana,sans-serif;background:var(--lb);color:#fff;cursor:pointer;box-shadow:0 3px 0 rgba(0,0,0,.18)}#flsafa-french-app .ff-b.or{background:var(--or)}#flsafa-french-app .ff-b.wh{background:#fff;color:var(--nv)}#flsafa-french-app .ff-bk{margin-top:12px}#flsafa-french-app .ff-p{background:#fff;border-radius:18px;padding:14px;margin-top:12px;box-shadow:0 4px 12px rgba(18,48,107,.1);animation:ffi .25s}#flsafa-french-app .ff-p:fullscreen{overflow:auto}#flsafa-french-app .ff-home{display:grid;grid-template-columns:repeat(auto-fit,minmax(145px,1fr));gap:12px;background:none;box-shadow:none;padding:0}#flsafa-french-app .ff-card{background:#fff;border:0;border-radius:18px;padding:14px 8px;color:var(--nv);font:700 1rem Verdana,sans-serif;cursor:pointer;min-height:112px;box-shadow:0 4px 12px rgba(18,48,107,.12)}#flsafa-french-app .ff-card i{display:block;font-size:2rem;font-style:normal}#flsafa-french-app .ff-card small{display:block;font-weight:400;color:#51668f;font-size:.8rem}#flsafa-french-app .ff-big{font-size:clamp(3rem,16vw,5.5rem);font-weight:800;text-align:center;line-height:1.15;margin:10px 0}#flsafa-french-app .c1{color:var(--lb)}#flsafa-french-app .c2{color:var(--or)}#flsafa-french-app .ff-row{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:10px 0}#flsafa-french-app .ff-cols{display:grid;grid-template-columns:1fr 1fr;gap:12px}#flsafa-french-app .ff-chip{min-width:48px;min-height:48px;padding:0 10px;border-radius:12px;border:2px solid var(--ln);background:#fff;color:var(--nv);font:700 1.1rem Verdana,sans-serif;cursor:pointer}#flsafa-french-app .ff-chip.s1{background:var(--lb);border-color:var(--lb);color:#fff}#flsafa-french-app .ff-chip.s2{background:var(--or);border-color:var(--or);color:#fff}#flsafa-french-app .ff-tw{overflow-x:auto}#flsafa-french-app table{border-collapse:collapse;margin:auto}#flsafa-french-app td,#flsafa-french-app th{padding:2px;text-align:center;font-size:1.1rem}#flsafa-french-app .ff-sm{font-size:.85rem;color:#51668f}#flsafa-french-app .ff-pg{height:12px;background:var(--ln);border-radius:9px;overflow:hidden}#flsafa-french-app .ff-pg i{display:block;height:100%;background:var(--or);transition:width .3s}#flsafa-french-app .ff-op{font-size:1.5rem;min-height:64px;flex:1 1 90px}#flsafa-french-app .ff-b.ok{background:#2f9e5a}#flsafa-french-app .ff-b.no{background:#d94b4b}#flsafa-french-app .ff-fb{min-height:1.5em;text-align:center;font-weight:700}#flsafa-french-app .ff-cv{position:relative;height:230px;background:#fff;border:2px solid var(--ln);border-radius:14px;touch-action:none}#flsafa-french-app .ff-cv canvas{position:absolute;left:0;top:0;width:100%;height:100%}#flsafa-french-app .ff-in{width:100%;min-height:50px;padding:8px 12px;border:2px solid var(--ln);border-radius:12px;font:1.2rem Verdana,sans-serif;color:var(--nv)}#flsafa-french-app .ff-msg{margin-top:10px;background:#fff7ec;border-left:5px solid var(--or);padding:8px 12px;border-radius:10px;font-size:.9rem}#flsafa-french-app .ff-ft{text-align:center;margin-top:12px;font-size:.85rem}#flsafa-french-app .ff-ft a{color:var(--nv)!important;font-weight:700}#flsafa-french-app button:focus-visible,#flsafa-french-app input:focus-visible,#flsafa-french-app a:focus-visible{outline:3px solid var(--or);outline-offset:2px}@keyframes ffi{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){#flsafa-french-app .ff-p{animation:none}#flsafa-french-app .ff-pg i{transition:none}} www.flsafa.comNiveau 1DébutantNiveau 2IntermédiaireNiveau 3Avancé⭐ 0✔ 0⏹← AccueilApprendre à lire et à écrire en français · www.flsafa.com (function(){ var R=document.getElementById('flsafa-french-app'); if(!R){return} var $=function(s){return R.querySelector(s)}; var P=$('.ff-p'),M=$('.ff-msg'),BK=$('.ff-bk'); var S={lv:1,st:0,ok:0,v:'home',au:true}; var rnd=function(a){return a.slice().sort(function(){return Math.random()-0.5})}; var pick=function(a){return a[Math.floor(Math.random()*a.length)]}; var C1='b c d f j l m n p r s t v'.split(' '),V1='a e i o u'.split(' '); var AL='abcdefghijklmnopqrstuvwxyz'.split(''); function cons(){return S.lv==1?C1:C1.concat(S.lv==2?['ch']:['ch','ph','gn'])} function vow(){return S.lv==1?V1:V1.concat(S.lv==2?['ou','on','an']:['ou','on','an','en','oi','ai','eau'])} var W=[[1,'a-mi'],[1,'mo-to'],[1,'vé-lo'],[1,'pa-pa'],[1,'ma-man'],[1,'lu-ne'],[1,'ro-be'],[1,'so-fa'],[1,'ta-pis'],[1,'ba-na-ne'], [2,'chat'],[2,'chien'],[2,'mai-son'],[2,'é-co-le'],[2,'li-vre'],[2,'bal-lon'],[2,'to-ma-te'],[2,'la-pin'],[2,'cra-yon'],[2,'gâ-teau'], [3,'cha-peau'],[3,'ba-teau'],[3,'pois-son'],[3,'ca-deau'],[3,'jar-din'],[3,'fe-nê-tre'],[3,'oi-seau'],[3,'pa-pil-lon'],[3,'é-lé-phant'],[3,'mon-ta-gne']]; var SEN=['Papa a un vélo.','Le chat dort.','Maman lit un livre.','Le ballon est rond.']; var SN=[['ch','chat'],['ou','loup'],['on','mon'],['an','maman'],['en','dent'],['oi','poire'],['ai','lait'],['eau','bateau'],['ph','photo'],['gn','montagne']]; var tx=function(w){return w.replace(/-/g,'')}; function wl(){return W.filter(function(w){return w[0]==S.lv}).map(function(w){return w[1]})} var vc=null; function voice(){var l=window.speechSynthesis?speechSynthesis.getVoices():[];vc=l.filter(function(v){return v.lang.replace('_','-').toLowerCase().indexOf('fr')==0})[0]||null;return l.length} if(window.speechSynthesis){voice();speechSynthesis.onvoiceschanged=voice} function note(t){M.textContent=t;M.hidden=!t} function say(t){ if(!window.speechSynthesis){note("Le son n'est pas disponible sur ce navigateur. Tu peux quand même lire et écrire.");return} speechSynthesis.cancel(); var u=new SpeechSynthesisUtterance(t);u.lang='fr-FR';u.rate=0.8; if(vc){u.voice=vc}else{if(voice()>0){note("Aucune voix française trouvée sur cet appareil : le son peut être absent ou approximatif.")}} speechSynthesis.speak(u)} function hud(){$('.ff-st').textContent=S.st;$('.ff-ok').textContent=S.ok} function reward(ok){if(ok){S.st++;S.ok++;hud();return '⭐ '+pick(['Bravo !','Très bien !','Continue !'])}return 'Presque ! Écoute encore et réessaie.'} /* Syllabes */ var sy={c:0,v:0},tb=''; function col(k,a,i,s,t){return '<div><h3>'+t+'</h3><div class="ff-row"><button class="ff-b" data-a="d" data-x="'+k+'-1" aria-label="Précédent">◀</button><button class="ff-b" data-a="d" data-x="'+k+'1" aria-label="Suivant">▶</button></div><div class="ff-row">'+a.map(function(x,j){return '<button class="ff-chip'+(j==i?' '+s:'')+'" data-a="p" data-x="'+k+j+'">'+x+'</button>'}).join('')+'</div></div>'} function vSy(){var c=cons(),v=vow();sy.c=sy.c%c.length;sy.v=sy.v%v.length; return '<h2>Syllabes</h2><div class="ff-cols">'+col('c',c,sy.c,'s1','Consonnes')+col('v',v,sy.v,'s2','Voyelles')+'</div><div class="ff-big" aria-live="polite"><span class="c1">'+c[sy.c]+'</span><span class="c2">'+v[sy.v]+'</span></div>'+(S.lv>1?'<p class="ff-sm">Les sons composés sont prononcés de façon approximative par la voix automatique.</p>':'')+'<div class="ff-row"><button class="ff-b or" data-a="sl">🔊 Écouter</button><button class="ff-b" data-a="sn">Nouvelle combinaison</button><button class="ff-b wh" data-a="sr">Recommencer</button><button class="ff-b wh" data-a="fs">Plein écran</button><button class="ff-b wh" data-a="au">Son automatique : '+(S.au?'oui':'non')+'</button></div>'} function syT(){return cons()[sy.c]+vow()[sy.v]} /* Tableau */ function vTb(){var c=cons(),v=vow();return '<h2>Tableau de syllabes</h2><p class="ff-sm">Touche une case pour écouter.'+(S.lv>1?' Les sons composés sont approximatifs.':'')+'</p><div class="ff-tw"><table><tr><th></th>'+v.map(function(x){return '<th class="c2">'+x+'</th>'}).join('')+'</tr>'+c.map(function(k){return '<tr><th class="c1">'+k+'</th>'+v.map(function(x){return '<td><button class="ff-chip'+(tb==k+x?' s1':'')+'" data-a="t" data-x="'+k+x+'">'+k+x+'</button></td>'}).join('')+'</tr>'}).join('')+'</table></div>'} /* Sons */ function t1(x){return '<button class="ff-chip" data-a="s" data-x="'+x+'">'+x.toUpperCase()+' '+x+'</button>'} function vSo(){return '<h2>Sons et lettres</h2><h3>Voyelles</h3><div class="ff-row">'+V1.map(t1).join('')+'</div><h3>Consonnes</h3><div class="ff-row">'+AL.filter(function(x){return V1.indexOf(x)==-1}).map(t1).join('')+'</div><h3>Sons composés</h3><div class="ff-row">'+SN.map(function(s){return '<button class="ff-chip" data-a="s" data-x="'+s[1]+'"><b>'+s[0]+'</b> '+s[1]+'</button>'}).join('')+'</div><p class="ff-sm">Pour les sons composés, la voix lit le mot exemple.</p>'} /* Lecture */ var lc={i:0,r:0}; function vLe(){var l=wl(),w=l[lc.i%l.length],s=w.split('-'),n=lc.r||s.length; return '<h2>Lecture</h2><div class="ff-big">'+s.map(function(x,j){return '<span class="c'+(j%2+1)+'"'+(n>j?'':' style="opacity:.12"')+'>'+x+'</span>'}).join('')+'</div><div class="ff-row"><button class="ff-b wh" data-a="le" data-x="p">◀</button><button class="ff-b or" data-a="le" data-x="l">🔊 Écouter</button><button class="ff-b" data-a="le" data-x="s">Pas à pas</button><button class="ff-b wh" data-a="le" data-x="n">▶</button></div><div class="ff-row"><button class="ff-b wh" data-a="le" data-x="w">✏️ Écrire ce mot</button></div><p class="ff-sm" style="text-align:center">Mot '+(lc.i%l.length+1)+' / '+l.length+' · Niveau '+S.lv+'</p>'} /* Mots */ function vMo(){return '<h2>Mots</h2><p class="ff-sm">Touche un mot pour le lire.</p>'+[1,2,3].map(function(l){return '<h3>Niveau '+l+'</h3><div class="ff-row">'+W.filter(function(w){return w[0]==l}).map(function(w){return '<button class="ff-chip" data-a="m" data-x="'+w[1]+'">'+tx(w[1])+'</button>'}).join('')+'</div>'}).join('')} /* Ecriture */ var wt={t:'l',i:0}; function items(){if(wt.t=='l'){return AL.map(function(x){return x.toUpperCase()+' '+x})} if(wt.t=='s'){var o=[];C1.forEach(function(c){V1.forEach(function(v){o.push(c+v)})});return o} return W.map(function(w){return tx(w[1])})} function cur(){var l=items();return l[wt.i%l.length]} function vWr(){var c=S.v=='cursive'; return '<h2>'+(c?'Écriture cursive':'Écriture')+'</h2><p>Écris : <b>'+cur()+'</b></p><div class="ff-row">'+[['l','Lettres'],['s','Syllabes'],['m','Mots']].map(function(x){return '<button class="ff-chip'+(wt.t==x[0]?' s1':'')+'" data-a="wt" data-x="'+x[0]+'">'+x[1]+'</button>'}).join('')+'</div><div class="ff-cv"><canvas class="mdl"></canvas><canvas class="drw"></canvas></div><div class="ff-row"><button class="ff-b wh" data-a="wi" data-x="-1">◀</button><button class="ff-b wh" data-a="wi" data-x="1">▶</button><button class="ff-b" data-a="we">Effacer</button><button class="ff-b wh" data-a="wr">Recommencer</button><button class="ff-b or" data-a="ws">🔊 Écouter</button></div><label for="ffkb">Écris aussi au clavier :</label><input id="ffkb" class="ff-in ff-kb" autocomplete="off" spellcheck="false"><div class="ff-fb ff-f3" aria-live="polite"></div><p class="ff-sm">Cette activité ne corrige pas ton tracé : compare avec le modèle gris. Le modèle cursif dépend de la police de ton appareil.</p>'} function cv(){var c=S.v=='cursive',w=$('.ff-cv'),m=$('.mdl'),d=$('.drw'),r=window.devicePixelRatio||1,Wd=w.clientWidth,H=w.clientHeight; [m,d].forEach(function(e){e.width=Wd*r;e.height=H*r;e.getContext('2d').scale(r,r)}); var x=m.getContext('2d'),t=cur(); x.strokeStyle='#9bbbe8';x.lineWidth=1.5; [[0.22,[]],[0.47,[6,6]],[0.72,[]]].forEach(function(l){x.setLineDash(l[1]);x.beginPath();x.moveTo(8,H*l[0]);x.lineTo(Wd-8,H*l[0]);x.stroke()}); var sz=Math.min(H*0.62,Wd/(t.length*0.62)); x.font=sz+'px '+(c?'"Segoe Script","Bradley Hand","Comic Sans MS","Brush Script MT",cursive':'Verdana,sans-serif'); x.fillStyle='#d3e3fb';x.textAlign='center';x.fillText(t,Wd/2,H*0.72); var g=d.getContext('2d'),on=false;g.lineWidth=5;g.lineCap='round';g.lineJoin='round';g.strokeStyle='#12306b'; function pt(e){var b=d.getBoundingClientRect();return [e.clientX-b.left,e.clientY-b.top]} d.onpointerdown=function(e){on=true;try{d.setPointerCapture(e.pointerId)}catch(z){}var p=pt(e);g.beginPath();g.moveTo(p[0],p[1]);g.lineTo(p[0]+0.1,p[1]+0.1);g.stroke();e.preventDefault()}; d.onpointermove=function(e){if(on){var p=pt(e);g.lineTo(p[0],p[1]);g.stroke()}}; d.onpointerup=d.onpointercancel=function(){on=false}} /* Dictée */ var dt={l:[],i:0}; function dtList(){if(S.lv==1){return V1.concat(['ba','mi','lo','fu','ta','ne','pu','sa','ri','do'])} if(S.lv==2){return W.filter(function(w){return 3>w[0]}).map(function(w){return tx(w[1])})} return W.filter(function(w){return w[0]==3}).map(function(w){return tx(w[1])}).concat(SEN)} function dcur(){return dt.l[dt.i%dt.l.length]} function vDi(){if(!dt.l.length){dt.l=rnd(dtList())} return '<h2>Dictée</h2><p>Écoute, puis écris ce que tu entends.</p><div class="ff-row"><button class="ff-b or" data-a="di" data-x="l">🔊 Écouter</button></div><input class="ff-in ff-dk" autocomplete="off" autocapitalize="off" spellcheck="false" aria-label="Écris ici"><div class="ff-row"><button class="ff-b" data-a="di" data-x="v">Vérifier</button><button class="ff-b wh" data-a="di" data-x="n">Exercice suivant</button></div><div class="ff-fb ff-f2" aria-live="polite"></div>'} var nm=function(s){return s.toLowerCase().replace(/[.!?\s]+$/,'').replace(/\s+/g,' ').trim()}; var pl=function(s){return nm(s).normalize('NFD').replace(/[\u0300-\u036f]/g,'')}; /* Quiz */ var qz={},gm='',as={}; function qStart(k){var it; if(k=='ec'){var o=[];cons().forEach(function(c){vow().forEach(function(v){o.push([c,v])})});it=rnd(o).slice(0,20)} else{it=rnd(wl()).slice(0,10)} qz={k:k,l:it,i:0,ok:0};qB()} function qB(){var q=qz,x=q.l[q.i];if(!x){return}q.d=false; if(q.k=='ec'){q.s=x[0]+x[1];q.o=rnd([q.s].concat(rnd(cons().filter(function(c){return c!=x[0]})).slice(0,2).map(function(c){return c+x[1]})))} else{q.s=tx(x);q.o=rnd([q.s].concat(rnd(wl().map(tx).filter(function(w){return w!=q.s})).slice(0,2)))}} function qR(){var q=qz,n=q.l.length,t=q.k=='ec'?"J'écoute et je choisis":'Choisis le mot'; if(q.i>=n){return '<h2>Terminé !</h2><div class="ff-big">'+q.ok+' / '+n+'</div><p style="text-align:center">Bravo, continue à t’entraîner !</p><div class="ff-row"><button class="ff-b or" data-a="qr">Recommencer</button></div>'} return '<h2>'+t+'</h2><div class="ff-pg"><i style="width:'+(q.i/n*100)+'%"></i></div><p class="ff-sm">Question '+(q.i+1)+' / '+n+' · Réponses justes : '+q.ok+'</p><div class="ff-row"><button class="ff-b or" data-a="ql">🔊 Écouter</button></div><div class="ff-row">'+q.o.map(function(x){return '<button class="ff-b ff-op" data-a="qa" data-x="'+x+'">'+x+'</button>'}).join('')+'</div><div class="ff-fb ff-f2" aria-live="polite"></div><div class="ff-row"><button class="ff-b wh ff-nx" data-a="qn" hidden>Question suivante</button></div>'} /* Jeux */ function asNew(){var a=as;if(a.i>=a.l.length){return}var s=a.l[a.i].split('-');a.p=rnd(s.map(function(x,j){return [x,j]}));a.b=[]} function vJe(){ if(gm=='jm'){return qR()} if(gm=='as'){var a=as,n=a.l.length; if(a.i>=n){return '<h2>Terminé !</h2><p style="text-align:center">Bravo, tu as assemblé tous les mots !</p><div class="ff-row"><button class="ff-b or" data-a="gs" data-x="as">Rejouer</button></div>'} return '<h2>Assemble le mot</h2><div class="ff-pg"><i style="width:'+(a.i/n*100)+'%"></i></div><div class="ff-big">'+(a.b.map(function(j){return a.p[j][0]}).join('')||'…')+'</div><div class="ff-row">'+a.p.map(function(p,j){return a.b.indexOf(j)>-1?'':'<button class="ff-chip" data-a="ac" data-x="'+j+'">'+p[0]+'</button>'}).join('')+'</div><div class="ff-row"><button class="ff-b or" data-a="al">🔊 Écouter le mot</button><button class="ff-b wh" data-a="ae">Effacer</button></div><div class="ff-fb">'+(a.f||'')+'</div>'} return '<h2>Jeux éducatifs</h2><div class="ff-row"><button class="ff-b or" data-a="gs" data-x="jm">🎧 Choisis le mot</button><button class="ff-b" data-a="gs" data-x="as">🧩 Assemble le mot</button></div><p class="ff-sm">Les jeux utilisent les mots du niveau choisi.</p>'} var NAV=[['lecture','📖','Lecture','Lire des mots'],['sons','🔤','Sons','Lettres et sons'],['syllabes','🧩','Syllabes','Former des syllabes'],['tableau','🗂️','Tableau de syllabes','Toucher et écouter'],['mots','📝','Mots','Bibliothèque de mots'],['ecriture','✏️','Écriture','Tracer les lettres'],['cursive','🖋️','Écriture cursive','Lettres attachées'],['dictee','🎧','Dictée','Écouter et écrire'],['ecoute','👂','Écoute et choisis','Quiz de syllabes'],['jeux','🎲','Jeux éducatifs','Jouer avec les mots']]; var V={lecture:vLe,sons:vSo,syllabes:vSy,tableau:vTb,mots:vMo,ecriture:vWr,cursive:vWr,dictee:vDi,ecoute:qR,jeux:vJe}; function go(v){S.v=v;BK.hidden=(v=='home'); if(v=='home'){P.className='ff-p ff-home';P.innerHTML=NAV.map(function(n){return '<button class="ff-card" data-a="g" data-x="'+n[0]+'"><i>'+n[1]+'</i>'+n[2]+'<small>'+n[3]+'</small></button>'}).join('');return} P.className='ff-p';P.innerHTML=V[v](); if(v=='ecriture'||v=='cursive'){cv()}} function lvUI(){Array.prototype.forEach.call(R.querySelectorAll('.ff-lv button'),function(b){b.className='ff-b'+(b.getAttribute('data-x')==S.lv?' on':'')})} var A={ g:function(x){note('');if(x=='ecoute'){qStart('ec')}if(x=='jeux'){gm=''}go(x);if(x=='ecoute'){say(qz.s)}}, lv:function(x){S.lv=+x;dt={l:[],i:0};sy={c:0,v:0};tb='';lc={i:0,r:0};qz={};gm='';lvUI();A.g(S.v)}, stop:function(){if(window.speechSynthesis){speechSynthesis.cancel()}}, p:function(x){var k=x.charAt(0);sy[k]=parseInt(x.slice(1),10);if(S.au){say(syT())}go('syllabes')}, d:function(x){var k=x.charAt(0),n=parseInt(x.slice(1),10),len=(k=='c'?cons():vow()).length;sy[k]=(sy[k]+n+len)%len;if(S.au){say(syT())}go('syllabes')}, sl:function(){say(syT())}, sn:function(){sy.c=Math.floor(Math.random()*cons().length);sy.v=Math.floor(Math.random()*vow().length);go('syllabes');say(syT())}, sr:function(){sy={c:0,v:0};go('syllabes')}, au:function(){S.au=!S.au;go('syllabes')}, fs:function(){var f=P.requestFullscreen||P.webkitRequestFullscreen;if(f){try{f.call(P)}catch(z){note("Plein écran non disponible.")}}else{note("Plein écran non disponible sur ce navigateur.")}}, t:function(x){tb=x;say(x);go('tableau')}, s:function(x){say(x)}, le:function(x){var l=wl(),w=l[lc.i%l.length],s=w.split('-'); if(x=='l'){say(tx(w));return} if(x=='p'){lc.i=(lc.i+l.length-1)%l.length;lc.r=0;go('lecture');return} if(x=='n'){lc.i=(lc.i+1)%l.length;lc.r=0;go('lecture');return} if(x=='s'){lc.r++;if(lc.r>s.length){lc.r=0;go('lecture');say(tx(w))}else{go('lecture');say(s[lc.r-1])}return} wt.t='m';wt.i=items().indexOf(tx(w));go('ecriture')}, m:function(x){var w=W.filter(function(a){return a[1]==x})[0];S.lv=w[0];lvUI();lc={i:wl().indexOf(x),r:0};say(tx(x));go('lecture')}, wt:function(x){wt.t=x;wt.i=0;go(S.v)}, wi:function(x){var n=items().length;wt.i=(wt.i+parseInt(x,10)+n)%n;go(S.v)}, we:function(){var d=$('.drw');d.getContext('2d').clearRect(0,0,d.width,d.height)}, wr:function(){wt.i=0;go(S.v)}, ws:function(){say(cur().replace(' ',', '))}, di:function(x){var t=dcur(),k=$('.ff-dk'),f=$('.ff-f2'); if(x=='l'){say(t);return} if(x=='n'){dt.i++;go('dictee');say(dcur());return} var v=k.value; if(nm(v)==nm(t)){f.textContent=reward(true)} else{if(pl(v)==pl(t)){f.textContent='Presque ! Vérifie les accents. Réponse : '+t}else{f.textContent='Pas tout à fait. La bonne réponse : '+t}}}, qr:function(){qStart(qz.k);go(S.v);say(qz.s)}, ql:function(){say(qz.s)}, qa:function(x,b){var q=qz;if(q.d){return}q.d=true; Array.prototype.forEach.call(R.querySelectorAll('.ff-op'),function(e){if(e.getAttribute('data-x')==q.s){e.classList.add('ok')}}); var good=(x==q.s);if(!good){b.classList.add('no')}else{q.ok++} $('.ff-f2').textContent=reward(good)+(good?'':' La bonne réponse est '+q.s+'.'); $('.ff-nx').hidden=false}, qn:function(){qz.i++;qB();go(S.v);if(qz.i>=qz.l.length){return}say(qz.s)}, gs:function(x){if(x=='jm'){gm='jm';qStart('jm')}else{gm='as';as={l:rnd(wl().filter(function(w){return w.indexOf('-')>0})).slice(0,10),i:0,f:''};asNew()}go('jeux');if(x=='jm'){say(qz.s)}}, ac:function(x){var a=as;a.b.push(+x); if(a.b.length==a.p.length){var w=a.b.map(function(j){return a.p[j][0]}).join(''),t=tx(a.l[a.i]); if(w==t){a.f=reward(true);say(t);a.i++;asNew()}else{a.f='Presque ! Essaie encore.';a.b=[]}} go('jeux')}, ae:function(){as.b=[];go('jeux')}, al:function(){say(tx(as.l[as.i]))} }; R.addEventListener('click',function(e){var t=e.target.closest('[data-a]');if(t){A[t.getAttribute('data-a')](t.getAttribute('data-x'),t)}}); R.addEventListener('input',function(e){if(e.target.classList.contains('ff-kb')){var f=$('.ff-f3'),v=e.target.value.trim();f.textContent=(v&&cur().split(' ').indexOf(v)>-1)?'✔ Bien écrit !':''}}); if(!window.speechSynthesis){note("Le son n'est pas disponible sur ce navigateur. Tu peux quand même lire et écrire.")} lvUI();hud();go('home'); })();