.9&&(t++,a=" (+1 choice)"),0===_d?(e++,t++,l=" (+1 upgrade and choice)"):_d<=3&&(t++,l=" (+1 choice)");e--;){let _=function(_){let e=_w().map(_=>({..._,score:Math.random()+(_z[_.id]||0)})).sort((_,e)=>_.score-e.score).filter(_=>A[_.id]<_.max).slice(0,_).sort((_,e)=>_.id>e.id?1:-1);return e.forEach(_=>{_x(_.id)}),e.map(_=>({text:_.name+(A[_.id]?" lvl "+(A[_.id]+1):""),icon:W["icon:"+_.id],value:_.id,help:_.help(A[_.id]+1)}))}(t+A.one_more_choice-A.instant_upgrade);if(!_.length)break;let o=`
You just finished level ${G+1}/${_F()} and picked those upgrades so far :
${_p()}
`,s=await e_({title:"Pick an upgrade "+(e?"("+(e+1)+")":""),actions:_,text:`
You caught ${_a-_g} coins ${a} out of ${_u} in ${Math.round(_5/1e3)} seconds${r}.
You missed ${_d} times ${l}.
${r&&a&&l&&"Impressive, keep it up !"||(r||a||l)&&"Well done !"||"Try to catch all coins, never miss the bricks or clear the level under 30s to gain additional choices and upgrades."}
`,allowClose:!1,textAfterButtons:o});A[s]++,"instant_upgrade"===s&&(e+=2),_V.upgrades_picked++}P(void 0,void 0),_n()}function _W(_){Z(!1),_>0&&_v().then(),G=_,_6=0,_E=_5=0,_g=_a,_u=0,_d=0,_V.levelsPlayed++,P(void 0,void 0),Q(),_n();let t=_k();t.size!==E&&(E=t.size,X()),_y=[],_m=[...t.bricks],_b=[],J.src="data:image/svg+xml;UTF8,"+t.svg,en(),function(){if(!et("record"))return;!o&&(s=(o=document.createElement("canvas")).getContext("2d",{antialias:!1,alpha:!1}),l=(a=o.captureStream(0)).getVideoTracks()[0],et("sound")&&_3()&&e&&a.addTrack(e.stream.getAudioTracks()[0])),o.width=N,o.height=j;let _=[],t=new MediaRecorder(a,{videoBitsPerSecond:35e5});r=t,t.start(),r.pause(),t.ondataavailable=function(e){_.push(e.data)},t.onstop=async function(){let e;let t=new Blob(_,{type:"video/webm"});if(t.size<2e5)return;for(;!(e=document.getElementById("level-recording-container"));)await new Promise(_=>setTimeout(_,200));let r=document.createElement("video");r.autoplay=!0,r.controls=!1,r.disablePictureInPicture=!0,r.disableRemotePlayback=!0,r.width=o.width,r.height=o.height,r.loop=!0,r.muted=!0,r.playsInline=!0,r.src=URL.createObjectURL(t);let a=document.createElement("a");a.download=function(_="webm"){return"breakout-71-capture-"+new Date().toISOString().replace(/[^0-9\-]+/gi,"-")+"."+_}("webm"),a.target="_blank",a.href=r.src,a.textContent=`Download video (${(t.size/1e6).toFixed(2)}MB)`,e.appendChild(r),e.appendChild(a)}}()}function _k(){return B[G%B.length]}let _f=_q();function _w(){return f.filter(_=>_f>=_.threshold).filter(_=>!_?.requires||A[_?.requires])}let _z={};function _x(_){_z[_]=Math.round(Date.now()/1e3)}let _M={},_S=!1,_B=0;function _G(_){for(let _ of(_f=_q(),!function(_=null){let e=_M?.level,t=_M?.level?k.filter(_=>_.name===e):[],r=k.filter(_=>_f>=_.threshold).filter(_=>_.name!==_M?.level).filter(e=>e.name!==_||1===k.length).sort(()=>Math.random()-.5);B=t.concat(r.slice(0,10).sort((_,e)=>_.sortKey-e.sortKey))}(_5||_a?_k().name:null),_V=_$(),_a=0,_B=0,f))A[_.id]=0;if(_)Object.assign(A,_),_S=!0;else{_S=!1;let _=_w().filter(_=>_.giftable),e=_M?.perk||et("easy")&&"slow_down"||_[Math.floor(Math.random()*_.length)].id;A[e]=1,delete _M.perk,_x(e)}_W(0),ec()}let _R=0;function _L(_){Y=!0,($=_)F+N-L/2&&($=F+N-L/2),H||_5||_h()}z.addEventListener("mouseup",_=>{0===_.button&&(H?Z(!0):(q(),et("pointerLock")&&z.requestPointerLock()))}),z.addEventListener("mousemove",_=>{document.pointerLockElement===z?_L($+_.movementX):_L(_.x)}),z.addEventListener("touchstart",_=>{_.preventDefault(),_.touches?.length&&(_L(_.touches[0].pageX),q())}),z.addEventListener("touchend",_=>{_.preventDefault(),Z(!0)}),z.addEventListener("touchcancel",_=>{_.preventDefault(),Z(!0),Y=!0}),z.addEventListener("touchmove",_=>{_.touches?.length&&_L(_.touches[0].pageX)});let _A=performance.now();function _C(_,e){return _t(Math.floor(e/U),Math.floor((_-I)/U))}function _O(_){if(_m[_])return _}function _T(_,e,t){return _O(_C(_-t,e-t))??_O(_C(_+t,e-t))??_O(_C(_+t,e+t))??_O(_C(_-t,e+t))}function _P(_,e,t){if(_.destroyed)return;_.previousx=_.x,_.previousy=_.y,_.x+=_.vx*t,_.y+=_.vy*t,_.sx||=0,_.sy||=0,_.sx+=_.previousx-_.x,_.sy+=_.previousy-_.y,_.sx*=.9,_.sy*=.9,A.wind&&(_.vx+=($-(I+D/2))/D*A.wind*.5);let r=0,a=0;return _.xz.width-F-e&&(_.x=z.width-F-e,_.vx*=-1,a=1),a+2*r}let _E=0;function _H(_){return A.telekinesis&&!_.hitSinceBounce&&_.vy<0}const _$=()=>({started:Date.now(),levelsPlayed:0,runTime:0,coins_spawned:0,score:0,bricks_broken:0,misses:0,balls_lost:0,puck_bounces:0,upgrades_picked:1,max_combo:1,max_level:0});let _V=_$();function _q(){try{return JSON.parse(localStorage.getItem("breakout_71_total_score")||"0")}catch(_){return 0}}function _Z(_,e){let t;if(!H)return;Z(!0),en(),function(_){try{localStorage.setItem("breakout_71_total_play_time",JSON.stringify(JSON.parse(localStorage.getItem("breakout_71_total_play_time")||"0")+_))}catch(_){}}(_V.runTime),_V.max_level=G+1;let r=-300,a=()=>"animation-delay:"+(r+=800)+"ms;",l="",o=_q(),s=o-_a,i=(t=[],f.forEach(_=>{_.threshold&&t.push({threshold:_.threshold,title:_.name+" (Perk)"})}),k.forEach(_=>{t.push({threshold:_.threshold,title:_.name+" (Level)"})}),t.filter(_=>_.threshold).sort((_,e)=>_.threshold-e.threshold));i.filter(_=>_.threshold>s&&_.threshold{l+=`
${_.title}
`});let c=function(_,e){let t=_.length;for(;--t;)if(e(_[t],t,_))return _[t]}(i,_=>_.threshold<=o)?.threshold||0,n=i.find(_=>_.threshold>o);if(n){let _=n?.threshold-c;e+=`Score ${n.threshold-o} more points to reach the next unlock.`;let t=((o-c)/_).toFixed(2);l+=`
${n.title}
`,i.slice(i.indexOf(n)+1).slice(0,3).forEach(_=>{l+=`
${_.title}
`})}O=1,e_({allowClose:!0,title:_,text:`
${_S?"This test run and its score are not being recorded
":""}
${e}
${l}
`,actions:[{value:null,text:"Start a new run",help:""}],textAfterButtons:`
${function(){let _="";try{let e=JSON.parse(localStorage.getItem("breakout_71_runs_history")||"[]");e.sort((_,e)=>_.score-e.score).reverse(),(e=e.slice(0,100)).push({..._V,perks:A,appVersion:g}),_S||localStorage.setItem("breakout_71_runs_history",JSON.stringify(e,null,2));let t=(_,t,r)=>{let a=e.map(_=>t(_)||0),l=Math.min(...a),o=Math.max(...a);if(l===o)return"";o-l<10&&(l=Math.max(0,o-10),o=Math.max(o,l+10));let s=Math.min(a.length,10);if(s<3)return"";let i=[],c=[];for(let _=0;_Math.min(i.length-1,Math.floor((_-l)/n));if(a.forEach(_=>{if(isNaN(_))return;let e=h(_);i[e]++,c[e]+=_}),i.filter(_=>_).length<3)return"";let m=Math.max(...i),b=a[a.length-1],y=h(b),g=i.map((_,e)=>{let t=`height: ${_/m*80}px`;return`${!_&&" "||e==y&&b+r||Math.round(c[e]/_)+r}`}).join("");return`${_} : ${b}${r}
${g}
`};_+=t("Total score",_=>_.score,""),_+=t("Catch rate",_=>Math.round(_.score/_.coins_spawned*100),"%"),_+=t("Bricks broken",_=>_.bricks_broken,""),_+=t("Bricks broken per minute",_=>Math.round(_.bricks_broken/_.runTime*6e4)," bpm"),_+=t("Hit rate",_=>Math.round((1-_.misses/_.puck_bounces)*100),"%"),_+=t("Duration per level",_=>Math.round(_.runTime/1e3/_.levelsPlayed),"s"),_+=t("Level reached",_=>_.levelsPlayed,""),_+=t("Upgrades applied",_=>_.upgrades_picked,""),_+=t("Balls lost",_=>_.balls_lost,""),_+=t("Average combo",_=>Math.round(_.coins_spawned/_.bricks_broken),""),(_+=t("Max combo",_=>_.max_combo,""))&&(_=`Find below your run statistics compared to your ${e.length-1} best runs.
`+_)}catch(_){console.warn(_)}return _}()}
`}).then(()=>_G())}function _I(_,e,t){let r=_m[_];if(r){if("black"===r){delete _m[_];let t=__(_),r=_e(_);_0.explode(e.x);let a=_%E,l=Math.floor(_/E),o=1+A.bigger_explosions;for(let _=-o;_<=o;_++)for(let t=-o;t<=o;t++){let r=_t(l+t,a+_);_m[r]&&-1!==r&&_I(r,e,!0)}_y.forEach(_=>{let e=_.x-t,a=_.y-r,l=Math.max(U,Math.abs(e)+Math.abs(a));_.vx+=e/l*10*o/_.weight,_.vy+=a/l*10*o/_.weight}),_l=Date.now(),_b.push({type:"ball",duration:150,time:_5,size:2*U,color:"white",x:t,y:r}),_r(7*(1+A.bigger_explosions),t,r,"white",150,S),e.hitSinceBounce++,_V.bricks_broken++}else if(r){if(e.hitSinceBounce++,A.sturdy_bricks&&A.sturdy_bricks>5*Math.random()){_0.coinBounce(e.x,1);return}let a=__(_),l=_e(_);_m[_]="";let o=O;A.sturdy_bricks&&(o+=Math.ceil((10+A.sturdy_bricks)/10*o)),_u+=o,_V.coins_spawned+=o,_V.bricks_broken++;let s=400*(et("basic")?.5:1),i=Math.max(1,Math.ceil(o/(_y.length>400?1:Math.floor(s-_y.length)/3)));for(;o>0;){let _=Math.min(i,o);(_<0||isNaN(_))&&console.error({points:_}),o-=_;let t=a+(Math.random()-.5)*(U-S),s=l+(Math.random()-.5)*(U-S);_y.push({points:_,color:A.metamorphosis?r:"gold",x:t,y:s,previousx:t,previousy:s,vx:e.previousvx*(.5+Math.random()),vy:e.previousvy*(.5+Math.random()),sx:0,sy:0,a:Math.random()*Math.PI*2,sa:Math.random()-.5,weight:.8+.2*Math.random()})}O+=Math.max(0,A.streak_shots+A.compound_interest+A.left_is_lava+A.right_is_lava+A.top_is_lava+A.picky_eater-Math.round(Math.random()*A.soft_reset)),t||((A.picky_eater||A.pierce_color)&&r!==_c&&r?(A.picky_eater&&P(e.x,e.y),_c=r):_0.comboIncreaseMaybe(e.x,1)),_b.push({type:"ball",duration:40,time:_5,size:U,color:r,x:a,y:l}),_r(5+Math.min(O,30),a,l,r,150,S/2)}_m[_]||"black"===r||e.hitItem?.push({index:_,color:r})}}function _F(){return 7+A.extra_levels}let _D=document.createElement("canvas"),_N=null,_j={};function _U(_,e,t,r,a=0){let l="puck"+e+"_"+t+"_"+r;if(!_j[l]){let _=document.createElement("canvas");_.width=t,_.height=2*r;let a=_.getContext("2d");a.fillStyle=e,a.beginPath(),a.moveTo(0,2*r),a.lineTo(0,1.25*r),a.bezierCurveTo(0,.75*r,t,.75*r,t,1.25*r),a.lineTo(t,2*r),a.fill(),_j[l]=_}_.drawImage(_j[l],Math.round($-t/2),j-2*r+a)}function _Y(_,e,t,r,a,l=""){let o="ball"+e+"_"+t+"_"+l,s=Math.round(t);if(!_j[o]){let _=document.createElement("canvas");_.width=s,_.height=s;let t=_.getContext("2d");t.beginPath(),t.arc(s/2,s/2,Math.round(s/2)-1,0,2*Math.PI),t.fillStyle=e,t.fill(),l&&(t.lineWidth=2,t.strokeStyle=l,t.stroke()),_j[o]=_}_.drawImage(_j[o],Math.round(r-s/2),Math.round(a-s/2))}function _J(_,e,t,r,a,l,o){let s=(Math.round(o/Math.PI*64)%32+32)%32,i="coin with halo_"+e+"_"+t+"_"+l+"_"+("gold"===e?s:"whatever");if(!_j[i]){let _=document.createElement("canvas");_.width=t,_.height=t;let r=_.getContext("2d");r.beginPath(),r.arc(t/2,t/2,t/2,0,2*Math.PI),r.fillStyle=e,r.fill(),"gold"===e&&(r.strokeStyle=l,r.stroke(),r.beginPath(),r.arc(t/2,t/2,t/2*.6,0,2*Math.PI),r.fillStyle="rgba(255,255,255,0.5)",r.fill(),r.translate(t/2,t/2),r.rotate(s/16),r.translate(-t/2,-t/2),r.globalCompositeOperation="multiply",_X(r,"$",e,t-2,t/2,t/2+1),_X(r,"$",e,t-2,t/2,t/2+1)),_j[i]=_}_.drawImage(_j[i],Math.round(r-t/2),Math.round(a-t/2))}function _K(_,e,t,r,a){let l="fuzzy-circle"+e+"_"+t,o=Math.round(3*t);if(!_j[l]){let _=document.createElement("canvas");_.width=o,_.height=o;let t=_.getContext("2d"),r=t.createRadialGradient(o/2,o/2,0,o/2,o/2,o/2);r.addColorStop(0,e),r.addColorStop(1,"transparent"),t.fillStyle=r,t.fillRect(0,0,o,o),_j[l]=_}_.drawImage(_j[l],Math.round(r-o/2),Math.round(a-o/2))}function _X(_,e,t,r,a,l,o=!1){let s="text"+e+"_"+t+"_"+r+"_"+o;if(!_j[s]){let _=document.createElement("canvas");_.width=r*e.length,_.height=r;let a=_.getContext("2d");a.fillStyle=t,a.textAlign=o?"left":"center",a.textBaseline="middle",a.font=r+"px monospace",a.fillText(e,o?0:_.width/2,_.height/2,_.width),_j[s]=_}_.drawImage(_j[s],o?a:Math.round(a-_j[s].width/2),Math.round(l-_j[s].height/2))}let _Q=NaN,_1=6;function _2(_,e,t){(_1+=_)>11&&(_1=0),_1<0&&(_1=11);let r=_=>{let r=392*Math.pow(1.05945594920268,_),a=Math.abs(_-5.5),l=Math.max(0,t*(1-a/16.5));return _4(r,e,l),r.toFixed(2)+" at "+Math.floor(100*l)+"% diff "+a};r(12+_1),r(_1),r(-12+_1)}const _0={wallBeep:_=>{et("sound")&&_4(800,(_-I)/D)},comboIncreaseMaybe:(_,e)=>{if(!et("sound"))return;let t=0;!isNaN(_Q)&&(_QO&&(t=-1)),_2(t,(_-I)/D,e),_Q=O},comboDecrease(){et("sound")&&_2(-1,.5,.5)},coinBounce:(_,e)=>{et("sound")&&_4(1200,(_-I)/D,e,.1,"triangle")},explode:_=>{et("sound")&&!function(_=.5){let r=_3();if(!t){let _=2*r.sampleRate,e=(t=r.createBuffer(1,_,r.sampleRate)).getChannelData(0);for(let t=0;t<_;t++)e[t]=2*Math.random()-1}let a=r.createBufferSource();a.buffer=t;let l=r.createGain();a.connect(l);let o=r.createBiquadFilter();o.type="lowpass",o.frequency.setValueAtTime(1e3,r.currentTime),l.connect(o);let s=r.createStereoPanner();s.pan.setValueAtTime(2*_-1,r.currentTime),o.connect(s),s.connect(r.destination),s.connect(e),l.gain.setValueAtTime(1,r.currentTime),l.gain.exponentialRampToValueAtTime(.01,r.currentTime+1),o.frequency.exponentialRampToValueAtTime(60,r.currentTime+1),a.start(r.currentTime),a.stop(r.currentTime+1)}((_-I)/D)},revive:()=>{et("sound")&&function(_=440){let t=_3(),r=[t.createOscillator(),t.createOscillator(),t.createOscillator()];r.forEach((e,r)=>{e.type="sine",e.frequency.setValueAtTime(_+2*r,t.currentTime)});let a=t.createGain();r.forEach(_=>_.connect(a));let l=t.createStereoPanner();l.pan.setValueAtTime(0,t.currentTime),a.connect(l),l.connect(t.destination),l.connect(e),a.gain.setValueAtTime(0,t.currentTime),a.gain.linearRampToValueAtTime(.5,t.currentTime+.5),a.gain.exponentialRampToValueAtTime(.001,t.currentTime+2),r.forEach(_=>_.start(t.currentTime)),r.forEach(_=>_.stop(t.currentTime+2))}(500)},coinCatch(_){et("sound")&&_4(900,(_-I)/D,.8,.1,"triangle")}};function _3(){return _||(e=(_=new(window.AudioContext||window.webkitAudioContext)).createMediaStreamDestination()),_}function _4(_=800,t=.5,r=1,a=.1,l="sine"){let o=_3(),s=o.createOscillator();s.type=l,s.frequency.setValueAtTime(_,o.currentTime);let i=o.createGain();s.connect(i);let c=o.createStereoPanner();c.pan.setValueAtTime(2*t-1,o.currentTime),i.connect(c),c.connect(o.destination),c.connect(e),i.gain.setValueAtTime(.8*r,o.currentTime),i.gain.exponentialRampToValueAtTime(.001,o.currentTime+a),s.start(o.currentTime),s.stop(o.currentTime+a)}let _5=0,_6=0;window.addEventListener("visibilitychange",()=>{document.hidden&&Z(!0)});const _7=document.getElementById("score");let _8=0,_9=null;function e_({title:_,text:e,actions:t,allowClose:r=!0,textAfterButtons:a="",actionsAsGrid:l=!1}){return _8++,new Promise(o=>{let s=document.createElement("div");function i(_){o(_),setTimeout(()=>{document.body.removeChild(s)})}if(document.body.appendChild(s),s.className="popup "+(l?"actionsAsGrid ":""),r){let _=document.createElement("button");_.title="close",_.className="close-modale",_.addEventListener("click",_=>{_.preventDefault(),i(null)}),_9=()=>{i(null)},s.appendChild(_)}let c=document.createElement("div");if(_){let e=document.createElement("h2");e.innerHTML=_,c.appendChild(e)}if(e){let _=document.createElement("div");_.innerHTML=e,c.appendChild(_)}let n=document.createElement("section");if(c.appendChild(n),t.filter(_=>_).forEach(({text:_,value:e,help:t,disabled:r,className:a="",icon:l=""})=>{let o=document.createElement("button");o.innerHTML=`
${l}
${_}
${t||""}
`,r?o.setAttribute("disabled","disabled"):o.addEventListener("click",_=>{_.preventDefault(),i(e)}),o.className=a,n.appendChild(o)}),a){let _=document.createElement("div");_.className="textAfterButtons",_.innerHTML=a,c.appendChild(_)}s.appendChild(c),c.querySelector("button:not([disabled])")?.focus()}).then(_=>(_8--,_9=null,_),()=>{_9=null,_8--})}let ee={};function et(_){if(void 0===ee[_])try{ee[_]=JSON.parse(localStorage.getItem("breakout-settings-enable-"+_))}catch(_){console.warn(_)}return ee[_]??w[_]?.default??!1}async function er(){Z(!0);let _=await e_({title:` ${_a} points at level ${G+1} / ${_F()}`,text:`
${_S?"This is a test run, score is not recorded permanently
":""}
Upgrades picked so far :
${_p()}
`,allowClose:!0,actions:[{text:"Resume",help:"Return to your run",value:()=>{}},{text:"Restart",help:"Start a brand new run.",value:()=>{_G()}}]});_&&_()}async function ea(){Z(!0);let _=[];for(let e in w)w[e]&&_.push({disabled:w[e].disabled(),icon:et(e)?W["icon:checkmark_checked"]:W["icon:checkmark_unchecked"],text:w[e].name,help:w[e].help,value:()=>{!function(_){ee[_]=!et(_);try{localStorage.setItem("breakout-settings-enable-"+_,JSON.stringify(ee[_]))}catch(_){console.warn(_)}w[_].afterChange&&w[_].afterChange()}(e),ea()}});let e=Math.max(...f.map(_=>_.threshold)),t=await e_({title:"Breakout 71",text:`
`,allowClose:!0,actions:[{text:"Resume",help:"Return to your run",value(){}},{text:"Starting perk",help:"Try perks and levels you unlocked",value(){el()}},..._,(document.fullscreenEnabled||document.webkitFullscreenEnabled)&&(null!==document.fullscreenElement?{text:"Exit Fullscreen",icon:W["icon:exit_fullscreen"],help:"Might not work on some machines",value(){eh()}}:{icon:W["icon:fullscreen"],text:"Fullscreen",help:"Might not work on some machines",value(){eh()}}),{text:"Creative mode",help:_q()({icon:e.icon,text:e.name,help:(_[e.id]||0)+"/"+e.max,value:e,className:_[e.id]?"":"grey-out-unless-hovered"})),{text:"Start run",value:"start"}]});){if("start"===e){_G(_);break}e&&(_[e.id]=((_[e.id]||0)+1)%(e.max+1))}}},{text:"Reset Game",help:"Erase high score and statistics",async value(){await e_({title:"Reset",actions:[{text:"Yes",value:!0},{text:"No",value:!1}],allowClose:!0})&&(localStorage.clear(),window.location.reload())}}],textAfterButtons:`
Made in France by Renan LE CARO.
Privacy Policy
F-Droid
Google Play
itch.io
Gitlab
Web version
HackerNews
v.${g}
`});t&&t()}async function el(){let _=_q(),e=[...f.sort((_,e)=>_.threshold-e.threshold).map(({name:e,id:t,threshold:r,icon:a,fullHelp:l})=>({text:e,help:_>=r?l:`Unlocks at total score ${r}.`,disabled:__.threshold-e.threshold).map(e=>{let t=_>=e.threshold;return{text:e.name,help:t?`A ${e.size}x${e.size} level with ${e.bricks.filter(_=>_).length} bricks`:`Unlocks at total score ${e.threshold}.`,disabled:!t,value:{level:e.name},icon:W[e.name]}})],t=Math.round(e.filter(_=>!_.disabled).length/e.length*100),r=await e_({title:`You unlocked ${t}% of the game.`,text:`
Your total score is ${_}. Below are all the upgrades and levels the games has to offer.
${t<100?"The greyed out ones can be unlocked by increasing your total score. The total score increases every time you score in game.":""}
`,textAfterButtons:`
Your high score is ${_o}.
Click an item above to start a run with it.
`,actions:e,allowClose:!0});r&&(!G||await e_({title:"Restart run to try this item?",text:"You're about to start a new run with the selected unlocked item, is that really what you wanted ? ",actions:[{value:!0,text:"Restart game to test item"},{value:!1,text:"Cancel"}]}))&&(_M=r,_G())}function eo(_,e){return Math.sqrt(Math.pow(_.x-e.x,2)+Math.pow(_.y-e.y,2))}function es(){return`hsl(${2*Math.round(_5/4)%360},100%,70%)`}function ei(_,e,t,r){let a=eo(_,e),l=D/2;if(a>l)return;let o=(_.x-e.x)/a,s=(_.y-e.y)/a,i=-t*(l-a)/(1.2*l)/3*Math.min(500,_5)/500;r&&(e.vx+=o*i,e.vy+=s*i),_.vx-=o*i,_.vy-=s*i,_b.push({type:"particle",duration:100,time:_5,size:S/2,color:es(),ethereal:!0,x:_.x,y:_.y,vx:-(10*o)+_.vx+(Math.random()-.5)*2,vy:-(10*s)+_.vy+(Math.random()-.5)*2}),r&&_b.push({type:"particle",duration:100,time:_5,size:S/2,color:es(),ethereal:!0,x:e.x,y:e.y,vx:10*o+e.vx+(Math.random()-.5)*2,vy:10*s+e.vy+(Math.random()-.5)*2})}function ec(){et("record")&&r?.state==="recording"&&r?.pause()}function en(){et("record")&&r&&(r?.stop(),r=null)}function eh(){try{if(null!==document.fullscreenElement)document.exitFullscreen?document.exitFullscreen().then():document.webkitCancelFullScreen&&document.webkitCancelFullScreen();else{let _=document.documentElement;_.requestFullscreen?_.requestFullscreen().then():_.webkitRequestFullscreen&&_.webkitRequestFullscreen()}}catch(_){console.warn(_)}}_7.addEventListener("click",_=>{_.preventDefault(),er().then()}),document.getElementById("menu").addEventListener("click",_=>{_.preventDefault(),ea().then()});const em={ArrowLeft:0,ArrowRight:0,Shift:0};function eb(_,e){em[_]=e,_R=(em.ArrowRight-em.ArrowLeft)*(1+2*em.Shift)*D/50}document.addEventListener("keydown",_=>{"f"!==_.key.toLowerCase()||_.ctrlKey||_.metaKey?_.key in em&&eb(_.key,1):eh()," "===_.key&&!_8&&(H?Z(!0):q(),_.preventDefault())}),document.addEventListener("keyup",_=>{let e=document.querySelector("button:focus");if(_.key in em)eb(_.key,0);else if("ArrowDown"===_.key&&e?.nextElementSibling?.tagName==="BUTTON")e?.nextElementSibling?.focus();else if("ArrowUp"===_.key&&e?.previousElementSibling?.tagName==="BUTTON")e?.previousElementSibling?.focus();else if("Escape"===_.key&&_9)_9();else if("Escape"===_.key&&H)Z(!0);else if("m"!==_.key.toLowerCase()||_8){if("s"!==_.key.toLowerCase()||_8)return;er().then()}else ea().then();_.preventDefault()}),X(),_G(),function _(){Q();let e=performance.now();if(L=D/12*(3-A.smaller_puck+A.bigger_puck),_R&&_L($+_R),H){_5+=e-_A,_V.runTime+=e-_A,_V.max_combo=Math.max(_V.max_combo,O);let _=Math.min(4,(e-_A)/(1e3/60));_*=+!!H,_y=_y.filter(_=>!_.destroyed),_i=_i.filter(_=>!_.destroyed);let t=_m.filter(_=>_&&"black"!==_).length;if(_5>_E+1e3&&A.hot_start&&(_E=_5,function(_,e,t){let r=Math.max(0,O-(O=Math.max(T(),O-_)));r&&(_0.comboDecrease(),void 0!==e&&void 0!==t&&_b.push({type:"text",text:"-"+r,time:_5,color:"red",x:e,y:t,duration:300,size:20}))}(A.hot_start,$,j-40)),t<=A.skip_last&&!_6&&(_m.forEach((_,e)=>{_&&_I(e,_i[0],!0)}),_6++),t||_y.length){if(H||_5){let e=!1,t=Math.round(S/2);if(_y.forEach(r=>{if(r.destroyed)return;A.coin_magnet&&(r.vx+=_*($-r.x)/(100+Math.pow(r.y-j,2)+Math.pow(r.x-$,2))*A.coin_magnet*100);let a=1-(.03*A.viscosity+.005)*_;r.vy*=a,r.vx*=a,r.vx>7*C&&(r.vx=7*C),r.vx<-7*C&&(r.vx=-7*C),r.vy>7*C&&(r.vy=7*C),r.vy<-7*C&&(r.vy=-7*C),r.a+=r.sa,r.vy+=_*r.weight*.8;let l=Math.abs(r.sx)+Math.abs(r.sx),o=_P(r,t,_);if(r.y>j-t-20&&r.y_o&&!_S&&(_o=_a,localStorage.setItem("breakout-3-hs",_a.toString())),et("basic")||_b.push({type:"particle",duration:100+50*Math.random(),time:_5,size:S/2,color:r.color,x:r.previousx,y:r.previousy,vx:(z.width-r.x)/100,vy:-r.y/100,ethereal:!0}),Date.now()-_s>16&&(_s=Date.now(),_0.coinCatch(r.x)),_V.score+=r.points;else r.y>z.height+t&&(r.destroyed=!0,A.compound_interest&&P(r.x,r.y));let s=function(_){let e=S/2,{x:t,y:r,previousx:a,previousy:l}=_,o=_T(a,r,e),s=_T(t,l,e),i=void 0===o&&void 0===s&&_T(t,r,e)||void 0;if(void 0!==o||void 0!==i){_.y=_.previousy,_.vy*=-1;let a=_m[_C(t-e,r+e)],l=_m[_C(t+e,r+e)];a&&!l&&(_.vx+=1,_.sa-=1),!a&&l&&(_.vx-=1,_.sa+=1)}return(void 0!==s||void 0!==i)&&(_.x=_.previousx,_.vx*=-1),o??s??i}(r);A.metamorphosis&&void 0!==s&&_m[s]&&r.color!==_m[s]&&"black"!==_m[s]&&!r.coloredABrick&&(_m[s]=r.color,r.coloredABrick=!0),(void 0!==s||o)&&(r.vx*=.8,r.vy*=.8,r.sa*=.9,l>20&&!e&&(e=!0,_0.coinBounce(r.x,.2)),3>Math.abs(r.vy)&&(r.vy=0))}),_i.forEach(e=>(function(_,e){_.previousvx=_.vx,_.previousvy=_.vy;let t=1+A.telekinesis+A.ball_repulse_ball+A.puck_repulse_ball+A.ball_attract_ball;if(_H(_)&&(t+=3,_.vx+=($-_.x)/1e3*e*A.telekinesis),_.vx*_.vx+_.vy*_.vy0?1:-1)*.02/t),A.ball_repulse_ball)for(let e of _i)e.x>=_.x||ei(_,e,A.ball_repulse_ball,!0);if(A.ball_attract_ball)for(let e of _i)e.x>=_.x||function(_,e,t){let r=eo(_,e),a=.5*D;if(r1&&!et("basic"))for(let e=0;e<_.hitItem?.length-1&&e.5,l=Math.random()>.5?1:-1,o=Math.random()>.5?1:-1;_b.push({type:"particle",duration:250,ethereal:!0,time:_5,size:S/2,color:r,x:__(t)+l*U/2,y:_e(t)+o*U/2,vx:a?0:-l*C,vy:a?-o*C:0})}let r=_P(_,10,e);r&&(A.left_is_lava&&r%2&&_.xI+D/2&&P(_.x,_.y),A.top_is_lava&&r>=2&&P(_.x,_.y+20),_0.wallBeep(_.x),_.bouncesList?.push({x:_.previousx,y:_.previousy}));let a=j-20-10;if(_.y>a&&Math.abs(_.x-$)<10+L/2&&_.vy>0){let e=Math.sqrt(_.vx*_.vx+_.vy*_.vy),t=Math.atan2(-L/2,_.x-$);_.vx=e*Math.cos(t),_.vy=e*Math.sin(t),_0.wallBeep(_.x),A.streak_shots&&P(_.x,_.y),A.respawn&&_.hitItem.slice(0,-1).slice(0,A.respawn).forEach(({index:_,color:e})=>{_m[_]||"black"===e||(_m[_]=e)}),_.hitItem=[],_.hitSinceBounce||(_V.misses++,_d++,P(_.x,_.y),_b.push({type:"text",text:"miss",duration:500,time:_5,size:30,color:"red",x:$,y:j-40})),_V.puck_bounces++,_.hitSinceBounce=0,_.sapperUses=0,_.piercedSinceBounce=0,_.bouncesList=[{x:_.previousx,y:_.previousy}]}_.y>j+10&&H&&(_.destroyed=!0,_V.balls_lost++,_i.find(_=>!_.destroyed)||(A.extra_life?(A.extra_life--,_n(),_0.revive(),Z(!1),_y=[],_b.push({type:"ball",duration:500,time:_5,size:2*U,color:"white",x:_.x,y:_.y})):_Z("Game Over","You dropped the ball after catching "+_a+" coins. ")));let l=function(_){let{x:e,y:t,previousx:r,previousy:a}=_,l=_T(r,t,10),o=_T(e,a,10),s=void 0===l&&void 0===o&&_T(e,t,10)||void 0,i=_.piercedSinceBounce<3*A.pierce;return i&&(void 0!==l||void 0!==o||void 0!==s)&&_.piercedSinceBounce++,A.pierce_color&&(void 0===l||_m[l]===_c)&&(void 0===o||_m[o]===_c)&&(void 0===s||_m[s]===_c)&&(i=!0),void 0===l&&void 0===s||i||(_.y=_.previousy,_.vy*=-1),void 0===o&&void 0===s||i||(_.x=_.previousx,_.vx*=-1),l??o??s}(_);if(void 0!==l){let e=_m[l];_I(l,_,!1),_.sapperUses1&&(_b.push({type:"particle",duration:100*_.sparks,time:_5,size:S/2,color:_c,x:_.x,y:_.y,vx:(Math.random()-.5)*C,vy:(Math.random()-.5)*C}),_.sparks=0))})(e,_)),A.wind){let _=($-(I+D/2))/D*2*A.wind;for(let e=0;e.5&&_b.push({type:"particle",duration:150,ethereal:!0,time:_5,size:S/2,color:es(),x:F+Math.random()*N,y:Math.random()*j,vx:8*_,vy:0})}_b.forEach(e=>{"particle"===e.type&&(e.x+=e.vx*_,e.y+=e.vy*_,!e.ethereal&&(e.vy+=.5,_O(_C(e.x,e.y))&&(e.destroyed=!0)))})}}else G+1<_F()?_W(G+1):_Z("Run finished with "+_a+" points","You cleared all levels for this run.");if(O>T()){let _=!et("basic")&&(O-T())*Math.random()>5&&H&&{type:"particle",duration:100*(Math.random()+1),time:_5,size:S/2,color:"red",ethereal:!0};if(A.top_is_lava&&_&&_b.push({..._,x:F+Math.random()*N,y:0,vx:(Math.random()-.5)*10,vy:5}),A.left_is_lava&&_&&_b.push({..._,x:F,y:Math.random()*j,vx:5,vy:(Math.random()-.5)*10}),A.right_is_lava&&_&&_b.push({..._,x:F+N,y:Math.random()*j,vx:-5,vy:(Math.random()-.5)*10}),A.compound_interest){let e=$,t=0;do e=F+N*Math.random(),t++;while(Math.abs(e-$){let{x:e,y:t,time:r,color:a,size:l,type:o,duration:s}=_;x.globalAlpha=Math.min(1,2-(_5-r)/s*2),"particle"===o&&_Y(x,a,l,e,t)});else if(x.globalCompositeOperation="source-over",x.globalAlpha=.4,x.fillStyle="#000",x.fillRect(0,0,n,h),x.globalCompositeOperation="screen",x.globalAlpha=.6,_y.forEach(_=>{_.destroyed||_K(x,_.color,2*S,_.x,_.y)}),_i.forEach(_=>{_K(x,_c,40,_.x,_.y)}),x.globalAlpha=.5,_m.forEach((_,e)=>{if(!_)return;let t=__(e),r=_e(e);_K(x,"black"==_?"#666":_,U,t,r)}),x.globalAlpha=1,_b.forEach(_=>{let{x:e,y:t,time:r,color:a,size:l,type:o,duration:s}=_;x.globalAlpha=Math.min(1,2-(_5-r)/s*2),"ball"===o&&_K(x,a,l,e,t),"particle"===o&&_K(x,a,3*l,e,t)}),x.globalAlpha=.2,x.globalCompositeOperation="multiply",x.fillStyle="black",x.fillRect(0,0,n,h),x.globalAlpha=.8,x.globalCompositeOperation="multiply",c.svg&&J.width&&J.complete){if(K.title!==c.name){K.title=c.name,K.width=z.width,K.height=z.height;let _=K.getContext("2d");_.fillStyle=c.color||"#000",_.fillRect(0,0,z.width,z.height),_.fillStyle=x.createPattern(J,"repeat"),_.fillRect(0,0,n,h)}x.drawImage(K,0,0)}else x.fillStyle="#000",x.fillRect(0,0,n,h);x.globalAlpha=1,x.globalCompositeOperation="source-over";let b=Date.now()-_l+5,y=b<200;if(y){let _=(A.bigger_explosions+1)*50/b;x.translate(Math.sin(Date.now())*_,Math.sin(Date.now()+36)*_)}if(x.globalCompositeOperation="source-over",function(){x.globalAlpha=1;let _=O>T()&&A.picky_eater,e=D+"_"+_m.join("_")+R.complete+"_"+_+"_"+_c+"_"+A.pierce_color;if(e!==_N){_N=e,_D.width=D,_D.height=D+1;let t=_D.getContext("2d");t.clearRect(0,0,D,D),t.resetTransform(),t.translate(-I,0),_m.forEach((e,r)=>{let a=__(r),l=_e(r);if(!e)return;let o=_c!==e&&"black"!==e&&_&&"red"||e;(function(_,e,t,r,a){let l=Math.ceil(r-U/2),o=Math.ceil(a-U/2),s=Math.ceil(r+U/2)-1-l,i=Math.ceil(a+U/2)-1-o,c="brick"+e+"_"+t+"_"+s+"_"+i;if(!_j[c]){var n,h,m,b,y,g;let _=document.createElement("canvas");_.width=s,_.height=i;let r=_.getContext("2d");r.fillStyle=e,r.strokeStyle=t,r.lineJoin="round",r.lineWidth=2,n=r,h=1,m=1,b=s-2,y=i-2,g=2,n.beginPath(),n.moveTo(3,1),n.lineTo(h+b-g,m),n.quadraticCurveTo(h+b,m,h+b,m+g),n.lineTo(h+b,m+y-g),n.quadraticCurveTo(h+b,m+y,h+b-g,m+y),n.lineTo(h+g,m+y),n.quadraticCurveTo(h,m+y,h,m+y-g),n.lineTo(h,m+g),n.quadraticCurveTo(h,m,h+g,m),n.closePath(),r.fill(),r.stroke(),_j[c]=_}_.drawImage(_j[c],l,o,s,i)})(t,e,o,a,l),"black"===e&&(t.globalCompositeOperation="source-over",function(_,e,t,r,a){let l="svg"+e+"_"+t+"_"+e.complete;if(!_j[l]){let _=document.createElement("canvas");_.width=t,_.height=t;let r=_.getContext("2d"),a=t/Math.max(e.width,e.height),o=e.width*a,s=e.height*a;r.drawImage(e,(t-o)/2,(t-s)/2,o,s),_j[l]=_}_.drawImage(_j[l],Math.round(r-t/2),Math.round(a-t/2))}(t,R,U,a,l))})}x.drawImage(_D,I,0)}(),x.globalCompositeOperation="screen",(_b=_b.filter(_=>_5-_.time<_.duration&&!_.destroyed)).forEach(_=>{let{x:e,y:t,time:r,color:a,size:l,type:o,text:s,duration:i}=_,c=_5-r;x.globalAlpha=Math.max(0,Math.min(1,2-c/i*2)),"text"===o?(x.globalCompositeOperation="source-over",_X(x,s,a,l,e,t-c/10)):"particle"===o&&(x.globalCompositeOperation="screen",_Y(x,a,l,e,t),_K(x,a,l,e,t))}),x.globalAlpha=1,x.globalCompositeOperation="source-over",_y.forEach(_=>{_.destroyed||_J(x,_.color,S,_.x,_.y,c.color||"black",_.a)}),_y.length>10&&!et("basic")&&(x.globalAlpha=Math.min(.8,(_y.length-10)/50),_i.forEach(_=>{_Y(x,c.color||"#000",120,_.x,_.y)})),x.globalAlpha=1,x.globalCompositeOperation="source-over",_i.forEach(_=>{_Y(x,_c,20,_.x,_.y,M),_H(_)&&(x.strokeStyle=M,x.beginPath(),x.bezierCurveTo($,j,$,_.y,_.x,_.y),x.stroke())}),x.globalAlpha=1,x.globalCompositeOperation="source-over",A.streak_shots&&O>T()&&_U(x,"red",L,20,-2),_U(x,M,L,20),O>1){x.globalCompositeOperation="source-over";let _="x "+O,e=20*_.length/1.8+2*S,t=$-e/2;eT();x.globalCompositeOperation="source-over",F?(x.fillStyle=g&&A.left_is_lava?"red":M,x.fillRect(I-1,0,1,h),x.fillStyle=g&&A.right_is_lava?"red":M,x.fillRect(n-I+1,0,1,h)):(x.fillStyle="red",g&&A.left_is_lava&&x.fillRect(0,0,1,h),g&&A.right_is_lava&&x.fillRect(n-1,0,1,h)),A.top_is_lava&&O>T()&&(_=x,e=F,t=0,r=N,i=1,_.fillStyle="red",_.fillRect(e,0,r,1));let d=A.compound_interest&&O>T();x.fillStyle=d?"red":M,et("mobile-mode")?(x.fillRect(F,j,N,1),H||_X(x,"Press and hold here to play",M,20,z.width/2,j+(z.height-j)/2)):d&&x.fillRect(F,j-1,N,1),y&&x.resetTransform(),et("record")&&H&&a&&(s&&(s.drawImage(z,F,0,N,j,0,0,o.width,o.height),s.fillStyle="#FFF",s.textBaseline="top",s.font="12px monospace",s.textAlign="right",s.fillText(_a.toString(),o.width-12,12),s.textAlign="left",s.fillText("Level "+(G+1)+"/"+_F(),12,12)),l?.requestFrame?l?.requestFrame():a?.requestFrame&&a.requestFrame())})(),requestAnimationFrame(_),_A=e}();