// ==UserScript==
// @name Geoguessr GeoStats Script
// @description Keeps track of various stats and displays it on an interactive map on your profile (Duels and Classic)
// @author nappyslappy
// @version 2.2.1
// @match https://www.geoguessr.com/*
// @grant none
// @license none
// @icon https://www.google.com/s2/favicons?sz=64&domain=geoguessr.com
// @copyright nappyslappy 2022, (https://greasyfork.org/en/users/922456)
// @namespace https://greasyfork.org/en/users/922456-nappyslappy
// @downloadURL none
// ==/UserScript==
//Published: June 6th, 2022
//Last Update: September 7th, 2022
/******************************** SETUP ********************************/
/* */
/* If you haven't already, download the free extension 'tampermonkey' */
/* and then install this script */
/* */
/* Go to your profile page and setup the script at the bottom */
/* */
/* You do not need an API key to use this script */
/* nor do you need to change anything below */
/* */
/***********************************************************************/
//************************************************************* START OF SCRIPT *************************************************************//
//GLOBAL VARIABLES
//Get User ID
let USER_ID = JSON.parse(document.getElementById('__NEXT_DATA__').innerText).props.middlewareResults[0].account.user.userId;
//Checking Profile
let statsToProfile = false;
let setupToProfile = false;
let updateToProfile = false;
//Checking Duels Rounds
let player_index = 0;
let previous_last_guess_number = 0;
let checkingDuelsRoundOver = false;
let checkingDuelsGameOver = false;
//Checking Classic Rounds
let checkingClassicRoundOver = false;
//Map Colors
let green_range = 0.75;
let yellow_range = 0.25;
let red_range = 0;
//Set the map color ranges
if(window.localStorage.getItem(`duels-map-color-left-range-${USER_ID}`)){
green_range = parseInt(window.localStorage.getItem(`duels-map-color-right-range-${USER_ID}`)) * 0.01;
yellow_range = parseInt(window.localStorage.getItem(`duels-map-color-left-range-${USER_ID}`)) * 0.01;
}
else{
window.localStorage.setItem(`duels-map-color-left-range-${USER_ID}`, 25);
window.localStorage.setItem(`duels-map-color-right-range-${USER_ID}`, 75);
}
//Set the healing rounds toggle switch
if(window.localStorage.getItem('allow-healing-rounds') == null){
window.localStorage.setItem('allow-healing-rounds', JSON.stringify({include: true}));
}
//Set the competitive mode toggle switch
if(window.localStorage.getItem('competitive-only-mode') == null){
window.localStorage.setItem('competitive-only-mode', JSON.stringify({include: true}));
}
//Set the included maps
if(!window.localStorage.getItem(`geostats-classic-included-maps-${USER_ID}`)){
window.localStorage.setItem(`geostats-classic-included-maps-${USER_ID}`, JSON.stringify({ids: ['us-state-streak','country-streak']}));
}
//Evaluate the new duels guess
function evaluateDuelsGuess(guess,location,distance,userScore,opponentScore,startTime,timerTime,guessTime,opponentDistance){
if(guess == 'AQ'){
return;
}
let correct_exists = window.localStorage.getItem(`${location}-number-correct-${USER_ID}`);
let total_exists = window.localStorage.getItem(`${location}-number-total-${USER_ID}`);
let correct_overall = window.localStorage.getItem(`overall-correct-${USER_ID}`);
let total_overall = window.localStorage.getItem(`overall-total-${USER_ID}`);
let correct_value = 1;
let total_value = 1;
//Setting correct value
if(guess === location){
if(correct_exists !== null){
correct_value = parseInt(correct_exists,10);
correct_value = correct_value + 1;
}
window.localStorage.setItem(`${location}-number-correct-${USER_ID}`,correct_value);
}
//Setting overall values
if(total_overall !== null){
if(guess === location){
window.localStorage.setItem(`overall-correct-${USER_ID}`,((parseInt(correct_overall,10))+1));
}
window.localStorage.setItem(`overall-total-${USER_ID}`,((parseInt(total_overall,10))+1));
}
else{
if(guess === location){
window.localStorage.setItem(`overall-correct-${USER_ID}`,1);
}
else{
window.localStorage.setItem(`overall-correct-${USER_ID}`,0);
}
window.localStorage.setItem(`overall-total-${USER_ID}`,1);
}
//Setting total value
if(total_exists !== null){
total_value = parseInt(total_exists,10);
total_value = total_value + 1;
}
window.localStorage.setItem(`${location}-number-total-${USER_ID}`,total_value);
//Setting distance
let distance_average = window.localStorage.getItem(`${location}-distance-average-${USER_ID}`);
let distance_number = window.localStorage.getItem(`${location}-distance-number-${USER_ID}`);
if(distance_average === null && distance_number === null){
window.localStorage.setItem(`${location}-distance-average-${USER_ID}`,distance);
window.localStorage.setItem(`${location}-distance-number-${USER_ID}`,1);
}
else{
distance_number = parseInt(distance_number) + 1;
distance_average = ((distance_average * (distance_number - 1)) + distance) / distance_number;
window.localStorage.setItem(`${location}-distance-average-${USER_ID}`,distance_average);
window.localStorage.setItem(`${location}-distance-number-${USER_ID}`,distance_number);
}
//SETTING ALL OTHER STATS FOR COUNTRY AND OVERALL
let countryStats = {
totalCount: 0,
totalCorrect: 0,
averageScore: 0,
averageDistance: 0,
closerThanOpponent: 0,
averageTime: 0,
guessedFirst: 0,
total5ks: 0,
countryCorrectStreak: 0,
countryCorrectMax: 0,
countryWrongStreak: 0,
countryWrongMax: 0,
distanceFromOpponent: [0,0],
//Wrong country
incorrectCountry: {},
};
let overallStats = {
//Total
totalCount: 0,
totalCorrect: 0,
totalWin: 0,
totalLoss: 0,
total5ks: 0,
totalGames: 0,
totalSeconds: 0,
//Average
averageScore: 0,
averageDistance: 0,
averageGameLengthWin: 0,
averageGameLengthLoss: 0,
averageTime: 0,
//Wrong country
incorrectCountry: {},
//Other
guessedFirst: 0,
closerThanOpponent: 0,
countryCorrectStreak: 0,
countryCorrectMax: 0,
countryWrongStreak: 0,
countryWrongMax: 0,
opponentRating: 0,
distanceFromOpponent: [0,0],
};
if(window.localStorage.getItem(`${location}-all-country-stats-${USER_ID}`)){
countryStats = JSON.parse(window.localStorage.getItem(`${location}-all-country-stats-${USER_ID}`));
}
if(window.localStorage.getItem(`overall-country-stats-${USER_ID}`)){
overallStats = JSON.parse(window.localStorage.getItem(`overall-country-stats-${USER_ID}`));
}
//Time String to Seconds
function timeToSeconds(value){
let time = value.slice(11,19);
time = time.split(/[.:]/);
time = (parseInt(time[0]) * 60 * 60) + (parseInt(time[1]) * 60) + parseInt(time[2]);
return time;
}
//Get Correct Time Values
startTime = timeToSeconds(startTime);
timerTime = timeToSeconds(timerTime);
guessTime = timeToSeconds(guessTime);
let timeToGuess = guessTime - startTime;
//Total Count
countryStats.totalCount++;
overallStats.totalCount++;
//Total Correct
countryStats.totalCorrect = correct_value;
overallStats.totalCorrect = parseInt(correct_overall,10);
//Average Score
countryStats.averageScore = ((countryStats.averageScore * (countryStats.totalCount - 1)) + userScore) / countryStats.totalCount;
overallStats.averageScore = ((overallStats.averageScore * (overallStats.totalCount - 1)) + userScore) / overallStats.totalCount;
//Average Distance
countryStats.averageDistance = ((countryStats.averageDistance * (countryStats.totalCount - 1)) + distance) / countryStats.totalCount;
overallStats.averageDistance = ((overallStats.averageDistance * (overallStats.totalCount - 1)) + distance) / overallStats.totalCount;
//Average Time
if(timeToGuess >= 0){
countryStats.averageTime = ((countryStats.averageTime * (countryStats.totalCount - 1)) + timeToGuess) / countryStats.totalCount;
overallStats.averageTime = ((overallStats.averageTime * (overallStats.totalCount - 1)) + timeToGuess) / overallStats.totalCount;
}
//Closer Than Opponent
if(userScore >= opponentScore){
countryStats.closerThanOpponent++;
overallStats.closerThanOpponent++;
}
//Guessed First
if(guessTime == timerTime){
countryStats.guessedFirst++;
overallStats.guessedFirst++;
}
//Total 5ks
if(userScore == 5000){
countryStats.total5ks++;
overallStats.total5ks++;
}
//Country Streaks (Correct)
if(guess == location){
//Country
countryStats.countryWrongStreak = 0;
countryStats.countryCorrectStreak++;
if(countryStats.countryCorrectStreak > countryStats.countryCorrectMax){
countryStats.countryCorrectMax = countryStats.countryCorrectStreak;
}
//Overall
overallStats.countryWrongStreak = 0;
overallStats.countryCorrectStreak++;
if(overallStats.countryCorrectStreak > overallStats.countryCorrectMax){
overallStats.countryCorrectMax = overallStats.countryCorrectStreak;
}
}
//Country Streaks (Incorrect)
if(guess != location){
//Country
countryStats.countryCorrectStreak = 0;
countryStats.countryWrongStreak++;
if(countryStats.countryWrongStreak > countryStats.countryWrongMax){
countryStats.countryWrongMax = countryStats.countryWrongStreak;
}
//Overall
overallStats.countryCorrectStreak = 0;
overallStats.countryWrongStreak++;
if(overallStats.countryWrongStreak > overallStats.countryWrongMax){
overallStats.countryWrongMax = overallStats.countryWrongStreak;
}
}
//Wrong Country
if(guess != location){
//Overall
if(!overallStats.incorrectCountry){
overallStats.incorrectCountry = {};
}
if(location != 'ERROR'){
if(overallStats.incorrectCountry[`${location}`]){
overallStats.incorrectCountry[`${location}`]++;
}
else{
overallStats.incorrectCountry[`${location}`] = 1;
}
}
//Country
if(!countryStats.incorrectCountry){
countryStats.incorrectCountry = {};
}
if(guess != 'ERROR'){
if(countryStats.incorrectCountry[`${guess}`]){
countryStats.incorrectCountry[`${guess}`]++;
}
else{
countryStats.incorrectCountry[`${guess}`] = 1;
}
}
}
//Distance From Opponent
if(opponentDistance != 'DNF'){
let distanceDifference = opponentDistance - distance;
//Country
if(countryStats.distanceFromOpponent){
countryStats.distanceFromOpponent[0]++;
countryStats.distanceFromOpponent[1] = ((countryStats.distanceFromOpponent[1] * (countryStats.distanceFromOpponent[0] - 1)) + distanceDifference) / countryStats.distanceFromOpponent[0];
}
else{
countryStats.distanceFromOpponent = [1,distanceDifference];
}
//Overall
if(overallStats.distanceFromOpponent){
overallStats.distanceFromOpponent[0]++;
overallStats.distanceFromOpponent[1] = ((overallStats.distanceFromOpponent[1] * (overallStats.distanceFromOpponent[0] - 1)) + distanceDifference) / overallStats.distanceFromOpponent[0];
}
else{
overallStats.distanceFromOpponent = [1,distanceDifference];
}
}
//Save Updated Stats
window.localStorage.setItem(`${location}-all-country-stats-${USER_ID}`, JSON.stringify(countryStats));
window.localStorage.setItem(`overall-country-stats-${USER_ID}`, JSON.stringify(overallStats));
};
//Add Stats When Duels Game Is Finished
function duelsGameFinished(userHealth,opponentHealth,opponentRating,userBefore,userAfter,gameId,gameLength,start,end){
if(window.sessionStorage.getItem('current-game-id') == gameId){
return;
}
window.sessionStorage.setItem('current-game-id', gameId);
//Time String to Seconds
function timeToSeconds(value){
let time = value.slice(11,19);
time = time.split(/[.:]/);
time = (parseInt(time[0]) * 60 * 60) + (parseInt(time[1]) * 60) + parseInt(time[2]);
return time;
}
let overallStats = JSON.parse(window.localStorage.getItem(`overall-country-stats-${USER_ID}`));
let gameTime = timeToSeconds(end) - timeToSeconds(start);
//If there is a calculation error (end is smaller than start)
if(gameTime < 0){
gameTime = 0;
}
if(overallStats.totalSeconds < 0){
overallStats.totalSeconds = 0;
}
//Total Games Played
overallStats.totalGames++;
//Average Opponent Rating
overallStats.opponentRating = ((overallStats.opponentRating * (overallStats.totalGames - 1)) + opponentRating) / overallStats.totalGames;
//Win or Loss
let win = false;
if(userHealth > opponentHealth){
win = true;
}
//Game Length (Win)
if(win){
overallStats.totalWin++;
overallStats.averageGameLengthWin = ((overallStats.averageGameLengthWin * (overallStats.totalWin - 1)) + gameLength) / overallStats.totalWin;
}
//Game Length (Loss)
if(!win){
overallStats.totalLoss++;
overallStats.averageGameLengthLoss = ((overallStats.averageGameLengthLoss * (overallStats.totalLoss - 1)) + gameLength) / overallStats.totalLoss;
}
//Total Seconds Played
if(overallStats.totalSeconds){
overallStats.totalSeconds += gameTime;
}
else{
overallStats.totalSeconds = gameTime;
}
//Average Rating Change
if(userBefore != null && userAfter != null){
if(!overallStats.averageRatingChange){
overallStats.averageRatingChange = {
win: [0,0],
loss: [0,0],
};
}
if(win){
overallStats.averageRatingChange.win[0]++;
overallStats.averageRatingChange.win[1] = ((overallStats.averageRatingChange.win[1] * (overallStats.averageRatingChange.win[0] - 1)) + (userAfter-userBefore)) / overallStats.averageRatingChange.win[0];
}
else if(!win){
overallStats.averageRatingChange.loss[0]++;
overallStats.averageRatingChange.loss[1] = ((overallStats.averageRatingChange.loss[1] * (overallStats.averageRatingChange.loss[0] - 1)) + (userAfter-userBefore)) / overallStats.averageRatingChange.loss[0];
}
}
//Save Updated Stats
window.localStorage.setItem(`overall-country-stats-${USER_ID}`, JSON.stringify(overallStats));
};
//Check the country code
function checkGuessCountryCode(out){
let countryCode = 'NO CODE';
if(out.address.country_code){
countryCode = out.address.country_code;
}
//Check for US territories
if(countryCode == 'us'){
//Puerto Rico
if(out.address['ISO3166-2-lvl4'] == 'US-PR'){
countryCode = 'pr';
}
//Guam
if(out.address['ISO3166-2-lvl4'] == 'US-GU'){
countryCode = 'gu';
}
//Northern Mariana Islands
if(out.address['ISO3166-2-lvl4'] == 'US-MP'){
countryCode = 'mp';
}
//Virgin Islands
if(out.address['ISO3166-2-lvl4'] == 'US-VI'){
countryCode = 'vi';
}
//American Samoa
if(out.address['ISO3166-2-lvl4'] == 'US-AS'){
countryCode = 'as';
}
}
//US Minor Outlying Islands
if(countryCode == 'um'){
countryCode = 'us';
}
//Check for AU territories
if(countryCode == 'au'){
//Cocos Islands
if(out.address['territory'] == 'Cocos (Keeling) Islands'){
countryCode = 'cc';
}
//Christmas Island
if(out.address['territory'] == 'Christmas Island'){
countryCode = 'cx';
}
}
//Check for NL territories
if(countryCode == 'nl'){
//CuraƧao
if(out.address['ISO3166-2-lvl3'] == 'NL-CW'){
countryCode = 'cw';
}
}
//Check for Palestine
if(countryCode == 'ps'){
countryCode = 'il';
}
//Check for Hong Kong & Macau
if(countryCode == 'cn'){
if(out.address['ISO3166-2-lvl3']){
if(out.address['ISO3166-2-lvl3'] == 'CN-HK'){
countryCode = 'hk';
}
else if(out.address['ISO3166-2-lvl3'] == 'CN-MO'){
countryCode = 'mo';
}
}
}
return countryCode;
};
//Get the guess country code
async function getGuessCountryCode(location){
if(location[0] <= -85.05 || location == null){
return 'AQ';
}
else{
let api = "https://nominatim.openstreetmap.org/reverse.php?lat="+location[0]+"&lon="+location[1]+"&format=jsonv2";
let country_code = await fetch(api)
.then(res => res.json())
.then((out) => {
return checkGuessCountryCode(out);
}).catch(err => {return 'ERROR'});
return country_code.toUpperCase();
};
};
//Check if a new duels guess has been made
async function checkDuelsGuess(api){
return new Promise((resolve,reject) => {
fetch(api,{credentials: 'include'})
.then((res) => res.json())
.then((out) => {
if(out.teams[0].players[0].playerId === USER_ID){
player_index = 0;
}
else if(out.teams[1].players[0].playerId === USER_ID){
player_index = 1;
}
else{
return;
}
//If competitve only mode is on
let competitiveOnly = JSON.parse(window.localStorage.getItem('competitive-only-mode'));
if(competitiveOnly.include && !out.options.isRated){
return;
}
let last_guess_number = out.teams[player_index].players[0].guesses.length;
//If the game is finished
if(out.status == 'Finished'){
let opponentIndex = 0;
if(player_index == 0){
opponentIndex = 1;
}
let userRatingBefore = null;
let userRatingAfter = null;
if(out.options.isRated){
userRatingBefore = out.teams[player_index].players[0].progressChange.competitiveProgress.ratingBefore;
userRatingAfter = out.teams[player_index].players[0].progressChange.competitiveProgress.ratingAfter;
}
let opponentRatingBefore = out.teams[opponentIndex].players[0].rating;
let userHealth = out.teams[player_index].health;
let opponentHealth = out.teams[opponentIndex].health;
let gameLength = out.currentRoundNumber;
let gameStartTime = out.rounds[0].startTime;
let gameEndTime = out.rounds[gameLength-1].endTime;
duelsGameFinished(userHealth,opponentHealth,opponentRatingBefore,userRatingBefore,userRatingAfter,out.gameId,gameLength,gameStartTime,gameEndTime);
return;
}
//If the round's guesses haven't been sent
if(out.teams[player_index].roundResults.length != last_guess_number){
return;
}
//If a new guess hasn't been made
if(last_guess_number == previous_last_guess_number){
return;
}
else if(out.teams[player_index].players[0].guesses[last_guess_number-1].roundNumber !== out.currentRoundNumber){
return;
}
//If include healing toggle is off
let allowHealing = JSON.parse(window.localStorage.getItem('allow-healing-rounds'));
if(!allowHealing.include && out.rounds[out.currentRoundNumber-1].isHealingRound){
return;
}
let current_guess = [out.teams[player_index].players[0].guesses[last_guess_number-1].lat, out.teams[player_index].players[0].guesses[last_guess_number-1].lng];
//If the player refreshes during the 15 second countdown after making a guess
if(current_guess[0] == window.sessionStorage.getItem('last-guess-lat') && current_guess[1] == window.sessionStorage.getItem('last-guess-lng')){
return;
}
else{
window.sessionStorage.setItem('last-guess-lat', current_guess[0]);
window.sessionStorage.setItem('last-guess-lng', current_guess[1]);
}
//Everything is good
previous_last_guess_number = last_guess_number;
let current_round = out.currentRoundNumber;
getGuessCountryCode(current_guess)
.then((guess) => {
//Get all values
let location_code = out.rounds[current_round-1].panorama.countryCode.toUpperCase();
let distance = out.teams[player_index].players[0].guesses[last_guess_number-1].distance;
let opponent_index = 0;
if(player_index == 0){
opponent_index = 1;
}
let userScore = out.teams[player_index].roundResults[last_guess_number-1].score;
let opponentScore = out.teams[opponent_index].roundResults[last_guess_number-1].score;
let startTime = out.rounds[current_round-1].startTime;
let timerTime = out.rounds[current_round-1].timerStartTime;
let guessTime = out.teams[player_index].players[0].guesses[last_guess_number-1].created;
let opponentDistance = 'DNF';
let opponentGuess = out.teams[opponent_index].players[0];
if(opponentGuess.guesses[opponentGuess.guesses.length-1] && opponentGuess.guesses[opponentGuess.guesses.length-1].roundNumber == current_round){
opponentDistance = opponentGuess.guesses[opponentGuess.guesses.length-1].distance;
}
//If guess is good
if(guess != undefined){
//Check location code
location_code = checkGuessCountryCode({address:{country_code:location_code}});
//Evaluate all values and update stats
evaluateDuelsGuess(guess,location_code,distance,userScore,opponentScore,startTime,timerTime,guessTime,opponentDistance);
}
resolve(out);
});
})
.catch((error) => {
reject(error);
});
});
};
//Evaluate The Stats For The Finished Classic Game
function evaluateClassicGameFinished(out){
if(out.mode == 'streak'){
//Evaluate Country Streaks Game Stats
if(out.streakType == 'countrystreak'){
}
//Evaluate USA Streaks Game Stats
else if(out.streakType == 'usstatestreak'){
}
}
//Evaluate Standard Game Stats
else if(out.mode == 'standard'){
let overallStats = JSON.parse(window.localStorage.getItem(`geostats-overall-standard-stats-${USER_ID}`));
overallStats.totalGames++;
overallStats.totalSeconds += out.player.totalTime;
overallStats.averageGameTime = ((overallStats.averageGameTime * (overallStats.totalGames - 1)) + out.player.totalTime) / overallStats.totalGames;
//HIGHSCORE STUFF HERE
//Save Updated Stats
window.localStorage.setItem(`geostats-overall-standard-stats-${USER_ID}`, JSON.stringify(overallStats));
}
};
//Evaluate The Guess For The Finished Classic Round
function evaluateClassicRoundFinished(out){
if(out.mode == 'streak'){
//Evaluate Country Streaks Round Stats
if(out.streakType == 'countrystreak'){
}
//Evaluate USA Streaks Game Stats
else if(out.streakType == 'usstatestreak'){
}
}
else if(out.mode == 'standard'){
//Evaluate Standard Game Stats
let current_guess = [out.player.guesses[out.player.guesses.length-1].lat, out.player.guesses[out.player.guesses.length-1].lng];
let current_location = [out.rounds[out.player.guesses.length-1].lat, out.rounds[out.player.guesses.length-1].lng];
//If the guess timed out
if(out.player.guesses[out.player.guesses.length-1].timedOut){
return;
}
getGuessCountryCode(current_guess)
.then(guess => {
getGuessCountryCode(current_location)
.then(location => {
let standardCountryStats = {
//Total
totalCount: 0,
totalCorrect: 0,
totalSeconds: 0,
total5ks: 0,
//Average
averageScore: 0,
averageDistance: 0,
averageRoundTime: 0,
//Wrong country
incorrectCountry: {},
//Streak
countryCorrectStreak: 0,
countryCorrectMax: 0,
countryWrongStreak: 0,
countryWrongMax: 0,
};
let standardOverallStats = {
//Total
totalCount: 0,
totalCorrect: 0,
totalGames: 0,
totalSeconds: 0,
total5ks: 0,
//Average
averageScore: 0,
averageDistance: 0,
averageRoundTime: 0,
averageGameTime: 0,
//Wrong country
incorrectCountry: {},
//5k locations:
all5kLocations: [],
//Streak
countryCorrectStreak: 0,
countryCorrectMax: 0,
countryWrongStreak: 0,
countryWrongMax: 0,
};
//Get Exisiting Stats
if(window.localStorage.getItem(`geostats-${location}-all-standard-stats-${USER_ID}`)){
standardCountryStats = JSON.parse(window.localStorage.getItem(`geostats-${location}-all-standard-stats-${USER_ID}`));
}
if(window.localStorage.getItem(`geostats-overall-standard-stats-${USER_ID}`)){
standardOverallStats = JSON.parse(window.localStorage.getItem(`geostats-overall-standard-stats-${USER_ID}`));
}
//Useful variables
let score = out.player.guesses[out.player.guesses.length-1].roundScoreInPoints;
let distance = out.player.guesses[out.player.guesses.length-1].distanceInMeters;
let time = out.player.guesses[out.player.guesses.length-1].time;
//Country Total
standardCountryStats.totalCount++;
standardOverallStats.totalCount++;
//Country Correct
if(guess == location){
//Country
standardCountryStats.totalCorrect++;
standardCountryStats.countryWrongStreak = 0;
standardCountryStats.countryCorrectStreak++;
if(standardCountryStats.countryCorrectStreak > standardCountryStats.countryCorrectMax){
standardCountryStats.countryCorrectMax = standardCountryStats.countryCorrectStreak;
}
//Overall
standardOverallStats.totalCorrect++;
standardOverallStats.countryWrongStreak = 0;
standardOverallStats.countryCorrectStreak++;
if(standardOverallStats.countryCorrectStreak > standardOverallStats.countryCorrectMax){
standardOverallStats.countryCorrectMax = standardOverallStats.countryCorrectStreak;
}
}
//Country Incorrect
else{
//Country
standardCountryStats.countryCorrectStreak = 0;
standardCountryStats.countryWrongStreak++;
if(standardCountryStats.countryWrongStreak > standardCountryStats.countryWrongMax){
standardCountryStats.countryWrongMax = standardCountryStats.countryWrongStreak;
}
if(guess != 'ERROR'){
if(standardCountryStats.incorrectCountry[`${guess}`]){
standardCountryStats.incorrectCountry[`${guess}`]++;
}
else{
standardCountryStats.incorrectCountry[`${guess}`] = 1;
}
}
//Overall
standardOverallStats.countryCorrectStreak = 0;
standardOverallStats.countryWrongStreak++;
if(standardOverallStats.countryWrongStreak > standardOverallStats.countryWrongMax){
standardOverallStats.countryWrongMax = standardOverallStats.countryWrongStreak;
}
if(location != 'ERROR'){
if(standardOverallStats.incorrectCountry[`${location}`]){
standardOverallStats.incorrectCountry[`${location}`]++;
}
else{
standardOverallStats.incorrectCountry[`${location}`] = 1;
}
}
}
//Average Score
standardCountryStats.averageScore = ((standardCountryStats.averageScore * (standardCountryStats.totalCount - 1)) + score) / standardCountryStats.totalCount;
standardOverallStats.averageScore = ((standardOverallStats.averageScore * (standardOverallStats.totalCount - 1)) + score) / standardOverallStats.totalCount;
//Average Distance
standardCountryStats.averageDistance = ((standardCountryStats.averageDistance * (standardCountryStats.totalCount - 1)) + distance) / standardCountryStats.totalCount;
standardOverallStats.averageDistance = ((standardOverallStats.averageDistance * (standardOverallStats.totalCount - 1)) + distance) / standardOverallStats.totalCount;
//Average Round Time
standardCountryStats.averageRoundTime = ((standardCountryStats.averageRoundTime * (standardCountryStats.totalCount - 1)) + time) / standardCountryStats.totalCount;
standardOverallStats.averageRoundTime = ((standardOverallStats.averageRoundTime * (standardOverallStats.totalCount - 1)) + time) / standardOverallStats.totalCount;
//Total Seconds
standardCountryStats.totalSeconds += time;
//Total 5ks
if(score == 5000){
standardCountryStats.total5ks++;
standardOverallStats.total5ks++;
standardOverallStats.all5kLocations.push({lat: out.rounds[out.player.guesses.length-1].lat, lng: out.rounds[out.player.guesses.length-1].lng, id: out.token, map: out.map, round: out.player.guesses.length-1});
}
//Save Updated Stats
window.localStorage.setItem(`geostats-${location}-all-standard-stats-${USER_ID}`, JSON.stringify(standardCountryStats));
window.localStorage.setItem(`geostats-overall-standard-stats-${USER_ID}`, JSON.stringify(standardOverallStats));
});
});
}
};
//Add The Classic Game Id (if needed)
function addGameId(newId){
if(!window.localStorage.getItem(`geostats-unfinished-classic-games-${USER_ID}`)){
window.localStorage.setItem(`geostats-unfinished-classic-games-${USER_ID}`, JSON.stringify({gameIds:[]}));
}
let allGames = JSON.parse(window.localStorage.getItem(`geostats-unfinished-classic-games-${USER_ID}`));
if(!allGames.gameIds.includes(newId)){
allGames.gameIds.push(newId);
}
//Save Updated Ids
window.localStorage.setItem(`geostats-unfinished-classic-games-${USER_ID}`, JSON.stringify(allGames));
};
//Check if the user is on the profile page
function profileCheck(){
if(location.pathname.endsWith('/profile')){
if(window.localStorage.getItem(`geostats-setup-complete-${USER_ID}`)){
if(!window.localStorage.getItem(`geostats-update-2.2.1-complete-${USER_ID}`) && !updateToProfile){
addUpdateToProfile();
}
else if(window.localStorage.getItem(`geostats-update-2.2.1-complete-${USER_ID}`) && !statsToProfile){
USER_ID = JSON.parse(document.getElementById('__NEXT_DATA__').innerText).props.middlewareResults[0].account.user.userId;
addMapToProfile();
}
}
else if(!window.localStorage.getItem(`geostats-setup-complete-${USER_ID}`) && !setupToProfile){
addSetupPageToProfile();
}
}
else if(!location.pathname.endsWith('/profile')){
if(statsToProfile){
statsToProfile = false;
document.getElementById('map-wrapper-element').remove();
document.getElementById('css-for-map').remove();
}
else if(setupToProfile){
setupToProfile = false;
document.getElementById('geostats-setup-css').remove();
document.getElementById('geostats-setup-html').remove();
}
else if(updateToProfile){
updateToProfile = false;
document.getElementById('geostats-update-css').remove();
document.getElementById('geostats-update-html').remove();
}
}
};
//Check if the user is playing a classic game
function classicCheck(){
if(!location.pathname.startsWith('/game/')){
return;
}
//If a round has finished
if(document.getElementsByClassName('result-layout_root__NfX12').length > 0){
const game_tag = window.location.href.substring(window.location.href.lastIndexOf('/') + 1);
const api_url = 'https://www.geoguessr.com/api/v3/games/' + game_tag;
if(!checkingClassicRoundOver){
checkingClassicRoundOver = true;
fetch(api_url)
.then((res) => res.json())
.then((out) => {
//Check if the map is included in the selected maps
if(!window.localStorage.getItem(`geostats-classic-included-maps-${USER_ID}`)){
window.localStorage.setItem(`geostats-classic-included-maps-${USER_ID}`, JSON.stringify({ids: ['us-state-streak','country-streak']}));
}
let mapId = out.map;
let includedMaps = JSON.parse(window.localStorage.getItem(`geostats-classic-included-maps-${USER_ID}`));
if(!includedMaps.ids.includes(mapId)){
return;
}
//IF THE GAME IS FINISHED
if(out.state == 'finished'){
if(window.localStorage.getItem(`geostats-unfinished-classic-games-${USER_ID}`)){
let allGames = JSON.parse(window.localStorage.getItem(`geostats-unfinished-classic-games-${USER_ID}`));
if(allGames.gameIds.length > 0 && allGames.gameIds.includes(game_tag)){
//Remove the game id from unfinished games
const index = allGames.gameIds.indexOf(game_tag);
allGames.gameIds.splice(index,1);
window.localStorage.setItem(`geostats-unfinished-classic-games-${USER_ID}`, JSON.stringify(allGames));
evaluateClassicRoundFinished(out);
evaluateClassicGameFinished(out);
}
}
else{
return;
}
}
//IF THE GAME IS NOT FINISHED
else{
evaluateClassicRoundFinished(out);
addGameId(game_tag);
}
})
.catch((error) => {
throw error;
});
}
}
else{
checkingClassicRoundOver = false;
}
};
//Check if the user is playing a duels game
function duelsCheck(){
if(!location.pathname.startsWith('/duels/') || location.pathname.endsWith('/summary')){
return;
}
const game_tag = window.location.href.substring(window.location.href.lastIndexOf('/') + 1);
const api_url = "https://game-server.geoguessr.com/api/duels/"+game_tag;
//If a round has finished
if(document.getElementsByClassName('overlay_overlay__AR02x').length > 0){
//If the round is finished
if(document.getElementsByClassName('round-score_container__s6qNg').length > 0){
if(!checkingDuelsRoundOver){
checkingDuelsRoundOver = true;
checkDuelsGuess(api_url);
}
}
//If the game is finished
else if(document.getElementsByClassName('game-finished_container___UprU').length > 0){
if(!checkingDuelsGameOver){
checkingDuelsGameOver = true;
checkDuelsGuess(api_url);
}
}
}
else{
checkingDuelsRoundOver = false;
checkingDuelsGameOver = false;
}
};
//Check if the user is about to start a standard game
function startpageCheck(){
if(location.pathname.startsWith('/maps/') && location.pathname.endsWith('/play')){
if(!document.getElementById('geostats-standard-game-start-page-toggle-html')){
addToggleToStartPage();
}
}
};
//Run duelsCheck twice every second
setInterval(duelsCheck,500);
//Run classicCheck four times every second
setInterval(classicCheck,250);
//Run profileCheck twice every second
setInterval(profileCheck,500);
//Console Log Script Name
console.log('*** Geoguessr GeoStats v2.2.1 by NappySlappy ***');
/************************************************** UPDATE STUFF HERE **************************************************/
function addUpdateToProfile(){
updateToProfile = true;
//Create The Update Elements
const cssForUpdate = document.createElement('style');
cssForUpdate.setAttribute('id','geostats-update-css');
const htmlForUpdate = document.createElement('div');
htmlForUpdate.setAttribute('id','geostats-update-html');
const scriptForUpdate = document.createElement('script');
scriptForUpdate.setAttribute('id','geostats-update-script');
//CSS For Update
cssForUpdate.textContent = `
#update-page-title-wrapper{
margin: 20px auto;
text-align: center;
}
#update-page-title{
font-family: var(--font-neo-sans);
font-size: 40px;
color: white;
}
#update-page-content-wrapper{
margin: 20px auto;
text-align: center;
width: 65%;
border: solid 2px white;
border-radius: 40px;
}
#update-page-content{
font-family: var(--font-neo-sans);
font-size: 20px;
color: white;
padding: 20px;
}
#update-page-button-wrapper{
margin: 20px auto;
text-align: center;
}
#update-page-button{
border-radius: 15px;
background-color: transparent;
color: white;
border-color: white;
padding: 5px 10px 5px 10px;
}
#update-page-button:hover{
background-color: white;
color: black;
border-color: black;
cursor: pointer;
}
`;
//HTML For Update
htmlForUpdate.innerHTML = `
GeoStats Update v2.2.1
`;
//Script For Update
scriptForUpdate.textContent = `
{
let currentSlide = 0;
let firstSlide = 'Minor Bug Fixes';
let allSliders = [firstSlide];
function changeSlide(){
currentSlide++;
if(currentSlide == allSliders.length){
window.localStorage.setItem('geostats-update-2.2.1-complete-${USER_ID}', new Date());
document.getElementById('geostats-update-css').remove();
document.getElementById('geostats-update-html').remove();
}
else{
document.getElementById('update-page-content').textContent = allSliders[currentSlide];
}
}
document.getElementById('update-page-content').textContent = allSliders[0];
document.getElementById('update-page-button').addEventListener('click', changeSlide);
}
`;
//Add Everything To The Page
let referenceNode = document.getElementsByClassName('version3_main__xNkED')[0];
let siblingNode = document.getElementsByClassName('footer_footer__NmtmJ')[0];
referenceNode.parentNode.insertBefore(htmlForUpdate, siblingNode);
document.head.appendChild(cssForUpdate);
document.getElementById('geostats-update-html').appendChild(scriptForUpdate);
}
/************************************************** SETUP STUFF HERE **************************************************/
//Add the setup page to the bottom of the profile page when the user uses the script for the first time
function addSetupPageToProfile(){
setupToProfile = true;
//Create The Setup Elements
const cssForSetup = document.createElement('style');
cssForSetup.setAttribute('id','geostats-setup-css');
const htmlForSetup = document.createElement('div');
htmlForSetup.setAttribute('id','geostats-setup-html');
const scriptForSetup = document.createElement('script');
scriptForSetup.setAttribute('id','geostats-setup-script');
//CSS For Setup
cssForSetup.textContent = `
#setup-page-title-wrapper{
margin: 20px auto;
text-align: center;
}
#setup-page-title{
font-family: var(--font-neo-sans);
font-size: 40px;
color: white;
}
#setup-page-content-wrapper{
margin: 20px auto;
text-align: center;
width: 65%;
border: solid 2px white;
border-radius: 40px;
}
#setup-page-content{
font-family: var(--font-neo-sans);
font-size: 20px;
color: white;
padding: 20px;
}
#setup-page-button-wrapper{
margin: 20px auto;
text-align: center;
}
#setup-page-button{
border-radius: 15px;
background-color: transparent;
color: white;
border-color: white;
padding: 5px 10px 5px 10px;
}
#setup-page-button:hover{
background-color: white;
color: black;
border-color: black;
cursor: pointer;
}
`;
//HTML For Setup
htmlForSetup.innerHTML = `
Welcome To GeoStats!
`;
//SCRIPT For Setup
scriptForSetup.textContent = `
{
let currentSlide = 0;
let firstSlide = "This script was made to keep track of various stats in your games. It will monitor your guesses and keep a unique record of stats for each country, as well as for your overall stats. If there is a round where you don't make a guess, it won't count against you. Currently supported gamemodes are: Duels and Classic";
let secondSlide = "All of the stats will be visible at the bottom of your profile page. Some countries are too small to show on the map so there is a search bar on the left side to filter through them. You can hover over a country to see your percentage of getting it correct and double click it to view more detailed stats. You can also use 'shift + scroll' to zoom into the map.";
let thirdSlide = "You can reset your stats by clicking the 'Reset All Stats' button in settings, as well as for individual countries. Keep in mind that all information is stored in your browser on your device so if you want the same stats on different devices/browsers you will need to download a file of your stats (located in settings) and upload the same file on the other device/browser. This also means that clearing your browser cache will unfortunatlely also clear all of your stats.";
let fourthSlide = "The creator of this script is NappySlappy. Please leave some feedback if you like the script or if you have any ideas for improvements. Thanks! :)";
let allSliders = [firstSlide,secondSlide,thirdSlide,fourthSlide];
function changeSlide(){
currentSlide++;
if(currentSlide == allSliders.length){
window.localStorage.setItem('geostats-setup-complete-${USER_ID}', new Date());
document.getElementById('geostats-setup-css').remove();
document.getElementById('geostats-setup-html').remove();
}
else{
if(currentSlide == allSliders.length-1){
document.getElementById('setup-page-button').textContent = 'View Stats';
}
document.getElementById('setup-page-content').textContent = allSliders[currentSlide];
}
}
document.getElementById('setup-page-content').textContent = allSliders[0];
document.getElementById('setup-page-button').addEventListener('click', changeSlide);
}
`;
//Add Everything To The Page
let referenceNode = document.getElementsByClassName('version3_main__xNkED')[0];
let siblingNode = document.getElementsByClassName('footer_footer__NmtmJ')[0];
referenceNode.parentNode.insertBefore(htmlForSetup, siblingNode);
document.head.appendChild(cssForSetup);
document.getElementById('geostats-setup-html').appendChild(scriptForSetup);
};
/************************************************** STATS STUFF HERE **************************************************/
//Add the map (and related stuff) to the bottom of the profile page
function addMapToProfile(){
statsToProfile = true;
const svgMap = document.createElement('div');
svgMap.setAttribute('id','map-wrapper-element');
const cssForMap = document.createElement('style');
cssForMap.setAttribute('id', 'css-for-map');
const scriptForMap = document.createElement('script');
scriptForMap.setAttribute('id', 'script-for-map');
cssForMap.textContent = `
.map-wrapper-element{
position: relative;
left: 0px;
}
#map-title{
font-size: 30px;
text-align: center;
color: var(--ds-color-yellow-50);
font-family: var(--font-neo-sans);
}
.geostats-gamemodes-menu-item:hover{
cursor: pointer;
}
#total-percentage-wrapper{
width: 100%;
background-color: gray;
height: 50px;
position: relative;
}
#total-percentage-text-wrapper{
position: absolute;
left: 0;
right: 0;
height: 100%;
}
#total-percentage-text{
display: flex;
font-size: 20px;
height: 100%;
justify-content: center;
align-items: center;
color: black;
}
#total-percentage-bar{
width: 50%;
height: 100%;
background-color: gold;
}
.display-wrapper{
margin: 0 auto;
padding: 10px;
width: fit-content;
font-size: 20px;
}
.display-wrapper #display-country-details{
visibility: show;
color: white;
}
.display-wrapper #display-country-distance{
visibility: show;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.map-wrapper{
margin: 0 auto;
pointer-events: none;
padding-bottom: 25px;
}
#world-map {
display: block;
position: relative;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: auto;
transform: scale(1);
transform-origin: 0px 0px;
z-index: 2;
border-top-style: solid;
border-bottom-style: solid;
border-width: 0.5px;
border-color: #fbfafa;
}
#world-map path{
stroke: white;
fill: black;
transition: fill 0.3s ease;
pointer-events: all;
}
#world-map path:hover{
fill: rgb(175, 175, 175);
pointer-events: all;
cursor: pointer;
}
#search-bar-wrapper{
pointer-events: all;
position: absolute;
z-index: 3;
}
#search-bar {
box-sizing: border-box;
z-index: 3;
}
#search-bar-list {
list-style: none;
display: none;
z-index: 3;
}
#search-bar-list li {
padding: 10px;
width: 73.5%;
border-bottom: 2px solid #ffffff;
z-index: 3;
text-align: center;
}
#search-bar-list li:hover {
background: #ffffff;
color: #000000;
cursor: pointer;
}
#overall-stats-page-wrapper{
}
#overall-stats-display-details{
color: var(--ds-color-yellow-50);
margin: 0 auto;
width: fit-content;
font-size: 30px;
padding: 20px;
}
#overall-stats-values-progress-circles{
display: flex;
height: 300px;
flex-direction: row;
flex-wrap: wrap;
}
#overall-stats-values-bottom{
border-top: .0625rem solid;
margin-top: 360px;
margin-bottom: 50px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.overall-stats-bottom-elements{
margin: 20px 0;
width: 33.333%;
text-align: center;
display: flex;
flex-direction: column;
}
#overall-stats-distance-from-opponent-value{
font-size: 30px;
width: 50%;
margin: 20px 25%;
}
#overall-stats-total-play-time-value{
font-size: 30px;
width: 50%;
margin: 20px 25%;
}
#country-stats-page-wrapper{
margin-top: 10px;
}
#country-stats-display-title{
margin: 0 auto;
padding: 10px;
width: fit-content;
font-size: 20px;
}
#country-stats-display-details{
visibility: show;
color: white;
}
#country-stats-wrapper{
}
#country-stats-values{
display: flex;
height: 300px;
flex-direction: row;
flex-wrap: wrap;
}
.country-stat-wrapper{
width: 33.333%;
height: 50%;
text-align: center;
display: flex;
flex-direction: column;
}
.country-stat-outer-circle{
position: relative;
height: 100px;
width: 100px;
border-radius: 50%;
margin: auto;
}
.country-stat-inner-circle{
position: absolute;
height: 85%;
width: 85%;
border-radius: 50%;
background-color: #1a1a2e;
top: 0; bottom: 0; left: 0; right: 0;
margin: auto;
}
.country-stat-value-wrapper{
display: flex;
align-items: center;
justify-content: center;
color: white;
height: 100%;
}
.country-stat-value{
font-size: 25px;
}
.country-stat-title{
position: relative;
color: #ffffff;
margin: auto;
}
.country-stat-spacing-wrapper{
width: 100%;
height: 25%;
}
#country-stats-values-bottom{
border-top: .0625rem solid;
margin-top: 100px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.country-stats-bottom-elements{
margin: 20px 0;
width: 50%;
text-align: center;
display: flex;
flex-direction: column;
}
#country-stats-distance-from-opponent-value{
font-size: 30px;
width: 50%;
margin: 20px 25%;
}
#country-stats-reset-btn-wrapper{
padding: 20px 0px 100px 0px;
text-align: center;
}
#country-stats-reset-btn{
border-color: red;
background-color: red;
color: white;
}
#country-stats-reset-btn:hover{
cursor: pointer;
}
#map-settings-wrapper{
var(--font-neo-sans);
text-align: center;
display: none;
}
#map-settings-title{
font-size: 40px;
margin-top: 20px;
padding-bottom: 20px;
}
#map-settings-content{
}
#settings-map-color-ranges-wrapper{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
}
#map-color-ranges-slider-wrapper{
position: relative;
}
#slider-output-wrapper{
position: relative;
margin-top: 20px;
width: 100%;
}
#left-slider-output{
position: absolute;
left: 50%;
}
#right-slider-output{
position: absolute;
left: 50%;
}
#map-color-ranges-slider{
position: relative;
width: 100%;
height: 100px;
margin-top: 0px;
}
#slider-track{
width: 100%;
height: 5px;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
border-radius: 5px;
}
.map-color-ranges{
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 100%;
outline: none;
position: absolute;
margin: 0px -50%;
top: 0;
bottom: 0;
background-color: transparent;
pointer-events: none;
border-color: transparent;
padding: 0px;
}
.map-color-ranges::-webkit-slider-runnable-track{
-webkit-appearance: none;
height: 5px;
}
.map-color-ranges::-webkit-slider-thumb{
-webkit-appearance: none;
height: 1.7em;
width: 1.7em;
background-color: #ffffff;
cursor: pointer;
margin-top: -9px;
pointer-events: auto;
border-radius: 50%;
border: 1px solid #808080;
}
#settings-toggles-wrapper{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
text-align: center;
display: flex;
}
#settings-allow-healing-rounds-wrapper{
flex: 1;
}
#settings-allow-healing-rounds{
height: 0;
width: 0;
visibility: hidden;
}
#label-allow-healing{
cursor: pointer;
text-indent: -9999px;
width: 50px;
height: 25px;
background: gray;
display: block;
border-radius: 25px;
position: relative;
margin: auto;
}
#label-allow-healing:after{
content: '';
position: absolute;
top: 1.25px;
left: 3px;
width: 22.5px;
height: 22.5px;
background: #fff;
border-radius: 22.5px;
transition: 0.3s;
}
#settings-allow-healing-rounds:checked + #label-allow-healing{
background: #bada55;
}
#settings-allow-healing-rounds:checked + #label-allow-healing:after{
left: calc(100% - 5px);
transform: translateX(-100%);
}
#label-allow-healing:active:after{
width: 32.5px;
}
#settings-competitive-only-mode-wrapper{
flex: 1;
}
#settings-competitive-only-mode{
height: 0;
width: 0;
visibility: hidden;
}
#label-competitive-only{
cursor: pointer;
text-indent: -9999px;
width: 50px;
height: 25px;
background: gray;
display: block;
border-radius: 25px;
position: relative;
margin: auto;
}
#label-competitive-only:after{
content: '';
position: absolute;
top: 1.25px;
left: 3px;
width: 22.5px;
height: 22.5px;
background: #fff;
border-radius: 22.5px;
transition: 0.3s;
}
#settings-competitive-only-mode:checked + #label-competitive-only{
background: #bada55;
}
#settings-competitive-only-mode:checked + #label-competitive-only:after{
left: calc(100% - 5px);
transform: translateX(-100%);
}
#label-competitive-only:active:after{
width: 32.5px;
}
#unit-selector{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
}
#unit-selector-mi,
#unit-selector-km{
accent-color: #bada55;
}
#unit-selector-mi:hover,
#unit-selector-km:hover{
cursor: pointer;
}
#settings-import-and-export-wrapper{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
display: flex;
}
.download-upload-buttons{
border: 1px solid #ccc;
border-radius: 15px;
background-color: transparent;
color: white;
border-color: white;
cursor: pointer;
padding: 5px 10px 5px 10px;
}
.download-upload-buttons:hover{
background-color: white;
color: black;
}
#settings-export-wrapper{
flex: 1;
}
#download-file-status{
padding-top: 7px;
}
#settings-import-wrapper{
flex: 1;
}
#settings-import-content{
display: flex;
justify-content: space-evenly;
align-items: baseline;
}
#select-file-button{
display: none;
}
#select-file-status{
padding-top: 15px;
}
#upload-file-status{
padding-top: 7px;
}
#settings-reset-scores-btn-wrapper{
border-top: 2px solid white;
padding-bottom: 50px;
padding-top: 25px;
margin-left: 50px;
margin-right: 50px;
}
#reset-scores-btn{
border-color: red;
background-color: red;
color: white;
}
#reset-scores-btn:hover{
cursor: pointer;
}
#map-settings-btn-wrapper{
text-align: center;
margin-bottom: 10px;
}
#map-settings-btn{
border-radius: 15px;
background-color: transparent;
color: white;
border-color: white;
padding: 5px 10px 5px 10px;
}
#map-settings-btn:hover{
background-color: white;
color: black;
border-color: black;
cursor: pointer;
}
#footer-wrapper{
display: flex;
}
#version-number{
flex: 1;
font-family: Arial;
padding-left: 10px
}
#feedback-link-wrapper{
flex: 1;
font-family: Arial;
text-align: center;
}
#creator-tag{
flex: 1;
font-family: Arial;
padding-right: 10px;
padding-bottom: 10px;
text-align: right;
}
`;
svgMap.innerHTML = `
Country Name: 0 / 0 (0%)
Average Distance: 0.0 km
OVERALL STATS
Average Time To Guess (Sec)
Average Rounds Played (Win)
Average Rounds Played (Loss)
AVERAGE DISTANCE FROM OPPONENT
COUNTRY STREAKS
Current:
Highest: Correct | Incorrect
AVERAGE DISTANCE FROM OPPONENT
COUNTRY STREAKS
Current:
Highest: Correct | Incorrect
`;
scriptForMap.textContent = `
{
let countries = ['AF','AX','AL','DZ','AS','AD','AO','AI','AQ','AG','AR','AM','AW','AU','AT','AZ','BS','BH','BD','BB','BY','BE','BZ','BJ','BM','BT','BO','BQ','BA','BW','BV','BR','IO','BN','BG','BF','BI','KH','CM','CA','CV','KY','CF','TD','CL','CN','CX','CC','CO','KM','CG','CD','CK','CR','CI','HR','CU','CW','CY','CZ','DK','DJ','DM','DO','EC','EG','SV','GQ','ER','EE','ET','FK','FO','FJ','FI','FR','GF','PF','TF','GA','GM','GE','DE','GH','GI','GR','GL','GD','GP','GU','GT','GG','GN','GW','GY','HT','HM','VA','HN','HK','HU','IS','IN','ID','IR','IQ','IE','IM','IL','IT','JM','JP','JE','JO','KZ','KE','KI','KP','KR','XK','KW','KG','LA','LV','LB','LS','LR','LY','LI','LT','LU','MO','MK','MG','MW','MY','MV','ML','MT','MH','MQ','MR','MU','YT','MX','FM','MD','MC','MN','ME','MS','MA','MZ','MM','NA','NR','NP','NL','NC','NZ','NI','NE','NG','NU','NF','MP','NO','OM','PK','PW','PA','PG','PY','PE','PH','PN','PL','PT','PR','QA','RS','RE','RO','RU','RW','BL','SH','KN','LC','MF','VC','WS','ST','SA','SN','SC','SL','SG','SX','SK','SI','SB','SO','ZA','GS','SS','ES','LK','SD','SR','SJ','SZ','SE','CH','SY','TW','TJ','TZ','TH','TL','TG','TK','TO','TT','TN','TR','TM','TC','TV','UG','UA','AE','GB','US','UY','UZ','VU','VE','VN','VG','VI','WF','EH','YE','ZM','ZW','SM'];
//UNIT SELECTION
if(window.localStorage.getItem('units-svg-map') === 'mi'){
document.getElementById('unit-selector-mi').checked = true;
}
else if(window.localStorage.getItem('units-svg-map') === 'km'){
document.getElementById('unit-selector-km').checked = true;
}
document.getElementById('unit-selector-mi').addEventListener('click', function(){
window.localStorage.setItem('units-svg-map', 'mi');
});
document.getElementById('unit-selector-km').addEventListener('click', function(){
window.localStorage.setItem('units-svg-map', 'km');
});
//DUELS MAP SETUP
function setAllDuelsStats(){
//Percentage Bar
let correct_total = parseInt(window.localStorage.getItem('overall-correct-${USER_ID}'));
let total_total = parseInt(window.localStorage.getItem('overall-total-${USER_ID}'));
let percentage_total = Math.floor((correct_total / total_total) * 100);
document.getElementById('total-percentage-bar').style.width = percentage_total + '%';
document.getElementById('total-percentage-text').innerHTML = 'Overall Score: ' + correct_total + ' / ' + total_total + ' (' + percentage_total +'%) ';
if(percentage_total >= 100*${green_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'green';
}
else if(percentage_total >= 100*${yellow_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'yellow';
}
else if(percentage_total >= 100*${red_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'red';
}
//Country colors
countries.forEach(function(country){
let correct = 0;
let total = 0;
if(window.localStorage.getItem(country + '-number-correct-${USER_ID}') !== null){
correct = window.localStorage.getItem(country + '-number-correct-${USER_ID}');
}
if(window.localStorage.getItem(country + '-number-total-${USER_ID}') !== null){
total = window.localStorage.getItem(country + '-number-total-${USER_ID}');
}
let percentage = parseInt(correct) / parseInt(total);
if(correct === 0 && total === 0){
percentage = 'none';
}
let targetCountry = document.getElementById(country);
if(!targetCountry){
return;
}
//Setting the countries to a color based on their percentage
if(percentage >= ${green_range}){
targetCountry.setAttribute('style', 'fill: lightgreen'); //green
}
else if(percentage >= ${yellow_range}){
targetCountry.setAttribute('style', 'fill: rgb(233, 233, 84)'); //yellow
}
else if(percentage >= ${red_range}){
targetCountry.setAttribute('style', 'fill: lightcoral'); //red
}
else{
targetCountry.setAttribute('style', 'fill: black');
}
});
//OVERALL STATS SETUP
let overallStats = JSON.parse(window.localStorage.getItem('overall-country-stats-${USER_ID}'));
let percentage;
let percentageColor;
let totalCount = overallStats.totalCount;
let totalWin = overallStats.totalWin;
let totalLoss = overallStats.totalLoss;
let total5ks = overallStats.total5ks;
let totalGames = overallStats.totalGames;
let averageScore = Math.floor(overallStats.averageScore);
let averageDistance = Math.floor(overallStats.averageDistance/1000);
let gameLengthWin = overallStats.averageGameLengthWin;
let gameLengthLoss = overallStats.averageGameLengthLoss;
let averageTime = Math.floor(overallStats.averageTime);
let guessedFirst = overallStats.guessedFirst;
let closerThanOpponent = overallStats.closerThanOpponent;
let correctStreak = overallStats.countryCorrectStreak;
let correctMax = overallStats.countryCorrectMax;
let wrongStreak = overallStats.countryWrongStreak;
let wrongMax = overallStats.countryWrongMax;
let opponentRating = Math.floor(overallStats.opponentRating);
//Find correct percentage to color the outside circle
function findPercentage(stat, max){
percentage = (stat/max);
if(percentage >= ${green_range}){
percentageColor = 'green';
}
else if(percentage >= ${yellow_range}){
percentageColor = 'yellow';
}
else{
percentageColor = 'red';
}
percentage = 100 * percentage;
if(percentage <= 0){
percentage = 2;
}
};
//Average Score
findPercentage(averageScore, 5000);
document.getElementById('overall-stat-average-score-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-average-score-value').innerText = averageScore;
//Average Distance
findPercentage(2500-averageDistance, 2500);
document.getElementById('overall-stat-average-distance-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
if(window.localStorage.getItem('units-svg-map') == 'mi'){
document.getElementById('overall-stat-average-distance-title').innerText = 'Average Distance (mi)';
averageDistance = Math.floor(averageDistance / 1.609);
}
else{
document.getElementById('overall-stat-average-distance-title').innerText = 'Average Distance (km)';
}
document.getElementById('overall-stat-average-distance-value').innerText = averageDistance;
//Closer Than Opponent
findPercentage(closerThanOpponent, totalCount);
document.getElementById('overall-stat-closer-than-opponent-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-closer-than-opponent-value').innerText = Math.floor((100 * (closerThanOpponent/totalCount))) + '%';
//Average Time
findPercentage(120-averageTime, 120);
document.getElementById('overall-stat-average-time-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-average-time-value').innerText = averageTime;
//Guessed First
findPercentage(guessedFirst, totalCount);
document.getElementById('overall-stat-guessed-first-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-guessed-first-value').innerText = Math.floor((100 * (guessedFirst/totalCount))) + '%';
//Total 5ks
findPercentage(total5ks, 100);
document.getElementById('overall-stat-total-5ks-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-total-5ks-value').innerText = total5ks;
//Game Length (Win)
findPercentage(15-gameLengthWin, 15);
document.getElementById('overall-stat-average-game-length-win-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-average-game-length-win-value').innerText = Math.round(10 * gameLengthWin) / 10;
//Game Length (Loss)
findPercentage(gameLengthLoss, 15);
document.getElementById('overall-stat-average-game-length-loss-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-average-game-length-loss-value').innerText = Math.round(10 * gameLengthLoss) / 10;
//Opponent Rating
findPercentage(opponentRating, 1200);
document.getElementById('overall-stat-opponent-rating-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('overall-stat-opponent-rating-value').innerText = opponentRating;
//BOTTOM STATS SETUP
//Distance From Opponent
let distanceFromOpponent = [Math.round(overallStats.distanceFromOpponent[1] / 1000),'km','+','green'];
if(window.localStorage.getItem('units-svg-map') == 'mi'){
distanceFromOpponent[0] = Math.round(distanceFromOpponent[0] / 1.609);
distanceFromOpponent[1] = 'mi';
}
if(distanceFromOpponent[0] < 0){
distanceFromOpponent[0] *= -1;
distanceFromOpponent[2] = '-';
distanceFromOpponent[3] = 'red';
}
document.getElementById('overall-stats-distance-from-opponent-title').innerText = 'AVERAGE DISTANCE FROM OPPONENT';
document.getElementById('overall-stats-distance-from-opponent-value').style.color = distanceFromOpponent[3];
document.getElementById('overall-stats-distance-from-opponent-value').innerText = distanceFromOpponent[2] + distanceFromOpponent[0] + ' ' + distanceFromOpponent[1];
//Country Streaks
if(overallStats.countryCorrectStreak > 0){
document.getElementById('overall-stats-country-streaks-value-current-value').innerText = overallStats.countryCorrectStreak + ' Correct';
document.getElementById('overall-stats-country-streaks-value-current-value').style.color = 'green';
}
else if(overallStats.countryWrongStreak > 0){
document.getElementById('overall-stats-country-streaks-value-current-value').innerText = overallStats.countryWrongStreak + ' Incorrect';
document.getElementById('overall-stats-country-streaks-value-current-value').style.color = 'red';
}
document.getElementById('overall-stats-country-streaks-value-max-correct-value').innerText = overallStats.countryCorrectMax;
document.getElementById('overall-stats-country-streaks-value-max-wrong-value').innerText = overallStats.countryWrongMax;
//Time Played
let minutesPlayed = Math.floor(Math.floor(overallStats.totalSeconds / 60) % 60);
let hoursPlayed = Math.floor(overallStats.totalSeconds / 3600);
document.getElementById('overall-stats-total-play-time-value').innerText = hoursPlayed + 'h ' + minutesPlayed + 'm ';
//Make All Stats Visible
document.getElementById('overall-stat-average-score-wrapper').style.display = 'flex';
document.getElementById('overall-stat-average-distance-wrapper').style.display = 'flex';
document.getElementById('overall-stat-closer-than-opponent-wrapper').style.display = 'flex';
document.getElementById('overall-stat-average-time-wrapper').style.display = 'flex';
document.getElementById('overall-stat-guessed-first-wrapper').style.display = 'flex';
document.getElementById('overall-stat-total-5ks-wrapper').style.display = 'flex';
document.getElementById('overall-stat-average-game-length-win-wrapper').style.display = 'flex';
document.getElementById('overall-stat-average-game-length-loss-wrapper').style.display = 'flex';
document.getElementById('overall-stat-opponent-rating-wrapper').style.display = 'flex';
document.getElementById('duels-stats-spacing-wrapper-1').style.display = 'flex'
document.getElementById('duels-stats-spacing-wrapper-2').style.display = 'flex'
document.getElementById('overall-stats-values-bottom').style.marginTop = '360px';
};
//Set All Classic Stats
function setAllClassicStats(){
//Total Percentage Bar
let totalCount = 'none';
let totalCorrect = 'none'
let percentage_total = 'none';
if(window.localStorage.getItem('geostats-overall-standard-stats-${USER_ID}')){
totalCount = JSON.parse(window.localStorage.getItem('geostats-overall-standard-stats-${USER_ID}')).totalCount;
totalCorrect = JSON.parse(window.localStorage.getItem('geostats-overall-standard-stats-${USER_ID}')).totalCorrect;
percentage_total = Math.floor((totalCorrect / totalCount) * 100);
}
if(percentage_total >= 100*${green_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'green';
}
else if(percentage_total >= 100*${yellow_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'yellow';
}
else if(percentage_total >= 100*${red_range}){
document.getElementById('total-percentage-bar').style.backgroundColor = 'red';
}
if(percentage_total != 'none'){
document.getElementById('total-percentage-bar').style.width = percentage_total + '%';
document.getElementById('total-percentage-text').innerHTML = 'Overall Score: ' + totalCorrect + ' / ' + totalCount + ' (' + percentage_total +'%) ';
}
//Country colors
countries.forEach(function(countryId){
let countryStats = null;
let percentage = 'none';
if(window.localStorage.getItem('geostats-' + countryId + '-all-standard-stats-${USER_ID}')){
countryStats = JSON.parse(window.localStorage.getItem('geostats-' + countryId + '-all-standard-stats-${USER_ID}'));
percentage = countryStats.totalCorrect / countryStats.totalCount;
}
let targetCountry = document.getElementById(countryId);
if(!targetCountry){
return;
}
//Setting the countries to a color based on their percentage
if(percentage >= ${green_range}){
targetCountry.setAttribute('style', 'fill: lightgreen'); //green
}
else if(percentage >= ${yellow_range}){
targetCountry.setAttribute('style', 'fill: rgb(233, 233, 84)'); //yellow
}
else if(percentage >= ${red_range}){
targetCountry.setAttribute('style', 'fill: lightcoral'); //red
}
else{
targetCountry.setAttribute('style', 'fill: black');
}
});
//Find correct percentage to color the outside circle
function findPercentage(stat, max){
percentage = (stat/max);
if(percentage >= ${green_range}){
percentageColor = 'green';
}
else if(percentage >= ${yellow_range}){
percentageColor = 'yellow';
}
else{
percentageColor = 'red';
}
percentage = 100 * percentage;
if(percentage <= 0){
percentage = 2;
}
};
//OVERALL STATS
let overallStats = JSON.parse(window.localStorage.getItem('geostats-overall-standard-stats-${USER_ID}'));
let percentage;
let percentageColor;
let averageScore = Math.floor(overallStats.averageScore);
let averageDistance = Math.floor(overallStats.averageDistance/1000);
let averageRoundTime = Math.floor(overallStats.averageRoundTime);
let averageGameTime = overallStats.averageGameTime/60;
let total5ks = overallStats.total5ks;
//Average Score
findPercentage(averageScore, 5000);
document.getElementById('standard-overall-stat-average-score-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('standard-overall-stat-average-score-value').innerText = averageScore;
//Average Distance
findPercentage(2500-averageDistance, 2500);
document.getElementById('standard-overall-stat-average-distance-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
if(window.localStorage.getItem('units-svg-map') == 'mi'){
document.getElementById('standard-overall-stat-average-distance-title').innerText = 'Average Distance (mi)';
averageDistance = Math.floor(averageDistance / 1.609);
}
else{
document.getElementById('standard-overall-stat-average-distance-title').innerText = 'Average Distance (km)';
}
document.getElementById('standard-overall-stat-average-distance-value').innerText = averageDistance;
//Average Round Time
findPercentage(120-averageRoundTime, 120);
document.getElementById('standard-overall-stat-average-round-time-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('standard-overall-stat-average-round-time-value').innerText = averageRoundTime;
//Average Game Time
findPercentage(10-averageGameTime, 10);
document.getElementById('standard-overall-stat-average-game-time-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('standard-overall-stat-average-game-time-value').innerText = round(averageGameTime,1);
//Total 5ks
findPercentage(total5ks, 100);
document.getElementById('standard-overall-stat-total5ks-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('standard-overall-stat-total5ks-value').innerText = total5ks;
//BOTTOM STATS SETUP
//Commonly Guessed Incorrectly
document.getElementById('overall-stats-distance-from-opponent-title').innerText = 'TOP INCORRECT COUNTRIES';
let textColor = 'green';
let innerText = '';
if(Object.keys(overallStats.incorrectCountry).length != 0){
let incorrectGuesses = Object.entries(overallStats.incorrectCountry).sort((a,b) => b[1]-a[1]);
for(let i = 0; i < 3; i++){
let tempText = '';
if(i < incorrectGuesses.length && incorrectGuesses[i][0] != 'ERROR'){
tempText = document.getElementById(incorrectGuesses[i][0]).dataset.name + ' - ' + incorrectGuesses[i][1];
}
innerText += tempText + '\\n';
}
textColor = 'red';
}
else{
innerText = 'N/A';
}
document.getElementById('overall-stats-distance-from-opponent-value').style.color = textColor;
document.getElementById('overall-stats-distance-from-opponent-value').innerText = innerText;
//Country Streaks
if(overallStats.countryCorrectStreak > 0){
document.getElementById('overall-stats-country-streaks-value-current-value').innerText = overallStats.countryCorrectStreak + ' Correct';
document.getElementById('overall-stats-country-streaks-value-current-value').style.color = 'green';
}
else if(overallStats.countryWrongStreak > 0){
document.getElementById('overall-stats-country-streaks-value-current-value').innerText = overallStats.countryWrongStreak + ' Incorrect';
document.getElementById('overall-stats-country-streaks-value-current-value').style.color = 'red';
}
document.getElementById('overall-stats-country-streaks-value-max-correct-value').innerText = overallStats.countryCorrectMax;
document.getElementById('overall-stats-country-streaks-value-max-wrong-value').innerText = overallStats.countryWrongMax;
//Time Played
let minutesPlayed = Math.floor(Math.floor(overallStats.totalSeconds / 60) % 60);
let hoursPlayed = Math.floor(overallStats.totalSeconds / 3600);
document.getElementById('overall-stats-total-play-time-value').innerText = hoursPlayed + 'h ' + minutesPlayed + 'm ';
//Make All Stats Visible
document.getElementById('standard-overall-stat-average-score-wrapper').style.display = 'flex';
document.getElementById('standard-overall-stat-average-distance-wrapper').style.display = 'flex';
document.getElementById('standard-overall-stat-average-round-time-wrapper').style.display = 'flex';
document.getElementById('standard-overall-stat-average-game-time-wrapper').style.display = 'flex';
document.getElementById('standard-overall-stat-total5ks-wrapper').style.display = 'flex';
document.getElementById('standard-stats-spacing-wrapper-1').style.display = 'flex'
document.getElementById('overall-stats-values-bottom').style.marginTop = '160px';
};
//Clear All Overall Stats On Gamemode Change
function clearAllOverallStats(){
//Duels
document.getElementById('overall-stat-average-score-wrapper').style.display = 'none';
document.getElementById('overall-stat-average-distance-wrapper').style.display = 'none';
document.getElementById('overall-stat-closer-than-opponent-wrapper').style.display = 'none';
document.getElementById('overall-stat-average-time-wrapper').style.display = 'none';
document.getElementById('overall-stat-guessed-first-wrapper').style.display = 'none';
document.getElementById('overall-stat-total-5ks-wrapper').style.display = 'none';
document.getElementById('overall-stat-average-game-length-win-wrapper').style.display = 'none';
document.getElementById('overall-stat-average-game-length-loss-wrapper').style.display = 'none';
document.getElementById('overall-stat-opponent-rating-wrapper').style.display = 'none';
document.getElementById('duels-stats-spacing-wrapper-1').style.display = 'none';
document.getElementById('duels-stats-spacing-wrapper-2').style.display = 'none';
//Standard
document.getElementById('standard-overall-stat-average-score-wrapper').style.display = 'none';
document.getElementById('standard-overall-stat-average-distance-wrapper').style.display = 'none';
document.getElementById('standard-overall-stat-average-round-time-wrapper').style.display = 'none';
document.getElementById('standard-overall-stat-average-game-time-wrapper').style.display = 'none';
document.getElementById('standard-overall-stat-total5ks-wrapper').style.display = 'none';
document.getElementById('standard-stats-spacing-wrapper-1').style.display = 'none';
}
//If Current Gamemode Is Not Set
if(!window.localStorage.getItem('geostats-current-gamemode-${USER_ID}')){
window.localStorage.setItem('geostats-current-gamemode-${USER_ID}', 'duels');
}
//Event Listener For Gamemode Menu
document.getElementById('geostats-gamemodes-menu').addEventListener('click', (e) => {
let gameMode = e.path[0].id;
if(!(gameMode.includes('duels') || gameMode.includes('classic'))){
return;
}
//Make all gray
function menuItemsGray(){
let menuItems = document.getElementsByClassName('geostats-gamemodes-menu-item');
for(let i in menuItems){
if(i < menuItems.length){
menuItems[i].style.color = 'var(--ds-color-white-60)';
}
}
}
//If duels - set the stats and make it white
if(gameMode.includes('duels') && window.localStorage.getItem('overall-country-stats-${USER_ID}')){
//Clear All Current Overall Stats
clearAllOverallStats();
//Set Stats
setAllDuelsStats();
window.localStorage.setItem('geostats-current-gamemode-${USER_ID}', 'duels');
//Change Menu Color
menuItemsGray();
document.getElementById('geostats-gamemodes-menu-item-duels').style.color = 'white';
//If country stats are open, change to duels
if(document.getElementById('country-stats-page-wrapper').style.display == 'block'){
setupCountryStatsDuels('switch', window.localStorage.getItem('select-country-stats-id'));
}
}
//If classic - set the stats and make it white
else if(gameMode.includes('classic') && window.localStorage.getItem('geostats-overall-standard-stats-${USER_ID}')){
//Clear All Current Overall Stats
clearAllOverallStats();
//Set stats
setAllClassicStats();
window.localStorage.setItem('geostats-current-gamemode-${USER_ID}', 'classic');
//Change Menu Color
menuItemsGray();
document.getElementById('geostats-gamemodes-menu-item-classic').style.color = 'white';
//If country stats are open, change to classic
if(document.getElementById('country-stats-page-wrapper').style.display == 'block'){
setupCountryStatsClassic('switch', window.localStorage.getItem('select-country-stats-id'));
}
}
});
//First Time
clearAllOverallStats();
switch(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}')){
case 'duels':
if(window.localStorage.getItem('overall-country-stats-${USER_ID}')){
setAllDuelsStats();
}
document.getElementById('geostats-gamemodes-menu-item-duels').style.color = 'white';
break;
case 'classic':
if(window.localStorage.getItem('geostats-overall-standard-stats-${USER_ID}')){
setAllClassicStats();
}
document.getElementById('geostats-gamemodes-menu-item-classic').style.color = 'white';
break;
}
function mouseOverCountry(country){
if(typeof country.target !== 'undefined'){
country = country.target;
}
if (country.tagName == 'path'){
let content = country.dataset.name;
//Changing the color when you hover over a country
if(country.style.fill == 'lightcoral'){
country.setAttribute('style', 'fill:red');
}
else if(country.style.fill == 'lightgreen'){
country.setAttribute('style', 'fill:green');
}
else if(country.style.fill == 'rgb(233, 233, 84)'){
country.setAttribute('style', 'fill:yellow');
}
else if(country.style.fill == 'black'){
country.setAttribute('style', 'fill:rgb(175, 175, 175)');
}
//Displaying the country and the stats at the top of the page
let countryName = country.dataset.name;
let countryCorrect = 0;
let countryTotal = 0;
let countryPercentage = 0;
let countryDistance = 0.0;
let distanceUnit = 'km';
let target = country.id;
//IF DUELS
if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'duels'){
if(window.localStorage.getItem(target + '-number-correct-${USER_ID}') !== null){
countryCorrect = window.localStorage.getItem(target + '-number-correct-${USER_ID}');
}
if(window.localStorage.getItem(target + '-number-total-${USER_ID}') !== null){
countryTotal = window.localStorage.getItem(target + '-number-total-${USER_ID}');
}
if((countryCorrect !== 0) && (countryTotal !== 0)){
countryPercentage = Math.floor(100 * (parseInt(countryCorrect) / parseInt(countryTotal)));
}
if(window.localStorage.getItem(target + '-distance-average-${USER_ID}') !== null){
countryDistance = parseInt(window.localStorage.getItem(target + '-distance-average-${USER_ID}')) / 1000;
if(document.getElementById('unit-selector-mi').checked){
countryDistance = countryDistance / 1.609;
}
countryDistance = round(countryDistance,1);
}
if(document.getElementById('unit-selector-mi').checked){
distanceUnit = 'mi';
}
}
//IF CLASSIC
else if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'classic'){
if(window.localStorage.getItem('geostats-' + target +'-all-standard-stats-${USER_ID}')){
let stats = JSON.parse(window.localStorage.getItem('geostats-' + target +'-all-standard-stats-${USER_ID}'));
countryCorrect = stats.totalCorrect;
countryTotal = stats.totalCount;
countryPercentage = Math.floor(100 * (countryCorrect / countryTotal));
countryDistance = stats.averageDistance / 1000;
if(document.getElementById('unit-selector-mi').checked){
countryDistance = countryDistance / 1.609;
}
countryDistance = round(countryDistance,1);
}
if(document.getElementById('unit-selector-mi').checked){
distanceUnit = 'mi';
}
}
document.getElementById("display-country-details").textContent = countryName + ": " + countryCorrect + " / " + countryTotal + " (" + countryPercentage + "%)";
document.getElementById("display-country-details").style.visibility = "visible";
document.getElementById("display-country-distance").textContent = 'Average Distance: ' + countryDistance + ' ' + distanceUnit;
document.getElementById("display-country-distance").style.visibility = "visible";
}
};
function mouseOutCountry(country){
if(typeof country.target !== 'undefined'){
country = country.target;
}
if (country.tagName == 'path'){
//Changing the color when you stop hovering over a country
if(country.style.fill == 'red'){
country.setAttribute('style', 'fill:lightcoral');
}
if(country.style.fill == 'green'){
country.setAttribute('style', 'fill:lightgreen');
}
if(country.style.fill == 'yellow'){
country.setAttribute('style', 'fill:rgb(233, 233, 84)');
}
if(country.style.fill == 'rgb(175, 175, 175)'){
country.setAttribute('style', 'fill:black');
}
//Hiding the display at the top when no country is hovering
document.getElementById("display-country-details").style.visibility = "hidden";
document.getElementById("display-country-distance").style.visibility = "hidden";
}
};
function round(value, precision) {
let multiplier = Math.pow(10, precision || 0);
return Math.round(value * multiplier) / multiplier;
};
//REGULAR LISTENERS
document.getElementById('map-wrapper-element').addEventListener('mouseover', mouseOverCountry);
document.getElementById('map-wrapper-element').addEventListener('mouseout', mouseOutCountry);
//SEARCH LIST
function mouseOverList(e){
let temp = e.target.id.toUpperCase();
let target_country = document.getElementById(temp);
mouseOverCountry(target_country);
}
function mouseOutList(e){
let temp = e.target.id.toUpperCase();
let target_country = document.getElementById(temp);
mouseOutCountry(target_country);
}
document.getElementById('search-bar').addEventListener('click', () => {
let search_bar = document.getElementById('search-bar');
let list = document.querySelectorAll('#search-bar-list li');
list.forEach(item => item.addEventListener('mouseover', mouseOverList));
list.forEach(item => item.addEventListener('mouseout', mouseOutList));
search_bar.onkeyup = () => {
let search = search_bar.value.toLowerCase();
let count = 0;
if(search_bar.value !== ''){
document.getElementById('search-bar-list').style.display = 'inline';
}
else{
document.getElementById('search-bar-list').style.display = 'none';
}
//Showing the results that match and hiding those that dont (max 6 items)
for(let i of list){
let item = i.innerHTML.toLowerCase();
if(item.indexOf(search) == -1){
i.style.display = 'none';
}
else{
if(count < 6){
count = count + 1;
i.style.display = 'block';
}
else{
i.style.display = 'none';
}
}
};
};
});
//OPEN AND CLOSE SETTINGS (and get back to homepage from country stats)
document.getElementById('map-settings-btn').addEventListener('click', () => {
if(document.getElementById('map-settings-btn').innerText == 'Back to Map'){
document.getElementById('map-settings-wrapper').style.display = 'none';
document.getElementById("country-stats-page-wrapper").style.display = 'none';
document.getElementById('map-settings-btn').innerText = 'Settings';
document.getElementsByClassName('display-wrapper')[0].style.display = 'block';
document.getElementById('search-bar-wrapper').style.display = 'block';
document.getElementsByClassName('map-wrapper')[0].style.display = 'block';
document.getElementById('overall-stats-page-wrapper').style.display = 'block';
//Scroll to the map
window.scrollTo(0,2550);
}
else{
document.getElementById('map-settings-wrapper').style.display = 'block';
document.getElementById('map-settings-btn').innerText = 'Back to Map';
document.getElementsByClassName('display-wrapper')[0].style.display = 'none';
document.getElementById('search-bar-wrapper').style.display = 'none';
document.getElementsByClassName('map-wrapper')[0].style.display = 'none';
document.getElementById('overall-stats-page-wrapper').style.display = 'none';
//Reset button text
if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'duels'){
document.getElementById('reset-scores-btn').textContent = 'Reset All Duels Stats';
}
else if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'classic'){
document.getElementById('reset-scores-btn').textContent = 'Reset All Classic Stats';
}
}
});
//SET HEALING ROUNDS TOGGLE IN SETTINGS
let healing = JSON.parse(window.localStorage.getItem('allow-healing-rounds'));
if(healing.include){
document.getElementById('settings-allow-healing-rounds').checked = true;
}
else{
document.getElementById('settings-allow-healing-rounds').checked = false;
}
document.getElementById('settings-allow-healing-rounds').addEventListener('click', () => {
if(document.getElementById('settings-allow-healing-rounds').checked){
window.localStorage.setItem('allow-healing-rounds', JSON.stringify({include: true}));
}
else{
window.localStorage.setItem('allow-healing-rounds', JSON.stringify({include: false}));
}
});
//SET COMPETITIVE ONLY TOGGLE IN SETTINGS
let competitive = JSON.parse(window.localStorage.getItem('competitive-only-mode'));
if(competitive.include){
document.getElementById('settings-competitive-only-mode').checked = true;
}
else{
document.getElementById('settings-competitive-only-mode').checked = false;
}
document.getElementById('settings-competitive-only-mode').addEventListener('click', () => {
if(document.getElementById('settings-competitive-only-mode').checked){
window.localStorage.setItem('competitive-only-mode', JSON.stringify({include: true}));
}
else{
window.localStorage.setItem('competitive-only-mode', JSON.stringify({include: false}));
}
});
//RESET ALL SCORES
document.getElementById('reset-scores-btn').addEventListener('click', () => {
if(confirm('Are you sure you want to reset your stats? This cannot be undone.')){
if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'duels'){
resetDuelsScores();
}
else if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'classic'){
resetClassicScores();
}
//Reload the page
location.reload();
}
});
//Reset Duels Scores
function resetDuelsScores(){
//Remove country scores
countries.forEach(function(country){
window.localStorage.removeItem(country + '-number-correct-${USER_ID}');
window.localStorage.removeItem(country + '-number-total-${USER_ID}');
window.localStorage.removeItem(country + '-distance-average-${USER_ID}');
window.localStorage.removeItem(country + '-distance-number-${USER_ID}');
window.localStorage.removeItem(country + '-all-country-stats-${USER_ID}');
});
//Remove overall scores
window.localStorage.removeItem('overall-total-${USER_ID}');
window.localStorage.removeItem('overall-correct-${USER_ID}');
window.localStorage.removeItem('overall-country-stats-${USER_ID}');
};
//Reset Classic Scores
function resetClassicScores(){
//Country
countries.forEach(function(country){
window.localStorage.removeItem('geostats-' + country + '-all-standard-stats-${USER_ID}');
});
//Overall
window.localStorage.removeItem('geostats-overall-standard-stats-${USER_ID}');
};
//OPEN COUNTRY STATS PAGE
document.getElementById('map-wrapper-element').addEventListener('dblclick', (e) => {
let countryId = (e.path[0].id).toUpperCase();
if(countryId.length != 2){
return;
}
//Setup
window.localStorage.setItem('select-country-stats-id', countryId);
//IF DUELS
if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'duels'){
if(!window.localStorage.getItem(countryId + '-all-country-stats-${USER_ID}')){
return;
}
setupCountryStatsDuels(e,countryId);
}
//IF CLASSIC
else if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'classic'){
if(!window.localStorage.getItem('geostats-' + countryId + '-all-standard-stats-${USER_ID}')){
return;
}
setupCountryStatsClassic(e,countryId);
}
//HIDE EVERYTHING
document.getElementById('search-bar-wrapper').style.display = 'none';
document.getElementById('overall-stats-page-wrapper').style.display = 'none';
document.getElementsByClassName('map-wrapper')[0].style.display = 'none';
document.getElementsByClassName('display-wrapper')[0].style.display = 'none';
//SHOW CORRECT STUFF
document.getElementById("country-stats-page-wrapper").style.display = 'block';
document.getElementById('map-settings-btn').innerText = 'Back to Map';
});
//Setup For Country Stats (Duels)
function setupCountryStatsDuels(type,countryId){
//Set the stats to the correct values for the country (IF THE COUNTRY HAS STATS)
if(!window.localStorage.getItem(countryId + '-all-country-stats-${USER_ID}')){
return;
}
clearAllCountryStats();
setCountryStatsDuels(countryId);
let countryName;
//If Switching Gamemodes
if(type == 'switch'){
countryName = document.getElementById(countryId).dataset.name
}
else{
countryName = type.path[0].dataset.name;
}
let countryCorrect = 0;
let countryTotal = 0;
let countryPercentage = 0;
if(typeof countryName == 'undefined'){
countryName = type.path[0].textContent;
}
if(window.localStorage.getItem(countryId + '-number-correct-${USER_ID}') !== null){
countryCorrect = window.localStorage.getItem(countryId + '-number-correct-${USER_ID}');
}
if(window.localStorage.getItem(countryId + '-number-total-${USER_ID}') !== null){
countryTotal = window.localStorage.getItem(countryId + '-number-total-${USER_ID}');
}
if((countryCorrect !== 0) && (countryTotal !== 0)){
countryPercentage = Math.floor(100 * (parseInt(countryCorrect) / parseInt(countryTotal)));
}
document.getElementById('country-stats-display-details').textContent = countryName + ": " + countryCorrect + " / " + countryTotal + " (" + countryPercentage + "%)";
document.getElementById('country-stats-reset-btn').textContent = 'Reset All ' + countryName + ' Duels Stats';
};
//Setup For Country Stats (Classic)
function setupCountryStatsClassic(type,countryId){
//Set the stats to the correct values for the country (IF THE COUNTRY HAS STATS)
if(!window.localStorage.getItem('geostats-' + countryId + '-all-standard-stats-${USER_ID}')){
return;
}
clearAllCountryStats();
setCountryStatsClassic(countryId);
let countryName;
//If Switching Gamemodes
if(type == 'switch'){
countryName = document.getElementById(countryId).dataset.name
}
else{
countryName = type.path[0].dataset.name;
}
let countryCorrect = 0;
let countryTotal = 0;
let countryPercentage = 0;
if(typeof countryName == 'undefined'){
countryName = type.path[0].textContent;
}
let stats = JSON.parse(window.localStorage.getItem('geostats-' + countryId + '-all-standard-stats-${USER_ID}'));
countryCorrect = stats.totalCorrect;
countryTotal = stats.totalCount;
countryPercentage = Math.floor(100 * (countryCorrect / countryTotal));
document.getElementById('country-stats-display-details').textContent = countryName + ": " + countryCorrect + " / " + countryTotal + " (" + countryPercentage + "%)";
document.getElementById('country-stats-reset-btn').textContent = 'Reset All ' + countryName + ' Classic Stats';
};
//Clear All Country Stats On Gamemode Change
function clearAllCountryStats(){
//Duels
document.getElementById('country-stat-average-score-wrapper').style.display = 'none';
document.getElementById('country-stat-average-distance-wrapper').style.display = 'none';
document.getElementById('country-stat-closer-than-opponent-wrapper').style.display = 'none';
document.getElementById('country-stat-average-time-wrapper').style.display = 'none';
document.getElementById('country-stat-guessed-first-wrapper').style.display = 'none';
document.getElementById('country-stat-total-5ks-wrapper').style.display = 'none';
document.getElementById('duels-country-stats-spacing-wrapper-1').style.display = 'none';
//Standard
document.getElementById('standard-country-stat-average-score-wrapper').style.display = 'none';
document.getElementById('standard-country-stat-average-distance-wrapper').style.display = 'none';
document.getElementById('standard-country-stat-average-round-time-wrapper').style.display = 'none';
document.getElementById('standard-country-stat-total-5ks-wrapper').style.display = 'none';
document.getElementById('standard-country-stats-total-time-spent').style.display = 'none';
document.getElementById('standard-country-stats-spacing-wrapper-1').style.display = 'none';
};
//SET COUNTRY STATS FOR DUELS(ON DOUBLE CLICK)
function setCountryStatsDuels(countryCode){
let countryObject = JSON.parse(window.localStorage.getItem(countryCode + '-all-country-stats-${USER_ID}'));
let percentage;
let percentageColor;
//Country Stats
let totalCount = countryObject.totalCount;
let averageScore = Math.floor(countryObject.averageScore);
let averageDistance = Math.floor(countryObject.averageDistance/1000);
let closerThanOpponent = countryObject.closerThanOpponent;
let averageTime = Math.floor(countryObject.averageTime);
let guessedFirst = countryObject.guessedFirst;
let total5ks = countryObject.total5ks;
//Find correct percentage to color the outside circle
function findPercentage(stat, max){
percentage = (stat/max);
if(percentage >= ${green_range}){
percentageColor = 'green';
}
else if(percentage >= ${yellow_range}){
percentageColor = 'yellow';
}
else{
percentageColor = 'red';
}
percentage = 100 * percentage;
if(percentage <= 0){
percentage = 2;
}
};
//Average Score
findPercentage(averageScore, 5000);
document.getElementById('country-stat-average-score-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-average-score-value').innerText = averageScore;
//Average Distance
findPercentage(2500-averageDistance, 2500);
document.getElementById('country-stat-average-distance-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
if(window.localStorage.getItem('units-svg-map') == 'mi'){
document.getElementById('country-stat-average-distance-title').innerText = 'Average Distance (mi)';
averageDistance = Math.floor(averageDistance / 1.609);
}
else{
document.getElementById('country-stat-average-distance-title').innerText = 'Average Distance (km)';
}
document.getElementById('country-stat-average-distance-value').innerText = averageDistance;
//Closer Than Opponent
findPercentage(closerThanOpponent, totalCount);
document.getElementById('country-stat-closer-than-opponent-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-closer-than-opponent-value').innerText = Math.floor((100 * (closerThanOpponent/totalCount))) + '%';
//Average Time
findPercentage(120-averageTime, 120);
document.getElementById('country-stat-average-time-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-average-time-value').innerText = averageTime;
//Guessed First
findPercentage(guessedFirst, totalCount);
document.getElementById('country-stat-guessed-first-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-guessed-first-value').innerText = Math.floor((100 * (guessedFirst/totalCount))) + '%';
//Total 5ks
findPercentage(total5ks, 10);
document.getElementById('country-stat-total-5ks-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('country-stat-total-5ks-value').innerText = total5ks;
//BOTTOM STATS SETUP
document.getElementById('country-stats-distance-from-opponent-title').innerText = 'AVERAGE DISTANCE FROM OPPONENT';
//Distance From Opponent
let distanceFromOpponent = [Math.round(countryObject.distanceFromOpponent[1] / 1000),'km','+','green'];
if(window.localStorage.getItem('units-svg-map') == 'mi'){
distanceFromOpponent[0] = Math.round(distanceFromOpponent[0] / 1.609);
distanceFromOpponent[1] = 'mi';
}
if(distanceFromOpponent[0] < 0){
distanceFromOpponent[0] *= -1;
distanceFromOpponent[2] = '-';
distanceFromOpponent[3] = 'red';
}
document.getElementById('country-stats-distance-from-opponent-value').style.color = distanceFromOpponent[3];
document.getElementById('country-stats-distance-from-opponent-value').innerText = distanceFromOpponent[2] + distanceFromOpponent[0] + ' ' + distanceFromOpponent[1];
//Country Streaks
if(countryObject.countryCorrectStreak > 0){
document.getElementById('country-stats-country-streaks-value-current-value').innerText = countryObject.countryCorrectStreak + ' Correct';
document.getElementById('country-stats-country-streaks-value-current-value').style.color = 'green';
}
else if(countryObject.countryWrongStreak > 0){
document.getElementById('country-stats-country-streaks-value-current-value').innerText = countryObject.countryWrongStreak + ' Incorrect';
document.getElementById('country-stats-country-streaks-value-current-value').style.color = 'red';
}
document.getElementById('country-stats-country-streaks-value-max-correct-value').innerText = countryObject.countryCorrectMax;
document.getElementById('country-stats-country-streaks-value-max-wrong-value').innerText = countryObject.countryWrongMax;
//SHOW CORRECT VALUES
document.getElementById('country-stat-average-score-wrapper').style.display = 'flex';
document.getElementById('country-stat-average-distance-wrapper').style.display = 'flex';
document.getElementById('country-stat-closer-than-opponent-wrapper').style.display = 'flex';
document.getElementById('country-stat-average-time-wrapper').style.display = 'flex';
document.getElementById('country-stat-guessed-first-wrapper').style.display = 'flex';
document.getElementById('country-stat-total-5ks-wrapper').style.display = 'flex';
document.getElementById('duels-country-stats-spacing-wrapper-1').style.display = 'flex';
//CORRECT WIDTH FOR BOTTOM STATS
document.getElementById('country-stats-distance-from-opponent').style.width = '50%';
document.getElementById('country-stats-country-streaks').style.width = '50%';
document.getElementById('standard-country-stats-total-time-spent').style.width = '50%';
};
//SET COUNTRY STATS FOR CLASSIC (ON DOUBLE CLICK)
function setCountryStatsClassic(countryCode){
//Find correct percentage to color the outside circle
function findPercentage(stat, max){
percentage = (stat/max);
if(percentage >= ${green_range}){
percentageColor = 'green';
}
else if(percentage >= ${yellow_range}){
percentageColor = 'yellow';
}
else{
percentageColor = 'red';
}
percentage = 100 * percentage;
if(percentage <= 0){
percentage = 2;
}
};
//OVERALL STATS
let overallStats = JSON.parse(window.localStorage.getItem('geostats-' + countryCode + '-all-standard-stats-${USER_ID}'));
let percentage;
let percentageColor;
let averageScore = Math.floor(overallStats.averageScore);
let averageDistance = Math.floor(overallStats.averageDistance/1000);
let averageRoundTime = Math.floor(overallStats.averageRoundTime);
let total5ks = overallStats.total5ks;
//Average Score
findPercentage(averageScore, 5000);
document.getElementById('standard-country-stat-average-score-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('standard-country-stat-average-score-value').innerText = averageScore;
//Average Distance
findPercentage(2500-averageDistance, 2500);
document.getElementById('standard-country-stat-average-distance-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
if(window.localStorage.getItem('units-svg-map') == 'mi'){
document.getElementById('standard-country-stat-average-distance-title').innerText = 'Average Distance (mi)';
averageDistance = Math.floor(averageDistance / 1.609);
}
else{
document.getElementById('standard-country-stat-average-distance-title').innerText = 'Average Distance (km)';
}
document.getElementById('standard-country-stat-average-distance-value').innerText = averageDistance;
//Average Round Time
findPercentage(120-averageRoundTime, 120);
document.getElementById('standard-country-stat-average-round-time-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('standard-country-stat-average-round-time-value').innerText = averageRoundTime;
//Total 5ks
findPercentage(total5ks, 10);
document.getElementById('standard-country-stat-total-5ks-outer-circle').style.background = 'conic-gradient(' + percentageColor + ', ' + percentageColor + ' ' + percentage + '%, #808080 ' + percentage + '%, #808080)';
document.getElementById('standard-country-stat-total-5ks-value').innerText = total5ks;
//BOTTOM STATS SETUP
//Commonly Guessed Incorrectly
document.getElementById('country-stats-distance-from-opponent-title').innerText = 'COMMONLY GUESSED INSTEAD';
let textColor = 'green';
let innerText = '';
if(Object.keys(overallStats.incorrectCountry).length != 0){
let incorrectGuesses = Object.entries(overallStats.incorrectCountry).sort((a,b) => b[1]-a[1]);
for(let i = 0; i < 3; i++){
let tempText = '';
if(i < incorrectGuesses.length && incorrectGuesses[i][0] != 'ERROR'){
tempText = document.getElementById(incorrectGuesses[i][0]).dataset.name + ' - ' + incorrectGuesses[i][1];
}
innerText += tempText + '\\n';
}
textColor = 'red';
}
else{
innerText = 'N/A';
}
document.getElementById('country-stats-distance-from-opponent-value').style.color = textColor;
document.getElementById('country-stats-distance-from-opponent-value').innerText = innerText;
//Country Streaks
if(overallStats.countryCorrectStreak > 0){
document.getElementById('country-stats-country-streaks-value-current-value').innerText = overallStats.countryCorrectStreak + ' Correct';
document.getElementById('country-stats-country-streaks-value-current-value').style.color = 'green';
}
else if(overallStats.countryWrongStreak > 0){
document.getElementById('country-stats-country-streaks-value-current-value').innerText = overallStats.countryWrongStreak + ' Incorrect';
document.getElementById('country-stats-country-streaks-value-current-value').style.color = 'red';
}
document.getElementById('country-stats-country-streaks-value-max-correct-value').innerText = overallStats.countryCorrectMax;
document.getElementById('country-stats-country-streaks-value-max-wrong-value').innerText = overallStats.countryWrongMax;
//Time Spent
let minutesPlayed = Math.floor(Math.floor(overallStats.totalSeconds / 60) % 60);
let hoursPlayed = Math.floor(overallStats.totalSeconds / 3600);
document.getElementById('standard-country-stats-total-time-spent-value').innerText = hoursPlayed + 'h ' + minutesPlayed + 'm ';
//SHOW CORRECT VALUES
document.getElementById('standard-country-stat-average-score-wrapper').style.display = 'flex';
document.getElementById('standard-country-stat-average-distance-wrapper').style.display = 'flex';
document.getElementById('standard-country-stat-average-round-time-wrapper').style.display = 'flex';
document.getElementById('standard-country-stat-total-5ks-wrapper').style.display = 'flex';
document.getElementById('standard-country-stats-total-time-spent').style.display = 'flex';
document.getElementById('standard-country-stats-spacing-wrapper-1').style.display = 'flex';
//CORRECT WIDTH FOR BOTTOM STATS
document.getElementById('country-stats-distance-from-opponent').style.width = '33.333%';
document.getElementById('country-stats-country-streaks').style.width = '33.333%';
document.getElementById('standard-country-stats-total-time-spent').style.width = '33.333%';
};
//RESET SCORES FOR SELECTED COUNTRY
document.getElementById('country-stats-reset-btn').addEventListener('click', () => {
let resetId = window.localStorage.getItem('select-country-stats-id');
//Reset all scores for country
if(confirm('Are you sure you want to reset your stats? This cannot be undone.')){
if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'duels'){
resetDuelsCountryScores(resetId);
}
else if(window.localStorage.getItem('geostats-current-gamemode-${USER_ID}') == 'classic'){
resetClassicCountryScores(resetId);
}
//Reload the page
location.reload();
}
});
//Reset Duels Country Scores
function resetDuelsCountryScores(resetId){
let countryCorrect = parseInt(window.localStorage.getItem(resetId + '-number-correct-${USER_ID}'));
let countryTotal = parseInt(window.localStorage.getItem(resetId + '-number-total-${USER_ID}'));
let countryStats = JSON.parse(window.localStorage.getItem(resetId + '-all-country-stats-${USER_ID}'));
let overallStats = JSON.parse(window.localStorage.getItem('overall-country-stats-${USER_ID}'));
if(isNaN(countryCorrect)){
countryCorrect = 0;
}
if(isNaN(countryTotal)){
countryTotal = 0;
}
//REMOVE FROM OVERALL
countryCorrect = (parseInt(window.localStorage.getItem('overall-correct-${USER_ID}')) - countryCorrect);
countryTotal = (parseInt(window.localStorage.getItem('overall-total-${USER_ID}')) - countryTotal);
//Average Score
let overallScore = overallStats.averageScore * overallStats.totalCount;
let countryScore = countryStats.averageScore * countryStats.totalCount;
overallStats.averageScore = (overallScore - countryScore) / (overallStats.totalCount - countryStats.totalCount);
//Average Distance
let overallDistance = overallStats.averageDistance * overallStats.totalCount;
let countryDistance = countryStats.averageDistance * countryStats.totalCount;
overallStats.averageDistance = (overallDistance - countryDistance) / (overallStats.totalCount - countryStats.totalCount);
//Average Time
let overallTime = overallStats.averageTime * overallStats.totalCount;
let countryTime = countryStats.averageTime * countryStats.totalCount;
overallStats.averageRoundTime = (overallTime - countryTime) / (overallStats.totalCount - countryStats.totalCount);
//Average Distance From Opponent
let overallAverageDistance = overallStats.distanceFromOpponent[0] * overallStats.distanceFromOpponent[1];
let countryAverageDistance = countryStats.distanceFromOpponent[0] * countryStats.distanceFromOpponent[1];
overallStats.distanceFromOpponent[0] = (overallStats.distanceFromOpponent[0] - countryStats.distanceFromOpponent[0]);
overallStats.distanceFromOpponent[1] = (overallAverageDistance - countryAverageDistance) / overallStats.distanceFromOpponent[0];
//Incorrect Countries
if(overallStats.incorrectCountry[resetId]){
delete overallStats.incorrectCountry[resetId];
}
//Closer Than Opponent
overallStats.closerThanOpponent -= countryStats.closerThanOpponent;
//Guessed First
overallStats.guessedFirst -= countryStats.guessedFirst;
//Total 5ks
overallStats.total5ks -= countryStats.total5ks;
//Total Correct
overallStats.totalCorrect -= countryStats.totalCorrect;
//Total Count
overallStats.totalCount -= countryStats.totalCount;
//Set Stats To New Values
window.localStorage.setItem('overall-correct-${USER_ID}', countryCorrect);
window.localStorage.setItem('overall-total-${USER_ID}', countryTotal);
window.localStorage.setItem('overall-country-stats-${USER_ID}',JSON.stringify(overallStats));
//Remove Country Scores
window.localStorage.removeItem(resetId + '-number-correct-${USER_ID}');
window.localStorage.removeItem(resetId + '-number-total-${USER_ID}');
window.localStorage.removeItem(resetId + '-distance-average-${USER_ID}');
window.localStorage.removeItem(resetId + '-distance-number-${USER_ID}');
window.localStorage.removeItem(resetId + '-all-country-stats-${USER_ID}');
};
//Reset Classic Country Scores
function resetClassicCountryScores(resetId){
let country = JSON.parse(window.localStorage.getItem('geostats-' + resetId + '-all-standard-stats-${USER_ID}'));
let overall = JSON.parse(window.localStorage.getItem('geostats-overall-standard-stats-${USER_ID}'));
//REMOVE FROM OVERALL
//Average Score
let overallScore = overall.averageScore * overall.totalCount;
let countryScore = country.averageScore * country.totalCount;
overall.averageScore = (overallScore - countryScore) / (overall.totalCount - country.totalCount);
//Average Distance
let overallDistance = overall.averageDistance * overall.totalCount;
let countryDistance = country.averageDistance * country.totalCount;
overall.averageDistance = (overallDistance - countryDistance) / (overall.totalCount - country.totalCount);
//Average Round Time
let overallRoundTime = overall.averageRoundTime * overall.totalCount;
let countryRoundTime = country.averageRoundTime * country.totalCount;
overall.averageRoundTime = (overallRoundTime - countryRoundTime) / (overall.totalCount - country.totalCount);
//Total
overall.totalCount -= country.totalCount;
overall.totalCorrect -= country.totalCorrect;
overall.total5ks -= country.total5ks;
overall.totalSeconds -= country.totalSeconds;
//Incorrect Countries
if(overall.incorrectCountry[resetId]){
delete overall.incorrectCountry[resetId];
}
// Remove country
window.localStorage.removeItem('geostats-' + resetId + '-all-standard-stats-${USER_ID}');
//Save overall
window.localStorage.setItem('geostats-overall-standard-stats-${USER_ID}',JSON.stringify(overall));
};
//MAP SLIDER RANGES
let leftSlider = document.getElementById("left-slider");
let rightSlider = document.getElementById("right-slider");
let sliderTrack = document.getElementById("slider-track");
let minGap = 5;
leftSlider.value = window.localStorage.getItem('duels-map-color-left-range-${USER_ID}');
rightSlider.value = window.localStorage.getItem('duels-map-color-right-range-${USER_ID}');
//Change Left Slider Value
function calcLeftSlider(){
if(parseInt(rightSlider.value) - parseInt(leftSlider.value) <= minGap){
leftSlider.value = parseInt(rightSlider.value) - minGap;
}
else if(leftSlider.value < 5){
leftSlider.value = 5;
}
document.getElementById('left-slider-output').innerText = leftSlider.value + '%';
document.getElementById('left-slider-output').style.left = findValue(leftSlider.value);
fillColor();
window.localStorage.setItem('duels-map-color-left-range-${USER_ID}', leftSlider.value);
}
//Change Right Slider Value
function calcRightSlider(){
if(parseInt(rightSlider.value) - parseInt(leftSlider.value) <= minGap){
rightSlider.value = parseInt(leftSlider.value) + minGap;
}
else if(rightSlider.value > 95){
rightSlider.value = 95;
}
document.getElementById('right-slider-output').innerText = rightSlider.value + '%';
document.getElementById('right-slider-output').style.left = findValue(rightSlider.value);
fillColor();
window.localStorage.setItem('duels-map-color-right-range-${USER_ID}', rightSlider.value);
}
//Fill The Slider With Colors
function fillColor(){
let percent1 = parseInt(leftSlider.value);
let percent2 = parseInt(rightSlider.value);
sliderTrack.style.background = 'linear-gradient(to right, red 0%, red ' + percent1 + '%, yellow ' + percent1 + '%, yellow ' + percent2 +'%, green ' + percent2 + '%, green 100%)';
}
//Put Value Above Slider Thumb
function findValue(val){
let valueOne = parseInt(val);
let valueTwo = valueOne * 0.2;
let final = 'calc(' + valueOne + '% - ' + valueTwo + 'px)';
return final;
}
//Add Event Listeners
document.getElementById("left-slider").addEventListener('input', calcLeftSlider);
document.getElementById("right-slider").addEventListener('input', calcRightSlider);
calcLeftSlider();
calcRightSlider();
//UPLOAD AND DOWNLOAD STATS FILE
let downloadFile = null;
let uploadFileData = {};
let readyToUpload = false;
let uploadData = null;
function getAllDuelsStats(downloadData){
downloadData.gameMode = 'duels';
//Get All Scores
for(let key in window.localStorage){
let newValue = [];
if(key.includes('${USER_ID}')){
if(key.includes('-number-correct-') || key.includes('-number-total-') || key.includes('-distance-average-') || key.includes('-distance-number-') || key.includes('-all-country-stats-') || key.includes('overall-total-') || key.includes('overall-correct-') || key.includes('overall-country-stats-')){
newValue.push(key);
if(isJson(window.localStorage[key])){
newValue.push(JSON.parse(window.localStorage[key]));
}
else{
newValue.push(window.localStorage[key]);
}
downloadData.userInfo.push(newValue);
}
}
}
};
function getAllClassicStats(downloadData){
downloadData.gameMode = 'classic';
//Country
countries.forEach(function(country){
let key = 'geostats-' + country + '-all-standard-stats-${USER_ID}';
if(window.localStorage.getItem(key)){
downloadData.userInfo.push([key, JSON.parse(window.localStorage.getItem(key))]);
}
});
//Overall
key = 'geostats-overall-standard-stats-${USER_ID}';
if(window.localStorage.getItem(key)){
downloadData.userInfo.push([key , JSON.parse(window.localStorage.getItem(key))]);
}
//Included Maps
key = 'geostats-classic-included-maps-${USER_ID}';
if(window.localStorage.getItem(key)){
downloadData.userInfo.push([key , JSON.parse(window.localStorage.getItem(key))]);
}
//Unfinished Classic Games
key = 'geostats-unfinished-classic-games-${USER_ID}';
if(window.localStorage.getItem(key)){
downloadData.userInfo.push([key , JSON.parse(window.localStorage.getItem(key))]);
}
};
function getAllGamemodeStats(downloadData){
downloadData.gameMode = 'all';
for(let key in window.localStorage){
let newValue = [];
if(key.includes('${USER_ID}')){
newValue.push(key);
if(isJson(window.localStorage[key])){
newValue.push(JSON.parse(window.localStorage[key]));
}
else{
newValue.push(window.localStorage[key]);
}
downloadData.userInfo.push(newValue);
}
}
};
function isJson(string){
try{
JSON.parse(string);
}
catch(e){
return false;
}
return true;
};
//DOWNLOAD
function getFileContent(){
let downloadData = {
type: 'GeoStats_Object',
id: '${USER_ID}',
gameMode: '',
userInfo: []
};
//Get Settings Values
if(window.localStorage.getItem('units-svg-map')){
downloadData.userInfo.push(['units-svg-map', window.localStorage.getItem('units-svg-map')]);
}
if(window.localStorage.getItem('allow-healing-rounds')){
downloadData.userInfo.push(['allow-healing-rounds', JSON.parse(window.localStorage.getItem('allow-healing-rounds'))]);
}
if(window.localStorage.getItem('competitive-only-mode')){
downloadData.userInfo.push(['competitive-only-mode', JSON.parse(window.localStorage.getItem('competitive-only-mode'))]);
}
let baseInfoCount = downloadData.userInfo.length + 4; //+4 is for: "update, setup, left range, right range" in localstorage
let userOption = prompt("Which Stats Would You Like To Download?\\nEnter 'd' for Duels, 'c' for Classic, or 'a' for All");
switch(userOption){
case 'd':
getAllDuelsStats(downloadData);
break;
case'c':
getAllClassicStats(downloadData);
break;
case 'a':
getAllGamemodeStats(downloadData);
break;
case null:
return 'NO OPTION SELECTED';
break;
default:
return 'INVALID INPUT';
}
//If There Are No Stats To Download
if(downloadData.userInfo.length <= baseInfoCount){
return 'NO EXISTING STATS TO DOWNLOAD';
}
return JSON.stringify(downloadData);
};
function makeTextFile(text){
let data = new Blob([text], {type: 'text/plain'});
if(downloadFile != null){
window.URL.revokeObjectURL(downloadFile);
}
downloadFile = window.URL.createObjectURL(data);
return downloadFile;
};
function downloadAllStats(e){
if(!e.isTrusted){
return;
}
let link = document.getElementById('download-link');
let fileContent = getFileContent();
if(fileContent == 'NO EXISTING STATS TO DOWNLOAD'){
document.getElementById('download-file-status').style.color = 'red';
document.getElementById('download-file-status').textContent = 'No Existing Stats To Download';
}
else if(fileContent == 'NO OPTION SELECTED'){
document.getElementById('download-file-status').style.color = 'red';
document.getElementById('download-file-status').textContent = 'No option selected';
}
else if(fileContent == 'INVALID INPUT'){
document.getElementById('download-file-status').style.color = 'red';
document.getElementById('download-file-status').textContent = 'Invalid Input';
}
else{
link.href = makeTextFile(fileContent);
link.click();
document.getElementById('download-file-status').style.color = 'green';
document.getElementById('download-file-status').textContent = 'Successfully Downloaded Stats';
}
};
//UPLOAD
function deleteOldStats(gameMode){
switch(gameMode){
case 'duels':
resetDuelsScores();
break;
case 'classic':
resetClassicScores();
break;
case 'all':
for(let key in window.localStorage){
if(key.includes('${USER_ID}')){
window.localStorage.removeItem(key);
}
}
break;
default:
}
};
function addNewStats(){
uploadFileData.userInfo.forEach((value) => {
if(typeof value[1] === 'string'){
window.localStorage.setItem(value[0], value[1]);
}
else{
window.localStorage.setItem(value[0], JSON.stringify(value[1]));
}
});
};
function getFileData(event){
let reader = new FileReader();
reader.readAsText(event.target.files[0]);
reader.addEventListener('load', (event) => {
try{
//Check if file content is JSON
if(!isJson(event.target.result)){
throw "File Content Is Not Json";
}
uploadFileData = JSON.parse(event.target.result);
//Check if the object is the right one
if(uploadFileData.type != 'GeoStats_Object'){
throw "File Content Is The Wrong Type";
}
//Check if the file stats have the same user id
if(uploadFileData.id != '${USER_ID}'){
throw "File Contains Different User Id";
}
let gameMode = uploadFileData.gameMode;
if(confirm('Are you sure you want to upload new stats? This will erase ' + gameMode + ' exisiting stats.')){
//Delete existing stats
deleteOldStats(gameMode);
//Add new stats
addNewStats();
//If all good
document.getElementById('upload-file-status').style.color = 'green';
document.getElementById('upload-file-status').textContent = 'Successfully Uploaded New Stats - Reload Page';
}
}
catch(message){
//If error exists
document.getElementById('upload-file-status').style.color = 'red';
document.getElementById('upload-file-status').textContent = message;
}
});
};
function checkFile(event){
readyToUpload = false;
uploadData = null;
document.getElementById('select-file-status').style.color = 'red';
document.getElementById('select-file-status').textContent = event.target.files[0].name;
//Check if the file is the right type to upload
if(event.target.files.length != 1){
return;
}
if(event.target.files[0].type != 'text/plain'){
return;
}
//If all good
readyToUpload = true;
uploadData = event;
document.getElementById('select-file-status').style.color = 'green';
};
//Add Event Listeners For Upload and Download
document.getElementById('download-file-button').addEventListener('click', downloadAllStats);
document.getElementById('select-file-button').addEventListener('change', checkFile);
document.getElementById('upload-file-button').addEventListener('click', () => {
if(readyToUpload){
getFileData(uploadData);
}
else{
document.getElementById('upload-file-status').style.color = 'red';
document.getElementById('upload-file-status').textContent = 'Please Select A File To Upload';
}
});
//PANNING AND ZOOMING ON THE MAP
let worldMap = document.getElementById('world-map');
let viewbox = worldMap.viewBox.baseVal;
let pointerDown = false;
let mousePoint;
//Return x and y values from pointer event
function getPointFromEvent(event){
let point = worldMap.createSVGPoint();
point.x = event.clientX;
point.y = event.clientY;
//Get current transformation matrix and inverse it
let invertedSVGMatrix = worldMap.getScreenCTM().inverse();
return point.matrixTransform(invertedSVGMatrix);
}
//When user clicks map to start panning
function onPointerDown(event){
event.preventDefault();
pointerDown = true;
mousePoint = getPointFromEvent(event);
}
//When user drags mouse
function onPointerMove(event){
if (!pointerDown){
return;
}
event.preventDefault();
document.getElementById('world-map').style = 'cursor: grabbing';
let pointerPosition = getPointFromEvent(event);
viewbox.x = (viewbox.x - (pointerPosition.x - mousePoint.x));
viewbox.y = (viewbox.y - (pointerPosition.y - mousePoint.y));
checkBounds();
}
//When user lifts mouse up
function onPointerUp(){
event.preventDefault();
pointerDown = false;
document.getElementById('world-map').style = 'cursor: auto';
}
//When user scrolls mouse
function onMouseWheel(event){
if(!event.shiftKey){
return;
}
event.preventDefault();
let delta = (event.wheelDelta ? event.wheelDelta : -event.deltaY);
mousePoint = getPointFromEvent(event);
//If mouse wheel moves forward
if(delta > 0){
//Zoom In Limit
if(viewbox.width > 325 && viewbox.height > 140){
//Make the viewbox smaller
viewbox.width /= 1.1;
viewbox.height /= 1.1;
//Position the top left accordingly
viewbox.x = (((mousePoint.x - viewbox.x) * viewbox.width) - ((mousePoint.x - viewbox.x) * mousePoint.x) - ((viewbox.x + (viewbox.width * 1.1) - mousePoint.x) * mousePoint.x) ) / ( -((mousePoint.x - viewbox.x) + (viewbox.x + (viewbox.width * 1.1) - mousePoint.x)) );
viewbox.y = (((mousePoint.y - viewbox.y) * viewbox.height) - ((mousePoint.y - viewbox.y) * mousePoint.y) - ((viewbox.y + (viewbox.height * 1.1) - mousePoint.y) * mousePoint.y) ) / ( -((mousePoint.y - viewbox.y) + (viewbox.y + (viewbox.height * 1.1) - mousePoint.y)) );
}
}
//If mouse wheel moves backward
else{
//Zoom Out Limit
if(viewbox.width < 2000 && viewbox.height < 857){
//Make the viewbox bigger
viewbox.width *= 1.1;
viewbox.height *= 1.1;
//Position the top left accordingly
viewbox.x = (((viewbox.x + (viewbox.width / 1.1) - mousePoint.x) * mousePoint.x) - ((mousePoint.x - viewbox.x) * viewbox.width) + ((mousePoint.x - viewbox.x) * mousePoint.x)) / ((mousePoint.x - viewbox.x) + (viewbox.x + (viewbox.width / 1.1) - mousePoint.x));
viewbox.y = (((viewbox.y + (viewbox.height / 1.1) - mousePoint.y) * mousePoint.y) - ((mousePoint.y - viewbox.y) * viewbox.height) + ((mousePoint.y - viewbox.y) * mousePoint.y)) / ((mousePoint.y - viewbox.y) + (viewbox.y + (viewbox.height / 1.1) - mousePoint.y));
}
}
checkBounds();
}
//Check if the map is out of bounds
function checkBounds(){
//Left
if(viewbox.x < 0){
viewbox.x = 0;
}
//Top
if(viewbox.y < 0){
viewbox.y = 0;
}
//Right
if((viewbox.x + viewbox.width) > 2000){
viewbox.x = 2000 - viewbox.width;
}
//Bottom
if((viewbox.y + viewbox.height) > 857){
viewbox.y = 857 - viewbox.height;
}
}
//Add event listeners
worldMap.addEventListener('pointerdown', onPointerDown);
worldMap.addEventListener('pointerup', onPointerUp);
worldMap.addEventListener('pointerleave', onPointerUp);
worldMap.addEventListener('pointermove', onPointerMove);
worldMap.addEventListener('wheel', onMouseWheel);
}`;
let referenceNode = document.getElementsByClassName('version3_main__xNkED')[0];
let siblingNode = document.getElementsByClassName('footer_footer__NmtmJ')[0];
referenceNode.parentNode.insertBefore(svgMap, siblingNode);
document.head.appendChild(cssForMap);
document.getElementById('map-wrapper-element').appendChild(scriptForMap);
};
/************************************************** START PAGE STUFF HERE **************************************************/
function addToggleToStartPage(){
//Create The Html
const htmlForToggle = `
`;
//Create The Script
const scriptForToggle = document.createElement('script');
scriptForToggle.setAttribute('id','geostats-standard-game-start-page-toggle-script');
scriptForToggle.textContent = `{
//Check If Toggle Should Be Checked
let maps = JSON.parse(window.localStorage.getItem('geostats-classic-included-maps-${USER_ID}'));
let currentMapId = window.location.href.replace('https://www.geoguessr.com/maps/', '');
currentMapId = currentMapId.replace('/play', '');
if(maps.ids.includes(currentMapId)){
document.getElementById('geostats-track-stats-for-this-map-toggle').checked = true;
}
//When The Toggle Changes
function toggleChange(toggle){
let currentMapId = window.location.href.replace('https://www.geoguessr.com/maps/', '');
currentMapId = currentMapId.replace('/play', '');
let maps = JSON.parse(window.localStorage.getItem('geostats-classic-included-maps-${USER_ID}'));
if(toggle.path[0].checked){
//Add The Map Id
if(!maps.ids.includes(currentMapId)){
maps.ids.push(currentMapId);
}
}
else{
//Remove The Map Id
if(maps.ids.includes(currentMapId)){
const index = maps.ids.indexOf(currentMapId);
maps.ids.splice(index,1);
}
}
//Save Updated Maps List
window.localStorage.setItem('geostats-classic-included-maps-${USER_ID}', JSON.stringify(maps));
}
document.getElementById('geostats-track-stats-for-this-map-toggle').addEventListener('click', toggleChange);
}`;
//Add Everything To The Page
document.querySelector('.section_sectionMedium__yXgE6').insertAdjacentHTML('beforeend', htmlForToggle);
document.getElementById('geostats-standard-game-start-page-toggle-html').appendChild(scriptForToggle);
};
let observer = new MutationObserver((mutations) => {
startpageCheck();
});
observer.observe(document.body, {
characterDataOldValue: false,
subtree: true,
childList: true,
characterData: false
});
//************************************************************** END OF SCRIPT **************************************************************//