"use strict";const cat={player:1,map:16,body:256,bullet:4096,powerUp:65536,mob:1048576,mobBullet:16777216,mobShield:268435456,phased:4294967296},color={background:"#ddd",block:"rgba(140,140,140,0.85)",blockS:"#222",map:"#444",bullet:"#000"};function shuffle(e){for(var t,n,i=e.length;0!==i;)n=Math.floor(Math.random()*i),t=e[i-=1],e[i]=e[n],e[n]=t;return e}function getUrlVars(){let e={};return window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,(function(t,n,i){e[n]=i})),e}window.addEventListener("load",(()=>{const e=getUrlVars();if(0!==Object.keys(e).length){build.populateGrid(),openExperimentMenu();for(const t in e){if(e[t]=e[t].replace(/%20/g," "),e[t]=e[t].replace(/%27/g,"'"),e[t]=e[t].replace(/%CE%A8/g,"Ψ"),"field"===t){let n,i=!1;for(let s=0;s<m.fieldUpgrades.length;s++)if(e[t]===m.fieldUpgrades[s].name){n=s,i=!0;break}i&&build.choosePowerUp(document.getElementById(`field-${n}`),n,"field")}if("gun"===t.substring(0,3)){let n,i=!1;for(let s=0;s<b.guns.length;s++)if(e[t]===b.guns[s].name){n=s,i=!0;break}i&&build.choosePowerUp(document.getElementById(`gun-${n}`),n,"gun")}if("tech"===t.substring(0,4))for(let n=0;n<tech.tech.length;n++)if(e[t]===tech.tech[n].name){build.choosePowerUp(document.getElementById(`tech-${n}`),n,"tech",!0);break}"difficulty"===t&&(simulation.difficultyMode=Number(e[t]),lore.setTechGoal(),document.getElementById("difficulty-select-experiment").value=Number(e[t])),"level"===t&&(document.getElementById("starting-level").value=Math.max(Number(e[t])-1,0)),"noPower"===t&&(document.getElementById("no-power-ups").checked=Number(e[t]))}}}));const canvas=document.getElementById("canvas"),ctx=canvas.getContext("2d");function setupCanvas(){canvas.width=window.innerWidth,canvas.height=window.innerHeight,canvas.width2=canvas.width/2,canvas.height2=canvas.height/2,ctx.font="25px Arial",ctx.lineJoin="round",ctx.lineCap="round",simulation.setZoom()}document.body.style.backgroundColor="#fff",document.oncontextmenu=function(){return!1},setupCanvas(),window.onresize=()=>{setupCanvas()};for(let e=0,t=tech.tech.length;e<t;e++)tech.tech[e].link||(tech.tech[e].link=`<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(tech.tech[e].name).replace(/'/g,"%27")}&title=Special:Search' class="link">${tech.tech[e].name}</a>`);const build={pauseGrid(){let e="";tech.nailBotCount&&(e+=`<br>nail-bots: ${tech.nailBotCount}`),tech.orbitBotCount&&(e+=`<br>orbital-bots: ${tech.orbitBotCount}`),tech.boomBotCount&&(e+=`<br>boom-bots: ${tech.boomBotCount}`),tech.laserBotCount&&(e+=`<br>laser-bots: ${tech.laserBotCount}`),tech.foamBotCount&&(e+=`<br>foam-bots: ${tech.foamBotCount}`),tech.dynamoBotCount&&(e+=`<br>dynamo-bots: ${tech.dynamoBotCount}`),tech.plasmaBotCount&&(e+=`<br>plasma-bots: ${tech.plasmaBotCount}`),tech.missileBotCount&&(e+=`<br>missile-bots: ${tech.missileBotCount}`);const t=100*(1-m.harmReduction());let n='<div class="pause-grid-module" style = "font-size: 13px;line-height: 120%;padding: 5px;">';simulation.isChoosing||(n+='<br><span style="font-size:1.5em;font-weight: 600;">PAUSED</span> press P to resume\n<br><br><svg class="SVG-button" onclick="build.shareURL(false)" width="92" height="20" style="padding:0px; margin: 1px;">\n <g stroke=\'none\' fill=\'#333\' stroke-width="2" font-size="14px" font-family="Ariel, sans-serif"> <text x="5" y="15">copy build url</text></g>\n</svg><br>'),n+=`<strong class='color-d'>damage</strong> increase: ${(100*(tech.damageFromTech()-1)).toFixed(0)}%\n<br><strong class='color-harm'>harm</strong> reduction: ${t.toFixed(t>90?2:0)}%\n<br><strong><em>fire delay</em></strong> decrease: ${(100*(1-b.fireCDscale)).toFixed(b.fireCDscale<.1?2:0)}%\n<br><strong class='color-dup'>duplication</strong> chance: ${(100*tech.duplicationChance()).toFixed(0)}%\n${e}\n<br>\n<br><strong class='color-m'>tech</strong>: ${tech.totalCount} <strong class='color-r'>research</strong>: ${powerUps.research.count} \n<br><strong class='color-h'>health</strong>: (${(100*m.health).toFixed(0)} / ${(100*m.maxHealth).toFixed(0)}) <strong class='color-f'>energy</strong>: (${(100*m.energy).toFixed(0)} / ${(100*m.maxEnergy).toFixed(0)})\n<br><strong class='color-g'>gun</strong>: ${null!==b.activeGun?b.guns[b.activeGun].name:"null"} <strong class='color-g'>ammo</strong>: ${null!==b.activeGun?b.guns[b.activeGun].ammo:"0"}\n<br>position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)}) velocity: (${player.velocity.x.toFixed(1)}, ${player.velocity.y.toFixed(1)})\n<br>mouse: (${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)}) mass: ${player.mass.toFixed(1)} \n<br>\n<br>level: ${level.levels[level.onLevel]} (${level.difficultyText()}) ${m.cycle} cycles\n<br>${mob.length} mobs, ${body.length} blocks, ${bullet.length} bullets, ${powerUp.length} power ups\n\n<br>damage difficulty scale: ${(100*b.dmgScale).toFixed(2)}%\n<br>harm difficulty scale: ${(100*simulation.dmgScale).toFixed(0)}%\n<br>heal difficulty scale: ${(100*simulation.healScale).toFixed(1)}%\n${simulation.isCheating?"<br><br><em>lore disabled</em>":""}\n</div>`;for(let e=0,t=b.inventory.length;e<t;e++)n+=`<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid gun"></div> ${build.nameLink(b.guns[b.inventory[e]].name)} - <span style="font-size:100%;font-weight: 100;">${b.guns[b.inventory[e]].ammo}</span></div> ${b.guns[b.inventory[e]].description}</div>`;let i=document.getElementById("pause-grid-left");i.style.display="grid",i.innerHTML=n,n="",n+=`<div class="pause-grid-module" id ="pause-field"><div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div> ${m.fieldUpgrades[m.fieldMode].description}</div>`;for(let e=0,t=tech.tech.length;e<t;e++)if(tech.tech[e].count>0&&!tech.tech[e].isNonRefundable){const t=tech.tech[e].count>1?`(${tech.tech[e].count}x)`:"";tech.tech[e].isFieldTech?n+=`<div class="pause-grid-module"><div class="grid-title">\n <span style="position:relative;">\n <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>\n <div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div>\n </span>\n ${tech.tech[e].link} ${t}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div></div>`:tech.tech[e].isGunTech?n+=`<div class="pause-grid-module"><div class="grid-title">\n <span style="position:relative;">\n <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>\n <div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>\n </span>\n ${tech.tech[e].link} ${t}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div></div>`:tech.tech[e].isLore?n+=`<div class="pause-grid-module"><div class="grid-title lore-text"><div class="circle-grid lore"></div> ${tech.tech[e].name} ${t}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div></div>`:n+=`<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid tech"></div> ${tech.tech[e].link} ${t}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div></div>`}else tech.tech[e].isLost&&(n+=`<div class="pause-grid-module" style="text-decoration: line-through;"><div class="grid-title">${tech.tech[e].link}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div></div>`);i=document.getElementById("pause-grid-right"),i.style.display="grid",i.innerHTML=n},unPauseGrid(){document.getElementById("pause-grid-left").style.display="none",document.getElementById("pause-grid-right").style.display="none",window.scrollTo(0,0)},isExperimentSelection:!1,isExperimentRun:!1,choosePowerUp(e,t,n,i=!1){if("gun"===n){let n=!1;for(let i=0,s=b.inventory.length;i<s;i++)if(b.guns[b.inventory[i]].name===b.guns[t].name){n=!0,e.classList.remove("build-gun-selected"),b.inventory.splice(i,1),b.guns[t].count=0,b.guns[t].have=!1,b.guns[t].ammo!=1/0&&(b.guns[t].ammo=0),0===b.inventory.length&&(b.activeGun=null),simulation.makeGunHUD();break}n||(e.classList.add("build-gun-selected"),b.giveGuns(t))}else"field"===n?m.fieldMode!==t&&(document.getElementById("field-"+m.fieldMode).classList.remove("build-field-selected"),m.setField(t),e.classList.add("build-field-selected")):"tech"===n&&(tech.tech[t].count<tech.tech[t].maxCount?(e.classList.contains("build-tech-selected")||e.classList.add("build-tech-selected"),tech.giveTech(t)):tech.tech[t].isNonRefundable?(e.classList.remove("build-tech-selected"),setTimeout((()=>{e.classList.add("build-tech-selected")}),50)):(tech.totalCount-=tech.tech[t].count,tech.removeTech(t),e.classList.remove("build-tech-selected")));for(let e=0,t=tech.tech.length;e<t;e++){const t=document.getElementById("tech-"+e);if(!tech.tech[e].isExperimentHide&&(!tech.tech[e].isNonRefundable||tech.tech[e].isExperimentalMode))if(tech.tech[e].allowed()||i||tech.tech[e].count>0){const n=tech.tech[e].count>1?`(${tech.tech[e].count}x)`:"";tech.tech[e].isFieldTech?(t.classList.remove("experiment-grid-hide"),t.innerHTML=`\n <div class="grid-title">\n <span style="position:relative;">\n <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>\n <div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div>\n </span>\n ${tech.tech[e].link} ${n}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}\n </div>`):tech.tech[e].isGunTech?(t.classList.remove("experiment-grid-hide"),t.innerHTML=`\n <div class="grid-title">\n <span style="position:relative;">\n <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>\n <div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>\n </span>\n ${tech.tech[e].link} ${n}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}\n </div>`):tech.tech[e].isJunk?t.innerHTML=`<div class="grid-title"><div class="circle-grid junk"></div> ${tech.tech[e].link} ${n}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div>`:tech.tech[e].isExperimentalMode?t.innerHTML=`<div class="grid-title">${tech.tech[e].name}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div>`:t.innerHTML=`<div class="grid-title"><div class="circle-grid tech"></div> ${tech.tech[e].link} ${n}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div>`,0===tech.tech[e].count&&t.classList.contains("build-tech-selected")&&t.classList.remove("build-tech-selected"),t.classList.contains("experiment-grid-disabled")&&(t.classList.remove("experiment-grid-disabled"),t.setAttribute("onClick",`javascript: build.choosePowerUp(this,${e},'tech')`))}else t.innerHTML=`<div class="grid-title">${tech.tech[e].name}</div>${tech.tech[e].descriptionFunction?tech.tech[e].descriptionFunction():tech.tech[e].description}</div>`,t.classList.contains("experiment-grid-disabled")||(t.classList.add("experiment-grid-disabled"),t.onclick=null),tech.tech[e].count>0&&tech.removeTech(e),t.classList.contains("build-tech-selected")&&t.classList.remove("build-tech-selected")}},populateGrid(){let e='\n <div style="display: flex; justify-content: space-around; align-items: center;">\n <svg class="SVG-button" onclick="build.startExperiment()" width="115" height="51">\n <g stroke=\'none\' fill=\'#333\' stroke-width="2" font-size="40px" font-family="Ariel, sans-serif">\n <text x="18" y="38">start</text>\n </g>\n </svg>\n <svg class="SVG-button" onclick="build.reset()" width="50" height="25">\n <g stroke=\'none\' fill=\'#333\' stroke-width="2" font-size="17px" font-family="Ariel, sans-serif">\n <text x="5" y="18">reset</text>\n </g>\n </svg>\n <svg class="SVG-button" onclick="build.shareURL(true)" width="52" height="25">\n <g stroke=\'none\' fill=\'#333\' stroke-width="2" font-size="17px" font-family="Ariel, sans-serif">\n <text x="5" y="18">share</text>\n </g>\n </svg>\n </div>\n <div style="align-items: center; text-align:center; font-size: 1.00em; line-height: 190%;background-color:var(--build-bg-color);">\n <div>starting level: <input id=\'starting-level\' type="number" step="1" value="1" min="0" max="99"></div>\n <div>\n <label for="difficulty-select" title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed, heal effects">difficulty:</label>\n <select name="difficulty-select" id="difficulty-select-experiment">\n <option value="1">easy</option>\n <option value="2" selected>normal</option>\n <option value="4">hard</option>\n <option value="6">why?</option>\n </select>\n </div>\n <div>\n <label for="no-power-ups" title="no tech, fields, or guns will spawn">no power ups:</label>\n <input type="checkbox" id="no-power-ups" name="no-power-ups" style="width:17px; height:17px;">\n </div>\n </div>';for(let t=0,n=m.fieldUpgrades.length;t<n;t++)e+=`<div id ="field-${t}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${t},'field')"><div class="grid-title"><div class="circle-grid field"></div> ${build.nameLink(m.fieldUpgrades[t].name)}</div> ${m.fieldUpgrades[t].description}</div>`;for(let t=0,n=b.guns.length;t<n;t++)e+=`<div id = "gun-${t}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${t},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> ${build.nameLink(b.guns[t].name)}</div> ${b.guns[t].description}</div>`;for(let t=0,n=tech.tech.length;t<n;t++)tech.tech[t].isExperimentHide||(!tech.tech[t].allowed()||tech.tech[t].isNonRefundable&&!tech.tech[t].isExperimentalMode?e+=`<div id="tech-${t}" class="experiment-grid-module experiment-grid-disabled"><div class="grid-title"> ${tech.tech[t].name}</div> ${tech.tech[t].descriptionFunction?tech.tech[t].descriptionFunction():tech.tech[t].description}</div>`:tech.tech[t].isExperimentalMode?e+=`<div id="tech-${t}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${t},'tech')"><div class="grid-title">${tech.tech[t].name}</div> ${tech.tech[t].descriptionFunction?tech.tech[t].descriptionFunction():tech.tech[t].description}</div>`:e+=`<div id="tech-${t}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${t},'tech')"><div class="grid-title"><div class="circle-grid tech"></div> ${tech.tech[t].link}</div> ${tech.tech[t].descriptionFunction?tech.tech[t].descriptionFunction():tech.tech[t].description}</div>`);document.getElementById("experiment-grid").innerHTML=e,document.getElementById("difficulty-select-experiment").value=document.getElementById("difficulty-select").value,document.getElementById("difficulty-select-experiment").addEventListener("input",(()=>{simulation.difficultyMode=Number(document.getElementById("difficulty-select-experiment").value),lore.setTechGoal(),localSettings.difficultyMode=Number(document.getElementById("difficulty-select-experiment").value),document.getElementById("difficulty-select").value=document.getElementById("difficulty-select-experiment").value,localStorage.setItem("localSettings",JSON.stringify(localSettings))}));for(let e=0,t=tech.tech.length;e<t;e++)document.getElementById(`tech-${e}`)&&document.getElementById(`tech-${e}`).setAttribute("data-descr",tech.tech[e].requires)},nameLink:e=>`<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(e).replace(/'/g,"%27")}&title=Special:Search' class="link">${e}</a>`,reset(){build.isExperimentSelection=!0,build.isExperimentRun=!0,simulation.startGame(!0),build.isExperimentSelection=!0,build.isExperimentRun=!0,simulation.paused=!0,b.inventory=[];for(let e=0,t=b.guns.length;e<t;++e)b.guns[e].count=0,b.guns[e].have=!1,b.guns[e].ammo!=1/0&&(b.guns[e].ammo=0);b.activeGun=null,simulation.makeGunHUD(),tech.setupAllTech(),build.populateGrid(),document.getElementById("field-0").classList.add("build-field-selected"),document.getElementById("experiment-grid").style.display="grid"},shareURL(e=!1){let t="https://landgreen.github.io/sidescroller/index.html?",n=0;for(let e=0;e<b.inventory.length;e++)b.guns[b.inventory[e]].have&&(t+=`&gun${n}=${encodeURIComponent(b.guns[b.inventory[e]].name.trim())}`,n++);n=0;for(let e=0;e<tech.tech.length;e++)for(let i=0;i<tech.tech[e].count;i++)tech.tech[e].isLore||tech.tech[e].isJunk||tech.tech[e].isNonRefundable||tech.tech[e].isExperimentHide||(t+=`&tech${n}=${encodeURIComponent(tech.tech[e].name.trim())}`,n++);t+=`&field=${encodeURIComponent(m.fieldUpgrades[m.fieldMode].name.trim())}`,t+=`&difficulty=${simulation.difficultyMode}`,e?(t+=`&level=${Math.abs(Number(document.getElementById("starting-level").value))}`,t+=`&noPower=${Number(document.getElementById("no-power-ups").checked)}`):simulation.makeTextLog("n-gon build URL copied to clipboard.<br>Paste into browser address bar."),console.log("n-gon build URL copied to clipboard.\nPaste into browser address bar."),console.log(t),navigator.clipboard.writeText(t).then((function(){e&&setTimeout((function(){alert("n-gon build URL copied to clipboard.\nPaste into browser address bar.")}),300)}),(function(){e&&setTimeout((function(){alert("copy failed")}),300),console.log("copy failed")}))},hasExperimentalMode:!1,startExperiment(){build.isExperimentSelection=!1,spawn.setSpawnList(),spawn.setSpawnList(),b.inventory.length>0&&(b.activeGun=b.inventory[0],simulation.makeGunHUD());for(let e=0;e<bullet.length;++e)Matter.Composite.remove(engine.world,bullet[e]);bullet=[];const e=Math.abs(Number(document.getElementById("starting-level").value)-1);if(level.difficultyIncrease(Math.min(99,e*simulation.difficultyMode)),level.levelsCleared+=e,simulation.isNoPowerUps=document.getElementById("no-power-ups").checked,simulation.isNoPowerUps){function e(){for(let t=0;t<powerUp.length;t++)if("tech"===powerUp[t].name||"gun"===powerUp[t].name||"field"===powerUp[t].name){Matter.Composite.remove(engine.world,powerUp[t]),powerUp.splice(t,1),e();break}}e()}if(build.hasExperimentalMode=!1,!simulation.isCheating){for(let e=0,t=tech.tech.length;e<t;e++)tech.tech[e].count>0&&(tech.tech[e].isExperimentalMode?build.hasExperimentalMode=!0:tech.tech[e].isLore||(simulation.isCheating=!0));0===b.inventory.length&&0===m.fieldMode||(simulation.isCheating=!0)}if(simulation.isCheating){lore.techCount=0;for(let e=0,t=tech.tech.length;e<t;e++)tech.tech[e].isLore&&(tech.tech[e].frequency=0,tech.tech[e].count=0);simulation.updateTechHUD()}else{for(let e=0;e<powerUp.length;++e)Matter.Composite.remove(engine.world,powerUp[e]);powerUp=[]}document.body.style.cursor="none",document.body.style.overflow="hidden",document.getElementById("experiment-grid").style.display="none",simulation.paused=!1,requestAnimationFrame(cycle)}};function openExperimentMenu(){document.getElementById("experiment-button").style.display="none",document.getElementById("training-button").style.display="none";document.getElementById("experiment-grid").style.display="grid",document.body.style.overflowY="scroll",document.body.style.overflowX="hidden",document.getElementById("info").style.display="none",build.reset()}document.getElementById("experiment-button").addEventListener("click",(()=>{let e=0,t=[],n=[];if(!simulation.firstRun){e=m.fieldMode,t=[...b.inventory];for(let e=0;e<tech.tech.length;e++)n.push(tech.tech[e].count)}openExperimentMenu()}));const input={fire:!1,field:!1,up:!1,down:!1,left:!1,right:!1,isPauseKeyReady:!0,key:{fire:"KeyF",field:"Space",up:"KeyW",down:"KeyS",left:"KeyA",right:"KeyD",pause:"KeyP",nextGun:"KeyE",previousGun:"KeyQ",testing:"KeyT"},setDefault(){input.key={fire:"KeyF",field:"Space",up:"KeyW",down:"KeyS",left:"KeyA",right:"KeyD",pause:"KeyP",nextGun:"KeyE",previousGun:"KeyQ",testing:"KeyT"},input.controlTextUpdate()},controlTextUpdate(){function e(e){return e.replace("Key","").replace("Digit","")}input.key.fire||(input.key.fire="KeyF"),document.getElementById("key-fire").innerHTML=e(input.key.fire),document.getElementById("key-field").innerHTML=e(input.key.field),document.getElementById("key-up").innerHTML=e(input.key.up),document.getElementById("key-down").innerHTML=e(input.key.down),document.getElementById("key-left").innerHTML=e(input.key.left),document.getElementById("key-right").innerHTML=e(input.key.right),document.getElementById("key-pause").innerHTML=e(input.key.pause),document.getElementById("key-next-gun").innerHTML=e(input.key.nextGun),document.getElementById("key-previous-gun").innerHTML=e(input.key.previousGun),document.getElementById("key-testing").innerHTML=e(input.key.testing),document.getElementById("splash-up").innerHTML=e(input.key.up)[0],document.getElementById("splash-down").innerHTML=e(input.key.down)[0],document.getElementById("splash-left").innerHTML=e(input.key.left)[0],document.getElementById("splash-right").innerHTML=e(input.key.right)[0],document.getElementById("splash-next-gun").innerHTML=e(input.key.nextGun)[0],document.getElementById("splash-previous-gun").innerHTML=e(input.key.previousGun)[0],localSettings.key=input.key,localStorage.setItem("localSettings",JSON.stringify(localSettings))},focus:null,setTextFocus(){const e="#fff";document.getElementById("key-fire").style.background=e,document.getElementById("key-field").style.background=e,document.getElementById("key-up").style.background=e,document.getElementById("key-down").style.background=e,document.getElementById("key-left").style.background=e,document.getElementById("key-right").style.background=e,document.getElementById("key-pause").style.background=e,document.getElementById("key-next-gun").style.background=e,document.getElementById("key-previous-gun").style.background=e,document.getElementById("key-testing").style.background=e,input.focus&&(input.focus.style.background="rgb(0, 200, 255)")},setKeys(e){if(e.code&&"ArrowRight"!==e.code&&"ArrowLeft"!==e.code&&"ArrowUp"!==e.code&&"ArrowDown"!==e.code&&e.code!==input.key.fire&&e.code!==input.key.field&&e.code!==input.key.up&&e.code!==input.key.down&&e.code!==input.key.left&&e.code!==input.key.right&&e.code!==input.key.pause&&e.code!==input.key.nextGun&&e.code!==input.key.previousGun&&e.code!==input.key.testing)switch(input.focus.id){case"key-fire":input.key.fire=e.code;break;case"key-field":input.key.field=e.code;break;case"key-up":input.key.up=e.code;break;case"key-down":input.key.down=e.code;break;case"key-left":input.key.left=e.code;break;case"key-right":input.key.right=e.code;break;case"key-pause":input.key.pause=e.code;break;case"key-next-gun":input.key.nextGun=e.code;break;case"key-previous-gun":input.key.previousGun=e.code;break;case"key-testing":input.key.testing=e.code}input.controlTextUpdate(),input.endKeySensing()},endKeySensing(){window.removeEventListener("keydown",input.setKeys),input.focus=null,input.setTextFocus()}};document.getElementById("control-table").addEventListener("click",(e=>{"key-input"===e.target.className&&(input.focus=e.target,input.setTextFocus(),window.addEventListener("keydown",input.setKeys))})),document.getElementById("control-details").addEventListener("toggle",(function(){input.controlTextUpdate(),input.endKeySensing()})),document.getElementById("control-reset").addEventListener("click",input.setDefault),window.addEventListener("keyup",(function(e){switch(e.code){case input.key.right:case"ArrowRight":input.right=!1;break;case input.key.left:case"ArrowLeft":input.left=!1;break;case input.key.up:case"ArrowUp":input.up=!1;break;case input.key.down:case"ArrowDown":input.down=!1;break;case input.key.fire:input.fire=!1;break;case input.key.field:input.field=!1}})),window.addEventListener("keydown",(function(e){switch(e.code){case input.key.right:case"ArrowRight":input.right=!0;break;case input.key.left:case"ArrowLeft":input.left=!0;break;case input.key.up:case"ArrowUp":input.up=!0;break;case input.key.down:case"ArrowDown":input.down=!0;break;case input.key.fire:input.fire=!0;break;case input.key.field:e.preventDefault(),input.field=!0;break;case input.key.nextGun:simulation.nextGun();break;case input.key.previousGun:simulation.previousGun();break;case input.key.pause:!simulation.isChoosing&&input.isPauseKeyReady&&m.alive&&(input.isPauseKeyReady=!1,setTimeout((function(){input.isPauseKeyReady=!0}),300),simulation.paused?(build.unPauseGrid(),simulation.paused=!1,document.body.style.cursor="none",requestAnimationFrame(cycle)):(simulation.paused=!0,build.pauseGrid(),document.body.style.cursor="auto",(tech.isPauseSwitchField||simulation.testing)&&document.getElementById("pause-field").addEventListener("click",(()=>{const e=m.energy;m.setField(m.fieldMode===m.fieldUpgrades.length-1?1:m.fieldMode+1),m.energy=e,document.getElementById("pause-field").innerHTML=`<div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[m.fieldMode].name}</div> ${m.fieldUpgrades[m.fieldMode].description}`}))));break;case input.key.testing:m.alive&&localSettings.loreCount>0&&(simulation.testing?(simulation.testing=!1,simulation.loop=simulation.normalLoop,simulation.isConstructionMode&&(document.getElementById("construct").style.display="none"),simulation.makeTextLog("",0)):(simulation.testing=!0,simulation.loop=simulation.testingLoop,simulation.isConstructionMode&&(document.getElementById("construct").style.display="inline"),simulation.testing&&tech.setCheating(),simulation.makeTextLog("<table class=\"pause-table\">\n <tr>\n <td class='key-input-pause'>T</td>\n <td class='key-used'><strong>toggle testing</strong></td>\n </tr>\n <tr>\n <td class='key-input-pause'>R</td>\n <td class='key-used'>teleport to mouse</td>\n </tr>\n <tr>\n <td class='key-input-pause'>F</td>\n <td class='key-used'>cycle field</td>\n </tr>\n <tr>\n <td class='key-input-pause'>G</td>\n <td class='key-used'>all guns</td>\n </tr> \n <tr>\n <td class='key-input-pause'>H</td>\n <td class='key-used'>harm immunity</td>\n </tr>\n <tr>\n <td class='key-input-pause'>B</td>\n <td class='key-used'>damage, research</td>\n </tr>\n <tr>\n <td class='key-input-pause'>N</td>\n <td class='key-used'>fill health, energy</td>\n </tr>\n <tr>\n <td class='key-input-pause'>Y</td>\n <td class='key-used'>random tech</td>\n </tr>\n <tr>\n <td class='key-input-pause'>U</td>\n <td class='key-used'>next level</td>\n </tr>\n <tr>\n <td class='key-input-pause'>J</td>\n <td class='key-used'>clear mobs</td>\n </tr>\n <tr>\n <td class='key-input-pause'>I/O</td>\n <td class='key-used'>zoom in / out</td>\n </tr>\n <tr>\n <td class='key-input-pause'>1-8</td>\n <td class='key-used'>spawn things</td>\n </tr>\n <tr>\n <td class='key-input-pause'>⇧X</td>\n <td class='key-used'>restart</td>\n </tr> \n </table>",1/0)))}if(simulation.testing)switch("X"===e.key&&m.death(),e.key.toLowerCase()){case"o":simulation.isAutoZoom=!1,simulation.zoomScale/=.9,simulation.setZoom();break;case"i":simulation.isAutoZoom=!1,simulation.zoomScale*=.9,simulation.setZoom();break;case"`":powerUps.directSpawn(simulation.mouseInGame.x,simulation.mouseInGame.y,"research");break;case"1":powerUps.directSpawn(simulation.mouseInGame.x,simulation.mouseInGame.y,"heal");break;case"2":powerUps.directSpawn(simulation.mouseInGame.x,simulation.mouseInGame.y,"ammo");break;case"3":powerUps.directSpawn(simulation.mouseInGame.x,simulation.mouseInGame.y,"gun");break;case"4":powerUps.directSpawn(simulation.mouseInGame.x,simulation.mouseInGame.y,"field");break;case"5":powerUps.directSpawn(simulation.mouseInGame.x,simulation.mouseInGame.y,"tech");break;case"6":const e=body.length;spawn.bodyRect(simulation.mouseInGame.x,simulation.mouseInGame.y,50,50),body[e].collisionFilter.category=cat.body,body[e].collisionFilter.mask=cat.player|cat.map|cat.body|cat.bullet|cat.mob|cat.mobBullet,body[e].classType="body",Composite.add(engine.world,body[e]);break;case"7":const t=spawn.fullPickList[Math.floor(Math.random()*spawn.fullPickList.length)];spawn[t](simulation.mouseInGame.x,simulation.mouseInGame.y);break;case"8":spawn.randomLevelBoss(simulation.mouseInGame.x,simulation.mouseInGame.y);break;case"f":const n=m.fieldMode===m.fieldUpgrades.length-1?0:m.fieldMode+1;m.setField(n);break;case"g":b.giveGuns("all",1e3);break;case"h":m.immuneCycle=1/0;break;case"n":m.addHealth(1/0),m.energy=m.maxEnergy;break;case"y":tech.giveTech();break;case"b":tech.isRerollDamage=!0,powerUps.research.changeRerolls(1e5);break;case"r":m.resetHistory(),Matter.Body.setPosition(player,simulation.mouseInGame),Matter.Body.setVelocity(player,{x:0,y:0});for(let e=0;e<bullet.length;e++)bullet[e].botType&&(Matter.Body.setPosition(bullet[e],Vector.add(player.position,{x:250*(Math.random()-.5),y:250*(Math.random()-.5)})),Matter.Body.setVelocity(bullet[e],{x:0,y:0}));break;case"u":level.nextLevel();break;case"j":for(let e=0,t=mob.length;e<t;++e)mob[e].damage(1/0,!0);setTimeout((()=>{for(let e=0,t=mob.length;e<t;++e)mob[e].damage(1/0,!0)}),100),setTimeout((()=>{for(let e=0,t=mob.length;e<t;++e)mob[e].damage(1/0,!0)}),200)}})),document.body.addEventListener("mousemove",(e=>{simulation.mouse.x=e.clientX,simulation.mouse.y=e.clientY})),document.body.addEventListener("mouseup",(e=>{3===e.which?input.field=!1:input.fire=!1})),document.body.addEventListener("mousedown",(e=>{3===e.which?input.field=!0:input.fire=!0})),document.body.addEventListener("mouseenter",(e=>{1===e.button?input.fire=!0:input.fire=!1,3===e.button?input.field=!0:input.field=!1})),document.body.addEventListener("mouseleave",(e=>{1===e.button?input.fire=!0:input.fire=!1,3===e.button?input.field=!0:input.field=!1})),document.body.addEventListener("wheel",(e=>{simulation.paused||(e.deltaY>0?simulation.nextGun():simulation.previousGun())}),{passive:!0});let localSettings=JSON.parse(localStorage.getItem("localSettings"));localSettings?(localSettings.key?input.key=localSettings.key:input.setDefault(),void 0===localSettings.loreCount&&(localSettings.loreCount=0,localStorage.setItem("localSettings",JSON.stringify(localSettings))),simulation.isCommunityMaps=localSettings.isCommunityMaps,document.getElementById("community-maps").checked=localSettings.isCommunityMaps,simulation.difficultyMode=localSettings.difficultyMode,lore.setTechGoal(),document.getElementById("difficulty-select").value=localSettings.difficultyMode,"max"===localSettings.fpsCapDefault?simulation.fpsCapDefault=999999999:simulation.fpsCapDefault=Number(localSettings.fpsCapDefault),document.getElementById("fps-select").value=localSettings.fpsCapDefault):(localSettings={isCommunityMaps:!1,difficultyMode:"2",fpsCapDefault:"max",runCount:0,levelsClearedLastGame:0,loreCount:0,isHuman:!1,key:void 0},input.setDefault(),localStorage.setItem("localSettings",JSON.stringify(localSettings)),document.getElementById("community-maps").checked=localSettings.isCommunityMaps,simulation.isCommunityMaps=localSettings.isCommunityMaps,document.getElementById("difficulty-select").value=localSettings.difficultyMode,document.getElementById("fps-select").value=localSettings.fpsCapDefault),document.getElementById("control-testing").style.visibility=0===localSettings.loreCount?"hidden":"visible",input.controlTextUpdate(),document.getElementById("fps-select").addEventListener("input",(()=>{let e=document.getElementById("fps-select").value;simulation.fpsCapDefault="max"===e?999999999:Number(e),localSettings.fpsCapDefault=e,localStorage.setItem("localSettings",JSON.stringify(localSettings))})),document.getElementById("community-maps").addEventListener("input",(()=>{simulation.isCommunityMaps=document.getElementById("community-maps").checked,localSettings.isCommunityMaps=simulation.isCommunityMaps,localStorage.setItem("localSettings",JSON.stringify(localSettings))})),document.getElementById("difficulty-select").addEventListener("input",(()=>{simulation.difficultyMode=Number(document.getElementById("difficulty-select").value),lore.setTechGoal(),localSettings.difficultyMode=simulation.difficultyMode,localSettings.levelsClearedLastGame=0,localStorage.setItem("localSettings",JSON.stringify(localSettings))})),document.getElementById("updates").addEventListener("toggle",(function(){let e='<strong>n-gon</strong>: <a href="https://github.com/landgreen/n-gon/blob/master/todo.txt">todo list</a> and complete <a href="https://github.com/landgreen/n-gon/commits/master">change-log</a><hr>';var t,n,i,s;document.getElementById("updates-div").innerHTML=e,t="https://api.github.com/repos/landgreen/n-gon/commits",n=function(t){for(let n=0,i=20;n<i;n++)e+="<strong>"+t[n].commit.author.date.substr(0,10)+"</strong> - ",e+=t[n].commit.message,n<i-1&&(e+="<hr>");document.getElementById("updates-div").innerHTML=e.replace(/\n/g,"<br />")},i=function(e){console.error(e)},(s=new XMLHttpRequest).onreadystatechange=function(){s.readyState===XMLHttpRequest.DONE&&(200===s.status?n&&n(JSON.parse(s.responseText)):i&&i(s))},s.open("GET",t,!0),s.send()}));const sound={tone(e,t=1e3,n=.05){const i=new(window.AudioContext||window.webkitAudioContext),s=i.createOscillator(),o=i.createGain();o.gain.value=n,s.connect(o),o.connect(i.destination),s.type="sine",s.frequency.value=e,s.start(),setTimeout((()=>{i.suspend(),i.close()}),t)},portamento(e,t=1e3,n=10,i=.05){const s=new(window.AudioContext||window.webkitAudioContext),o=s.createOscillator(),l=s.createGain();l.gain.value=i,o.connect(l),l.connect(s.destination),o.type="sine",o.frequency.value=e,o.start();for(let i=0,l=.1*t;i<l;i++)o.frequency.setValueAtTime(e+i*n,s.currentTime+.01*i);setTimeout((()=>{s.suspend(),s.close()}),t)}};function cycle(){simulation.paused||requestAnimationFrame(cycle);const e=Date.now(),t=e-simulation.then;t>simulation.fpsInterval&&(simulation.then=e-t%simulation.fpsInterval,simulation.cycle++,m.cycle++,simulation.clearNow&&(simulation.clearNow=!1,simulation.clearMap(),level.start()),simulation.loop())}simulation.loop=simulation.normalLoop;