Better Soccer Project

For making SP a little bit better

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name        Better Soccer Project
// @namespace   sp
// @description For making SP a little bit better
// @include     *soccerproject.com/*
// @version     2.1
// @grant       none
// ==/UserScript==
// add jquery
 
//add jquery
function includeJs(jsFilePath) {
	var js = document.createElement("script");
 
	js.type = "text/javascript";
	js.src = jsFilePath;
 
	document.body.appendChild(js);
}
 
includeJs("//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js");
 
function bootSP(){
	if(typeof window.jQuery !== 'function'){
		window.setTimeout(bootSP, 150);
		return;
	}
	var $ = window.jQuery;
	//Rebind console to c
	var c = false;
 
	if(typeof console === "object" && typeof console.error === "function"){
		c = console,
			c = function (msg){"use strict"; console.info(msg);};
	}
 
	var SP = {};

	function parsePercentValue(text) {
		var match = String(text || '').match(/(\d+)/);
		return match ? parseInt(match[1], 10) : 0;
	}

	function getHiddenSkillEstimateFromDetails(statsTable) {
		var excludedLabels = {
			'Club': true,
			'Fitness': true,
			'Global rating': true,
			'Morale': true,
			'Aggression': true,
			'Experience': true
		};
		var rating = 0;
		var visibleSkills = [];
		$(statsTable).find('tr').each(function () {
			var cells = $(this).find('td');
			if (cells.length < 2) return;
			var label = $(cells[0]).text().replace(/\s+/g, ' ').trim();
			var value = parsePercentValue($(cells[1]).text());
			if (!label) return;
			if (label === 'Global rating') {
				rating = value * 10;
				return;
			}
			if (!excludedLabels[label]) {
				visibleSkills.push(value * 10);
			}
		});
		if (!rating || visibleSkills.length < 9) return 0;
		var regularSkillTotal = visibleSkills.slice(0, 7).reduce(function (sum, value) {
			return sum + value;
		}, 0);
		var mainSkill1 = visibleSkills[7];
		var mainSkill2 = visibleSkills[8];
		var mainSkillSum = mainSkill1 + mainSkill2;
		var morale = parsePercentValue($(statsTable).find('tr td:first-child').filter(function(){ return $(this).text().replace(/\s+/g, ' ').trim() === 'Morale'; }).next('td').first().text()) * 10;
		var experience = parsePercentValue($(statsTable).find('tr td:first-child').filter(function(){ return $(this).text().replace(/\s+/g, ' ').trim() === 'Experience'; }).next('td').first().text()) * 10;
		var estimate = 4 + (7.5 * rating) - (0.5 * regularSkillTotal) - mainSkillSum - (0.5 * morale) - (0.5 * experience);
		return Math.min(Math.max(Math.round(estimate), 0), 1000);
	}

	function addHiddenSkillToPlayerDetails() {
		const tables = document.querySelectorAll(".player_detail_window");
		const statsTable = tables[2];
		if (!statsTable || statsTable.querySelector(".sp-hidden-skill-row")) return;
		var hiddenSkill = getHiddenSkillEstimateFromDetails(statsTable);
		if (!hiddenSkill) return;
		var hiddenPercent = (hiddenSkill / 10).toFixed(1).replace(/\.0$/, '');
		var powerBand = Math.ceil((hiddenSkill / 10) / 10) * 10;
		var powerClass = powerBand >= 100 ? 'power100 powermax' : 'power' + (powerBand - 10) + 'a' + powerBand;
		$(statsTable).find("tr").eq(2).after(
			`<tr class="sp-hidden-skill-row"><td>Hidden skill</td><td class="kleurright" title="Estimated from visible stats">${hiddenPercent} %</td><td><div class="powerbar" title="${hiddenPercent} % (estimated)"><img src="https://media.soccerproject.com/trans2.gif" class="powerbarfill ${powerClass}" style="display:block;width:${hiddenPercent}%;" alt="${hiddenPercent}% estimated" /></div></td></tr>`
		);
	}
 
	//urls
	const setNavigation = () => {
        $('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">')
        $('body').append(
            '<div aria-expanded="false" class="menuBtn" id="hamburgerToggle" role="button"><div class="menuBtnContainer"><div></div><div></div><div></div></div></div>'
        )
        $('#navigation li:last').remove()
        $('#navigation li:first').after(
            $(
                '<li><a href="./spnewl_team_fixtures.php" class="more">Fixtures</a></li><li><a href="./spnewl_team_results.php" class="more">Results</a></li><li><a' +
                ' href="./spnewl_speler_overview.php" class="more">Players</a></li><li><a href="./spnewl_friendly_pool.php" class="more">Friendlies</a></li><li><a' +
                ' href="./spnewl_transfer_overview.php" class="more">Transfer Overview</a><li><a' +
                ' href="./spnewl_friendlycup_invitations.php?step=6" class="more">FC</a></li>'
            )
        )
    }
 
 
	/*************************************
	 *            FUNCTIONS               *
	 **************************************/
	var GOOD_PLAYERS_STORAGE_KEY = 'sp_public_good_players';
	var GOOD_PLAYERS_STORAGE_TS_KEY = 'sp_public_good_players_timestamp';
	var GOOD_PLAYERS_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1000;
	var GOOD_PLAYERS_MIN_HIDDEN = 950;

	function parsePriceValue(text) {
		var normalized = String(text || '')
			.replace(/\u00a0/g, ' ')
			.replace(/\s+/g, ' ')
			.trim();
		if (!normalized) return '';
		var match = normalized.match(/€\s*([\d.,]+)\s*([MK])?/i);
		if (!match) return normalized;
		var amount = match[1].replace(/\./g, '').replace(',', '.');
		var suffix = (match[2] || '').toUpperCase();
		return '€ ' + amount + (suffix ? ' ' + suffix : '');
	}

	function extractPlayerIdFromOnclick(onclickValue) {
		var match = String(onclickValue || '').match(/LoadPlayerInDiv\((\d+),/);
		return match ? parseInt(match[1], 10) : 0;
	}

	function parsePowerbarPercent(cell) {
		if (!cell) return 0;
		var img = cell.querySelector('.powerbarfill');
		if (img) {
			var alt = img.getAttribute('alt') || '';
			var altMatch = alt.match(/(\d+)/);
			if (altMatch) return parseInt(altMatch[1], 10);
		}
		var powerbar = cell.querySelector('.powerbar');
		if (powerbar) {
			var title = powerbar.getAttribute('title') || '';
			var titleMatch = title.match(/(\d+)/);
			if (titleMatch) return parseInt(titleMatch[1], 10);
		}
		return parsePercentValue(cell.textContent);
	}

	function getTransferTableFromRoot(root) {
		var tables = root.querySelectorAll('table.sortable, table[summary=""]');
		for (var i = 0; i < tables.length; i++) {
			var headers = Array.prototype.slice.call(tables[i].querySelectorAll('th')).map(function (th) {
				return $(th).text().replace(/\s+/g, ' ').trim();
			});
			if (headers.indexOf('Name') !== -1 && headers.indexOf('Age') !== -1 && headers.indexOf('Rating') !== -1 && headers.indexOf('Price') !== -1) {
				return tables[i];
			}
		}
		return null;
	}

	function parseTransferPlayersFromDocument(root) {
		var table = getTransferTableFromRoot(root);
		if (!table) return [];
		var players = [];
		$(table).find('tr').each(function () {
			var row = this;
			if (row.id && row.id.indexOf('id_') === 0) return;
			var cells = row.querySelectorAll('td');
			if (cells.length < 6) return;
			var link = cells[1].querySelector('a.dummylink');
			if (!link) return;
			var playerId = extractPlayerIdFromOnclick(link.getAttribute('onclick'));
			if (!playerId) return;
			var name = $(link).attr('title') || $(link).text().replace(/\u00a0/g, ' ').trim();
			var rating = parsePowerbarPercent(cells[3]) * 10;
			players.push({
				id: playerId,
				name: name,
				age: parsePercentValue(cells[2].textContent),
				rating: rating,
				timeframe: $(cells[4]).text().replace(/\u00a0/g, ' ').replace(/\s+/g, ' ').trim(),
				price: parsePriceValue(cells[5].textContent),
				buyNow: parsePriceValue(cells[6] ? cells[6].textContent : ''),
				url: 'spnewl_transfer_buy.php?step=2&spid=' + playerId
			});
		});
		return players;
	}

	function getPaginatorPageUrls(root) {
		var urls = [window.location.href];
		$(root).find('#paginator a').each(function () {
			var href = this.getAttribute('href');
			if (!href) return;
			var absolute = new URL(href, window.location.origin).href;
			if (urls.indexOf(absolute) === -1) urls.push(absolute);
		});
		return urls;
	}

	function fetchHtmlDocument(url) {
		return $.get(url).then(function (html) {
			return new DOMParser().parseFromString(html, 'text/html');
		});
	}

	function getStatsTableFromDetailDocument(doc) {
		var tables = doc.querySelectorAll('.player_detail_window');
		return tables && tables[2] ? tables[2] : null;
	}

	function fetchPlayerDetailSummary(playerId) {
		var url = '/spnewl_speler_detail.php?spid=' + playerId + '&newWindow=1';
		return new Promise(function (resolve) {
			$.get(url)
				.done(function (html) {
					var doc = new DOMParser().parseFromString(html, 'text/html');
					var statsTable = getStatsTableFromDetailDocument(doc);
					resolve({ hidden: statsTable ? getHiddenSkillEstimateFromDetails(statsTable) : 0 });
				})
				.fail(function () {
					resolve({ hidden: 0 });
				});
		});
	}

	function cleanupOldGoodPlayers() {
		var timestamp = parseInt(localStorage.getItem(GOOD_PLAYERS_STORAGE_TS_KEY), 10);
		if (!timestamp) return [];
		if ((Date.now() - timestamp) > GOOD_PLAYERS_MAX_AGE_MS) {
			localStorage.removeItem(GOOD_PLAYERS_STORAGE_KEY);
			localStorage.removeItem(GOOD_PLAYERS_STORAGE_TS_KEY);
			return [];
		}
		try {
			return JSON.parse(localStorage.getItem(GOOD_PLAYERS_STORAGE_KEY)) || [];
		} catch (e) {
			localStorage.removeItem(GOOD_PLAYERS_STORAGE_KEY);
			localStorage.removeItem(GOOD_PLAYERS_STORAGE_TS_KEY);
			return [];
		}
	}

	function saveGoodPlayers(players) {
		var filteredPlayers = (players || []).filter(function (player) {
			return player && Number(player.hidden) >= GOOD_PLAYERS_MIN_HIDDEN;
		});
		localStorage.setItem(GOOD_PLAYERS_STORAGE_KEY, JSON.stringify(filteredPlayers));
		localStorage.setItem(GOOD_PLAYERS_STORAGE_TS_KEY, String(Date.now()));
	}

	function mergeGoodPlayers(existingPlayers, newPlayers) {
		var byId = {};
		(existingPlayers || []).forEach(function (player) {
			if (!player || !player.id || Number(player.hidden) < GOOD_PLAYERS_MIN_HIDDEN) return;
			byId[player.id] = player;
		});
		(newPlayers || []).forEach(function (player) {
			if (!player || !player.id || Number(player.hidden) < GOOD_PLAYERS_MIN_HIDDEN) return;
			byId[player.id] = player;
		});
		return Object.keys(byId).map(function (key) {
			return byId[key];
		});
	}

	function ensureGoodPlayersContainer() {
		if (!document.getElementById('divShowAll')) {
			var paginator = document.getElementById('paginator');
			var container = document.createElement('div');
			container.id = 'divShowAll';
			container.style.marginTop = '12px';
			if (paginator && paginator.parentNode) {
				paginator.parentNode.insertBefore(container, paginator.nextSibling);
			} else {
				document.querySelector('#content').appendChild(container);
			}
		}
		return $('#divShowAll');
	}

	function getSelectedTransferPositionLabel() {
		var select = document.getElementById('selpos');
		if (!select) return '';
		var option = select.options[select.selectedIndex];
		return option ? String(option.text || '').replace(/\s+/g, ' ').trim() : '';
	}

	function ensureFindGoodPlayersButton() {
		if ($('.findGoodPlayers').length) return;
		var buttonHtml = '<a class="button findGoodPlayers" href="#" style="margin-right:8px;">Find Good Players</a>';
		if ($('#paginator').length) {
			$('#paginator').before(buttonHtml);
			return;
		}
		var table = getTransferTableFromRoot(document);
		if (table) {
			$(table).before(buttonHtml);
			return;
		}
		$('#content').append(buttonHtml);
	}

	function renderGoodPlayers(players) {
		var container = ensureGoodPlayersContainer();
		if (!players.length) {
			container.html('<div class="box"><b>Good Players</b><div>No players found with hidden skill 950 or more.</div></div>');
			return;
		}
		var rows = players.map(function (player) {
			return '<tr>' +
				'<td style="text-align:left"><a href="#" title=" ' + player.name + ' " onclick="window.open(\'spnewl_speler_detail.php?spid=' + player.id + '\', \'_blank\',\'height=640, width=500\'); return false;">' + player.name + '</a></td>' +
				'<td style="text-align:center">' + (player.position || '-') + '</td>' +
				'<td style="text-align:center">' + player.age + '</td>' +
				'<td style="text-align:center">' + (player.rating / 10).toFixed(0) + '%</td>' +
				'<td style="text-align:center">' + (player.hidden / 10).toFixed(0) + '%</td>' +
				'<td style="text-align:center">' + player.timeframe + '</td>' +
				'<td style="text-align:center">' + player.price + '</td>' +
				'<td style="text-align:center">' + (player.buyNow || '-') + '</td>' +
				'<td style="text-align:center"><a href="' + player.url + '">Open</a></td>' +
				'</tr>';
		}).join('');
		container.html(
			'<div class="box">' +
				'<div style="margin-bottom:6px;"><b>Good Players</b> - hidden skill 950 or more (' + players.length + ')</div>' +
				'<table class="sortable" summary=""><tbody>' +
				'<tr><th style="text-align:left">Name</th><th>Pos</th><th>Age</th><th>Rating</th><th>Hidden</th><th>Timeframe</th><th>Price</th><th>Buy Now</th><th>Link</th></tr>' +
				rows +
				'</tbody></table>' +
			'</div>'
		);
	}

	function setGoodPlayersStatus(text) {
		ensureGoodPlayersContainer().html('<div class="box"><b>Good Players</b><div>' + text + '</div></div>');
	}

	function findGoodPlayers() {
		var existingPlayers = cleanupOldGoodPlayers();
		var selectedPosition = getSelectedTransferPositionLabel();
		setGoodPlayersStatus('Scanning transfer pages...');
		var pageUrls = getPaginatorPageUrls(document);
		var allPlayers = [];
		var seenIds = {};
		var chain = Promise.resolve();

		pageUrls.forEach(function (pageUrl, pageIndex) {
			chain = chain.then(function () {
				setGoodPlayersStatus('Scanning page ' + (pageIndex + 1) + ' of ' + pageUrls.length + '...');
				return fetchHtmlDocument(pageUrl).then(function (doc) {
					var pagePlayers = parseTransferPlayersFromDocument(doc);
					var innerChain = Promise.resolve();
					pagePlayers.forEach(function (player, playerIndex) {
						if (seenIds[player.id]) return;
						seenIds[player.id] = true;
						innerChain = innerChain.then(function () {
							setGoodPlayersStatus('Checking ' + player.name + ' (' + (allPlayers.length + playerIndex + 1) + ')...');
							return fetchPlayerDetailSummary(player.id).then(function (summary) {
								if (summary.hidden >= GOOD_PLAYERS_MIN_HIDDEN) {
									player.hidden = summary.hidden;
									player.position = selectedPosition || player.position || '';
									allPlayers.push(player);
								}
							});
						});
					});
					return innerChain;
				});
			});
		});

		chain.then(function () {
			var mergedPlayers = mergeGoodPlayers(existingPlayers, allPlayers);
			mergedPlayers.sort(function (a, b) {
				if (b.hidden !== a.hidden) return b.hidden - a.hidden;
				if (b.rating !== a.rating) return b.rating - a.rating;
				return a.age - b.age;
			});
			saveGoodPlayers(mergedPlayers);
			renderGoodPlayers(mergedPlayers);
		}).catch(function (error) {
			console.error(error);
			setGoodPlayersStatus('Failed to scan transfer pages.');
		});
	}

	function removeAllPlayers () {
		$('#formation_field select').each(function(){ //loop through selectable players.
			var me = $(this),
				options = me.find('option');
			me.find('option:selected').removeAttr('selected'); //remove all selected items
			options.first().attr('selected','selected');
			updatePlayer(options.first().parent().get(0));
		});
	}
 
	function updatefitestplayers () {
		removeAllPlayers ();
		var allPlayers = [], i=0;
		$('[id^=trPlayer]').each(function(){ //loop through all of the players
			var player = $(this).find('td');
			var fitness = player.eq(3).text().replace( /^\D+/g, '');
			var fitness = fitness.substring(0, fitness.length - 1); //get out their fitness and then remove the trailing %
			var playerID = player.eq(0).find('a').attr("onclick").replace( /^\D+/g, '');
			var playerID = playerID.slice(0,8);
			var playerID = parseInt(playerID, 10); // get out the players ID
 
			allPlayers.push([playerID,fitness]); //update array of players
		});
 
		allPlayers.sort(function(a,b){ //sort players by highest fitness
			return a[1] - b[1];
		}).reverse();
 
		allPlayers = allPlayers.slice(0,16); //remove the most unfit players
		console.info(allPlayers);
		$('#formation_field select').each(function(){ //loop through selectable players.
			var me = $(this),
				options = me.find('option');
			me.find('option:selected').removeAttr('selected'); //remove all selected items
 
			options.each(function(){ //loop through and add selected if it matches
				if($(this).val()==allPlayers[i][0]){
					var meText = $(this).text(),
						number = meText.substring(0,2),
						name = meText.substring(4);
					$(this).attr('selected','selected');
					updatePlayer(this.parentNode.parentElement);
				};
			});
			i++;
		});
	}
 
	function updateLowestMoralPlayers () {
		//removeAllPlayers ();
		var allPlayers = [], i=0;
		$('[id^=trPlayer]').each(function(){ //loop through all of the players
			var player = $(this).find('td');
			var moral = player.eq(2).text().replace( /^\D+/g, ''); //get moral from players
			var moral = moral.substring(0, moral.length - 1); //get out their fitness and then remove the trailing %
			var playerID = player.eq(0).find('a').attr("onclick").replace( /^\D+/g, '');
			var playerID = playerID.slice(0,8);
			var playerID = parseInt(playerID, 10); // get out the players ID
 
			allPlayers.push([playerID,moral]); //update array of players
		});
 
		allPlayers.sort(function(a,b){ //sort players by highest fitness
			return a[1] - b[1];
		});
 
		allPlayers = allPlayers.slice(0,16);
 
		$('#formation_field select').each(function(){ //loop through selectable players.
			var me = $(this),
				options = me.find('option');
			me.find('option:selected').removeAttr('selected'); //remove all selected items
 
			options.each(function(){ //loop through and add selected if it matches
				if(typeof allPlayers[i] !== "undefined" && $(this).val()==allPlayers[i][0]){
					var meText = $(this).text(),
						number = meText.substring(0,2),
						name = meText.substring(4);
					$(this).attr('selected','selected');
					updatePlayer(this.parentNode.parentElement);
				};
			});
			i++;
		});
	}
 
	/*************************************
	 *            Players               *
	 **************************************/
	function workOutStam(type){
		if(type==='startNonFullyStam'){
			selectArray.forEach(function(key) {
				var select = selects[key],
					stam = selects[key][1],
					currentlySelected = selects[key][selects[key].selectedIndex];
				if(typeof stam !== "undefined" && stam.className!=="maxed"){
					currentlySelected.removeAttribute('selected');
					stam.setAttribute('selected', 'selected');
				}
			});
		}
		if(type==='startStamFullMaxedOtherSkills'){
			var i=1;
			selectArray.forEach(function(key) {
				i++;
				var select = selects[key],
					stam = selects[key][1],
					skill1 = selects[key][1],
					skill2 = selects[key][2],
					skill3 = selects[key][3],
					skill4 = selects[key][4],
					skill5 = selects[key][5],
					skill6 = selects[key][6],
					skill7 = selects[key][7],
					skill8 = selects[key][8],
					skill9 = selects[key][9],
					nothing = selects[key][0],
					currentlySelected = selects[key][selects[key].selectedIndex],
					maxedNumber = $(select).find('.maxed').length;
				if(typeof stam !== "undefined" && maxedNumber===8){
					currentlySelected.removeAttribute('selected');
					stam.setAttribute('selected', 'selected');
				}else if(typeof stam !== "undefined" && maxedNumber===9){
					currentlySelected.removeAttribute('selected');
					stam.removeAttribute('selected');
					nothing.setAttribute("selected", "selected");
					select.removeAttribute('style');
                    $('<span>fully trained</span>').insertAfter(select);
				}
			});
		}
	}
 
	/*************************************
	 *                Pages               *
	 **************************************/
	if(document.location.pathname==="/spnewl_speler_training.php"){
		var selects = document.getElementsByTagName('select'),
			selectArray = Object.keys(selects).slice(0,selects.length);
 
		selectArray.forEach(function(key) {
			var myself = selects[key][selects[key].selectedIndex];
			if(typeof myself !== "undefined" && myself.className==="maxed"){
				selects[key].setAttribute("style","background: red; color: #FFF");
			}
		});
		$('#trainform .pbutton').append('<a class="button startStam" href="#">Start ALL Non Fully Trained Stamina</a><a class="button startStamFullMaxedOtherSkills" href="#">Start Stam on players with maxed everything else</a>');
		$('.startStam').click(function(){
			workOutStam('startNonFullyStam');
			return false;
		});
		$('.startStamFullMaxedOtherSkills').click(function(){
			workOutStam('startStamFullMaxedOtherSkills');
			return false;
		});
	}
 
	if(document.location.pathname==="/spnewl_game_selectie.php"){
 
		if($('.info').text() === 'The selection was saved.'){
			//window.location.href = '/spnewl_team_fixtures.php'
            window.close();
		}
 
		$('.pbutton a:first').after('<a class="button fittness" href="#">Pick Fittest Team</a><a class="button lowmoral" href="#">Pick lowest moral</a>');
		$('.pbutton a:last').after('<a class="button removeplayers" href="#">Remove All Players</a>');
		$('.fittness').click(function(){
			updatefitestplayers('remove');
			return false;
		});
		$('.removeplayers').click(function(){
			removeAllPlayers();
			return false;
		});
		$('.lowmoral').click(function(){
			updateLowestMoralPlayers();
			document.forms['selform'].submit();
			return false;
		});
	}
 
	if(document.location.pathname==="/spnewl_friendly_pool.php" && location.search.includes('step=2')){
		document.forms['inviteform'].submit();
	}
	if(document.location.pathname==="/spnewl_speler_detail.php"){
		addHiddenSkillToPlayerDetails();
	}
	if(document.location.pathname==="/spnewl_transfer_buy.php"){
		cleanupOldGoodPlayers();
		ensureFindGoodPlayersButton();
		if (localStorage.getItem(GOOD_PLAYERS_STORAGE_KEY)) {
			try {
				renderGoodPlayers(JSON.parse(localStorage.getItem(GOOD_PLAYERS_STORAGE_KEY)) || []);
			} catch (e) {
				localStorage.removeItem(GOOD_PLAYERS_STORAGE_KEY);
				localStorage.removeItem(GOOD_PLAYERS_STORAGE_TS_KEY);
			}
		}
		$('.findGoodPlayers').off('click').on('click', function(){
			findGoodPlayers();
			return false;
		});
	}
	var actionButtons = document.querySelectorAll('.button');
	if(actionButtons.length > 1 && actionButtons[1].innerHTML === "Selection"){
		window.open(actionButtons[1]);
		if (actionButtons[0]) {
			actionButtons[0].click();
		}
	}
 
    const startSP = () => {
        setNavigation()
    }
    startSP()
	console.info('loaded');
}
bootSP();