let w,h,ratio,i,s,el,g,div,dragQ,game,my={};let QNoLast=-1;function wordquestionsMain(filterOp=''){let version='0.63';my.filter={op:filterOp,lvl:0} my.qPrevs=[] w=460;h=320;coords=new CoordsFull(w-90,200,'-1','-10,','1000','10',true);tickSparseness=0.04;my.choices=[] for(let i=0;i<4;i++){my.choices.push({id:'ans'+i})} my.gameRadioN=0;my.games=[{name:'Add Tens',typ:'add',min:10,max:99,num:[20,100],dec:0},{name:'Add 100s',typ:'add',min:100,max:999,num:[200,1000],dec:0},{name:'Add 1/10ths',typ:'add',min:1,max:20,num:[0,10],dec:1,input:'num'},{name:'Subtract 10s',typ:'sub',min:10,max:50,num:[0,40],dec:0},{name:'Subtract 100s',typ:'sub',min:100,max:500,num:[0,400],dec:0},{name:'Subtract 1/10ths',typ:'sub',min:1,max:20,num:[0,10],dec:1,input:'num'},{name:'Multiply',typ:'mul',min:2,max:10,num:[0,100],dec:0},{name:'Multiply Tens',typ:'mul',min:10,max:30,num:[100,1000],dec:0},{name:'Multiply 1/10ths',typ:'mul',min:2,max:20,num:[0,10],dec:1,input:'num'},];my.score=0 my.numMax=8 this.marks=[];this.midX=w/2;this.midY=h-90;this.width=w-40;let s='';s+='';s+='' s+='
';s+='
';s+='
Score:
';s+='
0
';s+='
';s+='
';s+='
?
';s+='
' my.choices.map(choice=>{s+=``}) s+='
';s+='
 
';s+='
 
';s+='
';s+=getPopHTML();s+='
' s+='   ';s+='';s+='
';s+='
© 2020 MathsIsFun.com v'+version+'
';s+='
';document.write(s);dragType='';my.clrs=[["Blue",'#0000FF'],["Red",'#FF0000'],["Black",'#000000'],["Green",'#00cc00'],["Orange",'#FFA500'],["Slate Blue",'#6A5ACD'],["Lime",'#00FF00'],["Spring Green",'#00FF7F'],["Teal",'#008080'],["Gold",'#ffd700'],["Med Purple",'#aa00aa'],["Light Blue",'#ADD8E6'],["Navy",'#000080'],["Purple",'#800080'],["Dark SeaGreen",'#8FBC8F']];clrNum=0;parser=new Parser();my.qs=qsLoad();my.names=namesGet();my.things=thingsLoad();qNext()} function ontouchstart(evt){let touch=evt.targetTouches[0];evt.clientX=touch.clientX;evt.clientY=touch.clientY;evt.touchQ=true;onmouseDown(evt)} function ontouchmove(evt){let touch=evt.targetTouches[0];evt.clientX=touch.clientX;evt.clientY=touch.clientY;evt.touchQ=true;onmouseMove(evt);evt.preventDefault();} function ontouchend(evt){el2.addEventListener('touchstart',ontouchstart,false);window.removeEventListener("touchend",ontouchend,false);} function onmouseDown(evt){if(my.resultQ)return;let bRect=el2.getBoundingClientRect();let mouseX=(evt.clientX-bRect.left);let xVal=numlineVal(mouseX);choose(xVal);if(evt.preventDefault){evt.preventDefault();} else if(evt.returnValue){evt.returnValue=false;} return false;} function onmouseMove(evt){if(my.resultQ)return;let bRect=el2.getBoundingClientRect();let mouseX=(evt.clientX-bRect.left);let mouseY=(evt.clientY-bRect.top);let xVal=numlineVal(mouseX);drawNumLine(g2,50,30,0,10,mouseX,mouseY);} function numlineVal(mousex){return coords.toXVal(mousex-50);} function calcScore(diff){let pct=Math.abs(diff/(my.game.num[1]-my.game.num[0]))*100;if(pct<=2){return 5;}else{if(pct<=4){return 4;}else{if(pct<=7){return 3;}else{if(pct<=10){return 2;}else{if(pct<=15)return 1;}}}} return 0;} function fancyText(s,x,y){let clr=g.fillStyle;g.fillStyle='#fff';let d=1;g.fillText(s,x-d,y-d);g.fillText(s,x-d,y+d);g.fillText(s,x+d,y+d);g.fillText(s,x+d,y-d);g.fillStyle=clr;g.fillText(s,x,y);} function qNext(){document.getElementById('msg').innerHTML='' my.q=qGet();if(my.q==null){return} my.numMax++ my.numMax=Math.min(my.numMax,20) console.log('my.numMax',my.numMax) document.getElementById('quest').innerHTML=my.q.txtStr let div=document.getElementById('method') div.style.visibility='hidden' div.innerHTML=my.q.methodStr document.getElementById('nextBtn').style.visibility='hidden' anssGet(my.q) console.log("qNext",my.q);let i=0 my.choices.map(choice=>{let div=document.getElementById(choice.id) div.innerHTML=my.q.anss[i++] div.classList.remove("lo") div.classList.remove("hi")})} function ansClick(id){let idNo=parseInt(id.substr(3)) console.log('ansClick',id,idNo) if(idNo==my.q.ansNo){document.getElementById(id).classList.add("hi") let div=document.getElementById('msg') div.style.color='gold' div.innerHTML='Well done!' my.score+=5 document.getElementById('score').innerHTML=my.score document.getElementById('method').style.visibility='visible' document.getElementById('nextBtn').style.visibility='visible'}else{document.getElementById(id).classList.add("lo") let div=document.getElementById('msg') div.style.color='#888' div.innerHTML='Whoops, that was the wrong answer, try again ...' my.score-=2 my.score=Math.max(0,my.score) document.getElementById('score').innerHTML=my.score}} function qsLoad(){let qs=[];qs.push([2,"y-x",["y>x","Cups:give"],"You chose [x] Cupsx and your friend chose [y] Cupsx. How many more Cupsx did your friend choose?","[y] - [x] = [y-x]"]);qs.push([1,"x+y",["x>2","Cups:give"],"Betty gives John [x] Cupsx. John already had [y] Cupsy. So how many does John have now?","[x] Cupsy + [y] Cupsx = [x+y] Cups"]);qs.push([2,"y-x",["y>6","y>x"],"In your class today, only [x] of the [y] students were at school. How many were absent?","[y] - [x] = [y-x]"]);qs.push([2,"x-y",["x>y","Cups:money"],"You saved [x] Cupsx and your brother saved [y] Cupsy. How many more Cups did you save?","[x] - [y] = [x-y]"]);qs.push([2,"x-y",["x>2","x>y","y>2"],"You have [x] birthday gifts! [y] came from your family, the rest came from your friends. How many gifts did your friends give you?","[x] - [y] = [x-y]"]);qs.push([2,"y-x",["y>x","x>2","Cups:give"],"Your friends just gave you [x] Cupsx, now you have [y].
How many did you have before your friends gave you them?","[y] - [x] = [y-x]"]);qs.push([1,"x+y",["y>1","x>1","Cups:gift"],"John got [x] new Cups on his birthday. If he already had [y], how many Cups does he have now?","[x] + [y] = [x+y]"]);qs.push([1,"x-y",["y>1","x>y","Cups:eat"],"John ate [x] Cups and Betty ate [y] Cups. How many more Cups did John eat than Betty?","[x] - [y] = [x-y]"]);qs.push([1,"3x",["x>1"],"How many corners are on [x] triangles?","[x] × 3 = [x*3]"]);qs.push([1,"4x",["x>1"],"How many corners are on [x] squares?","[x] × 4 = [x*4]"]);qs.push([3,"y",["x>3","y>x","Cups:eat"],"John is preparing Cupsx for the tennis event. He has already prepared [x] Cupsx, but needs [x+y].
How many more Cupsx does he need?","[x+y] - [x] = [y]"]);qs.push([1,"x-y",["x>y","y>1","Cups:clr"],"John has [x] Cupsx. [y] are green and the rest are blue. How many Cups are blue?","[x] Cupsx - [y] Cupsy = [x-y] Cups"]);qs.push([1,"y-x",["x>2","y>x","Cups:give"],"John has just been given [x] Cupsx, he now has [y] Cupsy. How many did he have before?","[y] Cupsx - [x] Cupsy = [y-x] Cups"]);qs.push([1,"x+y",["x>2","Cups:give"],"John lost [x] Cupsx, and now has only [y] Cupsy. How many did he have before?","[x] Cupsy + [y] Cupsx = [x+y] Cups"]);qs.push([1,"x+y",["x>2","Cups:give"],"John had [x] Cupsx and was given [y] more, how many Cups does he have now?","[x] Cupsy + [y] Cupsx = [x+y] Cups"]);qs.push([1,"x+y",["x>2","Cups:give"],"John has [x] Cupsx and plans to get [y] more tomorrow. How many will he have then?","[x] Cupsy + [y] Cupsx = [x+y] Cups"]);qs.push([1,"x+y",["x>2","Cups:money"],"On Monday John earned [x] Cupsx. On Tuesday he earned [y] Cupsy. How much did he earn on the two days?","[x] Cupsy + [y] Cupsx = [x+y] Cups"]);qs.push([3,"y",["x=30","y>2","y<10"],"It takes [x*y] days to save enough money for my vacation. About how many months is that?","[x*y] ÷ [x] = [(x*y)/x]"]);qs.push([3,"y",["x>6","x<20","y>10","y<30","Cups:give"],"John has [x*y] Cupsx to share among [x] friends. How many Cupsx will each of them receive?","[x*y] ÷ [x] = [y]"]);qs.push([2,"y-x",["x>2","y>x","Cups:give"],"John just gave you [x] Cupsx, now you have [y].
How many did you have before he gave you [x] more?","[y] Cupsy - [x] Cupsx = [y-x] Cups"]);qs.push([1,"x+y",["x>2","Cups:give"],"John had [x] Cupsx and was given [y] more, how many Cups does he have now?","[x] Cupsy + [y] Cupsx = [x+y] Cups"]);let qobjs=[];for(let i=0;i=my.qPrevs.length-notInLast;i--){if(qNo==my.qPrevs[i]){okQ=false break}}}while(!okQ) my.qPrevs.push(qNo) let q=qs[qNo];if(q==null)return null;let qStr=q.txt;let methodStr=q.method;if(methodStr==null){methodStr="";} vals=[];let GTs=[0,0,0];let maxP1=my.numMax+1 let LTs=[maxP1,maxP1,maxP1];let anss=[];let attempts=0;let OKQ=false let Name1,Name2 do{for(i=0;i<3;i++){vals[i]=randomInt(GTs[i]+1,LTs[i]-1);} OKQ=true;for(i=0;i","="]);if(condarr.length==3){let lhs=evalExpr(condarr[0],vals);let condtype=condarr[1];let rhs=evalExpr(condarr[2],vals);if(condarr[0]=="a"){anss.push(condarr[2]);}else{let n=varNo(condarr[0]);if(n>=0){switch(condtype){case ">":GTs[n]=rhs;LTs[n]=Math.max(LTs[n],GTs[n]+2);vals[n]=randomInt(GTs[n]+1,LTs[n]);break;case "<":LTs[n]=rhs;GTs[n]=Math.min(GTs[n],LTs[n]-2);vals[n]=randomInt(GTs[n]+1,LTs[n]);break;case "=":vals[n]=Number(rhs);break;default:}}}}} attempts++;}while(!OKQ&&attempts<100);if(!OKQ){return(null);} Name1=my.names[randomInt(0,my.names.length-1)];do{Name2=my.names[randomInt(0,my.names.length-1)];}while(Name2.name==Name1.name);console.log("Name1, Name2",Name1,Name2);let t=my.things.slice(0);for(let i=0;i0){t=tnew.slice(0);} break;default:}}} if(t.length==1){let Thing1=t[0];let Thing2=t[0];}else{Thing1=t[randomInt(0,t.length-1)];attempts=0;do{Thing2=t[randomInt(0,t.length-1)];attempts++;}while(Thing2==Thing1&&attempts<100);if(Thing2==Thing1){return(null);}} console.log('Thing1',Thing1) q.thing=Thing1 q.txtStr=qFmt(qStr,Name1,Name2,Thing1,Thing2,vals) console.log('methodStr',methodStr) q.methodStr=qFmt(methodStr,Name1,Name2,Thing1,Thing2,vals) return q} function namesGet(){let names=[{sex:"n",name:"Sam"},{sex:"n",name:"Alex"},{sex:"m",name:"Raj"},{sex:"m",name:"Emir"},{sex:"f",name:"Aisha"},{sex:"n",name:"Jìngyi"},{sex:"n",name:"Li"},{sex:"m",name:"John"},{sex:"m",name:"Henry"},{sex:"m",name:"Patrick"},{sex:"m",name:"Josh"},{sex:"m",name:"Mr Edwards"},{sex:"m",name:"the man"},{sex:"f",name:"Betty"},{sex:"f",name:"Jill"},{sex:"f",name:"Tiffany"},{sex:"f",name:"Sofia"},{sex:"f",name:"Jasmine"},{sex:"f",name:"Mrs Jones"},{sex:"f",name:"the woman"},{sex:"n",name:"the teacher"},{sex:"n",name:"Hunter"},{sex:"n",name:"Billy"},{sex:"n",name:"Angel"},{sex:"n",name:"Drew"},{sex:"n",name:"Jazz"},{sex:"n",name:"Riley"},{sex:"n",name:"Sky"},{sex:"n",name:"Toby"},{sex:"n",name:"Sage"},{sex:"n",name:"Ariel"},{sex:"n",name:"Mason"},{sex:"n",name:"Noel"},] return names} function thingsLoad(){let things=[];things.push({one:"apple",many:"apples",props:["eat","give","buy"]});things.push({one:"pear",many:"pears",props:["eat","give","buy"]});things.push({one:"banana",many:"bananas",props:["eat","give","buy"]});things.push({one:"orange",many:"oranges",props:["eat","give","buy"]});things.push({one:"sandwich",many:"sandwiches",props:["eat","give","buy"]});things.push({one:"sausage",many:"sausages",props:["eat","give","buy"]});things.push({one:"salad",many:"salads",props:["eat","give","buy"]});things.push({one:"chocolate",many:"chocolates",props:["eat","give","buy"]});things.push({one:"cupcake",many:"cupcakes",props:["eat","give","buy"]});things.push({one:"pie",many:"pies",props:["eat","give","buy"]});things.push({one:"drink",many:"drinks",props:["eat","give","buy"]});things.push({one:"mouse",many:"mice",props:["give","buy"]});things.push({one:"marble",many:"marbles",props:["clr","gift","give","buy"]});things.push({one:"balloon",many:"balloons",props:["clr","give","buy"]});things.push({one:"toy",many:"toys",props:["clr","give","gift","buy"]});things.push({one:"plant",many:"plants",props:["give","gift","buy"]});things.push({one:"ball",many:"balls",props:["clr","gift","give","buy"]});things.push({one:"cat",many:"cats",props:["4legs"]});things.push({one:"dog",many:"dogs",props:["4legs"]});things.push({one:"horse",many:"horses",props:["4legs"]});things.push({one:"person",many:"people",props:["2legs"]});things.push({one:"bird",many:"birds",props:["bird","2legs","buy"]});things.push({one:"seagull",many:"seagulls",props:["bird","2legs"]});things.push({one:"robin",many:"robins",props:["bird","2legs"]});things.push({one:"blackbird",many:"blackbirds",props:["bird","2legs"]});things.push({one:"pen",many:"pens",props:["clr","give","buy"]});things.push({one:"book",many:"books",props:["give","buy"]});things.push({one:"May",many:"May",props:["month"]});things.push({one:"July",many:"July",props:["month"]});things.push({one:"March",many:"March",props:["month"]});things.push({one:"dollar",many:"dollars",props:["give","money"]});things.push({one:"coin",many:"coins",props:["give","money"]});return things} function str2Tokens(s){let a=[];while(s.length>0){let bracStt=s.indexOf("[");if(bracStt>-1){let bracEnd=s.indexOf("]",bracStt);if(bracEnd<0){return null;} let before=s.substr(0,bracStt);let inside=s.substr(bracStt+1,bracEnd-bracStt-1);let after=s.substr(bracEnd+1,s.length-bracEnd-1);if(before.length>0) a.push(["o",before]);if(inside.length>0) a.push(["i",inside]);s=after;}else{if(s.length>0) a.push(["o",s]);s="";}} return a;} function doLang(){let Lang="en";switch(Lang){case "en":let LangNo=0;LangMistake="Whoops, that was the wrong answer, try again";LangSuccess="Well Done!";LangSkipQ="(skip question)";LangClue="Clue";break;case "es":LangNo=1;break;default:}} function qsFilter(){let qs=my.qs.slice(0);if(my.filter.lvl>0){let temp=[];for(let i=0;i=my.filter.lvl-1&&qs[i][QLevelAt]<=my.filter.lvl+1) temp.push(qs[i]);} qs=temp.slice(0);} if(my.filter.op.length>0){let temp=[];for(i=0;i=0){s+="["+tokens[i][1]+"]";}else{parser.setVarVal("x",vals[0]);parser.setVarVal("y",vals[1]);parser.setVarVal("z",vals[2]);parser.newParse(tokens[i][1]);let val=parser.getVal();plural=val;s+=val.toString()}}} s=toSentenceCase(s);return(s);} function namesChg(qStr,Name1,Name2){qStr=qStr.replace(/ he /gi," %he1 ");qStr=qStr.replace(/ she /gi," %he2 ");qStr=qStr.replace(/ his /gi," %his1 ");qStr=qStr.replace(/ her /gi," %his2 ");console.log('qStr before:',qStr) qStr=qStr.replace(/John/g,Name1.name);let sex1=Name1.sex=='n'?Math.random()>0.5?'m':'f':Name1.sex qStr=qStr.replace(/%he1/gi,sex1=='m'?"he":"she");qStr=qStr.replace(/%his1/gi,sex1=='m'?"his":"her");qStr=qStr.replace(/Betty/g,Name2.name);let sex2=Name2.sex=='n'?Math.random()>0.5?'m':'f':Name2.sex qStr=qStr.replace(/%he2/gi,sex2=='m'?"he":"she");qStr=qStr.replace(/%his2/gi,sex2=='m'?"his":"her");console.log('qStr after:',qStr) return qStr} function thingsChg(qStr,Thing1,Thing2,plural){qStr=thingChg(qStr,/Cupsx/g,Thing1,plural);qStr=thingChg(qStr,/Cupsy/g,Thing1,plural);qStr=thingChg(qStr,/Platesx/g,Thing2,plural);qStr=thingChg(qStr,/Platesy/g,Thing2,plural);qStr=thingChg(qStr,/Cups/g,Thing1,plural);qStr=thingChg(qStr,/Plates/g,Thing2,plural);return qStr;} function thingChg(s,from,thing,plural){if(s.search(from)>-1){return s.replace(from,thingGet(thing,plural))}else{return s}} function anssGet(q){console.log('anssGet',q) parser.setVarVal("x",vals[0]);parser.setVarVal("y",vals[1]);parser.setVarVal("z",vals[2]);parser.newParse(q.formula);correctAnswer=parser.getVal();let answers=getWrongAnswers(correctAnswer,true,true);let anspos=randomInt(0,3);answers[anspos]=correctAnswer;if(hasThing(q)){answers=answers.map(ans=>{ans+=' ' ans+=Math.abs(ans)==1?q.thing.one:q.thing.many return ans})} q.anss=answers q.ansNo=anspos} function hasThing(q){let s=q.txt if(s.search(/cups/i)>=0)return true if(s.indexOf('plates')>=0)return true return false} function getWrongAnswers(ans,NoNegQ,NoZeroQ){var wrongs=[] wrongs.push(ans+Math.round(Math.random()*(9-2)+2));wrongs.push(ans-Math.round(Math.random()*(9-2)+2));wrongs.push(ans+1);wrongs.push(ans+2);wrongs.push(ans+3);wrongs.push(ans-1);wrongs.push(ans-2);wrongs.push(ans-3);wrongs.push(ans+10);wrongs.push(ans-10);wrongs.push(ans+20);wrongs.push(ans*2);wrongs.push(ans*2-1);wrongs.push(ans*2+1);wrongs.push(Math.round(ans/2));var temp=[] for(var i=0;i0){dec1=getRandomInt(0,dec-a.toString().length+1);dec2=getRandomInt(0,dec-b.toString().length+1);if(dec1>0)a*=Math.pow(10,dec1);if(dec2>0)b*=Math.pow(10,dec2);} my.q=fmtDec(a,dec)+' + '+fmtDec(b,dec)+' =';my.tgtN=fmtDec(a+b,dec) break;case 'sub':a=getRandomInt(min,max);b=getRandomInt(min,max);if(dec>0){let dec1=getRandomInt(0,dec-a.toString().length+1);let dec2=getRandomInt(0,dec-b.toString().length+1);if(dec1>0)a*=Math.pow(10,dec1);if(dec2>0)b*=Math.pow(10,dec2);} if(a0){dec1=getRandomInt(0,dec);dec2=dec-dec1;decAns=dec*2;if(dec1>0)a*=Math.pow(10,dec1);if(dec2>0)b*=Math.pow(10,dec2);} my.tgtN=fmtDec(a*b,decAns,true) my.q=fmtDec(a,dec)+' × '+fmtDec(b,dec)+' =';break;case 'div':a=getRandomInt(min,max);b=getRandomInt(min,max);if(dec>0){dec1=getRandomInt(0,dec);dec2=dec-dec1;decAns=dec*2;if(dec1>0)a*=Math.pow(10,dec1);if(dec2>0)b*=Math.pow(10,dec2);} my.tgtN=fmtDec(a,dec,true);my.q=fmtDec(a*b,decAns,true)+' / '+fmtDec(b,dec)+' =';break;default:} document.getElementById('quest').innerHTML=my.q;} function chgVal(val,doneQ){console.log("chgVal",val,val.length,my.tgtN.toString().length,doneQ);if(doneQ||(val.length==my.tgtN.toString().length)||(Number(val)==Number(my.tgtN))){choose(val);document.getElementById('user').value='';}} function choose(val){if(!my.gameQ)return;my.resultQ=true;let gap,score switch(my.game.typ){case 'count':val=Math.round(val);console.log("choose",my.game.typ,val,my.tgtN);g.textAlign='center';g.font='bold 65px Arial';s=''+my.tgtN;g.fillStyle='blue';fancyText(s,w/2,120);if(val==my.tgtN){g.font='bold 40px Arial';s='Exactly Right!';g.fillStyle='gold';fancyText(s,w/2,170);} let gap=val-my.tgtN;let score=calcScore(gap/2);if(score!=0){my.score+=score;document.getElementById('score').innerHTML=my.score;g.font='36px Arial';s='Score +'+score;g.fillStyle='black';fancyText(s,w/2,250);} break;case 'pct':val=Math.round(val);console.log("choose",my.game.typ,val,my.tgtN);g.font='bold 44px Arial';g.textAlign='center';s=my.tgtN+'%';g.fillStyle='black';fancyText(s,graphWd/2,graphHt/2+18);gap=val-my.tgtN;score=calcScore(gap);if(score!=0){my.score+=score;document.getElementById('score').innerHTML=my.score;s='Score +'+score;g.fillStyle='black';fancyText(s,w/2,250);} break;case 'add':case 'sub':case 'mul':case 'div':document.getElementById('quest').innerHTML=my.q+' '+my.tgtN;gap=val-my.tgtN;score=calcScore(gap);if(score!=0){my.score+=score;document.getElementById('score').innerHTML=my.score;} break;default:} if(my.gameQ)setTimeout(newRound,1500);} function getRegular(midX,midY,radius,sttAngle,n){let pts=[];let dAngle=Math.PI*2/n;for(let i=0;i-1){let condarr=cond.split(condtype);return([condarr[0],condtype,condarr[1]]);}else{return([]);}} function evalExpr(expr,vals){let x=0;let no=varNo(expr);if(no>=0){x=vals[no];}else{x=Number(expr);} return(x);} function varNo(valName){switch(valName){case "x":return 0;case "y":return 1;case "z":return 2;default:} return-1;} function getRadioHTML(prompt,id,lbls,func){let s='';s+='
';for(let i=0;i';let idi=id+i;let lbl=lbls[i];let check='';if(i==0)check=' checked="checked" ';s+='';s+='';s+='
';} s+='';return s;} function radioClick(n){my.gameRadioN=n;} function getPopHTML(){s='';s+='';s+='
';let gms=[];for(let i=0;i';s+='';s+='';s+='
';s+='';return s;} function editpop(){console.log("editpop");let pop=document.getElementById('editpop');pop.style.transitionDuration="0.3s";pop.style.opacity=1;pop.style.zIndex=12;pop.style.left='50px';} function editYes(){let pop=document.getElementById('editpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-500px';console.log("editYes",my.fn);my.game=my.games[my.gameRadioN];gameNew();} function editNo(){let pop=document.getElementById('editpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-500px';} function gameOverCallback(){console.log("end!!");my.gameQ=false;g.clearRect(0,0,el.width,el.height);g.textAlign='center';s='Game: '+my.game.name;g.font='36px Arial';g.fillStyle='orange';fancyText(s,w/2,100);s='Total Score: '+my.score;g.font='bold 36px Arial';g.fillStyle='orange';fancyText(s,w/2,145);} function Timer(g,rad,secs,clr,funcEnd){this.g=g;this.rad=rad;this.secs=secs;this.clr=clr;this.funcEnd=funcEnd;this.x=rad;this.y=rad;this.stt=performance.now();this.stopQ=false;} Timer.prototype.update=function(){let now=performance.now();let elapsed=now-this.stt;};Timer.prototype.restart=function(secs){this.secs=secs;this.stt=performance.now();this.stopQ=false;requestAnimationFrame(this.draw.bind(this));};Timer.prototype.more=function(secs){this.stt+=secs*1000;};Timer.prototype.stop=function(){this.stopQ=true;};Timer.prototype.draw=function(){if(this.stopQ)return;let now=performance.now();let elapsed=now-this.stt;let ratio=Math.min(1,elapsed/this.secs/1000);let g=this.g;g.beginPath();g.fillStyle="#def";g.arc(this.x,this.y,this.rad,0,2*Math.PI);g.fill();g.beginPath();g.moveTo(this.x,this.y);g.fillStyle=this.clr;g.arc(this.x,this.y,this.rad,-Math.PI/2,ratio*2*Math.PI-Math.PI/2);g.fill();if(ratio<1){requestAnimationFrame(this.draw.bind(this));}else{this.funcEnd();}};function drawNumLine(g,lt,tp,min,max,currx,curry){g.clearRect(0,0,el2.width,el2.height);min=my.minAns;max=my.maxAns;coords=new CoordsFull(w-90,200,min,'-10,',max,'10',true);let wd=coords.width;let ticks=getTicks();g.textAlign='center';g.lineWidth=1;let minV=Infinity;let maxV=-Infinity;let zeroPx=-999;for(let i=0;imaxV)maxV=v;if(v0)clr='blue';g.strokeStyle=clr;g.fillStyle=clr;let txtY=30;if(vStr.length>5){let lastChr=vStr.replace(/0+$/,'').slice(-1);let evenQ=Number(lastChr)%2==0;if(!evenQ){txtY=50;}} let tickHt=1;if(majorQ){g.lineWidth=2;tickHt=12;g.fillText(vStr,xp,tp+txtY);}else{g.lineWidth=1;tickHt=8;} g.beginPath();g.moveTo(xp,tp-tickHt);g.lineTo(xp,tp+tickHt);g.stroke();v+=1;} if(zeroPx==-999){if(maxV<0)zeroPx=wd;if(minV>0)zeroPx=-1;} let lnStt=lt-25;let lnEnd=lt+wd+25;if(zeroPx>lnStt){g.strokeStyle='red';g.drawPipe(lnStt+10,tp,Math.min(zeroPx,lnEnd-10),tp,g.strokeStyle);} if(zeroPxlnStt?'red':'blue';g.beginPath();g.drawArrow(lt-35,tp,30,2,45,25,Math.PI);g.fill();g.fillStyle=zeroPx>lnEnd?'red':'blue';g.beginPath();g.drawArrow(lt+wd+35,tp,30,2,45,25,0);g.fill();if(currx>0&&currx0&&rel<1){xp=lt+rel*wd;g.fillText(mark[1],xp,tp-25);g.beginPath();g.moveTo(xp,tp);g.lineTo(xp,tp-20);g.stroke();g.drawArrow(xp,tp,20,2,20,10,3*Math.PI/2);g.fill();}}} function getTicks(){let majorTick=coords.xTickInterval(tickSparseness,true);let minorTick=coords.xTickInterval(tickSparseness,false);let minorTickEvery=majorTick.div(minorTick,0).getNumber();let majorNum=majorTick;let minorNum=majorNum.div(new Num(minorTickEvery.toString()),30);let curNum=coords.xStt;curNum=curNum.div(majorNum,0);curNum=curNum.sub(new Num("1"));curNum=curNum.mult(majorNum);let gap=num2pix(minorNum)-num2pix(new Num("0"));let textWd=majorNum.add(minorNum).fmt().length*9;let labelQ=(textWd0) continue;let tickPx=num2pix(tick);ticks.push([minorTickNo==0,minorTickNo,tickPx,tick.fmt(10)]);} curNum=curNum.add(majorNum);} return ticks;} function makeCursor(el,typ,clr){let div=document.createElement('canvas');let ctx=div.getContext('2d');let wd switch(typ){case 'none':break;case 'arrow':wd=24;div.width=wd;div.height=wd;ctx.strokeStyle=clr;ctx.lineWidth=5;ctx.lineCap='round';ctx.moveTo(2,wd-6);ctx.lineTo(2,2);ctx.lineTo(wd-6,2);ctx.moveTo(2,2);ctx.lineTo(wd,wd);ctx.stroke();break;case 'crosshair':wd=30;div.width=wd;div.height=wd;ctx.translate(wd/2,wd/2);div.left=(-wd/2);div.style.left=(-wd/2)+'px';ctx.strokeStyle=clr;ctx.lineWidth=1;ctx.lineCap='round';ctx.moveTo(-wd/2,0);ctx.lineTo(wd/2,0);ctx.moveTo(0,-wd/2);ctx.lineTo(0,wd/2);ctx.stroke();break;default:} el.style.cursor='url('+div.toDataURL()+'), auto';} function dist(dx,dy){return Math.sqrt(dx*dx+dy*dy);} function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1)+min);} CanvasRenderingContext2D.prototype.drawPipe=function(x0,y0,x1,y1,clr){let g=this;let alpha=[1.00,0.80,0.60,0.40,0.40,0.20,0.40,0.60,1.00];let size=alpha.length;for(let i=0;i0){temp=this.xStt;this.xStt=this.xEnd;this.xEnd=temp;} let xSpan=this.xEnd.sub(this.xStt);if(xSpan.compare(new Num("0"))<=0)xSpan.setNum("0.1");xScale=xSpan.div(new Num(this.width.toString()),10);};CoordsFull.prototype.toXVal=function(pix){return(this.xStt.add(xScale.mult(new Num(pix.toString())))).getNumber();};CoordsFull.prototype.toXNum=function(pix){return(this.xStt.add(xScale.mult(new Num(pix.toString()))));};CoordsFull.prototype.xTickInterval=function(tickSparseness,majorQ){return this.tickInterval(this.xEnd.sub(this.xStt).mult(new Num(tickSparseness.toString())),majorQ);};CoordsFull.prototype.yTickInterval=function(tickSparseness,majorQ){return this.tickInterval(this.yEnd.sub(this.yStt).mult(new Num(tickSparseness.toString())),majorQ);};CoordsFull.prototype.tickInterval=function(span,majorQ){let mantissa=span.getSci()[0];let intervals=[[7,10,1],[3,1,1],[2,1,0.5],[1,1,0.1]];let interval=null for(let i=0;i=interval[0]||i==intervals.length-1){break;}} if(majorQ){result=interval[1];}else{result=interval[2];} let num=new Num(result.toString());num=num.mult10(span.getSci()[1]+1);return num;};function Num(s,base){s=typeof s!=='undefined'?s:'';base=typeof base!=='undefined'?base:10;this.sign=1;this.digits="";this.dec=0;this.setNum(s,base);} Num.prototype.baseDigits="0123456789ABCDEFGHJKLMNP";Num.prototype.MAXDEC=20;Num.prototype.setNum=function(s,base){base=typeof base!=='undefined'?base:10;if(s==0){this.digits='0';return;} if(base==10){let digits=s;if(digits.charAt(0)=="-"){this.sign=-1;digits=digits.substring(1);}else{this.sign=1;} let eVal=0;let ePos=digits.indexOf("e");if(ePos>=0){eVal=(digits.substr(ePos+1))>>0;digits=digits.substr(0,ePos);} this.dec=digits.length-(digits.indexOf(".")+1);if(this.dec==digits.length){this.dec=0;} this.dec-=eVal;digits=digits.split(".").join("");digits=digits.replace(/^0+/,'');if(digits.length==0){this.sign=1;}else{let s1="";for(let i=0;i=0){s1+=digit;}} digits=s1;} this.digits=digits;}else{this.setFromBase(s,base);}};Num.prototype.setFromBase=function(numStr,base){let srcSign="";if(numStr.charAt(0)=="-"){srcSign="-";numStr=numStr.substring(1);} let baseDec=numStr.length-(numStr.indexOf(".")+1);if(baseDec==numStr.length){baseDec=0;} numStr=numStr.split(".").join("");numStr=numStr.replace(/^0+/,'');if(numStr.length==0){this.setNum("0");}else{let i=0;let len=numStr.length;let baseStr=base.toString();let digit=this.baseDigits.indexOf(numStr.charAt(i++).toUpperCase()).toString();let result=digit;while(i0){let divBy=this.fullPower(baseStr,baseDec);result=this.fullDivide(result,divBy,this.MAXDEC);} this.setNum(srcSign+result);}};Num.prototype.toBase=function(base,places){let parts=this.splitWholeFrac();let s=this.fullBaseWhole(parts[0],base);if(parts[1].length>0){s+="."+this.fullBaseFrac(parts[1],base,places);} if(this.sign==-1){if(s!="0"){s="-"+s;}} return s;};Num.prototype.getNumber=function(){return Number(this.fmt(10,0));};Num.prototype.mult10=function(n){let xNew=this.clone();xNew.dec=xNew.dec-n;if(xNew.dec<0){xNew.digits=xNew.digits+"0".repeat(-xNew.dec);xNew.dec=0;} return xNew;};Num.prototype.clone=function(){let ansNum=new Num();ansNum.digits=this.digits;ansNum.dec=this.dec;ansNum.sign=this.sign;return ansNum;};Num.prototype.mult=function(num){return this.multNums(this,num);};Num.prototype.fullMultiply=function(x,y){return this.multNums(new Num(x),new Num(y)).fmt();};Num.prototype.multNums=function(xNum,yNum){let N1=xNum.digits;let N2=yNum.digits;let ans="0";for(let i=N1.length-1;i>=0;i--){ans=this.fullAdd(ans,(this.fullMultiply1(N2,N1.charAt(i))+"0".repeat(N1.length-i-1)));} let ansNum=new Num(ans);ansNum.dec=xNum.dec+yNum.dec;ansNum.sign=xNum.sign*yNum.sign;return ansNum;};Num.prototype.fullMultiply1=function(x,y1){let carry="0";let ans="";for(let i=x.length-1;i>(-1);i--){let product=((x.charAt(i))>>0)*(y1>>0)+(carry>>0);let prodStr=product.toString();if(product<10){prodStr="0"+prodStr;} carry=prodStr.charAt(0);ans=prodStr.charAt(1)+ans;} if(carry!="0"){ans=carry+ans;} return ans;};Num.prototype.fullMultiplyInt=function(x,y){let xLen=x.length;let yLen=y.length;if(xLen==0)return "0";if(yLen==0)return "0";if(xLen+yLen<=9){return(parseInt(x)*parseInt(y)).toString();} let maxLen=Math.max(xLen,yLen);let split=Math.ceil(maxLen/2);if(xLen=0;i--){let temp=((xdig.charAt(i))>>0)+((ydig.charAt(i))>>0)+carry;if((temp>=0)&&(temp<20)){if(temp>9){carry=1;ans=temp-10+ans;}else{carry=0;ans=temp+ans;}}} if(carry==1){ans="1"+ans;} ansNum.setNum(ans);ansNum.sign=xNum.sign;ansNum.dec=maxdec;return ansNum;};Num.prototype.fullPower=function(x,n){return this.expNums(new Num(x),n).fmt();};Num.prototype.expNums=function(xNum,nInt){let n=nInt;let b2pow=0;while((n&1)==0){b2pow++;n>>=1;} let x=xNum.digits;let r=x;while((n>>=1)>0){x=this.fullMultiply(x,x);if((n&1)!=0){r=this.fullMultiply(r,x);}} while(b2pow-->0){r=this.fullMultiply(r,r);} let ansNum=new Num(r);ansNum.dec=xNum.dec*nInt;return ansNum;};Num.prototype.div=function(num,decimals){return this.divNums(this,num,decimals);};Num.prototype.fullDivide=function(x,y,decimals){return this.divNums(new Num(x),new Num(y),decimals).fmt();};Num.prototype.divNums=function(xNum,yNum,decimals){decimals=typeof decimals!=='undefined'?decimals:this.MAXDEC;if(xNum.digits.length==0){return new Num("0");} if(yNum.digits.length==0){return new Num("0");} let xDec=xNum.mult10(decimals);let fullDec=Math.max(xDec.dec,yNum.dec);let xdig=xDec.digits+"0".repeat(fullDec-xDec.dec);let ydig=yNum.digits+"0".repeat(fullDec-yNum.dec);xdig=xdig.replace(/^0+/,'');if(this.compareDigits(xdig,"0")==0){return new Num("0");} ydig=ydig.replace(/^0+/,'');if(this.compareDigits(ydig,"0")==0){return new Num("0");} let timestable=[];timestable.push("0");timestable.push(ydig);let tdig=ydig;for(let i=2;i<10;i++){tdig=this.fullAdd(tdig,ydig);timestable.push(tdig);} let ans="0";let xNew=xdig;let n=0;while(this.compareDigits(xNew,ydig)>=0){let col=1;while(this.compareDigits(xNew.substring(0,col),ydig)<0){col++;} let xCurr=xNew.substring(0,col);let mult=9;while(this.compareDigits(timestable[mult],xCurr)>0){mult--;} let fullmult=mult+""+"0".repeat(xNew.length-xCurr.length);ans=this.fullAdd(ans,fullmult);xNew=this.fullSubtract(xNew,this.fullMultiply(ydig,fullmult));if(n++>100){console.log("runaway code divNums");break;}} let ansNum=new Num(ans);ansNum.dec=decimals;ansNum.sign=xNum.sign*yNum.sign;return ansNum;};Num.prototype.sub=function(num){return this.subNums(this,num);};Num.prototype.fullSubtract=function(x,y){return this.subNums(new Num(x),new Num(y)).fmt();};Num.prototype.subNums=function(xNum,yNum){let ansNum=new Num();if(xNum.sign*yNum.sign==-1){ansNum=xNum.abs().add(yNum.abs());if(xNum.sign==-1){ansNum.sign*=-1;} return ansNum;} let maxdec=Math.max(xNum.dec,yNum.dec);let xdig=xNum.digits+"0".repeat(maxdec-xNum.dec);let ydig=yNum.digits+"0".repeat(maxdec-yNum.dec);let maxlen=Math.max(xdig.length,ydig.length);xdig="0".repeat(maxlen-xdig.length)+xdig;ydig="0".repeat(maxlen-ydig.length)+ydig;let sign=this.compareDigits(xdig,ydig);if(sign==0){return new Num("0");} if(sign==-1){let temp=xdig;xdig=ydig;ydig=temp;} let ans="";let isborrow=0;for(let i=xdig.length-1;i>=0;i--){let xPiece=(xdig.charAt(i))>>0;let yPiece=(ydig.charAt(i))>>0;if(isborrow==1){isborrow=0;xPiece=xPiece-1;} if(xPiece<0){xPiece=9;isborrow=1;} if(xPiecesigDigits){let cutDigit="";if(sigDigits>=0){s=this.digits.substr(0,sigDigits);cutDigit=this.digits.charAt(sigDigits);}else{s="";cutDigit="";} switch(roundType){case "5up":if(cutDigit>"5"||(cutDigit=="5"&&this.sign==1)){s=this.fullAdd(s,"1",10);} break;case "5down":if(cutDigit>"5"||(cutDigit=="5"&&this.sign==-1)){s=fullAdd(s,"1");} break;case "5away0":if(cutDigit>="5"){s=fullAdd(s,"1");} break;case "5to0":if(cutDigit>"5"){s=fullAdd(s,"1");} break;case "5even":if(cutDigit>"5"){s=fullAdd(s,"1");}else{if(cutDigit=="5"){if((parseInt(s.charAt(s.length-1))&1)!=0){s=fullAdd(s,"1");}}} break;case "5odd":if(cutDigit>"5"){s=fullAdd(s,"1");}else{if(cutDigit=="5"){if((parseInt(s.charAt(s.length-1))&1)==0){s=fullAdd(s,"1");}}} break;case "floor":if(sigDigits<0){decpos-=sigDigits;if(this.sign==-1){s="1";}else{s="";}}else{if(this.sign==-1){if(Strings.trimLeft(digits.substr(sigDigits),"0").length!=0){s=fullAdd(s,"1");}}} break;case "ceiling":if(sigDigits<0){decpos-=sigDigits;if(this.sign==1){s="1";}else{s="";}}else{if(this.sign==1){if(Strings.trimLeft(digits.substr(sigDigits),"0").length!=0){s=fullAdd(s,"1");}}} break;default:} if(s.length>sigDigits){if(sigDigits>0) s=s.substr(0,sigDigits);decpos++;} if(s.length==0){s="0";}else{if(decpos-sigDigits>0) s+="0".repeat(decpos-sigDigits);}}} let eVal=decpos-1;if(eStt>0&&Math.abs(eVal)>=eStt){let s1=s.substr(0,1)+"."+s.substr(1);s1=s1.replace(/0+$/,'');if(s1.charAt(s1.length-1)=="."){s1=s1.substr(0,s1.length-1);} if(eVal>0){s=s1+"e+"+eVal;}else{s=s1+"e"+eVal;}}else{if(decpos<0){s="0."+"0".repeat(-decpos)+s;}else if(decpos==0){s="0."+s;}else if(decpos>0){if(this.dec>=0){s=s.substr(0,decpos)+"."+s.substr(decpos,this.dec);}else{s=s+"0".repeat(-this.dec)+".";}} if(s.indexOf(".")>=0){s=s.replace(/0+$/,'');} if(s.charAt(s.length-1)=="."){s=s.substring(0,s.length-1);}} if(this.sign==-1){if(s!="0"){s="-"+s;}} this.dec=decWas;this.digits=digitsWas;return s;};Num.prototype.compare=function(yNum){return this.compareNums(this,yNum);};Num.prototype.compareNums=function(xNum,yNum){if(xNum.digits.length==0) xNum.sign=1;if(xNum.digits=="0") xNum.sign=1;if(yNum.digits.length==0) yNum.sign=1;if(yNum.digits=="0") yNum.sign=1;if(xNum.sign==1&&yNum.sign==-1){return 1;} if(xNum.sign==-1&&yNum.sign==1){return-1;} let maxdec=Math.max(xNum.dec,yNum.dec);let xdig=xNum.digits+strRepeat("0",maxdec-xNum.dec);let ydig=yNum.digits+strRepeat("0",maxdec-yNum.dec);let maxlen=Math.max(xdig.length,ydig.length);xdig=strRepeat("0",maxlen-xdig.length)+xdig;ydig=strRepeat("0",maxlen-ydig.length)+ydig;for(let i=0;iydig.charAt(i)){return 1*xNum.sign;}} return 0;};Num.prototype.compareDigits=function(x,y){if(x.length>y.length){return 1;} if(x.lengthy.charAt(i)){return 1;}} return 0;};Num.prototype.splitWholeFrac=function(){let s=this.digits;let decpos=s.length-this.dec;if(decpos<0){s="0".repeat(-decpos)+s;decpos=0;} if(this.dec<0){s=s+"0".repeat(-this.dec)+".";} let wholePart=s.substr(0,decpos);let fracPart=s.substr(decpos);if(fracPart.replace(/^0+/,'').length==0){fracPart="";}else{fracPart="0."+fracPart;} return[wholePart,fracPart];};Num.prototype.fullBaseWhole=function(d,base){let baseStr=base.toString();let dWhole=this.fullDivide(d,baseStr,0);let dRem=this.fullSubtract(d,this.fullMultiply(dWhole,baseStr));if(dWhole=="0"){return this.baseDigits.charAt(dRem>>0);}else{return this.fullBaseWhole(dWhole,base)+this.baseDigits.charAt(dRem>>0);}};Num.prototype.fullBaseFrac=function(d,base,places,level){level=typeof level!=='undefined'?level:0;let r=this.fullMultiply(d,base.toString());let parts=r.split(".");let wholePart=parts[0];if(parts.length==1||level>=places-1){return this.baseDigits.charAt(wholePart>>0);}else{let fracPart="0."+parts[1];return this.baseDigits.charAt(wholePart>>0)+this.fullBaseFrac(fracPart,base,places,level+1);}};Num.prototype.getSignStr=function(){if(this.sign==-1){return "-";}else{return "";}};Num.prototype.getWholeStr=function(){let s=this.digits;let decpos=s.length-this.dec;if(decpos<0){s="0".repeat(-decpos)+s;decpos=0;} if(this.dec<0){s=s+"0".repeat(-this.dec)+".";} return s.substr(0,decpos);};Num.prototype.getDecStr=function(){let s=this.digits;let decpos=s.length-this.dec;if(decpos<0){s="0".repeat(-decpos)+s;decpos=0;} if(this.dec<0){s=s+"0".repeat(-this.dec)+".";} return s.substr(decpos);};Num.prototype.fullProdSeq=function(n0,n1){if(n0==n1)return n1.toString();let nMid=((n1+n0)/2)<<0;return(this.fullMultiplyInt(this.fullProdSeq(n0,nMid),this.fullProdSeq(nMid+1,n1)));};Num.prototype.getSci=function(){let len=this.digits.length;let s=this.digits.substr(0,1)+"."+this.digits.substr(1);s=s.replace(/0+$/,'');if(s.charAt(s.length-1)=="."){s=s.substr(0,s.length-1);} if(this.sign==-1){s="-"+s;} return[s,len-this.dec-1];};Num.prototype.fullCombPerm=function(n,r,orderQ,replaceQ){let i=1;let s="";if(orderQ){if(replaceQ){s=this.fullPower(n.toString(),r);}else{if(r>n){s="";}else{s=this.fullProdSeq(n-r+1,n);}}}else{let tops=[];let bots=[];if(replaceQ){if(false){}else{for(i=n;i<=n+r-1;i++){tops.push(i);} for(i=2;i<=r;i++){bots.push(i);}}}else{if(r>n){s="";}else{if(rtrimToLen){let origLen=this.digits.length;this.digits=this.digits.substr(0,trimToLen);this.dec-=(origLen-this.digits.length);}};function strRepeat(chr,count){let s="";while(count>0){s+=chr;count-=1;} return s;} function Parser(){this.operators="+-*(/),^.";this.rootNode;this.tempNode=[];this.Variable="x";this.errMsg="";this.radiansQ=true;this.vals=[];for(let i=0;i<26;i++){this.vals[i]=0;} this.reset();} Parser.prototype.setVarVal=function(varName,newVal){switch(varName){case "x":this.vals[23]=newVal;break;case "y":this.vals[24]=newVal;break;case "z":this.vals[25]=newVal;break;default:if(varName.length==1){this.vals[varName.charCodeAt(0)-'a'.charCodeAt(0)]=newVal;}}};Parser.prototype.getVal=function(){return(this.rootNode.walk(this.vals));};Parser.prototype.newParse=function(s){this.reset();s=s.split(" ").join("");s=s.split("�").join("../index.html");s=s.split("[").join("(");s=s.split("]").join(")");s=s.replace(/\u2212/g,'-');s=s.replace(/\u00F7/g,'../index.html');s=s.replace(/\u00D7/g,'*');s=s.replace(/\u00B2/g,'^2');s=s.replace(/\u00B3/g,'^3');s=s.replace(/\u221a/g,'sqrt');s=this.fixParentheses(s);s=this.fixUnaryMinus(s);s=this.fixImplicitMultply(s);this.rootNode=this.parse(s);};Parser.prototype.fixParentheses=function(s){let sttParCount=0;let endParCount=0;for(let i=0;i="0"&&c<="9"){thisType="N";}else{if(this.operators.indexOf(c)>=0){if(c=="-"){thisType="-";}else{thisType="O";}}else{if(c=="."||c==this.Variable){thisType="N";}else{thisType="C";}} if(c=="("){thisType="(";} if(c==")"){thisType=")";}} x+=thisType;if(prevType=="("&&thisType=="-"){y+="0";} if(OpenQ){switch(thisType){case "N":break;default:y+=")";OpenQ=false;}} if(prevType=="O"&&thisType=="-"){y+="(0";OpenQ=true;} y+=c;prevType=thisType;} if(OpenQ){y+=")";OpenQ=false;} return(y);};Parser.prototype.fixImplicitMultply=function(s){let x=s+"\n";let y="";let prevType="?";let prevName="";let thisType="?";let thisName="";for(let i=0;i="0"&&c<="9"){thisType="N";}else{if(this.operators.indexOf(c)>=0){thisType="O";thisName="";}else{thisType="C";thisName+=c;} if(c=="("){thisType="(";} if(c==")"){thisType=")";}} x+=thisType;if(prevType=="N"&&thisType=="C"){y+="*";thisName="";} if(prevType=="N"&&thisType=="("){y+="*";} if(prevType==")"&&thisType=="("){y+="*";} if(thisType=="("){switch(prevName){case "i":case "pi":case "e":case "a":case this.Variable:y+="*";break;}} y+=c;prevType=thisType;prevName=thisName;} return(y);};Parser.prototype.reset=function(){this.tempNode=[];this.errMsg="";};Parser.prototype.parse=function(s){if(s==""){return new MathNode("real","0",this.radiansQ);} if(isNumeric(s)){return new MathNode("real",s,this.radiansQ);} if(s.charAt(0)=="$"){if(isNumeric(s.substr(1))){return this.tempNode[Number(s.substr(1))];}} let sLo=s.toLowerCase();if(sLo.length==1){if(sLo>="a"&&sLo<="z"){return new MathNode("var",sLo,this.radiansQ);}} switch(sLo){case "pi":return new MathNode("var",sLo,this.radiansQ);} let bracStt=s.lastIndexOf("(");if(bracStt>-1){let bracEnd=s.indexOf(")",bracStt);if(bracEnd<0){this.errMsg+="Missing ')'\n";return new MathNode("real","0",this.radiansQ);} let isParam=false;if(bracStt==0){isParam=false;}else{let prefix=s.substr(bracStt-1,1);isParam=this.operators.indexOf(prefix)<=-1;} if(!isParam){this.tempNode.push(this.parse(s.substr(bracStt+1,bracEnd-bracStt-1)));return this.parse(s.substr(0,bracStt)+"$"+(this.tempNode.length-1).toString()+s.substr(bracEnd+1,s.length-bracEnd-1));}else{let startM=-1;for(let u=bracStt-1;u>-1;u--){let found=this.operators.indexOf(s.substr(u,1));if(found>-1){startM=u;break;}} nnew=new MathNode("func",s.substr(startM+1,bracStt-1-startM),this.radiansQ);nnew.addchild(this.parse(s.substr(bracStt+1,bracEnd-bracStt-1)));this.tempNode.push(nnew);return this.parse(s.substr(0,startM+1)+"$"+(this.tempNode.length-1).toString()+s.substr(bracEnd+1,s.length-bracEnd-1));}} let k;let k1=s.lastIndexOf("+");let k2=s.lastIndexOf("-");if(k1>-1||k2>-1){if(k1>k2){k=k1;let nnew=new MathNode("op","add",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;}else{k=k2;nnew=new MathNode("op","sub",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;}} k1=s.lastIndexOf("*");k2=s.lastIndexOf("../index.html");if(k1>-1||k2>-1){if(k1>k2){k=k1;nnew=new MathNode("op","mult",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;}else{k=k2;nnew=new MathNode("op","div",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;}} k=s.indexOf("^");if(k>-1){nnew=new MathNode("op","pow",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;} if(isNumeric(s)){return new MathNode("real",s,this.radiansQ);}else{if(s.length==0){return new MathNode("real","0",this.radiansQ);}else{this.errMsg+="'"+s+"' is not a number.\n";return new MathNode("real","0",this.radiansQ);}}};function MathNode(typ,val,radQ){this.tREAL=0;this.tVAR=1;this.tOP=2;this.tFUNC=3;this.radiansQ=true;this.setNew(typ,val,radQ);} MathNode.prototype.setNew=function(typ,val,radQ){this.radiansQ=typeof radQ!=='undefined'?radQ:true;this.clear();switch(typ){case "real":this.typ=this.tREAL;this.r=Number(val);break;case "var":this.typ=this.tVAR;this.v=val;break;case "op":this.typ=this.tOP;this.op=val;break;case "func":this.typ=this.tFUNC;this.op=val;break;} return(this);};MathNode.prototype.clear=function(){this.r=1;this.v="";this.op="";this.child=[];this.childCount=0;};MathNode.prototype.addchild=function(n){this.child.push(n);this.childCount++;return(this.child[this.child.length-1]);};MathNode.prototype.getLevelsHigh=function(){let lvl=0;for(let i=0;i0){let parq=false;if(this.op=="add")parq=true;if(this.op=="sub")parq=true;if(prevop=="div")parq=true;if(noparq)parq=false;if(this.typ==this.tFUNC)parq=true;if(this.typ==this.tOP){}else{s+=this.fmt(true);} if(parq)s+="(";for(let i=0;i0)s+=this.fmt();s+=this.child[i].walkFmta(false,this.op);if(this.typ==this.tFUNC||(parq&&i>0)){s+=")";}}}else{s+=this.fmt();if(prevop=="sin"||prevop=="cos"||prevop=="tan"){if(this.radiansQ){s+=" rad";}else{s+="°";}}} return s;};MathNode.prototype.walkNodesFmt=function(level){let s="";for(let i=0;i2){f*=i;} return f;} function isNumeric(n){return!isNaN(parseFloat(n))&&isFinite(n);} function num2pix(num){return(num.sub(coords.xStt).getNumber()/coords.xEnd.sub(coords.xStt).getNumber()*coords.width);} function pix2num(pix){return(coords.xStt.getNumber()+pix/coords.width*(coords.xEnd.getNumber()-coords.xStt.getNumber()));} function hex2rgba(hex,opacity){hex=hex.replace('#','');let r=parseInt(hex.substring(0,2),16);let g=parseInt(hex.substring(2,4),16);let b=parseInt(hex.substring(4,6),16);result='rgba('+r+','+g+','+b+','+opacity+')';return result;} function fmtDec(v,dec,dropZerosQ){dropZerosQ=typeof dropZerosQ!=='undefined'?dropZerosQ:false;let s=(v/Math.pow(10,dec)).toFixed(dec);if(dropZerosQ){if(s.indexOf(".")>=0){s=s.replace(/0+$/,'');} if(s.charAt(s.length-1)=="."){s=s.substring(0,s.length-1);}} return s;} function addZeros(num,digits){let counter=0;let temp="";do{temp+="0";counter++;}while(counter