Better Soccer Project

For making SP a little bit better

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==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();