Geoguessr Unity Script

For a full list of features included in this script, see this document https://docs.google.com/document/d/18nLXSQQLOzl4WpUgZkM-mxhhQLY6P3FKonQGp-H0fqI/edit?usp=sharing

Verzia zo dňa 11.02.2022. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name          Geoguessr Unity Script
// @description   For a full list of features included in this script, see this document https://docs.google.com/document/d/18nLXSQQLOzl4WpUgZkM-mxhhQLY6P3FKonQGp-H0fqI/edit?usp=sharing
// @version       5.0.0
// @author        Jupaoqq
// @include       https://www.geoguessr.com/*
// @run-at        document-start
// @license       MIT
// @namespace     https://greasyfork.org/users/838374
// @grant         none
// ==/UserScript==

/**
 * Custom your minimap here!
 */

/**
 * 1: replace "roadmap" in the customMode field with any of the options below:
 * "roadmap" displays the default road map view. This is the default map type.
 * "satellite" displays Google Earth satellite images.
 * "hybrid" displays a mixture of normal and satellite views.
 * "terrain" displays a physical map based on terrain information.
 */

let customMode = "roadmap";

/**
 * 2: Go to https://mapstyle.withgoogle.com/ first click "No thanks, take me to the old style wizard"
 * then click "MORE OPTIONS" to hide or reveal certain features.
 * When you are done, click "FINISH", then "COPY JSON", and replace my settings in custom with your settings below.
 */

let custom =

    [
        {
            "featureType": "administrative",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "landscape",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "poi.park",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "road",
            "elementType": "labels",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "transit",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        }
    ]

/**
 * End of Minimap customization instruction section
 */

/**
 * Overlay anything on the minimap here!
 * 1. overlay an GeoJSON object
 * 2. overlay a custom image
 */

/**
 * Overlay an GeoJSON object:
 */

// change the GeoJson display style.
// strokeOpacity, strokeWeight, fillOpacity takes a value between 0 and 1.
// strokeColor and fillColor supports Hexadecimal color (#00FF00 is green)
// If clickable is set to true, you would not be able to make a guess within the shape

let GEOJSON_STYLE =
    {
        strokeColor: "black",
        strokeOpacity: 1,
        strokeWeight: 0.2,
        fillColor: "#00FF00",
        fillOpacity: 0,
        clickable: false,
    }

// replace the URL with your desired link
// For example, search "Germany GeoJson" on Github, find this link (https://github.com/isellsoap/deutschlandGeoJSON/blob/main/4_kreise/4_niedrig.geo.json)
// Then click "Download" to get the raw.githubusercontent.com link (https://raw.githubusercontent.com/isellsoap/deutschlandGeoJSON/main/4_kreise/4_niedrig.geo.json)
// and replace the URL below with that URL.
// State zipcode: see this site https://github.com/OpenDataDE/State-zip-code-GeoJSON

let YOUR_URL = "https://raw.githubusercontent.com/severinlandolt/map-switzerland/main/02%20GeoJSON/CH_Kantonsgrenzen_100_geo.json"

// set it to true to add your custom GeoJSON by copy it to the code below (this is for

let GeoJsonCustomUser = false

// replace with your custom GeoJson, go to https://geojson.io/ to customize it then copy the Json to here

let CUSTOM_GEOJSON =

    {
        "type": "FeatureCollection",
        "features": [
            {
                "type": "Feature",
                "properties": {},
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [
                            2.493896484375,
                            52.7163309360463
                        ],
                        [
                            2.4609375,
                            53.15994678846807
                        ],
                        [
                            3.2025146484375,
                            53.179703893605385
                        ],
                        [
                            3.2080078125,
                            52.96518371955126
                        ],
                        [
                            2.48291015625,
                            52.948637884883205
                        ]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {},
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [
                            3.218994140625,
                            52.05586831074774
                        ],
                        [
                            3.218994140625,
                            52.13685974852633
                        ],
                        [
                            2.515869140625,
                            52.1267438596429
                        ],
                        [
                            2.515869140625,
                            51.77803705914517
                        ],
                        [
                            3.2354736328125,
                            51.78993084774129
                        ],
                        [
                            3.228607177734375,
                            51.96119237712624
                        ],
                        [
                            2.8571319580078125,
                            51.95230623740452
                        ]
                    ]
                }
            },
            {
                "type": "Feature",
                "properties": {
                    "stroke": "#555555",
                    "stroke-width": 2,
                    "stroke-opacity": 1
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [
                            2.5048828125,
                            52.619725272670266
                        ],
                        [
                            2.5103759765625,
                            52.274880130680536
                        ],
                        [
                            2.867431640625,
                            52.284962354465726
                        ],
                        [
                            3.2299804687499996,
                            52.29504228453735
                        ],
                        [
                            3.2135009765625,
                            52.63973017532399
                        ],
                        [
                            2.5096893310546875,
                            52.621392697207625
                        ]
                    ]
                }
            }
        ]
    }

/**
 * Overlay a custom image:
 */

// set it to true to add your image overlay

let OverlayCustom = false

// replace the URL with your desired link

let OVERLAY_URL = "https://www.battleface.com/blog/wp-content/uploads/2020/10/patreon-profile-tom-geowizard.jpg"

// set the bounds for the image - latitude (North and South), longitude (North and South)

let OVERLAY_BOUNDS =
    {
        north: 53,
        west: -3,
        south: 51,
        east: 1,
    };

// change the image overlay display style.

let OVERLAY_STYLE =
    {
        fillOpacity: 0.2,
        clickable: false,
    }

/**
 * End of Minimap Overlay instruction section
 */

// API Keys

var MS_API_KEY = "AjWqExh5E9aZfgKKBrgJMM2tbBeJ_q9ET7__194VDfcpl8lEWYTYNRWoYE1kqy95";
var YANDEX_API_KEY = "b704b5a9-3d67-4d19-b702-ec7807cecfc6";
var KAKAO_API_KEY = "cbacbe41e3a223d794f321de4f3e247b";
const MAPS_API_URL = "https://maps.googleapis.com/maps/api/js"; // removed "?" from the link
var MAPILLARY_API_KEY_LIST =
    ["MLY|6723031704435203|5afd537469b114cf814881137ad74b7c",
     "MLY|6691659414239148|b45e7e82cde126044cbc2cf5d4a7c9b1",
     "MLY|5074369465929308|f7ad2802cbaf26c63f88046a292df68b",
     "MLY|7451643761528219|6477f2db0e3928b51e45ec9311983936",
     "MLY|4855256237866198|6d0464771831c8a4bf2be095e1e1aabc",
     "MLY|4772941976102161|8458d4f08d2e1970cdfe0a4e242c04ff",
     "MLY|4492067214235489|94c44703942362ad6f6b70b5d32c3a45",
     "MLY|4618251611628426|0cef71d6ec8b997a5ec06ecdeabf11ec",
     "MLY|4096846270415982|fa2ce29641503e6ef665f17459633570",
     "MLY|4231415756962414|fe353880fd246e8a4a6ae32152f7dbb0",]

var MAPILLARY_API_KEY = MAPILLARY_API_KEY_LIST[Math.floor(Math.random() * MAPILLARY_API_KEY_LIST.length)];

console.log("Geoguessr Unity Script v5.0.0 by Jupaoqq");

// Store each player instance

let YandexPlayer, KakaoPlayer, GooglePlayer, MapillaryPlayer, MSStreetPlayer;
let YANDEX_INJECTED = false;
let BAIDU_INJECTED = false;
let KAKAO_INJECTED = false;
let MAPILLARY_INJECTED = false;
let MS_INJECTED = false;

// Game mode detection

let isBattleRoyale = false;
let isDuel = false;
let isBullseye = false;

// Player detection and coordinate conversion

let nextPlayer = "Google";
let global_lat = 0;
let global_lng = 0;
let global_panoID = null;
let global_BDID, global_BDAh, global_BDBh;
let yId, yTime, yEnd, iId;
let global_heading = null;
let global_pitch = null;

let krCoordinates = [38.75292321084364, 124.2804539232574, 33.18509676203202, 129.597381999198]
let global_radi = 100

// Callback variables

let eventListenerAttached = false;
let povListenerAttached = false;
let playerLoaded = false;
let teleportLoaded = false;
let syncLoaded = false;

// Minimize Yandex API use

let yandex_map = false;
let Kakao_map = false;

// Mapillary Image Key

let mmKey = 0;

// Handle Yandex compass

let COMPASS = null;

// Handle undo

let locHistory = [];
let defaultPanoIdChange = true;

// Round check

let ROUND = 0;
let CURRENT_ROUND_DATA = null;

let switch_call = true;
let one_reset = false;
// let cnt = 0;

let cn_tips = false;
var isFirefox = typeof InstallTrigger !== 'undefined';

let linksList = []
let fire1 = true;

let CNBorder = false;

// Satellite Map Radius (in Meters)
let ms_radius = 10000;

// Create the Maps, but not reload API
let partialCreateYandex = false;
let partialCreateKakao = false;
let partialCreateMapillary = false;
let partialCreateMS = false;

// let NEW_ROUND_LOADED = false;

// Geoguessr Canvas String Names

let GENERAL_CANVAS = ".game-layout__panorama-canvas";
let BR_CANVAS = ".br-game-layout__panorama-canvas";
let FAIL_TO_LOAD_CANVAS = ".game-layout__panorama-message";
let DUEL_LAYOUT = ".game_layout__TO_jf";
let DUELS_CANVAS = ".game-panorama_panorama__rdhFg";
let DUELS_CANVAS2 = ".game-panorama_panoramaCanvas__PNKve";
let BULLSEYE_CANVAS = ".game-panorama_panorama__ncMwh";
let BULLSEYE_CANVAS2 = ".game-panorama_panoramaCanvas__r_5ea";
let DUELS_POPUP = ".overlay_overlay__AR02x"
let BR_POPUP = ".popup__content"

let BR_LOAD_KAKAO = false;
let BR_LOAD_YANDEX = false;
let BR_LOAD_MS = false;

let ms_sat_map = false;

/**
 * Helper Functions
 */

// Highlight API Load Message

function myHighlight(...args) {
    console.log(`%c${[...args]}`, "color: dodgerblue; font-size: 24px;");
}

// Hex to number conversion for Baidu coordinate conversion

function hex2a(hexx) {
    var hex = hexx.toString();
    var str = '';
    for (var i = 0; i < hex.length; i += 2)
    {
        str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    }
    return str;
}

// Coordinate computation given heading, distance and current coordinates for teleport

function FindPointAtDistanceFrom(lat, lng, initialBearingRadians, distanceKilometres) {
    const radiusEarthKilometres = 6371.01;
    var distRatio = distanceKilometres / radiusEarthKilometres;
    var distRatioSine = Math.sin(distRatio);
    var distRatioCosine = Math.cos(distRatio);

    var startLatRad = DegreesToRadians(lat);
    var startLonRad = DegreesToRadians(lng);

    var startLatCos = Math.cos(startLatRad);
    var startLatSin = Math.sin(startLatRad);

    var endLatRads = Math.asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.cos(initialBearingRadians)));

    var endLonRads = startLonRad
    + Math.atan2(
        Math.sin(initialBearingRadians) * distRatioSine * startLatCos,
        distRatioCosine - startLatSin * Math.sin(endLatRads));

    return { lat: RadiansToDegrees(endLatRads), lng: RadiansToDegrees(endLonRads) };
}

function DegreesToRadians(degrees) {
    const degToRadFactor = Math.PI / 180;
    return degrees * degToRadFactor;
}

function RadiansToDegrees(radians) {
    const radToDegFactor = 180 / Math.PI;
    return radians * radToDegFactor;
}

function toRadians(degrees) {
    return degrees * Math.PI / 180;
};

// Converts from radians to degrees.
function toDegrees(radians) {
    return radians * 180 / Math.PI;
}

function bearing(start_latitude, start_longitude, stop_latitude, stop_longitude){
    let y = Math.sin(stop_longitude-start_longitude) * Math.cos(stop_latitude);
    let x = Math.cos(start_latitude)*Math.sin(stop_latitude) -
        Math.sin(start_latitude)*Math.cos(stop_latitude)*Math.cos(stop_longitude-start_longitude);
    let brng = Math.atan2(y, x) * 180 / Math.PI;
    return brng
}

// Check if two floating point numbers are really really really really close to each other (to 10 decimal points)
function almostEqual (a, b) {
    return a.toFixed(10) === b.toFixed(10)
}

function almostEqual2 (a, b) {
    return a.toFixed(3) === b.toFixed(3)
}

// Script injection, extracted from extenssr:
// https://gitlab.com/nonreviad/extenssr/-/blob/main/src/injected_scripts/maps_api_injecter.ts

function overrideOnLoad(googleScript, observer, overrider) {
    const oldOnload = googleScript.onload
    googleScript.onload = (event) => {
        const google = window.google
        if (google) {
            observer.disconnect()
            overrider(google)
        }
        if (oldOnload) {
            oldOnload.call(googleScript, event)
        }
    }
}

function grabGoogleScript(mutations) {
    for (const mutation of mutations) {
        for (const newNode of mutation.addedNodes) {
            const asScript = newNode
            if (asScript && asScript.src && asScript.src.startsWith('https://maps.googleapis.com/')) {
                return asScript
            }
        }
    }
    return null
}

function injecter(overrider) {
    if (document.documentElement)
    {
        injecterCallback(overrider);
    }
    else
    {
        alert("Script didn't load, refresh to try loading the script");
    }
}

function observeMapChange()
{
    if (document.querySelector(".game-options_optionLabel__dJ_Cy") !== null)
    {
        let mapName = document.querySelector(".game-options_optionLabel__dJ_Cy").innerHTML;
        if (mapName !== "" && mapName !== "Sound off" && mapName !== "Sound on" && mapName !== sessionStorage.getItem('mapName'))
        {
            console.log("Mapname: " + mapName);
            sessionStorage.setItem('mapName', mapName);
        }
    }
}

function injecterCallback(overrider)
{
    new MutationObserver((mutations, observer) => {
        const googleScript = grabGoogleScript(mutations)
        if (googleScript) {
            overrideOnLoad(googleScript, observer, overrider)
        }
        observeMapChange();
        let nav = document.getElementById('MicrosoftNav');
        if (nav)
        {
            nav.style.visibility = "hidden";
        }
    }).observe(document.documentElement, { childList: true, subtree: true })
    //         if (document.querySelector(".game-options_optionLabel__dJ_Cy" !== null))
    //     {
    //         let mapName = document.querySelector(".game-options_optionLabel__dJ_Cy")
    //         console.log(mapName.innerHTML)
    //         sessionStorage.setItem(mapName.innerHTML, 'mapName')
    //     }
}

// Getter function for the button elements

function setButtons()
{
    return [document.getElementById("Teleport Button"), document.getElementById("plus"), document.getElementById("minus"), document.getElementById("reset"), document.getElementById("switch"), document.getElementById("Show Buttons"), document.getElementById("Date Button"), document.getElementById("minus year"), document.getElementById("plus year"), document.getElementById("Minimap Button"), document.getElementById("Overlay Button"), document.getElementById("Help Button"), document.getElementById("Teleport Options Button")];
}

// Store default position for the button elements

function resetBtnPos()
{
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    teleportBtn.style.top = "8.5em";
    teleportMoreBtn.style.top = "8.5em";
    teleportLessBtn.style.top = "8.5em";
    teleportDistResetBtn.style.top = "11em";
    switchCovergeButton.style.top = "6em";
    mainMenuBtn.style.top = "6em";
    timeMachineBtn.style.top = "13.5em";
    timeMachineOlderBtn.style.top = "13.5em";
    timeMachineNewerBtn.style.top = "13.5em";
    MinimapBtn.style.top = "16em";
    OverlayBtn.style.top = "16em";
    HelpBtn.style.top = "6em";
    TeleportArisBtn.style.top = "11em";
    document.getElementById("Youtube Button").style.top = "13.5em";

    teleportBtn.style.right = "9.5em";
    teleportMoreBtn.style.right = "7em";
    teleportLessBtn.style.right = "20em";
    teleportDistResetBtn.style.right = "13em";
    switchCovergeButton.style.right = "7em";
    mainMenuBtn.style.right = "0.5em";
    timeMachineBtn.style.right = "9.5em";
    timeMachineOlderBtn.style.right = "20em";
    timeMachineNewerBtn.style.right = "7em";
    MinimapBtn.style.right = "14.75em";
    OverlayBtn.style.right = "7em";
    HelpBtn.style.right = "16em";
    TeleportArisBtn.style.right = "7em";
    document.getElementById("Youtube Button").style.right = "0.5em";

    let hC = 0
    for (let mapDiv of document.getElementsByClassName("preset-minimap")){
        mapDiv.style.top = (18.1 + (hC * 1.6)).toString() + "em";
        mapDiv.style.right = "14.75em";
        hC++;
    }
    let hC2 = 0
    for (let mapDiv2 of document.getElementsByClassName("overlay-minimap")){
        mapDiv2.style.top = (18.1 + (hC2 * 1.6)).toString() + "em";
        mapDiv2.style.right = "7em";
        hC2++;
    }
}

// Adjust Buttons for different game modes

function AdjustBtnPos(top, right)
{
    resetBtnPos();
    for (let element of document.getElementsByClassName("unity-btn")){
        let eTop = element.style.top;
        let eRight = element.style.right;
        element.style.top = "calc(" + top.toString() + " + " + eTop + ")";
        element.style.right = "calc(" + right.toString() + " + " + eRight + ")";
        // console.log(element.style.top)
    }
}

/**
 * Creates Unity buttons
 *
 * @returns Promise
 */

function UnityInitiate() {
    const google = window.google;
    let curPosition;
    let kakao_enabled = true;

    function svCheck(data, status) {
        if (status === 'OK') {
            // console.log("STATUS OK");
            let l = data.location.latLng.toString().split(',');
            let lat = l[0].replaceAll('(', '');
            let lng = l[1].replaceAll(')', '');
            if (lat == curPosition.lat && lng == curPosition.lng && !switch_call)
            {
                console.log("Trying more distance");
                teleportBtn.distance += 100;
                teleportBtn.innerHTML = "Teleport " + teleportBtn.distance + " m";
            }
            else
            {
                console.log("Teleport Success");
                GooglePlayer.setPosition(data.location.latLng);
                GooglePlayer.setPov({
                    heading: switchCovergeButton.heading,
                    pitch: 0,
                })
                if (teleportBtn.distance > 150)
                {
                    teleportBtn.distance = 100;
                    teleportBtn.innerHTML = "Teleport " + teleportBtn.distance + " m";
                }
            }
            switch_call = false;
        }
        else {
            console.log("STATUS NOT OK");
            teleportBtn.distance += 100;
            teleportBtn.innerHTML = "Teleport " + teleportBtn.distance + " m";
        }
    }

    google.maps.Map = class extends google.maps.Map {
        constructor(...args) {
            super(...args);
            if (GeoJsonCustomUser)
            {
                if (GeoJsonCustomUser)
                {
                    this.data.addGeoJson(CUSTOM_GEOJSON);
                }
                this.data.setStyle(function(feature) {
                    return GEOJSON_STYLE
                });
            }
            if (OverlayCustom)
            {
                let customOverlay = new google.maps.GroundOverlay(OVERLAY_URL, OVERLAY_BOUNDS, OVERLAY_STYLE);
                customOverlay.setMap(this);
            }

            if (CNBorder)
            {
                this.data.loadGeoJson("https://raw.githubusercontent.com/Jupaoqq/Jupaoqq.github.io/main/10DD.json");
                this.data.setStyle(function(feature) {
                    return {
                        clickable: false,
                        strokeWeight: 1
                    }
                });

                const imageBounds3 = {
                    north: NW[0],
                    west: NW[1],
                    south: NW[2],
                    east: NW[3],
                };

                SEOverlay3 = new google.maps.GroundOverlay(
                    "https://www.countryflags.com/wp-content/uploads/china-flag-png-large.png",
                    imageBounds3, {clickable: false, opacity: 1}
                );
                SEOverlay3.setMap(this);

                this.addListener("zoom_changed", () => {
                    let zoomLevel = this.getZoom();
                    let opacity = 1;
                    if (SEOverlay)
                    {
                        SEOverlay.setMap(null);
                        NWOverlay.setMap(null);
                    }
                    let borderSE = TW[0]
                    let borderNW = TS[0]
                    if (zoomLevel > 7 && zoomLevel < 14)
                    {
                        borderSE = TW[zoomLevel - 7];
                        borderNW = TS[1];
                    }
                    if (zoomLevel >= 14)
                    {
                        opacity = 0;
                    }
                    const imageBounds = {
                        north: borderSE[0],
                        west: borderSE[1],
                        south: borderSE[2],
                        east: borderSE[3],
                    };
                    SEOverlay = new google.maps.GroundOverlay(
                        "https://www.countryflags.com/wp-content/uploads/china-flag-png-large.png",
                        imageBounds, {clickable: false, opacity: opacity}
                    );
                    SEOverlay.setMap(this);
                    const imageBounds2 = {
                        north: borderNW[0],
                        west: borderNW[1],
                        south: borderNW[2],
                        east: borderNW[3],
                    };
                    NWOverlay = new google.maps.GroundOverlay(
                        "https://www.countryflags.com/wp-content/uploads/china-flag-png-large.png",
                        imageBounds2, {clickable: false, opacity: 1}
                    );
                    NWOverlay.setMap(this);
                });
            }
            for (let mapDiv of document.getElementsByClassName("preset-minimap")){
                google.maps.event.addDomListener(mapDiv, "click", () => {
                    MinimapBtn.current = mapDiv.id;
                    if (mapDiv.id == "Hybrid")
                    {
                        this.setMapTypeId('hybrid');
                    }
                    else if (mapDiv.id == "Terrain")
                    {
                        this.setMapTypeId('terrain');
                    }
                    else if (mapDiv.id == "Satellite")
                    {
                        this.setMapTypeId('satellite');
                    }
                    else if (mapDiv.id == "Custom")
                    {
                        this.setMapTypeId(customMode);
                    }
                    else
                    {
                        this.setMapTypeId('roadmap');
                    }
                    // this.setTilt(45);
                    for (let ar of presetMinimap)
                    {
                        if (ar[1] == mapDiv.id)
                        {
                            this.set('styles', ar[0]);
                        }
                    }
                    for (let element of document.getElementsByClassName("preset-minimap")){
                        if (element.id == MinimapBtn.current)
                        {
                            element.style.background = "#ff1493";
                        }
                        else
                        {
                            element.style.background = "#ff69b4";
                        }
                    }

                });
            }
            for (let mapDiv of document.getElementsByClassName("overlay-minimap")){
                google.maps.event.addDomListener(mapDiv, "click", () => {
                    OverlayBtn.current = mapDiv.id;
                    //                     console.log(mapDiv.url)
                    //                     console.log(mapDiv.id)
                    //                     console.log(mapDiv.loaded)
                    if (!mapDiv.loaded)
                    {
                        this.data.loadGeoJson(mapDiv.url, {
                            id: mapDiv.id
                        });
                        mapDiv.loaded = true;
                    }
                    if (mapDiv.id == "Clear")
                    {
                        this.overlayMapTypes.clear();
                        this.data.setStyle(function(feature) {
                            return GEOJSON_INVISIBLE
                        });
                        for (let element of document.getElementsByClassName("overlay-minimap")){
                            if (element.id === "Clear")
                            {
                                element.style.background = "#ff1493";
                            }
                            else
                            {
                                element.style.background = "#ff69b4";
                            }
                        }
                    }
                    else
                    {
                        if (mapDiv.id == "Coverage" || mapDiv.id == "Official")
                        {
                            this.overlayMapTypes.clear();
                            const coverageLayer = new google.maps.ImageMapType({
                                getTileUrl ({ x, y }, z) {
                                    // Omits photospheres
                                    // return `https://mts1.googleapis.com/vt?hl=en-US&lyrs=svv|cb_client:apiv3&style=5,8&x=${x}&y=${y}&z=${z}`

                                    // Omits unofficial and trekker, but also half of mongolia
                                    if (mapDiv.id == "Official")
                                    {
                                        return `https://mts1.googleapis.com/vt?hl=en-US&lyrs=svv|cb_client:app&style=5,8&x=${x}&y=${y}&z=${z}`
                                    }
                                    // return `https://maps.googleapis.com/maps/vt?pb=!1m5!1m4!1i${z}!2i${x}!3i${y}!4i256!2m8!1e2!2ssvv!4m2!1scb_client!2sapp!4m2!1scc!2s*211m3*211e3*212b1*213e2*211m3*211e2*212b1*213e2!3m3!3sUS!12m1!1e68!4e0`

                                    // Includes everything
                                    else
                                    {
                                        return `https://maps.googleapis.com/maps/vt?pb=!1m5!1m4!1i${z}!2i${x}!3i${y}!4i256!2m8!1e2!2ssvv!4m2!1scb_client!2sapiv3!4m2!1scc!2s*211m3*211e3*212b1*213e2*211m3*211e2*212b1*213e2!3m3!3sUS!12m1!1e68!4e0`
                                    }
                                },
                                maxZoom: 20,
                                tileSize: new google.maps.Size(256, 256),
                            })
                            this.overlayMapTypes.push(coverageLayer);

                            let other = "Official";
                            if (mapDiv.id == "Official")
                            {
                                other = "Coverage"
                            }

                            mapDiv.style.background = "#ff1493";

                            for (let element of document.getElementsByClassName("overlay-minimap")){
                                if (element.id === "Clear" || element.id === other)
                                {
                                    element.style.background = "#ff69b4";
                                }
                            }
                        }
                        else
                        {
                            this.data.setStyle(function(feature) {
                                return GEOJSON_STYLE
                            });
                            for (let element of document.getElementsByClassName("overlay-minimap")){
                                if (element.id !== "Coverage" && element.id !== "Official")
                                {
                                    if (element.id !== "Clear" && element.loaded)
                                    {
                                        element.style.background = "#ff1493";
                                    }
                                    else
                                    {
                                        element.style.background = "#ff69b4";
                                    }
                                }
                            }
                        }
                    }
                });
            }
        }

    }

    const svService = new google.maps.StreetViewService();
    google.maps.StreetViewPanorama = class extends google.maps.StreetViewPanorama {
        constructor(...args) {
            super(...args);
            GooglePlayer = this;

            const isGamePage = () => location.pathname.startsWith("/challenge/") || location.pathname.startsWith("/results/") || location.pathname.startsWith("/game/")|| location.pathname.startsWith("/battle-royale/") || location.pathname.startsWith("/duels/") || location.pathname.startsWith("/team-duels/") || location.pathname.startsWith("/bullseye/");

            this.addListener('position_changed', () => {
                // Maybe this could be used to update the position in the other players
                // so that they are always in sync
                try {
                    if (!isGamePage()) return;
                    // timeMachineBtn.panoId = GooglePlayer.pano;
                    // timeMachineBtn.index = -1;
                    const lat = this.getPosition().lat();
                    const lng = this.getPosition().lng();
                    const { heading } = this.getPov();

                    curPosition = { lat, lng, heading };

                    if (switchCovergeButton.useGoogle)
                    {
                        switchCovergeButton.lng = lng;
                        switchCovergeButton.lat = lat;
                        switchCovergeButton.heading = heading;
                        if (!timeMachineBtn.list.some(row => row.includes(GooglePlayer.pano)))
                        {
                            timeMachineBtn.innerHTML = "Time Machine";
                            timeMachineBtn.panoId = GooglePlayer.pano;
                            timeMachineBtn.index = -1;
                            timeMachineBtn.plusminusLock = true;
                            timeMachineNewerBtn.style.backgroundColor = "red";
                            timeMachineNewerBtn.disabled = true;
                            timeMachineOlderBtn.style.backgroundColor = "red";
                            timeMachineOlderBtn.disabled = true;
                        }
                    }
                    switchCovergeButton.useGoogle = true;
                    teleportBtn.google = true;
                    // console.log("also run");

                    // switchCovergeButton.heading = position.lat;
                    // console.log(position.heading);
                    // console.log(switchCovergeButton.lng);
                }
                catch (e) {
                    console.error("GeoGuessr Path Logger Error:", e);
                }
            });
            this.addListener('pov_changed', () => {
                const { heading, pitch } = this.getPov();
                if (KakaoPlayer) {
                    if (typeof KakaoPlayer !== 'string' )
                    {
                        const vp = KakaoPlayer.getViewpoint();
                        // Prevent a recursive loop: only update kakao's viewpoint if it got out of sync with google's
                        if ((!almostEqual(vp.pan, heading) || !almostEqual(vp.tilt, pitch)) && nextPlayer == "Kakao") {
                            KakaoPlayer.setViewpoint({ pan: heading, tilt: pitch, zoom: vp.zoom });
                        }
                    }
                }
            });
        }
    };


    var mainMenuBtn = document.createElement("Button");
    mainMenuBtn.classList.add("unity-btn");
    mainMenuBtn.id = "Show Buttons"
    mainMenuBtn.innerHTML = "Geoguessr Unity Script<br><font size=1>by Jupaoqq<br>v5.0.0</font>";
    mainMenuBtn.style =
        "visibility:hidden;width:6em;height:7em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    // document.querySelector(".game-layout__status").appendChild(mainMenuBtn)
    document.body.appendChild(mainMenuBtn);
    mainMenuBtn.addEventListener("click", () => {
        if (hide) {
            for (let element of document.getElementsByClassName("unity-btn")){
                if (!element.classList.contains("preset-minimap") && !element.classList.contains("overlay-minimap"))
                {
                    element.style.visibility = "";
                    if ((nextPlayer != "Youtube") && element.id == "Youtube Button")
                    {
                        element.style.visibility = "hidden";
                    }
                }
            }
            hide = false;
        }
        else {
            for (let element of document.getElementsByClassName("unity-btn")){
                if (element.id !== "Show Buttons")
                {
                    element.style.visibility = "hidden";
                }
            }
            hide = true;
        }
    });

    var teleportBtn = document.createElement("Button");
    teleportBtn.classList.add("unity-btn");
    teleportBtn.teleType = "default";
    teleportBtn.id = "Teleport Button";
    teleportBtn.distance = 100;
    teleportBtn.google = true;
    teleportBtn.innerHTML = "Teleport 100m";
    teleportBtn.style =
        "visibility:hidden;width:10em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(teleportBtn);
    teleportBtn.addEventListener("click", () => {
        // console.log("Google Teleport");
        if (switchCovergeButton.init)
        {
            // console.log("run");
            switchCovergeButton.init = false;
            if (teleportBtn.google)
            {
                switchCovergeButton.useGoogle = true;
                teleportBtn.google = true;
            }
            else
            {
                switchCovergeButton.useGoogle = false;
                teleportBtn.google = false;
            }
        }
        else
        {
            // console.log(teleportBtn.google)
            if (teleportBtn.google && GooglePlayer != null)
            {
                let heading = GooglePlayer.getPov().heading;
                let place = FindPointAtDistanceFrom(curPosition.lat, curPosition.lng , DegreesToRadians(heading), teleportBtn.distance * 0.001)
                svService.getPanorama({ location: place, radius: 1000, source: teleportBtn.teleType}, svCheck);
            }
        }
    });

    var teleportMoreBtn = document.createElement("Button");
    teleportMoreBtn.classList.add("unity-btn");
    teleportMoreBtn.id = "plus"
    teleportMoreBtn.innerHTML = "+";
    teleportMoreBtn.style =
        "visibility:hidden;width:2em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(teleportMoreBtn);
    teleportMoreBtn.addEventListener("click", () => {
        if (teleportBtn.distance > 21 && teleportBtn.distance < 149) {
            teleportBtn.distance = teleportBtn.distance + 25;
        }
        teleportBtn.innerHTML = "Teleport " + teleportBtn.distance + " m";
    });

    var teleportLessBtn = document.createElement("Button");
    teleportLessBtn.classList.add("unity-btn");
    teleportLessBtn.id = "minus"
    teleportLessBtn.innerHTML = "-";
    teleportLessBtn.style =
        "visibility:hidden;width:2em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(teleportLessBtn);
    teleportLessBtn.addEventListener("click", () => {
        if (teleportBtn.distance > 26) {
            teleportBtn.distance = teleportBtn.distance - 25;
        }
        teleportBtn.innerHTML = "Teleport " + teleportBtn.distance + " m";
    });

    var teleportDistResetBtn = document.createElement("Button");
    teleportDistResetBtn.classList.add("unity-btn");
    teleportDistResetBtn.id = "reset"
    teleportDistResetBtn.innerHTML = "Reset Distance";
    teleportDistResetBtn.style =
        "visibility:hidden;width:9em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(teleportDistResetBtn);
    teleportDistResetBtn.addEventListener("click", () => {
        teleportBtn.distance = 100;
        teleportBtn.innerHTML = "Teleport " + teleportBtn.distance + " m";
    });

    var switchCovergeButton = document.createElement("Button");
    switchCovergeButton.classList.add("unity-btn");
    switchCovergeButton.id = "switch";
    switchCovergeButton.init = false;
    switchCovergeButton.nextPlayer = "Google";
    switchCovergeButton.useGoogle = false;
    switchCovergeButton.lng = 0
    switchCovergeButton.lat = 0
    switchCovergeButton.heading = 0
    switchCovergeButton.innerHTML = "Switch Coverage";
    switchCovergeButton.small_canvas = false;
    switchCovergeButton.style =
        "visibility:hidden;width:8.5em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(switchCovergeButton);
    switchCovergeButton.addEventListener("click", () => {
        let GOOGLE_MAPS_CANVAS1 = document.querySelector(".game-layout__panorama-canvas");
        let GOOGLE_MAPS_CANVAS2 = document.querySelector(".br-game-layout__panorama-canvas");
        let GOOGLE_MAPS_CANVAS3 = document.querySelector(".inactive");
        let GOOGLE_MAPS_CANVAS4 = document.querySelector(".game-panorama_panoramaCanvas__r_5ea");
        let duel = false;

        let GOOGLE_MAPS_CANVAS = null;
        if (GOOGLE_MAPS_CANVAS1 !== null)
        {
            GOOGLE_MAPS_CANVAS = GOOGLE_MAPS_CANVAS1;
        }
        else if (GOOGLE_MAPS_CANVAS2 !== null)
        {
            GOOGLE_MAPS_CANVAS = GOOGLE_MAPS_CANVAS2;
        }
        else if (GOOGLE_MAPS_CANVAS4 !== null)
        {
            GOOGLE_MAPS_CANVAS = GOOGLE_MAPS_CANVAS4;
        }
        if (GOOGLE_MAPS_CANVAS3 !== null)
        {
            duel = true;
        }

        let KAKAO_MAPS_CANVAS = document.getElementById("roadview");
        let YANDEX_MAPS_CANVAS = document.querySelector(".ymaps-2-1-79-panorama-screen");
        let MAPILLARY_MAPS_CANVAS = document.getElementById("mapillary-player")
        let BAIDU_MAPS_CANVAS = document.getElementById("i_container");
        let MS_MAPS_CANVAS = document.getElementById("ms-player");
        //         if (switchCovergeButton.nextPlayer !== "Baidu") {
        if (switchCovergeButton.useGoogle == false) {
            if (duel)
            {
                document.getElementById("default_player").className = "game-panorama_panoramaCanvas__PNKve";
                if (switchCovergeButton.nextPlayer == "Kakao")
                {
                    KAKAO_MAPS_CANVAS.className = "inactive";
                }
                else if (switchCovergeButton.nextPlayer == "MS Satellite" || switchCovergeButton.nextPlayer == "MS Streetside")
                {
                    MS_MAPS_CANVAS.className = "inactive";
                }
                else
                {
                    MAPILLARY_MAPS_CANVAS.className = "inactive";
                    MAPILLARY_MAPS_CANVAS.style.visibility = "hidden";
                }
            }
            else
            {
                GOOGLE_MAPS_CANVAS.style.visibility = "";
                if (switchCovergeButton.nextPlayer == "Kakao")
                {
                    KAKAO_MAPS_CANVAS.style.visibility = "hidden";
                }
                else if (switchCovergeButton.nextPlayer == "Yandex")
                {
                    YANDEX_MAPS_CANVAS.style.visibility = "hidden";
                }
                else if (switchCovergeButton.nextPlayer == "Baidu")
                {
                    BAIDU_MAPS_CANVAS.style.visibility = "hidden";
                }
                else if (switchCovergeButton.nextPlayer == "Mapillary" || switchCovergeButton.nextPlayer == "Google")
                {
                    MAPILLARY_MAPS_CANVAS.style.visibility = "hidden";
                }
                else if (switchCovergeButton.nextPlayer == "MS Satellite" || switchCovergeButton.nextPlayer == "MS Streetside")
                {
                    MS_MAPS_CANVAS.style.visibility = "hidden";
                }

            }
            const lat = GooglePlayer.getPosition().lat();
            const lng = GooglePlayer.getPosition().lng();
            switch_call = true;
            if (!almostEqual2(lat, switchCovergeButton.lat) || !almostEqual2(lat, switchCovergeButton.lng)) {
                svService.getPanorama({ location: { lat: switchCovergeButton.lat, lng: switchCovergeButton.lng }, radius: 1000 }, svCheck);
            }
            switchCovergeButton.useGoogle = true;
            teleportBtn.google = true;
            switchCovergeButton.init = false;
            console.log("use Google");
        }
        else {
            if (duel)
            {
                document.getElementById("default_player").className = "inactive";
                if (switchCovergeButton.nextPlayer == "Kakao")
                {
                    KAKAO_MAPS_CANVAS.className = "game-panorama_panoramaCanvas__PNKve";
                }
                else if (switchCovergeButton.nextPlayer == "MS Satellite" || switchCovergeButton.nextPlayer == "MS Streetside")
                {
                    MS_MAPS_CANVAS.className = "game-panorama_panoramaCanvas__PNKve";
                }
                else
                {
                    MAPILLARY_MAPS_CANVAS.className = "game-panorama_panoramaCanvas__PNKve";
                    MAPILLARY_MAPS_CANVAS.style.visibility = "";
                    MapillaryPlayer.resize();
                    //window.dispatchEvent(new Event('resize'));
                    // document.querySelector(".mapillary-canvas").style.;
                    // mapillary-canvas
                }

            }
            else
            {
                GOOGLE_MAPS_CANVAS.style.visibility = "hidden";
                if (switchCovergeButton.nextPlayer == "Kakao")
                {
                    KAKAO_MAPS_CANVAS.style.visibility = "";
                }
                else if (switchCovergeButton.nextPlayer == "Yandex")
                {
                    YANDEX_MAPS_CANVAS.style.visibility = "";
                }
                else if (switchCovergeButton.nextPlayer == "Baidu")
                {
                    BAIDU_MAPS_CANVAS.style.visibility = "";
                }
                else if (switchCovergeButton.nextPlayer == "Mapillary" || switchCovergeButton.nextPlayer == "Google" )
                {
                    MAPILLARY_MAPS_CANVAS.style.visibility = "";
                }
                else if (switchCovergeButton.nextPlayer == "MS Satellite" || switchCovergeButton.nextPlayer == "MS Streetside")
                {
                    MS_MAPS_CANVAS.style.visibility = "";
                }
            }
            switchCovergeButton.useGoogle = false;
            teleportBtn.google = false;
            switchCovergeButton.init = true;
            console.log("use Others");
        }
        //         }
        //         else {
        //             switchCovergeButton.useGoogle = false;
        //             teleportBtn.google = false;
        //             console.log("use Others");
        //         }

    });

    var timeMachineNewerBtn = document.createElement("Button");
    timeMachineNewerBtn.classList.add("unity-btn");
    timeMachineNewerBtn.id = "plus year"
    timeMachineNewerBtn.innerHTML = "+";
    timeMachineNewerBtn.style =
        "visibility:hidden;width:2em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(timeMachineNewerBtn);
    timeMachineNewerBtn.addEventListener("click", () => {
        if (timeMachineBtn.index < timeMachineBtn.list.length - 1 && !timeMachineBtn.plusminusLock) {
            timeMachineBtn.index = timeMachineBtn.index + 1;
            GooglePlayer.setPano(timeMachineBtn.list[timeMachineBtn.index][0]);
            timeMachineBtn.innerHTML = "<font size=2>[" + (timeMachineBtn.index + 1) + "] " + timeMachineBtn.list[timeMachineBtn.index][1] + "</font>";
            // console.log(timeMachineBtn.index)
        }
        GenBtnColor();

    });

    var timeMachineOlderBtn = document.createElement("Button");
    timeMachineOlderBtn.classList.add("unity-btn");
    timeMachineOlderBtn.id = "minus year"
    timeMachineOlderBtn.innerHTML = "-";
    timeMachineOlderBtn.style =
        "visibility:hidden;width:2em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(timeMachineOlderBtn);
    timeMachineOlderBtn.addEventListener("click", () => {
        if (timeMachineBtn.index > 0 && !timeMachineBtn.plusminusLock) {
            timeMachineBtn.index = timeMachineBtn.index - 1;
            GooglePlayer.setPano(timeMachineBtn.list[timeMachineBtn.index][0]);
            timeMachineBtn.innerHTML = "<font size=2>[" + (timeMachineBtn.index + 1) + "] " + timeMachineBtn.list[timeMachineBtn.index][1] + "</font>";
            // console.log(timeMachineBtn.index)
        }
        GenBtnColor();
    });

    function svCheck2(data, status) {
        let l = []
        if (status === 'OK') {
            // console.log("OK for " + data.location.latLng + " at ID " + data.location.pano);
            // console.log(data.time)
            for (const alt of data.time) {
                let date = Object.values(alt).find((value) => value instanceof Date)

                l.push([alt.pano, date.toDateString()]);
            }
            // console.log(l);
            timeMachineBtn.list = l
            timeMachineBtn.index = l.length - 1;
            timeMachineBtn.innerHTML = "<font size=2>[" + (timeMachineBtn.index + 1) + "] " + timeMachineBtn.list[timeMachineBtn.index][1] + "</font>";
            GenBtnColor();
            timeMachineBtn.plusminusLock = false;
            // timeMachineOlderBtn.click()
            // timeMachineBtn.innerHTML = "Default Date";
        }
    }

    var timeMachineBtn = document.createElement("Button");
    timeMachineBtn.classList.add("unity-btn");
    timeMachineBtn.id = "Date Button";
    timeMachineBtn.plusminusLock = true;
    timeMachineBtn.panoId = 0;
    timeMachineBtn.index = -1;
    timeMachineBtn.list = [];
    timeMachineBtn.innerHTML = "Time Machine";
    timeMachineBtn.style =
        "visibility:hidden;width:10em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(timeMachineBtn);
    timeMachineBtn.addEventListener("click", () => {
        // console.log(timeMachineBtn.index)
        if (timeMachineBtn.panoId != 0)
        {
            if(timeMachineBtn.index == -1)
            {
                svService.getPanorama({pano: timeMachineBtn.panoId}, svCheck2);
            }
            else
            {
                timeMachineBtn.index = timeMachineBtn.list.length - 1;
                GooglePlayer.setPano(timeMachineBtn.list[timeMachineBtn.index][0]);
                timeMachineBtn.innerHTML = "<font size=2>[" + (timeMachineBtn.index + 1) + "] " + timeMachineBtn.list[timeMachineBtn.index][1] + "</font>";
                GenBtnColor();
            }
        }
        else
        {
            timeMachineBtn.panoId = GooglePlayer.pano;
            svService.getPanorama({pano: timeMachineBtn.panoId}, svCheck2);
        }
    });

    // Battle Royale UI optimization

    let hide = true;

    var MinimapBtn = document.createElement("Button");
    MinimapBtn.classList.add("unity-btn");
    MinimapBtn.id = "Minimap Button";
    MinimapBtn.innerHTML = "Minimap Style";
    MinimapBtn.current = "Default";
    MinimapBtn.childVisible = false;
    MinimapBtn.style =
        "visibility:hidden;width:7.25em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(MinimapBtn);
    MinimapBtn.addEventListener("click", () => {
        if (MinimapBtn.childVisible)
        {
            for (let element of document.getElementsByClassName("preset-minimap")){
                element.style.visibility="hidden";
            }
            MinimapBtn.childVisible = false;
        }
        else
        {
            for (let element of document.getElementsByClassName("preset-minimap")){
                element.style.visibility="";
            }
            MinimapBtn.childVisible = true;
        }

    });


    let HeightCount = 0
    for (let a of presetMinimap)
    {
        let aButton = document.createElement("Button");
        aButton.id = a[1];
        aButton.classList.add("preset-minimap");
        aButton.classList.add("unity-btn");
        aButton.innerHTML = a[1];
        aButton.style =
            "visibility:hidden;width:7.25em;height:1.5em;position:absolute;z-index:99999;background-color: #ff69b4;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
        document.body.appendChild(aButton);
        HeightCount++;
    }

    var OverlayBtn = document.createElement("Button");
    OverlayBtn.classList.add("unity-btn");
    OverlayBtn.id = "Overlay Button";
    OverlayBtn.innerHTML = "Overlay";
    OverlayBtn.current = "Clear";
    OverlayBtn.childVisible = false;
    OverlayBtn.style =
        "visibility:hidden;width:7.25em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(OverlayBtn);

    OverlayBtn.addEventListener("click", () => {
        if (OverlayBtn.childVisible)
        {
            for (let element of document.getElementsByClassName("overlay-minimap")){
                element.style.visibility = "hidden";
            }
            OverlayBtn.childVisible = false;
        }
        else
        {
            for (let element of document.getElementsByClassName("overlay-minimap")){
                element.style.visibility = "";
            }
            OverlayBtn.childVisible = true;
        }

    });

    let HeightCount2 = 0
    for (let b of presetOverlay)
    {
        let bButton = document.createElement("Button");
        bButton.id = b[0];
        bButton.url = b[1];
        bButton.loaded = false;
        bButton.classList.add("overlay-minimap");
        bButton.classList.add("unity-btn");
        bButton.innerHTML = b[0];
        bButton.style =
            "visibility:hidden;width:7.25em;height:1.5em;position:absolute;z-index:99999;background-color: #ff69b4;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
        if (bButton.id == "Clear")
        {
            bButton.loaded = true;
            bButton.style.background = "#ff1493";
        }
        document.body.appendChild(bButton);
        HeightCount2++;
    }

    var HelpBtn = document.createElement("Button");
    HelpBtn.classList.add("unity-btn");
    HelpBtn.id = "Help Button";
    HelpBtn.innerHTML = "Script Help";
    HelpBtn.style =
        "visibility:hidden;width:6em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(HelpBtn);
    HelpBtn.addEventListener("click", () => {
        window.open('https://docs.google.com/document/d/18nLXSQQLOzl4WpUgZkM-mxhhQLY6P3FKonQGp-H0fqI/edit?usp=sharing');
    });

    var TeleportArisBtn = document.createElement("Button");
    TeleportArisBtn.classList.add("unity-btn");
    TeleportArisBtn.id = "Teleport Options Button";
    TeleportArisBtn.innerHTML = "Default";
    TeleportArisBtn.style =
        "visibility:hidden;width:5.5em;height:2em;position:absolute;z-index:99999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(TeleportArisBtn);
    TeleportArisBtn.addEventListener("click", () => {
        if (teleportBtn.teleType == "default")
        {
            teleportBtn.teleType = "outdoor"
            TeleportArisBtn.innerHTML = "Official";
        }
        else
        {
            teleportBtn.teleType = "default"
            TeleportArisBtn.innerHTML = "Default";
        }
    });

    var playYoutubeBtn = document.createElement("Button");
    playYoutubeBtn.classList.add("unity-btn");
    playYoutubeBtn.id = "Youtube Button";
    playYoutubeBtn.innerHTML = "Play video";
    playYoutubeBtn.style =
        "visibility:hidden;width:6em;height:4.5em;position:absolute;z-index:999999;background-color: #BF40BF;border: none;color: white;padding: none;text-align: center;vertical-align: text-top;text-decoration: none;display: inline-block;font-size: 16px;";
    document.body.appendChild(playYoutubeBtn);
    playYoutubeBtn.addEventListener("click", () => {
        let iframe = document.getElementById("i_container");
        iframe.style.position = "absolute";
        iframe.allow = "autoplay";
        let srcString = "https://www.youtube.com/embed/" + yId + "?&playlist=" + yId + "&autoplay=1&modestbranding=1&controls=0&start=";
        if (yTime == "0" && yEnd == "0")
        {
        }
        else
        {
            srcString += yTime + "&end=" + yEnd;
        }
        iframe.src = srcString;
        iframe.style.visibility = "";
        playYoutubeBtn.innerHTML = "Play video from start";
    });


    console.log("Buttons Loaded");
}

function GenBtnColor()
{
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    if (timeMachineBtn.index == timeMachineBtn.list.length - 1)
    {
        timeMachineNewerBtn.style.backgroundColor = "red";
        timeMachineNewerBtn.disabled = true;
    }
    else
    {
        timeMachineNewerBtn.style.backgroundColor = "#BF40BF";
        timeMachineNewerBtn.disabled = false;
    }
    if (timeMachineBtn.index == 0)
    {
        timeMachineOlderBtn.style.backgroundColor = "red";
        timeMachineOlderBtn.disabled = true;
    }
    else
    {
        timeMachineOlderBtn.style.backgroundColor = "#BF40BF";
        timeMachineOlderBtn.disabled = false;
    }
}

/**
 * Handle Keyboard inputs
 */

function kBoard()
{
    document.addEventListener('keydown', logKey);
}

function logKey(e) {
    // console.log(e.code);
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    if (e.code == "Space")
    {
        setHidden(true);
    }
    if (e.code == "Digit3")
    {
        teleportBtn.click();
    }
    else if (e.code == "Digit4")
    {
        timeMachineOlderBtn.click();
    }
    else if (e.code == "Digit5")
    {
        timeMachineBtn.click();
    }
    else if (e.code == "Digit6")
    {
        timeMachineNewerBtn.click();
    }
    else if (e.code == "Digit7")
    {
        if (mainMenuBtn.style.visibility == "hidden")
        {
            mainMenuBtn.style.visibility = "";
        }
        else
        {
            mainMenuBtn.style.visibility = "hidden";
        }
    }
}


/**
 * Hide or reveal the buttons, and disable buttons if such feature is not available
 */

function setHidden(cond)
{
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    if (cond)
    {
        if (mainMenuBtn != null)
        {
            if (teleportBtn != null)
            {
                for (let element of document.getElementsByClassName("unity-btn")){
                    element.style.visibility = "hidden";
                }
            }
            let iframe = document.getElementById("i_container");
            if (iframe != null)
            {
                if (!isBattleRoyale)
                {
                    iframe.src = ""
                }
                else
                {
                    // TODO
                }
            }
        }
    }
    else
    {
        if (mainMenuBtn != null)
        {
            mainMenuBtn.style.visibility = "";
        }
    }
}

function setDisable(cond) {
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    if (teleportBtn != null) {
        if (cond == "NMPZ") {
            teleportMoreBtn.style.backgroundColor = "red";
            teleportMoreBtn.disabled = true;
            teleportLessBtn.style.backgroundColor = "red";
            teleportLessBtn.disabled = true;
            teleportDistResetBtn.style.backgroundColor = "red";
            teleportDistResetBtn.disabled = true;
            if (nextPlayer == "Kakao")
            {
                switchCovergeButton.style.backgroundColor = "#BF40BF";
                switchCovergeButton.disabled = false;
            }
            else
            {
                switchCovergeButton.style.backgroundColor = "red";
                switchCovergeButton.disabled = true;
            }
            teleportBtn.disabled = true;
            teleportBtn.style.backgroundColor = "red";
            TeleportArisBtn.style.backgroundColor = "red";
            TeleportArisBtn.disabled = true;
            timeMachineBtn.style.backgroundColor = "#BF40BF";
            timeMachineBtn.disabled = false;
        }
        else if (cond == "Google") {
            teleportMoreBtn.style.backgroundColor = "#BF40BF";
            teleportMoreBtn.disabled = false;
            teleportLessBtn.style.backgroundColor = "#BF40BF";
            teleportLessBtn.disabled = false;
            teleportDistResetBtn.style.backgroundColor = "#BF40BF";
            teleportDistResetBtn.disabled = false;
            switchCovergeButton.style.backgroundColor = "#BF40BF";
            switchCovergeButton.disabled = false;
            teleportBtn.disabled = false;
            teleportBtn.style.backgroundColor = "#BF40BF";
            TeleportArisBtn.disabled = false;
            TeleportArisBtn.style.backgroundColor = "#BF40BF";
            timeMachineBtn.style.backgroundColor = "#BF40BF";
            timeMachineBtn.disabled = false;
        }
        else if (nextPlayer === "Baidu" || nextPlayer === "Youtube" || nextPlayer === "Image") {
            teleportMoreBtn.style.backgroundColor = "red";
            teleportMoreBtn.disabled = true;
            teleportLessBtn.style.backgroundColor = "red";
            teleportLessBtn.disabled = true;
            teleportDistResetBtn.style.backgroundColor = "red";
            teleportDistResetBtn.disabled = true;
            switchCovergeButton.style.backgroundColor = "#BF40BF";
            switchCovergeButton.disabled = false;
            teleportBtn.disabled = true;
            teleportBtn.style.backgroundColor = "red";
            TeleportArisBtn.style.backgroundColor = "red";
            TeleportArisBtn.disabled = true;
            timeMachineBtn.style.backgroundColor = "red";
            timeMachineBtn.disabled = true;
        }
        else if (cond == "Kakao" || cond == "Yandex" || cond == "Mapillary" || cond == "MS Streetside") {
            teleportMoreBtn.style.backgroundColor = "#BF40BF";
            teleportMoreBtn.disabled = false;
            teleportLessBtn.style.backgroundColor = "#BF40BF";
            teleportLessBtn.disabled = false;
            teleportDistResetBtn.style.backgroundColor = "#BF40BF";
            teleportDistResetBtn.disabled = false;
            switchCovergeButton.style.backgroundColor = "#BF40BF";
            switchCovergeButton.disabled = false;
            teleportBtn.disabled = false;
            teleportBtn.style.backgroundColor = "#BF40BF";
            TeleportArisBtn.disabled = false;
            TeleportArisBtn.style.backgroundColor = "#BF40BF";
            timeMachineBtn.style.backgroundColor = "red";
            timeMachineBtn.disabled = true;
        }
        else if (cond == "MS Satellite") {
            teleportMoreBtn.style.backgroundColor = "red";
            teleportMoreBtn.disabled = true;
            teleportLessBtn.style.backgroundColor = "red";
            teleportLessBtn.disabled = true;
            teleportDistResetBtn.style.backgroundColor = "red";
            teleportDistResetBtn.disabled = true;
            switchCovergeButton.style.backgroundColor = "red";
            switchCovergeButton.disabled = true;
            teleportBtn.disabled = true;
            teleportBtn.style.backgroundColor = "red";
            TeleportArisBtn.style.backgroundColor = "red";
            TeleportArisBtn.disabled = true;
            timeMachineBtn.style.backgroundColor = "red";
            timeMachineBtn.disabled = true;
        }
        timeMachineNewerBtn.style.backgroundColor = "red";
        timeMachineNewerBtn.disabled = true;
        timeMachineOlderBtn.style.backgroundColor = "red";
        timeMachineOlderBtn.disabled = true;
    }
}


/**
 * This observer stays alive while the script is running
 */

function launchObserver() {
    UnityInitiate();
    BYKTeleport();
    SyncListener();
    kBoard();
    console.log("Main Observer");
    const OBSERVER = new MutationObserver((mutations, observer) => {
        observeMapChange();
        detectGamePage();
        let nav = document.getElementById('MicrosoftNav');
        if (nav)
        {
            nav.style.visibility = "hidden";
        }
    });
    observerCallback(OBSERVER)
}
function observerCallback(obs)
{
    if (obs)
    {
        obs.observe(document.head, { attributes: true, childList: true, subtree: true });
    }
    else
    {
        setTimeout(observerCallback, 250);
    }
}

/**
 * Once the Google Maps API was loaded we can do more stuff
 */

window.addEventListener('DOMContentLoaded', (event) => {
    injecter(() => {
        launchObserver();
    })
});

const base62 = {
    charset: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    .split(''),
    encode: integer => {
        if (integer === 0) {
            return 0;
        }
        let s = [];
        while (integer > 0) {
            s = [base62.charset[integer % 62], ...s];
            integer = Math.floor(integer / 62);
        }
        return s.join('');
    },
    decode: chars => chars.split('').reverse().reduce((prev, curr, i) =>
                                                      prev + (base62.charset.indexOf(curr) * (62 ** i)), 0)
};


/**
 * Check whether the current page is a game, if so which game mode
 */

function detectGamePage() {
    if (document.querySelector(".game-layout__panorama-message") !== null && !one_reset)
    {
        one_reset = true;
        console.log("Hide fail to load panorama canvas");
        document.querySelector(".game-layout__panorama-message").style.visibility = "hidden";
    }
    function loadModule()
    {
        if (toLoad) {
            initializeCanvas();
        }
        waitLoad();
    }
    let toLoad = !playerLoaded && !YandexPlayer && !KakaoPlayer && !MapillaryPlayer && !MSStreetPlayer && !YANDEX_INJECTED && !KAKAO_INJECTED && !MAPILLARY_INJECTED && !MS_INJECTED
    const PATHNAME = window.location.pathname;
    if (PATHNAME.startsWith("/game/") || PATHNAME.startsWith("/challenge/")) {
        // console.log("Game page");
        isBattleRoyale = false;
        isDuel = false;
        loadModule();
    }
    else if (PATHNAME.startsWith("/battle-royale/")) {
        if (document.querySelector(".br-game-layout") == null) {
            // console.log("Battle Royale Lobby");
            rstValues();
        }
        else {
            // console.log("Battle Royale");
            isBattleRoyale = true;
            isDuel = false;
            loadModule();
        }
    }
    else if (PATHNAME.startsWith("/duels/") || PATHNAME.startsWith("/team-duels/")) {
        if (document.querySelector(".game_layout__TO_jf") == null) {
            // console.log("Battle Royale Lobby");
            rstValues();
        }
        else {
            // console.log("Duels");
            isBattleRoyale = true;
            isDuel = true;
            loadModule();
        }
    }
    else if (PATHNAME.startsWith("/bullseye/")) {
        if (document.querySelector(".game_layout__0vAWj") == null) {
            // console.log("Battle Royale Lobby");
            rstValues();
        }
        else {
//             console.log("bullseye");
            isBattleRoyale = true;
            isBullseye = true;
            loadModule();
        }
    }
    else {
        rstValues();
        //console.log("Not a Game page");
    }
}

function rstValues()
{
    ROUND = 0;
    YandexPlayer = null;
    KakaoPlayer = null;
    MapillaryPlayer = null;
    MSStreetPlayer = null;

    BAIDU_INJECTED = false;
    YANDEX_INJECTED = false;
    KAKAO_INJECTED = false;
    MAPILLARY_INJECTED = false;
    MS_INJECTED = false;

    nextPlayer = "Google"
    global_lat = 0;
    global_lng = 0;
    global_panoID = null;
    global_BDAh = null;
    global_BDBh = null;
    global_BDID = null;
    yId = null;
    yTime = null;
    yEnd = null;
    iId = null;

    COMPASS = null;
    eventListenerAttached = false;
    povListenerAttached = false;
    playerLoaded = false;
    locHistory = [];
    one_reset = false;
    setHidden(true);
    yandex_map = false;
    Kakao_map = false;
    mmKey = 0;
    CURRENT_ROUND_DATA = null;
    ms_radius = 10000;

    BR_LOAD_KAKAO = false;
    BR_LOAD_YANDEX = false;
    BR_LOAD_MS = false;

    ms_sat_map = false;

    linksList = [];
}

/**
 * Wait for various players to load
 */

function waitLoad() {
    if (!YandexPlayer || !KakaoPlayer || !MapillaryPlayer || !MSStreetPlayer || !YANDEX_INJECTED || !KAKAO_INJECTED || !MAPILLARY_INJECTED || !MS_INJECTED) {
        let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
        if (document.querySelector(".br-game-layout__panorama-canvas") != null)
        {
            AdjustBtnPos("-6em + 2px", "300px");
        }
        else if (document.querySelector(".game-panorama_panorama__rdhFg") != null)
        {
            AdjustBtnPos("2em", "0em");
        }
        else if (document.querySelector(".game-panorama_panorama__ncMwh") != null)
        {
            AdjustBtnPos("1em", "18.5em");
        }
        else
        {
            AdjustBtnPos("0em", "0em");
        }
        setTimeout(waitLoad, 250);
    } else {
        checkRound();
    }
}

/**
 * Checks for round changes
 */

function checkRound() {
    //   console.log("Check Round");
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();

    if (!isBattleRoyale) {
        // console.log("Check Round");
        let currentRound = getRoundFromPage();
        if (ROUND != currentRound) {
            fire1 = true;
            switchCovergeButton.init = true;
            console.log("New round");
            ROUND = currentRound;
            // NEW_ROUND_LOADED = true;
            COMPASS = null;
            locHistory = [];
            one_reset = false;
            getMapData();
            nextButtonCallback();
        }
    }
    else {
        getMapData();
    }
}

/**
 * Add listeners if buttons have been created
 */

function finalDetail()
{
    let target = document.querySelector("a[data-qa='play-same-map']");
    if (target)
    {
        var div = document.createElement("div");
        div.classList.add("buttons_buttons__0B3SB")
        document.querySelector('.result-layout_content__jAHfP').appendChild(div);
        for (var rd of linksList)
        {
            console.log(rd)
            let cl = target.cloneNode( true );
            let tx = "View R" + rd[0] + " in " + rd[1];
            cl.querySelector('.button_label__kpJrA').innerHTML = tx;
            cl.removeAttribute('data-qa');
            cl.removeAttribute('href');
            cl.urlStr = rd[2];
            cl.addEventListener("click", (e) => {
                window.open(cl.urlStr);
            })
            cl.style = "top:10px;right:-10px;";
            div.appendChild(cl);
        }
    }
    else
    {
        setTimeout(finalDetail, 500);
    }
}

function nextButtonCallback()
{
    let nextButton = document.querySelector("button[data-qa='close-round-result']");
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    if (nextButton != null && fire1)
    {
        fire1 = false;
        nextButton.addEventListener("click", (e) => {
            if (mainMenuBtn != null && !cn_tips && ROUND !== 5)
            {
                // console.log("try to show show buttons")
                mainMenuBtn.style.visibility = "";
            }
            if (ROUND == 5)
            {
                console.log("Game Finished")
                if (linksList)
                {
                    finalDetail();
                }
            }
        })
        let urlStr = ""

        if (nextPlayer !== "Google")
        {
            console.log("Clone buttons");
            let clone = document.querySelector("button[data-qa='close-round-result']").cloneNode( true );
            let tx = "View Location in " + nextPlayer;
            clone.querySelector('.button_label__kpJrA').innerHTML = tx;
            clone.setAttribute('id', "LinkBtn");
            clone.removeAttribute('data-qa');
            if (nextPlayer == "Baidu")
            {
                urlStr = "https://map.baidu.com/?panotype=street&pid=" + global_BDID + "&panoid=" + global_BDID + "&from=api";
            }
            else if (nextPlayer == "Youtube")
            {
                urlStr = "https://www.youtube.com/watch?v=" + yId;
            }
            else if (nextPlayer == "Image")
            {
                urlStr = iId;
            }
            else if (nextPlayer == "Kakao")
            {
                urlStr = "https://map.kakao.com/link/roadview/" + global_lat + "," + global_lng;
            }
            else if (nextPlayer == "Mapillary")
            {
                urlStr = "https://www.mapillary.com/app/?pKey=" + mmKey + "&focus=photo";
            }
            else if (nextPlayer == "Yandex")
            {
                urlStr = "https://yandex.com/maps/?&panorama%5Bdirection%5D=16%2C0&panorama%5Bpoint%5D=" + global_lng + "%2C" + global_lat;
            }
            else if (nextPlayer == "MS Satellite" || nextPlayer == "MS Streetside")
            {
                urlStr = "https://bing.com/maps/default.aspx?cp=" + global_lat + "~" + global_lng + "&lvl=20&style=r";
            }
            clone.addEventListener("click", (e) => {
                window.open(urlStr);
            })
            if (ROUND == 5)
            {
                clone.style = "top:10px;";
            }
            else
            {
                clone.style = "right:-10px;";
            }
            linksList.push([ROUND, nextPlayer, urlStr]);
            document.querySelector('.round-result_actions__5j26U').appendChild(clone);
        }
    }
    else
    {
        setTimeout(nextButtonCallback, 500);
    }
}

function guessButtonCallback()
{
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let guessButton = document.querySelector("button[data-qa='perform-guess']");
    if (guessButton != null)
    {

        guessButton.addEventListener("click", (e) => {
            if (mainMenuBtn != null)
            {
                console.log("try to hide show buttons")
                mainMenuBtn.style.visibility = "hidden";
                setHidden(true);
            }
        })
    }
    else
    {
        setTimeout(guessButtonCallback, 500);
    }
}

/**
 * Load different streetview players
 */

function injectYandex()
{
    injectYandexScript().then(() => {
        console.log("Ready to inject Yandex player");
        injectYandexPlayer();
    }).catch((error) => {
        console.log(error);
    });
}

function loaderChecker(data)
{
//     console.log(data);
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    if (data.includes("A United World") || data.includes("A Unity World") || data.includes("Unity Test"))
    {
        console.log("Complete Map");
        data = "Yandex Bing Streetside Kakao";
    }

    if (data.includes("Yandex"))
    {
        console.log("Yandex Map");
        yandex_map = true;
        injectYandex();
        BR_LOAD_YANDEX = true;
    }
    else
    {
        console.log("Not Yandex map");
        YANDEX_INJECTED = true;
        YandexPlayer = "YD";
    }

    if (data.includes("Bing Streetside"))
    {
        console.log("Bing Streetside Map");
        injectMSPlayer();
        BR_LOAD_MS = true;
    }
    else if (data.includes("Bing Satellite"))
    {
        ms_sat_map = true;
        console.log("Bing Satellite Map");
        let tempRad = data.split("Bing Satellite")[1];
        ms_radius = parseInt(tempRad.replace(/\D/g,'')) * 1000;
        injectMSPlayer();
        BR_LOAD_MS = true;
    }
    else
    {
        console.log("Not Bing map");
        MS_INJECTED = true;
        MSStreetPlayer = "MS";
    }

    if (data.includes("Kakao"))
    {
        console.log("Kakao Map");
        Kakao_map = true;
        injectKakaoScript().then(() => {
            console.log("Ready to inject Kakao player");
        }).catch((error) => {
            console.log(error);
        });
        BR_LOAD_KAKAO = true;
    }
    else{
        KAKAO_INJECTED = true;
        KakaoPlayer = "KK";
        console.log("Not Kakao map");
    }

    if (!data.includes("China Tips for each province"))
    {
        cn_tips = false;
        mainMenuBtn.style.visibility = "";
        setHidden(false);
    }
    else
    {
        cn_tips = true;
        guaranteeUI();
    }

}

function loadPlayers() {
    playerLoaded = true;
    injectContainer();
    getSeed().then((data) => {
        if (!isBattleRoyale)
        {
            loaderChecker(data.mapName);
        }
        else
        {
            let dat;
            let rtd = false;
            if (typeof data.isRated !== 'undefined')
            {
                rtd = data.isRated;
            }
            if (data.isRated)
            {
                dat = "Public Game";
            }
            else
            {
                if (typeof sessionStorage['mapName'] !== 'undefined')
                {
                    dat = sessionStorage.getItem('mapName');
                }
                else
                {
                    dat = "A United World";
                }
            }
            loaderChecker(dat);
        }

    }).catch((error) => {
        console.log(error);
    });

}

function guaranteeUI()
{
    // console.log("UI")
    if (document.getElementById("GH-ui") !== null)
    {
        document.getElementById("GH-ui").style.display = "block";
    }
    else
    {
        setTimeout(guaranteeUI, 500);
    }
}

/**
 * Handles Return to start and undo
 */

function handleReturnToStart() {
    let rtsButton = document.querySelector("button[data-qa='return-to-start']");
    if (rtsButton != null) {
        console.log("handleReturnToStart listener attached");
        rtsButton.addEventListener("click", (e) => {
            if (nextPlayer != "Baidu")
            {
                goToLocation();
            }
            else
            {
                document.getElementById("i_container").src = "https://map.baidu.com/?panotype=street&pid=" + global_BDID + "&panoid=" + global_BDID + "&from=api";
            }
            const elementClicked = e.target;
            elementClicked.setAttribute('listener', 'true');
            console.log("Return to start");
        });
        guessButtonCallback();
        setTimeout(function () {goToLocation();}, 1000);
    }
    else
    {
        setTimeout(handleReturnToStart, 500);
    }
}

function handleUndo() {
    let undoButton = document.querySelector("button[data-qa='undo-move']");
    if (undoButton != null)
    {
        console.log("Attach undo");
        undoButton.addEventListener("click", (e) => {
            if (locHistory.length > 0) {
                goToUndoMove();
                console.log("Undo Move");
            }
        })
    }
    else
    {
        setTimeout(handleUndo, 500);
    }
}

/**
 * Load game information
 */

function getMapData() {
    // myHighlight("Seed data");
    getSeed().then((data) => {
        // myHighlight("Seed data");
        // console.log(data);
        let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
        if (isBattleRoyale) {
            if (data.status == "Finished" || typeof data.gameId == typeof undefined) {
                // console.log("Battle Royale Lobby");
            }
            else
            {
                let origin = false;
                if (!CURRENT_ROUND_DATA) {
                    CURRENT_ROUND_DATA = data
                    origin = true;
                }

                if (origin || !(data.currentRoundNumber === CURRENT_ROUND_DATA.currentRoundNumber)) {
                    // myHighlight("Battle Royale New round");
                    switchCovergeButton.init = true;
                    // NEW_ROUND_LOADED = true;
                    COMPASS = null;
                    locHistory = [];
                    one_reset = false;
                    setHidden(false);
                    if (!origin) {
                        CURRENT_ROUND_DATA = data;
                    }
                    locationCheck(data);
                    // console.log(data);
                    if (data.currentRoundNumber == 1)
                    {
                        setTimeout(function () {goToLocation();}, 3000);
                    }
                    else
                    {
                        goToLocation();
                    }
                    handleReturnToStart();
                    if (isDuel)
                    {
                        handleUndo();
                        hideButtons();
                    }
                    handleMinimapCallback();

                }
            }
        }
        else {
            if (!cn_tips)
            {
                mainMenuBtn.style.visibility = "";
            }
            else
            {
                mainMenuBtn.style.visibility = "hidden";
                AdjustBtnPos("14em", "0em");
            }
            locationCheck(data);
            if (data.currentRoundNumber == 1)
            {
                setTimeout(function () {goToLocation();}, 3000);
            }
            else
            {
                goToLocation();
            }
            handleReturnToStart();
            handleUndo();
            hideButtons();
            handleMinimapCallback();
        }
    }).catch((error) => {
        console.log(error);
    });
}

function handleMinimapCallback()
{
    let trueCond = true;
    let timeoutTime = 250;
    if (isBattleRoyale) {
        if (isDuel)
        {
            if (document.querySelector(".overlay_overlay__AR02x"))
            {
                trueCond = false;
            }
            else
            {
                trueCond = true;
            }
        }
        else
        {
            if (document.querySelector(".popup__content"))
            {
                trueCond = false;
            }
            else
            {
                trueCond = true;
            }
        }
        timeoutTime = 2500;
    }

    if (trueCond)
    {
        let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
        let cur = MinimapBtn.current;
        console.log(cur)
        for (let mapDiv of document.getElementsByClassName("preset-minimap")){
            if (cur == mapDiv.id)
            {
                setTimeout(function () {mapDiv.click();}, 500);
                setTimeout(function () {mapDiv.click();}, 1000);
                setTimeout(function () {mapDiv.click();}, 3000);
            }
        }
    }
    else
    {
        setTimeout(handleMinimapCallback, 250);
    }
}

/**
 * Hide unnecessary buttons for non-Google coverages
 */

function hideButtons() {
    let CHECKPOINT = document.querySelector("button[data-qa='set-checkpoint']");
    let ZOOM_IN = document.querySelector("button[data-qa='pano-zoom-in']");
    let ZOOM_OUT = document.querySelector("button[data-qa='pano-zoom-out']");

    if (CHECKPOINT != null)
    {
        if (nextPlayer === "Google") {

            CHECKPOINT.style.visibility = "";
            ZOOM_IN.style.visibility = "";
            ZOOM_OUT.style.visibility = "";
            console.log("Buttons Unhidden");

        }
        else {

            CHECKPOINT.style.visibility = "hidden";
            ZOOM_IN.style.visibility = "hidden";
            ZOOM_OUT.style.visibility = "hidden";
            console.log("Buttons Hidden");

        }
    }
    else
    {
        setTimeout(hideButtons, 250);
    }
}

/**
 * Check which player to use for the next location
 */

function locationCheck(data) {
    // console.log(data);
    let round;
    if (isBattleRoyale) {
        if (isDuel || isBullseye)
        {
            round = data.rounds[data.currentRoundNumber - 1].panorama;
        }
        else
        {
            round = data.rounds[data.currentRoundNumber - 1];
        }
    }
    else {
        round = data.rounds[data.round - 1];
    }
    global_lat = round.lat;
    global_lng = round.lng;
    global_panoID = round.panoId;
    global_heading = round.heading;
    global_pitch = round.pitch;

    nextPlayer = "Google";

    if (ms_sat_map)
    {
        nextPlayer = "MS Satellite";
    }

    if (global_panoID) {
        let locInfo;
        if (isBullseye)
        {
            locInfo = global_panoID;
        }
        else
        {
            locInfo = hex2a(global_panoID);
        }
//         console.log(locInfo)
        if (locInfo.substring(0, 3) == "YTB")
        {
            nextPlayer = "Youtube";
            let lengths = [3, 11, 4, 4];
            let toPiece = lengths.map((p => i => locInfo.slice(p, p += i))(0));
            let fullID = locInfo.substring(3).split('START');
            yId = toPiece[1];
            yTime = Number(toPiece[2]);
            yEnd = Number(toPiece[3]);
        }
        else
        {
            let mapType = locInfo.substring(0, 5);

            // panoId unchanged

            if (mapType === "YDMAP" ) {
                nextPlayer = "Yandex";
            }
            else if (mapType === "KKMAP" ) {
                nextPlayer = "Kakao";
            }

            // New panoId formats

            else if (mapType === "BAIDU" ) {
                nextPlayer = "Baidu";
                let lengths = [5, 7, 7, 3];
                let toPiece = lengths.map((p => i => locInfo.slice(p, p += i))(0));
                let panoId1 = base62.decode(toPiece[1]).toString().substring(1);
                let panoId2 = base62.decode(toPiece[2]).toString().substring(1);
                global_BDID = panoId1 + panoId2 + toPiece[3]
            }
            else if (mapType === "MAPIL")
            {
                nextPlayer = "Mapillary";
                mmKey = locInfo.substring(5).replace(/\D/g,'');
            }
            else if (mapType === "IMAGE")
            {
                nextPlayer = "Image";
                let lengths = [5, 4, 4, 7, 2];
                let toPiece = lengths.map((p => i => locInfo.slice(p, p += i))(0));
                iId = "https://i.ibb.co/" + toPiece[3] + "/" + toPiece[1] + "." + toPiece[2].replace(/[^0-9a-z]/gi, '')
            }
            else if (mapType === "BINGM" ) {
                nextPlayer = "MS Streetside";
            }
            else if (mapType === "SATEL" ) {
                nextPlayer = "MS Satellite";
                ms_radius = parseInt(locInfo.substring(5).replace(/\D/g,'')) * 1000;
            }

            // legacy panoId formats support

            else if (mapType === "BDMAP") {
                nextPlayer = "Baidu";
                let coord = locInfo.substring(5);

                if(coord.includes('BDAh'))
                {
                    global_BDID = coord.split('BDAh')[0].replace("panoId","");
                    let tem = coord.split('BDAh')[1];
                    global_BDAh = tem.split('BDBh')[0];
                    global_BDBh = tem.split('BDBh')[1];
                }
                else
                {
                    global_BDID = coord.replace("panoId","");
                }
            }
            else if (mapType === "MLMAP") {
                nextPlayer = "Mapillary";
                mmKey = locInfo.substring(5);
            }
        }
    }
    else
    {
        if (Kakao_map)
        {
            nextPlayer = "Kakao";
        }
        else if (yandex_map)
        {
            nextPlayer = "Yandex";
        }
    }

    //     if ( krCoordinates[0] > global_lat && krCoordinates[2] < global_lat && krCoordinates[1] < global_lng && krCoordinates[3] > global_lng)
    //     {
    //         nextSecondaryPlayer = "Kakao";
    //     }
    //     else if (nextPlayer = "Mapillary")
    //     {
    //         nextSecondaryPlayer = "Google";
    //     }
    //     else
    //     {
    //         nextSecondaryPlayer = "Mapillary";
    //     }

    // Disable buttons if NM, NMPZ

    if(!isBattleRoyale)
    {
        if (data.forbidMoving || data.forbidRotating || data.forbidZooming)
        {
            setDisable("NMPZ");
        }
        else
        {
            setDisable(nextPlayer);
        }
    }
    else
    {
        // console.log(data)
        if (isBullseye)
        {
            if (data.options.movementOptions.forbidMoving || data.options.movementOptions.forbidRotating || data.options.movementOptions.forbidZooming)
            {
                setDisable("NMPZ");
            }
            else
            {
                setDisable(nextPlayer);
            }
        }
        else
        {
            if (data.movementOptions.forbidMoving || data.movementOptions.forbidRotating || data.movementOptions.forbidZooming)
            {
                setDisable("NMPZ");
            }
            else
            {
                setDisable(nextPlayer);
            }

        }
    }

    console.log(nextPlayer);
    injectCanvas();
}


/**
 * setID for canvas
 */

function initializeCanvas() {
    let GAME_CANVAS = "";
    let DUEL_CANVAS = "";
    //console.log("Is duels");
    //console.log(duels);

    if (isBattleRoyale) {
        if (isDuel) {
            GAME_CANVAS = document.querySelector(".game-panorama_panorama__rdhFg");
            DUEL_CANVAS = document.querySelector(".game-panorama_panoramaCanvas__PNKve");
        }
        else if (isBullseye) {
            GAME_CANVAS = document.querySelector(".game-panorama_panorama__ncMwh");
            DUEL_CANVAS = "dummy";
        }
        else
        {
            GAME_CANVAS = document.querySelector(".br-game-layout__panorama-wrapper");
            DUEL_CANVAS = "dummy";
        }
    }
    else {
        GAME_CANVAS = document.querySelector(".game-layout__canvas");
        DUEL_CANVAS = "dummy";
    }
    if (GAME_CANVAS && DUEL_CANVAS)
    {
        // console.log("Canvas injected");
        GAME_CANVAS.id = "player";

        if (isDuel) {
            DUEL_CANVAS.id = "default_player";
        }
        if (typeof mapillary !== typeof undefined)
        {
            partialCreateMapillary = true;
        }
        else
        {
            partialCreateMapillary = false;
        }
        if (typeof ymaps !== typeof undefined)
        {
            partialCreateYandex = true;
        }
        else
        {
            partialCreateYandex = false;
        }
        if (typeof kakao !== typeof undefined)
        {
            partialCreateKakao = true;
        }
        else
        {
            partialCreateKakao = false;
        }
        if (typeof Microsoft !== typeof undefined)
        {
            partialCreateMS = true;
        }
        else
        {
            partialCreateMS = false;
        }

        loadPlayers();
        injectMapillaryPlayer();
    }
    else
    {
        setTimeout(initializeCanvas, 250);
    }

}

/**
 * Hide or show players based on where the next location is
 */

function injectCanvas() {
    if (isDuel)
    {
        canvasSwitch();
    }
    else
    {
        Google();
        Baidu();
        Kakao();
        Yandex();
        Mapillary();
        Bing();
    }
    ZoomControls();
}

// for duels (class ID change)

function canvasSwitch()
{
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    if (document.querySelector(".compass") !== null && document.querySelector("button[data-qa='undo-move']") !== null)
    {
        let GOOGLE_MAPS_CANVAS = document.querySelector(".game-panorama_panoramaCanvas__PNKve");
        document.getElementById("default_player").style.position = "absolute";
        document.getElementById("default_player").className = "inactive";
        document.getElementById("i_container").style.position = "absolute";
        document.getElementById("i_container").className = "inactive";
        document.getElementById("mapillary-player").style.visibility = "hidden";
        document.getElementById("mapillary-player").style.position = "absolute";
        document.getElementById("mapillary-player").className = "inactive";
        if (BR_LOAD_KAKAO)
        {
            document.getElementById("roadview").style.position = "absolute";
            document.getElementById("roadview").className = "inactive";
        }
        if (BR_LOAD_YANDEX)
        {
            document.querySelector(".ymaps-2-1-79-panorama-screen").style.visibility = "hidden";
            document.querySelector(".ymaps-2-1-79-panorama-screen").style.position = "absolute";
        }
        if (BR_LOAD_MS)
        {
            document.getElementById("ms-player").style.position = "absolute";
            document.getElementById("ms-player").className = "inactive";
        }
        switchCovergeButton.nextPlayer = nextPlayer;
        teleportBtn.google = false;
        switchCovergeButton.useGoogle = false;
        document.querySelector(".compass").style.visibility = "";
        document.querySelector("button[data-qa='undo-move']").visibility = "";
        if (nextPlayer === "Google") {
            document.getElementById("default_player").className = "game-panorama_panoramaCanvas__PNKve";
            teleportBtn.google = true;
            switchCovergeButton.useGoogle = true;
            console.log("Google Duel Canvas loaded");
        }
        else if (nextPlayer === "Baidu" || nextPlayer === "Youtube" || nextPlayer === "Image")
        {
            document.getElementById("i_container").className = "game-panorama_panorama__rdhFg";
            document.querySelector(".compass").style.visibility = "hidden";
            document.querySelector("button[data-qa='undo-move']").visibility = "hidden";
            console.log("Container Duel Canvas loaded");
        }
        else if (nextPlayer === "Kakao")
        {
            if (BR_LOAD_KAKAO)
            {
                document.getElementById("roadview").className = "game-panorama_panorama__rdhFg";
            }
            console.log("Kakao Duel Canvas loaded");
        }
        else if (nextPlayer === "Yandex")
        {
            if (BR_LOAD_YANDEX)
            {
                document.querySelector(".ymaps-2-1-79-panorama-screen").style.visibility = "";
            }
            console.log("Yandex Duel Canvas loaded");
        }
        else if (nextPlayer === "Mapillary")
        {
            document.getElementById("mapillary-player").style.visibility = "";
            document.getElementById("mapillary-player").className = "game-panorama_panorama__rdhFg";
            document.querySelector(".compass").style.visibility = "hidden";
            // MapillaryPlayer.resize();
            console.log("Mapillary Duel Canvas loaded");
        }
        else if (nextPlayer === "MS Streetside" || nextPlayer === "MS Satellite")
        {
            if (BR_LOAD_MS)
            {
                document.getElementById("ms-player").className = "game-panorama_panorama__rdhFg";
            }
            document.querySelector(".compass").style.visibility = "hidden";
            console.log("MS Duel Canvas loaded");
        }
    }
    else
    {
        setTimeout(canvasSwitch, 250);
    }
}

// for Battle Royale and classic (change visibility)

function Google() {
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let GOOGLE_MAPS_CANVAS = ""
    if (isBattleRoyale) {
        if (!isBullseye)
        {
            GOOGLE_MAPS_CANVAS = document.querySelector(".br-game-layout__panorama-canvas");
        }
        else
        {
            GOOGLE_MAPS_CANVAS = document.querySelector(".game-panorama_panoramaCanvas__r_5ea");
        }
    }
    else {
        GOOGLE_MAPS_CANVAS = document.querySelector(".game-layout__panorama-canvas");
    }
    if (nextPlayer === "Google") {
        GOOGLE_MAPS_CANVAS.style.visibility = "";
        teleportBtn.google = true;
        switchCovergeButton.nextPlayer = "Google";
        switchCovergeButton.useGoogle = true;
        console.log("Google Canvas loaded");
    }
    else {
        GOOGLE_MAPS_CANVAS.style.visibility = "hidden";
        teleportBtn.google = false;
        console.log("Google Canvas hidden");
    }
}

function Baidu() {
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let BAIDU_MAPS_CANVAS = document.getElementById("i_container");
    // console.log("Baidu canvas");
    if (BAIDU_MAPS_CANVAS !== null && document.querySelector(".compass") !== null && document.querySelector("button[data-qa='undo-move']") !== null)
    {
        BAIDU_MAPS_CANVAS.style.position = "absolute";
        if (nextPlayer === "Baidu" || nextPlayer === "Youtube" || nextPlayer === "Image") {
            BAIDU_MAPS_CANVAS.style.visibility = "";
            switchCovergeButton.nextPlayer = "Baidu";
            switchCovergeButton.useGoogle = false;
            document.querySelector(".compass").style.visibility = "hidden";
            document.querySelector("button[data-qa='undo-move']").style.visibility = "hidden";
            console.log("Container Canvas loaded");
        }
        else {
            document.querySelector(".compass").style.visibility = "";
            document.querySelector("button[data-qa='undo-move']").style.visibility = "";
            BAIDU_MAPS_CANVAS.style.visibility = "hidden";
            console.log("Container Canvas hidden");
        }
    }
    else
    {
        setTimeout(Baidu, 250);
    }

}

function Kakao() {
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let KAKAO_MAPS_CANVAS = document.getElementById("roadview");
    // console.log("Kakao canvas");
    if (KAKAO_MAPS_CANVAS != null)
    {
        KAKAO_MAPS_CANVAS.style.position = "absolute";
        if (nextPlayer === "Kakao") {
            KAKAO_MAPS_CANVAS.style.visibility = "";
            switchCovergeButton.nextPlayer = "Kakao";
            switchCovergeButton.useGoogle = false;
            console.log("Kakao Canvas loaded");
        }
        else {
            KAKAO_MAPS_CANVAS.style.visibility = "hidden";
            console.log("Kakao Canvas hidden");
        }
    }
    else
    {
        setTimeout(Kakao, 250);
    }

}

function Yandex() {
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let YANDEX_MAPS_CANVAS = document.querySelector(".ymaps-2-1-79-panorama-screen");
    if (YANDEX_MAPS_CANVAS != null)
    {
        if (isBullseye)
        {
            let div = document.getElementById("player");
            YANDEX_MAPS_CANVAS.classList.add("game-panorama_panorama__ncMwh");
            div.prepend(YANDEX_MAPS_CANVAS);
        }
        // console.log("Yandex canvas");
        document.querySelector(".ymaps-2-1-79-panorama-screen").style.position = "absolute";
        // console.log("Yandex canvas");
        /*   console.log(YANDEX_MAPS_CANVAS); */
        if (nextPlayer === "Yandex") {
            YANDEX_MAPS_CANVAS.style.visibility = "";
            switchCovergeButton.nextPlayer = "Yandex";
            switchCovergeButton.useGoogle = false;
            console.log("Yandex Canvas loaded");
        }
        else {
            YANDEX_MAPS_CANVAS.style.visibility = "hidden";
            console.log("Yandex Canvas hidden");
        }
    }
    else
    {
        setTimeout(Yandex, 250);
    }

}

function Mapillary()
{
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let MAPILLARY_MAPS_CANVAS = document.getElementById("mapillary-player");
    if (MAPILLARY_MAPS_CANVAS != null)
    {
        // console.log("Mapillary canvas");
        MAPILLARY_MAPS_CANVAS.style.position = "absolute";
        if (nextPlayer === "Mapillary") {
            MAPILLARY_MAPS_CANVAS.style.visibility = "";
            switchCovergeButton.nextPlayer = "Mapillary";
            switchCovergeButton.useGoogle = false;
            console.log("Mapillary Canvas loaded");
        }
        else {
            MAPILLARY_MAPS_CANVAS.style.visibility = "hidden";
            console.log("Mapillary Canvas hidden");
        }
    }
    else
    {
        setTimeout(Mapillary, 250);
    }

}

function Bing() {
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let BING_MAPS_CANVAS = document.getElementById("ms-player");
    if (BING_MAPS_CANVAS != null && document.querySelector(".compass") !== null)
    {
        // console.log("Mapillary canvas");
        BING_MAPS_CANVAS.style.position = "absolute";
        if (nextPlayer === "MS Satellite" || nextPlayer === "MS Streetside") {
            BING_MAPS_CANVAS.style.visibility = "";
            switchCovergeButton.nextPlayer = nextPlayer;
            switchCovergeButton.useGoogle = false;
            document.querySelector(".compass").style.visibility = "hidden";
            console.log("Bing Canvas loaded");
        }
        else {
            BING_MAPS_CANVAS.style.visibility = "hidden";
            document.querySelector(".compass").style.visibility = "";
            console.log("Bing Canvas hidden");
        }
    }
    else
    {
        setTimeout(Bing, 250);
    }
}


/**
 * Adjust button placement
 */

function ZoomControls() {
    let style = `
	.ymaps-2-1-79-panorama-gotoymaps {display: none !important;}
	.game-layout__controls {bottom: 8rem !important; left: 1rem !important;}
	`;

    let style_element = document.createElement("style");
    style_element.innerHTML = style;
    document.body.appendChild(style_element);
}

/**
 * Updates the compass to match Yandex Panorama facing
 */
function updateCompass() {
    if (!COMPASS) {
        let compass = document.querySelector("img.compass__indicator");
        if (compass != null) {
            COMPASS = compass;
            let direction = YandexPlayer.getDirection()[0] * -1;
            COMPASS.setAttribute("style", `transform: rotate(${direction}deg);`);
        }
    }
    else {
        let direction = YandexPlayer.getDirection()[0] * -1;
        COMPASS.setAttribute("style", `transform: rotate(${direction}deg);`);
    }
}

/**
 * Open next location in streetview player given next player and next coordinate
 */

function goToLocation() {
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    console.log("Going to location");
    if (nextPlayer === "Yandex") {
        let options = {};
        YandexPlayer.moveTo([global_lat, global_lng], options);
        YandexPlayer.setDirection([0, 16]);
        YandexPlayer.setSpan([10, 67]);
    }
    else if (nextPlayer === "Baidu" || nextPlayer === "Youtube" || nextPlayer === "Image") {
        if (document.getElementById("i_container") !== null)
        {
            let iframe = document.getElementById("i_container");
            if (nextPlayer === "Baidu")
            {
                if (!isFirefox)
                {
                    iframe.style.top = '-60px';
                    iframe.style.height = (window.innerHeight + 200) + 'px';
                }
                else
                {
                    iframe.style.top = '-60px';
                    iframe.style.height = (window.innerHeight + 219) + 'px';
                }

                if (!isFirefox)
                {
                    iframe.style.right = '-55px';
                    iframe.style.width = (window.innerWidth + 55) + 'px';
                }
                else
                {
                    iframe.style.right = '-15px';
                    iframe.style.width = (window.innerWidth + 15) + 'px';
                }
                let urlStr2 = "https://map.baidu.com/?panotype=street&pid=" + global_BDID + "&panoid=" + global_BDID + "&from=api";
                let urlStr = "https://map.baidu.com/@" + global_BDAh + "," + global_BDBh + "#panoid=" + global_BDID + "&panotype=street&l=12&tn=B_NORMAL_MAP&sc=0&newmap=1&shareurl=1&pid=" + global_BDID;
                // console.log(urlStr)
                if (global_BDAh != null)
                {
                    iframe.src = urlStr;
                }
                else
                {
                    iframe.src = urlStr2;
                }
                iframe.style.visibility = "";
            }
            else if (nextPlayer === "Youtube")
            {
                document.getElementById("Youtube Button").style.visibility = "";
                document.getElementById("Youtube Button").innerHTML = "Play video";
                iframe.allow = "autoplay";
                iframe.style.visibility = "hidden";
                iframe.style.top = '-60px';
                iframe.style.height = (window.innerHeight + 235) + 'px';
            }
            else if (nextPlayer === "Image")
            {
                iframe.style.top = '0px';
                iframe.style.height = (window.innerHeight) + 'px';
                iframe.style.visibility = "";
                iframe.src = iId;
            }
        }
        else
        {
            setTimeout(goToLocation, 250);
        }
        //         let a = new BMap.Point(global_lng, global_lat);
        //         BaiduPlayer.setPov({ heading: -40, pitch: 6 });
        //         BaiduPlayer.setPosition(a);
    }
    else if (nextPlayer === "Kakao") {
        var roadviewClient = new kakao.maps.RoadviewClient();
        var position = new kakao.maps.LatLng(global_lat, global_lng);
        roadviewClient.getNearestPanoId(position, 500, function (panoId) {
            KakaoPlayer.setPanoId(panoId, position);
            KakaoPlayer.setViewpoint({ pan: global_heading, tilt: global_pitch, zoom: -3 })
        });
    }
    else if (nextPlayer === "Mapillary") {
        MapillaryPlayer.resize()
        MapillaryPlayer.moveTo(mmKey).then(
            image => { //console.log(image);
            },
            error => { console.log(error); });
    }
    else if (nextPlayer === "Google") {
        handleMapillary({lat: global_lat, lng: global_lng}, {meters: 500, limit: 500});
    }
    else if (nextPlayer === "MS Streetside") {
        MSStreetPlayer.setView({mapTypeId: Microsoft.Maps.MapTypeId.streetside,
                                zoom: 18,
                                streetsideOptions: {
                                    overviewMapMode: Microsoft.Maps.OverviewMapMode.hidden,
                                    showCurrentAddress: false,
                                    showProblemReporting: false,
                                    showExitButton: false,
                                },
                                center: new Microsoft.Maps.Location(global_lat, global_lng),
                                heading: 90,
                                pitch: -30,
                                disableStreetside: false});
    }
    else if (nextPlayer === "MS Satellite") {
        let ctr = new Microsoft.Maps.Location(global_lat, global_lng)
        let loc_centre = {lat: global_lat, lng: global_lng};
        for (var i = MSStreetPlayer.entities.getLength() - 1; i >= 0; i--) {
            var pushpin = MSStreetPlayer.entities.get(i);
            if (pushpin instanceof Microsoft.Maps.Pushpin) {
                MSStreetPlayer.entities.removeAt(i);
            }
        }
        let latlngBounds = getBBox2(loc_centre, ms_radius);
        // console.log(latlngBounds)
        let bounds = Microsoft.Maps.LocationRect.fromLocations(new Microsoft.Maps.Location(latlngBounds[0], latlngBounds[1]), new Microsoft.Maps.Location(latlngBounds[2], latlngBounds[3]));
        // console.log(bounds)
        MSStreetPlayer.setOptions({maxBounds: bounds})
        MSStreetPlayer.setView({mapTypeId: Microsoft.Maps.MapTypeId.aerial,
                                labelOverlay: Microsoft.Maps.LabelOverlay.hidden,
                                center: ctr,
                                zoom: 15,
                               })
        var pin = new Microsoft.Maps.Pushpin(ctr, {});

        //Add the pushpin to the map
        MSStreetPlayer.entities.push(pin);
        // hideNav();
    }
    switchCovergeButton.lat = global_lat;
    switchCovergeButton.lng = global_lng;
}

/**
 * Handle undo using the location history of the current round
 */

function goToUndoMove(data) {
    /*   console.log(global_lat);
      console.log(global_lng); */
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let options = {};
    let prevStep = null;
    if (locHistory.length === 1) {
        prevStep = locHistory[0];
    }
    else {
        prevStep = locHistory.pop();
    }
    // console.log(prevStep);
    // console.log(locHistory)
    if (nextPlayer === "Yandex") {
        defaultPanoIdChange = false;
        YandexPlayer.moveTo([prevStep[0], prevStep[1]], options);
        YandexPlayer.setDirection([prevStep[2], prevStep[3]]);
        YandexPlayer.setSpan([10, 67]);
        switchCovergeButton.lat = prevStep[0];
        switchCovergeButton.lng = prevStep[1];
    }
    else if (nextPlayer === "Kakao") {
        let btn = document.querySelector("button[data-qa='undo-move']");
        btn.disabled = false;
        btn.classList.remove('styles_disabled__2YdHD');
        defaultPanoIdChange = false;
        let position = new kakao.maps.LatLng(prevStep[0], prevStep[1]);
        KakaoPlayer.setPanoId(prevStep[2], position);
        switchCovergeButton.lat = prevStep[0];
        switchCovergeButton.lng = prevStep[1];
        switchCovergeButton.useGoogle = false;
        teleportBtn.google = false;
        // console.log("Undo 1 step");
        // console.log(locHistory);
    }
    else if (nextPlayer === "Mapillary" ) {
        // console.log(prevStep[1]);

        MapillaryPlayer.moveTo(prevStep[2]).then(
            image => {
                //console.log(image);
                switchCovergeButton.lat = prevStep[1];
                switchCovergeButton.lng = prevStep[0];
            },
            error => { console.log(error); });
    }
    else if (nextPlayer === "MS Streetside") {
        defaultPanoIdChange = false;
        console.log(locHistory);
        MSStreetPlayer.setView({center: new Microsoft.Maps.Location(prevStep[0], prevStep[1]),

                               });
        switchCovergeButton.lat = prevStep[0];
        switchCovergeButton.lng = prevStep[1];
        switchCovergeButton.heading = prevStep[2];
    }

}

function BYKTeleport()
{
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let teleportBtnBYK = teleportBtn;
    if (teleportBtnBYK)
    {
        teleportBtnBYK.addEventListener("click", () => {
            if (!teleportBtnBYK.google)
            {
                // console.log("non-Google Teleport");
                let prevStep = null;
                if (locHistory.length === 1) {
                    prevStep = locHistory[0];
                }
                else {
                    prevStep = locHistory[locHistory.length - 1];
                }
                console.log(locHistory);
                let options = {};
                let place, position, pID;
                if (nextPlayer === "Yandex") {
                    place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[2]), teleportBtnBYK.distance * 0.001);
                    YandexPlayer.setDirection([prevStep[2], prevStep[3]]);
                    YandexPlayer.moveTo([place.lat, place.lng], options);
                    YandexPlayer.setSpan([10, 67]);
                    switchCovergeButton.lat = place.lat;
                    switchCovergeButton.lng = place.lng;
                }
                else if (nextPlayer === "Kakao") {
                    var roadviewClient = new kakao.maps.RoadviewClient();
                    place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[3]), teleportBtnBYK.distance * 0.001);
                    position = new kakao.maps.LatLng(place.lat, place.lng);
                    roadviewClient.getNearestPanoId(position, 500, function (panoId) {
                        KakaoPlayer.setPanoId(panoId, position);
                    });
                    switchCovergeButton.lat = place.lat;
                    switchCovergeButton.lng = place.lng;
                }
                else if (nextPlayer === "Mapillary" || nextPlayer === "Google") {
                    place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[2]), teleportBtnBYK.distance * 0.001);
                    handleMapillary(place, {meters: 500, limit: 500});
                    switchCovergeButton.lat = place.lat;
                    switchCovergeButton.lng = place.lng;
                    // locHistory.push([place.lat, place.lng, prevStep[2], prevStep[3]]);
                }
                else if (nextPlayer === "MS Streetside") {
//                     console.log("teleport")
//                     console.log(prevStep);
                    place = FindPointAtDistanceFrom(prevStep[0], prevStep[1], DegreesToRadians(prevStep[2]), teleportBtnBYK.distance * 0.001);
                    let bounds = new Microsoft.Maps.LocationRect(new Microsoft.Maps.Location(place.lat, place.lng), 1, 1);
                    Microsoft.Maps.Map.getClosestPanorama(bounds, onSuccess, onMissingCoverage);
                    function onSuccess(panoramaInfo) {
//                         console.log("Coverage")
//                         console.log([panoramaInfo.la, panoramaInfo.lo])
                        MSStreetPlayer.setView({center: new Microsoft.Maps.Location(panoramaInfo.la, panoramaInfo.lo),
                                               });
                    }
                    function onMissingCoverage() {
                        console.log("No Coverage")
                    }
                }

                if (teleportBtnBYK.distance > 150)
                {
                    teleportBtnBYK.distance = 100;
                    teleportBtnBYK.innerHTML = "Teleport " + teleportBtnBYK.distance + " m";
                }
            }
        });
    }
    else
    {
    }
}

function SyncListener()
{
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    switchCovergeButton.addEventListener("click", () => {
        if (switchCovergeButton.useGoogle == false) {
            // switchCovergeButton.useGoogle = true;
            console.log(switchCovergeButton.nextPlayer)
            if (switchCovergeButton.nextPlayer === "Yandex") {
                let options = {};
                YandexPlayer.moveTo([switchCovergeButton.lat, switchCovergeButton.lng], options);
                YandexPlayer.setDirection([switchCovergeButton.heading, 0]);

                // switchCovergeButton.nextPlayer = "Yandex";
            }
            else if (switchCovergeButton.nextPlayer === "Kakao") {
                let roadviewClient = new kakao.maps.RoadviewClient();
                // console.log(switchCovergeButton.lat);
                let position = new kakao.maps.LatLng(switchCovergeButton.lat, switchCovergeButton.lng);
                roadviewClient.getNearestPanoId(position, 500, function (panoId) {
                    KakaoPlayer.setPanoId(panoId, position);
                });
                KakaoPlayer.setViewpoint({
                    pan: switchCovergeButton.heading,
                    tilt: 0,
                    zoom: -3
                });
                // switchCovergeButton.nextPlayer = "Kakao";
            }
            else if (switchCovergeButton.nextPlayer === "Mapillary" || switchCovergeButton.nextPlayer === "Google") {
                // switchCovergeButton.nextPlayer = "Kakao";
                handleMapillary({lat: switchCovergeButton.lat, lng: switchCovergeButton.lng}, {meters: 100, limit: 100});
            }
            else if (switchCovergeButton.nextPlayer === "MS Streetside") {
                let bounds = new Microsoft.Maps.LocationRect(new Microsoft.Maps.Location(switchCovergeButton.lat, switchCovergeButton.lng), 0.01, 0.01);
                Microsoft.Maps.Map.getClosestPanorama(bounds, onSuccess, onMissingCoverage);
                function onSuccess(panoramaInfo) {
                    MSStreetPlayer.setView({center: new Microsoft.Maps.Location(panoramaInfo.la, panoramaInfo.lo),
                                            heading: switchCovergeButton.heading
                                           });
                }
                function onMissingCoverage() {
                    console.log("No Coverage")
                }
            }
        }
    });

}

/**
 * Gets the seed data for the current game
 *
 * @returns Promise with seed data as object
 */
function getSeed() {
    // console.log("getSeed called");
    return new Promise((resolve, reject) => {
        let token = getToken();
        let URL;
        let cred = ""

        const PATHNAME = window.location.pathname;

        if (PATHNAME.startsWith("/game/")) {
            URL = `https://www.geoguessr.com/api/v3/games/${token}`;
        }
        else if (PATHNAME.startsWith("/challenge/")) {
            URL = `https://www.geoguessr.com/api/v3/challenges/${token}/game`;
        }
        else if (PATHNAME.startsWith("/battle-royale/")) {
            URL = `https://game-server.geoguessr.com/api/battle-royale/${token}`;
        }
        else if (PATHNAME.startsWith("/duels/") || PATHNAME.startsWith("/team-duels/")) {
            URL = `https://game-server.geoguessr.com/api/duels/${token}`;
        }
        else if (PATHNAME.startsWith("/bullseye/")) {
            URL = `https://game-server.geoguessr.com/api/bullseye/${token}`;
        }
        if (isBattleRoyale) {
            fetch(URL, {
                // Include credentials to GET from the endpoint
                credentials: 'include'
            })
                .then((response) => response.json())
                .then((data) => {
                resolve(data);
            })
                .catch((error) => {
                reject(error);
            });
        }
        else {
            fetch(URL)
                .then((response) => response.json())
                .then((data) => {
                resolve(data);
            })
                .catch((error) => {
                reject(error);
            });
        }
    });
}

/**
 * Gets the token from the current URL
 *
 * @returns token
 */
function getToken() {
    const PATHNAME = window.location.pathname;
    if (PATHNAME.startsWith("/game/")) {
        return PATHNAME.replace("/game/", "");
    }
    else if (PATHNAME.startsWith("/challenge/")) {
        return PATHNAME.replace("/challenge/", "");
    }
    else if (PATHNAME.startsWith("/battle-royale/")) {
        return PATHNAME.replace("/battle-royale/", "");
    }
    else if (PATHNAME.startsWith("/duels/")) {
        return PATHNAME.replace("/duels/", "");
    }
    else if (PATHNAME.startsWith("/team-duels/")) {
        return PATHNAME.replace("/team-duels/", "");
    }
    else if (PATHNAME.startsWith("/bullseye/")) {
        return PATHNAME.replace("/bullseye/", "");
    }
}

/**
 * Gets the round number from the ongoing game from the page itself
 *
 * @returns Round number
 */
function getRoundFromPage() {
    const roundData = document.querySelector("div[data-qa='round-number']");
    if (roundData) {
        let roundElement = roundData.querySelector("div:last-child");
        if (roundElement) {
            let round = parseInt(roundElement.innerText.charAt(0));
            if (!isNaN(round) && round >= 1 && round <= 5) {
                return round;
            }
        }
    }
    else {
        return ROUND;
    }
}


/**
 * Injects Yandex Script
 */
function injectYandexScript() {
    return new Promise((resolve, reject) => {
        if (!YANDEX_INJECTED) {
            if (YANDEX_API_KEY === "") {
                console.log("No Yandex Key")
                reject();
            }
            else {
                if (!partialCreateYandex)
                {
                    const SCRIPT = document.createElement("script");
                    SCRIPT.type = "text/javascript";
                    SCRIPT.async = true;
                    SCRIPT.src = `https://api-maps.yandex.ru/2.1/?lang=en_US&apikey=${YANDEX_API_KEY}`;
                    document.body.appendChild(SCRIPT);
                    SCRIPT.onload = () => {
                        ymaps.ready(() => {
                            YANDEX_INJECTED = true;
                            myHighlight("Yandex API Loaded");
                            resolve();
                        });
                    }
                }
                else
                {
                    YANDEX_INJECTED = true;
                    resolve();
                }
            }
        }
        else {
            resolve();
        }
    });
}

/**
 * Injects Yandex Player and calls handleReturnToStart
 */
function injectYandexPlayer() {
    let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
    let lat = 41.321861;
    let lng = 69.212920;

    let options = {
        "direction": [0, 16],
        "span": [10, 67],
        "controls": ["zoomControl"]
    };
    ymaps.panorama.createPlayer("player", [lat, lng], options)
        .done((player) => {
        YandexPlayer = player;
        YandexPlayer.events.add("directionchange", (e) => {
            updateCompass();
            let pov = YandexPlayer.getDirection();
            if (locHistory.length > 0 && nextPlayer == "Yandex") {
                switchCovergeButton.heading = pov[0];
                locHistory[locHistory.length - 1][2] = pov[0];
                locHistory[locHistory.length - 1][3] = pov[1];
            }
        });
        YandexPlayer.events.add("panoramachange", (e) => {
            if (defaultPanoIdChange) {
                let num = YandexPlayer.getPanorama().getPosition();
                let pov = YandexPlayer.getDirection();
                // console.log(num);
                // console.log(pov);
                if (nextPlayer == "Yandex")
                {
                    locHistory.push([num[0], num[1], pov[0], pov[1]]);
                    switchCovergeButton.lat = num[0];
                    switchCovergeButton.lng = num[1];
                }
                let btn = document.querySelector("button[data-qa='undo-move']");
                if (locHistory.length > 1) {
                    btn.disabled = false;
                    btn.classList.remove('styles_disabled__2YdHD');
                }
                // console.log(locHistory);
            }
            defaultPanoIdChange = true;

        });
        console.log("Yandex Player injected");
    });

}


/**
 * Injects Baidu script
 */

function reportWindowSize() {
    let iframeC = document.getElementById("i_container");
    if (iframeC)
    {
        if (nextPlayer == "Baidu")
        {
            iframeC.style.top = '-60px';
            iframeC.style.height = (window.innerHeight + 200) + 'px';
            iframeC.style.right = '-55px';
            iframeC.style.width = (window.innerWidth + 55) + 'px';
        }
        else if (nextPlayer == "Youtube")
        {
            iframeC.style.top = '-60px';
            iframeC.style.height = (window.innerHeight + 235) + 'px';
        }
        else if (nextPlayer == "Image")
        {
            iframeC.style.top = '0px';
            iframeC.style.height = (window.innerHeight) + 'px';
        }

    }
}

window.onresize = reportWindowSize;

function injectContainer() {
    myHighlight("iframe container loaded")
    const iframe = document.createElement('iframe');
    iframe.frameBorder = 0;
    iframe.style.position = "absolute";
    iframe.id = "i_container";
    if (isBattleRoyale) {
        if (isDuel)
        {
            iframe.className = "inactive"
        }
        else if (isBullseye)
        {
            iframe.className = "game-panorama_panorama__ncMwh"
        }
        else
        {
            iframe.className = "br-game-layout__panorama"
        }
    }
    else {
        iframe.className = "game-layout__panorama"
    }
    var div = document.getElementById("player");
    div.style.overflow = "hidden";
    if (isBullseye)
    {
        div.prepend(iframe);
    }
    else
    {
        div.appendChild(iframe);
    }
}

// function injectMedia() {
//     myHighlight("Baidu API loaded")
//     const iframe = document.createElement('iframe');
//     iframe.allow = "autoplay"
//     iframe.src = "https://www.youtube.com/embed/72kRM86V-dw?&autoplay=1&modestbranding=1&controls=0&start=10"
//     iframe.frameBorder = 0;
//     iframe.style.position = "absolute";
//     iframe.id = "media-player";
//     iframe.style="position:fixed; top: -60px; left:0; bottom: calc(100% + 175px); right:0; width:100%; height:calc(100% + 235px); border:none; margin:0; padding:0; overflow:hidden; z-index:999999;"
//     if (isBattleRoyale) {
//         if (isDuel)
//         {
//             iframe.className = "inactive"
//         }
//         else
//         {
//             iframe.className = "br-game-layout__panorama"
//         }
//     }
//     else {
//         iframe.className = "game-layout__panorama"
//     }
//     var div = document.getElementById("player");
//     div.style.overflow = "hidden";
//     div.appendChild(iframe);
// }

/**
 * Injects Kakao script
 */

function injectKakaoScript() {
    return new Promise((resolve, reject) => {
        let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
        if (!KAKAO_INJECTED) {
            if (KAKAO_API_KEY === "") {
                console.log("No Kakao Key")
            }
            else {

                let canvas = document.createElement("kmap");
                if (isBattleRoyale) {
                    if (isDuel)
                    {
                        canvas.innerHTML = `
                 <div id="roadview" class="inactive" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
            `;
                    }
                    else if (isBullseye)
                    {
                        canvas.innerHTML = `
                 <div id="roadview" class="game-panorama_panorama__ncMwh" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
            `;
                    }
                    else
                    {
                        canvas.innerHTML = `
                 <div id="roadview" class="br-game-layout__panorama" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
            `;
                    }
                }
                else {
                    canvas.innerHTML = `
                 <div id="roadview" class="game-layout__panorama" style="zIndex: 99999,position: "absolute", top: 0, left: 0, width: '100%', height: '100%',"> </div>
            `;
                }


                var div = document.getElementById("player");
                if (isBullseye)
                {
                    div.prepend(canvas);
                }
                else
                {
                    div.appendChild(canvas);
                }

                let SCRIPT;
                if (!partialCreateKakao)
                {
                    SCRIPT = document.createElement("script");
                    SCRIPT.async = true;
                    // SCRIPT.type = "text/javascript";
                    SCRIPT.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${KAKAO_API_KEY}&autoload=false`;
                    document.body.appendChild(SCRIPT);
                }

                function drawmapKakao()
                {
                    kakao.maps.load(function () {
                        var position = new kakao.maps.LatLng(33.450701, 126.560667);
                        let roadviewContainer = document.getElementById('roadview');
                        KakaoPlayer = new kakao.maps.Roadview(roadviewContainer);
                        var panoId = 1023434522;
                        KakaoPlayer.setPanoId(panoId, position);
                        KAKAO_INJECTED = true;
                        // Remove the compass from Kakao
                        kakao.maps.event.addListener(KakaoPlayer, 'init', () => {
                            const compassContainer = roadviewContainer.querySelector('div[id*="_box_util_"]');
                            if (compassContainer) compassContainer.style.display = 'none';
                        });
                        kakao.maps.event.addListener(KakaoPlayer, 'panoid_changed', function() {
                            if (defaultPanoIdChange && KakaoPlayer) {
                                let latlng = KakaoPlayer.getPosition();
                                let lat = latlng.getLat();
                                let lng = latlng.getLng();
                                let pID = KakaoPlayer.getViewpointWithPanoId();
                                if (nextPlayer == "Kakao" && lat != 33.45047613915499)
                                {
                                    // console.log("push");
                                    locHistory.push([lat, lng, pID.panoId, pID.pan]);
                                    switchCovergeButton.lat = lat;
                                    switchCovergeButton.lng = lng;
                                    switchCovergeButton.heading = pID.pan;
                                }
                                let btn = document.querySelector("button[data-qa='undo-move']");
                                if (locHistory.length > 1 && (btn != null)) {
                                    btn.disabled = false;
                                    btn.classList.remove('styles_disabled__2YdHD');
                                }
                                // console.log(locHistory);
                            }
                            defaultPanoIdChange = true;
                        });
                        kakao.maps.event.addListener(KakaoPlayer, 'viewpoint_changed', function() {
                            // console.log("pov_listener attached");
                            let pID = KakaoPlayer.getViewpointWithPanoId();
                            if (locHistory.length > 0 && nextPlayer == "Kakao") {
                                switchCovergeButton.heading = pID.pan;
                                locHistory[locHistory.length - 1][3] = pID.pan;
                            }
                            if (GooglePlayer) {
                                const { heading, pitch } = GooglePlayer.getPov()
                                if ((!almostEqual(pID.pan, heading) || !almostEqual(pID.tilt, pitch)) && nextPlayer == "Kakao") {
                                    // Updating the google street view POV will update the compass
                                    GooglePlayer.setPov({ heading: pID.pan, pitch: pID.tilt })
                                }
                            }
                            // console.log(locHistory);
                        })
                    });
                }

                if (partialCreateKakao)
                {
                    drawmapKakao();
                }
                else
                {
                    SCRIPT.onload = () => {
                        drawmapKakao();
                        myHighlight("Kakao API Loaded");
                        resolve();
                    };
                }

            }
        }
        else {
            resolve();
        }
    });
}


function injectMSPlayer() {
    return new Promise((resolve, reject) => {
        if (!MS_INJECTED) {
            if (MS_API_KEY === "") {
                let canvas = document.getElementById("player");
                console.log("No MS Key")
            }
            else {

                let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();
                let SCRIPT;
                if (!partialCreateMS)
                {
                    SCRIPT = document.createElement("script");
                    SCRIPT.type = "text/javascript";
                    SCRIPT.async = true;
                    SCRIPT.src = `https://www.bing.com/api/maps/mapcontrol?key=${MS_API_KEY}`;
                    document.body.appendChild(SCRIPT);
                }
                let canvas = document.createElement("msmap");
                if (isBattleRoyale) {
                    if (isDuel)
                    {
                        canvas.innerHTML = `<div id="ms-player" class="inactive" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
                    }
                    else if (isBullseye)
                    {
                        canvas.innerHTML = `<div id="ms-player" class="game-panorama_panorama__ncMwh" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
                    }
                    else
                    {
                        canvas.innerHTML = `<div id="ms-player" class="br-game-layout__panorama" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
                    }
                }
                else {
                    canvas.innerHTML = `<div id="ms-player" class="game-layout__panorama" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
                }

                var div = document.getElementById("player");
                if (isBullseye)
                {
                    div.prepend(canvas);
                }
                else
                {
                    div.appendChild(canvas);
                }

                function drawmapMS()
                {
                    MSStreetPlayer = new Microsoft.Maps.Map(document.getElementById('ms-player'),{disableStreetsideAutoCoverage: true});
                    MS_INJECTED = true;
                    Microsoft.Maps.Events.addHandler(MSStreetPlayer, 'viewchange', function () { updateView(MSStreetPlayer); });
                    function updateView(map) {
                        let ctrm = map.getCenter();
                        if (nextPlayer == "MS Streetside" && (switchCovergeButton.lat !== ctrm.latitude && switchCovergeButton.lng !== ctrm.longitude))
                        {
                            let heading2 = bearing(switchCovergeButton.lat, switchCovergeButton.lng, ctrm.latitude, ctrm.longitude)
//                             console.log("moved");
//                             console.log([switchCovergeButton.lat, switchCovergeButton.lng, ctrm.latitude, ctrm.longitude])
//                             console.log(heading2);
                            locHistory.push([ctrm.latitude, ctrm.longitude, heading2]);
                            switchCovergeButton.lat = ctrm.latitude;
                            switchCovergeButton.lng = ctrm.longitude;
                            switchCovergeButton.heading = heading2;
                            let btn = document.querySelector("button[data-qa='undo-move']");
                            if (locHistory.length > 1 && (btn != null)) {
                                btn.disabled = false;
                                btn.classList.remove('styles_disabled__2YdHD');
                            }
                        }
                    }
                }

                if (partialCreateMS)
                {
                    drawmapMS();
                }
                else
                {
                    SCRIPT.addEventListener('load', () => {
                        myHighlight("Bing Maps API loaded");
                        let timeout = 0;
                        let interval = setInterval(() => {
                            if (timeout >= 40) {
                                reject();
                                clearInterval(interval);
                            }
                            if (document.getElementById('ms-player') !== null && typeof Microsoft.Maps.Map !== typeof undefined) {
                                drawmapMS();
                                resolve();
                                clearInterval(interval);
                            }
                            timeout += 1;
                        }, 1000);
                    })
                }
            }
        }
        else {
            resolve();
        }
    });
}



function injectMapillaryPlayer() {
    return new Promise((resolve, reject) => {
        if (!MAPILLARY_INJECTED) {
            if (MAPILLARY_API_KEY === "") {
                let canvas = document.getElementById("player");
                console.log("No Mapillary Key")
            }
            else {
                let [teleportBtn, teleportMoreBtn, teleportLessBtn, teleportDistResetBtn, switchCovergeButton, mainMenuBtn, timeMachineBtn, timeMachineOlderBtn, timeMachineNewerBtn, MinimapBtn, OverlayBtn, HelpBtn, TeleportArisBtn] = setButtons();

                let SCRIPT;
                if (!partialCreateMapillary)
                {
                    SCRIPT = document.createElement("script");
                    SCRIPT.type = "text/javascript";
                    SCRIPT.async = true;
                    SCRIPT.src = `https://unpkg.com/[email protected]/dist/mapillary.js`;
                    document.body.appendChild(SCRIPT);
                    document.querySelector('head').innerHTML += '<link href="https://unpkg.com/[email protected]/dist/mapillary.css" rel="stylesheet"/>';
                }
                let canvas = document.createElement("mmap");
                if (isBattleRoyale) {
                    if (isDuel)
                    {

                        canvas.innerHTML = `<div id="mapillary-player" class="inactive" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
                    }
                    else if (isBullseye)
                    {
                        canvas.innerHTML = `<div id="mapillary-player" class="game-panorama_panorama__ncMwh" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
                    }
                    else
                    {
                        canvas.innerHTML = `<div id="mapillary-player" class="br-game-layout__panorama" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
                    }
                }
                else {
                    canvas.innerHTML = `<div id="mapillary-player" class="game-layout__panorama" style="zIndex: 99999, position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'"></div>`;
                }

                var div = document.getElementById("player");
                if (isBullseye)
                {
                    div.prepend(canvas);
                }
                else
                {
                    div.appendChild(canvas);
                }

                function drawMapML()
                {
                    var {Viewer} = mapillary;

                    MapillaryPlayer = new Viewer({
                        accessToken: MAPILLARY_API_KEY,
                        container: 'mapillary-player', // the ID of our container defined in the HTML body
                    });

                    MapillaryPlayer.on('image', async (event) => {
                        // cnt = cnt + 1;
                        // console.log(cnt);
                        let image = event.image;
                        let pos = image.originalLngLat;
                        let cond = true;
                        for (const element of locHistory) {
                            if (element[2] == image.id)
                            {
                                cond = false;
                            }
                        }
                        if (cond)
                        {
                            switchCovergeButton.lat = pos.lat;
                            switchCovergeButton.lng = pos.lng;
                            switchCovergeButton.heading = image.compassAngle;
                            // console.log(pos);
                            locHistory.push([pos.lat, pos.lng, image.id, image.compassAngle]);
                        }
                        let btn = document.querySelector("button[data-qa='undo-move']");
                        if (btn !== null && locHistory.length > 1)
                        {
                            btn.disabled = false;
                            btn.classList.remove('styles_disabled__2YdHD');
                        }
                    });

                    MAPILLARY_INJECTED = true;
                }
                if (partialCreateMapillary)
                {
                    drawMapML();
                }
                else
                {

                    SCRIPT.addEventListener('load', () => {
                        myHighlight("Mapillary API Loaded");
                        // resolve(BMap);
                        drawMapML();
                        resolve();
                    })
                }
            }
        }
        else {
            resolve();
        }
    });
}


function handleMapillary(latlng, options)
{
    console.log("handleMapillary")
    handleMapillaryHelper(latlng, options).then((data) => {
        //console.log(data.data)
        let idToSet = 0;
        let curDist = 100000000;
        for (const element of data.data) {
            // console.log(element)
            if (element.hasOwnProperty("computed_geometry"))
            {
                try {
                    let rCord = element.computed_geometry["coordinates"];
                    let dist = distance(latlng.lat,latlng.lng,rCord[1],rCord[0])
                    if (dist < curDist)
                    {
                        idToSet = element.id;
                        curDist = dist
                    }
                } catch (e) {
                    console.log("Error")
                }
            }
        }
        if (idToSet !== 0)
        {
            MapillaryPlayer.moveTo(idToSet).then(
                image => { //console.log(image);
                },
                error => { console.log(error); });
        }}).catch((error) => {
        console.log(error);
    });
}

function handleMapillaryHelper(latlng, options)
{
    return new Promise((resolve, reject) => {
        // console.log("1")
        let bbox = getBBox(latlng, options.meters);
        let URL = "https://graph.mapillary.com/images?access_token={0}&fields=id,computed_geometry&bbox={1}&limit={2}".replace('{0}', MAPILLARY_API_KEY).replace('{1}', bbox).replace('{2}', options.limit)
        // console.log(URL)
        fetch(URL)
            .then((response) => {resolve(response.json())})
            .catch((error) => {console.log(error);});
    });
}

function moveFrom(coords, angle, distance){
    const R_EARTH = 6378.137;
    const M = (1 / ((2 * Math.PI / 360) * R_EARTH)) / 1000;
    let radianAngle = -angle * Math.PI / 180;
    let x = 0 + (distance * Math.cos(radianAngle));
    let y = 0 + (distance * Math.sin(radianAngle));

    let newLat = coords.lat + (y * M);
    let newLng = coords.lng + (x * M) / Math.cos(coords.lat * (Math.PI / 180));
    return { lat: newLat, lng: newLng };
}

function getBBox(coordinates, meters){
    let SW = moveFrom(coordinates, 135, meters);
    let NE = moveFrom(coordinates, 315, meters);
    return `${SW.lng},${SW.lat},${NE.lng},${NE.lat}`;
}

function getBBox2(coordinates, meters){
    let SW = moveFrom(coordinates, 135, meters);
    let NE = moveFrom(coordinates, 315, meters);
    return [NE.lat,SW.lng,SW.lat,NE.lng];
}


function distance(lat1, lon1, lat2, lon2) {
    var p = 0.017453292519943295;    // Math.PI / 180
    var c = Math.cos;
    var a = 0.5 - c((lat2 - lat1) * p)/2 +
        c(lat1 * p) * c(lat2 * p) *
        (1 - c((lon2 - lon1) * p))/2;

    return 1000 * 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}


/**
 * Minimap presets
 */

let water_name_only =
    [
        {
            "elementType": "geometry",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "administrative",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "landscape",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "poi",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "road",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "transit",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        }
    ]
let country_name_only =
    [
        {
            "elementType": "geometry",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "administrative",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "administrative.country",
            "elementType": "labels",
            "stylers": [
                {
                    "visibility": "on"
                }
            ]
        },
        {
            "featureType": "landscape",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "poi",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "road",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "transit",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "water",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        }
    ]

let no_label_or_terrain =
    [
        {
            "elementType": "geometry",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "administrative",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "landscape",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "poi",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "road",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "transit",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "water",
            "stylers": [
                {
                    "visibility": "on"
                }
            ]
        },
        {
            "featureType": "water",
            "elementType": "labels",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        }
    ]

let no_label =
    [
        {
            "elementType": "labels",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        },
        {
            "featureType": "administrative",
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        }
    ]

let blank =

    [
        {
            "stylers": [
                {
                    "visibility": "off"
                }
            ]
        }
    ]

let thick_border =

    [
        {
            "featureType": "administrative.country",
            "elementType": "geometry.stroke",
            "stylers": [
                {
                    "weight": 1.5
                }
            ]
        },
        {
            "featureType": "administrative.province",
            "elementType": "geometry.stroke",
            "stylers": [
                {
                    "weight": 3.5
                }
            ]
        }
    ]

let default_preset = []

let presetMinimap = [[default_preset, "Default"],
                     [blank, "Blank"],
                     [water_name_only, "Oceanman"],
                     [country_name_only, "Impossible"],
                     [no_label_or_terrain, "Streaks"],
                     [no_label, "Easy 5K"],
                     [thick_border, "Borders"],
                     [default_preset, "Satellite"],
                     [default_preset, "Terrain"],
                     [default_preset, "Hybrid"],
                     [custom, "Custom", customMode]]

let GEOJSON_INVISIBLE =
    {
        strokeOpacity: 0,
        fillOpacity: 0,
    }

let presetOverlay = [["Clear",""],
                     ["Coverage",""],
                     ["Official",""],
                     ["Longitude", "https://raw.githubusercontent.com/Jupaoqq/Jupaoqq.github.io/main/lonl.json"],
                     ["Latitude", "https://raw.githubusercontent.com/Jupaoqq/Jupaoqq.github.io/main/latl.json"],
                     ["US County","https://raw.githubusercontent.com/CodeForCary/CountyDataUSA5m/master/cb_2017_us_county_5m.json"],
                     ["France","https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements.geojson"],
                     ["Time Zone", "https://raw.githubusercontent.com/treyerl/timezones/master/timezones_wVVG8.geojson"],
                     ["UK Parliament", "https://raw.githubusercontent.com/martinjc/UK-GeoJSON/master/json/electoral/gb/wpc.json"],
                     ["Custom", YOUR_URL]]

/**
 * Display map per local laws and regulations
 */

let SEOverlay, NWOverlay, SEOverlay3;
let TW = [[24.80, 119.00, 22.00, 123.20],
          [24.20, 119.90, 22.90, 121.85],
          [24.00, 120.90, 23.80, 121.20],
          [23.93, 121.03, 23.85, 121.15],
          [23.92, 121.055, 23.89, 121.10],
          [23.92, 121.055, 23.89, 121.10],
          [23.92, 121.055, 23.89, 121.10],
         ]

let TS = [[30.40, 93.40, 28, 97.20],
          [29.40, 94.55, 28.20, 96.45]]

let NW = [36.20, 77.70, 34.40, 80.70]