RollerCoin little helper

This script just help to notice games which have one play to rise difficulty level and to choose more profitable miner when you set miners in room. Of course my ref link: https://rollercoin.com/?r=lcy2is9p

// ==UserScript==
// @name         RollerCoin little helper
// @namespace    http://tampermonkey.net/
// @version      1.021
// @description  This script just help to notice games which have one play to rise difficulty level and to choose more profitable miner when you set miners in room. Of course my ref link: https://rollercoin.com/?r=lcy2is9p
// @author       Heymdale
// @match        https://rollercoin.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=rollercoin.com
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {

    let reloadInterval = 20000;
    let toReload = window.localStorage.getItem("toReload");
    let toBeep = window.localStorage.getItem("toBeep");
    // stop_reload stops reload then there are green items.
    let stop_reload = false
    const delimiter = " | ";
    if (toReload === null){
        window.localStorage.setItem("toReload", "false");
        toReload = "false";
    }
    if (toBeep === null){
        window.localStorage.setItem("toBeep", "false");
        toBeep = "false";
    }

    window.addEventListener('load', function()
    {
        waitHeadLine();
        window.setInterval(main, 1000);
    }, false);

    document.addEventListener('keydown', function(e) {
        if (event.keyCode === 49) {
            if (toReload == "true"){
                toReload = "false";
            }
            else{
                toReload = "true"
            }
            changeTitle();
            window.localStorage.setItem("toReload", toReload);
        }
        if (event.keyCode === 50) {
            if (toBeep == "true"){
                toBeep = "false";
            }
            else{
                toBeep = "true"
            }
            changeTitle();
            window.localStorage.setItem("toBeep", toBeep);
        }
        if (event.keyCode === 51) {
            show_absolute_power();
        }
        if (event.keyCode === 52) {
            sort_miners_by_true_power();
        }
    });

    function isChooseGamePage() {
        return (window.location.href == "https://rollercoin.com/game/choose_game");
        }

    function beep() {
        let snd = new Audio("data:audio/wav;base64,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qJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
        snd.play();
    }

    function _main(){
        let mainToBeep = false
        stop_reload = false
        let gameDivs = document.querySelectorAll(".choose-game-item-container");
        for (let i = 0; i < gameDivs.length; i++) {
            let progressBars = gameDivs[i].querySelectorAll(".progress-block");
            let difficulty = gameDivs[i].querySelectorAll(".game-information-number")[0].innerText
            let secondProgressBar = progressBars[progressBars.length - 2];
            let secondProgressBarDiv = secondProgressBar.firstChild.getAttribute("aria-valuenow");
            let lastProgressBar = progressBars[progressBars.length - 1];
            let thirdProgressBarDiv = lastProgressBar.firstChild.getAttribute("aria-valuenow");
            if (thirdProgressBarDiv == "100" && difficulty != "10"){
                let buttonText = gameDivs[i].querySelector(".btn-text").innerText;
                if (buttonText == 'START'){
                    gameDivs[i].style.color = "LightGreen";
                    // Page will not reload if there are game with one play to rise level
                    stop_reload = true
                    if (toBeep == "true"){
                        mainToBeep = true;
                    }
                }
                else if (buttonText == 'WAIT...'){
                    gameDivs[i].style.color = "red";
                }
            }
            else if (secondProgressBarDiv == "100" && difficulty != "10"){
                let buttonText = gameDivs[i].querySelector(".btn-text").innerText;
                if (buttonText == 'START'){
                    gameDivs[i].style.color = "Cyan";
                }
                else if (buttonText == 'WAIT...'){
                    gameDivs[i].style.color = "Blue";
                }
            }
            else{
                gameDivs[i].style.color = "white";
            }
        }
        if (mainToBeep) {
            beep();
        }
    }

    // Function must spy for document and change headline when it appears,
    // because "onload" needed tag didn't exist.
    // All this function is kluge.
    // It try to change <h1> every time then document.body get or lost child.
    function waitHeadLine(){
        let observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (!mutation.addedNodes.length) return
                if (!isChooseGamePage()) return
                if (document.querySelector("h1.choose-game-title") !== null) changeTitle();
            })
        })

        observer.observe(document.body, {
            childList: true
        })
    }

    // Added state of the userscript to headline
    function changeTitle(){
        let headLine = document.querySelector("h1.choose-game-title");
        let reloaderText = toReload == "true" ? "on" : "off";
        let beeperText = toBeep == "true" ? "on" : "off";
        if (headLine !== null)
        {
            headLine.innerText= "Play games to rise your power\n" +
                "Reloader:" + reloaderText + " Beeper:" + beeperText;
        }
    }


    /* Functions to show miner power */
    function show_absolute_power(){
        let powerBonus = getPowerBonus();
        let globalPower = powerBonus[0];
        let globalBonus = powerBonus[1];
        console.log("g_pow = ", globalPower, "g_bonus = ", globalBonus)
        let cards = document.querySelectorAll(".item-card");
        cards.forEach((element) => {
            if (element.querySelectorAll(".item-card-result-power").length > 0) return;
            let powerEl = element.querySelector(".item-card-power");
            let bonusEl = element.querySelector(".item-card-bonus");
            let power = normalizePower(powerEl.innerText);
            let bonus= parseFloat(bonusEl.innerText) / 100;
            let result_power = Math.round(power * (globalBonus+bonus) + bonus * (globalPower+power));
            console.log("power =", power, "bonus =", bonus * 100, "%\n", result_power);
            let span = document.createElement("span");
            span.className = "item-card-result-power";
            span.append(delimiter, result_power);
            bonusEl.parentElement.append(span)
        });
        let cardList = document.querySelector(".items-cards-wrapper");
        sortListByResultPower(cardList)
    }

    // функция сортировки
    function sortListByResultPower(list) {
        let listElements = Array.prototype.slice.call(list.children); // превращаем NodeList в настоящий массив
        // сортируем
        listElements.sort(function(a, b) {
            return (getValue(b)) - (getValue(a));
        })
        // очищаем родительский контейнер
        list.innerHTML = ''
        // вставляем элементы в новом порядке
        listElements.forEach(function(el) {
            list.appendChild(el)
        });
    }

    function getValue(a) {
        //console.log(a)
        let resultPowerEl = a.querySelector(".item-card-result-power")
        //console.log("result power while sort = ", resultPowerEl)
        return parseFloat(resultPowerEl.innerText.replace(delimiter, ""));
    }

    // Get current power and bonus from https://rollercoin.com/game page.
    // Power is calculate as "total power" / bonus, it's not raw power, but the best until we can manually set value
    function getPowerBonus(){
        let bonusPowerEl = document.querySelectorAll(".bonus-percent-power-wrapper");
        let bonusMultiplier = 1 + parseFloat(bonusPowerEl[0].innerText) / 100;
        let power = normalizePower(bonusPowerEl[1].innerText) / bonusMultiplier;
        return [power, bonusMultiplier]
    }

    // Normalize string power like "123.23 Ph/s" to Th/s
    function normalizePower(powStr) {
        let multiplier = 1;
        switch (powStr.trim().toLowerCase().slice(-4)) {
            case "gh/s":
                multiplier = 1/1000;
                break;
            case "ph/s":
                multiplier = 1000;
                break;
            case "eh/s":
                multiplier = 1000000;
                break;
            case "zh/s":
                multiplier = 1000000000;
                break;
        }
        return parseFloat(powStr) * multiplier;
    }

    function sort_miners_by_true_power() {
        return
        /*
        if (window.location.href != "https://rollercoin.com/storage/inventory") return;
        console.log("This is needed page");
        let table = document.querySelector(".inventory-parts-container")
        temp_result = []
        */
    }

    /* Wrap all functions */
    function main(){
        if (isChooseGamePage()) _main();
    }

    setInterval(function(){
        if (toReload == "true" && stop_reload == false) {
            if (isChooseGamePage()) document.location.reload();
        }
    }, reloadInterval);

})();